Beispiel #1
0
 public void SetZone( int idx, IDZone zone )
 {
     zones[idx] = zone;
 }
Beispiel #2
0
            public virtual void ReadFrom( BinaryReader reader, int size )
            {
                zones =  new IDZone[size];

                for ( int i=0; i<size; ++i ) {
                    zones[i] = new IDZone( reader );
                }
            }
Beispiel #3
0
            public ushort this[int x]
            {
                get {
                    return LookupZone( x ).ID;
                }
                set {
                    x = Lightmap.BaseNormalizeX( x );

                    // I think this is the longest set { } implementation I've ever written... :) ~ Inferis

                    // Transform x coordinate into a zoneindex
                    int index = LookupZoneIndex( x );
                    if ( index < 0 ) throw new ArgumentOutOfRangeException();

                    // Skip if we're trying to put the same value
                    IDZone zone = zones[index];
                    if ( zone.ID == value ) return;

                    // Find the length out
                    int length = index+1 < zones.Length ? (zones[index+1].X - zone.X) : (Lightmap.BaseWidth - zone.X);
                    IDZone[] list;

                    if ( length == 1 ) {
                        // Special case. We don't have to bother about resizing the zone, but we might have to join surrounding zones if they contain the same values.
                        zone.ID = value;

                        bool leftOk = (index > 0 && zones[index-1].ID == value);
                        bool rightOk = (index+1 < zones.Length && zones[index+1].ID == value);
                        if ( leftOk && !rightOk ) {
                            // Left equals us, but not the right... Just remove this block (it is joined with the left, left.X remains valid).
                            list = new IDZone[zones.Length-1];
                            Array.Copy( zones, 0, list, 0, index );
                            Array.Copy( zones, index+1, list, index, zones.Length-index-1 );
                            zones = list;
                        }
                        else if ( !leftOk && rightOk ) {
                            // Right equals us, but not the left... Keep this block, and remove the right (as our X remains valid)
                            list = new IDZone[zones.Length-1];
                            Array.Copy( zones, 0, list, 0, index+1 );
                            Array.Copy( zones, index+2, list, index+1, zones.Length-index-2 );
                            zones = list;
                        }
                        else if ( leftOk && rightOk ) {
                            // Both left and right equal us. Move all three into one block (keep left, as it's X remains valid)
                            list = new IDZone[zones.Length-2];
                            Array.Copy( zones, 0, list, 0, index );
                            Array.Copy( zones, index+2, list, index, zones.Length-index-2 );
                            zones = list;
                        }
                        else {
                            // None of the blocks beside us are equal. Simplest case, just change the value!
                            zones[index].ID = value;
                        }

                        return;
                    }

                    // Okay, our zone is longer than 1 pixel. Is it...
                    // ... At the start of this zone?
                    if ( x == zone.X ) {
                        // Yes, check if previous zone exists and if it has the same value...
                        if ( index == 0 || zones[index-1].ID != value ) {
                            // Nope, create a new zonelist in a temporary array, and place the new zone at the correct place
                            list = new IDZone[zones.Length+1];
                            Array.Copy( zones, 0, list, 0, index );
                            list[index] = new IDZone( x, value );
                            Array.Copy( zones, index, list, index+1, zones.Length-index );
                            // Assign new array
                            zones = list;
                            // Move index
                            ++index;
                        }

                        // Then, shorten this zone
                        zones[index].X += 1;
                        return;
                    }

                    // Not at the start, maybe at the end?
                    if ( x == zone.X+length-1 ) {
                        // Yeps, check if next zone exists and if it has the same value
                        if ( index+1 < zones.Length && zones[index+1].ID == value ) {
                            // Yes... Lengthen
                            zones[index+1].X -= 1;
                        }
                        else {
                            // Nope, create a new zonelist in a temporary array, and place the new zone at the correct place
                            list = new IDZone[zones.Length+1];
                            if ( index+1 == zones.Length ) {
                                // We're at the end, just copy the list and add the proc behind
                                zones.CopyTo( list, 0 );
                            }
                            else {
                                Array.Copy( zones, 0, list, 0, index+1 );
                                Array.Copy( zones, index+1, list, index+2, zones.Length-index-1 );
                                // Assign new array
                            }
                            list[index+1] = new IDZone( x, value );
                            zones = list;
                        }

                        return;
                    }

                    // So, somewhere in the middle. Split the zone in three.
                    IDZone left = new IDZone( zone.X, zone.ID );
                    IDZone right = new IDZone( x+1, zone.ID );
                    zone = new IDZone( x, value );

                    list = new IDZone[zones.Length+2];
                    Array.Copy( zones, 0, list, 0, index );
                    list[index] = left;
                    list[index+1] = zone;
                    list[index+2] = right;
                    Array.Copy( zones, index+1, list, index+3, zones.Length-index-1 );

                    zones = list;
                }
            }
