home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-03-10 | 6.6 KB | 270 lines | [TEXT/BROW] |
- //
- // File: update.c
- //
- // This file contains routines to manage the update from the offscreen to the screen.
- //
- // 2/19/95 -- Created by Mick
- //
-
- // include files
-
- #include "global.h"
-
- #include "update.h"
-
- // defines for this file
-
- #define kMaxRects 10 // the maximum number of update rects
- #define kInitialRects 10 // the initial number of update rects
-
- // global function declarations
-
- void clearUpdate( void );
- void addRectToUpdate( Rect *inUpdateRect );
- unsigned long getUpdateRectCount( void );
- void getUpdateRect( unsigned long inRectIndex, Rect *outUpdateRect );
- void increaseUpdateRects( void );
- void decreaseUpdateRects( void );
-
- // global data owned by this file
-
- // local function declarations
-
- static void adjustRect( Rect *ioRect );
-
- // static data
-
- static sNumUpdateRects = kInitialRects; // the number of update rects
- static Rect sUpdateRects[ kMaxRects ]; // the rects that needs to be udpated
- static unsigned long sUpdateRectCount; // how many update rects are there
-
- // functions
-
-
- //
- // clearUpdate -
- //
- // Reset the update area to none.
- //
-
- void clearUpdate( void )
- {
- // note that there are no update rects
- sUpdateRectCount = 0;
- }
-
-
- //
- // addRectToUpdate -
- //
- // Adds a rect to the update area.
- //
-
- void addRectToUpdate( Rect *inUpdateRect )
- {
- Rect newRect; // the rect we are adding
- unsigned long indexCounter; // a counter to scan the rect array
- unsigned char xTouch; // do the rects intersect horizontally
- unsigned char yTouch; // do the rects intersect vertically
- unsigned long bestIndex; // the index of our best canidate rect
- unsigned long bestArea; // the area of our best canidate rect
- unsigned long scratchArea; // a temp area for calculations
- Rect scratchRect; // a temp rect for calculations
- Rect bestRect; // the best rect so far
-
- // adjust the rect to 32 bit bounds
- newRect = *inUpdateRect;
- adjustRect( &newRect );
-
- // scan the list and see if the rect touches any of the rects there
- for( indexCounter = 0; indexCounter < sUpdateRectCount; indexCounter++ )
- {
- // do the rects touch?
-
- // check horizontally
- if ( newRect.left < sUpdateRects[ indexCounter ].left )
- {
- if ( newRect.right >= sUpdateRects[ indexCounter ].left )
- {
- xTouch = kTrue;
- }
- else
- {
- xTouch = kFalse;
- }
- }
- else
- {
- if ( sUpdateRects[ indexCounter ].right >= newRect.left )
- {
- xTouch = kTrue;
- }
- else
- {
- xTouch = kFalse;
- }
- }
-
- // check vertically
- if ( newRect.top < sUpdateRects[ indexCounter ].top )
- {
- if ( newRect.bottom >= sUpdateRects[ indexCounter ].top )
- {
- yTouch = kTrue;
- }
- else
- {
- yTouch = kFalse;
- }
- }
- else
- {
- if ( sUpdateRects[ indexCounter ].bottom >= newRect.top )
- {
- yTouch = kTrue;
- }
- else
- {
- yTouch = kFalse;
- }
- }
-
- // if the rects do touch,
- if ( yTouch && xTouch )
- {
- // join the rects into new rect
- newRect.left = ( newRect.left < sUpdateRects[ indexCounter ].left ) ? newRect.left : sUpdateRects[ indexCounter ].left;
- newRect.top = ( newRect.top < sUpdateRects[ indexCounter ].top ) ? newRect.top : sUpdateRects[ indexCounter ].top;
- newRect.right = ( newRect.right > sUpdateRects[ indexCounter ].right ) ? newRect.right : sUpdateRects[ indexCounter ].right;
- newRect.bottom = ( newRect.bottom > sUpdateRects[ indexCounter ].bottom ) ? newRect.bottom : sUpdateRects[ indexCounter ].bottom;
-
- // remove the rect from the list
- sUpdateRectCount -= 1;
- for( ; indexCounter < sUpdateRectCount; indexCounter++ )
- {
- // shift the next rects down
- sUpdateRects[ indexCounter ] = sUpdateRects[ indexCounter + 1 ];
- }
-
- // call this routine with the new, joined rect
- addRectToUpdate( &newRect );
-
- // we are done
- return;
- }
- }
-
- // if there is room, add this rect to the list
- if ( sUpdateRectCount < sNumUpdateRects )
- {
- sUpdateRects[ sUpdateRectCount ] = newRect;
- sUpdateRectCount++;
- }
- else
- {
- // otherwise find the rect where the union is the smallest
- bestIndex = 0;
- bestArea = 0xFFFFFFFF; // a very big area
- for( indexCounter = 0; indexCounter < sUpdateRectCount; indexCounter++ )
- {
- // create the unified rect
- scratchRect.left = ( newRect.left < sUpdateRects[ indexCounter ].left ) ? newRect.left : sUpdateRects[ indexCounter ].left;
- scratchRect.top = ( newRect.top < sUpdateRects[ indexCounter ].top ) ? newRect.top : sUpdateRects[ indexCounter ].top;
- scratchRect.right = ( newRect.right > sUpdateRects[ indexCounter ].right ) ? newRect.right : sUpdateRects[ indexCounter ].right;
- scratchRect.bottom = ( newRect.bottom > sUpdateRects[ indexCounter ].bottom ) ? newRect.bottom : sUpdateRects[ indexCounter ].bottom;
-
- // determine how much this will grow the rect
- scratchArea = ( scratchRect.right - scratchRect.left ) * ( scratchRect.bottom - scratchRect.top ) -
- ( sUpdateRects[ indexCounter ].right - sUpdateRects[ indexCounter ].left ) *
- ( sUpdateRects[ indexCounter ].bottom - sUpdateRects[ indexCounter ].top );
-
- // if this area is smaller than the best so far, keep it
- if ( scratchArea < bestArea )
- {
- bestArea = scratchArea;
- bestIndex = indexCounter;
- bestRect = scratchRect;
- }
- }
-
- // save our best canidate
- sUpdateRects[ bestIndex ] = bestRect;
- }
- }
-
-
- //
- // getUpdateRectCount -
- //
- // Get the number of update rects.
- //
-
- unsigned long getUpdateRectCount( void )
- {
- return sUpdateRectCount;
- }
-
-
- //
- // getUpdateRect -
- //
- // Return the update rect specified.
- //
-
- void getUpdateRect( unsigned long inRectIndex, Rect *outUpdateRect )
- {
- // return the correct rect
- *outUpdateRect = sUpdateRects[ inRectIndex ];
- }
-
-
- //
- // increaseUpdateRects -
- //
- // Increase the number of update rects. Never go above kMaxRects.
- //
-
- void increaseUpdateRects( void )
- {
- // make sure that we are not already at the maximum
- if ( sNumUpdateRects == kMaxRects )
- {
- return;
- }
-
- // increase the number
- sNumUpdateRects++;
- }
-
-
- //
- // decreaseUpdateRects -
- //
- // Decrease the number of update rects. Never go below 1.
- //
-
- void decreaseUpdateRects( void )
- {
- // make sure that we are not already at the minumum
- if ( sNumUpdateRects == 1 )
- {
- return;
- }
-
- // increase the number
- sNumUpdateRects--;
- }
-
-
- //
- // adjustRect -
- //
- // Move the left and right sides to 32 bit boundrys. This will speed up CopyBits.
- //
-
- void adjustRect( Rect *ioRect )
- {
- // expand the rect so its horizontal sides are on 32 bit bounds
- ioRect->left = ioRect->left & 0xfffC;
- ioRect->right = ( ioRect->right + 3 ) & 0xfffC;
- }