Пример #1
0
        /// <summary>
        /// Saves mul
        /// </summary>
        /// <param name="path"></param>
        public static unsafe void Save(string path)
        {
            checksumsLand   = new List <CheckSums>();
            checksumsStatic = new List <CheckSums>();
            string idx = Path.Combine(path, "artidx.mul");
            string mul = Path.Combine(path, "art.mul");

            using (FileStream fsidx = new FileStream(idx, FileMode.Create, FileAccess.Write, FileShare.Write),
                   fsmul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write))
            {
                MemoryStream  memidx = new MemoryStream();
                MemoryStream  memmul = new MemoryStream();
                SHA256Managed sha    = new SHA256Managed();
                //StreamWriter Tex = new StreamWriter(new FileStream("d:/artlog.txt", FileMode.Create, FileAccess.ReadWrite));

                using (BinaryWriter binidx = new BinaryWriter(memidx),
                       binmul = new BinaryWriter(memmul))
                {
                    for (int index = 0; index < GetIdxLength(); index++)
                    {
                        Files.FireFileSaveEvent();
                        if (m_Cache[index] == null)
                        {
                            if (index < 0x4000)
                            {
                                m_Cache[index] = GetLand(index);
                            }
                            else
                            {
                                m_Cache[index] = GetStatic(index - 0x4000, false);
                            }
                        }
                        Bitmap bmp = m_Cache[index];
                        if ((bmp == null) || (m_Removed[index]))
                        {
                            binidx.Write((int)-1); // lookup
                            binidx.Write((int)0);  // length
                            binidx.Write((int)-1); // extra
                            //Tex.WriteLine(System.String.Format("0x{0:X4} : 0x{1:X4} 0x{2:X4}", index, (int)-1, (int)-1));
                        }
                        else if (index < 0x4000)
                        {
                            byte[]    checksum = bmp.ToArray(PixelFormat.Format16bppArgb1555).ToSha256();
                            CheckSums sum;
                            if (compareSaveImagesLand(checksum, out sum))
                            {
                                binidx.Write((int)sum.pos); //lookup
                                binidx.Write((int)sum.length);
                                binidx.Write((int)0);
                                //Tex.WriteLine(System.String.Format("0x{0:X4} : 0x{1:X4} 0x{2:X4}", index, (int)sum.pos, (int)sum.length));
                                //Tex.WriteLine(System.String.Format("0x{0:X4} -> 0x{1:X4}", sum.index, index));
                                continue;
                            }
                            //land
                            BitmapData bd    = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format16bppArgb1555);
                            ushort *   line  = (ushort *)bd.Scan0;
                            int        delta = bd.Stride >> 1;
                            binidx.Write((int)binmul.BaseStream.Position); //lookup
                            int length    = (int)binmul.BaseStream.Position;
                            int x         = 22;
                            int y         = 0;
                            int linewidth = 2;
                            for (int m = 0; m < 22; ++m, ++y, line += delta, linewidth += 2)
                            {
                                --x;
                                ushort *cur = line;
                                for (int n = 0; n < linewidth; ++n)
                                {
                                    binmul.Write((ushort)(cur[x + n] ^ 0x8000));
                                }
                            }
                            x         = 0;
                            linewidth = 44;
                            y         = 22;
                            line      = (ushort *)bd.Scan0;
                            line     += delta * 22;
                            for (int m = 0; m < 22; m++, y++, line += delta, ++x, linewidth -= 2)
                            {
                                ushort *cur = line;
                                for (int n = 0; n < linewidth; n++)
                                {
                                    binmul.Write((ushort)(cur[x + n] ^ 0x8000));
                                }
                            }
                            int start = length;
                            length = (int)binmul.BaseStream.Position - length;
                            binidx.Write(length);
                            binidx.Write((int)0);
                            bmp.UnlockBits(bd);
                            CheckSums s = new CheckSums()
                            {
                                pos = start, length = length, checksum = checksum, index = index
                            };
                            //Tex.WriteLine(System.String.Format("0x{0:X4} : 0x{1:X4} 0x{2:X4}", index, start, length));
                            checksumsLand.Add(s);
                        }
                        else
                        {
                            byte[]    checksum = bmp.ToArray(PixelFormat.Format16bppArgb1555).ToSha256();
                            CheckSums sum;
                            if (compareSaveImagesStatic(checksum, out sum))
                            {
                                binidx.Write((int)sum.pos); //lookup
                                binidx.Write((int)sum.length);
                                binidx.Write((int)0);
                                //Tex.WriteLine(System.String.Format("0x{0:X4} -> 0x{1:X4}", sum.index, index));
                                //Tex.WriteLine(System.String.Format("0x{0:X4} : 0x{1:X4} 0x{2:X4}", index, sum.pos, sum.length));
                                continue;
                            }

                            // art
                            BitmapData bd    = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format16bppArgb1555);
                            ushort *   line  = (ushort *)bd.Scan0;
                            int        delta = bd.Stride >> 1;
                            binidx.Write((int)binmul.BaseStream.Position); //lookup
                            int length = (int)binmul.BaseStream.Position;
                            binmul.Write((int)1234);                       // header
                            binmul.Write((short)bmp.Width);
                            binmul.Write((short)bmp.Height);
                            int lookup    = (int)binmul.BaseStream.Position;
                            int streamloc = lookup + bmp.Height * 2;
                            int width     = 0;
                            for (int i = 0; i < bmp.Height; ++i)// fill lookup
                            {
                                binmul.Write(width);
                            }
                            int X = 0;
                            for (int Y = 0; Y < bmp.Height; ++Y, line += delta)
                            {
                                ushort *cur = line;
                                width = (int)(binmul.BaseStream.Position - streamloc) / 2;
                                binmul.BaseStream.Seek(lookup + Y * 2, SeekOrigin.Begin);
                                binmul.Write(width);
                                binmul.BaseStream.Seek(streamloc + width * 2, SeekOrigin.Begin);
                                int i = 0;
                                int j = 0;
                                X = 0;
                                while (i < bmp.Width)
                                {
                                    i = X;
                                    for (i = X; i <= bmp.Width; ++i)
                                    {
                                        //first pixel set
                                        if (i < bmp.Width)
                                        {
                                            if (cur[i] != 0)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                    if (i < bmp.Width)
                                    {
                                        for (j = (i + 1); j < bmp.Width; ++j)
                                        {
                                            //next non set pixel
                                            if (cur[j] == 0)
                                            {
                                                break;
                                            }
                                        }
                                        binmul.Write((short)(i - X)); //xoffset
                                        binmul.Write((short)(j - i)); //run
                                        for (int p = i; p < j; ++p)
                                        {
                                            binmul.Write((ushort)(cur[p] ^ 0x8000));
                                        }
                                        X = j;
                                    }
                                }
                                binmul.Write((short)0); //xOffset
                                binmul.Write((short)0); //Run
                            }
                            int start = length;
                            length = (int)binmul.BaseStream.Position - length;
                            binidx.Write(length);
                            binidx.Write((int)0);
                            bmp.UnlockBits(bd);
                            CheckSums s = new CheckSums()
                            {
                                pos = start, length = length, checksum = checksum, index = index
                            };
                            //Tex.WriteLine(System.String.Format("0x{0:X4} : 0x{1:X4} 0x{2:X4}", index, start, length));
                            checksumsStatic.Add(s);
                        }
                    }
                    memidx.WriteTo(fsidx);
                    memmul.WriteTo(fsmul);
                }
            }
        }
