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
12 KiB
C
Executable File
1 line
12 KiB
C
Executable File
//============================================================================
|
|
//----------------------------------------------------------------------------
|
|
// GameOver.c
|
|
//----------------------------------------------------------------------------
|
|
//============================================================================
|
|
|
|
|
|
#include <ToolUtils.h>
|
|
#include "Externs.h"
|
|
#include "Environ.h"
|
|
#include "MainWindow.h"
|
|
#include "Objects.h"
|
|
#include "RectUtils.h"
|
|
#include "Utilities.h"
|
|
|
|
|
|
#define kNumCountDownFrames 16
|
|
#define kPageFrames 14
|
|
#define kPagesPictID 1990
|
|
#define kPagesMaskID 1989
|
|
#define kLettersPictID 1988
|
|
#define kMilkywayPictID 1021
|
|
|
|
|
|
typedef struct
|
|
{
|
|
Rect dest, was;
|
|
short frame, counter;
|
|
Boolean stuck;
|
|
} pageType, *pagePtr;
|
|
|
|
|
|
void DoGameOverStarAnimation (void);
|
|
void SetUpFinalScreen (void);
|
|
void InitDiedGameOver (void);
|
|
void HandlePages (void);
|
|
void DrawPages (void);
|
|
|
|
|
|
pageType pages[8];
|
|
Rect pageSrcRect, pageSrc[kPageFrames], lettersSrc[8], angelSrcRect;
|
|
RgnHandle roomRgn;
|
|
GWorldPtr pageSrcMap, gameOverSrcMap, angelSrcMap;
|
|
GWorldPtr pageMaskMap, angelMaskMap;
|
|
short countDown, stopPages, pagesStuck;
|
|
Boolean gameOver;
|
|
|
|
extern Rect justRoomsRect;
|
|
extern short splashOriginH, splashOriginV, numWork2Main;
|
|
extern short numBack2Work;
|
|
extern Boolean playing, shadowVisible, demoGoing;
|
|
|
|
|
|
//============================================================== Functions
|
|
//-------------------------------------------------------------- DoGameOver
|
|
|
|
// Handles a game over. This is a game over where the player hasÉ
|
|
// completed the house.
|
|
|
|
void DoGameOver (void)
|
|
{
|
|
playing = false;
|
|
SetUpFinalScreen();
|
|
SetPort((GrafPtr)mainWindow);
|
|
ColorRect(&mainWindowRect, 244);
|
|
DoGameOverStarAnimation();
|
|
if (!TestHighScore())
|
|
RedrawSplashScreen();
|
|
}
|
|
|
|
//-------------------------------------------------------------- SetUpFinalScreen
|
|
|
|
// This sets up the game over screen (again, this function is for whenÉ
|
|
// the player completes the house).
|
|
|
|
void SetUpFinalScreen (void)
|
|
{
|
|
Rect tempRect;
|
|
Str255 tempStr, subStr;
|
|
short count, offset, i, textDown;
|
|
char wasState;
|
|
|
|
SetPort((GrafPtr)workSrcMap);
|
|
ColorRect(&workSrcRect, 244);
|
|
QSetRect(&tempRect, 0, 0, 640, 460);
|
|
CenterRectInRect(&tempRect, &workSrcRect);
|
|
LoadScaledGraphic(kMilkywayPictID, &tempRect);
|
|
textDown = tempRect.top;
|
|
if (textDown < 0)
|
|
textDown = 0;
|
|
|
|
wasState = HGetState((Handle)thisHouse);
|
|
HLock((Handle)thisHouse);
|
|
PasStringCopy((*thisHouse)->trailer, tempStr);
|
|
HSetState((Handle)thisHouse, wasState);
|
|
|
|
count = 0;
|
|
do
|
|
{
|
|
GetLineOfText(tempStr, count, subStr);
|
|
offset = ((thisMac.screen.right - thisMac.screen.left) -
|
|
TextWidth(subStr, 1, subStr[0])) / 2;
|
|
TextFont(applFont);
|
|
TextFace(bold);
|
|
TextSize(12);
|
|
ForeColor(blackColor);
|
|
MoveTo(offset + 1, textDown + 33 + (count * 20));
|
|
DrawString(subStr);
|
|
ForeColor(whiteColor);
|
|
MoveTo(offset, textDown + 32 + (count * 20));
|
|
DrawString(subStr);
|
|
ForeColor(blackColor);
|
|
count++;
|
|
}
|
|
while (subStr[0] > 0);
|
|
|
|
CopyRectWorkToBack(&workSrcRect);
|
|
|
|
for (i = 0; i < 5; i++) // initialize the falling stars
|
|
{
|
|
pages[i].dest = starSrc[0];
|
|
QOffsetRect(&pages[i].dest,
|
|
workSrcRect.right + RandomInt(workSrcRect.right / 5) +
|
|
(workSrcRect.right/ 4) * i,
|
|
RandomInt(workSrcRect.bottom) - workSrcRect.bottom / 2);
|
|
pages[i].was = pages[i].dest;
|
|
pages[i].frame = RandomInt(6);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------- DoGameOverStarAnimation
|
|
|
|
// This handles the falling stars and the flying angel when a playerÉ
|
|
// completes a house.
|
|
|
|
void DoGameOverStarAnimation (void)
|
|
{
|
|
#define kStarFalls 8
|
|
EventRecord theEvent;
|
|
KeyMap theKeys;
|
|
Rect angelDest;
|
|
long nextLoop;
|
|
short which, i, count, pass;
|
|
Boolean noInteruption;
|
|
|
|
angelDest = angelSrcRect;
|
|
QOffsetRect(&angelDest, -96, 0);
|
|
noInteruption = true;
|
|
nextLoop = TickCount() + 2;
|
|
count = 0;
|
|
pass = 0;
|
|
FlushEvents(everyEvent, 0);
|
|
|
|
while (noInteruption)
|
|
{
|
|
if ((angelDest.left % 32) == 0) // add a star
|
|
{
|
|
PlayPrioritySound(kMysticSound, kMysticPriority);
|
|
which = angelDest.left / 32;
|
|
which = which % 5;
|
|
ZeroRectCorner(&pages[which].dest);
|
|
QOffsetRect(&pages[which].dest, angelDest.left, angelDest.bottom);
|
|
if (count < (which + 1))
|
|
count = which + 1;
|
|
}
|
|
|
|
for (i = 0; i < count; i++)
|
|
{
|
|
pages[i].frame++;
|
|
if (pages[i].frame >= 6)
|
|
pages[i].frame = 0;
|
|
|
|
CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap),
|
|
(BitMap *)*GetGWorldPixMap(bonusMaskMap),
|
|
(BitMap *)*GetGWorldPixMap(workSrcMap),
|
|
&starSrc[pages[i].frame],
|
|
&starSrc[pages[i].frame],
|
|
&pages[i].dest);
|
|
|
|
pages[i].was = pages[i].dest;
|
|
pages[i].was.top -= kStarFalls;
|
|
|
|
AddRectToWorkRectsWhole(&pages[i].was);
|
|
AddRectToBackRects(&pages[i].dest);
|
|
|
|
if (pages[i].dest.top < workSrcRect.bottom)
|
|
QOffsetRect(&pages[i].dest, 0, kStarFalls);
|
|
}
|
|
|
|
if (angelDest.left <= (workSrcRect.right + 2))
|
|
{
|
|
CopyMask((BitMap *)*GetGWorldPixMap(angelSrcMap),
|
|
(BitMap *)*GetGWorldPixMap(angelMaskMap),
|
|
(BitMap *)*GetGWorldPixMap(workSrcMap),
|
|
&angelSrcRect, &angelSrcRect, &angelDest);
|
|
angelDest.left -= 2;
|
|
AddRectToWorkRectsWhole(&angelDest);
|
|
angelDest.left += 2;
|
|
AddRectToBackRects(&angelDest);
|
|
QOffsetRect(&angelDest, 2, 0);
|
|
pass = 0;
|
|
}
|
|
|
|
CopyRectsQD();
|
|
|
|
numWork2Main = 0;
|
|
numBack2Work = 0;
|
|
|
|
do
|
|
{
|
|
GetKeys(theKeys);
|
|
if ((BitTst(&theKeys, kCommandKeyMap)) || (BitTst(&theKeys, kOptionKeyMap)) ||
|
|
(BitTst(&theKeys, kShiftKeyMap)) || (BitTst(&theKeys, kControlKeyMap)))
|
|
noInteruption = false;
|
|
if (GetNextEvent(everyEvent, &theEvent))
|
|
if ((theEvent.what == mouseDown) || (theEvent.what == keyDown))
|
|
noInteruption = false;
|
|
}
|
|
while (TickCount() < nextLoop);
|
|
nextLoop = TickCount() + 2;
|
|
|
|
if (pass < 80)
|
|
pass++;
|
|
else
|
|
{
|
|
WaitForInputEvent(5);
|
|
noInteruption = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------- FlagGameOver
|
|
|
|
// Called to indicate (flag) that a game is over. Actual game overÉ
|
|
// sequence comes up after a short delay.
|
|
|
|
void FlagGameOver (void)
|
|
{
|
|
gameOver = true;
|
|
countDown = kNumCountDownFrames;
|
|
SetMusicalMode(kPlayWholeScoreMode);
|
|
}
|
|
|
|
//-------------------------------------------------------------- InitDiedGameOver
|
|
// This is called when a game is over due to the fact that the playerÉ
|
|
// lost their last glider (died), not due to getting through the entireÉ
|
|
// house. This function initializes the strucures/variables.
|
|
|
|
void InitDiedGameOver (void)
|
|
{
|
|
#define kPageSpacing 40
|
|
#define kPageRightOffset 128
|
|
#define kPageBackUp 128
|
|
short i;
|
|
CGrafPtr wasCPort;
|
|
GDHandle wasWorld;
|
|
OSErr theErr;
|
|
|
|
GetGWorld(&wasCPort, &wasWorld);
|
|
|
|
QSetRect(&pageSrcRect, 0, 0, 25, 32 * 8);
|
|
theErr = CreateOffScreenGWorld(&gameOverSrcMap, &pageSrcRect, kPreferredDepth);
|
|
SetGWorld(gameOverSrcMap, nil);
|
|
LoadGraphic(kLettersPictID);
|
|
|
|
QSetRect(&pageSrcRect, 0, 0, 32, 32 * kPageFrames);
|
|
theErr = CreateOffScreenGWorld(&pageSrcMap, &pageSrcRect, kPreferredDepth);
|
|
SetGWorld(pageSrcMap, nil);
|
|
LoadGraphic(kPagesPictID);
|
|
|
|
theErr = CreateOffScreenGWorld(&pageMaskMap, &pageSrcRect, 1);
|
|
SetGWorld(pageMaskMap, nil);
|
|
LoadGraphic(kPagesMaskID);
|
|
|
|
for (i = 0; i < kPageFrames; i++) // initialize src page rects
|
|
{
|
|
QSetRect(&pageSrc[i], 0, 0, 32, 32);
|
|
QOffsetRect(&pageSrc[i], 0, 32 * i);
|
|
}
|
|
|
|
for (i = 0; i < 8; i++) // initialize dest page rects
|
|
{
|
|
QSetRect(&pages[i].dest, 0, 0, 32, 32);
|
|
CenterRectInRect(&pages[i].dest, &thisMac.screen);
|
|
QOffsetRect(&pages[i].dest, -thisMac.screen.left, -thisMac.screen.top);
|
|
if (i < 4)
|
|
QOffsetRect(&pages[i].dest, -kPageSpacing * (4 - i), 0);
|
|
else
|
|
QOffsetRect(&pages[i].dest, kPageSpacing * (i - 3), 0);
|
|
QOffsetRect(&pages[i].dest, (thisMac.screen.right - thisMac.screen.left) / -2,
|
|
(thisMac.screen.right - thisMac.screen.left) / -2);
|
|
if (pages[i].dest.left % 2 == 1)
|
|
QOffsetRect(&pages[i].dest, 1, 0);
|
|
pages[i].was = pages[i].dest;
|
|
pages[i].frame = 0;
|
|
pages[i].counter = RandomInt(32);
|
|
pages[i].stuck = false;
|
|
}
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
QSetRect(&lettersSrc[i], 0, 0, 25, 32);
|
|
QOffsetRect(&lettersSrc[i], 0, 32 * i);
|
|
}
|
|
|
|
roomRgn = NewRgn();
|
|
RectRgn(roomRgn, &justRoomsRect);
|
|
pagesStuck = 0;
|
|
stopPages = ((thisMac.screen.bottom - thisMac.screen.top) / 2) - 16;
|
|
}
|
|
|
|
//-------------------------------------------------------------- HandlePages
|
|
|
|
// This handles the pieces of paper that blow across the screen.
|
|
|
|
void HandlePages (void)
|
|
{
|
|
short i;
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
if ((pages[i].dest.bottom + RandomInt(8)) > stopPages)
|
|
{
|
|
pages[i].frame = 0;
|
|
if (!pages[i].stuck)
|
|
{
|
|
pages[i].dest.right = pages[i].dest.left + 25;
|
|
pages[i].stuck = true;
|
|
pagesStuck++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (pages[i].frame == 0)
|
|
{
|
|
pages[i].counter--;
|
|
if (pages[i].counter <= 0)
|
|
pages[i].frame = 1;
|
|
}
|
|
else if (pages[i].frame == 7)
|
|
{
|
|
pages[i].counter--;
|
|
if (pages[i].counter <= 0)
|
|
{
|
|
pages[i].frame = 8;
|
|
if (RandomInt(2) == 0)
|
|
PlayPrioritySound(kPaper3Sound, kPapersPriority);
|
|
else
|
|
PlayPrioritySound(kPaper4Sound, kPapersPriority);
|
|
}
|
|
else
|
|
QOffsetRect(&pages[i].dest, 10, 10);
|
|
}
|
|
else
|
|
{
|
|
pages[i].frame++;
|
|
switch (pages[i].frame)
|
|
{
|
|
case 5:
|
|
QOffsetRect(&pages[i].dest, 6, 6);
|
|
break;
|
|
|
|
case 6:
|
|
QOffsetRect(&pages[i].dest, 8, 8);
|
|
break;
|
|
|
|
case 7:
|
|
QOffsetRect(&pages[i].dest, 8, 8);
|
|
pages[i].counter = RandomInt(4) + 4;
|
|
break;
|
|
|
|
case 8:
|
|
case 9:
|
|
QOffsetRect(&pages[i].dest, 8, 8);
|
|
break;
|
|
|
|
case 10:
|
|
QOffsetRect(&pages[i].dest, 6, 6);
|
|
break;
|
|
|
|
case kPageFrames:
|
|
QOffsetRect(&pages[i].dest, 8, 0);
|
|
pages[i].frame = 0;
|
|
pages[i].counter = RandomInt(8) + 8;
|
|
if (RandomInt(2) == 0)
|
|
PlayPrioritySound(kPaper1Sound, kPapersPriority);
|
|
else
|
|
PlayPrioritySound(kPaper2Sound, kPapersPriority);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------- DrawPages
|
|
|
|
// This function does the drawing for the pieces of paper that blowÉ
|
|
// across the screen.
|
|
|
|
void DrawPages (void)
|
|
{
|
|
short i;
|
|
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
if (pages[i].stuck)
|
|
{
|
|
CopyBits((BitMap *)*GetGWorldPixMap(gameOverSrcMap),
|
|
(BitMap *)*GetGWorldPixMap(workSrcMap),
|
|
&lettersSrc[i], &pages[i].dest,
|
|
srcCopy, roomRgn);
|
|
}
|
|
else
|
|
{
|
|
CopyMask((BitMap *)*GetGWorldPixMap(pageSrcMap),
|
|
(BitMap *)*GetGWorldPixMap(pageMaskMap),
|
|
(BitMap *)*GetGWorldPixMap(workSrcMap),
|
|
&pageSrc[pages[i].frame],
|
|
&pageSrc[pages[i].frame],
|
|
&pages[i].dest);
|
|
}
|
|
|
|
QUnionSimilarRect(&pages[i].dest, &pages[i].was, &pages[i].was);
|
|
AddRectToWorkRects(&pages[i].was);
|
|
AddRectToBackRects(&pages[i].dest);
|
|
|
|
CopyRectsQD();
|
|
|
|
numWork2Main = 0;
|
|
numBack2Work = 0;
|
|
|
|
pages[i].was = pages[i].dest;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------- DoDiedGameOver
|
|
|
|
// This is called when a game is over due to the fact that the playerÉ
|
|
// lost their last glider (died), not due to getting through the entireÉ
|
|
// house.
|
|
|
|
void DoDiedGameOver (void)
|
|
{
|
|
EventRecord theEvent;
|
|
KeyMap theKeys;
|
|
long nextLoop;
|
|
Boolean userAborted;
|
|
|
|
userAborted = false;
|
|
InitDiedGameOver();
|
|
CopyRectMainToWork(&workSrcRect);
|
|
CopyRectMainToBack(&workSrcRect);
|
|
FlushEvents(everyEvent, 0);
|
|
|
|
nextLoop = TickCount() + 2;
|
|
while (pagesStuck < 8)
|
|
{
|
|
HandlePages();
|
|
DrawPages();
|
|
do
|
|
{
|
|
GetKeys(theKeys);
|
|
if ((BitTst(&theKeys, kCommandKeyMap)) || (BitTst(&theKeys, kOptionKeyMap)) ||
|
|
(BitTst(&theKeys, kShiftKeyMap)) || (BitTst(&theKeys, kControlKeyMap)))
|
|
{
|
|
pagesStuck = 8;
|
|
userAborted = true;
|
|
}
|
|
if (GetNextEvent(everyEvent, &theEvent))
|
|
if ((theEvent.what == mouseDown) || (theEvent.what == keyDown))
|
|
{
|
|
pagesStuck = 8;
|
|
userAborted = true;
|
|
}
|
|
}
|
|
while (TickCount() < nextLoop);
|
|
nextLoop = TickCount() + 2;
|
|
}
|
|
|
|
if (roomRgn != nil)
|
|
DisposeRgn(roomRgn);
|
|
|
|
DisposeGWorld(pageSrcMap);
|
|
pageSrcMap = nil;
|
|
|
|
DisposeGWorld(pageMaskMap);
|
|
pageMaskMap = nil;
|
|
|
|
DisposeGWorld(gameOverSrcMap);
|
|
gameOverSrcMap = nil;
|
|
playing = false;
|
|
|
|
if (demoGoing)
|
|
{
|
|
if (!userAborted)
|
|
WaitForInputEvent(1);
|
|
}
|
|
else
|
|
{
|
|
if (!userAborted)
|
|
WaitForInputEvent(10);
|
|
TestHighScore();
|
|
}
|
|
RedrawSplashScreen();
|
|
}
|
|
|