Beispiel #4
0
            public void ImportBitmapBuffer( int[] buffer, int bufstart, int bufwidth, int left, int right )
            {
                ArrayList newZones = new ArrayList( bufwidth/8 );
                bufwidth += bufstart;

                IDZone currentZone = new IDZone( left, buffer[bufstart] );
                for ( int bx = bufstart+1, px = left+1; bx<bufwidth; ++bx, ++px ) {
                    if ( buffer[bx] != currentZone.ID ) {
                        // ID changes, so add this zone and start a new one
                        newZones.Add( currentZone );
                        currentZone = new IDZone( px, buffer[bx] );
                    }
                }
                // Add last zone
                newZones.Add( currentZone );

                int leftindex = LookupZoneIndex( left );
                int rightindex = LookupZoneIndex( right );

                //System.Diagnostics.Debug.Assert( leftindex <= rightindex, "invalid left/right index" );

                if ( zones[rightindex].ID == ((IDZone)newZones[newZones.Count-1]).ID ) {
                    // If the last new zone equals the original right zone, we can safely drop the original right zone.
                    // That means that rightindex is included in the "to be removed" area.
                    ++rightindex;
                }
                else if ( leftindex < rightindex ) {
                    // Otherwise, we'll have to adjust the X value of that original right zone, and shift
                    // rightindex one to the left.
                    zones[rightindex].X = (short)right;
                }
                else {
                    newZones.Add( new IDZone( right, zones[rightindex].ID ) );
                    ++rightindex;
                }

                if ( zones[leftindex].ID == ((IDZone)newZones[0]).ID ) {
                    // If the first new zone equals the original left zone, we'll need to adjust the first zone.
                    IDZone tmp = ((IDZone)newZones[0]);
                    tmp.X = zones[leftindex].X;
                    newZones[0] = tmp;
                }
                else {
                    // Otherwise, we start at the next zone, but only if the previous zone is different.
                    if ( leftindex > 0 && zones[leftindex-1].ID == ((IDZone)newZones[0]).ID ) {
                        newZones.RemoveAt( 0 );
                    }
                    else if ( zones[leftindex].X != ((IDZone)newZones[0]).X ) {
                        ++leftindex;
                    }
                }

                // leftindex and rightindex now define the bounds of the zones we need to get rid of
                int nzi = 0;
                for ( int zi=leftindex; zi<rightindex; ++zi ) {
                    if ( nzi < newZones.Count ) {
                        // we have new zones left, copy one over
                        zones[zi] = (IDZone)newZones[nzi++];
                    }
                    else {
                        // no more new zones left, shift the rest of the bunch to the left
                        for ( int shift=0; shift < zones.Length-rightindex; ++shift ) {
                            zones[zi+shift] = zones[rightindex+shift];
                        }
                        // Resize the array
                        IDZone[] zones2 = new IDZone[zi+zones.Length-rightindex];
                        Array.Copy( zones, 0, zones2, 0, zones2.Length );
                        zones = zones2;
                        break;
                    }
                }
                if ( nzi < newZones.Count ) {
                    // We still need to copy some
                    IDZone[] zones2 = new IDZone[zones.Length+newZones.Count-nzi];
                    Array.Copy( zones, 0, zones2, 0, rightindex );
                    Array.Copy( zones, rightindex, zones2, rightindex+newZones.Count-nzi, zones.Length-rightindex );

                    while ( nzi < newZones.Count ) {
                        zones2[rightindex++] = (IDZone)newZones[nzi++];
                    }
                    zones = zones2;
                }
            }
Beispiel #5
0
 public Scanline( ushort zero, IDZone[] zones )
 {
     this.zones = new IDZone[zones.Length];
     Array.Copy( zones, 0, this.zones, 0, zones.Length );
     zeroId = zero;
 }