mirror of
https://github.com/softdorothy/GliderPRO.git
synced 2024-11-22 20:31:19 +00:00
7a70d18ba6
Sources for Glider PRO, a Macintosh game written by John Calhoun and published by Casady & Greene, Inc. I believe it was using CodeWarrior IDE to create a fat (68K and PowerPC) binary.
1 line
8.3 KiB
C
Executable File
1 line
8.3 KiB
C
Executable File
//============================================================================
|
|
//----------------------------------------------------------------------------
|
|
// RectUtils.c
|
|
//----------------------------------------------------------------------------
|
|
//============================================================================
|
|
|
|
|
|
|
|
#include "Externs.h"
|
|
#include "RectUtils.h"
|
|
|
|
|
|
|
|
//============================================================== Functions
|
|
//-------------------------------------------------------------- FrameWHRect
|
|
// Given the top left corner and a width and height, this functionÉ
|
|
// simply creates the necessary rectangle and frames it.
|
|
|
|
void FrameWHRect (short left, short top, short wide, short high)
|
|
{
|
|
Rect theRect;
|
|
|
|
theRect.left = left;
|
|
theRect.top = top;
|
|
theRect.right = left + wide;
|
|
theRect.bottom = top + high;
|
|
FrameRect(&theRect);
|
|
}
|
|
|
|
//-------------------------------------------------------------- NormalizeRect
|
|
// This function ensures that a rect's top is less than it's bottomÉ
|
|
// and that left is less than right.
|
|
|
|
void NormalizeRect (Rect *theRect)
|
|
{
|
|
short tempSide;
|
|
|
|
if (theRect->left > theRect->right)
|
|
{
|
|
tempSide = theRect->left;
|
|
theRect->left = theRect->right;
|
|
theRect->right = tempSide;
|
|
}
|
|
|
|
if (theRect->top > theRect->bottom)
|
|
{
|
|
tempSide = theRect->top;
|
|
theRect->top = theRect->bottom;
|
|
theRect->bottom = tempSide;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------- ZeroRectCorner
|
|
// The rect passed in is slid over so that its top left corner isÉ
|
|
// at coordinates (0, 0).
|
|
|
|
void ZeroRectCorner (Rect *theRect) // Offset rect to (0, 0)
|
|
{
|
|
theRect->right -= theRect->left;
|
|
theRect->bottom -= theRect->top;
|
|
theRect->left = 0;
|
|
theRect->top = 0;
|
|
}
|
|
|
|
//-------------------------------------------------------------- CenterRectOnPoint
|
|
// Given a rectangle and a point, this function centers the rectangleÉ
|
|
// on that point.
|
|
|
|
void CenterRectOnPoint (Rect *theRect, Point where)
|
|
{
|
|
ZeroRectCorner(theRect);
|
|
QOffsetRect(theRect, -HalfRectWide(theRect), -HalfRectTall(theRect));
|
|
QOffsetRect(theRect, where.h, where.v);
|
|
}
|
|
|
|
//-------------------------------------------------------------- HalfRectWide
|
|
// Given a rectangle, this function returns the rect's width divided by 2.
|
|
|
|
short HalfRectWide (Rect *theRect)
|
|
{
|
|
return ((theRect->right - theRect->left) / 2);
|
|
}
|
|
|
|
//-------------------------------------------------------------- HalfRectTall
|
|
// Given a rectangle, this function returns the rect's height divided by 2.
|
|
|
|
short HalfRectTall (Rect *theRect)
|
|
{
|
|
return ((theRect->bottom - theRect->top) / 2);
|
|
}
|
|
|
|
//-------------------------------------------------------------- RectWide
|
|
// Given a rectangle, this simple function returns the rect's width.
|
|
|
|
short RectWide (Rect *theRect)
|
|
{
|
|
return (theRect->right - theRect->left);
|
|
}
|
|
|
|
//-------------------------------------------------------------- RectTall
|
|
// Given a rectangle, this simple function returns the rect's height.
|
|
|
|
short RectTall (Rect *theRect)
|
|
{
|
|
return (theRect->bottom - theRect->top);
|
|
}
|
|
|
|
//-------------------------------------------------------------- GlobalToLocalRect
|
|
|
|
// This function offsets a rectangle from global to local coordinates.
|
|
// The "local" coordinate system is assumed to be the current port (window).
|
|
|
|
void GlobalToLocalRect (Rect *theRect)
|
|
{
|
|
Point upperLeftPt;
|
|
|
|
upperLeftPt.h = 0;
|
|
upperLeftPt.v = 0;
|
|
GlobalToLocal(&upperLeftPt);
|
|
QOffsetRect(theRect, upperLeftPt.h, upperLeftPt.v);
|
|
}
|
|
|
|
//-------------------------------------------------------------- LocalToGlobalRect
|
|
|
|
// This function offsets a rectangle from local to global coordinates.
|
|
// The "local" coordinate system is assumed to be the current port (window).
|
|
|
|
void LocalToGlobalRect (Rect *theRect)
|
|
{
|
|
Point upperLeftPt;
|
|
|
|
upperLeftPt.h = 0;
|
|
upperLeftPt.v = 0;
|
|
LocalToGlobal(&upperLeftPt);
|
|
QOffsetRect(theRect, upperLeftPt.h, upperLeftPt.v);
|
|
}
|
|
|
|
//-------------------------------------------------------------- CenterRectInRect
|
|
// Given two rectangles, this function centers the first rectangleÉ
|
|
// within the second. The second rect is unchanged.
|
|
|
|
void CenterRectInRect (Rect *rectA, Rect *rectB)
|
|
{
|
|
short widthA, tallA;
|
|
|
|
widthA = RectWide(rectA);
|
|
tallA = RectTall(rectA);
|
|
|
|
rectA->left = rectB->left + (RectWide(rectB) - widthA) / 2;
|
|
rectA->right = rectA->left + widthA;
|
|
|
|
rectA->top = rectB->top + (RectTall(rectB) - tallA) / 2;
|
|
rectA->bottom = rectA->top + tallA;
|
|
}
|
|
|
|
//-------------------------------------------------------------- HOffsetRect
|
|
|
|
// Just a simple function to offset a rectangle horizontally only.
|
|
|
|
void HOffsetRect (Rect *theRect, short h)
|
|
{
|
|
theRect->left += h;
|
|
theRect->right += h;
|
|
}
|
|
|
|
//-------------------------------------------------------------- VOffsetRect
|
|
|
|
// Just a simple function to offset a rectangle vertically only.
|
|
|
|
void VOffsetRect (Rect *theRect, short v)
|
|
{
|
|
theRect->top += v;
|
|
theRect->bottom += v;
|
|
}
|
|
|
|
//-------------------------------------------------------------- IsRectLeftOfRect
|
|
|
|
// Given two rects, this function returns true if the first rectangleÉ
|
|
// is to the left of the second.
|
|
|
|
Boolean IsRectLeftOfRect (Rect *rect1, Rect *rect2)
|
|
{
|
|
short offset;
|
|
|
|
offset = (rect1->right - rect1->left) - (rect2->right - rect2->left) / 2;
|
|
if ((rect1->left) < (rect2->left + offset))
|
|
return (true);
|
|
else
|
|
return (false);
|
|
}
|
|
|
|
//-------------------------------------------------------------- QOffsetRect
|
|
|
|
// This duplicates a Mac ToolBox call, but since it's local, it's faster.
|
|
// It offsets a rectangle both vertically and horizontally.
|
|
|
|
void QOffsetRect (Rect *theRect, short h, short v)
|
|
{
|
|
theRect->right += h;
|
|
theRect->left += h;
|
|
theRect->bottom += v;
|
|
theRect->top += v;
|
|
}
|
|
|
|
//-------------------------------------------------------------- QSetRect
|
|
|
|
// This also duplicates a ToolBox call. It's needed often though, soÉ
|
|
// any gains in speed are nice. It sets up a rect structure.
|
|
|
|
void QSetRect (Rect *theRect, short l, short t, short r, short b)
|
|
{
|
|
theRect->left = l;
|
|
theRect->top = t;
|
|
theRect->right = r;
|
|
theRect->bottom = b;
|
|
}
|
|
|
|
//-------------------------------------------------------------- ForceRectInRect
|
|
// Given a source rectangle and a bounding rectangle, this functionÉ
|
|
// will clip the source rect so that it is entirely within the boundingÉ
|
|
// rect. It returns true if any clippiung was necessary.
|
|
|
|
Boolean ForceRectInRect (Rect *small, Rect *large)
|
|
{
|
|
SInt16 hOff, vOff;
|
|
Boolean changed;
|
|
|
|
changed = false;
|
|
|
|
NormalizeRect(small);
|
|
|
|
if ((small->bottom - small->top) > (large->bottom - large->top))
|
|
{
|
|
small->bottom = small->top + (large->bottom - large->top);
|
|
changed = true;
|
|
}
|
|
|
|
if ((small->right - small->left) > (large->right - large->left))
|
|
{
|
|
small->right = small->left + (large->right - large->left);
|
|
changed = true;
|
|
}
|
|
|
|
hOff = large->left - small->left;
|
|
if (hOff > 0)
|
|
{
|
|
OffsetRect(small, hOff, 0);
|
|
changed = true;
|
|
}
|
|
hOff = large->right - small->right;
|
|
if (hOff < 0)
|
|
{
|
|
OffsetRect(small, hOff, 0);
|
|
changed = true;
|
|
}
|
|
vOff = large->top - small->top;
|
|
if (vOff > 0)
|
|
{
|
|
OffsetRect(small, 0, vOff);
|
|
changed = true;
|
|
}
|
|
vOff = large->bottom - small->bottom;
|
|
if (vOff < 0)
|
|
{
|
|
OffsetRect(small, 0, vOff);
|
|
changed = true;
|
|
}
|
|
|
|
return changed;
|
|
}
|
|
|
|
//-------------------------------------------------------------- QUnionSimilarRect
|
|
|
|
// Given 2 rects that are assumed to have the same width and height,É
|
|
// this function returns a 3rd rect that is the union of those two.
|
|
|
|
void QUnionSimilarRect (Rect *rectA, Rect *rectB, Rect *rectC)
|
|
{
|
|
if (rectA->left < rectB->left)
|
|
rectC->left = rectA->left;
|
|
else
|
|
rectC->left = rectB->left;
|
|
|
|
if (rectA->top < rectB->top)
|
|
rectC->top = rectA->top;
|
|
else
|
|
rectC->top = rectB->top;
|
|
|
|
if (rectA->right > rectB->right)
|
|
rectC->right = rectA->right;
|
|
else
|
|
rectC->right = rectB->right;
|
|
|
|
if (rectA->bottom > rectB->bottom)
|
|
rectC->bottom = rectA->bottom;
|
|
else
|
|
rectC->bottom = rectB->bottom;
|
|
}
|
|
|
|
//-------------------------------------------------------------- FrameRectSansCorners
|
|
// This is similar to the ToolBox FrameRect() call. However, it doesn'tÉ
|
|
// draw the pixels in the 4 corners of the Rect.
|
|
|
|
void FrameRectSansCorners (Rect *theRect)
|
|
{
|
|
MoveTo(theRect->left + 1, theRect->top);
|
|
LineTo(theRect->right - 2, theRect->top);
|
|
|
|
MoveTo(theRect->right - 1, theRect->top + 1);
|
|
LineTo(theRect->right - 1, theRect->bottom - 2);
|
|
|
|
MoveTo(theRect->left + 1, theRect->bottom - 1);
|
|
LineTo(theRect->right - 2, theRect->bottom - 1);
|
|
|
|
MoveTo(theRect->left, theRect->top + 1);
|
|
LineTo(theRect->left, theRect->bottom - 2);
|
|
}
|
|
|