Пример #2
0
        public TileMatrixPatch(TileMatrix matrix, int index, string path)
        {
            BlockWidth  = matrix.BlockWidth;
            BlockHeight = matrix.BlockWidth;

            LandBlocksCount = StaticBlocksCount = 0;
            string mapDataPath, mapIndexPath;

            if (path == null)
            {
                mapDataPath  = Files.GetFilePath("mapdif{0}.mul", index);
                mapIndexPath = Files.GetFilePath("mapdifl{0}.mul", index);
            }
            else
            {
                mapDataPath = Path.Combine(path, String.Format("mapdif{0}.mul", index));
                if (!File.Exists(mapDataPath))
                {
                    mapDataPath = null;
                }

                mapIndexPath = Path.Combine(path, String.Format("mapdifl{0}.mul", index));
                if (!File.Exists(mapIndexPath))
                {
                    mapIndexPath = null;
                }
            }

            if (mapDataPath != null && mapIndexPath != null)
            {
                LandBlocks      = new Tile[matrix.BlockWidth][][];
                LandBlocksCount = PatchLand(matrix, mapDataPath, mapIndexPath);
            }

            string staDataPath, staIndexPath, staLookupPath;

            if (path == null)
            {
                staDataPath   = Files.GetFilePath("stadif{0}.mul", index);
                staIndexPath  = Files.GetFilePath("stadifl{0}.mul", index);
                staLookupPath = Files.GetFilePath("stadifi{0}.mul", index);
            }
            else
            {
                staDataPath = Path.Combine(path, String.Format("stadif{0}.mul", index));
                if (!File.Exists(staDataPath))
                {
                    staDataPath = null;
                }

                staIndexPath = Path.Combine(path, String.Format("stadifl{0}.mul", index));
                if (!File.Exists(staIndexPath))
                {
                    staIndexPath = null;
                }

                staLookupPath = Path.Combine(path, String.Format("stadifi{0}.mul", index));
                if (!File.Exists(staLookupPath))
                {
                    staLookupPath = null;
                }
            }

            if (staDataPath != null && staIndexPath != null && staLookupPath != null)
            {
                StaticBlocks      = new HuedTile[matrix.BlockWidth][][][][];
                StaticBlocksCount = PatchStatics(matrix, staDataPath, staIndexPath, staLookupPath);
            }
        }
