home *** CD-ROM | disk | FTP | other *** search
- /* -----------------------------------------------------------------------------------
- -----------------------------------------------------------------------------------
- BlitPixieScaled8Bit.c
-
- by Brian Roddy, 5/31/97
-
- Bug fixes by Vern Jensen, 12/7/98. Optimizations by Vern Jensen 2/7/99.
-
- These routines are 8-bit and 16-bit blitters that dynamically shrink or
- stretch the sprite.
-
- Use SWSetSpriteScaledSize to set the scaling size. When the sprite is drawn, it
- will be stretched or shrunk to the new width and height you specify.
- SWSetSpriteScaledSize takes a sprite pointer and a width and a height. e.g.:
-
- SWSetSpriteScaledSize(mySpritePtr, 20, 50); // Scale it
-
- Use a width or height <= 0 to turn off scaling. Note that just resetting
- the sprite's draw procedure will not turn off scaling properly. Make sure to
- call SWSetSpriteScaledSize with a negative width or height. e.g.:
-
- SWSetSpriteScaledSize(mySpritePtr, -1, -1); // Reset it back to normal
-
- The maximum scaled width is 800. Values larger than this are permissible as long as the Sprite
- is clipped so that the visible portion of the Sprite after being clipped is no larger than 800.
- For instance, if your SpriteWorld's window is 800 pixels wide and your Sprites are clipped
- to that window, then your may scale your Sprites larger than 800 pixels. Otherwise, you will
- get an assertion error if you try to scale them larger. You can get around this limitation
- if necessary; simply change the definition of kMaxScaledWidth at the beginning of
- BlitPixieScaled.c to any value, and your Sprites can then be scaled to that maximum size.
- There is no maximum scaled height; your height can be any size.
-
- Also note that scaling is done while drawing to the screen. As a result, the
- pixels in the frames don't match what shows up on the screen. This means that
- functions which rely on the sprite's mask, such as SWPixelCollision, won't work as
- expected. Thus using the pixel or mask collision routines with scaled sprites
- won't work accurately.
-
- SWSetSpriteScaledSize sets the scaling DrawProc for you automatically, so you don't
- need to call SWSetSpriteDrawProc, unless you want to use a RectDrawProc instead of the
- automatically assigned ScaledMaskDrawProc. It will also change the DrawProc back to one
- of the standard BlitPixieMaskDrawProcs when you set the scaled size to -1 to turn off
- scaling. Here is a list of the available DrawProcs:
-
- // User DrawProcs:
- BlitPixie8BitScaledRectDrawProc
- BlitPixie16BitScaledRectDrawProc
-
- // Sprite DrawProcs:
- BP8BitScaledSpriteRectDrawProc
- BP8BitScaledSpriteMaskDrawProc
- BP16BitScaledSpriteRectDrawProc
- BP16BitScaledSpriteMaskDrawProc
-
- The User DrawProcs are available for you to use directly if you want to do some direct
- scaling, such as scaling the contents of the work area as you copy it to the screen.
- The Sprite DrawProcs are what you should use when assigning a Sprite a scaling
- DrawProc. Do not get these two types of DrawProcs mixed up.
-
-
- -----------------------------------------------------------------------------------
- Implementation Notes:
-
- These blitters use the "Bresenham line drawing algorithm" to do the scaling. This is
- the standard technique used for many scaling and texture mapping algorithms. Additionally,
- the scaling data is pre-computed and stored in an array to speed up each line. In particular,
- this allows much faster blitting of shrunk Sprites, clipped Sprites, and direct-to-screen
- scaling.
-
- This source code is available for free use.
-
- -----------------------------------------------------------------------------------
- ----------------------------------------------------------------------------------- */
-
-
- #include "BlitPixieScaled.h"
-
- #define kMaxScaledWidth 800 // Change this to a larger value if necessary
-
- // The following variables are used by PrecomputeLookupTable
- static short gSrcLeftClip,
- gNumPixelsToCopy;
- static unsigned short gLookupArray[kMaxScaledWidth]; // Note: change this to a short
- // instead of a char to avoid the
- // 255 src pixels to 1 dst pixel
- // ratio limit mentioned in the
- // docs. Other code that creates
- // a pointer to this array must
- // be changed as well.
-
-
- #pragma mark ----------- Public API -------------
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteScaledSize
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetSpriteScaledSize(
- SpritePtr srcSpriteP,
- short width,
- short height)
- {
- short currentPixelDepth;
- OSErr err = noErr;
-
-
- currentPixelDepth = (*srcSpriteP->frameArray[0]->framePort->portPixMap)->pixelSize;
-
- if (currentPixelDepth == 8)
- {
- if ((width <= 0) || (height <= 0))
- {
- srcSpriteP->scaledWidth = -1;
- srcSpriteP->scaledHeight = -1;
- srcSpriteP->frameDrawProc = BlitPixie8BitMaskDrawProc;
- }
- else
- {
- srcSpriteP->scaledWidth = width;
- srcSpriteP->scaledHeight = height;
- srcSpriteP->frameDrawProc = BP8BitScaledSpriteMaskDrawProc;
- }
- }
- else if (currentPixelDepth == 16)
- {
- if ((width <= 0) || (height <= 0))
- {
- srcSpriteP->scaledWidth = -1;
- srcSpriteP->scaledHeight = -1;
- srcSpriteP->frameDrawProc = BlitPixieAllBitMaskDrawProc;
- }
- else
- {
- srcSpriteP->scaledWidth = width;
- srcSpriteP->scaledHeight = height;
- srcSpriteP->frameDrawProc = BP16BitScaledSpriteMaskDrawProc;
- }
- }
- else
- {
- err = kWrongDepthErr;
- }
-
- if (err == noErr)
- {
- // Force a refresh of the sprite in the case of sprites with one frame
- SWSetCurrentFrameIndex(srcSpriteP, srcSpriteP->curFrameIndex);
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
- ///--------------------------------------------------------------------------------------
- // SWGetSpriteScaledWidth
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC short SWGetSpriteScaledWidth(
- SpritePtr srcSpriteP)
- {
- return srcSpriteP->scaledWidth;
- }
-
- ///--------------------------------------------------------------------------------------
- // SWGetSpriteScaledHeight
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC short SWGetSpriteScaledHeight(
- SpritePtr srcSpriteP)
- {
- return srcSpriteP->scaledHeight;
- }
-
-
-
- ///--------------------------------------------------------------------------------------
- /// BLITTERS
- ///--------------------------------------------------------------------------------------
-
- extern SInt8 gSWmmuMode;
- extern SpritePtr gCurrentSpriteBeingDrawn;
-
-
- #pragma mark ----------- 8 Bit Blitters -------------
- ///--------------------------------------------------------------------------------------
- // BlitPixie8BitScaledRectDrawProc - doesn't "unclip" the source rect, so it
- // can be used directly by the user.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BlitPixie8BitScaledRectDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect* srcRect,
- Rect* dstRect)
- {
- Rect srcBlitRect = *srcRect;
- Rect dstBlitRect = *dstRect;
- short topClip, rightClip, bottomClip, leftClip;
-
- SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
- SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
-
- // Make sure some part of the Sprite is inside the dstFrame
- if (dstBlitRect.left >= dstFrameP->frameRect.right ||
- dstBlitRect.right <= dstFrameP->frameRect.left ||
- dstBlitRect.top >= dstFrameP->frameRect.bottom ||
- dstBlitRect.bottom <= dstFrameP->frameRect.top )
- {
- return;
- }
-
- topClip = rightClip = bottomClip = leftClip = 0;
-
- // Clip dstRect with dstFrameP->frameRect
- if (dstBlitRect.top < dstFrameP->frameRect.top)
- {
- topClip = dstFrameP->frameRect.top - dstBlitRect.top;
- dstBlitRect.top = dstFrameP->frameRect.top;
- }
-
- if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)
- bottomClip = dstBlitRect.bottom - dstFrameP->frameRect.bottom;
-
- if (dstBlitRect.left < dstFrameP->frameRect.left)
- leftClip = dstFrameP->frameRect.left - dstBlitRect.left;
-
- if (dstBlitRect.right > dstFrameP->frameRect.right)
- rightClip = dstBlitRect.right - dstFrameP->frameRect.right;
-
- START_32_BIT_MODE
-
- PrecomputeLookupTable(
- (srcBlitRect.right - srcBlitRect.left),
- (dstBlitRect.right - dstBlitRect.left),
- leftClip,
- rightClip);
-
-
- BlitPixie8BitScaled(
- // calculate the address of the first byte of the source
- (unsigned char *)(srcFrameP->frameBaseAddr +
- (srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top]) +
- srcBlitRect.left),
-
- // calculate the address of the first byte of the destination
- (unsigned char *)(dstFrameP->frameBaseAddr +
- (dstFrameP->scanLinePtrArray[dstBlitRect.top]) +
- dstBlitRect.left),
-
- // calculate the number of rows to blit
- (srcBlitRect.bottom - srcBlitRect.top),
- (dstBlitRect.bottom - dstBlitRect.top) + topClip,
-
- srcFrameP->frameRowBytes,
- dstFrameP->frameRowBytes,
-
- // clipping information
- leftClip,
- topClip,
- bottomClip,
-
- // are we blitting direct-to-screen?
- dstFrameP->isWindowFrame
- );
-
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BP8BitScaledSpriteRectDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BP8BitScaledSpriteRectDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect* srcRect,
- Rect* dstRect)
- {
- Rect srcBlitRect = *srcRect;
- Rect dstBlitRect = *dstRect;
- short topClip, rightClip, bottomClip, leftClip;
- short topClip2, rightClip2, bottomClip2, leftClip2;
-
- SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
- SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
-
- // Make sure some part of the Sprite is inside the dstFrame
- if (dstBlitRect.left >= dstFrameP->frameRect.right ||
- dstBlitRect.right <= dstFrameP->frameRect.left ||
- dstBlitRect.top >= dstFrameP->frameRect.bottom ||
- dstBlitRect.bottom <= dstFrameP->frameRect.top )
- {
- return;
- }
-
- topClip = rightClip = bottomClip = leftClip = 0;
- topClip2 = rightClip2 = bottomClip2 = leftClip2 = 0;
-
- // Clip dstRect with dstFrameP->frameRect
- if (dstBlitRect.top < dstFrameP->frameRect.top)
- {
- topClip = dstFrameP->frameRect.top - dstBlitRect.top;
- dstBlitRect.top = dstFrameP->frameRect.top;
- }
-
- if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)
- bottomClip = dstBlitRect.bottom - dstFrameP->frameRect.bottom;
-
- if (dstBlitRect.left < dstFrameP->frameRect.left)
- leftClip = dstFrameP->frameRect.left - dstBlitRect.left;
-
- if (dstBlitRect.right > dstFrameP->frameRect.right)
- rightClip = dstBlitRect.right - dstFrameP->frameRect.right;
-
-
- // "Unclip" sprite if it was already clipped before this function was called
- if (srcBlitRect.top > srcFrameP->frameRect.top)
- {
- topClip2 = srcBlitRect.top - srcFrameP->frameRect.top;
- srcBlitRect.top = srcFrameP->frameRect.top;
- }
-
- if (srcBlitRect.bottom < srcFrameP->frameRect.bottom)
- {
- bottomClip2 = srcFrameP->frameRect.bottom - srcBlitRect.bottom;
- srcBlitRect.bottom = srcFrameP->frameRect.bottom;
- dstBlitRect.bottom += bottomClip2;
- }
-
- if (srcBlitRect.left > srcFrameP->frameRect.left)
- {
- leftClip2 = srcBlitRect.left - srcFrameP->frameRect.left;
- srcBlitRect.left = srcFrameP->frameRect.left;
- dstBlitRect.left -= leftClip2;
- }
-
- if (srcBlitRect.right < srcFrameP->frameRect.right)
- {
- rightClip2 = srcFrameP->frameRect.right - srcBlitRect.right;
- srcBlitRect.right = srcFrameP->frameRect.right;
- dstBlitRect.right += rightClip2;
- }
-
- topClip += topClip2;
- leftClip += leftClip2;
- rightClip += rightClip2;
- bottomClip += bottomClip2;
-
-
- START_32_BIT_MODE
-
- PrecomputeLookupTable(
- (srcBlitRect.right - srcBlitRect.left),
- (dstBlitRect.right - dstBlitRect.left),
- leftClip,
- rightClip);
-
-
- BlitPixie8BitScaled(
- // calculate the address of the first byte of the source
- (unsigned char *)(srcFrameP->frameBaseAddr +
- (srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top]) +
- srcBlitRect.left),
-
- // calculate the address of the first byte of the destination
- (unsigned char *)(dstFrameP->frameBaseAddr +
- (dstFrameP->scanLinePtrArray[dstBlitRect.top]) +
- dstBlitRect.left),
-
- // calculate the number of rows to blit
- (srcBlitRect.bottom - srcBlitRect.top),
- (dstBlitRect.bottom - dstBlitRect.top) + topClip,
-
- srcFrameP->frameRowBytes,
- dstFrameP->frameRowBytes,
-
- // clipping information
- leftClip,
- topClip,
- bottomClip,
-
- // are we blitting direct-to-screen?
- dstFrameP->isWindowFrame
- );
-
-
- END_32_BIT_MODE
- }
-
- ///--------------------------------------------------------------------------------------
- // BP8BitScaledSpriteMaskDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BP8BitScaledSpriteMaskDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect *srcRect,
- Rect *dstRect)
- {
- Rect dstBlitRect = *dstRect;
- Rect srcBlitRect = *srcRect;
- unsigned long srcBaseOffset;
- short topClip, rightClip, bottomClip, leftClip;
- short topClip2, rightClip2, bottomClip2, leftClip2;
-
- SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
- SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
- SW_ASSERT(srcFrameP->maskPort != NULL);
-
- // Make sure some part of the Sprite is inside the dstFrame
- if (dstBlitRect.left >= dstFrameP->frameRect.right ||
- dstBlitRect.right <= dstFrameP->frameRect.left ||
- dstBlitRect.top >= dstFrameP->frameRect.bottom ||
- dstBlitRect.bottom <= dstFrameP->frameRect.top )
- {
- return;
- }
-
- topClip = rightClip = bottomClip = leftClip = 0;
- topClip2 = rightClip2 = bottomClip2 = leftClip2 = 0;
-
- // Clip dstRect with dstFrameP->frameRect
- if (dstBlitRect.top < dstFrameP->frameRect.top)
- {
- topClip = dstFrameP->frameRect.top - dstBlitRect.top;
- dstBlitRect.top = dstFrameP->frameRect.top;
- }
-
- if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)
- bottomClip = dstBlitRect.bottom - dstFrameP->frameRect.bottom;
-
- if (dstBlitRect.left < dstFrameP->frameRect.left)
- leftClip = dstFrameP->frameRect.left - dstBlitRect.left;
-
- if (dstBlitRect.right > dstFrameP->frameRect.right)
- rightClip = dstBlitRect.right - dstFrameP->frameRect.right;
-
-
- // "Unclip" sprite if it was already clipped before this function was called
- if (srcBlitRect.top > srcFrameP->frameRect.top)
- {
- topClip2 = srcBlitRect.top - srcFrameP->frameRect.top;
- srcBlitRect.top = srcFrameP->frameRect.top;
- }
-
- if (srcBlitRect.bottom < srcFrameP->frameRect.bottom)
- {
- bottomClip2 = srcFrameP->frameRect.bottom - srcBlitRect.bottom;
- srcBlitRect.bottom = srcFrameP->frameRect.bottom;
- dstBlitRect.bottom += bottomClip2;
- }
-
- if (srcBlitRect.left > srcFrameP->frameRect.left)
- {
- leftClip2 = srcBlitRect.left - srcFrameP->frameRect.left;
- srcBlitRect.left = srcFrameP->frameRect.left;
- dstBlitRect.left -= leftClip2;
- }
-
- if (srcBlitRect.right < srcFrameP->frameRect.right)
- {
- rightClip2 = srcFrameP->frameRect.right - srcBlitRect.right;
- srcBlitRect.right = srcFrameP->frameRect.right;
- dstBlitRect.right += rightClip2;
- }
-
- topClip += topClip2;
- leftClip += leftClip2;
- rightClip += rightClip2;
- bottomClip += bottomClip2;
-
-
- // Cache this value since it's used twice
- srcBaseOffset = (srcFrameP->scanLinePtrArray[srcBlitRect.top -
- srcFrameP->frameRect.top]) + srcBlitRect.left;
-
- START_32_BIT_MODE
-
- PrecomputeLookupTable(
- (srcBlitRect.right - srcBlitRect.left),
- (dstBlitRect.right - dstBlitRect.left),
- leftClip,
- rightClip);
-
-
- BlitPixieMask8BitScaled(
- // calculate the address of the first byte of the source
- (unsigned char *)(srcFrameP->frameBaseAddr + srcBaseOffset),
-
- // calculate the address of the first byte of the destination
- (unsigned char *)(dstFrameP->frameBaseAddr +
- (dstFrameP->scanLinePtrArray[dstBlitRect.top]) +
- dstBlitRect.left),
-
- // calculate the address of the first byte of the mask
- (unsigned char *)(srcFrameP->maskBaseAddr + srcBaseOffset),
-
- // calculate the number of rows to blit
- (srcBlitRect.bottom - srcBlitRect.top),
- (dstBlitRect.bottom - dstBlitRect.top) + topClip,
-
- srcFrameP->frameRowBytes,
- dstFrameP->frameRowBytes,
-
- // clipping information
- leftClip,
- topClip,
- bottomClip,
-
- // are we blitting direct-to-screen?
- dstFrameP->isWindowFrame
- );
-
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BlitPixie8BitScaled
- ///--------------------------------------------------------------------------------------
-
- void BlitPixie8BitScaled(
- register unsigned char *srcPixelP,
- register unsigned char *dstPixelP,
- long srcRowsToCopy,
- long dstRowsToCopy,
- unsigned long srcOffset,
- unsigned long dstOffset,
- short leftClip,
- short topClip,
- short bottomClip,
- Boolean isBlittingToScreen)
- {
- register unsigned char *startSrcPixelP;
- register unsigned char *startDstPixelP;
- long verticalEps;
- short curRow, numRowsToCopy;
-
- startSrcPixelP = srcPixelP;
- startDstPixelP = dstPixelP;
-
- if (srcRowsToCopy >= dstRowsToCopy)
- verticalEps = srcRowsToCopy / 2;
- else
- verticalEps = -dstRowsToCopy / 2;
-
- // Clip off the top if necessary
- for (curRow = 0; curRow < topClip; curRow++)
- {
- if (srcRowsToCopy >= dstRowsToCopy)
- {
- while ((verticalEps * 2) <= srcRowsToCopy)
- {
- // shrink
- startSrcPixelP += srcOffset;
- verticalEps += dstRowsToCopy;
- }
- verticalEps -= srcRowsToCopy;
- }
- else
- {
- // grow
- verticalEps += srcRowsToCopy;
- if ((verticalEps * 2) > dstRowsToCopy)
- {
- startSrcPixelP += srcOffset;
- verticalEps -= dstRowsToCopy;
- }
- }
- }
-
- // Handle the bottom clip
- numRowsToCopy = dstRowsToCopy - bottomClip;
-
- // Draw the thing
- for (; curRow < numRowsToCopy; curRow++)
- {
- BlitScaledLine8Bit(startSrcPixelP + gSrcLeftClip, startDstPixelP + leftClip,
- isBlittingToScreen);
-
- // bump to next row
- startDstPixelP += dstOffset;
-
- if (srcRowsToCopy >= dstRowsToCopy)
- {
- while ((verticalEps * 2) <= srcRowsToCopy)
- {
- // shrink
- startSrcPixelP += srcOffset;
- verticalEps += dstRowsToCopy;
- }
- verticalEps -= srcRowsToCopy;
- }
- else
- {
- // grow
- verticalEps += srcRowsToCopy;
- if ((verticalEps * 2) > dstRowsToCopy)
- {
- startSrcPixelP += srcOffset;
- verticalEps -= dstRowsToCopy;
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BlitPixieMask8BitScaled
- ///--------------------------------------------------------------------------------------
-
- void BlitPixieMask8BitScaled(
- register unsigned char *srcPixelP,
- register unsigned char *dstPixelP,
- register unsigned char *maskPixelP,
- long srcRowsToCopy,
- long dstRowsToCopy,
- unsigned long srcOffset,
- unsigned long dstOffset,
- short leftClip,
- short topClip,
- short bottomClip,
- short isBlittingToScreen)
- {
- register unsigned char *startSrcPixelP;
- register unsigned char *startDstPixelP;
- register unsigned char *startMaskPixelP;
- long verticalEps;
- short curRow, numRowsToCopy;
-
- startSrcPixelP = srcPixelP;
- startDstPixelP = dstPixelP;
- startMaskPixelP = maskPixelP;
-
- if (srcRowsToCopy >= dstRowsToCopy)
- verticalEps = srcRowsToCopy / 2;
- else
- verticalEps = -dstRowsToCopy / 2;
-
- // Clip off the top if necessary
- for (curRow = 0; curRow < topClip; curRow++)
- {
- if (srcRowsToCopy >= dstRowsToCopy) {
- while ((verticalEps * 2) <= srcRowsToCopy) {
- // shrink
- startSrcPixelP += srcOffset;
- startMaskPixelP += srcOffset;
- verticalEps += dstRowsToCopy;
- }
- verticalEps -= srcRowsToCopy;
- } else {
- // grow
- verticalEps += srcRowsToCopy;
- if ((verticalEps * 2) > dstRowsToCopy) {
- startSrcPixelP += srcOffset;
- startMaskPixelP += srcOffset;
- verticalEps -= dstRowsToCopy;
- }
- }
- }
-
- // Handle the bottom clip
- numRowsToCopy = dstRowsToCopy - bottomClip;
-
- // Draw the thing
- for (; curRow < numRowsToCopy; curRow++)
- {
- BlitScaledMaskedLine8Bit(startSrcPixelP + gSrcLeftClip, startMaskPixelP + gSrcLeftClip,
- startDstPixelP + leftClip, isBlittingToScreen);
-
- // bump to next row
- startDstPixelP += dstOffset;
-
- if (srcRowsToCopy >= dstRowsToCopy) {
- while ((verticalEps * 2) <= srcRowsToCopy) {
- // shrink
- startSrcPixelP += srcOffset;
- startMaskPixelP += srcOffset;
- verticalEps += dstRowsToCopy;
- }
- verticalEps -= srcRowsToCopy;
- } else {
- // grow
- verticalEps += srcRowsToCopy;
- if ((verticalEps * 2) > dstRowsToCopy) {
- startSrcPixelP += srcOffset;
- startMaskPixelP += srcOffset;
- verticalEps -= dstRowsToCopy;
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BlitScaledLine8Bit - it makes it slightly faster on 68k Macs to put this code in its
- // own function, instead of placing it directly in BlitPixie8BitScaled. It goes the same
- // speed on PPC. This must be because we're "breaking the cache" on 68k Macs otherwise.
- ///--------------------------------------------------------------------------------------
-
- void BlitScaledLine8Bit(
- register unsigned char *srcPixelP,
- register unsigned char *dstPixelP,
- Boolean weAreBlittingToScreen)
- {
- register unsigned short *lookupArrayP;
- short numPixelsToCopy;
-
- lookupArrayP = gLookupArray;
-
- numPixelsToCopy = gNumPixelsToCopy;
-
- // The following code speeds up both 68k and PPC Macs when blitting directly to the
- // screen, as well as 68k Macs slightly when blitting offscreen. (But not PPC
- // when blitting offscreen)
- if (weAreBlittingToScreen || !SW_PPC)
- {
- unsigned long srcBuffer;
- register unsigned char *srcBufferPixelP;
-
- while (numPixelsToCopy >= 4)
- {
- // Get char pointer to our 4-byte buffer
- srcBufferPixelP = (unsigned char *)&srcBuffer;
-
- // Load 1st pixel into buffer
- srcPixelP += *lookupArrayP;
- *srcBufferPixelP++ = *srcPixelP;
- lookupArrayP++;
-
- // Load 2nd pixel into buffer
- srcPixelP += *lookupArrayP;
- *srcBufferPixelP++ = *srcPixelP;
- lookupArrayP++;
-
- // Load 3rd pixel into buffer
- srcPixelP += *lookupArrayP;
- *srcBufferPixelP++ = *srcPixelP;
- lookupArrayP++;
-
- // Load 4th pixel into buffer
- srcPixelP += *lookupArrayP;
- *srcBufferPixelP++ = *srcPixelP;
- lookupArrayP++;
-
- // Copy from our 4-byte buffer to the destination
- *((unsigned long *) dstPixelP)++ = srcBuffer;
-
- numPixelsToCopy -= 4;
- }
- }
-
-
- // This code draws the rest of the line that was not handled above on 68k Macs,
- // or it draws the entire line on PowerMacs.
- while (numPixelsToCopy--)
- {
- srcPixelP += *lookupArrayP;
- lookupArrayP++;
-
- *dstPixelP = *srcPixelP;
- dstPixelP++;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BlitScaledMaskedLine8Bit - it makes it slightly faster on 68k Macs to put this code in its
- // own function, instead of placing it directly in BlitPixieMask8BitScaled. It goes the
- // same speed on PPC. This must be because we're "breaking the cache" on 68k Macs otherwise.
- ///--------------------------------------------------------------------------------------
-
- void BlitScaledMaskedLine8Bit(
- register unsigned char *srcPixelP,
- register unsigned char *maskPixelP,
- register unsigned char *dstPixelP,
- Boolean weAreBlittingToScreen)
- {
- register unsigned short *lookupArrayP;
- short numPixelsToCopy;
-
- lookupArrayP = gLookupArray;
-
- numPixelsToCopy = gNumPixelsToCopy;
-
- // The following code speeds up both 68k and PPC Macs when blitting directly to the
- // screen, as well as 68k Macs slightly when blitting offscreen. (But not PPC
- // when blitting offscreen)
- if (weAreBlittingToScreen || !SW_PPC)
- {
- unsigned long srcBuffer, maskBuffer;
- register unsigned char *srcBufferPixelP, *maskBufferPixelP;
- register unsigned long temp1;
-
- while (numPixelsToCopy >= 4)
- {
- // Get char pointers to our 4-byte buffers
- srcBufferPixelP = (unsigned char *)&srcBuffer;
- maskBufferPixelP = (unsigned char *)&maskBuffer;
-
- // Load 1st pixel into buffer
- srcPixelP += *lookupArrayP;
- maskPixelP += *lookupArrayP;
- *srcBufferPixelP++ = *srcPixelP;
- *maskBufferPixelP++ = *maskPixelP;
- lookupArrayP++;
-
- // Load 2nd pixel into buffer
- srcPixelP += *lookupArrayP;
- maskPixelP += *lookupArrayP;
- *srcBufferPixelP++ = *srcPixelP;
- *maskBufferPixelP++ = *maskPixelP;
- lookupArrayP++;
-
- // Load 3rd pixel into buffer
- srcPixelP += *lookupArrayP;
- maskPixelP += *lookupArrayP;
- *srcBufferPixelP++ = *srcPixelP;
- *maskBufferPixelP++ = *maskPixelP;
- lookupArrayP++;
-
- // Load 4th pixel into buffer
- srcPixelP += *lookupArrayP;
- maskPixelP += *lookupArrayP;
- *srcBufferPixelP = *srcPixelP;
- *maskBufferPixelP = *maskPixelP;
- lookupArrayP++;
-
- // Copy from our 4-byte buffer to the destination
- temp1 = *((unsigned long *) dstPixelP) & maskBuffer | srcBuffer;
- *((unsigned long *) dstPixelP)++ = temp1;
-
- numPixelsToCopy -= 4;
- }
- }
-
- // This code draws the rest of the line that was not handled above on 68k Macs,
- // or it draws the entire line on PowerMacs.
- while (numPixelsToCopy--)
- {
- srcPixelP += *lookupArrayP;
- maskPixelP += *lookupArrayP;
-
- if (*maskPixelP == 0)
- *dstPixelP = *srcPixelP;
-
- dstPixelP++;
- lookupArrayP++;
- }
- }
-
-
- #pragma mark ----------- 16 Bit Blitters -------------
-
- ///--------------------------------------------------------------------------------------
- // BlitPixie16BitScaledRectDrawProc - doesn't "unclip" the source rect, so it
- // can be used directly by the user.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BlitPixie16BitScaledRectDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect* srcRect,
- Rect* dstRect)
- {
- Rect srcBlitRect = *srcRect;
- Rect dstBlitRect = *dstRect;
- short topClip, rightClip, bottomClip, leftClip;
-
- SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
- SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 16);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 16);
-
- // Make sure some part of the Sprite is inside the dstFrame
- if (dstBlitRect.left >= dstFrameP->frameRect.right ||
- dstBlitRect.right <= dstFrameP->frameRect.left ||
- dstBlitRect.top >= dstFrameP->frameRect.bottom ||
- dstBlitRect.bottom <= dstFrameP->frameRect.top )
- {
- return;
- }
-
- topClip = rightClip = bottomClip = leftClip = 0;
-
- // Clip dstRect with dstFrameP->frameRect
- if (dstBlitRect.top < dstFrameP->frameRect.top)
- {
- topClip = dstFrameP->frameRect.top - dstBlitRect.top;
- dstBlitRect.top = dstFrameP->frameRect.top;
- }
-
- if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)
- bottomClip = dstBlitRect.bottom - dstFrameP->frameRect.bottom;
-
- if (dstBlitRect.left < dstFrameP->frameRect.left)
- leftClip = dstFrameP->frameRect.left - dstBlitRect.left;
-
- if (dstBlitRect.right > dstFrameP->frameRect.right)
- rightClip = dstBlitRect.right - dstFrameP->frameRect.right;
-
-
- START_32_BIT_MODE
-
- PrecomputeLookupTable(
- (srcBlitRect.right - srcBlitRect.left),
- (dstBlitRect.right - dstBlitRect.left),
- leftClip,
- rightClip);
-
-
- BlitPixie16BitScaled(
- // calculate the address of the first byte of the source
- (unsigned short *)(srcFrameP->frameBaseAddr +
- (srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top]) +
- (srcBlitRect.left << 1)),
-
- // calculate the address of the first byte of the destination
- (unsigned short *)(dstFrameP->frameBaseAddr +
- (dstFrameP->scanLinePtrArray[dstBlitRect.top]) +
- (dstBlitRect.left << 1)),
-
- // calculate the number of rows to blit
- srcBlitRect.bottom - srcBlitRect.top,
- dstBlitRect.bottom - dstBlitRect.top + topClip,
-
- // for PPC, just frameRowBytes
- srcFrameP->frameRowBytes,
- dstFrameP->frameRowBytes,
-
- // clipping information
- leftClip,
- topClip,
- bottomClip,
-
- // are we blitting direct-to-screen?
- dstFrameP->isWindowFrame
- );
-
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BP16BitScaledSpriteRectDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BP16BitScaledSpriteRectDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect* srcRect,
- Rect* dstRect)
- {
- Rect srcBlitRect = *srcRect;
- Rect dstBlitRect = *dstRect;
- short topClip, rightClip, bottomClip, leftClip;
- short topClip2, rightClip2, bottomClip2, leftClip2;
-
- SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
- SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 16);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 16);
-
- // Make sure some part of the Sprite is inside the dstFrame
- if (dstBlitRect.left >= dstFrameP->frameRect.right ||
- dstBlitRect.right <= dstFrameP->frameRect.left ||
- dstBlitRect.top >= dstFrameP->frameRect.bottom ||
- dstBlitRect.bottom <= dstFrameP->frameRect.top )
- {
- return;
- }
-
- topClip = rightClip = bottomClip = leftClip = 0;
- topClip2 = rightClip2 = bottomClip2 = leftClip2 = 0;
-
- // Clip dstRect with dstFrameP->frameRect
- if (dstBlitRect.top < dstFrameP->frameRect.top)
- {
- topClip = dstFrameP->frameRect.top - dstBlitRect.top;
- dstBlitRect.top = dstFrameP->frameRect.top;
- }
-
- if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)
- bottomClip = dstBlitRect.bottom - dstFrameP->frameRect.bottom;
-
- if (dstBlitRect.left < dstFrameP->frameRect.left)
- leftClip = dstFrameP->frameRect.left - dstBlitRect.left;
-
- if (dstBlitRect.right > dstFrameP->frameRect.right)
- rightClip = dstBlitRect.right - dstFrameP->frameRect.right;
-
-
- // "Unclip" sprite if it was already clipped before this function was called
- if (srcBlitRect.top > srcFrameP->frameRect.top)
- {
- topClip2 = srcBlitRect.top - srcFrameP->frameRect.top;
- srcBlitRect.top = srcFrameP->frameRect.top;
- }
-
- if (srcBlitRect.bottom < srcFrameP->frameRect.bottom)
- {
- bottomClip2 = srcFrameP->frameRect.bottom - srcBlitRect.bottom;
- srcBlitRect.bottom = srcFrameP->frameRect.bottom;
- dstBlitRect.bottom += bottomClip2;
- }
-
- if (srcBlitRect.left > srcFrameP->frameRect.left)
- {
- leftClip2 = srcBlitRect.left - srcFrameP->frameRect.left;
- srcBlitRect.left = srcFrameP->frameRect.left;
- dstBlitRect.left -= leftClip2;
- }
-
- if (srcBlitRect.right < srcFrameP->frameRect.right)
- {
- rightClip2 = srcFrameP->frameRect.right - srcBlitRect.right;
- srcBlitRect.right = srcFrameP->frameRect.right;
- dstBlitRect.right += rightClip2;
- }
-
- topClip += topClip2;
- leftClip += leftClip2;
- rightClip += rightClip2;
- bottomClip += bottomClip2;
-
- START_32_BIT_MODE
-
- PrecomputeLookupTable(
- (srcBlitRect.right - srcBlitRect.left),
- (dstBlitRect.right - dstBlitRect.left),
- leftClip,
- rightClip);
-
-
- BlitPixie16BitScaled(
- // calculate the address of the first byte of the source
- (unsigned short *)(srcFrameP->frameBaseAddr +
- (srcFrameP->scanLinePtrArray[srcBlitRect.top - srcFrameP->frameRect.top]) +
- (srcBlitRect.left << 1)),
-
- // calculate the address of the first byte of the destination
- (unsigned short *)(dstFrameP->frameBaseAddr +
- (dstFrameP->scanLinePtrArray[dstBlitRect.top]) +
- (dstBlitRect.left << 1)),
-
- // calculate the number of rows to blit
- srcBlitRect.bottom - srcBlitRect.top,
- dstBlitRect.bottom - dstBlitRect.top + topClip,
-
- // for PPC, just frameRowBytes
- srcFrameP->frameRowBytes,
- dstFrameP->frameRowBytes,
-
- // clipping information
- leftClip,
- topClip,
- bottomClip,
-
- // are we blitting direct-to-screen?
- dstFrameP->isWindowFrame
- );
-
-
- END_32_BIT_MODE
- }
-
- ///--------------------------------------------------------------------------------------
- // BP16BitScaledSpriteMaskDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BP16BitScaledSpriteMaskDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect *srcRect,
- Rect *dstRect)
- {
- Rect dstBlitRect = *dstRect;
- Rect srcBlitRect = *srcRect;
- unsigned long srcBaseOffset;
- short topClip, rightClip, bottomClip, leftClip;
- short topClip2, rightClip2, bottomClip2, leftClip2;
-
- SW_ASSERT(srcFrameP->isFrameLocked && dstFrameP->isFrameLocked);
- SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 16);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 16);
- SW_ASSERT(srcFrameP->maskPort != NULL);
-
- // Make sure some part of the Sprite is inside the dstFrame
- if (dstBlitRect.left >= dstFrameP->frameRect.right ||
- dstBlitRect.right <= dstFrameP->frameRect.left ||
- dstBlitRect.top >= dstFrameP->frameRect.bottom ||
- dstBlitRect.bottom <= dstFrameP->frameRect.top )
- {
- return;
- }
-
- topClip = rightClip = bottomClip = leftClip = 0;
- topClip2 = rightClip2 = bottomClip2 = leftClip2 = 0;
-
- // Clip dstRect with dstFrameP->frameRect
- if (dstBlitRect.top < dstFrameP->frameRect.top)
- {
- topClip = dstFrameP->frameRect.top - dstBlitRect.top;
- dstBlitRect.top = dstFrameP->frameRect.top;
- }
-
- if (dstBlitRect.bottom > dstFrameP->frameRect.bottom)
- bottomClip = dstBlitRect.bottom - dstFrameP->frameRect.bottom;
-
- if (dstBlitRect.left < dstFrameP->frameRect.left)
- leftClip = dstFrameP->frameRect.left - dstBlitRect.left;
-
- if (dstBlitRect.right > dstFrameP->frameRect.right)
- rightClip = dstBlitRect.right - dstFrameP->frameRect.right;
-
-
- // "Unclip" sprite if it was already clipped before this function was called
- if (srcBlitRect.top > srcFrameP->frameRect.top)
- {
- topClip2 = srcBlitRect.top - srcFrameP->frameRect.top;
- srcBlitRect.top = srcFrameP->frameRect.top;
- }
-
- if (srcBlitRect.bottom < srcFrameP->frameRect.bottom)
- {
- bottomClip2 = srcFrameP->frameRect.bottom - srcBlitRect.bottom;
- srcBlitRect.bottom = srcFrameP->frameRect.bottom;
- dstBlitRect.bottom += bottomClip2;
- }
-
- if (srcBlitRect.left > srcFrameP->frameRect.left)
- {
- leftClip2 = srcBlitRect.left - srcFrameP->frameRect.left;
- srcBlitRect.left = srcFrameP->frameRect.left;
- dstBlitRect.left -= leftClip2;
- }
-
- if (srcBlitRect.right < srcFrameP->frameRect.right)
- {
- rightClip2 = srcFrameP->frameRect.right - srcBlitRect.right;
- srcBlitRect.right = srcFrameP->frameRect.right;
- dstBlitRect.right += rightClip2;
- }
-
- topClip += topClip2;
- leftClip += leftClip2;
- rightClip += rightClip2;
- bottomClip += bottomClip2;
-
- // calculate the offset to the first byte of the source
- srcBaseOffset = srcFrameP->scanLinePtrArray[srcBlitRect.top -
- srcFrameP->frameRect.top] + (srcBlitRect.left << 1);
-
- START_32_BIT_MODE
-
- PrecomputeLookupTable(
- (srcBlitRect.right - srcBlitRect.left),
- (dstBlitRect.right - dstBlitRect.left),
- leftClip,
- rightClip);
-
-
- BlitPixieMask16BitScaled(
- // calculate the address of the first byte of the source
- (unsigned short *)(srcFrameP->frameBaseAddr + srcBaseOffset),
-
- // calculate the address of the first byte of the destination
- (unsigned short *)(dstFrameP->frameBaseAddr +
- (dstFrameP->scanLinePtrArray[dstBlitRect.top]) +
- (dstBlitRect.left << 1)),
-
- // calculate the address of the first byte of the mask
- (unsigned short *)(srcFrameP->maskBaseAddr + srcBaseOffset),
-
- // calculate the number of rows to blit
- srcBlitRect.bottom - srcBlitRect.top,
- dstBlitRect.bottom - dstBlitRect.top + topClip,
-
- srcFrameP->frameRowBytes,
- dstFrameP->frameRowBytes,
-
- // clipping information
- leftClip,
- topClip,
- bottomClip
- );
-
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BlitPixie16BitScaled
- ///--------------------------------------------------------------------------------------
-
- void BlitPixie16BitScaled(
- unsigned short *srcPixelP,
- unsigned short *dstPixelP,
- register long srcRowsToCopy,
- register long dstRowsToCopy,
- register unsigned long srcOffset,
- register unsigned long dstOffset,
- short leftClip,
- short topClip,
- short bottomClip,
- short isBlittingToScreen)
- {
- register unsigned short *startSrcPixelP; // Stores the start of the
- register unsigned short *startDstPixelP; // line currently being drawn
- long verticalEps = 0;
- short curRow, numRowsToCopy;
-
- startSrcPixelP = srcPixelP;
- startDstPixelP = dstPixelP;
-
- if (srcRowsToCopy >= dstRowsToCopy)
- verticalEps = srcRowsToCopy / 2;
- else
- verticalEps = -dstRowsToCopy / 2;
-
- // divide by 2 to get number of shorts from bytes
- srcOffset >>= 1;
- dstOffset >>= 1;
-
- // Clip off the top if necessary
- for (curRow = 0; curRow < topClip; curRow++)
- {
- if (srcRowsToCopy >= dstRowsToCopy) {
- while ((verticalEps * 2) <= srcRowsToCopy) {
- // shrink
- startSrcPixelP += srcOffset; // Bump source to next row
- verticalEps += dstRowsToCopy;
- }
- verticalEps -= srcRowsToCopy;
- } else {
- // grow
- verticalEps += srcRowsToCopy;
- if ((verticalEps * 2) > dstRowsToCopy) {
- startSrcPixelP += srcOffset; // Bump source to next row
- verticalEps -= dstRowsToCopy;
- }
- }
- }
-
- // Handle the bottom clip
- numRowsToCopy = dstRowsToCopy - bottomClip;
-
- // Draw the thing
- for (; curRow < numRowsToCopy; curRow++)
- {
- BlitScaledLine16Bit(startSrcPixelP + gSrcLeftClip, startDstPixelP + leftClip,
- isBlittingToScreen);
-
- // bump to next row
- startDstPixelP += dstOffset;
-
- if (srcRowsToCopy >= dstRowsToCopy) {
- while ((verticalEps * 2) <= srcRowsToCopy) {
- // shrink
- startSrcPixelP += srcOffset;
- verticalEps += dstRowsToCopy;
- }
- verticalEps -= srcRowsToCopy;
- } else {
- // grow
- verticalEps += srcRowsToCopy;
- if ((verticalEps * 2) > dstRowsToCopy) {
- startSrcPixelP += srcOffset;
- verticalEps -= dstRowsToCopy;
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BlitPixieMask16BitScaled
- ///--------------------------------------------------------------------------------------
-
- void BlitPixieMask16BitScaled(
- unsigned short *srcPixelP,
- unsigned short *dstPixelP,
- unsigned short *maskPixelP,
- register long srcRowsToCopy,
- register long dstRowsToCopy,
- register unsigned long srcOffset,
- register unsigned long dstOffset,
- short leftClip,
- short topClip,
- short bottomClip)
- {
- register unsigned short *startSrcPixelP;
- register unsigned short *startDstPixelP;
- register unsigned short *startMaskPixelP;
- long verticalEps = 0;
- short curRow, numRowsToCopy;
-
- startSrcPixelP = srcPixelP;
- startDstPixelP = dstPixelP;
- startMaskPixelP = maskPixelP;
-
- if (srcRowsToCopy >= dstRowsToCopy)
- verticalEps = srcRowsToCopy / 2;
- else
- verticalEps = -dstRowsToCopy / 2;
-
- // divide by 2 to get number of shorts from bytes
- srcOffset >>= 1;
- dstOffset >>= 1;
-
- // Clip off the top if necessary
- for (curRow = 0; curRow < topClip; curRow++)
- {
- if (srcRowsToCopy >= dstRowsToCopy) {
- while ((verticalEps * 2) <= srcRowsToCopy) {
- // shrink
- startSrcPixelP += srcOffset;
- startMaskPixelP += srcOffset;
- verticalEps += dstRowsToCopy;
- }
- verticalEps -= srcRowsToCopy;
- } else {
- // grow
- verticalEps += srcRowsToCopy;
- if ((verticalEps * 2) > dstRowsToCopy) {
- startSrcPixelP += srcOffset;
- startMaskPixelP += srcOffset;
- verticalEps -= dstRowsToCopy;
- }
- }
- }
-
- // Handle the bottom clip
- numRowsToCopy = dstRowsToCopy - bottomClip;
-
- // Draw the thing
- for (; curRow < numRowsToCopy; curRow++)
- {
- BlitScaledMaskedLine16Bit(startSrcPixelP + gSrcLeftClip, startMaskPixelP + gSrcLeftClip,
- startDstPixelP + leftClip);
-
- // bump to next row
- startDstPixelP += dstOffset;
-
- if (srcRowsToCopy >= dstRowsToCopy) {
- while ((verticalEps * 2) <= srcRowsToCopy) {
- // shrink
- startSrcPixelP += srcOffset;
- startMaskPixelP += srcOffset;
- verticalEps += dstRowsToCopy;
- }
- verticalEps -= srcRowsToCopy;
- } else {
- // grow
- verticalEps += srcRowsToCopy;
- if ((verticalEps * 2) > dstRowsToCopy) {
- startSrcPixelP += srcOffset;
- startMaskPixelP += srcOffset;
- verticalEps -= dstRowsToCopy;
- }
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BlitScaledLine16Bit - it makes it slightly faster on 68k Macs to put this code in its
- // own function, instead of placing it directly in BlitPixie16BitScaled. It goes the
- // same speed on PPC. This must be because we're "breaking the cache" on 68k Macs otherwise.
- ///--------------------------------------------------------------------------------------
-
- void BlitScaledLine16Bit(
- register unsigned short *srcPixelP,
- register unsigned short *dstPixelP,
- Boolean weAreBlittingToScreen)
- {
- register unsigned short *lookupArrayP;
- short numPixelsToCopy;
-
- lookupArrayP = gLookupArray;
-
- numPixelsToCopy = gNumPixelsToCopy;
-
- // The following code speeds up direct-to-screen blits, since we can make maximum
- // use of the bus.
- if (weAreBlittingToScreen)
- {
- unsigned long srcBuffer;
- register unsigned short *srcBufferPixelP;
-
-
- while (numPixelsToCopy >= 2)
- {
- // Get char pointers to our 4-byte buffers
- srcBufferPixelP = (unsigned short *)&srcBuffer;
-
- // Load 1st pixel into buffer
- srcPixelP += *lookupArrayP;
- *srcBufferPixelP++ = *srcPixelP;
- lookupArrayP++;
-
- // Load 2nd pixel into buffer
- srcPixelP += *lookupArrayP;
- *srcBufferPixelP = *srcPixelP;
- lookupArrayP++;
-
- // Copy from our 4-byte buffer to the destination
- *((unsigned long *) dstPixelP)++ = srcBuffer;
-
- numPixelsToCopy -= 2;
- }
- }
-
-
- // Finish any part of the line not drawn above, or draw the entire line if necessary
- while (numPixelsToCopy--)
- {
- srcPixelP += *lookupArrayP;
- lookupArrayP++;
-
- *dstPixelP = *srcPixelP;
- dstPixelP++;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BlitScaledMaskedLine16Bit - it makes it slightly faster on 68k Macs to put this code in its
- // own function, instead of placing it directly in BlitPixieMask16BitScaled. It goes the
- // same speed on PPC. This must be because we're "breaking the cache" on 68k Macs otherwise.
- ///--------------------------------------------------------------------------------------
-
- void BlitScaledMaskedLine16Bit(
- register unsigned short *srcPixelP,
- register unsigned short *maskPixelP,
- register unsigned short *dstPixelP)
- {
- register unsigned short *lookupArrayP;
- register short numPixelsToCopy;
-
- lookupArrayP = gLookupArray;
-
- numPixelsToCopy = gNumPixelsToCopy;
-
- // Draw the line
- while (numPixelsToCopy--)
- {
- srcPixelP += *lookupArrayP;
- maskPixelP += *lookupArrayP;
-
- if (*maskPixelP == 0)
- *dstPixelP = *srcPixelP;
-
- dstPixelP++;
- lookupArrayP++;
- }
- }
-
-
-
- #pragma mark ----------- Misc -------------
- ///--------------------------------------------------------------------------------------
- // PrecomputeLookupTable - calculates the data used to speed up the scaling blitter
- ///--------------------------------------------------------------------------------------
-
- void PrecomputeLookupTable(
- register long srcNumPixelsPerRow,
- register long dstNumPixelsPerRow,
- short leftClip,
- short rightClip)
- {
- register short numDstPixelsToDraw, eps;
- register short destIndex, srcIndex, srcAccum;
-
- if (srcNumPixelsPerRow >= dstNumPixelsPerRow)
- {
- // Shrink it. For now we don't do any pixel blending for this case.
- destIndex = 0;
- eps = srcNumPixelsPerRow / 2;
-
- // Clip off the left if necessary
- for (srcIndex = 0; destIndex < leftClip && srcIndex < srcNumPixelsPerRow; srcIndex++)
- {
- eps += dstNumPixelsPerRow;
- if ( (eps << 1) > srcNumPixelsPerRow )
- {
- destIndex++;
- eps -= srcNumPixelsPerRow;
- }
- }
-
- // Store the left clip of the source
- gSrcLeftClip = srcIndex;
-
- // Clip off the right
- numDstPixelsToDraw = dstNumPixelsPerRow - rightClip;
-
- // This lets us reset dstIndex to 0
- numDstPixelsToDraw -= destIndex;
- SW_ASSERT(numDstPixelsToDraw > 0);
- SW_ASSERT(numDstPixelsToDraw <= kMaxScaledWidth);
-
- gNumPixelsToCopy = numDstPixelsToDraw;
- destIndex = 0;
- srcAccum = 0;
-
- // Bresenham line draw
- while (srcIndex < srcNumPixelsPerRow && destIndex < numDstPixelsToDraw)
- {
- eps += dstNumPixelsPerRow;
- if ( (eps << 1) > srcNumPixelsPerRow )
- {
- gLookupArray[destIndex] = srcAccum;
- destIndex++;
- srcAccum = 0;
- eps -= srcNumPixelsPerRow;
- }
- srcAccum++;
- srcIndex++;
- }
- }
- else
- {
- // Stretch It. For now we don't do any anti aliasing for this case.
- srcIndex = 0;
- eps = -dstNumPixelsPerRow / 2;
-
- // Clip off the left if necessary
- for (destIndex = 0; destIndex < leftClip; destIndex++)
- {
- eps += srcNumPixelsPerRow;
- if ( (eps << 1) > dstNumPixelsPerRow )
- {
- srcIndex++;
- eps -= dstNumPixelsPerRow;
- }
- }
-
- // Store the left clip of the source
- gSrcLeftClip = srcIndex;
-
- // Clip off the right
- numDstPixelsToDraw = dstNumPixelsPerRow - rightClip;
-
- // This lets us reset dstIndex to 0
- numDstPixelsToDraw -= destIndex;
- SW_ASSERT(numDstPixelsToDraw > 0);
- SW_ASSERT(numDstPixelsToDraw <= kMaxScaledWidth);
-
- gNumPixelsToCopy = numDstPixelsToDraw;
- destIndex = 0;
- srcAccum = 0;
-
- // Use Bresenham's line drawing algorithm to store the values in gLookupArray
- while (destIndex < numDstPixelsToDraw)
- {
- gLookupArray[destIndex] = srcAccum;
- eps += srcNumPixelsPerRow;
- if ( (eps << 1) > dstNumPixelsPerRow )
- {
- srcIndex++;
- srcAccum = 1;
- eps -= dstNumPixelsPerRow;
- }
- else
- srcAccum = 0;
- destIndex++;
- }
- }
- }
-
-