Esempio n. 1
0
        internal void FlushBuffer()
        {
            if (!m_IsCompressed || m_BufferAll || m_Buffer.Position <= 0)
            {
                return;
            }

            int outLen = (int)(m_Buffer.Position * 1.1);

            if (m_CompBuff == null || m_CompBuff.Length < outLen)
            {
                m_CompBuff = new byte[outLen];
            }
            else
            {
                outLen = m_CompBuff.Length;
            }

            ZLibError error = ZLib.compress2(m_CompBuff, ref outLen, m_Buffer.ToArray(), (int)m_Buffer.Position, ZLibCompressionLevel.Z_BEST_COMPRESSION);

            if (error != ZLibError.Z_OK)
            {
                throw new Exception("ZLib error during copression: " + error.ToString());
            }

            Raw.Write((int)outLen);
            Raw.Write((int)m_Buffer.Position);
            Raw.Write(m_CompBuff, 0, outLen);

            m_Buffer.Position = 0;
        }
Esempio n. 2
0
        public DesignStateDetailed(Serial serial, int revision, int xMin, int yMin, int xMax, int yMax, MultiTileEntry[] tiles) : base(0xD8)
        {
            EnsureCapacity(17 + (tiles.Length * 5));

            Write((byte)0x03);                // Compression Type
            Write((byte)0x00);                // Unknown
            Write((uint)serial);
            Write((int)revision);
            Write((short)tiles.Length);
            Write((short)0);               // Buffer length : reserved
            Write((byte)0);                // Plane count : reserved

            int totalLength = 1;           // includes plane count

            int width  = (xMax - xMin) + 1;
            int height = (yMax - yMin) + 1;

            if (m_PlaneBuffers == null)
            {
                m_PlaneBuffers = new byte[9][];
                m_PlaneUsed    = new bool[9];

                for (int i = 0; i < m_PlaneBuffers.Length; ++i)
                {
                    m_PlaneBuffers[i] = new byte[0x400];
                }

                m_StairBuffers = new byte[6][];

                for (int i = 0; i < m_StairBuffers.Length; ++i)
                {
                    m_StairBuffers[i] = new byte[MaxItemsPerStairBuffer * 5];
                }
            }
            else
            {
                for (int i = 0; i < m_PlaneUsed.Length; ++i)
                {
                    m_PlaneUsed[i] = false;
                }

                Clear(m_PlaneBuffers[0], width * height * 2);

                for (int i = 0; i < 4; ++i)
                {
                    Clear(m_PlaneBuffers[1 + i], (width - 1) * (height - 2) * 2);
                    Clear(m_PlaneBuffers[5 + i], width * (height - 1) * 2);
                }
            }

            int totalStairsUsed = 0;

            for (int i = 0; i < tiles.Length; ++i)
            {
                MultiTileEntry mte = tiles[i];
                int            x = mte.m_OffsetX - xMin;
                int            y = mte.m_OffsetY - yMin;
                int            z = mte.m_OffsetZ;
                int            plane, size;
                bool           floor = false;
                try
                {
                    floor = (Ultima.TileData.ItemTable[mte.m_ItemID & 0x3FFF].Height <= 0);
                }
                catch
                {
                }

                switch (z)
                {
                case 0: plane = 0; break;

                case 7: plane = 1; break;

                case 27: plane = 2; break;

                case 47: plane = 3; break;

                case 67: plane = 4; break;

                default:
                {
                    int    stairBufferIndex = (totalStairsUsed / MaxItemsPerStairBuffer);
                    byte[] stairBuffer      = m_StairBuffers[stairBufferIndex];

                    int byteIndex = (totalStairsUsed % MaxItemsPerStairBuffer) * 5;

                    stairBuffer[byteIndex++] = (byte)((mte.m_ItemID >> 8) & 0x3F);
                    stairBuffer[byteIndex++] = (byte)mte.m_ItemID;

                    stairBuffer[byteIndex++] = (byte)mte.m_OffsetX;
                    stairBuffer[byteIndex++] = (byte)mte.m_OffsetY;
                    stairBuffer[byteIndex++] = (byte)mte.m_OffsetZ;

                    ++totalStairsUsed;

                    continue;
                }
                }

                if (plane == 0)
                {
                    size = height;
                }
                else if (floor)
                {
                    size = height - 2;
                    x   -= 1;
                    y   -= 1;
                }
                else
                {
                    size   = height - 1;
                    plane += 4;
                }

                int index = ((x * size) + y) * 2;

                m_PlaneUsed[plane]               = true;
                m_PlaneBuffers[plane][index]     = (byte)((mte.m_ItemID >> 8) & 0x3F);
                m_PlaneBuffers[plane][index + 1] = (byte)mte.m_ItemID;
            }

            int planeCount = 0;

            for (int i = 0; i < m_PlaneBuffers.Length; ++i)
            {
                if (!m_PlaneUsed[i])
                {
                    continue;
                }

                ++planeCount;

                int size = 0;

                if (i == 0)
                {
                    size = width * height * 2;
                }
                else if (i < 5)
                {
                    size = (width - 1) * (height - 2) * 2;
                }
                else
                {
                    size = width * (height - 1) * 2;
                }

                byte[] inflatedBuffer = m_PlaneBuffers[i];

                int       deflatedLength = m_DeflatedBuffer.Length;
                ZLibError ce             = ZLib.compress2(m_DeflatedBuffer, ref deflatedLength, inflatedBuffer, size, ZLibCompressionLevel.Z_DEFAULT_COMPRESSION);

                if (ce != ZLibError.Z_OK)
                {
                    Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce);
                    deflatedLength = 0;
                    size           = 0;
                }

                Write((byte)(0x20 | i));
                Write((byte)size);
                Write((byte)deflatedLength);
                Write((byte)(((size >> 4) & 0xF0) | ((deflatedLength >> 8) & 0xF)));
                Write(m_DeflatedBuffer, 0, deflatedLength);

                totalLength += 4 + deflatedLength;
            }

            int totalStairBuffersUsed = (totalStairsUsed + (MaxItemsPerStairBuffer - 1)) / MaxItemsPerStairBuffer;

            for (int i = 0; i < totalStairBuffersUsed; ++i)
            {
                ++planeCount;

                int count = (totalStairsUsed - (i * MaxItemsPerStairBuffer));

                if (count > MaxItemsPerStairBuffer)
                {
                    count = MaxItemsPerStairBuffer;
                }

                int size = count * 5;

                byte[] inflatedBuffer = m_StairBuffers[i];

                int       deflatedLength = m_DeflatedBuffer.Length;
                ZLibError ce             = ZLib.compress2(m_DeflatedBuffer, ref deflatedLength, inflatedBuffer, size, ZLibCompressionLevel.Z_DEFAULT_COMPRESSION);

                if (ce != ZLibError.Z_OK)
                {
                    Console.WriteLine("ZLib error: {0} (#{1})", ce, (int)ce);
                    deflatedLength = 0;
                    size           = 0;
                }

                Write((byte)(9 + i));
                Write((byte)size);
                Write((byte)deflatedLength);
                Write((byte)(((size >> 4) & 0xF0) | ((deflatedLength >> 8) & 0xF)));
                Write(m_DeflatedBuffer, 0, deflatedLength);

                totalLength += 4 + deflatedLength;
            }

            Seek(15, System.IO.SeekOrigin.Begin);

            Write((short)totalLength);              // Buffer length
            Write((byte)planeCount);                // Plane count

            /*int planes = (tiles.Length + (MaxItemsPerPlane - 1)) / MaxItemsPerPlane;
             *
             * if ( planes > 255 )
             *      planes = 255;
             *
             * int totalLength = 0;
             *
             * Write( (byte) planes );
             ++totalLength;
             *
             * int itemIndex = 0;
             *
             * for ( int i = 0; i < planes; ++i )
             * {
             *      int byteIndex = 0;
             *
             *      for ( int j = 0; j < MaxItemsPerPlane && itemIndex < tiles.Length; ++j, ++itemIndex )
             *      {
             *              MultiTileEntry e = tiles[itemIndex];
             *
             *              m_InflatedBuffer[byteIndex++] = (byte)((e.m_ItemID >> 8) & 0x3F);
             *              m_InflatedBuffer[byteIndex++] = (byte)e.m_ItemID;
             *              m_InflatedBuffer[byteIndex++] = (byte)e.m_OffsetX;
             *              m_InflatedBuffer[byteIndex++] = (byte)e.m_OffsetY;
             *              m_InflatedBuffer[byteIndex++] = (byte)e.m_OffsetZ;
             *      }
             *
             *      int deflatedLength = m_DeflatedBuffer.Length;
             *      ZLibError ce = ZLib.compress2( m_DeflatedBuffer, ref deflatedLength, m_InflatedBuffer, byteIndex, ZLibCompressionLevel.Z_DEFAULT_COMPRESSION );
             *
             *      if ( ce != ZLibError.Z_OK )
             *      {
             *              Console.WriteLine( "ZLib error: {0} (#{1})", ce, (int)ce );
             *              deflatedLength = 0;
             *              byteIndex = 0;
             *      }
             *
             *      Write( (byte) 0x00 );
             *      Write( (byte) byteIndex );
             *      Write( (byte) deflatedLength );
             *      Write( (byte) (((byteIndex >> 4) & 0xF0) | ((deflatedLength >> 8) & 0xF)) );
             *      Write( m_DeflatedBuffer, 0, deflatedLength );
             *
             *      totalLength += 4 + deflatedLength;
             * }
             *
             * Seek( 15, System.IO.SeekOrigin.Begin );
             * Write( (short) totalLength ); // Buffer length*/
        }