Ejemplo n.º 1
0
        public DecompressedBlock( CompressedBlock block )
        {
            root = new Node( false );
            idTable = new ushort[IDTABLE_SIZE];
            idCount = 0;

            DecodeFrom( block );
        }
Ejemplo n.º 2
0
        public void ReadBlocks( Stream stream )
        {
            // Calculate the number of blocks to read. This depends on the zoomlevel.
            int blockcount = ((Map.Width >> (5+zoom)) * (Map.Height >> (5+zoom)));

            blocks = new CompressedBlock[blockcount];
            int offsetStart = 0, offsetEnd = 0;
            int baseOffset = (blockcount+1) * 3 + 1;
            for ( int i=0; i<blockcount; ++i ) {
                if ( i == 0 ) {
                    offsetStart = stream.ReadByte() + (stream.ReadByte()<<8) + (stream.ReadByte()<<16);
                    offsetEnd = stream.ReadByte() + (stream.ReadByte()<<8) + (stream.ReadByte()<<16);
                }
                else {
                    offsetStart = offsetEnd;
                    offsetEnd = stream.ReadByte() + (stream.ReadByte()<<8) + (stream.ReadByte()<<16);
                }

                blocks[i] = new CompressedBlock( baseOffset+offsetStart, offsetEnd-offsetStart, this );      // Defer reading the block data till later.
            }

            // Read another byte. The last offset is stored as a 4-byte integer, but only 3 bytes where read in the loop before.
            int zero = stream.ReadByte();

            // Read all the actual data afterwards
            for ( int i=0; i<blockcount; ++i ) {
                blocks[i].Read( stream );
            }

            sourceFilename = stream is FileStream ? ((FileStream)stream).Name : "";
        }
Ejemplo n.º 3
0
        public void DecodeFrom( CompressedBlock block )
        {
            const int INVALID_ADJ = 15;
            const int TERMINATOR = 128;

            Install install = block.Parent.Install;

            byte[] data = block.Data;
            for ( int i=0; i<IDTABLE_SIZE; ++i ) idTable[i] = ushort.MaxValue;
            int index = 0;
            idCount = -1;

            // Get a list of province ids
            do {
                ++idCount;
                idTable[idCount] = (ushort)(data[idCount<<1] + ((data[(idCount<<1)+1]&127) << 8));
                index += 2;
            } while ( data[(idCount<<1)+1] < TERMINATOR );
            ++idCount;

            // Normalize the IDs... Basically, we're stripping some of that data away which we don't need (mainly to do with borders).
            for ( int i=0; i<idCount; ++i ) {
                if ( idTable[i] <= Province.MaxID ) continue;

                ushort id = idTable[((idTable[i]>>9) & 63)-4];
                if( id > Province.MaxID )
                    id = install.Provinces.TerraIncognita.ID;
                else {
                    int river = (idTable[i]>>5) & 15;
                    if ( river != INVALID_ADJ ) id = install.Provinces[id].GetNeighbor( river ).ID;

                    idTable[i] = id;
                }
            }

            // Build the tree.
            DecompressorState decompstate = new DecompressorState( index, ref data );
            BuildTree( root, decompstate, 5 );
            index = decompstate.GetFinalNodeIndex();
            // Define ownership and colors tables
            int numLeaves = decompstate.NumOfLeaves;
            int sizeLeaves = decompstate.SizeOfLeaves;
            byte[] colors = new byte[decompstate.SizeOfLeaves + (4-(decompstate.SizeOfLeaves % 4))];
            ushort[] ownership = null;
            decompstate = null;

            if ( idCount == 1 ) {
                ownership = new ushort[numLeaves];
                for ( int i=0; i<numLeaves; ++i )
                    ownership[i] = idTable[0];
            }
            else if ( idCount == 2 ) {
                ownership = new ushort[numLeaves + (8-(numLeaves % 8))];
                for ( int i=0; i<numLeaves; ++index ) {
                    ownership[i++] = idTable[(data[index] >> 0) & 1];
                    ownership[i++] = idTable[(data[index] >> 1) & 1];
                    ownership[i++] = idTable[(data[index] >> 2) & 1];
                    ownership[i++] = idTable[(data[index] >> 3) & 1];
                    ownership[i++] = idTable[(data[index] >> 4) & 1];
                    ownership[i++] = idTable[(data[index] >> 5) & 1];
                    ownership[i++] = idTable[(data[index] >> 6) & 1];
                    ownership[i++] = idTable[(data[index] >> 7) & 1];
                }
            }
            else if ( idCount <= 4 ) {
                ownership = new ushort[numLeaves + (4-(numLeaves % 4))];
                for ( int i=0; i<numLeaves; ++index ) {
                    ownership[i++] = idTable[(data[index] >> 0) & 3];
                    ownership[i++] = idTable[(data[index] >> 2) & 3];
                    ownership[i++] = idTable[(data[index] >> 4) & 3];
                    ownership[i++] = idTable[(data[index] >> 6) & 3];
                }
            }
            else if ( idCount <= 16 ) {
                ownership = new ushort[numLeaves + (2-(numLeaves % 2))];
                for ( int i=0; i<numLeaves; index++ ) {
                    ownership[i++] = idTable[(data[index] >> 0) & 15];
                    ownership[i++] = idTable[(data[index] >> 4) & 15];
                }
            }
            else if ( idCount > 16 ) {
                ownership = new ushort[numLeaves];
                for ( int i=0; i<ownership.Length; ++i, ++index )
                    ownership[i] = idTable[data[index]];
            }

            // Read in color table
            // Finally, read the leaf data. This part contains the "color" data for each leaf.
            for ( int i=0; i<sizeLeaves; ) {
                colors[i++] = (byte)(data[index] & 63);
                colors[i++] = (byte)((data[index] >> 6 | data[index+1] << 2) & 63);
                colors[i++] = (byte)((data[index+1] >> 4 | data[index+2] << 4) & 63);
                colors[i++] = (byte)(data[index+2] >> 2);
                index += 3;
            }

            // Fill them into the tree
            PopulatorState popstate = new PopulatorState( ref ownership, ref colors );
            PopulateTree( root, popstate );
        }
Ejemplo n.º 4
0
 public void EncodeTo( CompressedBlock block )
 {
 }