Пример #3
0
        public static void DefragStatics(string path, Map map, int width, int height, bool remove)
        {
            string       indexPath = Files.GetFilePath("staidx{0}.mul", map.FileIndex);
            FileStream   m_Index;
            BinaryReader m_IndexReader;

            if (indexPath != null)
            {
                m_Index       = new FileStream(indexPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                m_IndexReader = new BinaryReader(m_Index);
            }
            else
            {
                return;
            }

            string staticsPath = Files.GetFilePath("statics{0}.mul", map.FileIndex);

            FileStream   m_Statics;
            BinaryReader m_StaticsReader;

            if (staticsPath != null)
            {
                m_Statics       = new FileStream(staticsPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                m_StaticsReader = new BinaryReader(m_Statics);
            }
            else
            {
                return;
            }


            int blockx = width >> 3;
            int blocky = height >> 3;

            string idx = Path.Combine(path, String.Format("staidx{0}.mul", map.FileIndex));
            string mul = Path.Combine(path, String.Format("statics{0}.mul", map.FileIndex));

            using (FileStream fsidx = new FileStream(idx, FileMode.Create, FileAccess.Write, FileShare.Write),
                   fsmul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write))
            {
                MemoryStream memidx = new MemoryStream();
                MemoryStream memmul = new MemoryStream();
                using (BinaryWriter binidx = new BinaryWriter(memidx),
                       binmul = new BinaryWriter(memmul))
                {
                    for (int x = 0; x < blockx; ++x)
                    {
                        for (int y = 0; y < blocky; ++y)
                        {
                            try
                            {
                                m_IndexReader.BaseStream.Seek(((x * blocky) + y) * 12, SeekOrigin.Begin);
                                int lookup = m_IndexReader.ReadInt32();
                                int length = m_IndexReader.ReadInt32();
                                int extra  = m_IndexReader.ReadInt32();

                                if (((lookup < 0 || length <= 0) &&
                                     (!map.Tiles.PendingStatic(x, y))) ||
                                    (map.Tiles.IsStaticBlockRemoved(x, y)))
                                {
                                    binidx.Write((int)-1); // lookup
                                    binidx.Write((int)-1); // length
                                    binidx.Write((int)-1); // extra
                                }
                                else
                                {
                                    if ((lookup >= 0) && (length > 0))
                                    {
                                        m_Statics.Seek(lookup, SeekOrigin.Begin);
                                    }

                                    int fsmullength = (int)binmul.BaseStream.Position;
                                    int count       = length / 7;
                                    if (!remove) //without duplicate remove
                                    {
                                        bool firstitem = true;
                                        for (int i = 0; i < count; ++i)
                                        {
                                            ushort graphic = m_StaticsReader.ReadUInt16();
                                            byte   sx      = m_StaticsReader.ReadByte();
                                            byte   sy      = m_StaticsReader.ReadByte();
                                            sbyte  sz      = m_StaticsReader.ReadSByte();
                                            short  shue    = m_StaticsReader.ReadInt16();
                                            if ((graphic >= 0) && (graphic <= Art.GetMaxItemID()))
                                            {
                                                if (shue < 0)
                                                {
                                                    shue = 0;
                                                }
                                                if (firstitem)
                                                {
                                                    binidx.Write((int)binmul.BaseStream.Position); //lookup
                                                    firstitem = false;
                                                }
                                                binmul.Write(graphic);
                                                binmul.Write(sx);
                                                binmul.Write(sy);
                                                binmul.Write(sz);
                                                binmul.Write(shue);
                                            }
                                        }
                                        StaticTile[] tilelist = map.Tiles.GetPendingStatics(x, y);
                                        if (tilelist != null)
                                        {
                                            for (int i = 0; i < tilelist.Length; ++i)
                                            {
                                                if ((tilelist[i].m_ID >= 0) && (tilelist[i].m_ID <= Art.GetMaxItemID()))
                                                {
                                                    if (tilelist[i].m_Hue < 0)
                                                    {
                                                        tilelist[i].m_Hue = 0;
                                                    }
                                                    if (firstitem)
                                                    {
                                                        binidx.Write((int)binmul.BaseStream.Position); //lookup
                                                        firstitem = false;
                                                    }
                                                    binmul.Write(tilelist[i].m_ID);
                                                    binmul.Write(tilelist[i].m_X);
                                                    binmul.Write(tilelist[i].m_Y);
                                                    binmul.Write(tilelist[i].m_Z);
                                                    binmul.Write(tilelist[i].m_Hue);
                                                }
                                            }
                                        }
                                    }
                                    else //with duplicate remove
                                    {
                                        StaticTile[] tilelist = new StaticTile[count];
                                        int          j        = 0;
                                        for (int i = 0; i < count; ++i)
                                        {
                                            StaticTile tile = new StaticTile();
                                            tile.m_ID  = m_StaticsReader.ReadUInt16();
                                            tile.m_X   = m_StaticsReader.ReadByte();
                                            tile.m_Y   = m_StaticsReader.ReadByte();
                                            tile.m_Z   = m_StaticsReader.ReadSByte();
                                            tile.m_Hue = m_StaticsReader.ReadInt16();

                                            if ((tile.m_ID >= 0) && (tile.m_ID <= Art.GetMaxItemID()))
                                            {
                                                if (tile.m_Hue < 0)
                                                {
                                                    tile.m_Hue = 0;
                                                }
                                                bool first = true;
                                                for (int k = 0; k < j; ++k)
                                                {
                                                    if ((tilelist[k].m_ID == tile.m_ID) &&
                                                        ((tilelist[k].m_X == tile.m_X) && (tilelist[k].m_Y == tile.m_Y)) &&
                                                        (tilelist[k].m_Z == tile.m_Z) &&
                                                        (tilelist[k].m_Hue == tile.m_Hue))
                                                    {
                                                        first = false;
                                                        break;
                                                    }
                                                }
                                                if (first)
                                                {
                                                    tilelist[j] = tile;
                                                    j++;
                                                }
                                            }
                                        }
                                        if (map.Tiles.PendingStatic(x, y))
                                        {
                                            StaticTile[] pending = map.Tiles.GetPendingStatics(x, y);
                                            StaticTile[] old     = tilelist;
                                            tilelist = new StaticTile[old.Length + pending.Length];
                                            old.CopyTo(tilelist, 0);
                                            for (int i = 0; i < pending.Length; ++i)
                                            {
                                                if ((pending[i].m_ID >= 0) && (pending[i].m_ID <= Art.GetMaxItemID()))
                                                {
                                                    if (pending[i].m_Hue < 0)
                                                    {
                                                        pending[i].m_Hue = 0;
                                                    }
                                                    bool first = true;
                                                    for (int k = 0; k < j; ++k)
                                                    {
                                                        if ((tilelist[k].m_ID == pending[i].m_ID) &&
                                                            ((tilelist[k].m_X == pending[i].m_X) && (tilelist[k].m_Y == pending[i].m_Y)) &&
                                                            (tilelist[k].m_Z == pending[i].m_Z) &&
                                                            (tilelist[k].m_Hue == pending[i].m_Hue))
                                                        {
                                                            first = false;
                                                            break;
                                                        }
                                                    }
                                                    if (first)
                                                    {
                                                        tilelist[j++] = pending[i];
                                                    }
                                                }
                                            }
                                        }
                                        if (j > 0)
                                        {
                                            binidx.Write((int)binmul.BaseStream.Position); //lookup
                                            for (int i = 0; i < j; ++i)
                                            {
                                                binmul.Write(tilelist[i].m_ID);
                                                binmul.Write(tilelist[i].m_X);
                                                binmul.Write(tilelist[i].m_Y);
                                                binmul.Write(tilelist[i].m_Z);
                                                binmul.Write(tilelist[i].m_Hue);
                                            }
                                        }
                                    }

                                    fsmullength = (int)binmul.BaseStream.Position - fsmullength;
                                    if (fsmullength > 0)
                                    {
                                        binidx.Write(fsmullength); //length
                                        if (extra == -1)
                                        {
                                            extra = 0;
                                        }
                                        binidx.Write(extra); //extra
                                    }
                                    else
                                    {
                                        binidx.Write((int)-1); //lookup
                                        binidx.Write((int)-1); //length
                                        binidx.Write((int)-1); //extra
                                    }
                                }
                            }
                            catch // fill the rest
                            {
                                binidx.BaseStream.Seek(((x * blocky) + y) * 12, SeekOrigin.Begin);
                                for (; x < blockx; ++x)
                                {
                                    for (; y < blocky; ++y)
                                    {
                                        binidx.Write((int)-1); //lookup
                                        binidx.Write((int)-1); //length
                                        binidx.Write((int)-1); //extra
                                    }
                                    y = 0;
                                }
                            }
                        }
                    }
                    memidx.WriteTo(fsidx);
                    memmul.WriteTo(fsmul);
                }
            }
            m_IndexReader.Close();
            m_StaticsReader.Close();
        }
Пример #4
0
        public static void RewriteMap(string path, int map, int width, int height)
        {
            string       mapPath = Files.GetFilePath("map{0}.mul", map);
            FileStream   m_map;
            BinaryReader m_mapReader;

            if (mapPath != null)
            {
                m_map       = new FileStream(mapPath, FileMode.Open, FileAccess.Read, FileShare.Read);
                m_mapReader = new BinaryReader(m_map);
            }
            else
            {
                return;
            }

            int blockx = width >> 3;
            int blocky = height >> 3;

            string mul = Path.Combine(path, String.Format("map{0}.mul", map));

            using (FileStream fsmul = new FileStream(mul, FileMode.Create, FileAccess.Write, FileShare.Write))
            {
                MemoryStream memmul = new MemoryStream();
                using (BinaryWriter binmul = new BinaryWriter(memmul))
                {
                    for (int x = 0; x < blockx; ++x)
                    {
                        for (int y = 0; y < blocky; ++y)
                        {
                            try
                            {
                                m_mapReader.BaseStream.Seek(((x * blocky) + y) * 196, SeekOrigin.Begin);
                                int header = m_mapReader.ReadInt32();
                                binmul.Write(header);

                                for (int i = 0; i < 64; ++i)
                                {
                                    short tileid = m_mapReader.ReadInt16();
                                    sbyte z      = m_mapReader.ReadSByte();
                                    if ((tileid < 0) || (tileid >= 0x4000))
                                    {
                                        tileid = 0;
                                    }
                                    if (z < -128)
                                    {
                                        z = -128;
                                    }
                                    if (z > 127)
                                    {
                                        z = 127;
                                    }
                                    binmul.Write(tileid);
                                    binmul.Write(z);
                                }
                            }
                            catch //fill rest
                            {
                                binmul.BaseStream.Seek(((x * blocky) + y) * 196, SeekOrigin.Begin);
                                for (; x < blockx; ++x)
                                {
                                    for (; y < blocky; ++y)
                                    {
                                        binmul.Write((int)0);
                                        for (int i = 0; i < 64; ++i)
                                        {
                                            binmul.Write((short)0);
                                            binmul.Write((sbyte)0);
                                        }
                                    }
                                    y = 0;
                                }
                            }
                        }
                    }
                    memmul.WriteTo(fsmul);
                }
            }
            m_mapReader.Close();
        }
Пример #5
0
        public TileMatrix(int fileIndex, int mapID, int width, int height, string path)
        {
            Width       = width;
            Height      = height;
            BlockWidth  = width >> 3;
            BlockHeight = height >> 3;

            if (path == null)
            {
                mapPath = Files.GetFilePath("map{0}.mul", fileIndex);

                if (String.IsNullOrEmpty(mapPath) || !File.Exists(mapPath))
                {
                    mapPath = Files.GetFilePath("map{0}LegacyMUL.uop", fileIndex);
                }

                if (mapPath != null && mapPath.EndsWith(".uop"))
                {
                    IsUOPFormat = true;
                }
            }
            else
            {
                mapPath = Path.Combine(path, String.Format("map{0}.mul", fileIndex));

                if (!File.Exists(mapPath))
                {
                    mapPath = Path.Combine(path, String.Format("map{0}LegacyMUL.uop", fileIndex));
                }

                if (!File.Exists(mapPath))
                {
                    mapPath = null;
                }
                else if (mapPath != null && mapPath.EndsWith(".uop"))
                {
                    IsUOPFormat = true;
                }
            }

            if (path == null)
            {
                indexPath = Files.GetFilePath("staidx{0}.mul", fileIndex);
            }
            else
            {
                indexPath = Path.Combine(path, String.Format("staidx{0}.mul", fileIndex));
                if (!File.Exists(indexPath))
                {
                    indexPath = null;
                }
            }

            if (path == null)
            {
                staticsPath = Files.GetFilePath("statics{0}.mul", fileIndex);
            }
            else
            {
                staticsPath = Path.Combine(path, String.Format("statics{0}.mul", fileIndex));
                if (!File.Exists(staticsPath))
                {
                    staticsPath = null;
                }
            }

            EmptyStaticBlock = new HuedTile[8][][];

            for (int i = 0; i < 8; ++i)
            {
                EmptyStaticBlock[i] = new HuedTile[8][];

                for (int j = 0; j < 8; ++j)
                {
                    EmptyStaticBlock[i][j] = new HuedTile[0];
                }
            }

            InvalidLandBlock = new Tile[196];

            m_LandTiles   = new Tile[BlockWidth][][];
            m_StaticTiles = new HuedTile[BlockWidth][][][][];

            Patch = new TileMatrixPatch(this, mapID, path);
        }
Пример #6
0
 /// <summary>
 /// Initialize <see cref="StringList"/> of Language
 /// </summary>
 /// <param name="language"></param>
 public StringList(string language)
 {
     Language = language;
     LoadEntry(Files.GetFilePath(String.Format("cliloc.{0}", language)));
 }
Пример #7
0
        public static unsafe void Initialize()
        {
            var filePath = Files.GetFilePath("tiledata.mul");

            if (filePath != null)
            {
                using (var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.Read))
                {
                    var useNeWTileDataFormat = Art.IsUOAHS();
                    landheader = new int[512];
                    var j = 0;
                    LandTable = new LandData[0x4000];

                    var  buffer  = new byte[fs.Length];
                    var  gc      = GCHandle.Alloc(buffer, GCHandleType.Pinned);
                    long currpos = 0;
                    try
                    {
                        fs.Read(buffer, 0, buffer.Length);
                        for (var i = 0; i < 0x4000; i += 32)
                        {
                            var ptrheader = new IntPtr((long)gc.AddrOfPinnedObject() + currpos);
                            currpos        += 4;
                            landheader[j++] = (int)Marshal.PtrToStructure(ptrheader, typeof(int));
                            for (var count = 0; count < 32; ++count)
                            {
                                var ptr = new IntPtr((long)gc.AddrOfPinnedObject() + currpos);
                                if (useNeWTileDataFormat)
                                {
                                    currpos += sizeof(NewLandTileDataMul);
                                    var cur = (NewLandTileDataMul)Marshal.PtrToStructure(ptr, typeof(NewLandTileDataMul));
                                    LandTable[i + count] = new LandData(cur);
                                }
                                else
                                {
                                    currpos += sizeof(OldLandTileDataMul);
                                    var cur = (OldLandTileDataMul)Marshal.PtrToStructure(ptr, typeof(OldLandTileDataMul));
                                    LandTable[i + count] = new LandData(cur);
                                }
                            }
                        }

                        var remaining  = buffer.Length - currpos;
                        var structsize = useNeWTileDataFormat ? sizeof(NewItemTileDataMul) : sizeof(OldItemTileDataMul);
                        itemheader = new int[(remaining / ((structsize * 32) + 4))];
                        var itemlength = itemheader.Length * 32;

                        ItemTable     = new ItemData[itemlength];
                        m_HeightTable = new int[itemlength];

                        j = 0;
                        for (var i = 0; i < itemlength; i += 32)
                        {
                            var ptrheader = new IntPtr((long)gc.AddrOfPinnedObject() + currpos);
                            currpos        += 4;
                            itemheader[j++] = (int)Marshal.PtrToStructure(ptrheader, typeof(int));
                            for (var count = 0; count < 32; ++count)
                            {
                                var ptr = new IntPtr((long)gc.AddrOfPinnedObject() + currpos);
                                if (useNeWTileDataFormat)
                                {
                                    currpos += sizeof(NewItemTileDataMul);
                                    var cur = (NewItemTileDataMul)Marshal.PtrToStructure(ptr, typeof(NewItemTileDataMul));
                                    ItemTable[i + count]     = new ItemData(cur);
                                    m_HeightTable[i + count] = cur.height;
                                }
                                else
                                {
                                    currpos += sizeof(OldItemTileDataMul);
                                    var cur = (OldItemTileDataMul)Marshal.PtrToStructure(ptr, typeof(OldItemTileDataMul));
                                    ItemTable[i + count]     = new ItemData(cur);
                                    m_HeightTable[i + count] = cur.height;
                                }
                            }
                        }
                    }
                    finally
                    {
                        gc.Free();
                    }
                }
            }
        }
