home *** CD-ROM | disk | FTP | other *** search
Text File | 1999-01-01 | 57.3 KB | 2,096 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // SWFastLine.c
- //
- // Everything except BlitLine68kAsm is by Vern Jensen, 12/21/98.
- // BlitLine68kAsm is by Oleg Doperchuk, and is believed to be in the public domain.
- // Thanks to Alex Ni for getting it to compile under CodeWarrior.
- ///--------------------------------------------------------------------------------------
-
- #include "SWFastLine.h"
-
- #define SIGN(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0))
- #define ABS(x) ((x) < 0 ? -(x) : (x))
-
-
- #if !SW_PPC
- ///--------------------------------------------------------------------------------------
- // SWDrawLine68kAsm - warning, no clipping is performed by this function!
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawLine68kAsm(
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint,
- Byte color)
- {
- Ptr baseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[0];
- unsigned long rowBytes = dstFrameP->frameRowBytes;
-
- SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
- SW_ASSERT(srcPoint.h >= dstFrameP->frameRect.left && srcPoint.h < dstFrameP->frameRect.right);
- SW_ASSERT(srcPoint.v >= dstFrameP->frameRect.top && srcPoint.v < dstFrameP->frameRect.bottom);
- SW_ASSERT(dstPoint.h >= dstFrameP->frameRect.left && dstPoint.h < dstFrameP->frameRect.right);
- SW_ASSERT(dstPoint.v >= dstFrameP->frameRect.top && dstPoint.v < dstFrameP->frameRect.bottom);
-
- START_32_BIT_MODE
-
- BlitLine68kAsm(baseAddr, rowBytes, srcPoint.h, dstPoint.h, srcPoint.v, dstPoint.v, color);
-
- END_32_BIT_MODE
- }
- #endif
-
-
- ///--------------------------------------------------------------------------------------
- // SWDrawLine
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawLine(
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint,
- Byte color)
- {
- Boolean thereIsALine = true;
-
- SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
- START_32_BIT_MODE
-
- // Check to see if the line is straight horizontally or vertically
- if (srcPoint.v == dstPoint.v || srcPoint.h == dstPoint.h)
- {
- BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
- }
- else
- {
- // Clip the line with the frameRect
- thereIsALine = SWClipLineWithRect(&srcPoint, &dstPoint, &dstFrameP->frameRect);
-
- if (thereIsALine)
- BlitLine(dstFrameP, srcPoint, dstPoint, color);
- }
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCopyLine
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCopyLine(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint)
- {
- Boolean thereIsALine = true;
-
- SW_ASSERT(srcFrameP != NULL && srcFrameP->isFrameLocked);
- SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
- SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
- START_32_BIT_MODE
-
- // Check to see if the line is straight horizontally or vertically
- if (srcPoint.v == dstPoint.v || srcPoint.h == dstPoint.h)
- {
- BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
- }
- else
- {
- // Clip the line with the dstFrameP->frameRect
- thereIsALine = SWClipLineWithRect(&srcPoint, &dstPoint, &dstFrameP->frameRect);
-
- if (thereIsALine)
- BPCopyLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
- }
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDrawFrameRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawFrameRect(
- FramePtr dstFrameP,
- Rect *dstRectP,
- Byte color)
- {
- Point srcPoint, dstPoint;
- Rect destRect = *dstRectP;
-
- SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
- START_32_BIT_MODE
-
- // Swap things around if they're in the wrong order
- if (destRect.right < destRect.left)
- {
- destRect.right = destRect.left;
- destRect.left = dstRectP->right;
- }
-
- if (destRect.bottom < destRect.top)
- {
- destRect.bottom = destRect.top;
- destRect.top = dstRectP->bottom;
- }
-
- // Clip destRect with dstFrameP->frameRect
- if (destRect.top < dstFrameP->frameRect.top)
- destRect.top = dstFrameP->frameRect.top;
- if (destRect.bottom > dstFrameP->frameRect.bottom)
- destRect.bottom = dstFrameP->frameRect.bottom;
- if (destRect.left < dstFrameP->frameRect.left)
- destRect.left = dstFrameP->frameRect.left;
- if (destRect.right > dstFrameP->frameRect.right)
- destRect.right = dstFrameP->frameRect.right;
-
- if (destRect.right <= destRect.left || destRect.bottom <= destRect.top)
- return;
-
-
- // Draw top side
- srcPoint.h = destRect.left;
- srcPoint.v = destRect.top;
- dstPoint.h = destRect.right-1;
- dstPoint.v = destRect.top;
- BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
-
- // Draw right side
- srcPoint.h = destRect.right-1;
- dstPoint.v = destRect.bottom-1;
- BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
-
- // Draw bottom side
- srcPoint.h = destRect.left;
- srcPoint.v = destRect.bottom-1;
- BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
-
- // Draw left side
- srcPoint.v = destRect.top;
- dstPoint.h = destRect.left;
- BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCopyFrameRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCopyFrameRect(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect *dstRectP)
- {
- Point srcPoint, dstPoint;
- Rect destRect = *dstRectP;
-
- SW_ASSERT(srcFrameP != NULL && srcFrameP->isFrameLocked);
- SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
- SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
- START_32_BIT_MODE
-
- // Swap things around if they're in the wrong order
- if (destRect.right < destRect.left)
- {
- destRect.right = destRect.left;
- destRect.left = dstRectP->right;
- }
-
- if (destRect.bottom < destRect.top)
- {
- destRect.bottom = destRect.top;
- destRect.top = dstRectP->bottom;
- }
-
- // Clip destRect with dstFrameP->frameRect
- if (destRect.top < dstFrameP->frameRect.top)
- destRect.top = dstFrameP->frameRect.top;
- if (destRect.bottom > dstFrameP->frameRect.bottom)
- destRect.bottom = dstFrameP->frameRect.bottom;
- if (destRect.left < dstFrameP->frameRect.left)
- destRect.left = dstFrameP->frameRect.left;
- if (destRect.right > dstFrameP->frameRect.right)
- destRect.right = dstFrameP->frameRect.right;
-
- if (destRect.right <= destRect.left || destRect.bottom <= destRect.top)
- return;
-
-
- // Draw top side
- srcPoint.h = destRect.left;
- srcPoint.v = destRect.top;
- dstPoint.h = destRect.right-1;
- dstPoint.v = destRect.top;
- BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
-
- // Draw right side
- srcPoint.h = destRect.right-1;
- dstPoint.v = destRect.bottom-1;
- BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
-
- // Draw bottom side
- srcPoint.h = destRect.left;
- srcPoint.v = destRect.bottom-1;
- BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
-
- // Draw left side
- srcPoint.v = destRect.top;
- dstPoint.h = destRect.left;
- BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDrawLineInScrollingWorld - clips drawing to the visScrollRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawLineInScrollingWorld(
- SpriteWorldPtr spriteWorldP,
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint,
- Byte color)
- {
- Boolean thereIsALine;
- Rect frameRect = dstFrameP->frameRect;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
- START_32_BIT_MODE
-
- // Check to see if the line is straight horizontally or vertically
- if (srcPoint.v == dstPoint.v || srcPoint.h == dstPoint.h)
- {
- Rect visScrollRect = spriteWorldP->visScrollRect;
-
- // Clip the line with the visScrollRect
- if (srcPoint.v < visScrollRect.top) srcPoint.v = visScrollRect.top;
- if (dstPoint.v < visScrollRect.top) dstPoint.v = visScrollRect.top;
- if (srcPoint.v >= visScrollRect.bottom) srcPoint.v = visScrollRect.bottom-1;
- if (dstPoint.v >= visScrollRect.bottom) dstPoint.v = visScrollRect.bottom-1;
- if (srcPoint.h < visScrollRect.left) srcPoint.h = visScrollRect.left;
- if (dstPoint.h < visScrollRect.left) dstPoint.h = visScrollRect.left;
- if (srcPoint.h >= visScrollRect.right) srcPoint.h = visScrollRect.right-1;
- if (dstPoint.h >= visScrollRect.right) dstPoint.h = visScrollRect.right-1;
-
- // Make the line's points local to the offscreen area
- srcPoint.h -= spriteWorldP->horizScrollRectOffset;
- srcPoint.v -= spriteWorldP->vertScrollRectOffset;
- dstPoint.h -= spriteWorldP->horizScrollRectOffset;
- dstPoint.v -= spriteWorldP->vertScrollRectOffset;
-
- // Determine whether to call the wrapping or non-wrapping version
- if (srcPoint.h >= frameRect.left && srcPoint.h < frameRect.right &&
- dstPoint.h >= frameRect.left && dstPoint.h < frameRect.right &&
- srcPoint.v >= frameRect.top && srcPoint.v < frameRect.bottom &&
- dstPoint.v >= frameRect.top && dstPoint.v < frameRect.bottom)
- {
- // The line is contained entirely inside the dstFrameP
- BlitStraightLine(dstFrameP, srcPoint, dstPoint, color);
- }
- else
- {
- // The line needs wrapping
- BlitStraightWrappingLine(dstFrameP, srcPoint, dstPoint, color);
- }
- }
- else
- {
- // Clip the line with the visScrollRect
- thereIsALine = SWClipLineWithRect(&srcPoint, &dstPoint, &spriteWorldP->visScrollRect);
-
- // Make the line's points local to the offscreen area
- srcPoint.h -= spriteWorldP->horizScrollRectOffset;
- srcPoint.v -= spriteWorldP->vertScrollRectOffset;
- dstPoint.h -= spriteWorldP->horizScrollRectOffset;
- dstPoint.v -= spriteWorldP->vertScrollRectOffset;
-
- if (thereIsALine)
- {
- // Determine whether to call the wrapping or non-wrapping version
- if (srcPoint.h >= frameRect.left && srcPoint.h < frameRect.right &&
- dstPoint.h >= frameRect.left && dstPoint.h < frameRect.right &&
- srcPoint.v >= frameRect.top && srcPoint.v < frameRect.bottom &&
- dstPoint.v >= frameRect.top && dstPoint.v < frameRect.bottom)
- {
- // The line is contained entirely inside the dstFrameP
- BlitLine(dstFrameP, srcPoint, dstPoint, color);
- }
- else
- {
- // The line needs wrapping
- BlitWrappingLine(dstFrameP, srcPoint, dstPoint, color);
- }
- }
- }
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCopyLineInScrollingWorld - clips drawing to the visScrollRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCopyLineInScrollingWorld(
- SpriteWorldPtr spriteWorldP,
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint,
- Rect *clipRectP)
- {
- Boolean thereIsALine;
- Rect frameRect = dstFrameP->frameRect;
- short vertScrollRectOffset, horizScrollRectOffset;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(srcFrameP != NULL && srcFrameP->isFrameLocked);
- SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
- START_32_BIT_MODE
-
- // ClipRectP should be either the visScrollRect or oldVisScrollRect
- vertScrollRectOffset = spriteWorldP->backRect.bottom *
- (clipRectP->top / spriteWorldP->backRect.bottom);
-
- horizScrollRectOffset = spriteWorldP->backRect.right *
- (clipRectP->left / spriteWorldP->backRect.right);
-
- // Check to see if the line is straight horizontally or vertically
- if (srcPoint.v == dstPoint.v || srcPoint.h == dstPoint.h)
- {
- // Clip the line with the visScrollRect
- if (srcPoint.v < clipRectP->top) srcPoint.v = clipRectP->top;
- if (dstPoint.v < clipRectP->top) dstPoint.v = clipRectP->top;
- if (srcPoint.v >= clipRectP->bottom) srcPoint.v = clipRectP->bottom-1;
- if (dstPoint.v >= clipRectP->bottom) dstPoint.v = clipRectP->bottom-1;
- if (srcPoint.h < clipRectP->left) srcPoint.h = clipRectP->left;
- if (dstPoint.h < clipRectP->left) dstPoint.h = clipRectP->left;
- if (srcPoint.h >= clipRectP->right) srcPoint.h = clipRectP->right-1;
- if (dstPoint.h >= clipRectP->right) dstPoint.h = clipRectP->right-1;
-
- // Make the line's points local to the offscreen area
- srcPoint.h -= horizScrollRectOffset;
- srcPoint.v -= vertScrollRectOffset;
- dstPoint.h -= horizScrollRectOffset;
- dstPoint.v -= vertScrollRectOffset;
-
- // Determine whether to call the wrapping or non-wrapping version
- if (srcPoint.h >= frameRect.left && srcPoint.h < frameRect.right &&
- dstPoint.h >= frameRect.left && dstPoint.h < frameRect.right &&
- srcPoint.v >= frameRect.top && srcPoint.v < frameRect.bottom &&
- dstPoint.v >= frameRect.top && dstPoint.v < frameRect.bottom)
- {
- // The line is contained entirely inside the dstFrameP
- BPCopyStraightLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
- }
- else
- {
- // The line needs wrapping
- BPCopyStraightWrappingLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
- }
- }
- else
- {
- // Clip the line with clipRectP (visScrollRect or oldVisScrollRect)
- thereIsALine = SWClipLineWithRect(&srcPoint, &dstPoint, clipRectP);
-
- // Make the line's points local to the offscreen area
- srcPoint.h -= horizScrollRectOffset;
- srcPoint.v -= vertScrollRectOffset;
- dstPoint.h -= horizScrollRectOffset;
- dstPoint.v -= vertScrollRectOffset;
-
- if (thereIsALine)
- {
- // Determine whether to call the wrapping or non-wrapping version
- if (srcPoint.h >= frameRect.left && srcPoint.h < frameRect.right &&
- dstPoint.h >= frameRect.left && dstPoint.h < frameRect.right &&
- srcPoint.v >= frameRect.top && srcPoint.v < frameRect.bottom &&
- dstPoint.v >= frameRect.top && dstPoint.v < frameRect.bottom)
- {
- // The line is contained entirely inside the frameRect
- BPCopyLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
- }
- else
- {
- // The line needs wrapping
- BPCopyWrappingLine(srcFrameP, dstFrameP, srcPoint, dstPoint);
- }
- }
- }
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDrawFrameRectInScrollingWorld
- // The dstFrameP should be either the work area or the background area.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDrawFrameRectInScrollingWorld(
- SpriteWorldPtr spriteWorldP,
- FramePtr dstFrameP,
- Rect *dstRectP,
- Byte color)
- {
- Point srcPoint, dstPoint;
- Rect destRect = *dstRectP;
- Rect frameRect = dstFrameP->frameRect;
- Boolean leftClipped, topClipped, rightClipped, bottomClipped;
- BlitLineProcPtr lineProcPtr;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
- START_32_BIT_MODE
-
- leftClipped = topClipped = rightClipped = bottomClipped = false;
-
- // Clip destRect with spriteWorldP->visScrollRect
- if (destRect.top < spriteWorldP->visScrollRect.top)
- {
- destRect.top = spriteWorldP->visScrollRect.top;
- topClipped = true;
- }
- if (destRect.bottom > spriteWorldP->visScrollRect.bottom)
- {
- destRect.bottom = spriteWorldP->visScrollRect.bottom;
- bottomClipped = true;
- }
- if (destRect.left < spriteWorldP->visScrollRect.left)
- {
- destRect.left = spriteWorldP->visScrollRect.left;
- leftClipped = true;
- }
- if (destRect.right > spriteWorldP->visScrollRect.right)
- {
- destRect.right = spriteWorldP->visScrollRect.right;
- rightClipped = true;
- }
-
- if (destRect.right <= destRect.left || destRect.bottom <= destRect.top)
- return;
-
-
- // Make the line's points local to the offscreen area
- destRect.left -= spriteWorldP->horizScrollRectOffset;
- destRect.right -= spriteWorldP->horizScrollRectOffset;
- destRect.top -= spriteWorldP->vertScrollRectOffset;
- destRect.bottom -= spriteWorldP->vertScrollRectOffset;
-
- // Determine whether to call the wrapping or non-wrapping version
- if (destRect.left >= frameRect.left && destRect.left < frameRect.right &&
- destRect.right >= frameRect.left && destRect.right < frameRect.right &&
- destRect.top >= frameRect.top && destRect.top < frameRect.bottom &&
- destRect.bottom >= frameRect.top && destRect.bottom < frameRect.bottom)
- {
- lineProcPtr = BlitLine; // The line is contained entirely inside the frameRect
- }
- else
- {
- lineProcPtr = BlitWrappingLine; // The line needs wrapping
- }
-
-
- // Draw top side
- srcPoint.h = destRect.left;
- srcPoint.v = destRect.top;
- dstPoint.h = destRect.right-1;
- dstPoint.v = destRect.top;
- if (!topClipped)
- (*lineProcPtr)(dstFrameP, srcPoint, dstPoint, color);
-
- // Draw right side
- srcPoint.h = destRect.right-1;
- dstPoint.v = destRect.bottom-1;
- if (!rightClipped)
- (*lineProcPtr)(dstFrameP, srcPoint, dstPoint, color);
-
- // Draw bottom side
- srcPoint.h = destRect.left;
- srcPoint.v = destRect.bottom-1;
- if (!bottomClipped)
- (*lineProcPtr)(dstFrameP, srcPoint, dstPoint, color);
-
- // Draw left side
- srcPoint.v = destRect.top;
- dstPoint.h = destRect.left;
- if (!leftClipped)
- (*lineProcPtr)(dstFrameP, srcPoint, dstPoint, color);
-
- END_32_BIT_MODE
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCopyFrameRectInScrollingWorld
- // The dstFrameP should be either the work area or the background area.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCopyFrameRectInScrollingWorld(
- SpriteWorldPtr spriteWorldP,
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect *dstRectP,
- Rect *clipRectP)
- {
- Point srcPoint, dstPoint;
- Rect destRect = *dstRectP;
- Rect frameRect = dstFrameP->frameRect;
- Boolean leftClipped, topClipped, rightClipped, bottomClipped;
- short horizScrollRectOffset, vertScrollRectOffset;
- CopyLineProcPtr lineProcPtr;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(srcFrameP != NULL && srcFrameP->isFrameLocked);
- SW_ASSERT(dstFrameP != NULL && dstFrameP->isFrameLocked);
- SW_ASSERT((*srcFrameP->framePort->portPixMap)->pixelSize == 8);
- SW_ASSERT((*dstFrameP->framePort->portPixMap)->pixelSize == 8);
- START_32_BIT_MODE
-
- // ClipRectP should be either the visScrollRect or oldVisScrollRect
- vertScrollRectOffset = spriteWorldP->backRect.bottom *
- (clipRectP->top / spriteWorldP->backRect.bottom);
-
- horizScrollRectOffset = spriteWorldP->backRect.right *
- (clipRectP->left / spriteWorldP->backRect.right);
-
- leftClipped = topClipped = rightClipped = bottomClipped = false;
-
- // Clip destRect with spriteWorldP->visScrollRect
- if (destRect.top < clipRectP->top)
- {
- destRect.top = clipRectP->top;
- topClipped = true;
- }
- if (destRect.bottom > clipRectP->bottom)
- {
- destRect.bottom = clipRectP->bottom;
- bottomClipped = true;
- }
- if (destRect.left < clipRectP->left)
- {
- destRect.left = clipRectP->left;
- leftClipped = true;
- }
- if (destRect.right > clipRectP->right)
- {
- destRect.right = clipRectP->right;
- rightClipped = true;
- }
-
- if (destRect.right <= destRect.left || destRect.bottom <= destRect.top)
- return;
-
- // Make the line's points local to the offscreen area
- destRect.left -= horizScrollRectOffset;
- destRect.right -= horizScrollRectOffset;
- destRect.top -= vertScrollRectOffset;
- destRect.bottom -= vertScrollRectOffset;
-
- // Determine whether to call the wrapping or non-wrapping version
- if (destRect.left >= frameRect.left && destRect.left < frameRect.right &&
- destRect.right >= frameRect.left && destRect.right < frameRect.right &&
- destRect.top >= frameRect.top && destRect.top < frameRect.bottom &&
- destRect.bottom >= frameRect.top && destRect.bottom < frameRect.bottom)
- {
- lineProcPtr = BPCopyStraightLine; // The line is contained entirely inside the frameRect
- }
- else
- {
- lineProcPtr = BPCopyStraightWrappingLine; // The line needs wrapping
- }
-
-
- // Draw top side
- srcPoint.h = destRect.left;
- srcPoint.v = destRect.top;
- dstPoint.h = destRect.right-1;
- dstPoint.v = destRect.top;
- if (!topClipped) // Draw top if it wasn't clipped
- (*lineProcPtr)(srcFrameP, dstFrameP, srcPoint, dstPoint);
-
- // Draw right side
- srcPoint.h = destRect.right-1;
- dstPoint.v = destRect.bottom-1;
- if (!rightClipped) // Draw right if it wasn't clipped
- (*lineProcPtr)(srcFrameP, dstFrameP, srcPoint, dstPoint);
-
- // Draw bottom side
- srcPoint.h = destRect.left;
- srcPoint.v = destRect.bottom-1;
- if (!bottomClipped) // Draw bottom if it wasn't clipped
- (*lineProcPtr)(srcFrameP, dstFrameP, srcPoint, dstPoint);
-
- // Draw left side
- srcPoint.v = destRect.top;
- dstPoint.h = destRect.left;
- if (!leftClipped) // Draw left if it wasn't clipped
- (*lineProcPtr)(srcFrameP, dstFrameP, srcPoint, dstPoint);
-
- END_32_BIT_MODE
- }
-
-
- #pragma mark -
- #pragma mark *** Diagonal Line Blitters:
- ///--------------------------------------------------------------------------------------
- // SWClipLineWithRect - Note: lines clipped with this routine will always be slightly
- // different than the unclipped version, since the accum and dx or dy from this routine
- // are not passed to the actual line drawing function.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC Boolean SWClipLineWithRect(
- Point *srcPoint,
- Point *dstPoint,
- Rect *clipRectP)
- {
- short x1 = srcPoint->h, y1 = srcPoint->v,
- x2 = dstPoint->h, y2 = dstPoint->v;
- short dx, dy, sx, sy, accum;
- short lastX, lastY;
- Boolean x1IsInRect, y1IsInRect, x2IsInRect, y2IsInRect;
- Boolean foundStartPt, endPointIsInRect;
- Rect clipRect = *clipRectP;
-
- // InsetRect(&clipRect, 50, 50); // Useful for testing
-
- x1IsInRect = (x1 >= clipRect.left && x1 < clipRect.right);
- y1IsInRect = (y1 >= clipRect.top && y1 < clipRect.bottom);
- x2IsInRect = (x2 >= clipRect.left && x2 < clipRect.right);
- y2IsInRect = (y2 >= clipRect.top && y2 < clipRect.bottom);
-
- // If line needs no clipping, return
- if (x1IsInRect && y1IsInRect && x2IsInRect && y2IsInRect)
- {
- return true;
- }
-
-
- dx = x2 - x1;
- dy = y2 - y1;
-
- sx = SIGN(dx);
- sy = SIGN(dy);
-
- dx = ABS(dx);
- dy = ABS(dy);
-
- foundStartPt = false;
- endPointIsInRect = false;
-
- // The possibilities are: A) Both start and end points are outside the rect.
- // B) Only the start point is outside. C) Only the end point is outside.
- // We know that at least one point is outside, since otherwise this function
- // would have returned already.
-
- // Check first pixel in line
- if (x1IsInRect && y1IsInRect)
- {
- foundStartPt = true;
- lastX = x1; // Store last point in line as well, in case only
- lastY = y1; // one pixel is inside the clipRect.
- }
-
- if (x2IsInRect && y2IsInRect)
- {
- endPointIsInRect = true;
- }
-
-
- if (dx > dy) // Longer horizontally than vertically
- {
- accum = dx >> 1; // accum = dx/2;
- while (x1 != x2)
- {
- accum -= dy;
- if (accum < 0)
- {
- accum += dx;
- y1 += sy;
- y1IsInRect = (y1 >= clipRect.top && y1 < clipRect.bottom);
- }
- x1 += sx;
- x1IsInRect = (x1 >= clipRect.left && x1 < clipRect.right);
-
- if (x1IsInRect && y1IsInRect) // Determine if current point is in rect
- {
- if (foundStartPt == false)
- {
- srcPoint->h = x1; // Store first point in line
- srcPoint->v = y1;
- foundStartPt = true;
-
- if (endPointIsInRect)
- return true; // Leave early, since we only needed to clip the first half
- }
-
- lastX = x1; // Store last point in line
- lastY = y1; // (We keep doing this until we hit the end.)
- }
- else if (foundStartPt == true)
- {
- break; // the line is leaving clipRect, so break early to save time
- }
- }
- }
- else // Longer vertically than horizontally, or both equal in length
- {
- accum = dy >> 1; // accum = dy/2;
- while (y1 != y2)
- {
- accum -= dx;
- if (accum < 0)
- {
- accum += dy;
- x1 += sx;
- x1IsInRect = (x1 >= clipRect.left && x1 < clipRect.right);
- }
- y1 += sy;
- y1IsInRect = (y1 >= clipRect.top && y1 < clipRect.bottom);
-
- if (x1IsInRect && y1IsInRect) // Determine if current point is in rect
- {
- if (foundStartPt == false)
- {
- srcPoint->h = x1; // Store first point in line
- srcPoint->v = y1;
- foundStartPt = true;
-
- if (endPointIsInRect)
- return true; // Leave early, since we only needed to clip the first half
- }
-
- lastX = x1; // Store last point in line
- lastY = y1; // (We keep doing this until we hit the end.)
- }
- else if (foundStartPt == true)
- {
- break; // the line is leaving clipRect, so break early to save time
- }
- }
- }
-
- // Store last point in line
- dstPoint->h = lastX; // lastX is the pixel just before we ran into the pixel outside bounds
- dstPoint->v = lastY;
-
- // Tell caller if we ever found any point of the line inside clipRect
- return foundStartPt;
- }
-
-
- #if !SW_PPC
- ///--------------------------------------------------------------------------------------
- // BlitLine68kAsm - called by SWDrawLine68kAsm. Written by Oleg Doperchuk.
- ///--------------------------------------------------------------------------------------
-
- SW_ASM_FUNC void BlitLine68kAsm
- (Ptr baseAddr,
- unsigned long rowBytes,
- short x1,
- short x2,
- short y1,
- short y2,
- Byte color)
- {
- SW_ASM_BEGIN
-
- #if __MWERKS__
- fralloc +
- #endif
-
- //dc.w 0xA9FF
- movem.l d0-d7/a0-a6,-(a7)
- moveq #0,d0
- moveq #0,d1
- moveq #0,d2
- moveq #0,d3
- move.w x1,d0
- move.w y1,d1
- move.w x2,d2
- move.w y2,d3
- sub.w d0,d2 // d2 = !x = ( x2 - x1 )
- bpl.s @noswap
- exg d1,d3 // swap endpoints
- neg.w d2 // !x = -!x = ( x1 - x2 )
- sub.w d2,d0 // d0 = x1 - ( x1 - x2 ) = x2
- @noswap:
- sub.w d1,d3 // d3 = !y = ( y2 - y1 )
- move.l baseAddr,a0
- move.l rowBytes,d6
- mulu.l d6,d1
- add.l d1,d0
- add.l d0,a0 // a0 = address of the first point to draw
- move.b color,d7
- // now we can freely use d0/d1
- tst.w d3 // Line upward?
- bmi @LineUp // yes
- beq @Horiz // horizontal line
- tst.w d2 // !x = 0 - vertical line downward
- beq @VertDn
- cmp.w d2,d3 // test line slope
- beq @DiagDn // slope = 1
- bpl @SteepDn // slope > 1
-
- moveq #0,d0 // lower 32bits
- divu.l d2,d3:d0 // d0 = 32bit ( !y/!x )
- moveq #0,d1 // accumulated error
- @FDLoop:
- move.b d7,(a0)+ // Plot a point and move 1 pixel rightward
- add.l d0,d1 // Add an accumulated error
- bcs.s @FDCarry
- dbra d2,@FDLoop
- bra @exit
- @FDCarry:
- add.l d6,a0 // One line down
- dbra d2,@FDLoop
- bra @exit
- @DiagDn:
- addq.l #1,d6 // Offset is rowbytes+1
- @DDLoop:
- move.b d7,(a0) // draw line
- add.l d6,a0
- dbra d2,@DDLoop
- bra @exit
- @SteepDn:
- moveq #0,d0
- divu.l d3,d2:d0 // d0 = 32bit ( !x/!y )
- moveq #0,d1 // accumulated error
- @SDLoop:
- move.b d7,(a0) // plot a point
- add.l d6,a0 // move 1 pixel downward
- add.l d0,d1 // Add an accumulated error
- bcs.s @SDCarry
- dbra d3,@SDLoop
- bra @exit
- @SDCarry:
- addq.l #1,a0
- dbra d3,@SDLoop
- bra @exit
- @Horiz:
- move.b d7,(a0)+
- dbra d2,@Horiz
- bra @exit
- @VertDn:
- move.b d7,(a0) // offset is rowbytes
- add.l d6,a0
- dbra d3,@VertDn
- bra @exit
- @LineUp:
- neg.w d3
- tst.w d2
- beq @VertUp
- cmp.w d2,d3
- beq @DiagUp // slope = -1
- bpl @SteepUp // slope < -1
-
- moveq #0,d0 // lower 32bits
- divu.l d2,d3:d0 // d0 = 32bit ( !y/!x )
- moveq #0,d1 // accumulated error
- @FULoop:
- move.b d7,(a0)+ // Plot a point and move 1 pixel rightward
- add.l d0,d1 // Add an accumulated error
- bcs.s @FUCarry
- dbra d2,@FULoop
- bra @exit
- @FUCarry:
- sub.l d6,a0 // One line up
- dbra d2,@FULoop
- bra @exit
- @DiagUp:
- subq.l #1,d6 // offset is 1-rowbytes
- @DULoop:
- move.b d7,(a0) // draw line
- sub.l d6,a0
- dbra d2,@DULoop
- bra @exit
- @SteepUp:
- moveq #0,d0
- divu.l d3,d2:d0 // d0 = 32bit ( !x/!y )
- moveq #0,d1 // accumulated error
- @SULoop:
- move.b d7,(a0) // plot a point
- sub.l d6,a0 // move 1 pixel upward
- add.l d0,d1 // Add an accumulated error
- bcs.s @SUCarry
- dbra d3,@SULoop
- bra @exit
- @SUCarry:
- addq.l #1,a0
- dbra d3,@SULoop
- bra @exit
- @VertUp:
- move.b d7,(a0) // offset is -rowbytes
- sub.l d6,a0
- dbra d3,@VertUp
- @exit: movem.l (a7)+,d0-d7/a0-a6
-
- #if __MWERKS__
- frfree
- #endif
-
- SW_ASM_END
- }
- #endif
-
-
- ///--------------------------------------------------------------------------------------
- // BlitLine - line-drawing code in C. Clipping must be done before this is called.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BlitLine(
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint,
- Byte color)
- {
- register Ptr baseAddr = dstFrameP->frameBaseAddr;
- unsigned long rowBytes = dstFrameP->frameRowBytes;
- short x1 = srcPoint.h, y1 = srcPoint.v,
- x2 = dstPoint.h, y2 = dstPoint.v;
- short dx, dy, sx, sy, iy;
- short accum;
-
- dx = x2 - x1;
- dy = y2 - y1;
-
- sx = SIGN(dx);
- sy = SIGN(dy);
-
- dx = ABS(dx);
- dy = ABS(dy);
-
- iy = (sy < 0) ? -rowBytes : rowBytes;
-
- baseAddr += dstFrameP->scanLinePtrArray[y1] + x1;
- *baseAddr = color; // Draw the first pixel
-
- if(dx > dy) // Longer horizontally than vertically
- {
- accum = dx >> 1;
- while(x1 != x2)
- {
- accum -= dy;
- if(accum < 0)
- {
- accum += dx;
- baseAddr += iy;
- }
- x1 += sx;
- baseAddr += sx;
- *baseAddr = color;
- }
- }
- else // Longer vertically than horizontally, or both equal in length
- {
- accum = dy >> 1;
- while(y1 != y2)
- {
- accum -= dx;
- if(accum < 0)
- {
- accum += dy;
- baseAddr += sx;
- }
- y1 += sy;
- baseAddr += iy;
- *baseAddr = color;
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BPCopyLine - line-drawing code in C. Clipping must be done before this is called.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BPCopyLine(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint)
- {
- Ptr srcBaseAddr = srcFrameP->frameBaseAddr;
- Ptr dstBaseAddr = dstFrameP->frameBaseAddr;
- unsigned long srcRowBytes = srcFrameP->frameRowBytes;
- unsigned long dstRowBytes = dstFrameP->frameRowBytes;
- short x1 = srcPoint.h, y1 = srcPoint.v,
- x2 = dstPoint.h, y2 = dstPoint.v;
- short dx, dy, sx, sy, srciy, dstiy;
- short accum;
-
- dx = x2 - x1;
- dy = y2 - y1;
-
- sx = SIGN(dx);
- sy = SIGN(dy);
-
- dx = ABS(dx);
- dy = ABS(dy);
-
- srcBaseAddr += srcFrameP->scanLinePtrArray[y1] + x1;
- dstBaseAddr += dstFrameP->scanLinePtrArray[y1] + x1;
-
- // Copy the first pixel in the line
- *dstBaseAddr = *srcBaseAddr;
-
- srciy = (sy < 0) ? -srcRowBytes : srcRowBytes;
- dstiy = (sy < 0) ? -dstRowBytes : dstRowBytes;
-
-
- if (dx > dy) // Longer horizontally than vertically
- {
- accum = dx >> 1;
- while(x1 != x2)
- {
- accum -= dy;
- if(accum < 0)
- {
- accum += dx;
- srcBaseAddr += srciy;
- dstBaseAddr += dstiy;
- }
- x1 += sx;
- srcBaseAddr += sx;
- dstBaseAddr += sx;
- *dstBaseAddr = *srcBaseAddr;
- }
- }
- else // Longer vertically than horizontally, or both equal in length
- {
- accum = dy >> 1;
- while(y1 != y2)
- {
- accum -= dx;
- if(accum < 0)
- {
- accum += dy;
- srcBaseAddr += sx;
- dstBaseAddr += sx;
- }
- y1 += sy;
- srcBaseAddr += srciy;
- dstBaseAddr += dstiy;
- *dstBaseAddr = *srcBaseAddr;
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BlitWrappingLine
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BlitWrappingLine(
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint,
- Byte color)
- {
- Ptr baseAddr;
- unsigned long rowBytes = dstFrameP->frameRowBytes;
- unsigned long vertOffset;
- short x1 = srcPoint.h, y1 = srcPoint.v,
- x2 = dstPoint.h, y2 = dstPoint.v;
- short dx, dy, sx, sy, iy;
- short accum;
- Rect frameRect = dstFrameP->frameRect;
- short frameWidth, frameHeight;
-
- frameWidth = SW_RECT_WIDTH(frameRect);
- frameHeight = SW_RECT_HEIGHT(frameRect);
-
- // vertOffset = rowBytes * frameHeight;
- vertOffset = dstFrameP->scanLinePtrArray[dstFrameP->numScanLines-1] + rowBytes -
- dstFrameP->scanLinePtrArray[0];
-
- dx = x2 - x1;
- dy = y2 - y1;
-
- sx = SIGN(dx);
- sy = SIGN(dy);
-
- dx = ABS(dx);
- dy = ABS(dy);
-
- // Even the very first pixel we draw might need to be wrapped before we draw it.
- if (y1 >= frameRect.bottom)
- {
- y1 -= frameHeight;
- y2 -= frameHeight;
- }
- else if (y1 < frameRect.top)
- {
- y1 += frameHeight;
- y2 += frameHeight;
- }
-
- if (x1 >= frameRect.right)
- {
- x1 -= frameWidth;
- x2 -= frameWidth;
- }
- else if (x1 < frameRect.left)
- {
- x1 += frameWidth;
- x2 += frameWidth;
- }
-
- baseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y1] + x1;
- *baseAddr = color;
-
- iy = (sy < 0) ? -rowBytes : rowBytes;
-
- if (dx > dy) // Longer horizontally than vertically
- {
- accum = dx >> 1; // accum = dx/2;
- while (x1 != x2)
- {
- accum -= dy;
- if (accum < 0)
- {
- accum += dx;
- y1 += sy;
- baseAddr += iy; // Move pixel up/down one row
-
- if (y1 >= frameRect.bottom)
- {
- y1 -= frameHeight;
- y2 -= frameHeight;
- baseAddr -= vertOffset; // Jump to top side
- }
- else if (y1 < frameRect.top)
- {
- y1 += frameHeight;
- y2 += frameHeight;
- baseAddr += vertOffset; // Jump to bottom side
- }
- }
- x1 += sx;
- baseAddr += sx; // Move left/right one pixel
-
- if (x1 >= frameRect.right)
- {
- x1 -= frameWidth;
- x2 -= frameWidth;
- baseAddr -= frameWidth; // Jump to left side
- }
- else if (x1 < frameRect.left)
- {
- x1 += frameWidth;
- x2 += frameWidth;
- baseAddr += frameWidth; // Jump to right side
- }
-
- *baseAddr = color;
- }
- }
- else // Longer vertically than horizontally, or both equal in length
- {
- accum = dy >> 1; // accum = dy/2;
- while (y1 != y2)
- {
- accum -= dx;
- if (accum < 0)
- {
- accum += dy;
- x1 += sx;
- baseAddr += sx;
-
- if (x1 >= frameRect.right)
- {
- x1 -= frameWidth;
- x2 -= frameWidth;
- baseAddr -= frameWidth; // Jump to left side
- }
- else if (x1 < frameRect.left)
- {
- x1 += frameWidth;
- x2 += frameWidth;
- baseAddr += frameWidth; // Jump to right side
- }
- }
- y1 += sy;
- baseAddr += iy;
-
- if (y1 >= frameRect.bottom)
- {
- y1 -= frameHeight;
- y2 -= frameHeight;
- baseAddr -= vertOffset; // Jump to top side
- }
- else if (y1 < frameRect.top)
- {
- y1 += frameHeight;
- y2 += frameHeight;
- baseAddr += vertOffset; // Jump to bottom side
- }
-
- *baseAddr = color;
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BPCopyWrappingLine - assumes srcFrameP and dstFrameP are the same size!
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BPCopyWrappingLine(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint)
- {
- Ptr srcBaseAddr = srcFrameP->frameBaseAddr;
- Ptr dstBaseAddr = dstFrameP->frameBaseAddr;
- unsigned long srcRowBytes = srcFrameP->frameRowBytes;
- unsigned long dstRowBytes = dstFrameP->frameRowBytes;
- unsigned long srcVertOffset, dstVertOffset;
- short x1 = srcPoint.h, y1 = srcPoint.v,
- x2 = dstPoint.h, y2 = dstPoint.v;
- short dx, dy, sx, sy, srciy, dstiy;
- short accum;
- Rect frameRect = dstFrameP->frameRect;
- short frameWidth, frameHeight;
-
- frameWidth = SW_RECT_WIDTH(frameRect);
- frameHeight = SW_RECT_HEIGHT(frameRect);
-
- // srcVertOffset = srcRowBytes * frameHeight;
- srcVertOffset = srcFrameP->scanLinePtrArray[srcFrameP->numScanLines-1] + srcRowBytes -
- srcFrameP->scanLinePtrArray[0];
- dstVertOffset = dstFrameP->scanLinePtrArray[dstFrameP->numScanLines-1] + dstRowBytes -
- dstFrameP->scanLinePtrArray[0];
-
- dx = x2 - x1;
- dy = y2 - y1;
-
- sx = SIGN(dx);
- sy = SIGN(dy);
-
- dx = ABS(dx);
- dy = ABS(dy);
-
- // Even the very first pixel we draw might need to be wrapped before we draw it.
- if (y1 >= frameRect.bottom)
- {
- y1 -= frameHeight;
- y2 -= frameHeight;
- }
- else if (y1 < frameRect.top)
- {
- y1 += frameHeight;
- y2 += frameHeight;
- }
-
- if (x1 >= frameRect.right)
- {
- x1 -= frameWidth;
- x2 -= frameWidth;
- }
- else if (x1 < frameRect.left)
- {
- x1 += frameWidth;
- x2 += frameWidth;
- }
-
- srcBaseAddr += srcFrameP->scanLinePtrArray[y1] + x1;
- dstBaseAddr += dstFrameP->scanLinePtrArray[y1] + x1;
-
- // Copy the first pixel in the line
- *dstBaseAddr = *srcBaseAddr;
-
- srciy = (sy < 0) ? -srcRowBytes : srcRowBytes;
- dstiy = (sy < 0) ? -dstRowBytes : dstRowBytes;
-
- if (dx > dy) // Longer horizontally than vertically
- {
- accum = dx >> 1; // accum = dx/2;
- while (x1 != x2)
- {
- accum -= dy;
- if (accum < 0)
- {
- accum += dx;
- y1 += sy;
- srcBaseAddr += srciy; // Move pixel up/down one row
- dstBaseAddr += dstiy;
-
- if (y1 >= frameRect.bottom)
- {
- y1 -= frameHeight;
- y2 -= frameHeight;
- srcBaseAddr -= srcVertOffset; // Jump to top side
- dstBaseAddr -= dstVertOffset;
- }
- else if (y1 < frameRect.top)
- {
- y1 += frameHeight;
- y2 += frameHeight;
- srcBaseAddr += srcVertOffset; // Jump to bottom side
- dstBaseAddr += dstVertOffset;
- }
- }
- x1 += sx;
- srcBaseAddr += sx; // Move left/right one pixel
- dstBaseAddr += sx;
-
- if (x1 >= frameRect.right)
- {
- x1 -= frameWidth;
- x2 -= frameWidth;
- srcBaseAddr -= frameWidth; // Jump to left side
- dstBaseAddr -= frameWidth;
- }
- else if (x1 < frameRect.left)
- {
- x1 += frameWidth;
- x2 += frameWidth;
- srcBaseAddr += frameWidth; // Jump to right side
- dstBaseAddr += frameWidth;
- }
-
- *dstBaseAddr = *srcBaseAddr; // Copy the pixel
- }
- }
- else // Longer vertically than horizontally, or both equal in length
- {
- accum = dy >> 1; // accum = dy/2;
- while (y1 != y2)
- {
- accum -= dx;
- if (accum < 0)
- {
- accum += dy;
- x1 += sx;
- srcBaseAddr += sx;
- dstBaseAddr += sx;
-
- if (x1 >= frameRect.right)
- {
- x1 -= frameWidth;
- x2 -= frameWidth;
- srcBaseAddr -= frameWidth; // Jump to left side
- dstBaseAddr -= frameWidth;
- }
- else if (x1 < frameRect.left)
- {
- x1 += frameWidth;
- x2 += frameWidth;
- srcBaseAddr += frameWidth; // Jump to right side
- dstBaseAddr += frameWidth;
- }
- }
- y1 += sy;
- srcBaseAddr += srciy;
- dstBaseAddr += dstiy;
-
- if (y1 >= frameRect.bottom)
- {
- y1 -= frameHeight;
- y2 -= frameHeight;
- srcBaseAddr -= srcVertOffset; // Jump to top side
- dstBaseAddr -= dstVertOffset;
- }
- else if (y1 < frameRect.top)
- {
- y1 += frameHeight;
- y2 += frameHeight;
- srcBaseAddr += srcVertOffset; // Jump to bottom side
- dstBaseAddr += dstVertOffset;
- }
-
- *dstBaseAddr = *srcBaseAddr; // Copy the pixel
- }
- }
- }
-
-
- #pragma mark -
- #pragma mark ***Straight Line Blitters:
- ///--------------------------------------------------------------------------------------
- // BlitStraightLine - Clipping is performed by function, since it's easy for a straight line.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BlitStraightLine(
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint,
- register Byte color)
- {
- unsigned long rowBytes = dstFrameP->frameRowBytes;
- short x1 = srcPoint.h, y1 = srcPoint.v,
- x2 = dstPoint.h, y2 = dstPoint.v;
- short dx, dy;
-
-
- if (x1 == x2) // Straight vertical line
- {
- register Ptr baseAddr;
-
- if (y2 < y1)
- {
- y1 = dstPoint.v; // Swap y1 and y2 if they're
- y2 = srcPoint.v; // in the wrong order.
- }
-
- // Make sure some part of the line is inside the frameRect
- if (x1 < dstFrameP->frameRect.left || x1 >= dstFrameP->frameRect.right)
- return;
-
- // Clip the ends of the line
- if (y1 < dstFrameP->frameRect.top)
- y1 = dstFrameP->frameRect.top;
- if (y2 >= dstFrameP->frameRect.bottom)
- y2 = dstFrameP->frameRect.bottom-1;
-
- dy = y2 - y1 + 1; // dy = number of pixels in line
- if (dy > 0) // Make sure there is a line first!
- {
- baseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y1] + x1;
- *baseAddr = color;
-
- while (--dy)
- {
- baseAddr += rowBytes;
- *baseAddr = color;
- }
- }
- }
- else if (y1 == y2) // Straight horizontal line
- {
- register unsigned long *longBaseAddr;
- register numLongBlits;
- unsigned long longColor;
-
- // Fill longColor with color
- longColor = (color<<24) | (color<<16) | (color<<8) | (color);
-
- if (x2 < x1)
- {
- x1 = dstPoint.h; // Swap x1 and x2 if they're
- x2 = srcPoint.h; // in the wrong order.
- }
-
- // Make sure some part of the line is inside the frameRect
- if (y1 < dstFrameP->frameRect.top || y1 >= dstFrameP->frameRect.bottom)
- return;
-
- if (x1 < dstFrameP->frameRect.left)
- x1 = dstFrameP->frameRect.left;
- if (x2 >= dstFrameP->frameRect.right)
- x2 = dstFrameP->frameRect.right-1;
-
- dx = x2 - x1 + 1; // dx = number of pixels in line
- if (dx > 0) // Make sure there is a line first!
- {
- numLongBlits = (dx >> 2);
- longBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr +
- dstFrameP->scanLinePtrArray[y1] + x1);
-
- while (numLongBlits--)
- {
- *(longBaseAddr)++ = longColor;
- }
-
- #ifdef __MWERKS__ // Do it nicely
- // Handle extra pixels at end of line
- if (dx & 0x2)
- *((unsigned short *) longBaseAddr)++ = (unsigned short)longColor;
- if (dx & 0x1)
- *((unsigned char *) longBaseAddr)++ = color;
- #else // Make Think C happy
- // Handle extra pixels at end of line
- if (dx & 0x2)
- {
- *((unsigned short *) longBaseAddr) = (unsigned short)longColor;
- longBaseAddr = (unsigned long *)(((unsigned short *)longBaseAddr) + 1);
- }
- if (dx & 0x1)
- {
- *((unsigned char *) longBaseAddr) = color;
- longBaseAddr = (unsigned long *)(((unsigned char *)longBaseAddr) + 1);
- }
- #endif
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BPCopyStraightLine - Clipping is performed by function, since it's easy for a straight
- // line. Assumes srcFrameP->frameRect and dstFrameP->frameRect are the same size!
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BPCopyStraightLine(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint)
- {
- unsigned long srcRowBytes = srcFrameP->frameRowBytes;
- unsigned long dstRowBytes = dstFrameP->frameRowBytes;
- short x1 = srcPoint.h, y1 = srcPoint.v,
- x2 = dstPoint.h, y2 = dstPoint.v;
- short dx, dy;
-
-
- if (x1 == x2) // Straight vertical line
- {
- register Ptr srcBaseAddr;
- register Ptr dstBaseAddr;
-
- if (y2 < y1)
- {
- y1 = dstPoint.v; // Swap y1 and y2 if they're
- y2 = srcPoint.v; // in the wrong order.
- }
-
- // Make sure some part of the line is inside the frameRect
- if (x1 < dstFrameP->frameRect.left || x1 >= dstFrameP->frameRect.right)
- return;
-
- // Clip the ends of the line
- if (y1 < dstFrameP->frameRect.top)
- y1 = dstFrameP->frameRect.top;
- if (y2 >= dstFrameP->frameRect.bottom)
- y2 = dstFrameP->frameRect.bottom-1;
-
- dy = y2 - y1 + 1; // dy = number of pixels in line
- if (dy > 0) // Make sure there is a line first!
- {
- srcBaseAddr = srcFrameP->frameBaseAddr + srcFrameP->scanLinePtrArray[y1] + x1;
- dstBaseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y1] + x1;
-
- *dstBaseAddr = *srcBaseAddr; // Copy the first pixel
-
- while (--dy)
- {
- srcBaseAddr += srcRowBytes;
- dstBaseAddr += dstRowBytes;
- *dstBaseAddr = *srcBaseAddr;
- }
- }
- }
- else if (y1 == y2) // Straight horizontal line
- {
- register unsigned long *srcBaseAddr;
- register unsigned long *dstBaseAddr;
- register numLongBlits;
-
- if (x2 < x1)
- {
- x1 = dstPoint.h; // Swap x1 and x2 if they're
- x2 = srcPoint.h; // in the wrong order.
- }
-
- // Make sure some part of the line is inside the frameRect
- if (y1 < dstFrameP->frameRect.top || y1 >= dstFrameP->frameRect.bottom)
- return;
-
- // Clip the ends of the line
- if (x1 < dstFrameP->frameRect.left)
- x1 = dstFrameP->frameRect.left;
- if (x2 >= dstFrameP->frameRect.right)
- x2 = dstFrameP->frameRect.right-1;
-
- dx = x2 - x1 + 1; // dx = number of pixels in line
- if (dx > 0) // Make sure there is a line first!
- {
- numLongBlits = (dx >> 2);
- srcBaseAddr = (unsigned long *)(srcFrameP->frameBaseAddr +
- srcFrameP->scanLinePtrArray[y1] + x1);
- dstBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr +
- dstFrameP->scanLinePtrArray[y1] + x1);
-
- while (numLongBlits--)
- {
- *(dstBaseAddr)++ = *(srcBaseAddr)++;
- }
-
-
- #ifdef __MWERKS__ // Do it nicely
- // Handle extra pixels at end of line
- if (dx & 0x2)
- *((unsigned short *) dstBaseAddr)++ = *((unsigned short *) srcBaseAddr)++;
- if (dx & 0x1)
- *((unsigned char *) dstBaseAddr)++ = *((unsigned char *) srcBaseAddr)++;
- #else // Make Think C happy
- // Handle extra pixels at end of line
- if (dx & 0x2)
- {
- *((unsigned short *) dstBaseAddr) = *((unsigned short *) srcBaseAddr);
- dstBaseAddr = (unsigned long *)(((unsigned short *)dstBaseAddr) + 1);
- srcBaseAddr = (unsigned long *)(((unsigned short *)srcBaseAddr) + 1);
- }
- if (dx & 0x1)
- {
- *((unsigned char *) dstBaseAddr) = *((unsigned char *) srcBaseAddr);
- dstBaseAddr = (unsigned long *)(((unsigned char *)dstBaseAddr) + 1);
- srcBaseAddr = (unsigned long *)(((unsigned char *)srcBaseAddr) + 1);
- }
- #endif
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BlitStraightWrappingLine - No clipping performed by function.
- // Assumes srcFrameP->frameRect and dstFrameP->frameRect are the same size!
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BlitStraightWrappingLine(
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint,
- register Byte color)
- {
- unsigned long rowBytes = dstFrameP->frameRowBytes;
- short x1 = srcPoint.h, y1 = srcPoint.v,
- x2 = dstPoint.h, y2 = dstPoint.v;
- short dx, dy;
-
- if (x1 == x2) // Straight vertical line
- {
- register Ptr baseAddr;
- short y3, y4; // Second half of wrapped line
-
- if (y2 < y1)
- {
- y1 = dstPoint.v; // Swap y1 and y2 if they're
- y2 = srcPoint.v; // in the wrong order.
- }
-
- // Wrap line horizontally if necessary before we start (only done once)
- // Remember x1 and x2 are the same, and x2 isn't used.
- if (x1 < dstFrameP->frameRect.left)
- x1 += dstFrameP->frameRect.right;
- else if (x1 >= dstFrameP->frameRect.right)
- x1 -= dstFrameP->frameRect.right;
-
- // Now we check to see if the line wraps vertically, in which case we
- // split it into two lines before drawing it.
- if (y1 < dstFrameP->frameRect.top)
- {
- if (y2 < dstFrameP->frameRect.top)
- y4 = y2 + dstFrameP->frameRect.bottom;
- else
- y4 = dstFrameP->frameRect.bottom-1;
-
- y3 = y1 + dstFrameP->frameRect.bottom;
- y1 = dstFrameP->frameRect.top;
- }
- else if (y2 >= dstFrameP->frameRect.bottom)
- {
- if (y1 >= dstFrameP->frameRect.bottom)
- y3 = y1 - dstFrameP->frameRect.bottom;
- else
- y3 = dstFrameP->frameRect.top;
-
- y4 = y2 - dstFrameP->frameRect.bottom;
- y2 = dstFrameP->frameRect.bottom-1;
- }
- else
- {
- y3 = 0; // The formula for no second line
- y4 = -1;
- }
-
- // -----Draw the first line-----
- dy = y2 - y1 + 1; // dy = number of pixels in line
- if (dy > 0) // Make sure there is a line first!
- {
- baseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y1] + x1;
- *baseAddr = color;
-
- while(--dy)
- {
- baseAddr += rowBytes;
- *baseAddr = color;
- }
- }
-
-
- // -----Draw the second line-----
- dy = y4 - y3 + 1; // dy = number of pixels in line
- if (dy > 0) // Make sure there is a line first!
- {
- baseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y3] + x1;
- *baseAddr = color;
-
- while(--dy)
- {
- baseAddr += rowBytes;
- *baseAddr = color;
- }
- }
- }
- else if (y1 == y2) // Straight horizontal line
- {
- register unsigned long *longBaseAddr;
- register numLongBlits;
- unsigned long longColor;
- short x3, x4; // Second half of wrapped line
-
- // Fill longColor with color
- longColor = (color<<24) | (color<<16) | (color<<8) | (color);
-
- if (x2 < x1)
- {
- x1 = dstPoint.h; // Swap x1 and x2 if they're
- x2 = srcPoint.h; // in the wrong order.
- }
-
- // Wrap line vertically if necessary before we start (only done once)
- // Remember y1 and y2 are the same, and y2 isn't used.
- if (y1 < dstFrameP->frameRect.top)
- y1 += dstFrameP->frameRect.bottom;
- else if (y1 >= dstFrameP->frameRect.bottom)
- y1 -= dstFrameP->frameRect.bottom;
-
- // Now we check to see if the line wraps horizontally, in which case we
- // split it into two lines before drawing it.
- if (x1 < dstFrameP->frameRect.left)
- {
- if (x2 < dstFrameP->frameRect.left)
- x4 = x2 + dstFrameP->frameRect.right;
- else
- x4 = dstFrameP->frameRect.right-1;
-
- x3 = x1 + dstFrameP->frameRect.right;
- x1 = dstFrameP->frameRect.left;
- }
- else if (x2 >= dstFrameP->frameRect.right)
- {
- if (x1 >= dstFrameP->frameRect.right)
- x3 = x1 - dstFrameP->frameRect.right;
- else
- x3 = dstFrameP->frameRect.left;
-
- x4 = x2 - dstFrameP->frameRect.right;
- x2 = dstFrameP->frameRect.right-1;
- }
- else
- {
- x3 = 0; // The formula for no second line
- x4 = -1;
- }
-
- // ----Draw the first line----
- dx = x2 - x1 + 1; // dx = number of pixels in line
- if (dx > 0) // Make sure there is a line first!
- {
- numLongBlits = (dx >> 2);
- longBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr +
- dstFrameP->scanLinePtrArray[y1] + x1);
-
- while (numLongBlits--)
- {
- *(longBaseAddr)++ = longColor;
- }
-
- #ifdef __MWERKS__ // Do it nicely
- // Handle extra pixels at end of line
- if (dx & 0x2)
- *((unsigned short *) longBaseAddr)++ = (unsigned short)longColor;
- if (dx & 0x1)
- *((unsigned char *) longBaseAddr)++ = color;
- #else // Make Think C happy
- // Handle extra pixels at end of line
- if (dx & 0x2)
- {
- *((unsigned short *) longBaseAddr) = (unsigned short)longColor;
- longBaseAddr = (unsigned long *)(((unsigned short *)longBaseAddr) + 1);
- }
- if (dx & 0x1)
- {
- *((unsigned char *) longBaseAddr) = color;
- longBaseAddr = (unsigned long *)(((unsigned char *)longBaseAddr) + 1);
- }
- #endif
- }
-
-
- // ----Draw the second line----
- dx = x4 - x3 + 1; // dx = number of pixels in line
- if (dx > 0) // Make sure there is a line first!
- {
- numLongBlits = (dx >> 2);
- longBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr +
- dstFrameP->scanLinePtrArray[y1] + x3);
-
- while (numLongBlits--)
- {
- *(longBaseAddr)++ = longColor;
- }
-
- #ifdef __MWERKS__ // Do it nicely
- // Handle extra pixels at end of line
- if (dx & 0x2)
- *((unsigned short *) longBaseAddr)++ = (unsigned short)longColor;
- if (dx & 0x1)
- *((unsigned char *) longBaseAddr)++ = color;
- #else // Make Think C happy
- // Handle extra pixels at end of line
- if (dx & 0x2)
- {
- *((unsigned short *) longBaseAddr) = (unsigned short)longColor;
- longBaseAddr = (unsigned long *)(((unsigned short *)longBaseAddr) + 1);
- }
- if (dx & 0x1)
- {
- *((unsigned char *) longBaseAddr) = color;
- longBaseAddr = (unsigned long *)(((unsigned char *)longBaseAddr) + 1);
- }
- #endif
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // BPCopyStraightWrappingLine - No clipping performed by function.
- // Assumes srcFrameP->frameRect and dstFrameP->frameRect are the same size!
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void BPCopyStraightWrappingLine(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Point srcPoint,
- Point dstPoint)
- {
- unsigned long srcRowBytes = srcFrameP->frameRowBytes;
- unsigned long dstRowBytes = dstFrameP->frameRowBytes;
- short x1 = srcPoint.h, y1 = srcPoint.v,
- x2 = dstPoint.h, y2 = dstPoint.v;
- short dx, dy;
-
- if (x1 == x2) // Straight vertical line
- {
- register Ptr srcBaseAddr, dstBaseAddr;
- short y3, y4; // Second half of wrapped line
-
- if (y2 < y1)
- {
- y1 = dstPoint.v; // Swap y1 and y2 if they're
- y2 = srcPoint.v; // in the wrong order.
- }
-
- // Wrap line horizontally if necessary before we start (only done once)
- // Remember x1 and x2 are the same, and x2 isn't used.
- if (x1 < dstFrameP->frameRect.left)
- x1 += dstFrameP->frameRect.right;
- else if (x1 >= dstFrameP->frameRect.right)
- x1 -= dstFrameP->frameRect.right;
-
- // Now we check to see if the line wraps vertically, in which case we
- // split it into two lines before drawing it.
- if (y1 < dstFrameP->frameRect.top)
- {
- if (y2 < dstFrameP->frameRect.top)
- y4 = y2 + dstFrameP->frameRect.bottom;
- else
- y4 = dstFrameP->frameRect.bottom-1;
-
- y3 = y1 + dstFrameP->frameRect.bottom;
- y1 = dstFrameP->frameRect.top;
- }
- else if (y2 >= dstFrameP->frameRect.bottom)
- {
- if (y1 >= dstFrameP->frameRect.bottom)
- y3 = y1 - dstFrameP->frameRect.bottom;
- else
- y3 = dstFrameP->frameRect.top;
-
- y4 = y2 - dstFrameP->frameRect.bottom;
- y2 = dstFrameP->frameRect.bottom-1;
- }
- else
- {
- y3 = 0; // The formula for no second line
- y4 = -1;
- }
-
- // -----Draw the first line-----
- dy = y2 - y1 + 1; // dy = number of pixels in line
- if (dy > 0) // Make sure there is a line first!
- {
- srcBaseAddr = srcFrameP->frameBaseAddr + srcFrameP->scanLinePtrArray[y1] + x1;
- dstBaseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y1] + x1;
-
- *dstBaseAddr = *srcBaseAddr; // Copy the first pixel
-
- while (--dy)
- {
- srcBaseAddr += srcRowBytes;
- dstBaseAddr += dstRowBytes;
- *dstBaseAddr = *srcBaseAddr;
- }
- }
-
-
- // -----Draw the second line-----
- dy = y4 - y3 + 1; // dy = number of pixels in line
- if (dy > 0) // Make sure there is a line first!
- {
- srcBaseAddr = srcFrameP->frameBaseAddr + srcFrameP->scanLinePtrArray[y3] + x1;
- dstBaseAddr = dstFrameP->frameBaseAddr + dstFrameP->scanLinePtrArray[y3] + x1;
-
- *dstBaseAddr = *srcBaseAddr; // Copy the first pixel
-
- while (--dy)
- {
- srcBaseAddr += srcRowBytes;
- dstBaseAddr += dstRowBytes;
- *dstBaseAddr = *srcBaseAddr;
- }
- }
- }
- else if (y1 == y2) // Straight horizontal line
- {
- register unsigned long *srcBaseAddr, *dstBaseAddr;
- register numLongBlits;
- short x3, x4; // Second half of wrapped line
-
- if (x2 < x1)
- {
- x1 = dstPoint.h; // Swap x1 and x2 if they're
- x2 = srcPoint.h; // in the wrong order.
- }
-
- // Wrap line vertically if necessary before we start (only done once)
- // Remember y1 and y2 are the same, and y2 isn't used.
- if (y1 < dstFrameP->frameRect.top)
- y1 += dstFrameP->frameRect.bottom;
- else if (y1 >= dstFrameP->frameRect.bottom)
- y1 -= dstFrameP->frameRect.bottom;
-
- // Now we check to see if the line wraps horizontally, in which case we
- // split it into two lines before drawing it.
- if (x1 < dstFrameP->frameRect.left)
- {
- if (x2 < dstFrameP->frameRect.left)
- x4 = x2 + dstFrameP->frameRect.right;
- else
- x4 = dstFrameP->frameRect.right-1;
-
- x3 = x1 + dstFrameP->frameRect.right;
- x1 = dstFrameP->frameRect.left;
- }
- else if (x2 >= dstFrameP->frameRect.right)
- {
- if (x1 >= dstFrameP->frameRect.right)
- x3 = x1 - dstFrameP->frameRect.right;
- else
- x3 = dstFrameP->frameRect.left;
-
- x4 = x2 - dstFrameP->frameRect.right;
- x2 = dstFrameP->frameRect.right-1;
- }
- else
- {
- x3 = 0; // The formula for no second line
- x4 = -1;
- }
-
- // ----Draw the first line----
- dx = x2 - x1 + 1; // dx = number of pixels in line
- if (dx > 0) // Make sure there is a line first!
- {
- numLongBlits = (dx >> 2);
- srcBaseAddr = (unsigned long *)(srcFrameP->frameBaseAddr +
- srcFrameP->scanLinePtrArray[y1] + x1);
- dstBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr +
- dstFrameP->scanLinePtrArray[y1] + x1);
-
- while (numLongBlits--)
- {
- *(dstBaseAddr)++ = *(srcBaseAddr)++;
- }
-
-
- #ifdef __MWERKS__ // Do it nicely
- // Handle extra pixels at end of line
- if (dx & 0x2)
- *((unsigned short *) dstBaseAddr)++ = *((unsigned short *) srcBaseAddr)++;
- if (dx & 0x1)
- *((unsigned char *) dstBaseAddr)++ = *((unsigned char *) srcBaseAddr)++;
- #else // Make Think C happy
- // Handle extra pixels at end of line
- if (dx & 0x2)
- {
- *((unsigned short *) dstBaseAddr) = *((unsigned short *) srcBaseAddr);
- dstBaseAddr = (unsigned long *)(((unsigned short *)dstBaseAddr) + 1);
- srcBaseAddr = (unsigned long *)(((unsigned short *)srcBaseAddr) + 1);
- }
- if (dx & 0x1)
- {
- *((unsigned char *) dstBaseAddr) = *((unsigned char *) srcBaseAddr);
- dstBaseAddr = (unsigned long *)(((unsigned char *)dstBaseAddr) + 1);
- srcBaseAddr = (unsigned long *)(((unsigned char *)srcBaseAddr) + 1);
- }
- #endif
- }
-
-
- // ----Draw the second line----
- dx = x4 - x3 + 1; // dx = number of pixels in line
- if (dx > 0) // Make sure there is a line first!
- {
- numLongBlits = (dx >> 2);
- srcBaseAddr = (unsigned long *)(srcFrameP->frameBaseAddr +
- srcFrameP->scanLinePtrArray[y1] + x3);
- dstBaseAddr = (unsigned long *)(dstFrameP->frameBaseAddr +
- dstFrameP->scanLinePtrArray[y1] + x3);
-
- while (numLongBlits--)
- {
- *(dstBaseAddr)++ = *(srcBaseAddr)++;
- }
-
-
- #ifdef __MWERKS__ // Do it nicely
- // Handle extra pixels at end of line
- if (dx & 0x2)
- *((unsigned short *) dstBaseAddr)++ = *((unsigned short *) srcBaseAddr)++;
- if (dx & 0x1)
- *((unsigned char *) dstBaseAddr)++ = *((unsigned char *) srcBaseAddr)++;
- #else // Make Think C happy
- // Handle extra pixels at end of line
- if (dx & 0x2)
- {
- *((unsigned short *) dstBaseAddr) = *((unsigned short *) srcBaseAddr);
- dstBaseAddr = (unsigned long *)(((unsigned short *)dstBaseAddr) + 1);
- srcBaseAddr = (unsigned long *)(((unsigned short *)srcBaseAddr) + 1);
- }
- if (dx & 0x1)
- {
- *((unsigned char *) dstBaseAddr) = *((unsigned char *) srcBaseAddr);
- dstBaseAddr = (unsigned long *)(((unsigned char *)dstBaseAddr) + 1);
- srcBaseAddr = (unsigned long *)(((unsigned char *)srcBaseAddr) + 1);
- }
- #endif
- }
- }
- }
-
-