예제 #1
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 );
        }
예제 #2
0
        private void PopulateTree( Node currentNode, PopulatorState state )
        {
            if ( currentNode == null ) return;

            if ( !currentNode.IsLeaf() ) {
                // Walk over the tree in a breath-first manner
                PopulateTree( currentNode.BottomRightChild, state );
                PopulateTree( currentNode.BottomLeftChild, state );
                PopulateTree( currentNode.TopRightChild, state );
                PopulateTree( currentNode.TopLeftChild, state );
            }
            else {
                currentNode.Owner = state.CurrentOwner;
                currentNode.Color = state.CurrentColor;
                state.NextLeaf();
            }
        }