GliderPRO/Sources/Render.c
John Calhoun 7a70d18ba6 First check-in.
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.
2016-01-28 08:10:38 -08:00

1 line
19 KiB
C
Executable File

//============================================================================
//----------------------------------------------------------------------------
// Render.c
//----------------------------------------------------------------------------
//============================================================================
#include "Externs.h"
#include "Environ.h"
#include "MainWindow.h"
#include "Objects.h"
#include "Play.h"
#include "Player.h"
#include "RectUtils.h"
#include "Room.h"
#include "RubberBands.h"
#define kMaxGarbageRects 48
void DrawReflection (gliderPtr, Boolean);
void RenderFlames (void);
void RenderPendulums (void);
void RenderFlyingPoints (void);
void RenderSparkles (void);
void RenderStars (void);
void RenderBands (void);
void RenderShreds (void);
void CopyRectsQD (void);
void CopyRectsAssm (void);
Rect work2MainRects[kMaxGarbageRects];
Rect back2WorkRects[kMaxGarbageRects];
Rect shieldRect;
RgnHandle mirrorRgn;
Point shieldPt;
long nextFrame;
short numWork2Main, numBack2Work;
Boolean hasMirror;
extern bandPtr bands;
extern sparklePtr sparkles;
extern flyingPtPtr flyingPoints;
extern flamePtr flames, tikiFlames, bbqCoals;
extern pendulumPtr pendulums;
extern starPtr theStars;
extern shredPtr shreds;
extern Rect sparkleSrc[];
extern Rect pointsSrc[];
extern Rect bandRects[];
extern savedType savedMaps[];
extern Rect shadowSrc[], justRoomsRect, movieRect;
extern short numBands, numStars, numShredded;
extern short numSparkles, numFlyingPts, numPendulums, clockFrame;
extern short numFlames, numSavedMaps, numTikiFlames, numCoals;
extern Boolean evenFrame, shadowVisible, twoPlayerGame, tvOn;
//============================================================== Functions
//-------------------------------------------------------------- AddRectToWorkRects
void AddRectToWorkRects (Rect *theRect)
{
if (numWork2Main < (kMaxGarbageRects - 1))
{
work2MainRects[numWork2Main] = *theRect;
if (work2MainRects[numWork2Main].left < justRoomsRect.left)
work2MainRects[numWork2Main].left = justRoomsRect.left;
else if (work2MainRects[numWork2Main].right > justRoomsRect.right)
work2MainRects[numWork2Main].right = justRoomsRect.right;
if (work2MainRects[numWork2Main].top < justRoomsRect.top)
work2MainRects[numWork2Main].top = justRoomsRect.top;
else if (work2MainRects[numWork2Main].bottom > justRoomsRect.bottom)
work2MainRects[numWork2Main].bottom = justRoomsRect.bottom;
numWork2Main++;
}
}
//-------------------------------------------------------------- AddRectToBackRects
void AddRectToBackRects (Rect *theRect)
{
if (numBack2Work < (kMaxGarbageRects - 1))
{
back2WorkRects[numBack2Work] = *theRect;
if (back2WorkRects[numBack2Work].left < 0)
back2WorkRects[numBack2Work].left = 0;
else if (back2WorkRects[numBack2Work].right > workSrcRect.right)
back2WorkRects[numBack2Work].right = workSrcRect.right;
if (back2WorkRects[numBack2Work].top < 0)
back2WorkRects[numBack2Work].top = 0;
else if (back2WorkRects[numBack2Work].bottom > workSrcRect.bottom)
back2WorkRects[numBack2Work].bottom = workSrcRect.bottom;
numBack2Work++;
}
}
//-------------------------------------------------------------- AddRectToWorkRectsWhole
void AddRectToWorkRectsWhole (Rect *theRect)
{
if (numWork2Main < (kMaxGarbageRects - 1))
{
if ((theRect->right <= workSrcRect.left) ||
(theRect->bottom <= workSrcRect.top) ||
(theRect->left >= workSrcRect.right) ||
(theRect->top >= workSrcRect.bottom))
return;
work2MainRects[numWork2Main] = *theRect;
if (work2MainRects[numWork2Main].left < workSrcRect.left)
work2MainRects[numWork2Main].left = workSrcRect.left;
else if (work2MainRects[numWork2Main].right > workSrcRect.right)
work2MainRects[numWork2Main].right = workSrcRect.right;
if (work2MainRects[numWork2Main].top < workSrcRect.top)
work2MainRects[numWork2Main].top = workSrcRect.top;
else if (work2MainRects[numWork2Main].bottom > workSrcRect.bottom)
work2MainRects[numWork2Main].bottom = workSrcRect.bottom;
if ((work2MainRects[numWork2Main].right ==
work2MainRects[numWork2Main].left) ||
(work2MainRects[numWork2Main].top ==
work2MainRects[numWork2Main].bottom))
return;
numWork2Main++;
}
}
//-------------------------------------------------------------- DrawReflection
void DrawReflection (gliderPtr thisGlider, Boolean oneOrTwo)
{
RgnHandle wasClip;
Rect src, dest;
short which;
if (thisGlider->dontDraw)
return;
if (thisGlider->facing == kFaceRight)
which = 0;
else
which = 1;
dest = thisGlider->dest;
QOffsetRect(&dest, playOriginH - 20, playOriginV - 16);
wasClip = NewRgn();
if (wasClip == nil)
return;
SetPort((GrafPtr)workSrcMap);
GetClip(wasClip);
SetClip(mirrorRgn);
if (oneOrTwo)
{
if (showFoil)
CopyMask((BitMap *)*GetGWorldPixMap(glid2SrcMap),
(BitMap *)*GetGWorldPixMap(glidMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&thisGlider->src, &thisGlider->mask, &dest);
else
CopyMask((BitMap *)*GetGWorldPixMap(glidSrcMap),
(BitMap *)*GetGWorldPixMap(glidMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&thisGlider->src, &thisGlider->mask, &dest);
}
else
{
CopyMask((BitMap *)*GetGWorldPixMap(glid2SrcMap),
(BitMap *)*GetGWorldPixMap(glidMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&thisGlider->src, &thisGlider->mask, &dest);
}
SetClip(wasClip);
DisposeRgn(wasClip);
src =thisGlider->whole;
QOffsetRect(&src, playOriginH - 20, playOriginV - 16);
AddRectToWorkRects(&src);
AddRectToBackRects(&dest);
}
//-------------------------------------------------------------- RenderFlames
void RenderFlames (void)
{
short i;
if ((numFlames == 0) && (numTikiFlames == 0) && (numCoals == 0))
return;
for (i = 0; i < numFlames; i++)
{
flames[i].mode++;
flames[i].src.top += 15;
flames[i].src.bottom += 15;
if (flames[i].mode >= kNumCandleFlames)
{
flames[i].mode = 0;
flames[i].src.top = 0;
flames[i].src.bottom = 15;
}
CopyBits((BitMap *)*GetGWorldPixMap(savedMaps[flames[i].who].map),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&flames[i].src, &flames[i].dest, srcCopy, nil);
AddRectToWorkRects(&flames[i].dest);
}
for (i = 0; i < numTikiFlames; i++)
{
tikiFlames[i].mode++;
tikiFlames[i].src.top += 10;
tikiFlames[i].src.bottom += 10;
if (tikiFlames[i].mode >= kNumTikiFlames)
{
tikiFlames[i].mode = 0;
tikiFlames[i].src.top = 0;
tikiFlames[i].src.bottom = 10;
}
CopyBits((BitMap *)*GetGWorldPixMap(savedMaps[tikiFlames[i].who].map),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&tikiFlames[i].src, &tikiFlames[i].dest, srcCopy, nil);
AddRectToWorkRects(&tikiFlames[i].dest);
}
for (i = 0; i < numCoals; i++)
{
bbqCoals[i].mode++;
bbqCoals[i].src.top += 9;
bbqCoals[i].src.bottom += 9;
if (bbqCoals[i].mode >= kNumBBQCoals)
{
bbqCoals[i].mode = 0;
bbqCoals[i].src.top = 0;
bbqCoals[i].src.bottom = 9;
}
CopyBits((BitMap *)*GetGWorldPixMap(savedMaps[bbqCoals[i].who].map),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&bbqCoals[i].src, &bbqCoals[i].dest, srcCopy, nil);
AddRectToWorkRects(&bbqCoals[i].dest);
}
}
//-------------------------------------------------------------- RenderPendulums
void RenderPendulums (void)
{
short i;
Boolean playedTikTok;
playedTikTok = false;
if (numPendulums == 0)
return;
clockFrame++;
if ((clockFrame == 10) || (clockFrame == 15))
{
if (clockFrame >= 15)
clockFrame = 0;
for (i = 0; i < numPendulums; i++)
{
if (pendulums[i].active)
{
if (pendulums[i].toOrFro)
{
pendulums[i].mode++;
pendulums[i].src.top += 28;
pendulums[i].src.bottom += 28;
if (pendulums[i].mode >= 2)
{
pendulums[i].toOrFro = !pendulums[i].toOrFro;
if (!playedTikTok)
{
PlayPrioritySound(kTikSound, kTikPriority);
playedTikTok = true;
}
}
}
else
{
pendulums[i].mode--;
pendulums[i].src.top -= 28;
pendulums[i].src.bottom -= 28;
if (pendulums[i].mode <= 0)
{
pendulums[i].toOrFro = !pendulums[i].toOrFro;
if (!playedTikTok)
{
PlayPrioritySound(kTokSound, kTokPriority);
playedTikTok = true;
}
}
}
CopyBits((BitMap *)*GetGWorldPixMap(savedMaps[pendulums[i].who].map),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&pendulums[i].src, &pendulums[i].dest, srcCopy, nil);
AddRectToWorkRects(&pendulums[i].dest);
}
}
}
}
//-------------------------------------------------------------- RenderFlyingPoints
void RenderFlyingPoints (void)
{
short i;
if (numFlyingPts == 0)
return;
for (i = 0; i < kMaxFlyingPts; i++)
{
if (flyingPoints[i].mode != -1)
{
if (flyingPoints[i].mode > flyingPoints[i].stop)
{
flyingPoints[i].mode = flyingPoints[i].start;
flyingPoints[i].loops++;
}
if (flyingPoints[i].loops >= kMaxFlyingPointsLoop)
{
AddRectToWorkRects(&flyingPoints[i].dest);
flyingPoints[i].mode = -1;
numFlyingPts--;
}
else
{
flyingPoints[i].dest.left += flyingPoints[i].hVel;
flyingPoints[i].dest.right += flyingPoints[i].hVel;
if (flyingPoints[i].hVel > 0)
flyingPoints[i].whole.right = flyingPoints[i].dest.right;
else
flyingPoints[i].whole.left = flyingPoints[i].dest.left;
flyingPoints[i].dest.top += flyingPoints[i].vVel;
flyingPoints[i].dest.bottom += flyingPoints[i].vVel;
if (flyingPoints[i].vVel > 0)
flyingPoints[i].whole.bottom = flyingPoints[i].dest.bottom;
else
flyingPoints[i].whole.top = flyingPoints[i].dest.top;
CopyMask((BitMap *)*GetGWorldPixMap(pointsSrcMap),
(BitMap *)*GetGWorldPixMap(pointsMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&pointsSrc[flyingPoints[i].mode],
&pointsSrc[flyingPoints[i].mode],
&flyingPoints[i].dest);
AddRectToWorkRects(&flyingPoints[i].whole);
AddRectToBackRects(&flyingPoints[i].dest);
flyingPoints[i].whole = flyingPoints[i].dest;
flyingPoints[i].mode++;
}
}
}
}
//-------------------------------------------------------------- RenderSparkles
void RenderSparkles (void)
{
short i;
if (numSparkles == 0)
return;
for (i = 0; i < kMaxSparkles; i++)
{
if (sparkles[i].mode != -1)
{
if (sparkles[i].mode >= kNumSparkleModes)
{
AddRectToWorkRects(&sparkles[i].bounds);
sparkles[i].mode = -1;
numSparkles--;
}
else
{
CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap),
(BitMap *)*GetGWorldPixMap(bonusMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&sparkleSrc[sparkles[i].mode],
&sparkleSrc[sparkles[i].mode],
&sparkles[i].bounds);
AddRectToWorkRects(&sparkles[i].bounds);
AddRectToBackRects(&sparkles[i].bounds);
sparkles[i].mode++;
}
}
}
}
//-------------------------------------------------------------- RenderStars
void RenderStars (void)
{
short i;
if (numStars == 0)
return;
for (i = 0; i < numStars; i++)
{
if (theStars[i].mode != -1)
{
theStars[i].mode++;
theStars[i].src.top += 31;
theStars[i].src.bottom += 31;
if (theStars[i].mode >= 6)
{
theStars[i].mode = 0;
theStars[i].src.top = 0;
theStars[i].src.bottom = 31;
}
CopyBits((BitMap *)*GetGWorldPixMap(savedMaps[theStars[i].who].map),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&theStars[i].src, &theStars[i].dest, srcCopy, nil);
AddRectToWorkRects(&theStars[i].dest);
}
}
}
//-------------------------------------------------------------- RenderGlider
void RenderGlider (gliderPtr thisGlider, Boolean oneOrTwo)
{
Rect src, dest;
short which;
if (thisGlider->dontDraw)
return;
if (thisGlider->facing == kFaceRight)
which = 0;
else
which = 1;
if (shadowVisible)
{
dest = thisGlider->destShadow;
QOffsetRect(&dest, playOriginH, playOriginV);
if ((thisGlider->mode == kGliderComingUp) ||
(thisGlider->mode == kGliderGoingDown))
{
src = shadowSrc[which];
src.right = src.left + (dest.right - dest.left);
CopyMask((BitMap *)*GetGWorldPixMap(shadowSrcMap),
(BitMap *)*GetGWorldPixMap(shadowMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&src, &src, &dest);
}
else if (thisGlider->mode == kGliderComingDown)
{
src = shadowSrc[which];
src.left = src.right - (dest.right - dest.left);
CopyMask((BitMap *)*GetGWorldPixMap(shadowSrcMap),
(BitMap *)*GetGWorldPixMap(shadowMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&src, &src, &dest);
}
else
CopyMask((BitMap *)*GetGWorldPixMap(shadowSrcMap),
(BitMap *)*GetGWorldPixMap(shadowMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&shadowSrc[which], &shadowSrc[which], &dest);
src =thisGlider->wholeShadow;
QOffsetRect(&src, playOriginH, playOriginV);
AddRectToWorkRects(&src);
AddRectToBackRects(&dest);
}
dest = thisGlider->dest;
QOffsetRect(&dest, playOriginH, playOriginV);
if (oneOrTwo)
{
if ((!twoPlayerGame) && (showFoil))
CopyMask((BitMap *)*GetGWorldPixMap(glid2SrcMap),
(BitMap *)*GetGWorldPixMap(glidMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&thisGlider->src, &thisGlider->mask, &dest);
else
CopyMask((BitMap *)*GetGWorldPixMap(glidSrcMap),
(BitMap *)*GetGWorldPixMap(glidMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&thisGlider->src, &thisGlider->mask, &dest);
}
else
{
CopyMask((BitMap *)*GetGWorldPixMap(glid2SrcMap),
(BitMap *)*GetGWorldPixMap(glidMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&thisGlider->src, &thisGlider->mask, &dest);
}
src =thisGlider->whole;
QOffsetRect(&src, playOriginH, playOriginV);
AddRectToWorkRects(&src);
AddRectToBackRects(&dest);
}
//-------------------------------------------------------------- RenderBands
void RenderBands (void)
{
Rect dest;
short i;
if (numBands == 0)
return;
for (i = 0; i < numBands; i++)
{
dest = bands[i].dest;
QOffsetRect(&dest, playOriginH, playOriginV);
CopyMask((BitMap *)*GetGWorldPixMap(bandsSrcMap),
(BitMap *)*GetGWorldPixMap(bandsMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&bandRects[bands[i].mode],
&bandRects[bands[i].mode], &dest);
AddRectToWorkRects(&dest);
AddRectToBackRects(&dest);
}
}
//-------------------------------------------------------------- RenderShreds
void RenderShreds (void)
{
Rect src, dest;
short i, high;
if (numShredded > 0)
{
for (i = 0; i < numShredded; i++)
{
if (shreds[i].frame == 0)
{
shreds[i].bounds.bottom += 1;
high = shreds[i].bounds.bottom - shreds[i].bounds.top;
if (high >= 35)
shreds[i].frame = 1;
src = shredSrcRect;
src.top = src.bottom - high;
dest = shreds[i].bounds;
QOffsetRect(&dest, playOriginH, playOriginV);
CopyMask((BitMap *)*GetGWorldPixMap(shredSrcMap),
(BitMap *)*GetGWorldPixMap(shredMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&src, &src, &dest);
AddRectToBackRects(&dest);
dest.top--;
AddRectToWorkRects(&dest);
PlayPrioritySound(kShredSound, kShredPriority);
}
else if (shreds[i].frame < 20)
{
shreds[i].bounds.top += 4;
shreds[i].bounds.bottom += 4;
dest = shreds[i].bounds;
QOffsetRect(&dest, playOriginH, playOriginV);
shreds[i].frame++;
if (shreds[i].frame < 20)
{
CopyMask((BitMap *)*GetGWorldPixMap(shredSrcMap),
(BitMap *)*GetGWorldPixMap(shredMaskMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&shredSrcRect, &shredSrcRect, &dest);
}
else
{
AddSparkle(&shreds[i].bounds);
PlayPrioritySound(kFadeOutSound, kFadeOutPriority);
}
AddRectToBackRects(&dest);
dest.top -= 4;
AddRectToWorkRects(&dest);
}
}
}
}
//-------------------------------------------------------------- CopyRectsQD
void CopyRectsQD (void)
{
short i;
for (i = 0; i < numWork2Main; i++)
{
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
GetPortBitMapForCopyBits(GetWindowPort(mainWindow)),
&work2MainRects[i], &work2MainRects[i],
srcCopy, nil);
}
for (i = 0; i < numBack2Work; i++)
{
CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
&back2WorkRects[i], &back2WorkRects[i],
srcCopy, nil);
}
}
//-------------------------------------------------------------- RenderFrame
void RenderFrame (void)
{
if (hasMirror)
{
DrawReflection(&theGlider, true);
if (twoPlayerGame)
DrawReflection(&theGlider2, false);
}
HandleGrease();
RenderPendulums();
if (evenFrame)
RenderFlames();
else
RenderStars();
RenderDynamics();
RenderFlyingPoints();
RenderSparkles();
RenderGlider(&theGlider, true);
if (twoPlayerGame)
RenderGlider(&theGlider2, false);
RenderShreds();
RenderBands();
while (TickCount() < nextFrame)
{
}
nextFrame = TickCount() + kTicksPerFrame;
CopyRectsQD();
numWork2Main = 0;
numBack2Work = 0;
}
//-------------------------------------------------------------- InitGarbageRects
void InitGarbageRects (void)
{
short i;
numWork2Main = 0;
numBack2Work = 0;
numSparkles = 0;
for (i = 0; i < kMaxSparkles; i++)
sparkles[i].mode = -1;
numFlyingPts = 0;
for (i = 0; i < kMaxFlyingPts; i++)
flyingPoints[i].mode = -1;
nextFrame = TickCount() + kTicksPerFrame;
}
//-------------------------------------------------------------- CopyRectBackToWork
void CopyRectBackToWork (Rect *theRect)
{
CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap),
(BitMap *)*GetGWorldPixMap(workSrcMap),
theRect, theRect, srcCopy, nil);
}
//-------------------------------------------------------------- CopyRectWorkToBack
void CopyRectWorkToBack (Rect *theRect)
{
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
(BitMap *)*GetGWorldPixMap(backSrcMap),
theRect, theRect, srcCopy, nil);
}
//-------------------------------------------------------------- CopyRectWorkToMain
void CopyRectWorkToMain (Rect *theRect)
{
CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap),
GetPortBitMapForCopyBits(GetWindowPort(mainWindow)),
theRect, theRect, srcCopy, nil);
}
//-------------------------------------------------------------- CopyRectMainToWork
void CopyRectMainToWork (Rect *theRect)
{
CopyBits(GetPortBitMapForCopyBits(GetWindowPort(mainWindow)),
(BitMap *)*GetGWorldPixMap(workSrcMap),
theRect, theRect, srcCopy, nil);
}
//-------------------------------------------------------------- CopyRectMainToBack
void CopyRectMainToBack (Rect *theRect)
{
CopyBits(GetPortBitMapForCopyBits(GetWindowPort(mainWindow)),
(BitMap *)*GetGWorldPixMap(backSrcMap),
theRect, theRect, srcCopy, nil);
}
//-------------------------------------------------------------- AddToMirrorRegion
void AddToMirrorRegion (Rect *theRect)
{
RgnHandle tempRgn;
if (mirrorRgn == nil)
{
mirrorRgn = NewRgn();
if (mirrorRgn != nil)
RectRgn(mirrorRgn, theRect);
}
else
{
tempRgn = NewRgn();
if (tempRgn != nil)
{
RectRgn(tempRgn, theRect);
UnionRgn(mirrorRgn, tempRgn, mirrorRgn);
DisposeRgn(tempRgn);
}
}
hasMirror = true;
}
//-------------------------------------------------------------- ZeroMirrorRegion
void ZeroMirrorRegion (void)
{
if (mirrorRgn != nil)
DisposeRgn(mirrorRgn);
mirrorRgn = nil;
hasMirror = false;
}