Пример #8
0
        public FileIndex(string idxFile, string mulFile, int file, Verdata verdata, Files files)
        {
            _files        = files;
            this._Verdata = verdata;
            string idxPath = null;

            MulPath = null;
            if (_files.MulPath == null)
            {
                _files.LoadMulPath();
            }
            if (_files.MulPath.Count > 0)
            {
                idxPath = _files.MulPath[idxFile.ToLower()];
                MulPath = _files.MulPath[mulFile.ToLower()];
                if (String.IsNullOrEmpty(idxPath))
                {
                    idxPath = null;
                }
                else
                {
                    if (String.IsNullOrEmpty(Path.GetDirectoryName(idxPath)))
                    {
                        idxPath = Path.Combine(_files.RootDir, idxPath);
                    }
                    if (!File.Exists(idxPath))
                    {
                        idxPath = null;
                    }
                }
                if (String.IsNullOrEmpty(MulPath))
                {
                    MulPath = null;
                }
                else
                {
                    if (String.IsNullOrEmpty(Path.GetDirectoryName(MulPath)))
                    {
                        MulPath = Path.Combine(_files.RootDir, MulPath);
                    }
                    if (!File.Exists(MulPath))
                    {
                        MulPath = null;
                    }
                }
            }

            if ((idxPath != null) && (MulPath != null))
            {
                using (var index = new FileStream(idxPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    Stream = new FileStream(MulPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                    var count = (int)(index.Length / 12);
                    IdxLength = index.Length;
                    Index     = new Entry3D[count];
                    GCHandle gc     = GCHandle.Alloc(Index, GCHandleType.Pinned);
                    var      buffer = new byte[index.Length];
                    index.Read(buffer, 0, (int)index.Length);
                    Marshal.Copy(buffer, 0, gc.AddrOfPinnedObject(), (int)index.Length);
                    gc.Free();
                }
            }
            else
            {
                Stream = null;
                Index  = new Entry3D[1];
                return;
            }
            Entry5D[] patches = _Verdata.Patches;

            if (file > -1)
            {
                for (int i = 0; i < patches.Length; ++i)
                {
                    Entry5D patch = patches[i];

                    if (patch.file == file && patch.index >= 0 && patch.index < Index.Length)
                    {
                        Index[patch.index].lookup = patch.lookup;
                        Index[patch.index].length = patch.length | (1 << 31);
                        Index[patch.index].extra  = patch.extra;
                    }
                }
            }
        }
Пример #9
0
        public FileIndex(
            string idxFile,
            string mulFile,
            string uopFile,
            int length,
            int file,
            string uopEntryExtension,
            int idxLength,
            bool hasExtra, Verdata verdata, Files files)
        {
            _files        = files;
            this._Verdata = verdata;
            Index         = new Entry3D[length];

            string idxPath = null;

            MulPath = null;
            string uopPath = null;

            if (_files.MulPath == null)
            {
                _files.LoadMulPath();
            }

            if (_files.MulPath.Count > 0)
            {
                idxPath = _files.MulPath[idxFile.ToLower()];
                MulPath = _files.MulPath[mulFile.ToLower()];

                if (!String.IsNullOrEmpty(uopFile) && _files.MulPath.ContainsKey(uopFile.ToLower()))
                {
                    uopPath = _files.MulPath[uopFile.ToLower()];
                }

                if (String.IsNullOrEmpty(idxPath))
                {
                    idxPath = null;
                }
                else
                {
                    if (String.IsNullOrEmpty(Path.GetDirectoryName(idxPath)))
                    {
                        idxPath = Path.Combine(_files.RootDir, idxPath);
                    }

                    if (!File.Exists(idxPath))
                    {
                        idxPath = null;
                    }
                }

                if (String.IsNullOrEmpty(MulPath))
                {
                    MulPath = null;
                }
                else
                {
                    if (String.IsNullOrEmpty(Path.GetDirectoryName(MulPath)))
                    {
                        MulPath = Path.Combine(_files.RootDir, MulPath);
                    }

                    if (!File.Exists(MulPath))
                    {
                        MulPath = null;
                    }
                }

                if (String.IsNullOrEmpty(uopPath))
                {
                    uopPath = null;
                }
                else
                {
                    if (String.IsNullOrEmpty(Path.GetDirectoryName(uopPath)))
                    {
                        uopPath = Path.Combine(_files.RootDir, uopPath);
                    }

                    if (!File.Exists(uopPath))
                    {
                        uopPath = null;
                    }
                    else
                    {
                        MulPath = uopPath;
                    }
                }
            }

            /* UOP files support code, written by Wyatt (c) www.ruosi.org
             * idxLength variable was added for compatibility with legacy code for art (see art.cs)
             * At the moment the only UOP file having entries with extra field is gumpartlegacy.uop,
             * and it's two dwords in the beginning of the entry.
             * It's possible that UOP can include some entries with unknown hash: not really unknown for me, but
             * not useful for reading legacy entries. That's why i removed unknown hash exception throwing from this code
             */
            if (MulPath != null && MulPath.EndsWith(".uop"))
            {
                using (var index = new FileStream(MulPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    Stream = new FileStream(MulPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);

                    var    fi         = new FileInfo(MulPath);
                    string uopPattern = fi.Name.Replace(fi.Extension, "").ToLowerInvariant();

                    using (var br = new BinaryReader(Stream))
                    {
                        br.BaseStream.Seek(0, SeekOrigin.Begin);

                        if (br.ReadInt32() != 0x50594D)
                        {
                            throw new ArgumentException("Bad UOP file.");
                        }

                        br.ReadInt64();                         // version + signature
                        long nextBlock = br.ReadInt64();
                        br.ReadInt32();                         // block capacity
                        int count = br.ReadInt32();

                        if (idxLength > 0)
                        {
                            IdxLength = idxLength * 12;
                        }

                        var hashes = new Dictionary <ulong, int>();

                        for (int i = 0; i < length; i++)
                        {
                            string entryName = string.Format("build/{0}/{1:D8}{2}", uopPattern, i, uopEntryExtension);
                            ulong  hash      = HashFileName(entryName);

                            if (!hashes.ContainsKey(hash))
                            {
                                hashes.Add(hash, i);
                            }
                        }

                        br.BaseStream.Seek(nextBlock, SeekOrigin.Begin);

                        do
                        {
                            int filesCount = br.ReadInt32();
                            nextBlock = br.ReadInt64();

                            for (int i = 0; i < filesCount; i++)
                            {
                                long  offset             = br.ReadInt64();
                                int   headerLength       = br.ReadInt32();
                                int   compressedLength   = br.ReadInt32();
                                int   decompressedLength = br.ReadInt32();
                                ulong hash = br.ReadUInt64();
                                br.ReadUInt32();                                 // Adler32
                                short flag = br.ReadInt16();

                                int entryLength = flag == 1 ? compressedLength : decompressedLength;

                                if (offset == 0)
                                {
                                    continue;
                                }

                                int idx;
                                if (hashes.TryGetValue(hash, out idx))
                                {
                                    if (idx < 0 || idx > Index.Length)
                                    {
                                        throw new IndexOutOfRangeException("hashes dictionary and files collection have different count of entries!");
                                    }

                                    Index[idx].lookup = (int)(offset + headerLength);
                                    Index[idx].length = entryLength;

                                    if (hasExtra)
                                    {
                                        long curPos = br.BaseStream.Position;

                                        br.BaseStream.Seek(offset + headerLength, SeekOrigin.Begin);

                                        byte[] extra = br.ReadBytes(8);

                                        var extra1 = (ushort)((extra[3] << 24) | (extra[2] << 16) | (extra[1] << 8) | extra[0]);
                                        var extra2 = (ushort)((extra[7] << 24) | (extra[6] << 16) | (extra[5] << 8) | extra[4]);

                                        Index[idx].lookup += 8;
                                        Index[idx].extra   = extra1 << 16 | extra2;

                                        br.BaseStream.Seek(curPos, SeekOrigin.Begin);
                                    }
                                }
                            }
                        }while (br.BaseStream.Seek(nextBlock, SeekOrigin.Begin) != 0);
                    }
                }
            }
            else if ((idxPath != null) && (MulPath != null))
            {
                using (var index = new FileStream(idxPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    Stream = new FileStream(MulPath, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                    var count = (int)(index.Length / 12);
                    IdxLength = index.Length;
                    GCHandle gc     = GCHandle.Alloc(Index, GCHandleType.Pinned);
                    var      buffer = new byte[index.Length];
                    index.Read(buffer, 0, (int)index.Length);
                    Marshal.Copy(buffer, 0, gc.AddrOfPinnedObject(), (int)Math.Min(IdxLength, length * 12));
                    gc.Free();
                    for (int i = count; i < length; ++i)
                    {
                        Index[i].lookup = -1;
                        Index[i].length = -1;
                        Index[i].extra  = -1;
                    }
                }
            }
            else
            {
                Stream = null;
                return;
            }

            Entry5D[] patches = _Verdata.Patches;

            if (file > -1)
            {
                for (int i = 0; i < patches.Length; ++i)
                {
                    Entry5D patch = patches[i];

                    if (patch.file == file && patch.index >= 0 && patch.index < length)
                    {
                        Index[patch.index].lookup = patch.lookup;
                        Index[patch.index].length = patch.length | (1 << 31);
                        Index[patch.index].extra  = patch.extra;
                    }
                }
            }
        }
Пример #10
0
 public FileIndex(string idxFile, string mulFile, int length, int file, Verdata verdata, Files files)
     : this(idxFile, mulFile, null, length, file, ".dat", -1, false, verdata, files)
 {
 }
Пример #11
0
        /// <summary>
        /// Reads fonts.mul
        /// </summary>
        public static unsafe void Initialize()
        {
            string path = Files.GetFilePath("fonts.mul");

            if (path == null)
            {
                return;
            }

            using (var reader = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read))
            {
                var buffer = new byte[(int)reader.Length];
                reader.Read(buffer, 0, (int)reader.Length);
                fixed(byte *bin = buffer)
                {
                    byte *read = bin;

                    for (int i = 0; i < 10; ++i)
                    {
                        byte header = *read++;
                        Fonts[i] = new ASCIIFont(header);

                        for (int k = 0; k < 224; ++k)
                        {
                            byte width  = *read++;
                            byte height = *read++;
                            byte unk    = *read++; // delimiter?

                            if (width <= 0 || height <= 0)
                            {
                                continue;
                            }

                            if (height > Fonts[i].Height && k < 96)
                            {
                                Fonts[i].Height = height;
                            }

                            var        bmp = new Bitmap(width, height);
                            BitmapData bd  = bmp.LockBits(
                                new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, PixelFormat.Format16bppArgb1555);
                            var line  = (ushort *)bd.Scan0;
                            int delta = bd.Stride >> 1;

                            for (int y = 0; y < height; ++y, line += delta)
                            {
                                ushort *cur = line;
                                for (int x = 0; x < width; ++x)
                                {
                                    var pixel = (ushort)(*read++ | (*read++ << 8));
                                    if (pixel == 0)
                                    {
                                        cur[x] = pixel;
                                    }
                                    else
                                    {
                                        cur[x] = (ushort)(pixel ^ 0x8000);
                                    }
                                }
                            }
                            bmp.UnlockBits(bd);
                            Fonts[i].Characters[k] = bmp;
                            Fonts[i].Unk[k]        = unk;
                        }
                    }
                }
            }
        }