forked from softdorothy/GliderPRO
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathGameOver.c
executable file
·507 lines (428 loc) · 12.1 KB
/
GameOver.c
1
//============================================================================//----------------------------------------------------------------------------// 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 1021typedef 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();}