diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f42bf03 --- /dev/null +++ b/.gitignore @@ -0,0 +1,19 @@ +*.suo +*.db +*.opendb +*.ipch +*.pch +*.user +*.mcp +*.obj +*.log +*.tlog +*.lastbuildstate +*.dll +*.exe +*.exp +*.ilk +*.lib +*.pdb +.vs/* +Packaged/* diff --git a/Common.props b/Common.props new file mode 100644 index 0000000..81ac958 --- /dev/null +++ b/Common.props @@ -0,0 +1,12 @@ + + + + + + + + $(SolutionDir)Common;%(AdditionalIncludeDirectories) + + + + \ No newline at end of file diff --git a/Common/CoreDefs.h b/Common/CoreDefs.h new file mode 100644 index 0000000..7ff9917 --- /dev/null +++ b/Common/CoreDefs.h @@ -0,0 +1,34 @@ +#pragma once + +#ifndef __PL_COREDEFS_H__ +#define __PL_COREDEFS_H__ + +#if __cplusplus >= 199711L +#define PL_IS_CPP11 1 +#else +#define PL_IS_CPP11 0 +#endif + +#if PL_IS_CPP11 +#define PL_DELETED = delete +#else +#ifndef nullptr +#define nullptr 0 +#endif + +#ifndef override +#define override +#endif + +#ifndef final +#define final +#endif + +#define PL_DELETED +#endif + + +static const size_t PL_SYSTEM_MEMORY_ALIGNMENT = 16; + + +#endif diff --git a/GlidePort.sln b/GlidePort.sln new file mode 100644 index 0000000..8dc0ad4 --- /dev/null +++ b/GlidePort.sln @@ -0,0 +1,81 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2020 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hqx2bin", "hqx2bin\hqx2bin.vcxproj", "{45B1B18C-C846-4044-9206-74F58DFC5E88}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PortabilityLayer", "PortabilityLayer\PortabilityLayer.vcxproj", "{6EC62B0F-9353-40A4-A510-3788F1368B33}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MiniRez", "MiniRez\MiniRez.vcxproj", "{2FF15659-5C72-48B8-B55B-3C658E4125B5}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GpApp", "GpApp\GpApp.vcxproj", "{6233C3F2-5781-488E-B190-4FA8836F5A77}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GpD3D", "GpD3D\GpD3D.vcxproj", "{0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hqx2gp", "hqx2gp\hqx2gp.vcxproj", "{5FDE4822-C771-46A5-B6B2-FD12BACE86BF}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {45B1B18C-C846-4044-9206-74F58DFC5E88}.Debug|x64.ActiveCfg = Debug|x64 + {45B1B18C-C846-4044-9206-74F58DFC5E88}.Debug|x64.Build.0 = Debug|x64 + {45B1B18C-C846-4044-9206-74F58DFC5E88}.Debug|x86.ActiveCfg = Debug|Win32 + {45B1B18C-C846-4044-9206-74F58DFC5E88}.Debug|x86.Build.0 = Debug|Win32 + {45B1B18C-C846-4044-9206-74F58DFC5E88}.Release|x64.ActiveCfg = Release|x64 + {45B1B18C-C846-4044-9206-74F58DFC5E88}.Release|x64.Build.0 = Release|x64 + {45B1B18C-C846-4044-9206-74F58DFC5E88}.Release|x86.ActiveCfg = Release|Win32 + {45B1B18C-C846-4044-9206-74F58DFC5E88}.Release|x86.Build.0 = Release|Win32 + {6EC62B0F-9353-40A4-A510-3788F1368B33}.Debug|x64.ActiveCfg = Debug|x64 + {6EC62B0F-9353-40A4-A510-3788F1368B33}.Debug|x64.Build.0 = Debug|x64 + {6EC62B0F-9353-40A4-A510-3788F1368B33}.Debug|x86.ActiveCfg = Debug|Win32 + {6EC62B0F-9353-40A4-A510-3788F1368B33}.Debug|x86.Build.0 = Debug|Win32 + {6EC62B0F-9353-40A4-A510-3788F1368B33}.Release|x64.ActiveCfg = Release|x64 + {6EC62B0F-9353-40A4-A510-3788F1368B33}.Release|x64.Build.0 = Release|x64 + {6EC62B0F-9353-40A4-A510-3788F1368B33}.Release|x86.ActiveCfg = Release|Win32 + {6EC62B0F-9353-40A4-A510-3788F1368B33}.Release|x86.Build.0 = Release|Win32 + {2FF15659-5C72-48B8-B55B-3C658E4125B5}.Debug|x64.ActiveCfg = Debug|x64 + {2FF15659-5C72-48B8-B55B-3C658E4125B5}.Debug|x64.Build.0 = Debug|x64 + {2FF15659-5C72-48B8-B55B-3C658E4125B5}.Debug|x86.ActiveCfg = Debug|Win32 + {2FF15659-5C72-48B8-B55B-3C658E4125B5}.Debug|x86.Build.0 = Debug|Win32 + {2FF15659-5C72-48B8-B55B-3C658E4125B5}.Release|x64.ActiveCfg = Release|x64 + {2FF15659-5C72-48B8-B55B-3C658E4125B5}.Release|x64.Build.0 = Release|x64 + {2FF15659-5C72-48B8-B55B-3C658E4125B5}.Release|x86.ActiveCfg = Release|Win32 + {2FF15659-5C72-48B8-B55B-3C658E4125B5}.Release|x86.Build.0 = Release|Win32 + {6233C3F2-5781-488E-B190-4FA8836F5A77}.Debug|x64.ActiveCfg = Debug|x64 + {6233C3F2-5781-488E-B190-4FA8836F5A77}.Debug|x64.Build.0 = Debug|x64 + {6233C3F2-5781-488E-B190-4FA8836F5A77}.Debug|x86.ActiveCfg = Debug|Win32 + {6233C3F2-5781-488E-B190-4FA8836F5A77}.Debug|x86.Build.0 = Debug|Win32 + {6233C3F2-5781-488E-B190-4FA8836F5A77}.Release|x64.ActiveCfg = Release|x64 + {6233C3F2-5781-488E-B190-4FA8836F5A77}.Release|x64.Build.0 = Release|x64 + {6233C3F2-5781-488E-B190-4FA8836F5A77}.Release|x86.ActiveCfg = Release|Win32 + {6233C3F2-5781-488E-B190-4FA8836F5A77}.Release|x86.Build.0 = Release|Win32 + {0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Debug|x64.ActiveCfg = Debug|x64 + {0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Debug|x64.Build.0 = Debug|x64 + {0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Debug|x86.ActiveCfg = Debug|Win32 + {0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Debug|x86.Build.0 = Debug|Win32 + {0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Release|x64.ActiveCfg = Release|x64 + {0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Release|x64.Build.0 = Release|x64 + {0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Release|x86.ActiveCfg = Release|Win32 + {0E383EF0-CEF7-4733-87C6-5AC9844AA1EF}.Release|x86.Build.0 = Release|Win32 + {5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Debug|x64.ActiveCfg = Debug|x64 + {5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Debug|x64.Build.0 = Debug|x64 + {5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Debug|x86.ActiveCfg = Debug|Win32 + {5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Debug|x86.Build.0 = Debug|Win32 + {5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Release|x64.ActiveCfg = Release|x64 + {5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Release|x64.Build.0 = Release|x64 + {5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Release|x86.ActiveCfg = Release|Win32 + {5FDE4822-C771-46A5-B6B2-FD12BACE86BF}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {0D6869A7-07EB-400F-B2AD-48531564555A} + EndGlobalSection +EndGlobal diff --git a/GlidePort/GlidePort.vcxproj b/GlidePort/GlidePort.vcxproj new file mode 100644 index 0000000..ea335fd --- /dev/null +++ b/GlidePort/GlidePort.vcxproj @@ -0,0 +1,122 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {69C3CD2A-3114-4181-884A-C09A4C62FBE0} + GlidePort + 10.0.16299.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + + + + \ No newline at end of file diff --git a/GlidePort/GlidePort.vcxproj.filters b/GlidePort/GlidePort.vcxproj.filters new file mode 100644 index 0000000..f81daba --- /dev/null +++ b/GlidePort/GlidePort.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + \ No newline at end of file diff --git a/Glider PRO CW5.mcp b/Glider PRO CW5.mcp deleted file mode 100755 index 85e1daa..0000000 Binary files a/Glider PRO CW5.mcp and /dev/null differ diff --git a/Glider PRO.mcp b/Glider PRO.mcp deleted file mode 100755 index 589be91..0000000 Binary files a/Glider PRO.mcp and /dev/null differ diff --git a/GpApp/About.cpp b/GpApp/About.cpp new file mode 100644 index 0000000..c063b14 --- /dev/null +++ b/GpApp/About.cpp @@ -0,0 +1,258 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// About.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLNumberFormatting.h" +#include "PLResources.h" +#include "PLSound.h" +#include "PLPasStr.h" +#include "About.h" +#include "DialogUtils.h" +#include "Environ.h" +#include "Externs.h" + + +static void HiLiteOkayButton (void); +static void UnHiLiteOkayButton (void); +static void UpdateMainPict (DialogPtr); +static Boolean AboutFilter (DialogPtr, EventRecord *theEvent, short *hit); + + +static RgnHandle okayButtRgn; +static Rect okayButtonBounds, mainPICTBounds; +static Boolean okayButtIsHiLit, clickedDownInOkay; + + +//============================================================== Functions +//-------------------------------------------------------------- DoAbout +// Brings up the About dialog box. + +void DoAbout (void) +{ + #define kAboutDialogID 150 // res ID of About dialog + #define kTextItemVers 2 // item number of version text + #define kPictItemMain 4 // item number of main PICT + + DialogPtr aboutDialog; + Str255 longVersion; + StringPtr messagePtr; + VersRecHndl version; + Handle itemHandle; + short itemType, hit, wasResFile; + ModalFilterUPP aboutFilterUPP; + + aboutFilterUPP = NewModalFilterUPP(AboutFilter); + + wasResFile = CurResFile(); + UseResFile(thisMac.thisResFile); + + aboutDialog = GetNewDialog(kAboutDialogID, nil, (WindowRef)-1L); +// if (aboutDialog == nil) +// RedAlert(kErrDialogDidntLoad); + + version = (VersRecHndl)GetResource('vers', 1); + if (version != nil) + { + messagePtr = (**version).shortVersion + 1 + (**version).shortVersion[0]; + + BlockMove((Ptr)messagePtr, &longVersion, ((UInt8)*messagePtr) + 1); + SetDialogString(aboutDialog, kTextItemVers, longVersion); + } + + GetDialogItem(aboutDialog, kOkayButton, &itemType, &itemHandle, &okayButtonBounds); + okayButtRgn = NewRgn(); // Create diagonal button region + OpenRgn(); + MoveTo(okayButtonBounds.left + 1, okayButtonBounds.top + 45); + Line(44, -44); // These lines define the region + Line(16, 16); + Line(-44, 44); + Line(-16, -16); + CloseRgn(okayButtRgn); + okayButtIsHiLit = false; // Initially, button is not hilit + clickedDownInOkay = false; // Initially, didn't click in okay button + GetDialogItem(aboutDialog, kPictItemMain, &itemType, &itemHandle, &mainPICTBounds); + + do // Loop until user wants to exit + { + ModalDialog(aboutFilterUPP, &hit); + } + while ((hit != kOkayButton) && (okayButtRgn != nil)); + + if (okayButtRgn != nil) + DisposeRgn(okayButtRgn); // Clean up! + DisposeDialog(aboutDialog); + DisposeModalFilterUPP(aboutFilterUPP); + + UseResFile(wasResFile); +} + +//============================================================== Static Functions +//-------------------------------------------------------------- HiLiteOkayButton +// Draws my pseudo-button to appear as though it is clicked on. + +static void HiLiteOkayButton (void) +{ + #define kOkayButtPICTHiLit 151 // res ID of unhilit button PICT + PicHandle thePict; + + if (!okayButtIsHiLit) + { + thePict = GetPicture(kOkayButtPICTHiLit); + if (thePict != nil) + { + DrawPicture(thePict, &okayButtonBounds); + ReleaseResource((Handle)thePict); + + okayButtIsHiLit = true; + } + } +} + +//-------------------------------------------------------------- UnHiLiteOkayButton + +// Draws my pseudo-button normal (not clicked on). + +static void UnHiLiteOkayButton (void) +{ + #define kOkayButtPICTNotHiLit 150 // res ID of hilit button PICT + PicHandle thePict; + + if (okayButtIsHiLit) + { + thePict = GetPicture(kOkayButtPICTNotHiLit); + if (thePict != nil) + { + DrawPicture(thePict, &okayButtonBounds); + ReleaseResource((Handle)thePict); + + okayButtIsHiLit = false; + } + } +} + +//-------------------------------------------------------------- UpdateMainPict +// Redraws the main graphic in the dialog (in response to an update event). + +static void UpdateMainPict (DialogPtr theDial) +{ + Str255 theStr, theStr2; + long totalSize, contigSize; + + DrawDialog(theDial); + + PasStringCopy(PSTR("Memory: "), theStr); // display free memory + PurgeSpace(&totalSize, &contigSize); + totalSize /= 1024; + NumToString(totalSize, theStr2); + PasStringConcat(theStr, theStr2); + PasStringConcat(theStr, PSTR("K")); + DrawDialogUserText2(theDial, 7, theStr); + + PasStringCopy(PSTR("Screen: "), theStr); // display screen size/depth + NumToString((long)(thisMac.screen.right - thisMac.screen.left), theStr2); + PasStringConcat(theStr, theStr2); + PasStringConcat(theStr, PSTR("x")); + NumToString((long)(thisMac.screen.bottom - thisMac.screen.top), theStr2); + PasStringConcat(theStr, theStr2); + PasStringConcat(theStr, PSTR("x")); + NumToString((long)thisMac.isDepth, theStr2); + PasStringConcat(theStr, theStr2); + DrawDialogUserText2(theDial, 8, theStr); +} + +//-------------------------------------------------------------- AboutFilter +// Dialog filter for the About dialog. + +static Boolean AboutFilter (DialogPtr theDial, EventRecord *theEvent, short *hit) +{ + Point mousePt; + UInt32 dummyLong; + Boolean handledIt; + + if (Button() && clickedDownInOkay) + { + GetMouse(&mousePt); + if(PtInRgn(mousePt, okayButtRgn)) + HiLiteOkayButton(); + else + UnHiLiteOkayButton(); + } + + switch (theEvent->what) + { + case keyDown: + switch ((theEvent->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + HiLiteOkayButton(); + Delay(8, &dummyLong); + UnHiLiteOkayButton(); + *hit = kOkayButton; + handledIt = true; + break; + + default: + handledIt = false; + } + break; + + case mouseDown: + mousePt = theEvent->where; + GlobalToLocal(&mousePt); + if(PtInRgn(mousePt, okayButtRgn)) + { + clickedDownInOkay = true; + handledIt = false; + } + else + handledIt = false; + break; + + case mouseUp: + mousePt = theEvent->where; + GlobalToLocal(&mousePt); + if(PtInRgn(mousePt, okayButtRgn) && clickedDownInOkay) + { + UnHiLiteOkayButton(); + *hit = kOkayButton; + handledIt = true; + } + else + { + clickedDownInOkay = false; + handledIt = false; + } + break; + + case updateEvt: + if ((WindowPtr)theEvent->message == mainWindow) + { + SetPort((GrafPtr)mainWindow); + BeginUpdate((WindowPtr)theEvent->message); + UpdateMainWindow(); + EndUpdate((WindowPtr)theEvent->message); + SetPortDialogPort(theDial); + handledIt = true; + } + else if ((WindowPtr)theEvent->message == (WindowPtr)theDial) + { + SetPortDialogPort(theDial); + BeginUpdate((WindowPtr)theEvent->message); + UpdateMainPict(theDial); + EndUpdate((WindowPtr)theEvent->message); + handledIt = false; + } + break; + + default: + handledIt = false; + break; + } + + return (handledIt); +} + diff --git a/GpApp/About.h b/GpApp/About.h new file mode 100644 index 0000000..a90709e --- /dev/null +++ b/GpApp/About.h @@ -0,0 +1,10 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// About.h +//---------------------------------------------------------------------------- +//============================================================================ + + +void DoAbout (void); + + diff --git a/GpApp/AnimCursor.cpp b/GpApp/AnimCursor.cpp new file mode 100644 index 0000000..a8cd342 --- /dev/null +++ b/GpApp/AnimCursor.cpp @@ -0,0 +1,286 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// AnimCursor.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLResources.h" +#include "PLBigEndian.h" +#include "Externs.h" +#include "Environ.h" + + +#define rAcurID 128 +#define rHandCursorID 1000 + + +typedef struct +{ + BEInt16_t n; + BEInt16_t index; + struct + { + BEInt16_t resID; + BEInt16_t reserved; + } frame[1]; +} acurRec, *acurPtr, **acurHandle; + +typedef struct +{ + struct + { + Handle cursorHdl; + } frame[1]; +} compiledAcurRec, *compiledAcurPtr, **compiledAcurHandle; + + +Boolean GetMonoCursors (acurHandle, compiledAcurHandle); +Boolean GetColorCursors (acurHandle, compiledAcurHandle); +void InitAnimatedCursor (acurHandle); + + +acurHandle animCursorH = nil; +compiledAcurHandle compiledAnimCursorH = nil; +Boolean useColorCursor = false; + + +//============================================================== Functions +//-------------------------------------------------------------- GetMonoCursors + +// Loads b&w cursors (for animated beach ball). + +Boolean GetMonoCursors (acurHandle ballCursH, compiledAcurHandle compiledBallCursH) +{ + short i, j; + CursHandle cursHdl; + + if (ballCursH) // Were we passed a legit acur handle? + { + j = (*ballCursH)->n; // Get number of 'frames' in the acur + for (i = 0; i < j; i++) // Start walking the frames + { + cursHdl = GetCursor((*ballCursH)->frame[i].resID); + if (cursHdl == nil) // Did the cursor load? It didn't?... + { // Well then, toss what we got. + for (j = 0; j < i; j++) + DisposeHandle((*compiledBallCursH)->frame[j].cursorHdl); + return(false); // And report this to mother. + } // However!... + else // If cursor loaded ok... + { // Detach it from the resource map... + DetachResource((Handle)cursHdl); // And assign to our struct + (*compiledBallCursH)->frame[i].cursorHdl = (Handle)cursHdl; + } + } + } + return(true); +} + +//-------------------------------------------------------------- GetColorCursors + +// Loads color cursors (for animated beach ball). + +Boolean GetColorCursors (acurHandle ballCursH, compiledAcurHandle compiledBallCursH) +{ + short i, j; + CCrsrHandle cursHdl; + Boolean result = true; + + if (ballCursH) + { + j = (*ballCursH)->n; // Get the number of cursors + HideCursor(); // Hide the cursor + for (i = 0; i < j; i++) // Walk through the acur resource + { + cursHdl = GetCCursor((*ballCursH)->frame[i].resID); // Get the cursor + if (cursHdl == nil) // Make sure a real cursor was returned + { // If not, trash all cursors loaded + for (j = 0; j < i; j++) + DisposeCCursor((CCrsrHandle)(*compiledBallCursH)->frame[j].cursorHdl); + result = false; // Tell calling proc we failed + break; // And break out of the loop + } + else // But, if the cursor loaded ok + { // add it to our list or cursor handles + (*compiledBallCursH)->frame[i].cursorHdl = (Handle)cursHdl; + SetCCursor((CCrsrHandle)(*compiledBallCursH)->frame[i].cursorHdl); + } + } + InitCursor(); // Show the cursor again (as arrow) + } + return(result); // Return to calling proc w/ results +} + +//-------------------------------------------------------------- InitAnimatedCursor + +// Loads and sets up animated beach ball cursor structures. + +void InitAnimatedCursor (acurHandle ballCursH) +{ + Boolean useColor; + compiledAcurHandle compiledBallCursorH; + + useColor = thisMac.hasColor; + if (ballCursH == nil) + ballCursH = reinterpret_cast(GetResource('acur', 128)); + if (ballCursH && ballCursH != animCursorH) + { + compiledBallCursorH = (compiledAcurHandle)NewHandle(sizeof(compiledAcurRec) * (*ballCursH)->n); + if (!compiledBallCursorH) + RedAlert(kErrFailedResourceLoad); + + HNoPurge((Handle)ballCursH); + MoveHHi((Handle)ballCursH); + HLock((Handle)ballCursH); + if (useColor) + useColor = GetColorCursors(ballCursH, compiledBallCursorH); + if (!useColor && !GetMonoCursors(ballCursH, compiledBallCursorH)) + RedAlert(kErrFailedResourceLoad); + DisposCursors(); + + animCursorH = ballCursH; + compiledAnimCursorH = compiledBallCursorH; + useColorCursor = useColor; + (*ballCursH)->index = 0; + } + else + RedAlert(kErrFailedResourceLoad); +} + +//-------------------------------------------------------------- LoadCursors + +// Just calls the above function. Other code could be added here thoughÉ +// to add additional cursors. + +void LoadCursors (void) +{ + InitAnimatedCursor((acurHandle)GetResource('acur', rAcurID)); +} + +//-------------------------------------------------------------- DisposCursors + +// Disposes of all memory allocated by anaimated beach ball cursors. + +void DisposCursors (void) +{ + register short i, j; + + if (compiledAnimCursorH != nil) + { + j = (*animCursorH)->n; + if (useColorCursor) + { + for (i = 0; i < j; i++) + { + if ((*compiledAnimCursorH)->frame[i].cursorHdl != nil) + DisposeCCursor((CCrsrHandle)(*compiledAnimCursorH)->frame[i].cursorHdl); + } + } + else + { + for (i = 0; i < j; i++) + { + if ((*compiledAnimCursorH)->frame[i].cursorHdl != nil) + DisposeHandle((Handle)(*compiledAnimCursorH)->frame[i].cursorHdl); + } + } + DisposeHandle((Handle)compiledAnimCursorH); + compiledAnimCursorH = nil; + } + + if (animCursorH != nil) + { + ReleaseResource((Handle)animCursorH); + animCursorH = nil; + } +} + +//-------------------------------------------------------------- IncrementCursor + +// Advances the beach ball cursor one frame. + +void IncrementCursor (void) +{ + if (animCursorH == 0) + InitAnimatedCursor(nil); + if (animCursorH) + { + (*animCursorH)->index++; + (*animCursorH)->index %= (*animCursorH)->n; + if (useColorCursor) + { + SetCCursor((CCrsrHandle)(*compiledAnimCursorH)-> + frame[(*animCursorH)->index].cursorHdl); + } + else + { + SetCursor((CursPtr)*(*compiledAnimCursorH)-> + frame[(*animCursorH)->index].cursorHdl); + } + } + else + SetCursor((CursPtr)*GetCursor(watchCursor)); +} + +//-------------------------------------------------------------- DecrementCursor + +// Reverses the beach ball cursor one frame. + +void DecrementCursor (void) +{ + if (animCursorH == 0) + InitAnimatedCursor(nil); + if (animCursorH) + { + (*animCursorH)->index--; + if (((*animCursorH)->index) < 0) + (*animCursorH)->index = ((*animCursorH)->n) - 1; + if (useColorCursor) + { + SetCCursor((CCrsrHandle)(*compiledAnimCursorH)-> + frame[(*animCursorH)->index].cursorHdl); + } + else + { + SetCursor((CursPtr)*(*compiledAnimCursorH)-> + frame[(*animCursorH)->index].cursorHdl); + } + } + else + SetCursor((CursPtr)*GetCursor(watchCursor)); +} + +//-------------------------------------------------------------- SpinCursor + +// Advances the beach ball cursor the number of frames specified. + +void SpinCursor (short incrementIndex) +{ + UInt32 dummyLong; + short i; + + for (i = 0; i < incrementIndex; i++) + { + IncrementCursor(); + Delay(1, &dummyLong); + } +} + +//-------------------------------------------------------------- BackSpinCursor + +// Reverses the beach ball cursor the number of frames specified. + +void BackSpinCursor (short decrementIndex) +{ + UInt32 dummyLong; + short i; + + for (i = 0; i < decrementIndex; i++) + { + DecrementCursor(); + Delay(1, &dummyLong); + } +} + diff --git a/GpApp/AppleEvents.cpp b/GpApp/AppleEvents.cpp new file mode 100644 index 0000000..d4fd275 --- /dev/null +++ b/GpApp/AppleEvents.cpp @@ -0,0 +1,202 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// AppleEvents.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLAppleEvents.h" +#include "Externs.h" +#include "House.h" + + +#define kNoPrintingAlert 1031 + + +OSErr DoOpenAppAE (const AppleEvent *, AppleEvent *, UInt32); +OSErr DoOpenDocAE (const AppleEvent *, AppleEvent *, UInt32); +OSErr DoPrintDocAE (const AppleEvent *, AppleEvent *, UInt32); +OSErr DoQuitAE (const AppleEvent *, AppleEvent *, UInt32); +OSErr MyGotRequiredParams (const AppleEvent *); + +AEEventHandlerUPP openAppAEUPP, openDocAEUPP, printDocAEUPP, quitAEUPP; + + +extern FSSpecPtr theHousesSpecs; +extern long incrementModeTime; +extern short thisHouseIndex, splashOriginH, splashOriginV; +extern Boolean quitting; + + +//============================================================== Functions +//-------------------------------------------------------------- DoOpenAppAE +// Handles an "Open Application" Apple Event. + +OSErr DoOpenAppAE (const AppleEvent *theAE, AppleEvent *reply, UInt32 ref) +{ + OSErr theErr; + + theErr = MyGotRequiredParams(theAE); + return (theErr); +} + +//-------------------------------------------------------------- DoOpenDocAE +// Handles an "Open Document" Apple Event. + +OSErr DoOpenDocAE (const AppleEvent *theAE, AppleEvent *reply, UInt32 ref) +{ + FSSpec oneFSS; + FInfo finderInfo; + AEDescList docList; + long itemsInList; + Size actualSize; + AEKeyword keywd; + DescType returnedType; + OSErr theErr, whoCares; + short i; + + theErr = AEGetParamDesc(theAE, keyDirectObject, typeAEList, &docList); + if (theErr != noErr) + { + YellowAlert(kYellowAppleEventErr, theErr); + return (theErr); + } + + theErr = MyGotRequiredParams(theAE); + if (theErr != noErr) + { + whoCares = AEDisposeDesc(&docList); + return (theErr); + } + + theErr = AECountItems(&docList, &itemsInList); + if (theErr != noErr) + { + whoCares = AEDisposeDesc(&docList); + return (theErr); + } + +#ifndef COMPILEDEMO + for (i = 1; i <= itemsInList; i++) + { + theErr = AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType, + &oneFSS, sizeof(oneFSS), &actualSize); + if (theErr == noErr) + { + theErr = FSpGetFInfo(&oneFSS, &finderInfo); + if ((theErr == noErr) && (finderInfo.fdType == 'gliH')) + AddExtraHouse(&oneFSS); + } + } + if (itemsInList > 0) + { + theErr = AEGetNthPtr(&docList, 1, typeFSS, &keywd, &returnedType, + &oneFSS, sizeof(oneFSS), &actualSize); + if (theErr == noErr) + { + theErr = FSpGetFInfo(&oneFSS, &finderInfo); + if ((theErr == noErr) && (finderInfo.fdType == 'gliH')) + { + whoCares = CloseHouse(); + PasStringCopy(oneFSS.name, thisHouseName); + BuildHouseList(); + if (OpenHouse()) + whoCares = ReadHouse(); + PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); + OpenCloseEditWindows(); + incrementModeTime = TickCount() + kIdleSplashTicks; + if ((theMode == kSplashMode) || (theMode == kPlayMode)) + { + Rect updateRect; + + SetRect(&updateRect, splashOriginH + 474, splashOriginV + 304, splashOriginH + 474 + 166, splashOriginV + 304 + 12); + InvalWindowRect(mainWindow, &updateRect); + } + } + } + InitCursor(); + } +#endif + whoCares = AEDisposeDesc(&docList); + + return theErr; +} + +//-------------------------------------------------------------- DoPrintDocAE +// Handles a "Print Document" Apple Event. + +OSErr DoPrintDocAE (const AppleEvent *theAE, AppleEvent *reply, UInt32 ref) +{ + short hitWhat; + +// CenterAlert(kNoPrintingAlert); + hitWhat = Alert(kNoPrintingAlert, nil); + + return errAEEventNotHandled; +} + +//-------------------------------------------------------------- DoQuitAE +// Handles a "Quit Application" Apple Event. + +OSErr DoQuitAE (const AppleEvent *theAE, AppleEvent *reply, UInt32 ref) +{ + OSErr isHuman; + + isHuman = MyGotRequiredParams(theAE); + if (isHuman == noErr) + quitting = true; + + return isHuman; +} + +//-------------------------------------------------------------- MyGotRequiredParams +// Have no clue! :) + +OSErr MyGotRequiredParams (const AppleEvent *theAE) +{ + DescType returnedType; + Size actualSize; + + return (AEGetAttributePtr(theAE, keyMissedKeywordAttr, typeWildCard, + &returnedType, 0L, 0, &actualSize) == errAEDescNotFound) ? noErr : + errAEParamMissed; +} + +//-------------------------------------------------------------- SetUpAppleEvents +// Initializes all handlers, etc. for dealing with Apple Events. + +void SetUpAppleEvents (void) +{ + OSErr theErr; + + openAppAEUPP = NewAEEventHandlerProc(DoOpenAppAE); + openDocAEUPP = NewAEEventHandlerProc(DoOpenDocAE); + printDocAEUPP = NewAEEventHandlerProc(DoPrintDocAE); + quitAEUPP = NewAEEventHandlerProc(DoQuitAE); + + theErr = AEInstallEventHandler(kCoreEventClass, // install oapp + kAEOpenApplication, openAppAEUPP, 0, false); + if (theErr != noErr) + YellowAlert(kYellowAppleEventErr, theErr); + + theErr = AEInstallEventHandler(kCoreEventClass, // install odoc + kAEOpenDocuments, openDocAEUPP, 0, false); + if (theErr != noErr) + YellowAlert(kYellowAppleEventErr, theErr); + + theErr = AEInstallEventHandler(kCoreEventClass, // install pdoc + kAEPrintDocuments, printDocAEUPP, 0, false); + if (theErr != noErr) + YellowAlert(kYellowAppleEventErr, theErr); + + theErr = AEInstallEventHandler(kCoreEventClass, // install quit + kAEQuitApplication, quitAEUPP, 0, false); + if (theErr != noErr) + YellowAlert(kYellowAppleEventErr, theErr); + + theErr = AESetInteractionAllowed(kAEInteractWithAll); + if (theErr != noErr) + YellowAlert(kYellowAppleEventErr, theErr); +} + diff --git a/GpApp/Banner.cpp b/GpApp/Banner.cpp new file mode 100644 index 0000000..9a393d8 --- /dev/null +++ b/GpApp/Banner.cpp @@ -0,0 +1,238 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Banner.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLNumberFormatting.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "MainWindow.h" +#include "RectUtils.h" +#include "Room.h" +#include "Utilities.h" + + +#define kBannerPageTopPICT 1993 +#define kBannerPageBottomPICT 1992 +#define kBannerPageBottomMask 1991 +#define kStarsRemainingPICT 1017 +#define kStarRemainingPICT 1018 + + +void DrawBanner (Point *); +void DrawBannerMessage (Point); + + +short numStarsRemaining; +Boolean bannerStarCountOn; + +extern Rect justRoomsRect; +extern Boolean quickerTransitions, demoGoing, isUseSecondScreen; + + +//============================================================== Functions +//-------------------------------------------------------------- DrawBanner +// Displays opening banner (when a new game is begun). The banner looksÉ +// like a sheet of notebook paper. The text printed on it is specifiedÉ +// by the author of the house. + +void DrawBanner (Point *topLeft) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + Rect wholePage, partPage, mapBounds; + GWorldPtr tempMap; + GWorldPtr tempMask; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&wholePage, 0, 0, 330, 220); + mapBounds = thisMac.screen; + ZeroRectCorner(&mapBounds); + CenterRectInRect(&wholePage, &mapBounds); + topLeft->h = wholePage.left; + topLeft->v = wholePage.top; + partPage = wholePage; + partPage.bottom = partPage.top + 190; + SetGWorld(workSrcMap, nil); + LoadScaledGraphic(kBannerPageTopPICT, &partPage); + + partPage = wholePage; + partPage.top = partPage.bottom - 30; + mapBounds = partPage; + ZeroRectCorner(&mapBounds); + theErr = CreateOffScreenGWorld(&tempMap, &mapBounds, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(kBannerPageBottomPICT); + + theErr = CreateOffScreenGWorld(&tempMask, &mapBounds, 1); + SetGWorld(tempMask, nil); + LoadGraphic(kBannerPageBottomMask); + + CopyMask((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(tempMask), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &mapBounds, &mapBounds, &partPage); + SetPort((GrafPtr)workSrcMap); + + SetGWorld(wasCPort, wasWorld); + DisposeGWorld(tempMap); + DisposeGWorld(tempMask); +} + +//-------------------------------------------------------------- CountStarsInHouse +// Goes through the current house and counts the total number of stars within. + +short CountStarsInHouse (void) +{ + short i, h, numRooms, numStars; + char wasState; + + numStars = 0; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + numRooms = (*thisHouse)->nRooms; + for (i = 0; i < numRooms; i++) + { + if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) + for (h = 0; h < kMaxRoomObs; h++) + { + if ((*thisHouse)->rooms[i].objects[h].what == kStar) + numStars++; + } + } + HSetState((Handle)thisHouse, wasState); + + return (numStars); +} + +//-------------------------------------------------------------- DrawBannerMessage + +// This function prints the author's message acorss the notebook paper banner. + +void DrawBannerMessage (Point topLeft) +{ + Str255 bannerStr, subStr; + short count; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + PasStringCopy((*thisHouse)->banner, bannerStr); + HSetState((Handle)thisHouse, wasState); + + TextFont(applFont); + TextFace(bold); + TextSize(12); + ForeColor(blackColor); + count = 0; + do + { + GetLineOfText(bannerStr, count, subStr); + MoveTo(topLeft.h + 16, topLeft.v + 32 + (count * 20)); + DrawString(subStr); + count++; + } + while (subStr[0] > 0); + + if (bannerStarCountOn) + { + if (numStarsRemaining != 1) + GetLocalizedString(1, bannerStr); + else + GetLocalizedString(2, bannerStr); + + NumToString((long)numStarsRemaining, subStr); + PasStringConcat(bannerStr, subStr); + + if (numStarsRemaining != 1) + GetLocalizedString(3, subStr); + else + GetLocalizedString(4, subStr); + PasStringConcat(bannerStr, subStr); + + ForeColor(redColor); + MoveTo(topLeft.h + 16, topLeft.v + 164); + DrawString(bannerStr); + MoveTo(topLeft.h + 16, topLeft.v + 180); + GetLocalizedString(5, subStr); + DrawString(subStr); + } + ForeColor(blackColor); +} + +//-------------------------------------------------------------- BringUpBanner +// Handles bringing up displaying and disposing of the banner. + +void BringUpBanner (void) +{ + Rect wholePage; + Point topLeft; + + DrawBanner(&topLeft); + DrawBannerMessage(topLeft); +// if (quickerTransitions) +// DissBitsChunky(&justRoomsRect); // was workSrcRect +// else +// DissBits(&justRoomsRect); + QSetRect(&wholePage, 0, 0, 330, 220); + QOffsetRect(&wholePage, topLeft.h, topLeft.v); + + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &wholePage, &wholePage, srcCopy, nil); + + if (demoGoing) + WaitForInputEvent(4); + else + WaitForInputEvent(15); + +// if (quickerTransitions) +// DissBitsChunky(&justRoomsRect); +// else +// DissBits(&justRoomsRect); +} + +//-------------------------------------------------------------- DisplayStarsRemaining +// This brings up a small message indicating the number of stars remainingÉ +// in a house. It comes up when the player gets a star (the game is pausedÉ +// and the user informed as to how many remain). + +void DisplayStarsRemaining (void) +{ + Rect src, bounds; + Str255 theStr; + + SetPortWindowPort(mainWindow); + QSetRect(&bounds, 0, 0, 256, 64); + CenterRectInRect(&bounds, &thisMac.screen); + QOffsetRect(&bounds, -thisMac.screen.left, -thisMac.screen.top); + src = bounds; + InsetRect(&src, 64, 32); + + TextFont(applFont); + TextFace(bold); + TextSize(12); + NumToString((long)numStarsRemaining, theStr); + + QOffsetRect(&bounds, 0, -20); + if (numStarsRemaining < 2) + LoadScaledGraphic(kStarRemainingPICT, &bounds); + else + { + LoadScaledGraphic(kStarsRemainingPICT, &bounds); + MoveTo(bounds.left + 102 - (StringWidth(theStr) / 2), bounds.top + 23); + ColorText(theStr, 4L); + } + + DelayTicks(60); + if (WaitForInputEvent(30)) + RestoreEntireGameScreen(); + CopyRectWorkToMain(&bounds); +} + diff --git a/GpApp/ColorUtils.cpp b/GpApp/ColorUtils.cpp new file mode 100644 index 0000000..f7f45b6 --- /dev/null +++ b/GpApp/ColorUtils.cpp @@ -0,0 +1,225 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// ColorUtils.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "PLPalettes.h" +#include "PLPasStr.h" + + +//============================================================== Functions +//-------------------------------------------------------------- ColorText + +// Given a string and a color index (index into the current palette),É +// this function draws text in that color. It assumes the current port,É +// the current font, the current pen location, etc. + +void ColorText (StringPtr theStr, long color) +{ + RGBColor theRGBColor, wasColor; + + GetForeColor(&wasColor); + Index2Color(color, &theRGBColor); + RGBForeColor(&theRGBColor); + DrawString(theStr); + RGBForeColor(&wasColor); +} + +//-------------------------------------------------------------- ColorRect + +// Given a rectangle and color index, this function draws a solidÉ +// rectangle in that color. Current port, pen mode, etc. assumed. + +void ColorRect (Rect *theRect, long color) +{ + RGBColor theRGBColor, wasColor; + + GetForeColor(&wasColor); + Index2Color(color, &theRGBColor); + RGBForeColor(&theRGBColor); + PaintRect(theRect); + RGBForeColor(&wasColor); +} + +//-------------------------------------------------------------- ColorOval + +// Given a rectangle and color index, this function draws a solidÉ +// oval in that color. Current port, pen mode, etc. assumed. + +void ColorOval (Rect *theRect, long color) +{ + RGBColor theRGBColor, wasColor; + + GetForeColor(&wasColor); + Index2Color(color, &theRGBColor); + RGBForeColor(&theRGBColor); + PaintOval(theRect); + RGBForeColor(&wasColor); +} + +//-------------------------------------------------------------- ColorRegion + +// Given a region and color index, this function draws a solidÉ +// region in that color. Current port, pen mode, etc. assumed. + +void ColorRegion (RgnHandle theRgn, long color) +{ + RGBColor theRGBColor, wasColor; + + GetForeColor(&wasColor); + Index2Color(color, &theRGBColor); + RGBForeColor(&theRGBColor); + PaintRgn(theRgn); + RGBForeColor(&wasColor); +} + +//-------------------------------------------------------------- ColorLine + +// Given a the end points for a line and color index, this functionÉ +// draws a line in that color. Current port, pen mode, etc. assumed. + +void ColorLine (short h0, short v0, short h1, short v1, long color) +{ + RGBColor theRGBColor, wasColor; + + GetForeColor(&wasColor); + Index2Color(color, &theRGBColor); + RGBForeColor(&theRGBColor); + MoveTo(h0, v0); + LineTo(h1, v1); + RGBForeColor(&wasColor); +} + +//-------------------------------------------------------------- HiliteRect + +// Given a rect and two hilite colors, this function frames the top andÉ +// left edges of the rect with color 1 and frames the bottom and rightÉ +// sides with color 2. A rect can be made to appear "hi-lit" or "3D"É +// in this way. + +void HiliteRect (Rect *theRect, short color1, short color2) +{ + ColorLine(theRect->left, theRect->top, theRect->right - 2, + theRect->top, color1); + ColorLine(theRect->left, theRect->top, theRect->left, + theRect->bottom - 2, color1); + ColorLine(theRect->right - 1, theRect->top, theRect->right - 1, + theRect->bottom - 2, color2); + ColorLine(theRect->left + 1, theRect->bottom - 1, theRect->right - 1, + theRect->bottom - 1, color2); +} + +//-------------------------------------------------------------- ColorFrameRect + +// Given a rectangle and color index, this function frames aÉ +// rectangle in that color. Current port, pen mode, etc. assumed. + +void ColorFrameRect (Rect *theRect, long color) +{ + RGBColor theRGBColor, wasColor; + + GetForeColor(&wasColor); + Index2Color(color, &theRGBColor); + RGBForeColor(&theRGBColor); + FrameRect(theRect); + RGBForeColor(&wasColor); +} + +//-------------------------------------------------------------- ColorFrameWHRect + +// Given a the top-left corner of a rectangle, its width and height,É +// and a color index, this function frames a rectangle in that color. +// Current port, pen mode, etc. assumed. + +void ColorFrameWHRect (short left, short top, short wide, short high, long color) +{ + Rect theRect; + + theRect.left = left; + theRect.top = top; + theRect.right = left + wide; + theRect.bottom = top + high; + ColorFrameRect(&theRect, color); +} + +//-------------------------------------------------------------- ColorFrameOval + +// Given a rectangle and color index, this function frames anÉ +// oval in that color. Current port, pen mode, etc. assumed. + +void ColorFrameOval (Rect *theRect, long color) +{ + RGBColor theRGBColor, wasColor; + + GetForeColor(&wasColor); + Index2Color(color, &theRGBColor); + RGBForeColor(&theRGBColor); + FrameOval(theRect); + RGBForeColor(&wasColor); +} + +//-------------------------------------------------------------- LtGrayForeColor + +// This function finds the closest match to a "light gray" in theÉ +// current palette and sets the pen color to that. + +void LtGrayForeColor (void) +{ + RGBColor color; + + color.red = (unsigned short) 0xBFFF; + color.green = (unsigned short) 0xBFFF; + color.blue = (unsigned short) 0xBFFF; + + RGBForeColor(&color); +} + +//-------------------------------------------------------------- GrayForeColor + +// This function finds the closest match to a "medium gray" in theÉ +// current palette and sets the pen color to that. + +void GrayForeColor (void) +{ + RGBColor color; + + color.red = (unsigned short) 0x7FFF; + color.green = (unsigned short) 0x7FFF; + color.blue = (unsigned short) 0x7FFF; + + RGBForeColor(&color); +} + +//-------------------------------------------------------------- DkGrayForeColor + +// This function finds the closest match to a "dark gray" in theÉ +// current palette and sets the pen color to that. + +void DkGrayForeColor (void) +{ + RGBColor color; + + color.red = (unsigned short) 0x3FFF; + color.green = (unsigned short) 0x3FFF; + color.blue = (unsigned short) 0x3FFF; + + RGBForeColor(&color); +} + +//-------------------------------------------------------------- RestoreColorsSlam + +// This function forces the Macintosh to rebuild the palette. It isÉ +// called to restore a sense or normality after some serious mungingÉ +// with the palette. + +void RestoreColorsSlam (void) +{ + RestoreDeviceClut(nil); + PaintBehind(nil, GetGrayRgn()); + DrawMenuBar(); +} + diff --git a/GpApp/Coordinates.cpp b/GpApp/Coordinates.cpp new file mode 100644 index 0000000..362586c --- /dev/null +++ b/GpApp/Coordinates.cpp @@ -0,0 +1,197 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Coordinates.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLNumberFormatting.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "Marquee.h" +#include "ObjectEdit.h" +#include "RectUtils.h" + + +Rect coordWindowRect; +WindowPtr coordWindow; +short isCoordH, isCoordV; +short coordH, coordV, coordD; +Boolean isCoordOpen; + + +//============================================================== Functions +//-------------------------------------------------------------- SetCoordinateHVD + +// Given a horizontal, vertical and distance value, this functionÉ +// displays these values in the Coordinates window. + +void SetCoordinateHVD (short h, short v, short d) +{ +#ifndef COMPILEDEMO + if (h != -2) + coordH = h; + if (v != -2) + coordV = v; + if (d != -2) + coordD = d; + UpdateCoordWindow(); +#endif +} + +//-------------------------------------------------------------- DeltaCoordinateD + +// When the user is dragging a handle (such as the height of a blower)É +// this function can be called and passed the amount by which the userÉ +// has changed the height (delta). This function then displays it inÉ +// the Coordinate window. + +void DeltaCoordinateD (short d) +{ +#ifndef COMPILEDEMO + coordD = d; + UpdateCoordWindow(); +#endif +} + +//-------------------------------------------------------------- UpdateCoordWindow + +// Completely redraws and updates the Coordinate window. + +void UpdateCoordWindow (void) +{ +#ifndef COMPILEDEMO + Str255 tempStr, numStr; + GrafPtr wasPort; + + if (coordWindow == nil) + return; + + GetPort(&wasPort); + SetPort((GrafPtr)coordWindow); + EraseRect(&coordWindowRect); + + PasStringCopy(PSTR("h: "), tempStr); + if (coordH != -1) + { + NumToString((long)coordH, numStr); + PasStringConcat(tempStr, numStr); + } + else + PasStringConcat(tempStr, PSTR("-")); + MoveTo(5, 12); + DrawString(tempStr); + + PasStringCopy(PSTR("v: "), tempStr); + if (coordV != -1) + { + NumToString((long)coordV, numStr); + PasStringConcat(tempStr, numStr); + } + else + PasStringConcat(tempStr, PSTR("-")); + MoveTo(4, 22); + DrawString(tempStr); + + ForeColor(blueColor); + PasStringCopy(PSTR("d: "), tempStr); + if (coordD != -1) + { + NumToString((long)coordD, numStr); + PasStringConcat(tempStr, numStr); + } + else + PasStringConcat(tempStr, PSTR("-")); + MoveTo(5, 32); + DrawString(tempStr); + ForeColor(blackColor); + + SetPort((GrafPtr)wasPort); +#endif +} + +//-------------------------------------------------------------- OpenCoordWindow +// Brings up the Coordinate window. + +void OpenCoordWindow (void) +{ +#ifndef COMPILEDEMO + Rect src, dest; + Point globalMouse; + short direction, dist; + + if (coordWindow == nil) + { + QSetRect(&coordWindowRect, 0, 0, 50, 38); + if (thisMac.hasColor) + coordWindow = NewCWindow(nil, &coordWindowRect, + PSTR("Tools"), false, kWindoidWDEF, kPutInFront, true, 0L); + else + coordWindow = NewWindow(nil, &coordWindowRect, + PSTR("Tools"), false, kWindoidWDEF, kPutInFront, true, 0L); + + if (coordWindow == nil) + RedAlert(kErrNoMemory); + +// if (OptionKeyDown()) +// { +// isCoordH = qd.screenBits.bounds.right - 55; +// isCoordV = 204; +// } + MoveWindow(coordWindow, isCoordH, isCoordV, true); + globalMouse = MyGetGlobalMouse(); + QSetRect(&src, 0, 0, 1, 1); + QOffsetRect(&src, globalMouse.h, globalMouse.v); + GetWindowRect(coordWindow, &dest); + BringToFront(coordWindow); + ShowHide(coordWindow, true); +// FlagWindowFloating(coordWindow); TEMP - use flaoting windows + HiliteAllWindows(); + + coordH = -1; + coordV = -1; + coordD = -1; + TextFace(applFont); + TextSize(9); + + if (objActive != kNoObjectSelected) + { + if (ObjectHasHandle(&direction, &dist)) + coordD = dist; + SetCoordinateHVD(theMarquee.bounds.left, theMarquee.bounds.top, coordD); + } + } + + UpdateCoordinateCheckmark(true); +#endif +} + +//-------------------------------------------------------------- CloseCoordWindow +// Closes and disposes of the Coordinate window. + +void CloseCoordWindow (void) +{ + CloseThisWindow(&coordWindow); + UpdateCoordinateCheckmark(false); +} + +//-------------------------------------------------------------- ToggleCoordinateWindow +// Toggles the Coordinate windows state between open and closed. + +void ToggleCoordinateWindow (void) +{ +#ifndef COMPILEDEMO + if (coordWindow == nil) + { + OpenCoordWindow(); + isCoordOpen = true; + } + else + { + CloseCoordWindow(); + isCoordOpen = false; + } +#endif +} + diff --git a/Sources/DebugUtilities.c b/GpApp/DebugUtilities.c old mode 100755 new mode 100644 similarity index 100% rename from Sources/DebugUtilities.c rename to GpApp/DebugUtilities.c diff --git a/GpApp/DialogUtils.cpp b/GpApp/DialogUtils.cpp new file mode 100644 index 0000000..85e5c00 --- /dev/null +++ b/GpApp/DialogUtils.cpp @@ -0,0 +1,807 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// DialogUtils.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLControlDefinitions.h" +#include "PLLowMem.h" +#include "PLNumberFormatting.h" +#include "PLPasStr.h" +#include "DialogUtils.h" +#include "Externs.h" + + +#define kActive 0 +#define kInactive 255 + + +//============================================================== Functions +//-------------------------------------------------------------- BringUpDialog +// Given a dialog pointer and a resource ID, this function brings it upÉ +// centered, visible, and with the default button outlined. + +void BringUpDialog (DialogPtr *theDialog, short dialogID) +{ +// CenterDialog(dialogID); + *theDialog = GetNewDialog(dialogID, nil, kPutInFront); + if (*theDialog == nil) + RedAlert(kErrDialogDidntLoad); + SetPort((GrafPtr)*theDialog); + ShowWindow(GetDialogWindow(*theDialog)); + DrawDefaultButton(*theDialog); +} + +//-------------------------------------------------------------- GetPutDialogCorner +// Determines the upper left corner coordinates needed to properly centerÉ +// the standard Mac PutFile dialog (when you save files). +/* +void GetPutDialogCorner (Point *theCorner) +{ + DialogTHndl dlogHandle; + Rect theScreen, dlogBounds; + Byte wasState; + + theCorner->h = 64; + theCorner->v = 64; + theScreen = qd.screenBits.bounds; + theScreen.top += LMGetMBarHeight(); + OffsetRect(&theScreen, -theScreen.left, -theScreen.top); + + dlogHandle = (DialogTHndl)GetResource('DLOG', sfPutDialogID); + if (dlogHandle != nil) + { + wasState = HGetState((Handle)dlogHandle); + HLock((Handle)dlogHandle); + + dlogBounds = (**dlogHandle).boundsRect; + OffsetRect(&dlogBounds, -dlogBounds.left, -dlogBounds.top); + + theCorner->h = (theScreen.right - dlogBounds.right) / 2; + theCorner->v = (theScreen.bottom - dlogBounds.bottom) / 3; + + HSetState((Handle)dlogHandle, wasState); + } + theCorner->v += LMGetMBarHeight(); +} +*/ + +//-------------------------------------------------------------- GetPutDialogCorner +// Determines the upper left corner coordinates needed to properly centerÉ +// the standard Mac GetFile dialog (when you open files). +/* +void GetGetDialogCorner (Point *theCorner) +{ + DialogTHndl dlogHandle; + Rect theScreen, dlogBounds; + Byte wasState; + + theCorner->h = 64; + theCorner->v = 64; + theScreen = qd.screenBits.bounds; + theScreen.top += LMGetMBarHeight(); + OffsetRect(&theScreen, -theScreen.left, -theScreen.top); + + dlogHandle = (DialogTHndl)GetResource('DLOG', sfGetDialogID); + if (dlogHandle != nil) + { + wasState = HGetState((Handle)dlogHandle); + HLock((Handle)dlogHandle); + + dlogBounds = (**dlogHandle).boundsRect; + OffsetRect(&dlogBounds, -dlogBounds.left, -dlogBounds.top); + + theCorner->h = (theScreen.right - dlogBounds.right) / 2; + theCorner->v = (theScreen.bottom - dlogBounds.bottom) / 3; + + HSetState((Handle)dlogHandle, wasState); + } + theCorner->v += LMGetMBarHeight(); +} +*/ +//-------------------------------------------------------------- CenterDialog +// Given a resource ID for a dialog, this function properly centers it. +/* +void CenterDialog (SInt16 dialogID) +{ + DialogTHndl dlogHandle; + Rect theScreen, dlogBounds; + SInt16 hPos, vPos; + Byte wasState; + + theScreen = qd.screenBits.bounds; + theScreen.top += LMGetMBarHeight(); + + dlogHandle = (DialogTHndl)GetResource('DLOG', dialogID); + if (dlogHandle != nil) + { + wasState = HGetState((Handle)dlogHandle); + HLock((Handle)dlogHandle); + + dlogBounds = (**dlogHandle).boundsRect; + OffsetRect(&dlogBounds, -dlogBounds.left, -dlogBounds.top); + + hPos = ((theScreen.right - theScreen.left) - dlogBounds.right) / 2; + vPos = ((theScreen.bottom - theScreen.top) - dlogBounds.bottom) / 3; + + OffsetRect(&dlogBounds, hPos, vPos + LMGetMBarHeight()); + + (**dlogHandle).boundsRect = dlogBounds; + HSetState((Handle)dlogHandle, wasState); + } +} +*/ +//-------------------------------------------------------------- GetDialogRect +// Determines the bounding rectangle for a given dialog. + +void GetDialogRect (Rect *bounds, short dialogID) +{ + DialogTHndl dlogHandle; + Byte wasState; + + dlogHandle = (DialogTHndl)GetResource('DLOG', dialogID); + if (dlogHandle != nil) + { + wasState = HGetState((Handle)dlogHandle); + HLock((Handle)dlogHandle); + + *bounds = (**dlogHandle).boundsRect; + HSetState((Handle)dlogHandle, wasState); + } +} + +//-------------------------------------------------------------- TrueCenterDialog +// Places a dialog DEAD CENTER (as opposed to 1/3 of the way down asÉ +// is common for Mac dialog centering). +/* +void TrueCenterDialog (short dialogID) +{ + DialogTHndl dlogHandle; + Rect theScreen, dlogBounds; + short hPos, vPos; + Byte wasState; + + theScreen = qd.screenBits.bounds; + theScreen.top += LMGetMBarHeight(); + + dlogHandle = (DialogTHndl)GetResource('DLOG', dialogID); + if (dlogHandle != nil) + { + wasState = HGetState((Handle)dlogHandle); + HLock((Handle)dlogHandle); + + dlogBounds = (**dlogHandle).boundsRect; + OffsetRect(&dlogBounds, theScreen.left - dlogBounds.left, + theScreen.top - dlogBounds.top); + + hPos = ((theScreen.right - theScreen.left) - + (dlogBounds.right - dlogBounds.left)) / 2; + vPos = ((theScreen.bottom - theScreen.top) - + (dlogBounds.bottom - dlogBounds.top)) / 2; + + OffsetRect(&dlogBounds, hPos, vPos + LMGetMBarHeight()); + + (**dlogHandle).boundsRect = dlogBounds; + HSetState((Handle)dlogHandle, wasState); + } +} +*/ +//-------------------------------------------------------------- CenterAlert +// Given an alert ID, this function properly centers it on the main monitor. +/* +void CenterAlert (short alertID) +{ + AlertTHndl alertHandle; + Rect theScreen, alertRect; + short horiOff, vertOff; + Byte wasState; + + theScreen = qd.screenBits.bounds; + theScreen.top += LMGetMBarHeight(); + + alertHandle = (AlertTHndl)GetResource('ALRT', alertID); + if (alertHandle != nil) + { + wasState = HGetState((Handle)alertHandle); + HLock((Handle)alertHandle); + + alertRect = (**alertHandle).boundsRect; + OffsetRect(&alertRect, -alertRect.left, -alertRect.top); + + horiOff = ((theScreen.right - theScreen.left) - alertRect.right) / 2; + vertOff = ((theScreen.bottom - theScreen.top) - alertRect.bottom) / 3; + + OffsetRect(&alertRect, horiOff, vertOff + LMGetMBarHeight()); + + (**alertHandle).boundsRect = alertRect; + HSetState((Handle)alertHandle, wasState); + } +} +*/ +//-------------------------------------------------------------- ZoomOutDialogRect + +// Given a dialog, this function does the "zoom" animation to make theÉ +// the dialog appear to expand from nothingness or zoom in at you. +/* +void ZoomOutDialogRect (short dialogID) +{ + #define kSteps 16 + #define kZoomDelay 1 + DialogTHndl dlogHandle; + GrafPtr wasPort, tempPort; + Rect dlogBounds, zoomRect; + UInt32 dummyLong; + Byte wasState; + short wideStep, highStep, i; + + GetPort(&wasPort); + + tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); + OpenPort(tempPort); + + dlogHandle = (DialogTHndl)GetResource('DLOG', dialogID); + if (dlogHandle != nil) + { + wasState = HGetState((Handle)dlogHandle); + HLock((Handle)dlogHandle); + dlogBounds = (**dlogHandle).boundsRect; + HSetState((Handle)dlogHandle, wasState); + } + + wideStep = ((dlogBounds.right - dlogBounds.left) / 2) / kSteps; + highStep = ((dlogBounds.bottom - dlogBounds.top) / 2) / kSteps; + + SetRect(&zoomRect, dlogBounds.left + (wideStep * kSteps), + dlogBounds.top + (highStep * kSteps), + dlogBounds.right - (wideStep * kSteps), + dlogBounds.bottom - (highStep * kSteps)); + GlobalToLocalRect(&zoomRect); + + PenPat(GetQDGlobalsGray(&dummyPattern)); + PenMode(patXor); + + for (i = 0; i < kSteps; i++) + { + FrameRect(&zoomRect); + Delay(kZoomDelay, &dummyLong); + FrameRect(&zoomRect); + InsetRect(&zoomRect, -wideStep, -highStep); + } + + ClosePort(tempPort); + + SetPort((GrafPtr)wasPort); +} +*/ +//-------------------------------------------------------------- ZoomOutAlertRect + +// Like the above funciton but zooms out alerts instead of dialogs. +/* +void ZoomOutAlertRect (short alertID) +{ + #define kSteps 16 + #define kZoomDelay 1 + AlertTHndl alertHandle; + GrafPtr wasPort, tempPort; + Rect alertBounds, zoomRect; + UInt32 dummyLong; + Byte wasState; + short wideStep, highStep, i; + + GetPort(&wasPort); + + tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); + OpenPort(tempPort); + + alertHandle = (AlertTHndl)GetResource('ALRT', alertID); + if (alertHandle != nil) + { + wasState = HGetState((Handle)alertHandle); + HLock((Handle)alertHandle); + alertBounds = (**alertHandle).boundsRect; + HSetState((Handle)alertHandle, wasState); + } + + wideStep = ((alertBounds.right - alertBounds.left) / 2) / kSteps; + highStep = ((alertBounds.bottom - alertBounds.top) / 2) / kSteps; + + SetRect(&zoomRect, alertBounds.left + (wideStep * kSteps), + alertBounds.top + (highStep * kSteps), + alertBounds.right - (wideStep * kSteps), + alertBounds.bottom - (highStep * kSteps)); + GlobalToLocalRect(&zoomRect); + + PenPat(GetQDGlobalsGray(&dummyPattern)); + PenMode(patXor); + + for (i = 0; i < kSteps; i++) + { + FrameRect(&zoomRect); + Delay(kZoomDelay, &dummyLong); + FrameRect(&zoomRect); + InsetRect(&zoomRect, -wideStep, -highStep); + } + + ClosePort(tempPort); + + SetPort((GrafPtr)wasPort); +} +*/ + +//-------------------------------------------------------------- FlashDialogButton +// Flashes the default dialog button (item = 1) so as to make it appearÉ +// as though the user clicked on it. + +void FlashDialogButton (DialogPtr theDialog, short itemNumber) +{ + Rect itemRect; + Handle itemHandle; + UInt32 dummyLong; + short itemType; + + GetDialogItem(theDialog, itemNumber, &itemType, &itemHandle, &itemRect); + HiliteControl((ControlHandle)itemHandle, kControlButtonPart); + Delay(8, &dummyLong); + HiliteControl((ControlHandle)itemHandle, 0); +} + +//-------------------------------------------------------------- DrawDefaultButton +// Draws a fat outline around the default item (item = 1). This is theÉ +// item that is selected if the user hits the Return key. + +void DrawDefaultButton (DialogPtr theDialog) +{ + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, 1, &itemType, &itemHandle, &itemRect); + InsetRect(&itemRect, -4, -4); + PenSize(3, 3); + FrameRoundRect(&itemRect, 16, 16); + PenNormal(); +} + +//-------------------------------------------------------------- GetDialogString +// Returns a string from a specific dialog item. + +void GetDialogString (DialogPtr theDialog, short item, StringPtr theString) +{ + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + GetDialogItemText(itemHandle, theString); +} + +//-------------------------------------------------------------- SetDialogString +// Sets a specific string to a specific dialog item. + +void SetDialogString (DialogPtr theDialog, short item, const PLPasStr &theString) +{ + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + SetDialogItemText(itemHandle, theString); +} + +//-------------------------------------------------------------- GetDialogStringLen +// Returns the length of a dialog item string (text). + +short GetDialogStringLen (DialogPtr theDialog, short item) +{ + Rect itemRect; + Str255 theString; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + GetDialogItemText(itemHandle, theString); + return (theString[0]); +} + +//-------------------------------------------------------------- GetDialogItemValue +// Returns the value or "state" of a dialog item. For checkboxes andÉ +// radio buttons, this may be a 1 or 0. + +void GetDialogItemValue (DialogPtr theDialog, short item, short *theState) +{ + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + *theState = GetControlValue((ControlHandle)itemHandle); +} + +//-------------------------------------------------------------- SetDialogItemValue +// Sets a specific dialogf items value or state (can set or clearÉ +// checkboxes, radio buttons, etc.). + +void SetDialogItemValue (DialogPtr theDialog, short item, short theState) +{ + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + SetControlValue((ControlHandle)itemHandle, theState); +} + +//-------------------------------------------------------------- ToggleDialogItemValue +// If item is a checkbox or radio button, its state is toggled. + +void ToggleDialogItemValue (DialogPtr theDialog, short item) +{ + Rect itemRect; + Handle itemHandle; + short itemType, theState; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + theState = GetControlValue((ControlHandle)itemHandle); + if (theState == 0) + theState = 1; + else + theState = 0; + SetControlValue((ControlHandle)itemHandle, theState); +} + +//-------------------------------------------------------------- SetDialogNumToStr +// Function accepts an integer, converts it to a string and sets aÉ +// dialog items text to this string. + +void SetDialogNumToStr (DialogPtr theDialog, short item, long theNumber) +{ + Str255 theString; + Rect itemRect; + Handle itemHandle; + short itemType; + + NumToString(theNumber, theString); + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + SetDialogItemText(itemHandle, theString); +} + +//-------------------------------------------------------------- GetDialogNumFromStr +// Function extracts the text from a dialog item and converts it to anÉ +// integer for returning. + +void GetDialogNumFromStr (DialogPtr theDialog, short item, long *theNumber) +{ + Str255 theString; + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + GetDialogItemText(itemHandle, theString); + StringToNum(theString, theNumber); +} + +//-------------------------------------------------------------- GetDialogItemRect +// Returns the bounding rectangle of the specified dialog item. + +void GetDialogItemRect (DialogPtr theDialog, short item, Rect *theRect) +{ + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, theRect); +} + +//-------------------------------------------------------------- SetDialogItemRect +// Sets the bounding rectangle of the specified dialog item. Used toÉ +// resize or move a control. + +void SetDialogItemRect (DialogPtr theDialog, short item, Rect *theRect) +{ + Rect oldRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &oldRect); + OffsetRect(&oldRect, theRect->left - oldRect.left, theRect->top - oldRect.top); + SetDialogItem(theDialog, item, itemType, itemHandle, &oldRect); +} + +//-------------------------------------------------------------- OffsetDialogItemRect +// Moves a dialog item by h and v. + +void OffsetDialogItemRect (DialogPtr theDialog, short item, short h, short v) +{ + Rect oldRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &oldRect); + OffsetRect(&oldRect, h, v); + SetDialogItem(theDialog, item, itemType, itemHandle, &oldRect); +} + +//-------------------------------------------------------------- SelectFromRadioGroup +// Assuming a series of consecutively numbered radio buttons, this functionÉ +// clears the whole range of them but sets the one specified (as thoughÉ +// the radio buttons are linked and only one can be set at a time). + +void SelectFromRadioGroup (DialogPtr dial, short which, short first, short last) +{ + Rect iRect; + Handle iHandle; + short iType, i; + + for (i = first; i <= last; i++) + { + GetDialogItem(dial, i, &iType, &iHandle, &iRect); + SetControlValue((ControlHandle)iHandle, (short)false); + } + + GetDialogItem(dial, which, &iType, &iHandle, &iRect); + SetControlValue((ControlHandle)iHandle, (short)true); +} + +//-------------------------------------------------------------- AddMenuToPopUp +// Assigns a menu handle to a pop-up dialog item - thus, giving thatÉ +// pop-up item something to pop up. +/* +void AddMenuToPopUp (DialogPtr theDialog, short whichItem, MenuHandle theMenu) +{ + Rect iRect; + Handle iHandle; + short iType; + + GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); + (**(ControlHandle)iHandle).contrlRfCon = (long)theMenu; +} +*/ +//-------------------------------------------------------------- GetPopUpMenuValu +// Returns which item is currently selected in a pop-up menu. + +void GetPopUpMenuValue (DialogPtr theDialog, short whichItem, short *value) +{ + Rect iRect; + Handle iHandle; + short iType; + + GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); + *value = GetControlValue((ControlHandle)iHandle); +} + +//-------------------------------------------------------------- SetPopUpMenuValue +// Forces a specific item to be set (as though selected) in a pop-up menu. + +void SetPopUpMenuValue (DialogPtr theDialog, short whichItem, short value) +{ + Rect iRect; + Handle iHandle; + short iType; + + GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); + SetControlValue((ControlHandle)iHandle, value); +} + +//-------------------------------------------------------------- MyEnableControl +// "Un-grays" or enables a dialog item (usually a button). + +void MyEnableControl (DialogPtr theDialog, short whichItem) +{ + Rect iRect; + Handle iHandle; + short iType; + + GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); + HiliteControl((ControlHandle)iHandle, kActive); +} + +//-------------------------------------------------------------- MyDisableControl +// "Grays out" or disables a dialog item (usually a button). + +void MyDisableControl (DialogPtr theDialog, short whichItem) +{ + Rect iRect; + Handle iHandle; + short iType; + + GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); + HiliteControl((ControlHandle)iHandle, kInactive); +} + +//-------------------------------------------------------------- DrawDialogUserText +// Given a string of text and an item, this function draws the stringÉ +// within the bounding rect of the item. Dialog item assumed to beÉ +// a "user item" (invisible item with only bounds). + +void DrawDialogUserText (DialogPtr dial, short item, StringPtr text, Boolean invert) +{ + Rect iRect; + Handle iHandle; + Str255 newString, stringCopy; + short iType, textLong, i, inset; + + TextFont(applFont); + TextSize(9); + + PasStringCopy(text, stringCopy); + GetDialogItem(dial, item, &iType, &iHandle, &iRect); + if ((StringWidth(stringCopy) + 2) > (iRect.right - iRect.left)) + CollapseStringToWidth(stringCopy, iRect.right - iRect.left - 2); + textLong = stringCopy[0]; + for (i = 0; i < textLong; i++) + newString[i] = stringCopy[i + 1]; + + OffsetRect(&iRect, 0, 1); + EraseRect(&iRect); + OffsetRect(&iRect, 0, -1); + + inset = ((iRect.right - iRect.left) - (StringWidth(stringCopy) + 2)) / 2; + iRect.left += inset; + iRect.right -= inset; + + TETextBox(newString, textLong, &iRect, teCenter); + if (invert) + { + OffsetRect(&iRect, 0, 1); + InvertRect(&iRect); + } +} + +//-------------------------------------------------------------- DrawDialogUserText +// Similar to the above function but doesn't call TETextBox(). Instead,É +// it truncates the string (and appends "É") to the end in order thatÉ +// the string fits within the dialog item's bounds. + +void DrawDialogUserText2 (DialogPtr dial, short item, StringPtr text) +{ + Rect iRect; + Handle iHandle; + Str255 stringCopy; + short iType; + + TextFont(applFont); + TextSize(9); + + PasStringCopy(text, stringCopy); + GetDialogItem(dial, item, &iType, &iHandle, &iRect); + if ((StringWidth(stringCopy) + 2) > (iRect.right - iRect.left)) + CollapseStringToWidth(stringCopy, iRect.right - iRect.left - 2); + MoveTo(iRect.left, iRect.bottom); + DrawString(stringCopy); +} + +//-------------------------------------------------------------- LoadDialogPICT +// Draws a 'PICT' specified by ID within the bounds of the specifiedÉ +// dialog item. + +void LoadDialogPICT (DialogPtr theDialog, short item, short theID) +{ + Rect iRect; + Handle iHandle; + PicHandle thePict; + short iType; + + GetDialogItem(theDialog, item, &iType, &iHandle, &iRect); + thePict = GetPicture(theID); + if (thePict) + DrawPicture(thePict, &iRect); +} + +//-------------------------------------------------------------- FrameDialogItem +// Given a dialog item, this function draws a box around it. + +void FrameDialogItem (DialogPtr theDialog, short item) +{ + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + FrameRect(&itemRect); +} + +//-------------------------------------------------------------- FrameDialogItemC +// Given a dialog item, this function draws a color (specified) box around it. + +void FrameDialogItemC (DialogPtr theDialog, short item, long color) +{ + RGBColor theRGBColor, wasColor; + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + GetForeColor(&wasColor); + Index2Color(color, &theRGBColor); + RGBForeColor(&theRGBColor); + FrameRect(&itemRect); + RGBForeColor(&wasColor); +} + +//-------------------------------------------------------------- FrameOvalDialogItem +// Given a dialog item, this function draws an oval around it. + +void FrameOvalDialogItem (DialogPtr theDialog, short item) +{ + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + FrameOval(&itemRect); +} + +//-------------------------------------------------------------- BorderDialogItem +// Given a dialog item, this function draws any combination of 4 sidesÉ +// of a box around it. Which sides get drawn is encoded in "sides". + +void BorderDialogItem (DialogPtr theDialog, short item, short sides) +{ + Rect itemRect; + Handle itemHandle; + short itemType; + + // 1 = left + // 2 = top + // 4 = bottom + // 8 = right ... so 6 = top & bottom, 15 = all 4 sides + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + + if (sides >= 8) // 8 = right + { + MoveTo(itemRect.right, itemRect.top); + LineTo(itemRect.right, itemRect.bottom); + sides -= 8; + } + if (sides >= 4) // 4 = bottom + { + MoveTo(itemRect.left, itemRect.bottom); + LineTo(itemRect.right, itemRect.bottom); + sides -= 4; + } + if (sides >= 2) // 2 = top + { + MoveTo(itemRect.left, itemRect.top - 1); + LineTo(itemRect.right, itemRect.top - 1); + sides -= 2; + } + if (sides >= 1) // 1 = left + { + MoveTo(itemRect.left - 1, itemRect.top); + LineTo(itemRect.left - 1, itemRect.bottom); + } +} + +//-------------------------------------------------------------- ShadowDialogItem +// Draws a drop shadow to the right and below a specified dialog item. + +void ShadowDialogItem (DialogPtr theDialog, short item, short thickness) +{ + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + PenSize(thickness, thickness); + MoveTo(itemRect.left + thickness, itemRect.bottom); + Line(itemRect.right - itemRect.left - thickness, 0); + MoveTo(itemRect.right, itemRect.top + thickness); + Line(0, itemRect.bottom - itemRect.top - thickness); + PenNormal(); +} + +//-------------------------------------------------------------- EraseDialogItem +// Erases (but doesn't physically remove) a dialog item. + +void EraseDialogItem (DialogPtr theDialog, short item) +{ + Rect itemRect; + Handle itemHandle; + short itemType; + + GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + EraseRect(&itemRect); +} + diff --git a/GpApp/DialogUtils.h b/GpApp/DialogUtils.h new file mode 100644 index 0000000..da0f150 --- /dev/null +++ b/GpApp/DialogUtils.h @@ -0,0 +1,47 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// DialogUtils.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLDialogs.h" + + +void BringUpDialog (DialogPtr *theDialog, short dialogID); +//void GetPutDialogCorner (Point *); +//void GetGetDialogCorner (Point *); +//void CenterDialog (short); +void GetDialogRect (Rect *, short); +//void TrueCenterDialog (short); +//void CenterAlert (short); +//void ZoomOutDialogRect (short); +//void ZoomOutAlertRect (short); +void FlashDialogButton (DialogPtr, short); +void DrawDefaultButton (DialogPtr); +void GetDialogString (DialogPtr, short, StringPtr); +void SetDialogString (DialogPtr, short, const PLPasStr&); +short GetDialogStringLen (DialogPtr, short); +void GetDialogItemValue (DialogPtr, short, short *); +void SetDialogItemValue (DialogPtr, short, short); +void ToggleDialogItemValue (DialogPtr, short); +void SetDialogNumToStr (DialogPtr, short, long); +void GetDialogNumFromStr (DialogPtr, short, long *); +void GetDialogItemRect (DialogPtr, short, Rect *); +void SetDialogItemRect (DialogPtr, short, Rect *); +void OffsetDialogItemRect (DialogPtr, short, short, short); +void SelectFromRadioGroup (DialogPtr, short, short, short); +//void AddMenuToPopUp (DialogPtr, short, MenuHandle); +void GetPopUpMenuValue (DialogPtr, short, short *); +void SetPopUpMenuValue (DialogPtr, short, short); +void MyEnableControl(DialogPtr, short); +void MyDisableControl(DialogPtr, short); +void DrawDialogUserText (DialogPtr, short, StringPtr, Boolean); +void DrawDialogUserText2 (DialogPtr, short, StringPtr); +void LoadDialogPICT (DialogPtr, short, short); +void FrameDialogItem (DialogPtr, short); +void FrameDialogItemC (DialogPtr, short, long); +void FrameOvalDialogItem (DialogPtr, short); +void BorderDialogItem (DialogPtr, short, short); +void ShadowDialogItem (DialogPtr, short, short); +void EraseDialogItem (DialogPtr, short); diff --git a/GpApp/DynamicMaps.cpp b/GpApp/DynamicMaps.cpp new file mode 100644 index 0000000..33ccde6 --- /dev/null +++ b/GpApp/DynamicMaps.cpp @@ -0,0 +1,798 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// DynamicMaps.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Environ.h" +#include "MainWindow.h" +#include "Objects.h" +#include "RectUtils.h" +#include "Room.h" +#include "Utilities.h" + + +void BackUpFlames (Rect *, short); +void BackUpTikiFlames (Rect *, short); +void BackUpBBQCoals (Rect *, short); +void BackUpPendulum (Rect *, short); +void BackUpStar (Rect *, short); + + +sparklePtr sparkles; +flyingPtPtr flyingPoints; +flamePtr flames, tikiFlames, bbqCoals; +pendulumPtr pendulums; +starPtr theStars; +shredPtr shreds; +Rect pointsSrc[15]; +short numSparkles, numFlyingPts, numChimes; +short numFlames, numSavedMaps, numTikiFlames, numCoals; +short numPendulums, clockFrame, numStars, numShredded; + + +extern savedType savedMaps[]; +extern Rect flame[], tikiFlame[], coals[], pendulumSrc[]; +extern Rect starSrc[]; +extern short numGrease, numDynamics; + + +//============================================================== Functions +//-------------------------------------------------------------- NilSavedMaps +// Deletes array of "dyanmics" offscreen pixmaps. + +void NilSavedMaps (void) +{ + short i; + + for (i = 0; i < kMaxSavedMaps; i++) + { + if (savedMaps[i].map != nil) + { + DisposeGWorld(savedMaps[i].map); +// KillOffScreenPixMap(savedMaps[i].map); + savedMaps[i].map = nil; + } + savedMaps[i].where = -1; + savedMaps[i].who = -1; + } + numSavedMaps = 0; +} + +//-------------------------------------------------------------- BackUpToSavedMap +// Saves a copy of the room behind an object to an array of pixmaps. +// Then when the object in question is drawn, there is a copy of theÉ +// room that it obscured so that, should the player get the object,É +// it can be made to "disappear". + +short BackUpToSavedMap (Rect *theRect, short where, short who) +{ + Rect mapRect; + OSErr theErr; + + if (numSavedMaps >= kMaxSavedMaps) + return(-1); + + mapRect = *theRect; + ZeroRectCorner(&mapRect); + savedMaps[numSavedMaps].dest = *theRect; +// CreateOffScreenPixMap(&mapRect, &savedMaps[numSavedMaps].map); + theErr = CreateOffScreenGWorld(&savedMaps[numSavedMaps].map, &mapRect, kPreferredDepth); + + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + GetPortBitMapForCopyBits(savedMaps[numSavedMaps].map), + theRect, &mapRect, srcCopy, nil); + + savedMaps[numSavedMaps].where = where; + savedMaps[numSavedMaps].who = who; + numSavedMaps++; + + return (numSavedMaps - 1); // return array index +} + +//-------------------------------------------------------------- ReBackUpSavedMap +// This function is similar to the above, but assumes there is alreadyÉ +// a slot in the pixmap array for the object. It re-copies the backgroundÉ +// and is needed when the lights in the room go on or off. + +short ReBackUpSavedMap (Rect *theRect, short where, short who) +{ + Rect mapRect; + short i, foundIndex; + + foundIndex = -1; + + for (i = 0; i < numSavedMaps; i++) + { + if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) + { + foundIndex = i; + mapRect = *theRect; + ZeroRectCorner(&mapRect); + + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + GetPortBitMapForCopyBits(savedMaps[foundIndex].map), + theRect, &mapRect, srcCopy, nil); + + return (foundIndex); + } + } + + return (foundIndex); +} + +//-------------------------------------------------------------- RestoreFromSavedMap + +// This copies the saved background swatch to the screen - effectivelyÉ +// covering up or "erasing" the object. + +void RestoreFromSavedMap (short where, short who, Boolean doSparkle) +{ + Rect mapRect, bounds; + short i; + + for (i = 0; i < numSavedMaps; i++) + { + if ((savedMaps[i].where == where) && (savedMaps[i].who == who) && + (savedMaps[i].map != nil)) + { + mapRect = savedMaps[i].dest; + ZeroRectCorner(&mapRect); + + CopyBits(GetPortBitMapForCopyBits(savedMaps[i].map), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &mapRect, &savedMaps[i].dest, srcCopy, nil); + CopyBits(GetPortBitMapForCopyBits(savedMaps[i].map), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &mapRect, &savedMaps[i].dest, srcCopy, nil); + + AddRectToWorkRects(&savedMaps[i].dest); + + if (doSparkle) + { + bounds = savedMaps[i].dest; + QOffsetRect(&bounds, -playOriginH, -playOriginV); + AddSparkle(&bounds); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + break; + } + } +} + +//-------------------------------------------------------------- AddSparkle + +// This adds a "sparkle" object to the fixed array of sparkles. + +void AddSparkle (Rect *theRect) +{ + Rect centeredRect; + short i; + + if (numSparkles < kMaxSparkles) + { + theRect->left += playOriginH; + theRect->right += playOriginH; + theRect->top += playOriginV; + theRect->bottom += playOriginV; + + centeredRect = sparkleSrc[0]; + CenterRectInRect(¢eredRect, theRect); + + for (i = 0; i < kMaxSparkles; i++) + if (sparkles[i].mode == -1) + { + sparkles[i].bounds = centeredRect; + sparkles[i].mode = 0; + numSparkles++; + break; + } + } +} + +//-------------------------------------------------------------- AddFlyingPoint + +// This adds a "flying point" object to the array of flying points. + +void AddFlyingPoint (Rect *theRect, short points, short hVel, short vVel) +{ + Rect centeredRect; + short i; + + if (numFlyingPts < kMaxFlyingPts) + { + theRect->left += playOriginH; + theRect->right += playOriginH; + theRect->top += playOriginV; + theRect->bottom += playOriginV; + + centeredRect = pointsSrc[0]; + CenterRectInRect(¢eredRect, theRect); + + for (i = 0; i < kMaxFlyingPts; i++) + if (flyingPoints[i].mode == -1) + { + flyingPoints[i].dest = centeredRect; + flyingPoints[i].whole = centeredRect; + flyingPoints[i].loops = 0; + flyingPoints[i].hVel = hVel; + flyingPoints[i].vVel = vVel; + switch (points) + { + case 100: + flyingPoints[i].start = 12; + flyingPoints[i].stop = 14; + break; + + case 250: + flyingPoints[i].start = 9; + flyingPoints[i].stop = 11; + break; + + case 300: + flyingPoints[i].start = 6; + flyingPoints[i].stop = 8; + break; + + case 500: + flyingPoints[i].start = 3; + flyingPoints[i].stop = 5; + break; + + default: + flyingPoints[i].start = 0; + flyingPoints[i].stop = 2; + break; + } + flyingPoints[i].mode = flyingPoints[i].start; + numFlyingPts++; + break; + } + } +} + +//-------------------------------------------------------------- BackUpFlames + +// This makes copies of the area of the room behind a flame. The flameÉ +// graphic can be "copy masked" to this pixmap then and then simpleÉ +// CopyBits() calls will properly draw the flame on screen with theÉ +// proper background. + +void BackUpFlames (Rect *src, short index) +{ + Rect dest; + short i; + + QSetRect(&dest, 0, 0, 16, 15); + for (i = 0; i < kNumCandleFlames; i++) + { + // Copy background to map. + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + GetPortBitMapForCopyBits(savedMaps[index].map), + src, &dest, srcCopy, nil); + + // Copy flame to map. + CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), + (BitMap *)*GetGWorldPixMap(blowerMaskMap), + GetPortBitMapForCopyBits(savedMaps[index].map), + &flame[i], &flame[i], &dest); + + + QOffsetRect(&dest, 0, 15); + } +} + +//-------------------------------------------------------------- ReBackUpFlames + +// Like the above function but this is called when the lighting changesÉ +// in a room (lights go on or off). + +void ReBackUpFlames (short where, short who) +{ + short i, f; + + for (i = 0; i < numSavedMaps; i++) + { + if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) + { + for (f = 0; f < numFlames; f++) + { + if (flames[f].who == i) + { + BackUpFlames(&flames[f].dest, i); + return; + } + } + } + } +} + +//-------------------------------------------------------------- AddCandleFlame + +// This adds a candle flame to tha array of flames. + +void AddCandleFlame (short where, short who, short h, short v) +{ + Rect src, bounds; + short savedNum; + + if ((numFlames >= kMaxCandles) || (h < 16) || (v < 15)) + return; + + QSetRect(&src, 0, 0, 16, 15); + QOffsetRect(&src, h - 8, v - 15); + if ((thisMac.isDepth == 4) && ((src.left % 2) == 1)) + { + QOffsetRect(&src, -1, 0); + if (src.left < 0) + QOffsetRect(&src, 2, 0); + } + QSetRect(&bounds, 0, 0, 16, 15 * kNumCandleFlames); + savedNum = BackUpToSavedMap(&bounds, where, who); + if (savedNum != -1) + { + BackUpFlames(&src, savedNum); + flames[numFlames].dest = src; + flames[numFlames].mode = RandomInt(kNumCandleFlames); + QSetRect(&flames[numFlames].src, 0, 0, 16, 15); + QOffsetRect(&flames[numFlames].src, 0, flames[numFlames].mode * 15); + flames[numFlames].who = savedNum; + numFlames++; + } +} + +//-------------------------------------------------------------- BackUpTikiFlames +// This is like the function BackUpFlames() but customized for Tiki torches. + +void BackUpTikiFlames (Rect *src, short index) +{ + Rect dest; + short i; + + QSetRect(&dest, 0, 0, 8, 10); + for (i = 0; i < kNumTikiFlames; i++) + { + // copy background to map + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + GetPortBitMapForCopyBits(savedMaps[index].map), + src, &dest, srcCopy, nil); + + // copy flame to map + CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), + (BitMap *)*GetGWorldPixMap(blowerMaskMap), + GetPortBitMapForCopyBits(savedMaps[index].map), + &tikiFlame[i], &tikiFlame[i], &dest); + + QOffsetRect(&dest, 0, 10); + } +} + +//-------------------------------------------------------------- ReBackUpTikiFlames + +// This is like the function ReBackUpFlames() but customized for Tiki torches. + +void ReBackUpTikiFlames (short where, short who) +{ + short i, f; + + for (i = 0; i < numSavedMaps; i++) + { + if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) + { + for (f = 0; f < numTikiFlames; f++) + { + if (tikiFlames[f].who == i) + { + BackUpTikiFlames(&tikiFlames[f].dest, i); + return; + } + } + } + } +} + +//-------------------------------------------------------------- AddTikiFlame + +// This adds a tiki flame to the array of tiki flames. + +void AddTikiFlame (short where, short who, short h, short v) +{ + Rect src, bounds; + short savedNum; + + if ((numTikiFlames >= kMaxTikis) || (h < 8) || (v < 10)) + return; + + QSetRect(&src, 0, 0, 8, 10); + if ((thisMac.isDepth == 4) && ((h % 2) == 1)) + { + h--; + if (h < 0) + h += 2; + } + QOffsetRect(&src, h, v); + QSetRect(&bounds, 0, 0, 8, 10 * kNumTikiFlames); + savedNum = BackUpToSavedMap(&bounds, where, who); + if (savedNum != -1) + { + BackUpTikiFlames(&src, savedNum); + tikiFlames[numTikiFlames].dest = src; + tikiFlames[numTikiFlames].mode = RandomInt(kNumTikiFlames); + QSetRect(&tikiFlames[numTikiFlames].src, 0, 0, 8, 10); + QOffsetRect(&tikiFlames[numTikiFlames].src, 0, + tikiFlames[numTikiFlames].mode * 10); + tikiFlames[numTikiFlames].who = savedNum; + numTikiFlames++; + } +} + +//-------------------------------------------------------------- BackUpBBQCoals + +// Another one - but for BBQ coals. + +void BackUpBBQCoals (Rect *src, short index) +{ + Rect dest; + short i; + + QSetRect(&dest, 0, 0, 32, 9); + for (i = 0; i < kNumBBQCoals; i++) + { + // copy background to map + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + GetPortBitMapForCopyBits(savedMaps[index].map), + src, &dest, srcCopy, nil); + + // copy flame to map + CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), + (BitMap *)*GetGWorldPixMap(blowerMaskMap), + GetPortBitMapForCopyBits(savedMaps[index].map), + &coals[i], &coals[i], &dest); + + QOffsetRect(&dest, 0, 9); + } +} + +//-------------------------------------------------------------- ReBackUpBBQCoals + +// Sense a pattern here? + +void ReBackUpBBQCoals (short where, short who) +{ + short i, f; + + for (i = 0; i < numSavedMaps; i++) + { + if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) + { + for (f = 0; f < numCoals; f++) + { + if (bbqCoals[f].who == i) + { + BackUpBBQCoals(&bbqCoals[f].dest, i); + return; + } + } + } + } +} + +//-------------------------------------------------------------- AddBBQCoals + +// Adds BBQ coals to the array of BBQ coals. + +void AddBBQCoals (short where, short who, short h, short v) +{ + Rect src, bounds; + short savedNum; + + if ((numCoals >= kMaxCoals) || (h < 32) || (v < 9)) + return; + + QSetRect(&src, 0, 0, 32, 9); + if ((thisMac.isDepth == 4) && ((h % 2) == 1)) + { + h--; + if (h < 0) + h += 2; + } + QOffsetRect(&src, h, v); + QSetRect(&bounds, 0, 0, 32, 9 * kNumBBQCoals); + savedNum = BackUpToSavedMap(&bounds, where, who); + if (savedNum != -1) + { + BackUpBBQCoals(&src, savedNum); + bbqCoals[numCoals].dest = src; + bbqCoals[numCoals].mode = RandomInt(kNumBBQCoals); + QSetRect(&bbqCoals[numCoals].src, 0, 0, 32, 9); + QOffsetRect(&bbqCoals[numCoals].src, 0, bbqCoals[numCoals].mode * 9); + bbqCoals[numCoals].who = savedNum; + + numCoals++; + } +} + +//-------------------------------------------------------------- BackUpPendulum +// Just like many of the previous functions, but for the pendulum on theÉ +// cuckoo clock. + +void BackUpPendulum (Rect *src, short index) +{ + Rect dest; + short i; + + QSetRect(&dest, 0, 0, 32, 28); + for (i = 0; i < kNumPendulums; i++) + { + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + GetPortBitMapForCopyBits(savedMaps[index].map), + src, &dest, srcCopy, nil); + + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + GetPortBitMapForCopyBits(savedMaps[index].map), + &pendulumSrc[i], &pendulumSrc[i], &dest); + + QOffsetRect(&dest, 0, 28); + } +} + +//-------------------------------------------------------------- ReBackUpPendulum + +// Backs up the pendulums in the event of lights going on or off. + +void ReBackUpPendulum (short where, short who) +{ + short i, f; + + for (i = 0; i < numSavedMaps; i++) + { + if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) + { + for (f = 0; f < numPendulums; f++) + { + if (pendulums[f].who == i) + { + BackUpPendulum(&pendulums[f].dest, i); + return; + } + } + } + } +} + +//-------------------------------------------------------------- AddPendulum + +// Adds a pendulum to the array of pendulums. + +void AddPendulum (short where, short who, short h, short v) +{ + Rect src, bounds; + short savedNum; + + if ((numPendulums >= kMaxPendulums) || (h < 32) || (v < 28)) + return; + + clockFrame = 10; + QSetRect(&bounds, 0, 0, 32, 28 * kNumPendulums); + savedNum = BackUpToSavedMap(&bounds, where, who); + if (savedNum != -1) + { + QSetRect(&src, 0, 0, 32, 28); + if ((thisMac.isDepth == 4) && ((h % 2) == 1)) + { + h--; + if (h < 0) + h += 2; + } + QOffsetRect(&src, h, v); + BackUpPendulum (&src, savedNum); + pendulums[numPendulums].dest = src; + pendulums[numPendulums].mode = 1; + if (RandomInt(2) == 0) + pendulums[numPendulums].toOrFro = true; + else + pendulums[numPendulums].toOrFro = false; + pendulums[numPendulums].active = true; + QSetRect(&pendulums[numPendulums].src, 0, 0, 32, 28); + QOffsetRect(&pendulums[numPendulums].src, 0, 28); + pendulums[numPendulums].who = savedNum; + pendulums[numPendulums].where = where; + pendulums[numPendulums].link = who; + numPendulums++; + } +} + +//-------------------------------------------------------------- BackUpStar + +// Makes a copy of background beneath a star. + +void BackUpStar (Rect *src, short index) +{ + Rect dest; + short i; + + QSetRect(&dest, 0, 0, 32, 31); + for (i = 0; i < 6; i++) + { + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + GetPortBitMapForCopyBits(savedMaps[index].map), + src, &dest, srcCopy, nil); + + // copy flame to map + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + GetPortBitMapForCopyBits(savedMaps[index].map), + &starSrc[i], &starSrc[i], &dest); + + QOffsetRect(&dest, 0, 31); + } +} + +//-------------------------------------------------------------- ReBackUpStar + +// Re-backs up the stars - in the event of lighting switch. + +void ReBackUpStar (short where, short who) +{ + short i, f; + + for (i = 0; i < numSavedMaps; i++) + { + if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) + { + for (f = 0; f < numStars; f++) + { + if (theStars[f].who == i) + { + BackUpStar(&theStars[f].dest, i); + return; + } + } + } + } +} + +//-------------------------------------------------------------- AddStar + +// Adds a star to the star array. + +void AddStar (short where, short who, short h, short v) +{ + Rect src, bounds; + short savedNum; + + if (numStars >= kMaxStars) + return; + + QSetRect(&src, 0, 0, 32, 31); + if ((thisMac.isDepth == 4) && ((h % 2) == 1)) + { + h--; + if (h < 0) + h += 2; + } + QOffsetRect(&src, h, v); + + QSetRect(&bounds, 0, 0, 32, 31 * 6); + savedNum = BackUpToSavedMap(&bounds, where, who); + if (savedNum != -1) + { + BackUpStar(&src, savedNum); + theStars[numStars].dest = src; + theStars[numStars].mode = RandomInt(6); + QSetRect(&theStars[numStars].src, 0, 0, 32, 31); + QOffsetRect(&theStars[numStars].src, 0, theStars[numStars].mode * 31); + theStars[numStars].who = savedNum; + theStars[numStars].link = who; + theStars[numStars].where = where; + + numStars++; + } +} + +//-------------------------------------------------------------- StopPendulum + +// Will set a flag to kill a pendulum. + +void StopPendulum (short where, short who) +{ + short i; + + for (i = 0; i < numPendulums; i++) + { + if ((pendulums[i].link == who) && (pendulums[i].where == where)) + pendulums[i].active = false; + } +} + +//-------------------------------------------------------------- StopStar + +// Will set a flag to kill a star. + +void StopStar (short where, short who) +{ + short i; + + for (i = 0; i < numStars; i++) + { + if ((theStars[i].link == who) && (theStars[i].where == where)) + theStars[i].mode = -1; + } +} + +//-------------------------------------------------------------- AddAShreddedGlider + +// Adds a shredded glider. + +void AddAShreddedGlider (Rect *bounds) +{ + if (numShredded > kMaxShredded) + return; + + shreds[numShredded].bounds.left = bounds->left + 4; + shreds[numShredded].bounds.right = shreds[numShredded].bounds.left + 40; + shreds[numShredded].bounds.top = bounds->top + 14; + shreds[numShredded].bounds.bottom = shreds[numShredded].bounds.top; + shreds[numShredded].frame = 0; + + numShredded++; +} + +//-------------------------------------------------------------- RemoveShreds + +// Remves the shredded glider. + +void RemoveShreds (void) +{ + short largest, who, i; + + largest = 0; + who = -1; + for (i = 0; i < numShredded; i++) + { + if (shreds[i].frame > largest) + { + largest = shreds[i].frame; + who = i; + } + } + + if (who != -1) + { + if (who == (numShredded - 1)) + { + numShredded--; + shreds[who].frame = 0; + } + else + { + numShredded--; + shreds[who].bounds = shreds[numShredded].bounds; + shreds[who].frame = shreds[numShredded].frame; + shreds[numShredded].frame = 0; + } + } +} + +//-------------------------------------------------------------- ZeroFlamesAndTheLike + +// Zeroes all counters that indicate the number of flames, pendulums, etc thereÉ +// are in a room. Called before a room is drawn. As the room is drawn, theÉ +// above functions are called and the counters incremented as objects of theÉ +// specified types are drawn. + +void ZeroFlamesAndTheLike (void) +{ + numFlames = 0; + numTikiFlames = 0; + numCoals = 0; + numPendulums = 0; + numGrease = 0; + numStars = 0; + numShredded = 0; + numChimes = 0; +} + diff --git a/Headers/DynamicMaps.h b/GpApp/DynamicMaps.h old mode 100755 new mode 100644 similarity index 100% rename from Headers/DynamicMaps.h rename to GpApp/DynamicMaps.h diff --git a/GpApp/Dynamics.cpp b/GpApp/Dynamics.cpp new file mode 100644 index 0000000..d8887e2 --- /dev/null +++ b/GpApp/Dynamics.cpp @@ -0,0 +1,776 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Dynamics.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Environ.h" +#include "MainWindow.h" +#include "Objects.h" +#include "RectUtils.h" +#include "Room.h" + + +#define kShoveVelocity 8 + + +Rect breadSrc[kNumBreadPicts]; + +extern dynaPtr dinahs; +extern bandPtr bands; +extern short numBands, tvWithMovieNumber; +extern Boolean evenFrame, twoPlayerGame, onePlayerLeft, playerDead; + + +//============================================================== Functions +//-------------------------------------------------------------- CheckDynamicCollision + +// Checks for a collision betwen the glider and one of the dynamic objects. +// For example, did the glider hit a flying piece of toast? + +void CheckDynamicCollision (short who, gliderPtr thisGlider, Boolean doOffset) +{ + Rect dinahRect; + + dinahRect = dinahs[who].dest; + if (doOffset) + QOffsetRect(&dinahRect, -playOriginH, -playOriginV); + + if (SectGlider(thisGlider, &dinahRect, true)) + { + if ((thisGlider->mode == kGliderNormal) || + (thisGlider->mode == kGliderFaceLeft) || + (thisGlider->mode == kGliderFaceRight) || + (thisGlider->mode == kGliderBurning) || + (thisGlider->mode == kGliderGoingFoil) || + (thisGlider->mode == kGliderLosingFoil)) + { + if ((foilTotal > 0) || (thisGlider->mode == kGliderLosingFoil)) + { + if (IsRectLeftOfRect(&dinahRect, &thisGlider->dest)) + thisGlider->hDesiredVel = kShoveVelocity; + else + thisGlider->hDesiredVel = -kShoveVelocity; + if (dinahs[who].vVel < 0) + thisGlider->vDesiredVel = dinahs[who].vVel; + PlayPrioritySound(kFoilHitSound, kFoilHitPriority); + if ((evenFrame) && (foilTotal > 0)) + { + foilTotal--; + if (foilTotal <= 0) + StartGliderFoilLosing(thisGlider); + } + } + else + { + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } + } +} + +//-------------------------------------------------------------- DidBandHitDynamic + +// Checks to see if a rubber band struck a dynamic. + +Boolean DidBandHitDynamic (short who) +{ + Rect dinahRect; + short i; + Boolean collided; + + dinahRect = dinahs[who].dest; + + for (i = 0; i < numBands; i++) + { + if (bands[i].dest.bottom < dinahRect.top) + collided = false; + else if (bands[i].dest.top > dinahRect.bottom) + collided = false; + else if (bands[i].dest.right < dinahRect.left) + collided = false; + else if (bands[i].dest.left > dinahRect.right) + collided = false; + else + collided = true; + + if (collided) + break; + } + + return (collided); +} + +//-------------------------------------------------------------- RenderToast + +// The following handful of functions handle drawing specific "dynamic" objecsts. + +void RenderToast (short who) +{ + Rect src, dest; + short vClip; + + if (dinahs[who].moving) + { + dest = dinahs[who].dest; + QOffsetRect(&dest, playOriginH, playOriginV); + src = breadSrc[dinahs[who].frame]; + vClip = dinahs[who].dest.bottom - dinahs[who].hVel; + if (vClip > 0) + { + src.bottom -= vClip; + dest.bottom -= vClip; + } + + CopyMask((BitMap *)*GetGWorldPixMap(toastSrcMap), + (BitMap *)*GetGWorldPixMap(toastMaskMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &src, &src, &dest); + + AddRectToBackRects(&dest); + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + } +} + +//-------------------------------------------------------------- RenderBalloon + +void RenderBalloon (short who) +{ + Rect src, dest; + + if (dinahs[who].moving) + { + dest = dinahs[who].dest; + QOffsetRect(&dest, playOriginH, playOriginV); + src = balloonSrc[dinahs[who].frame]; + + CopyMask((BitMap *)*GetGWorldPixMap(balloonSrcMap), + (BitMap *)*GetGWorldPixMap(balloonMaskMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &src, &src, &dest); + + AddRectToBackRects(&dest); + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + } +} + +//-------------------------------------------------------------- RenderCopter + +void RenderCopter (short who) +{ + Rect src, dest; + + if (dinahs[who].moving) + { + dest = dinahs[who].dest; + QOffsetRect(&dest, playOriginH, playOriginV); + src = copterSrc[dinahs[who].frame]; + + CopyMask((BitMap *)*GetGWorldPixMap(copterSrcMap), + (BitMap *)*GetGWorldPixMap(copterMaskMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &src, &src, &dest); + + AddRectToBackRects(&dest); + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + } +} + +//-------------------------------------------------------------- RenderDart + +void RenderDart (short who) +{ + Rect src, dest; + + if (dinahs[who].moving) + { + dest = dinahs[who].dest; + QOffsetRect(&dest, playOriginH, playOriginV); + src = dartSrc[dinahs[who].frame]; + + CopyMask((BitMap *)*GetGWorldPixMap(dartSrcMap), + (BitMap *)*GetGWorldPixMap(dartMaskMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &src, &src, &dest); + + AddRectToBackRects(&dest); + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + } +} + +//-------------------------------------------------------------- RenderBall + +void RenderBall (short who) +{ + Rect src, dest; + + dest = dinahs[who].dest; + QOffsetRect(&dest, playOriginH, playOriginV); + src = ballSrc[dinahs[who].frame]; + + CopyMask((BitMap *)*GetGWorldPixMap(ballSrcMap), + (BitMap *)*GetGWorldPixMap(ballMaskMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &src, &src, &dest); + + AddRectToBackRects(&dest); + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); +} + +//-------------------------------------------------------------- RenderDrip + +void RenderDrip (short who) +{ + Rect src, dest; + + dest = dinahs[who].dest; + QOffsetRect(&dest, playOriginH, playOriginV); + src = dripSrc[dinahs[who].frame]; + + CopyMask((BitMap *)*GetGWorldPixMap(dripSrcMap), + (BitMap *)*GetGWorldPixMap(dripMaskMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &src, &src, &dest); + + AddRectToBackRects(&dest); + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); +} + +//-------------------------------------------------------------- RenderFish + +void RenderFish (short who) +{ + Rect src, dest; + + dest = dinahs[who].dest; + QOffsetRect(&dest, playOriginH, playOriginV); + src = fishSrc[dinahs[who].frame]; + + if (dinahs[who].moving) + { + CopyMask((BitMap *)*GetGWorldPixMap(fishSrcMap), + (BitMap *)*GetGWorldPixMap(fishMaskMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &src, &src, &dest); + AddRectToBackRects(&dest); + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(fishSrcMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &src, &dest, srcCopy, nil); + AddRectToBackRects(&dest); + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + } +} + +//-------------------------------------------------------------- HandleSparkleObject + +// The following handful of functions are called each game frame and handleÉ +// the movement and state of the various types of dynamic objects. + +void HandleSparkleObject (short who) +{ + Rect tempRect; + + if (dinahs[who].active) // is it on? + { + if (dinahs[who].frame <= 0) // is it idle? + { // it is idle + dinahs[who].timer--; + if (dinahs[who].timer <= 0) + { + dinahs[who].timer = RandomInt(240) + 60;// reset timer + dinahs[who].frame = kNumSparkleModes; // time to sparkle + tempRect = dinahs[who].dest; + AddSparkle(&tempRect); + PlayPrioritySound(kMysticSound, kMysticPriority); + } + } + else // it's sparkling + dinahs[who].frame--; + } + else + { + } +} + +//-------------------------------------------------------------- HandleToast + +void HandleToast (short who) +{ + Rect dest; + + if (dinahs[who].moving) + { + if (evenFrame) + { + dinahs[who].frame++; + if (dinahs[who].frame >= kNumBreadPicts) + dinahs[who].frame = 0; + } + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == theGlider.which) + CheckDynamicCollision(who, &theGlider2, false); + else + CheckDynamicCollision(who, &theGlider, false); + } + else + { + CheckDynamicCollision(who, &theGlider, false); + CheckDynamicCollision(who, &theGlider2, false); + } + } + else + CheckDynamicCollision(who, &theGlider, false); + VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); + dinahs[who].whole = dinahs[who].dest; + if (dinahs[who].vVel > 0) + dinahs[who].whole.top -= dinahs[who].vVel; + else + dinahs[who].whole.bottom -= dinahs[who].vVel; + dinahs[who].vVel++; // falls + if (dinahs[who].vVel > dinahs[who].count) + { + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + dinahs[who].moving = false; + dinahs[who].frame = dinahs[who].timer; + PlayPrioritySound(kToastLandSound, kToastLandPriority); + } + } + else + { + if (dinahs[who].active) + dinahs[who].frame--; + if (dinahs[who].frame <= 0) + { + if (dinahs[who].active) + { + dinahs[who].vVel = (short)-dinahs[who].count; + dinahs[who].frame = 0; + dinahs[who].moving = true; + PlayPrioritySound(kToastLaunchSound, kToastLaunchPriority); + } + else + dinahs[who].frame = dinahs[who].timer; + } + } +} + +//-------------------------------------------------------------- HandleMacPlus + +void HandleMacPlus (short who) +{ + if (dinahs[who].timer > 0) + { + dinahs[who].timer--; + if (dinahs[who].active) + { + if (dinahs[who].timer == 0) + AddRectToWorkRects(&dinahs[who].dest); + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kMacBeepSound, kMacBeepPriority); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &plusScreen2, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + else if (dinahs[who].timer == 30) + PlayPrioritySound(kMacOnSound, kMacOnPriority); + } + else + { + if (dinahs[who].timer == 0) + AddRectToWorkRects(&dinahs[who].dest); + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kMacOffSound, kMacOffPriority); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &plusScreen1, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + } + } +} + +//-------------------------------------------------------------- HandleTV + +void HandleTV (short who) +{ + if (dinahs[who].timer > 0) + { + dinahs[who].timer--; + if (dinahs[who].active) + { + if (dinahs[who].timer == 0) + { + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && + (who == tvWithMovieNumber)) + { + } + else + { + AddRectToWorkRects(&dinahs[who].dest); + } + } + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kTVOnSound, kTVOnPriority); + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && + (who == tvWithMovieNumber)) + { + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &tvScreen2, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + } + } + else + { + if (dinahs[who].timer == 0) + AddRectToWorkRects(&dinahs[who].dest); + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kTVOffSound, kTVOffPriority); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &tvScreen1, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + } + } +} + +//-------------------------------------------------------------- HandleCoffee + +void HandleCoffee (short who) +{ + if (dinahs[who].timer > 0) + { + dinahs[who].timer--; + if (dinahs[who].active) + { + if (dinahs[who].timer == 0) + { + AddRectToWorkRects(&dinahs[who].dest); + dinahs[who].timer = 200 + RandomInt(200); + } + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kMacOnSound, kMacOnPriority); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &coffeeLight2, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + else if (dinahs[who].timer == 100) + { + PlayPrioritySound(kCoffeeSound, kCoffeePriority); + dinahs[who].timer = 200 + RandomInt(200); + } + } + else + { + if (dinahs[who].timer == 0) + AddRectToWorkRects(&dinahs[who].dest); + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kMacOffSound, kMacOffPriority); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &coffeeLight1, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + } + } +} + +//-------------------------------------------------------------- HandleOutlet + +void HandleOutlet (short who) +{ + if (dinahs[who].position != 0) + { + dinahs[who].timer--; + + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == theGlider.which) + CheckDynamicCollision(who, &theGlider2, false); + else + CheckDynamicCollision(who, &theGlider, false); + } + else + { + CheckDynamicCollision(who, &theGlider, true); + CheckDynamicCollision(who, &theGlider2, true); + } + } + else + CheckDynamicCollision(who, &theGlider, true); + + if (dinahs[who].timer <= 0) + { + dinahs[who].frame = 0; + dinahs[who].position = 0; + dinahs[who].timer = dinahs[who].count; + } + else + { + if ((dinahs[who].timer % 5) == 0) + PlayPrioritySound(kZapSound, kZapPriority); + dinahs[who].frame++; + if (dinahs[who].frame >= kNumOutletPicts) + dinahs[who].frame = 1; + } + + if ((dinahs[who].position != 0) || (dinahs[who].hVel > 0)) + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &outletSrc[dinahs[who].frame], + &dinahs[who].dest, + srcCopy, nil); + } + else + { +// SetPort((GrafPtr)workSrcMap); + PaintRect(&dinahs[who].dest); + } + AddRectToWorkRects(&dinahs[who].dest); + } + else + { + if (dinahs[who].active) + dinahs[who].timer--; + + if (dinahs[who].timer <= 0) + { + if (dinahs[who].active) + { + dinahs[who].position = 1; + dinahs[who].timer = kLengthOfZap; + PlayPrioritySound(kZapSound, kZapPriority); + } + else + dinahs[who].timer = dinahs[who].count; + } + } +} + +//-------------------------------------------------------------- HandleVCR + +void HandleVCR (short who) +{ + if (dinahs[who].timer > 0) + { + dinahs[who].timer--; + if (dinahs[who].active) + { + if (dinahs[who].timer == 0) + { + AddRectToWorkRects(&dinahs[who].dest); + dinahs[who].timer = 115; + } + else if (dinahs[who].timer == 5) + PlayPrioritySound(kMacOnSound, kMacOnPriority); + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kVCRSound, kVCRPriority); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &vcrTime2, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + else if (dinahs[who].timer == 100) + { + AddRectToWorkRects(&dinahs[who].dest); + dinahs[who].timer = 115; + dinahs[who].frame = 1 - dinahs[who].frame; + } + else if (dinahs[who].timer == 101) + { + if (dinahs[who].frame == 0) + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &vcrTime2, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &vcrTime1, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + } + } + else + { + if (dinahs[who].timer == 0) + AddRectToWorkRects(&dinahs[who].dest); + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kMacOffSound, kMacOffPriority); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &vcrTime1, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + } + } +} + +//-------------------------------------------------------------- HandleStereo + +void HandleStereo (short who) +{ + if (dinahs[who].timer > 0) + { + dinahs[who].timer--; + if (dinahs[who].active) + { + if (dinahs[who].timer == 0) + { + AddRectToWorkRects(&dinahs[who].dest); + ToggleMusicWhilePlaying(); + } + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kMacOnSound, kMacOnPriority); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &stereoLight2, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + } + else + { + if (dinahs[who].timer == 0) + { + AddRectToWorkRects(&dinahs[who].dest); + ToggleMusicWhilePlaying(); + } + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kMacOffSound, kMacOffPriority); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &stereoLight1, &dinahs[who].dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + } + } +} + +//-------------------------------------------------------------- HandleMicrowave + +void HandleMicrowave (short who) +{ + Rect dest; + + if (dinahs[who].timer > 0) + { + dinahs[who].timer--; + if (dinahs[who].active) + { + if (dinahs[who].timer == 0) + AddRectToWorkRects(&dinahs[who].dest); + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kMacOnSound, kMacOnPriority); + dest = dinahs[who].dest; + dest.right = dest.left + 16; + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOn, &dest, + srcCopy, nil); + QOffsetRect(&dest, 16, 0); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOn, &dest, + srcCopy, nil); + QOffsetRect(&dest, 16, 0); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOn, &dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + } + else + { + if (dinahs[who].timer == 0) + AddRectToWorkRects(&dinahs[who].dest); + else if (dinahs[who].timer == 1) + { + PlayPrioritySound(kMacOffSound, kMacOffPriority); + dest = dinahs[who].dest; + dest.right = dest.left + 16; + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOff, &dest, + srcCopy, nil); + QOffsetRect(&dest, 16, 0); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOff, &dest, + srcCopy, nil); + QOffsetRect(&dest, 16, 0); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOff, &dest, + srcCopy, nil); + AddRectToBackRects(&dinahs[who].dest); + } + } + } +} + diff --git a/GpApp/Dynamics2.cpp b/GpApp/Dynamics2.cpp new file mode 100644 index 0000000..212640f --- /dev/null +++ b/GpApp/Dynamics2.cpp @@ -0,0 +1,589 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Dynamics2.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "RectUtils.h" + + +#define kBalloonStop 8 +#define kBalloonStart 310 +#define kCopterStart 8 +#define kCopterStop 310 +#define kDartVelocity 6 +#define kDartStop 310 +#define kEnemyDropSpeed 8 + + +extern dynaPtr dinahs; +extern short numBands; +extern Boolean evenFrame, twoPlayerGame, onePlayerLeft, playerDead; + + +//============================================================== Functions +//-------------------------------------------------------------- HandleBalloon + +void HandleBalloon (short who) +{ + Rect dest; + + if (dinahs[who].moving) + { + if (dinahs[who].vVel < 0) + { + if (evenFrame) + { + dinahs[who].frame++; + if (dinahs[who].frame >= 6) + dinahs[who].frame = 0; + } + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == theGlider.which) + CheckDynamicCollision(who, &theGlider2, false); + else + CheckDynamicCollision(who, &theGlider, false); + } + else + { + CheckDynamicCollision(who, &theGlider, false); + CheckDynamicCollision(who, &theGlider2, false); + } + } + else + CheckDynamicCollision(who, &theGlider, false); + + if ((numBands > 0) && (DidBandHitDynamic(who))) + { + dinahs[who].frame = 6; + dinahs[who].vVel = kEnemyDropSpeed; + PlayPrioritySound(kPopSound, kPopPriority); + } + else + { + VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); + dinahs[who].whole = dinahs[who].dest; + dinahs[who].whole.bottom -= dinahs[who].vVel; + } + } + else + { + if (evenFrame) + { + dinahs[who].frame++; + if (dinahs[who].frame >= 8) + dinahs[who].frame = 6; + } + + VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); + dinahs[who].whole = dinahs[who].dest; + dinahs[who].whole.top -= dinahs[who].vVel; + } + + if ((dinahs[who].dest.top <= kBalloonStop) || + (dinahs[who].dest.bottom >= kBalloonStart)) + { + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + dest = dinahs[who].dest; + AddSparkle(&dest); + PlayPrioritySound(kEnemyOutSound, kEnemyOutPriority); + dinahs[who].moving = false; + dinahs[who].vVel = -2; + dinahs[who].timer = dinahs[who].count; + dinahs[who].dest.bottom = kBalloonStart; + dinahs[who].dest.top = dinahs[who].dest.bottom - + RectTall(&balloonSrc[0]); + dinahs[who].whole = dinahs[who].dest; + } + } + else // balloon is idle, waiting to appear + { + if (dinahs[who].active) + { + dinahs[who].timer--; + if (dinahs[who].timer <= 0) + { + dinahs[who].moving = true; + if (dinahs[who].count < kStartSparkle) + { + dest = dinahs[who].dest; + AddSparkle(&dest); + PlayPrioritySound(kEnemyInSound, kEnemyInPriority); + } + } + else if (dinahs[who].timer == kStartSparkle) + { + dest = dinahs[who].dest; + AddSparkle(&dest); + PlayPrioritySound(kEnemyInSound, kEnemyInPriority); + } + } + } +} + +//-------------------------------------------------------------- HandleCopter + +void HandleCopter (short who) +{ + Rect dest; + + if (dinahs[who].moving) // is 'copter about? + { + if (dinahs[who].hVel != 0) // 'copter was not shot + { + dinahs[who].frame++; + if (dinahs[who].frame >= 8) + dinahs[who].frame = 0; + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == theGlider.which) + CheckDynamicCollision(who, &theGlider2, false); + else + CheckDynamicCollision(who, &theGlider, false); + } + else + { + CheckDynamicCollision(who, &theGlider, false); + CheckDynamicCollision(who, &theGlider2, false); + } + } + else + CheckDynamicCollision(who, &theGlider, false); + if ((numBands > 0) && (DidBandHitDynamic(who))) + { + dinahs[who].frame = 8; + dinahs[who].hVel = 0; + dinahs[who].vVel = kEnemyDropSpeed; + PlayPrioritySound(kPaperCrunchSound, kPaperCrunchPriority); + } + else + { + HOffsetRect(&dinahs[who].dest, dinahs[who].hVel); + VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); + dinahs[who].whole = dinahs[who].dest; + dinahs[who].whole.top -= dinahs[who].vVel; + if (dinahs[who].hVel < 0) + dinahs[who].whole.right -= dinahs[who].hVel; + else + dinahs[who].whole.left -= dinahs[who].hVel; + } + } + else // 'copter was shot + { + dinahs[who].frame++; + if (dinahs[who].frame >= 10) + dinahs[who].frame = 8; + VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); + dinahs[who].whole = dinahs[who].dest; + dinahs[who].whole.top -= dinahs[who].vVel; + } + + if ((dinahs[who].dest.top <= kCopterStart) || + (dinahs[who].dest.bottom >= kCopterStop)) + { + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + dest = dinahs[who].dest; + AddSparkle(&dest); + PlayPrioritySound(kEnemyOutSound, kEnemyOutPriority); + dinahs[who].moving = false; + dinahs[who].vVel = 2; + if (dinahs[who].type == kCopterLf) + dinahs[who].hVel = -1; + else + dinahs[who].hVel = 1; + dinahs[who].timer = dinahs[who].count; + dinahs[who].dest.top = kCopterStart; + dinahs[who].dest.bottom = dinahs[who].dest.top + + RectTall(&copterSrc[0]); + dinahs[who].dest.left = dinahs[who].position; + dinahs[who].dest.right = dinahs[who].dest.left + 32; + dinahs[who].whole = dinahs[who].dest; + } + } + else + { + if (dinahs[who].active) + { + dinahs[who].timer--; + if (dinahs[who].timer <= 0) + { + dinahs[who].moving = true; + if (dinahs[who].count < kStartSparkle) + { + dest = dinahs[who].dest; + AddSparkle(&dest); + PlayPrioritySound(kEnemyInSound, kEnemyInPriority); + } + } + else if (dinahs[who].timer == kStartSparkle) + { + dest = dinahs[who].dest; + AddSparkle(&dest); + PlayPrioritySound(kEnemyInSound, kEnemyInPriority); + } + } + } +} + +//-------------------------------------------------------------- HandleDart + +void HandleDart (short who) +{ + Rect dest; + + if (dinahs[who].moving) // Dart has appeared + { + if (dinahs[who].hVel != 0) // meaning it isn't falling + { + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == theGlider.which) + CheckDynamicCollision(who, &theGlider2, false); + else + CheckDynamicCollision(who, &theGlider, false); + } + else + { + CheckDynamicCollision(who, &theGlider, false); + CheckDynamicCollision(who, &theGlider2, false); + } + } + else + CheckDynamicCollision(who, &theGlider, false); + if ((numBands > 0) && (DidBandHitDynamic(who))) + { + if (dinahs[who].type == kDartLf) + dinahs[who].frame = 1; + else + dinahs[who].frame = 3; + dinahs[who].hVel = 0; + dinahs[who].vVel = kEnemyDropSpeed; + PlayPrioritySound(kPaperCrunchSound, kPaperCrunchPriority); + } + else + { + HOffsetRect(&dinahs[who].dest, dinahs[who].hVel); + VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); + dinahs[who].whole = dinahs[who].dest; + dinahs[who].whole.top -= dinahs[who].vVel; + if (dinahs[who].hVel < 0) + dinahs[who].whole.right -= dinahs[who].hVel; + else + dinahs[who].whole.left -= dinahs[who].hVel; + } + } + else // dart is falling straight down + { + VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); + dinahs[who].whole = dinahs[who].dest; + dinahs[who].whole.top -= dinahs[who].vVel; + } + + if ((dinahs[who].dest.left <= 0) || + (dinahs[who].dest.right >= kRoomWide) || + (dinahs[who].dest.bottom >= kDartStop)) + { + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + dest = dinahs[who].dest; + AddSparkle(&dest); + PlayPrioritySound(kEnemyOutSound, kEnemyOutPriority); + dinahs[who].moving = false; + dinahs[who].vVel = 2; + if (dinahs[who].type == kDartLf) + { + dinahs[who].frame = 0; + dinahs[who].hVel = -kDartVelocity; + dinahs[who].dest.right = kRoomWide; + dinahs[who].dest.left = dinahs[who].dest.right - + RectWide(&dartSrc[0]); + } + else + { + dinahs[who].frame = 2; + dinahs[who].hVel = kDartVelocity; + dinahs[who].dest.left = 0; + dinahs[who].dest.right = dinahs[who].dest.left + + RectWide(&dartSrc[0]); + } + dinahs[who].timer = dinahs[who].count; + dinahs[who].dest.top = dinahs[who].position; + dinahs[who].dest.bottom = dinahs[who].dest.top + + RectTall(&dartSrc[0]); + dinahs[who].whole = dinahs[who].dest; + } + } + else + { + if (dinahs[who].active) + { + dinahs[who].timer--; + if (dinahs[who].timer <= 0) + { + dinahs[who].moving = true; + if (dinahs[who].count < kStartSparkle) + { + dest = dinahs[who].dest; + AddSparkle(&dest); + PlayPrioritySound(kEnemyInSound, kEnemyInPriority); + } + } + else if (dinahs[who].timer == kStartSparkle) + { + dest = dinahs[who].dest; + AddSparkle(&dest); + PlayPrioritySound(kEnemyInSound, kEnemyInPriority); + } + } + } +} + +//-------------------------------------------------------------- HandleBall + +void HandleBall (short who) +{ + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == theGlider.which) + CheckDynamicCollision(who, &theGlider2, false); + else + CheckDynamicCollision(who, &theGlider, false); + } + else + { + CheckDynamicCollision(who, &theGlider, false); + CheckDynamicCollision(who, &theGlider2, false); + } + } + else + CheckDynamicCollision(who, &theGlider, false); + + if (dinahs[who].moving) // is ball bouncing? + { + VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); + if (dinahs[who].dest.bottom >= dinahs[who].position) // bounce! + { + dinahs[who].whole = dinahs[who].dest; + dinahs[who].whole.top -= dinahs[who].vVel; + dinahs[who].whole.bottom = dinahs[who].position; + dinahs[who].dest.bottom = dinahs[who].position; + dinahs[who].dest.top = dinahs[who].dest.bottom - 32; + if (dinahs[who].active) + dinahs[who].vVel = dinahs[who].count; + else + { + dinahs[who].vVel = -((dinahs[who].vVel * 3) / 4); + if (dinahs[who].vVel == 0) + dinahs[who].moving = false; // stop bounce + } + if (dinahs[who].whole.bottom < dinahs[who].dest.bottom) + dinahs[who].whole.bottom = dinahs[who].dest.bottom; + PlayPrioritySound(kBounceSound, kBouncePriority); + if (dinahs[who].moving) + dinahs[who].frame = 1; + } + else + { + dinahs[who].whole = dinahs[who].dest; + if (dinahs[who].vVel > 0) + dinahs[who].whole.top -= dinahs[who].vVel; + else + dinahs[who].whole.bottom -= dinahs[who].vVel; + if (evenFrame) + dinahs[who].vVel++; + dinahs[who].frame = 0; + } + } + else + { + if (dinahs[who].active) + { + dinahs[who].vVel = dinahs[who].count; + dinahs[who].moving = true; + evenFrame = true; + } + } +} + +//-------------------------------------------------------------- HandleDrip + +void HandleDrip (short who) +{ + Rect dest; + + if (dinahs[who].moving) + { + if (evenFrame) + dinahs[who].frame = 9 - dinahs[who].frame; + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == theGlider.which) + CheckDynamicCollision(who, &theGlider2, false); + else + CheckDynamicCollision(who, &theGlider, false); + } + else + { + CheckDynamicCollision(who, &theGlider, false); + CheckDynamicCollision(who, &theGlider2, false); + } + } + else + CheckDynamicCollision(who, &theGlider, false); + + VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); + if (dinahs[who].dest.bottom >= dinahs[who].position) + { + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + dinahs[who].dest.top = dinahs[who].hVel; + dinahs[who].dest.bottom = dinahs[who].dest.top + 12; + PlayPrioritySound(kDropSound, kDropPriority); + dinahs[who].vVel = 0; + dinahs[who].timer = dinahs[who].count; + dinahs[who].frame = 3; + dinahs[who].moving = false; + } + else + { + dinahs[who].whole = dinahs[who].dest; + dinahs[who].whole.top -= dinahs[who].vVel; + if (evenFrame) + dinahs[who].vVel++; + } + } + else + { + if (dinahs[who].active) + { + dinahs[who].timer--; + + if (dinahs[who].timer == 6) + dinahs[who].frame = 0; + else if (dinahs[who].timer == 4) + dinahs[who].frame = 1; + else if (dinahs[who].timer == 2) + dinahs[who].frame = 2; + else if (dinahs[who].timer <= 0) + { + VOffsetRect(&dinahs[who].dest, 3); + dinahs[who].whole = dinahs[who].dest; + dinahs[who].moving = true; + dinahs[who].frame = 4; + PlayPrioritySound(kDripSound, kDripPriority); + } + } + } +} + +//-------------------------------------------------------------- HandleFish + +void HandleFish (short who) +{ + Rect dest; + + if (dinahs[who].moving) // fish leaping + { + if ((dinahs[who].vVel >= 0) && (dinahs[who].frame < 7)) + dinahs[who].frame++; + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == theGlider.which) + CheckDynamicCollision(who, &theGlider2, false); + else + CheckDynamicCollision(who, &theGlider, false); + } + else + { + CheckDynamicCollision(who, &theGlider, false); + CheckDynamicCollision(who, &theGlider2, false); + } + } + else + CheckDynamicCollision(who, &theGlider, false); + + VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); + if (dinahs[who].dest.bottom >= dinahs[who].position) // splash down + { + dest = dinahs[who].whole; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + dinahs[who].dest.bottom = dinahs[who].position; + dinahs[who].dest.top = dinahs[who].dest.bottom - 16; + dinahs[who].whole = dinahs[who].dest; + dinahs[who].whole.top -= 2; + PlayPrioritySound(kDropSound, kDropPriority); + dinahs[who].vVel = dinahs[who].count; + dinahs[who].timer = dinahs[who].hVel; + dinahs[who].frame = 0; + dinahs[who].moving = false; + PlayPrioritySound(kFishInSound, kFishInPriority); + } + else + { + dinahs[who].whole = dinahs[who].dest; + if (dinahs[who].vVel > 0) + dinahs[who].whole.top -= dinahs[who].vVel; + else + dinahs[who].whole.bottom -= dinahs[who].vVel; + if (evenFrame) + dinahs[who].vVel++; + } + } + else // fish idle + { + dinahs[who].whole = dinahs[who].dest; + if ((dinahs[who].timer & 0x0003) == 0x0003) + { + dinahs[who].frame++; + if (dinahs[who].frame > 3) + dinahs[who].frame = 0; + if ((dinahs[who].frame == 1) || (dinahs[who].frame == 2)) + { + dinahs[who].dest.top++; + dinahs[who].dest.bottom++; + dinahs[who].whole.bottom++; + } + else + { + dinahs[who].dest.top--; + dinahs[who].dest.bottom--; + dinahs[who].whole.top--; + } + } + if (dinahs[who].active) + { + dinahs[who].timer--; + if (dinahs[who].timer <= 0) // fish leaps + { + dinahs[who].whole = dinahs[who].dest; + dinahs[who].moving = true; + dinahs[who].frame = 4; + PlayPrioritySound(kFishOutSound, kFishOutPriority); + } + } + } +} + diff --git a/GpApp/Dynamics3.cpp b/GpApp/Dynamics3.cpp new file mode 100644 index 0000000..5011153 --- /dev/null +++ b/GpApp/Dynamics3.cpp @@ -0,0 +1,555 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Dynamics3.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "RectUtils.h" + + +#define kBalloonStart 310 +#define kCopterStart 8 +#define kDartVelocity 6 + + +dynaPtr dinahs; +short numDynamics; + +extern Rect breadSrc[]; +extern short numLights; +extern Boolean evenFrame; + + +//============================================================== Functions +//-------------------------------------------------------------- HandleDynamics + +// This is the master function that calls all the specific handlers above. + +void HandleDynamics (void) +{ + short i; + + for (i = 0; i < numDynamics; i++) + { + switch (dinahs[i].type) + { + case kSparkle: + HandleSparkleObject(i); + break; + + case kToaster: + HandleToast(i); + break; + + case kMacPlus: + HandleMacPlus(i); + break; + + case kTV: + HandleTV(i); + break; + + case kCoffee: + HandleCoffee(i); + break; + + case kOutlet: + HandleOutlet(i); + break; + + case kVCR: + HandleVCR(i); + break; + + case kStereo: + HandleStereo(i); + break; + + case kMicrowave: + HandleMicrowave(i); + break; + + case kBalloon: + HandleBalloon(i); + break; + + case kCopterLf: + case kCopterRt: + HandleCopter(i); + break; + + case kDartLf: + case kDartRt: + HandleDart(i); + break; + + case kBall: + HandleBall(i); + break; + + case kDrip: + HandleDrip(i); + break; + + case kFish: + HandleFish(i); + break; + + default: + break; + } + } +} + +//-------------------------------------------------------------- HandleDynamics + +// This is the master function that calls all the various rendering handlersÉ +// above. + +void RenderDynamics (void) +{ + short i; + + for (i = 0; i < numDynamics; i++) + { + switch (dinahs[i].type) + { + case kToaster: + RenderToast(i); + break; + + case kBalloon: + RenderBalloon(i); + break; + + case kCopterLf: + case kCopterRt: + RenderCopter(i); + break; + + case kDartLf: + case kDartRt: + RenderDart(i); + break; + + case kBall: + RenderBall(i); + break; + + case kDrip: + RenderDrip(i); + break; + + case kFish: + RenderFish(i); + break; + + default: + break; + } + } +} + +//-------------------------------------------------------------- ZeroDinahs + +// This clears all dynamics - zeros them all out. Used to initialize them. + +void ZeroDinahs (void) +{ + short i; + + for (i = 0; i < kMaxDynamicObs; i++) + { + dinahs[i].type = kObjectIsEmpty; + QSetRect(&dinahs[i].dest, 0, 0, 0, 0); + QSetRect(&dinahs[i].whole, 0, 0, 0, 0); + dinahs[i].hVel = 0; + dinahs[i].vVel = 0; + dinahs[i].count = 0; + dinahs[i].frame = 0; + dinahs[i].timer = 0; + dinahs[i].position = 0; + dinahs[i].room = 0; + dinahs[i].byte0 = 0; + dinahs[i].active = false; + } + numDynamics = 0; +} + +//-------------------------------------------------------------- AddDynamicObject + +// When a room is being drawn, various dynamic objects are pointed here. +// This function sets up the structures to handle them. + +short AddDynamicObject (short what, Rect *where, objectType *who, + short room, short index, Boolean isOn) +{ + short position, velocity; + Boolean lilFrame; + + if (numDynamics >= kMaxDynamicObs) + return (-1); + + dinahs[numDynamics].type = what; + switch (what) + { + case kSparkle: + dinahs[numDynamics].dest = sparkleSrc[0]; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, where->left, where->top); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = 0; + dinahs[numDynamics].vVel = 0; + dinahs[numDynamics].count = 0; + dinahs[numDynamics].frame = 0; + dinahs[numDynamics].timer = RandomInt(60) + 15; + dinahs[numDynamics].position = 0; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + case kToaster: + dinahs[numDynamics].dest = breadSrc[0]; + CenterRectInRect(&dinahs[numDynamics].dest, where); + VOffsetRect(&dinahs[numDynamics].dest, + where->top - dinahs[numDynamics].dest.top); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = where->top + 2; // hVel used as clip + position = who->data.g.height; // reverse engineer init. vel. + velocity = 0; + do + { + velocity++; + position -= velocity; + } + while (position > 0); + dinahs[numDynamics].vVel = -velocity; + dinahs[numDynamics].count = velocity; // count = initial velocity + dinahs[numDynamics].frame = (short)who->data.g.delay * 3; + dinahs[numDynamics].timer = dinahs[numDynamics].frame; + dinahs[numDynamics].position = 0; // launch/idle state + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + case kMacPlus: + dinahs[numDynamics].dest = plusScreen1; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, + where->left + playOriginH + 10, + where->top + playOriginV + 7); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = 0; + dinahs[numDynamics].vVel = 0; + dinahs[numDynamics].count = 0; + dinahs[numDynamics].frame = 0; + dinahs[numDynamics].timer = 0; + dinahs[numDynamics].position = 0; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + case kTV: + dinahs[numDynamics].dest = tvScreen1; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, + where->left + playOriginH + 17, + where->top + playOriginV + 10); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = 0; + dinahs[numDynamics].vVel = 0; + dinahs[numDynamics].count = 0; + dinahs[numDynamics].frame = 0; + dinahs[numDynamics].timer = 0; + dinahs[numDynamics].position = 0; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + case kCoffee: + dinahs[numDynamics].dest = coffeeLight1; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, + where->left + playOriginH + 32, + where->top + playOriginV + 57); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = 0; + dinahs[numDynamics].vVel = 0; + dinahs[numDynamics].count = 0; + dinahs[numDynamics].frame = 0; + if (isOn) + dinahs[numDynamics].timer = 200; + else + dinahs[numDynamics].timer = 0; + dinahs[numDynamics].position = 0; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + case kOutlet: + dinahs[numDynamics].dest = outletSrc[0]; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, + where->left + playOriginH, + where->top + playOriginV); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = numLights; + dinahs[numDynamics].vVel = 0; + dinahs[numDynamics].count = ((short)who->data.g.delay * 6) / kTicksPerFrame; + dinahs[numDynamics].frame = 0; + dinahs[numDynamics].timer = dinahs[numDynamics].count; + dinahs[numDynamics].position = 0; // launch/idle state + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + case kVCR: + dinahs[numDynamics].dest = vcrTime1; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, + where->left + playOriginH + 64, + where->top + playOriginV + 6); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = 0; + dinahs[numDynamics].vVel = 0; + dinahs[numDynamics].count = 0; + dinahs[numDynamics].frame = 0; + if (isOn) + dinahs[numDynamics].timer = 115; + else + dinahs[numDynamics].timer = 0; + dinahs[numDynamics].position = 0; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + case kStereo: + dinahs[numDynamics].dest = stereoLight1; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, + where->left + playOriginH + 56, + where->top + playOriginV + 20); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = 0; + dinahs[numDynamics].vVel = 0; + dinahs[numDynamics].count = 0; + dinahs[numDynamics].frame = 0; + dinahs[numDynamics].timer = 0; + dinahs[numDynamics].position = 0; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + case kMicrowave: + dinahs[numDynamics].dest = microOn; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, + where->left + playOriginH + 14, + where->top + playOriginV + 13); + dinahs[numDynamics].dest.right = dinahs[numDynamics].dest.left + 48; + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = 0; + dinahs[numDynamics].vVel = 0; + dinahs[numDynamics].count = 0; + dinahs[numDynamics].frame = 0; + dinahs[numDynamics].timer = 0; + dinahs[numDynamics].position = 0; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + case kBalloon: + dinahs[numDynamics].dest = balloonSrc[0]; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, where->left, 0); + dinahs[numDynamics].dest.bottom = kBalloonStart; + dinahs[numDynamics].dest.top = dinahs[numDynamics].dest.bottom - + RectTall(&balloonSrc[0]); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = 0; + dinahs[numDynamics].vVel = -2; + dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; + dinahs[numDynamics].frame = 0; + dinahs[numDynamics].timer = dinahs[numDynamics].count; + dinahs[numDynamics].position = 0; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; // initially idle + break; + + case kCopterLf: + case kCopterRt: + dinahs[numDynamics].dest = copterSrc[0]; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, where->left, 0); + dinahs[numDynamics].dest.top = kCopterStart; + dinahs[numDynamics].dest.bottom = dinahs[numDynamics].dest.top + + RectTall(&copterSrc[0]); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + if (what == kCopterLf) + dinahs[numDynamics].hVel = -1; + else + dinahs[numDynamics].hVel = 1; + dinahs[numDynamics].vVel = 2; + dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; + dinahs[numDynamics].frame = 0; + dinahs[numDynamics].timer = dinahs[numDynamics].count; + dinahs[numDynamics].position = dinahs[numDynamics].dest.left; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; // initially idle + break; + + case kDartLf: + case kDartRt: + dinahs[numDynamics].dest = dartSrc[0]; + ZeroRectCorner(&dinahs[numDynamics].dest); + if (what == kDartLf) + { + QOffsetRect(&dinahs[numDynamics].dest, + kRoomWide - RectWide(&dartSrc[0]), where->top); + dinahs[numDynamics].hVel = -kDartVelocity; + dinahs[numDynamics].frame = 0; + } + else + { + QOffsetRect(&dinahs[numDynamics].dest, 0, where->top); + dinahs[numDynamics].hVel = kDartVelocity; + dinahs[numDynamics].frame = 2; + } + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].vVel = 2; + dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; + dinahs[numDynamics].timer = dinahs[numDynamics].count; + dinahs[numDynamics].position = dinahs[numDynamics].dest.top; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; // initially idle + break; + + case kBall: + dinahs[numDynamics].dest = ballSrc[0]; + ZeroRectCorner(&dinahs[numDynamics].dest); + QOffsetRect(&dinahs[numDynamics].dest, + where->left, where->top); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = 0; + position = who->data.h.length; // reverse engineer init. vel. + velocity = 0; + evenFrame = true; + lilFrame = true; + do + { + if (lilFrame) + velocity++; + lilFrame = !lilFrame; + position -= velocity; + } + while (position > 0); + dinahs[numDynamics].vVel = -velocity; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].count = -velocity; // count = initial velocity + dinahs[numDynamics].frame = 0; + dinahs[numDynamics].timer = 0; + dinahs[numDynamics].position = dinahs[numDynamics].dest.bottom; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].active = isOn; + break; + + case kDrip: + dinahs[numDynamics].dest = dripSrc[0]; + CenterRectInRect(&dinahs[numDynamics].dest, where); + VOffsetRect(&dinahs[numDynamics].dest, + where->top - dinahs[numDynamics].dest.top); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = dinahs[numDynamics].dest.top; // remember + dinahs[numDynamics].vVel = 0; + dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; + dinahs[numDynamics].frame = 3; + dinahs[numDynamics].timer = dinahs[numDynamics].count; + dinahs[numDynamics].position = dinahs[numDynamics].dest.top + + who->data.h.length; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + case kFish: + dinahs[numDynamics].dest = fishSrc[0]; + QOffsetRect(&dinahs[numDynamics].dest, + where->left + 10, where->top + 8); + dinahs[numDynamics].whole = dinahs[numDynamics].dest; + dinahs[numDynamics].hVel = ((short)who->data.h.delay * 6) / kTicksPerFrame; + position = who->data.g.height; // reverse engineer init. vel. + velocity = 0; + evenFrame = true; + lilFrame = true; + do + { + if (lilFrame) + velocity++; + lilFrame = !lilFrame; + position -= velocity; + } + while (position > 0); + dinahs[numDynamics].vVel = -velocity; + dinahs[numDynamics].count = -velocity; // count = initial velocity + dinahs[numDynamics].frame = 0; + dinahs[numDynamics].timer = dinahs[numDynamics].hVel; + dinahs[numDynamics].position = dinahs[numDynamics].dest.bottom; + dinahs[numDynamics].room = room; + dinahs[numDynamics].byte0 = (Byte)index; + dinahs[numDynamics].byte1 = 0; + dinahs[numDynamics].moving = false; + dinahs[numDynamics].active = isOn; + break; + + default: + return (-1); + break; + } + + numDynamics++; + + return (numDynamics - 1); +} + diff --git a/GpApp/Environ.cpp b/GpApp/Environ.cpp new file mode 100644 index 0000000..6f45c19 --- /dev/null +++ b/GpApp/Environ.cpp @@ -0,0 +1,492 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Environ.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLResources.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "HostDisplayDriver.h" + + +#define kSwitchDepthAlert 130 +#define kSetMemoryAlert 180 +#define kLowMemoryAlert 181 +#define kWNETrap 0x60 +#define kSetDepthTrap 0xA2 +#define kUnimpTrap 0x9F +#define kGestaltTrap 0xAD + +#define kDisplay9Inch 1 +#define kDisplay12Inch 2 +#define kDisplay13Inch 3 + + +typedef struct +{ + short flags; + long mem1; + long mem2; +} sizeType; + + +//short GetThisVolumeRefNum (void); +//long GetThisCurrentDirectoryID (void); +//Boolean TrapExists (short); +//Boolean DoWeHaveGestalt (void); +//Boolean DoWeHaveWNE (void); +//Boolean DoWeHaveColor (void); +//Boolean DoWeHaveSystem602 (void); +//Boolean DoWeHaveSystem605 (void); +//Boolean DoWeHaveSystem7 (void); +//Boolean DoWeHaveSoundManager3 (void); +Boolean DoWeHaveQuickTime (void); +Boolean DoWeHaveDragManager (void); +//Boolean CanWeDisplay4Bit (GDHandle); +//Boolean CanWeDisplay1Bit (GDHandle); +short HowManyUsableScreens (Boolean, Boolean, Boolean); +void GetDeviceRect (Rect *); +Boolean AreWeColorOrGrayscale (void); +void SwitchDepthOrAbort (void); + + +macEnviron thisMac; + +extern short isDepthPref; +extern Boolean dontLoadMusic, dontLoadSounds; + + +//============================================================== Functions +//-------------------------------------------------------------- GetThisVolumeRefNum +// Get a hard reference number for the current drive volume this app is on. +/* +short GetThisVolumeRefNum (void) +{ + OSErr theErr; + short vRef; + + theErr = GetVol(nil, &vRef); + return (vRef); +} +*/ +//-------------------------------------------------------------- GetThisCurrentDirectoryID +// Get a hard ID number for the current directory volume this app is in. +/* +long GetThisCurrentDirectoryID (void) +{ + long dirID; + + dirID = LMGetCurDirStore(); + return (dirID); +} +*/ +//-------------------------------------------------------------- TrapExists +// Returns whether or not a ToolBox trap exists for the users ROMs/System. +/* +Boolean TrapExists (short trapNumber) +{ + return ((NGetTrapAddress(trapNumber, ToolTrap) != + NGetTrapAddress(kUnimpTrap, ToolTrap))); +} +*/ +//-------------------------------------------------------------- DoWeHaveGestalt + +// Specifically tests for the availablity of the Gestalt() trap. +/* +Boolean DoWeHaveGestalt (void) +{ + return (TrapExists(kGestaltTrap)); +} +*/ +//-------------------------------------------------------------- DoWeHaveWNE + +// Specifically tests for the availablity of the WaitNextEvent() trap. +/* +Boolean DoWeHaveWNE (void) +{ + return (TrapExists(kWNETrap)); +} +*/ +//-------------------------------------------------------------- DoWeHaveColor +// Determines if ROMs support Color QuickDraw (monitor not neccessarily color). +/* +Boolean DoWeHaveColor (void) +{ + SysEnvRec thisWorld; + + SysEnvirons(2, &thisWorld); + return (thisWorld.hasColorQD); +} +*/ +//-------------------------------------------------------------- DoWeHaveSystem602 +// Determines if the System version is at least 6.0.2 or more recent. +/* +Boolean DoWeHaveSystem602 (void) +{ + SysEnvRec thisWorld; + Boolean haveIt; + + SysEnvirons(2, &thisWorld); + if (thisWorld.systemVersion >= 0x0602) + haveIt = true; + else + haveIt = false; + return (haveIt); +} +*/ +//-------------------------------------------------------------- DoWeHaveSystem605 +// Determines if the System version is at least 6.0.5 or more recent. +/* +Boolean DoWeHaveSystem605 (void) +{ + SysEnvRec thisWorld; + Boolean haveIt; + + SysEnvirons(2, &thisWorld); + if (thisWorld.systemVersion >= 0x0605) + haveIt = true; + else + haveIt = false; + return (haveIt); +} +/ +//-------------------------------------------------------------- DoWeHaveSystem7 + +// Determines if the System version is at least 7.0.0 or more recent. + +Boolean DoWeHaveSystem7 (void) +{ + SysEnvRec thisWorld; + Boolean haveIt; + + SysEnvirons(2, &thisWorld); + if (thisWorld.systemVersion >= 0x0700) + haveIt = true; + else + haveIt = false; + return (haveIt); +} + +//-------------------------------------------------------------- DoWeHaveSoundManager3 +// Determines if the Sound Manager version is at least 3.0.0 or more recent. +/* +Boolean DoWeHaveSoundManager3 (void) +{ +// NumVersion version; + Boolean hasIt; + + hasIt = true; + + version = SndSoundManagerVersion(); + hasIt = (version.majorRev >= 3); + + return hasIt; +} +*/ +//-------------------------------------------------------------- DoWeHaveQuickTime + +Boolean DoWeHaveQuickTime (void) +{ + return true; +} + +//-------------------------------------------------------------- DoWeHaveDragManager + +Boolean DoWeHaveDragManager (void) +{ + return true; +} + +//-------------------------------------------------------------- WhatsOurDepth + +// Determines the pixel bit depth for current device (monitor). + +short WhatsOurDepth (void) +{ + return 8; +} + +void SwitchToDepth (short, Boolean) +{ +} + +//-------------------------------------------------------------- CanWeDisplay4Bit +// Determines if device (monitor) capable of supporting 4 bit (16 colors/grays). +/* +Boolean CanWeDisplay4Bit (GDHandle theDevice) +{ + short canDepth; + Boolean canDo; + + canDo = false; + canDepth = HasDepth(theDevice, 4, 1, 0); + if (canDepth != 0) + canDo = true; + + return (canDo); +} +*/ +//-------------------------------------------------------------- CanWeDisplay1Bit +// Determines if device (monitor) capable of supporting 1 bit (black & white). +/* +Boolean CanWeDisplay1Bit (GDHandle theDevice) +{ + short canDepth; + Boolean canDo; + + canDo = false; + canDepth = HasDepth(theDevice, 1, 1, 0); + if (canDepth != 0) + canDo = true; + + return (canDo); +} +*/ +//-------------------------------------------------------------- HowManyUsableScreens + +// Counts the number of monitors that meet the depth criteria passed in. + +short HowManyUsableScreens (Boolean use1Bit, Boolean use4Bit, Boolean use8Bit) +{ + return 1; +} + +//-------------------------------------------------------------- CheckOurEnvirons +// Calls all the above functions in order to fill out a sort of "spec sheet"É +// for the current Mac. + +void CheckOurEnvirons (void) +{ + thisMac.thisResFile = CurResFile(); + thisMac.vRefNum = 0; // TEMP + thisMac.dirID = 0; // TEMP + thisMac.hasGestalt = true; // TEMP + thisMac.hasWNE = true; // TEMP + thisMac.hasColor = true; // TEMP + thisMac.canSwitch = true; // TEMP + thisMac.hasSystem7 = true; // TEMP + thisMac.hasSM3 = true; // TEMP + thisMac.hasQT = DoWeHaveQuickTime(); + thisMac.hasDrag = DoWeHaveDragManager(); + + FindOurDevice(); + thisMac.can1Bit = true; + thisMac.can4Bit = true; + thisMac.can8Bit = true; + thisMac.numScreens = HowManyUsableScreens(false, true, true); + GetDeviceRect(&thisMac.screen); + + thisMac.wasDepth = WhatsOurDepth(); + thisMac.wasColorOrGray = AreWeColorOrGrayscale(); +} + +//-------------------------------------------------------------- ReflectMonitor2Environs +// Tests second monitor (if available) for specific bit depth capabilities. +/* +void ReflectSecondMonitorEnvirons (Boolean use1Bit, Boolean use4Bit, Boolean use8Bit) +{ + GDHandle tempGDevice; + + tempGDevice = GetDeviceList(); + while (tempGDevice != nil) + { + if (TestDeviceAttribute(tempGDevice, screenDevice)) + if ((use1Bit && CanWeDisplay1Bit(tempGDevice)) || + (use4Bit && CanWeDisplay4Bit(tempGDevice)) || + (use8Bit && CanWeDisplay8Bit(tempGDevice))) + if (!TestDeviceAttribute(tempGDevice, mainScreen)) + { + thisGDevice = tempGDevice; + thisMac.can1Bit = CanWeDisplay1Bit(thisGDevice); + thisMac.can4Bit = CanWeDisplay4Bit(thisGDevice); + thisMac.can8Bit = CanWeDisplay8Bit(thisGDevice); + thisMac.wasDepth = WhatsOurDepth(); + thisMac.wasColorOrGray = AreWeColorOrGrayscale(); + GetDeviceRect(&thisMac.screen); + break; + } + tempGDevice = GetNextDevice(tempGDevice); + } +} +*/ +//-------------------------------------------------------------- HandleDepthSwitching + +// Handles setting up a monitor's depth to play on. + +void HandleDepthSwitching (void) +{ + if (thisMac.hasColor) + { + switch (isDepthPref) + { + case kSwitchIfNeeded: + if ((thisMac.wasDepth != 8) && + ((thisMac.wasDepth != 4) || (thisMac.wasColorOrGray))) + SwitchDepthOrAbort(); + break; + + case kSwitchTo256Colors: + if (thisMac.wasDepth != 8) + { + if (thisMac.can8Bit) + SwitchToDepth(8, true); + else + SwitchDepthOrAbort(); + } + break; + + case kSwitchTo16Grays: + if ((thisMac.wasDepth != 4) || (thisMac.wasColorOrGray)) + { + if (thisMac.can4Bit) + SwitchToDepth(4, false); + else + SwitchDepthOrAbort(); + } + break; + + default: + break; + } + } + + thisMac.isDepth = WhatsOurDepth(); +} + +//-------------------------------------------------------------- RestoreColorDepth + +// Restores a monitor to its previous depth when we quit (if we changed it). + +void RestoreColorDepth (void) +{ + if ((thisMac.hasColor) && ((thisMac.wasDepth != thisMac.isDepth) || + (thisMac.wasColorOrGray != AreWeColorOrGrayscale()))) + SwitchToDepth(thisMac.wasDepth, true); +} + +//-------------------------------------------------------------- CheckMemorySize + +// Tests for a specific amount of memory available. If the required memoryÉ +// is not available, attempts to turn off various game features (music, etc.)É +// in order to accomodate the constrained memory available. + +void CheckMemorySize (void) +{ + #define kBaseBytesNeeded 614400L // 600K Base memory + #define kPaddingBytes 204800L // 200K Padding + long bytesNeeded, bytesAvail; + long soundBytes, musicBytes; + + dontLoadMusic = false; + dontLoadSounds = false; + + bytesNeeded = kBaseBytesNeeded; // base memory + soundBytes = SoundBytesNeeded(); // sound memory + if (soundBytes <= 0L) + RedAlert(kErrNoMemory); + else + bytesNeeded += soundBytes; + musicBytes = MusicBytesNeeded(); // music memory + if (musicBytes <= 0L) + RedAlert(kErrNoMemory); + else + bytesNeeded += musicBytes; + bytesNeeded += 4L * (long)thisMac.screen.bottom; // main screen + bytesNeeded += (((long)houseRect.right - (long)houseRect.left) * + ((long)houseRect.bottom + 1 - (long)houseRect.top) * + (long)thisMac.isDepth) / 8L; // work map + bytesNeeded += 4L * (long)houseRect.bottom; + bytesNeeded += (((long)houseRect.right - (long)houseRect.left) * + ((long)houseRect.bottom + 1 - (long)houseRect.top) * + (long)thisMac.isDepth) / 8L; // back map + bytesNeeded += 4L * houseRect.bottom; + bytesNeeded += (((long)houseRect.right - (long)houseRect.left) * 21 * + (long)thisMac.isDepth) / 8L; // scoreboard map + bytesNeeded += (6396L * (long)thisMac.isDepth) / 8L; // more scoreboard + bytesNeeded += (32112L * (long)thisMac.isDepth) / 8L; // glider map + bytesNeeded += (32112L * (long)thisMac.isDepth) / 8L; // glider2 map + bytesNeeded += 32064L / 8L; // glider mask + bytesNeeded += (912L * (long)thisMac.isDepth) / 8L; // glider shadow + bytesNeeded += 864L / 8L; // shadow mask + bytesNeeded += (304L * (long)thisMac.isDepth) / 8L; // rubber bands + bytesNeeded += 288L / 8L; // bands mask + bytesNeeded += (19344L * (long)thisMac.isDepth) / 8L; // blower map + bytesNeeded += 19344L / 8L; // blower mask + bytesNeeded += (17856L * (long)thisMac.isDepth) / 8L; // furniture map + bytesNeeded += 17792L / 8L; // furniture mask + bytesNeeded += (33264L * (long)thisMac.isDepth) / 8L; // prizes map + bytesNeeded += 33176L / 8L; // prizes mask + bytesNeeded += (2904L * (long)thisMac.isDepth) / 8L; // points map + bytesNeeded += 2880L / 8L; // points mask + bytesNeeded += (1848L * (long)thisMac.isDepth) / 8L; // transport map + bytesNeeded += 1792L / 8L; // transport mask + bytesNeeded += (3360L * (long)thisMac.isDepth) / 8L; // switches map + bytesNeeded += (9144L * (long)thisMac.isDepth) / 8L; // lights map + bytesNeeded += 9072L / 8L; // lights mask + bytesNeeded += (21600L * (long)thisMac.isDepth) / 8L; // appliances map + bytesNeeded += 21520L / 8L; // appliances mask + bytesNeeded += (5600L * (long)thisMac.isDepth) / 8L; // toast map + bytesNeeded += 5568L / 8L; // toast mask + bytesNeeded += (1440L * (long)thisMac.isDepth) / 8L; // shredded map + bytesNeeded += 1400L / 8L; // shredded mask + bytesNeeded += (5784L * (long)thisMac.isDepth) / 8L; // balloon map + bytesNeeded += 5760L / 8L; // balloon mask + bytesNeeded += (9632L * (long)thisMac.isDepth) / 8L; // copter map + bytesNeeded += 9600L / 8L; // copter mask + bytesNeeded += (4928L * (long)thisMac.isDepth) / 8L; // dart map + bytesNeeded += 4864L / 8L; // dart mask + bytesNeeded += (2080L * (long)thisMac.isDepth) / 8L; // ball map + bytesNeeded += 2048L / 8L; // ball mask + bytesNeeded += (1168L * (long)thisMac.isDepth) / 8L; // drip map + bytesNeeded += 1152L / 8L; // drip mask + bytesNeeded += (1224L * (long)thisMac.isDepth) / 8L; // enemy map + bytesNeeded += 1188L / 8L; // enemy mask + bytesNeeded += (2064L * (long)thisMac.isDepth) / 8L; // fish map + bytesNeeded += 2048L / 8L; // fish mask + bytesNeeded += (8960L * (long)thisMac.isDepth) / 8L; // clutter map + bytesNeeded += 8832L / 8L; // clutter mask + bytesNeeded += (23040L * (long)thisMac.isDepth) / 8L; // support map + bytesNeeded += (4320L * (long)thisMac.isDepth) / 8L; // angel map + bytesNeeded += 4224L / 8L; // angel mask + bytesNeeded += sizeof(roomType); + bytesNeeded += sizeof(hotObject) * kMaxHotSpots; + bytesNeeded += sizeof(sparkleType) * kMaxSparkles; + bytesNeeded += sizeof(flyingPtType) * kMaxFlyingPts; + bytesNeeded += sizeof(flameType) * kMaxCandles; + bytesNeeded += sizeof(flameType) * kMaxTikis; + bytesNeeded += sizeof(flameType) * kMaxCoals; + bytesNeeded += sizeof(pendulumType) * kMaxPendulums; + bytesNeeded += sizeof(savedType) * kMaxSavedMaps; + bytesNeeded += sizeof(bandType) * kMaxRubberBands; + bytesNeeded += sizeof(greaseType) * kMaxGrease; + bytesNeeded += sizeof(starType) * kMaxStars; + bytesNeeded += sizeof(shredType) * kMaxShredded; + bytesNeeded += sizeof(dynaType) * kMaxDynamicObs; + bytesNeeded += sizeof(objDataType) * kMaxMasterObjects; + bytesNeeded += kDemoLength; SpinCursor(1); + + bytesAvail = FreeMem(); SpinCursor(1); +} + +void GetDeviceRect(Rect *rect) +{ + unsigned int width; + unsigned int height; + PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(width, height); + + SetRect(rect, 0, 0, static_cast(width), static_cast(height)); +} + +Boolean AreWeColorOrGrayscale() +{ + // ... As opposed to B&W + return true; +} + +void SwitchDepthOrAbort(void) +{ +} diff --git a/GpApp/Environ.h b/GpApp/Environ.h new file mode 100644 index 0000000..b344799 --- /dev/null +++ b/GpApp/Environ.h @@ -0,0 +1,37 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Environ.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQuickdraw.h" + + +typedef struct +{ + Rect screen, gray; + long dirID; + short wasDepth, isDepth; + short thisResFile; + short numScreens; + short vRefNum; + Boolean can1Bit; + Boolean can4Bit; + Boolean can8Bit; + Boolean wasColorOrGray; + Boolean hasWNE; + Boolean hasSystem7; + Boolean hasColor; + Boolean hasGestalt; + Boolean canSwitch; + Boolean canColor; + Boolean hasSM3; + Boolean hasQT; + Boolean hasDrag; +} macEnviron; + + +extern macEnviron thisMac; + + diff --git a/GpApp/Events.cpp b/GpApp/Events.cpp new file mode 100644 index 0000000..fae5158 --- /dev/null +++ b/GpApp/Events.cpp @@ -0,0 +1,574 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Events.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLAppleEvents.h" +#include "PLToolUtils.h" +#include "PLQuickdraw.h" +#include "Externs.h" +#include "Environ.h" +#include "House.h" +#include "ObjectEdit.h" + + +short BitchAboutColorDepth (void); +void HandleMouseEvent (EventRecord *); +void HandleKeyEvent (EventRecord *); +void HandleUpdateEvent (EventRecord *); +void HandleOSEvent (EventRecord *); +void HandleHighLevelEvent (EventRecord *); +void HandleIdleTask (void); +void IncrementMode (void); + + +long lastUp, incrementModeTime; +UInt32 doubleTime; +Point lastWhere; +short idleMode; +Boolean doAutoDemo, switchedOut; + +extern WindowPtr mapWindow, toolsWindow, linkWindow; +extern WindowPtr menuWindow; +extern short isEditH, isEditV, isMapH, isMapV, isToolsH, isToolsV; +extern short isLinkH, isLinkV, isCoordH, isCoordV; +extern Boolean quitting, isMusicOn, failedMusic; +extern Boolean autoRoomEdit, newRoomNow, isPlayMusicIdle; + + +//============================================================== Functions +//-------------------------------------------------------------- BitchAboutColorDepth +// Display a dialog that alerts the user that they have switched the bitÉ +// depth of the monitor under our noses. They must return it to previous. + +short BitchAboutColorDepth (void) +{ + #define kColorSwitchedAlert 1042 + short sheSaid; + +// CenterAlert(kColorSwitchedAlert); + sheSaid = Alert(kColorSwitchedAlert, nil); + + return (sheSaid); +} + +//-------------------------------------------------------------- HandleMouseEvent +// Handle a mouse click event. + +void HandleMouseEvent (EventRecord *theEvent) +{ + WindowPtr whichWindow; + long menuChoice, newSize; + short thePart, hDelta, vDelta; + Boolean isDoubleClick; + + thePart = FindWindow(theEvent->where, &whichWindow); + + switch (thePart) + { + case inSysWindow: +// SystemClick(theEvent, whichWindow); + break; + + case inMenuBar: + menuChoice = MenuSelect(theEvent->where); + DoMenuChoice(menuChoice); + break; + + case inDrag: + DragWindow(whichWindow, theEvent->where, &thisMac.screen); + if (whichWindow == mainWindow) + { + SendBehind(mainWindow, (WindowPtr)0L); + GetWindowLeftTop(whichWindow, &isEditH, &isEditV); + } + else if (whichWindow == mapWindow) + GetWindowLeftTop(whichWindow, &isMapH, &isMapV); + else if (whichWindow == toolsWindow) + GetWindowLeftTop(whichWindow, &isToolsH, &isToolsV); + else if (whichWindow == linkWindow) + GetWindowLeftTop(whichWindow, &isLinkH, &isLinkV); + else if (whichWindow == coordWindow) + GetWindowLeftTop(whichWindow, &isCoordH, &isCoordV); + HiliteAllWindows(); + break; + + case inGoAway: + if (TrackGoAway(whichWindow,theEvent->where)) + { + if (whichWindow == mapWindow) + ToggleMapWindow(); + else if (whichWindow == toolsWindow) + ToggleToolsWindow(); + else if (whichWindow == linkWindow) + CloseLinkWindow(); + else if (whichWindow == coordWindow) + ToggleCoordinateWindow(); + } + break; + + case inGrow: + if (whichWindow == mapWindow) + { + newSize = GrowWindow(mapWindow, theEvent->where, &thisMac.gray); + ResizeMapWindow(LoWord(newSize), HiWord(newSize)); + } + break; + + case inZoomIn: + case inZoomOut: + if (TrackBox(whichWindow, theEvent->where, thePart)) + ZoomWindow(whichWindow, thePart, true); + break; + + case inContent: + if (whichWindow == mainWindow) + { + hDelta = theEvent->where.h - lastWhere.h; + if (hDelta < 0) + hDelta = -hDelta; + vDelta = theEvent->where.v - lastWhere.v; + if (vDelta < 0) + vDelta = -vDelta; + if (((theEvent->when - lastUp) < doubleTime) && (hDelta < 5) && + (vDelta < 5)) + isDoubleClick = true; + else + { + isDoubleClick = false; + lastUp = theEvent->when; + lastWhere = theEvent->where; + } + HandleMainClick(theEvent->where, isDoubleClick); + } + else if (whichWindow == mapWindow) + HandleMapClick(theEvent); + else if (whichWindow == toolsWindow) + HandleToolsClick(theEvent->where); + else if (whichWindow == linkWindow) + HandleLinkClick(theEvent->where); + break; + + default: + break; + } +} + +//-------------------------------------------------------------- HandleKeyEvent +// Handle a key-down event. + +void HandleKeyEvent (EventRecord *theEvent) +{ + char theChar; + Boolean shiftDown, commandDown, optionDown; + + theChar = theEvent->message & charCodeMask; + shiftDown = ((theEvent->modifiers & shiftKey) != 0); + commandDown = ((theEvent->modifiers & cmdKey) != 0); + optionDown = ((theEvent->modifiers & optionKey) != 0); + + if ((commandDown) && (!optionDown)) + DoMenuChoice(MenuKey(theChar)); + else + { + switch (theChar) + { + case kHelpKeyASCII: + break; + + case kPageUpKeyASCII: + if (houseUnlocked) + PrevToolMode(); + break; + + case kPageDownKeyASCII: + if (houseUnlocked) + NextToolMode(); + break; + +#if BUILD_ARCADE_VERSION + + case kLeftArrowKeyASCII: + DoOptionsMenu(iHighScores); + break; + + case kRightArrowKeyASCII: + DoOptionsMenu(iHelp); + break; + + case kUpArrowKeyASCII: + DoGameMenu(iNewGame); + break; + + case kDownArrowKeyASCII: + DoGameMenu(iNewGame); + break; + +#else + + case kLeftArrowKeyASCII: + if (houseUnlocked) + { + if (objActive == kNoObjectSelected) + SelectNeighborRoom(kRoomToLeft); + else + MoveObject(kBumpLeft, shiftDown); + } + break; + + case kRightArrowKeyASCII: + if (houseUnlocked) + { + if (objActive == kNoObjectSelected) + SelectNeighborRoom(kRoomToRight); + else + MoveObject(kBumpRight, shiftDown); + } + break; + + case kUpArrowKeyASCII: + if (houseUnlocked) + { + if (objActive == kNoObjectSelected) + SelectNeighborRoom(kRoomAbove); + else + MoveObject(kBumpUp, shiftDown); + } + break; + + case kDownArrowKeyASCII: + if (houseUnlocked) + { + if (objActive == kNoObjectSelected) + SelectNeighborRoom(kRoomBelow); + else + MoveObject(kBumpDown, shiftDown); + } + break; + +#endif + + case kDeleteKeyASCII: + if (houseUnlocked) + { + if (objActive == kNoObjectSelected) + DeleteRoom(true); + else + DeleteObject(); + } + break; + + case kTabKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + { + if (shiftDown) + SelectPrevObject(); + else + SelectNextObject(); + } + break; + + case kEscapeKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + DeselectObject(); + break; + + case kAKeyASCII: + case kCapAKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + SetSpecificToolMode(kApplianceMode); + break; + + case kBKeyASCII: + case kCapBKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + SetSpecificToolMode(kBlowerMode); + break; + + case kCKeyASCII: + case kCapCKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + SetSpecificToolMode(kClutterMode); + break; + + case kEKeyASCII: + case kCapEKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + SetSpecificToolMode(kEnemyMode); + break; + + case kFKeyASCII: + case kCapFKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + SetSpecificToolMode(kFurnitureMode); + break; + + case kLKeyASCII: + case kCapLKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + SetSpecificToolMode(kLightMode); + break; + + case kPKeyASCII: + case kCapPKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + SetSpecificToolMode(kBonusMode); + break; + + case kSKeyASCII: + case kCapSKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + SetSpecificToolMode(kSwitchMode); + break; + + case kTKeyASCII: + case kCapTKeyASCII: + if ((theMode == kEditMode) && (houseUnlocked)) + SetSpecificToolMode(kTransportMode); + break; + + default: + break; + } + } +} + +//-------------------------------------------------------------- HandleUpdateEvent +// Handle an update event. + +void HandleUpdateEvent (EventRecord *theEvent) +{ + if ((WindowPtr)theEvent->message == mainWindow) + { + SetPort((GrafPtr)mainWindow); + BeginUpdate(mainWindow); + UpdateMainWindow(); + EndUpdate(mainWindow); + } + else if ((WindowPtr)theEvent->message == mapWindow) + { + SetPort((GrafPtr)mapWindow); + BeginUpdate(mapWindow); + UpdateMapWindow(); + EndUpdate(mapWindow); + } + else if ((WindowPtr)theEvent->message == toolsWindow) + { + SetPort((GrafPtr)toolsWindow); + BeginUpdate(toolsWindow); + UpdateToolsWindow(); + EndUpdate(toolsWindow); + } + else if ((WindowPtr)theEvent->message == linkWindow) + { + SetPort((GrafPtr)linkWindow); + BeginUpdate(linkWindow); + UpdateLinkWindow(); + EndUpdate(linkWindow); + } + else if ((WindowPtr)theEvent->message == coordWindow) + { + SetPort((GrafPtr)coordWindow); + BeginUpdate(coordWindow); + UpdateCoordWindow(); + EndUpdate(coordWindow); + } + else if ((WindowPtr)theEvent->message == menuWindow) + { + SetPort((GrafPtr)menuWindow); + BeginUpdate(menuWindow); + UpdateMenuBarWindow(); + EndUpdate(menuWindow); + } +} + +//-------------------------------------------------------------- HandleOSEvent +// Handle an OS Event (MultiFinder - user has switched in or out of app). + +void HandleOSEvent (EventRecord *theEvent) +{ + OSErr theErr; + short buttonHit; + + if (theEvent->message & 0x01000000) // suspend or resume event + { + if (theEvent->message & 0x00000001) // resume event + { + if (WhatsOurDepth() != thisMac.isDepth) + { + buttonHit = BitchAboutColorDepth(); + if (buttonHit == 1) // player wants to Quit + { +#ifndef COMPILEDEMO + if (QuerySaveChanges()) + quitting = true; +#else + quitting = true; +#endif + } + else + { + SwitchToDepth(thisMac.isDepth, thisMac.wasColorOrGray); + } + } + switchedOut = false; + InitCursor(); + if ((isPlayMusicIdle) && (theMode != kEditMode)) + { + theErr = StartMusic(); + if (theErr != noErr) + { + YellowAlert(kYellowNoMusic, theErr); + failedMusic = true; + } + } + incrementModeTime = TickCount() + kIdleSplashTicks; + +#ifndef COMPILEDEMO +// if (theMode == kEditMode) +// SeeIfValidScrapAvailable(true); +#endif + } + else // suspend event + { + switchedOut = true; + InitCursor(); + if ((isMusicOn) && (theMode != kEditMode)) + StopTheMusic(); + } + } +} + +//-------------------------------------------------------------- HandleHighLevelEvent +// Handle an AppleEvent (Open Document, Quit Application, etc.). + +void HandleHighLevelEvent (EventRecord *theEvent) +{ + OSErr theErr; + + theErr = AEProcessAppleEvent(theEvent); + if ((theErr != noErr) && (theErr != errAEEventNotHandled)) + YellowAlert(kYellowAppleEventErr, theErr); +} + +//-------------------------------------------------------------- HandleIdleTask +// Handle some processing during event lulls. + +void HandleIdleTask (void) +{ + if (theMode == kEditMode) + { + SetPort((GrafPtr)mainWindow); + DoMarquee(); + + if ((autoRoomEdit) && (newRoomNow)) + { + if (theMode == kEditMode) + DoRoomInfo(); + newRoomNow = false; + } + } +} + +//-------------------------------------------------------------- HandleEvent +// "Master" function that tests for events and calls the above functions toÉ +// handle each event type. Not called during and actual game. + +void HandleEvent (void) +{ + KeyMap eventKeys; + EventRecord theEvent; + long sleep = 2; + Boolean itHappened = true; + + GetKeys(eventKeys); + if ((BitTst(&eventKeys, kCommandKeyMap)) && + (BitTst(&eventKeys, kOptionKeyMap))) + { + HiliteAllObjects(); + } + else if ((BitTst(&eventKeys, kOptionKeyMap)) && (theMode == kEditMode) && + (houseUnlocked)) + { + EraseSelectedTool(); + SelectTool(kSelectTool); + } + + //if (thisMac.hasWNE) + // itHappened = WaitNextEvent(everyEvent, &theEvent, sleep, nil); + //else + { + // SystemTask(); + itHappened = GetNextEvent(everyEvent, &theEvent); + } + + if (itHappened) + { + switch (theEvent.what) + { + case mouseDown: + HandleMouseEvent(&theEvent); + break; + + case keyDown: + case autoKey: + HandleKeyEvent(&theEvent); + break; + + case updateEvt: + HandleUpdateEvent(&theEvent); + break; + + case osEvt: + HandleOSEvent(&theEvent); + break; + + case kHighLevelEvent: + HandleHighLevelEvent(&theEvent); + break; + } + } + else + HandleIdleTask(); + + if ((theMode == kSplashMode) && doAutoDemo && !switchedOut) + { + if (TickCount() >= incrementModeTime) + DoDemoGame(); + } +} + +//-------------------------------------------------------------- HiliteAllWindows + +// Ugly kludge in order to keep "floating windows" (palettes) on top ofÉ +// the main window. + +void HiliteAllWindows (void) +{ + if (mainWindow != nil) + HiliteWindow(mainWindow, true); + if (mapWindow != nil) + HiliteWindow(mapWindow, true); + if (toolsWindow != nil) + HiliteWindow(toolsWindow, true); + if (coordWindow != nil) + HiliteWindow(coordWindow, true); + if (linkWindow != nil) + HiliteWindow(linkWindow, true); +} + +//-------------------------------------------------------------- IgnoreThisClick + +// Another inelegant kludge designed to temporarily prevent an unwantedÉ +// double-click to be registered. + +void IgnoreThisClick (void) +{ + lastUp -= doubleTime; + lastWhere.h = -100; + lastWhere.v = -100; +} + diff --git a/GpApp/Externs.h b/GpApp/Externs.h new file mode 100644 index 0000000..0fb58ab --- /dev/null +++ b/GpApp/Externs.h @@ -0,0 +1,390 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Externs.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#pragma once + + +#include "PLMenus.h" + + +#define kPreferredDepth 8 + + +#define kNilPointer 0L +#define kPutInFront (WindowPtr)-1L +#define kNormalUpdates TRUE +#define kOneKilobyte 1024 +#define kOkayButton 1 +#define kCancelButton 2 +#define kControlActive 0 +#define kControlInactive 255 +#define kAsynch TRUE +#define kSynch FALSE + +#define kHomeKeyASCII 0x01 +#define kEnterKeyASCII 0x03 +#define kEndKeyASCII 0x04 +#define kHelpKeyASCII 0x05 +#define kDeleteKeyASCII 0x08 +#define kTabKeyASCII 0x09 +#define kPageUpKeyASCII 0x0B +#define kPageDownKeyASCII 0x0C +#define kReturnKeyASCII 0x0D +#define kFunctionKeyASCII 0x10 +#define kClearKeyASCII 0x1A +#define kEscapeKeyASCII 0x1B +#define kLeftArrowKeyASCII 0x1C +#define kRightArrowKeyASCII 0x1D +#define kUpArrowKeyASCII 0x1E +#define kDownArrowKeyASCII 0x1F +#define kSpaceBarASCII 0x20 +#define kExclamationASCII 0x21 +#define kPlusKeyASCII 0x2B +#define kMinusKeyASCII 0x2D +#define k0KeyASCII 0x30 +#define k1KeyASCII 0x31 +#define k2KeyASCII 0x32 +#define k3KeyASCII 0x33 +#define k4KeyASCII 0x34 +#define k5KeyASCII 0x35 +#define k6KeyASCII 0x36 +#define k7KeyASCII 0x37 +#define k8KeyASCII 0x38 +#define k9KeyASCII 0x39 + +#define kCapAKeyASCII 0x41 +#define kCapBKeyASCII 0x42 +#define kCapCKeyASCII 0x43 +#define kCapDKeyASCII 0x44 +#define kCapEKeyASCII 0x45 +#define kCapFKeyASCII 0x46 +#define kCapGKeyASCII 0x47 +#define kCapHKeyASCII 0x48 +#define kCapIKeyASCII 0x49 +#define kCapJKeyASCII 0x4A +#define kCapKKeyASCII 0x4B +#define kCapLKeyASCII 0x4C +#define kCapMKeyASCII 0x4D +#define kCapNKeyASCII 0x4E +#define kCapOKeyASCII 0x4F +#define kCapPKeyASCII 0x50 +#define kCapQKeyASCII 0x51 +#define kCapRKeyASCII 0x52 +#define kCapSKeyASCII 0x53 +#define kCapTKeyASCII 0x54 +#define kCapUKeyASCII 0x55 +#define kCapVKeyASCII 0x56 +#define kCapWKeyASCII 0x57 +#define kCapXKeyASCII 0x58 +#define kCapYKeyASCII 0x59 +#define kCapZKeyASCII 0x5A + +#define kAKeyASCII 0x61 +#define kBKeyASCII 0x62 +#define kCKeyASCII 0x63 +#define kDKeyASCII 0x64 +#define kEKeyASCII 0x65 +#define kFKeyASCII 0x66 +#define kGKeyASCII 0x67 +#define kHKeyASCII 0x68 +#define kIKeyASCII 0x69 +#define kJKeyASCII 0x6A +#define kKKeyASCII 0x6B +#define kLKeyASCII 0x6C +#define kMKeyASCII 0x6D +#define kNKeyASCII 0x6E +#define kOKeyASCII 0x6F +#define kPKeyASCII 0x70 +#define kQKeyASCII 0x71 +#define kRKeyASCII 0x72 +#define kSKeyASCII 0x73 +#define kTKeyASCII 0x74 +#define kUKeyASCII 0x75 +#define kVKeyASCII 0x76 +#define kWKeyASCII 0x77 +#define kXKeyASCII 0x78 +#define kYKeyASCII 0x79 +#define kZKeyASCII 0x7A +#define kForwardDeleteASCII 0x7F + +#define kPlusKeypadMap 66 // key map offset for + on keypad +#define kMinusKeypadMap 73 // key map offset for - on keypad +#define kTimesKeypadMap 68 // key map offset for * on keypad +#define k0KeypadMap 85 // key map offset for 0 on keypad +#define k1KeypadMap 84 // key map offset for 1 on keypad +#define k2KeypadMap 83 // key map offset for 2 on keypad +#define k3KeypadMap 82 // key map offset for 3 on keypad +#define k4KeypadMap 81 // key map offset for 4 on keypad +#define k5KeypadMap 80 // key map offset for 5 on keypad +#define k6KeypadMap 95 // key map offset for 6 on keypad +#define k7KeypadMap 94 // key map offset for 7 on keypad +#define k8KeypadMap 92 // key map offset for 8 on keypad +#define k9KeypadMap 91 // key map offset for 9 on keypad + +#define kUpArrowKeyMap 121 // key map offset for up arrow +#define kDownArrowKeyMap 122 // key map offset for down arrow +#define kRightArrowKeyMap 123 // key map offset for right arrow +#define kLeftArrowKeyMap 124 // key map offset for left arrow + +#define kAKeyMap 7 +#define kBKeyMap 12 +#define kCKeyMap 15 +#define kDKeyMap 5 +#define kEKeyMap 9 +#define kFKeyMap 4 +#define kGKeyMap 2 +#define kHKeyMap 3 +#define kMKeyMap 41 +#define kNKeyMap 42 +#define kOKeyMap 24 +#define kPKeyMap 36 +#define kQKeyMap 11 +#define kRKeyMap 8 +#define kSKeyMap 6 +#define kTKeyMap 22 +#define kVKeyMap 14 +#define kWKeyMap 10 +#define kXKeyMap 0 +#define kZKeyMap 1 +#define kPeriodKeyMap 40 +#define kCommandKeyMap 48 +#define kEscKeyMap 50 +#define kDeleteKeyMap 52 +#define kSpaceBarMap 54 +#define kTabKeyMap 55 +#define kControlKeyMap 60 +#define kOptionKeyMap 61 +#define kCapsLockKeyMap 62 +#define kShiftKeyMap 63 + +#define kTabRawKey 0x30 // key map offset for Tab key +#define kClearRawKey 0x47 // key map offset for Clear key +#define kF5RawKey 0x60 // key map offset for F5 +#define kF6RawKey 0x61 // key map offset for F6 +#define kF7RawKey 0x62 // key map offset for F7 +#define kF3RawKey 0x63 // key map offset for F3 +#define kF8RawKey 0x64 // key map offset for F8 +#define kF9RawKey 0x65 // key map offset for F9 +#define kF11RawKey 0x67 // key map offset for F11 +#define kF13RawKey 0x69 // key map offset for F13 +#define kF14RawKey 0x6B // key map offset for F14 +#define kF10RawKey 0x6D // key map offset for F10 +#define kF12RawKey 0x6F // key map offset for F12 +#define kF15RawKey 0x71 // key map offset for F15 +#define kF4RawKey 0x76 // key map offset for F4 +#define kF2RawKey 0x78 // key map offset for F2 +#define kF1RawKey 0x7A // key map offset for F1 + +#define kErrUnnaccounted 1 +#define kErrNoMemory 2 +#define kErrDialogDidntLoad 3 +#define kErrFailedResourceLoad 4 +#define kErrFailedGraphicLoad 5 +#define kErrFailedOurDirect 6 +#define kErrFailedValidation 7 +#define kErrNeedSystem7 8 +#define kErrFailedGetDevice 9 +#define kErrFailedMemoryOperation 10 +#define kErrFailedCatSearch 11 +#define kErrNeedColorQD 12 +#define kErrNeed16Or256Colors 13 + +#define iAbout 1 +#define iNewGame 1 +#define iTwoPlayer 2 +#define iOpenSavedGame 3 +#define iLoadHouse 5 +#define iQuit 7 +#define iEditor 1 +#define iHighScores 3 +#define iPrefs 4 +#define iHelp 5 +#define iNewHouse 1 +#define iSave 2 +#define iHouse 4 +#define iRoom 5 +#define iObject 6 +#define iCut 8 +#define iCopy 9 +#define iPaste 10 +#define iClear 11 +#define iDuplicate 12 +#define iBringForward 14 +#define iSendBack 15 +#define iGoToRoom 17 +#define iMapWindow 19 +#define iObjectWindow 20 +#define iCoordinateWindow 21 + +//-------------------------------------------------------------- Structs +/* +typedef short SICN[16]; +typedef SICN *SICNList; +typedef SICNList *SICNHand; +*/ + +typedef struct +{ + Str32 wasDefaultName; + Str15 wasLeftName, wasRightName; + Str15 wasBattName, wasBandName; + Str15 wasHighName; + Str31 wasHighBanner; +// long encrypted, fakeLong; + long wasLeftMap, wasRightMap; + long wasBattMap, wasBandMap; + short wasVolume; + short prefVersion; + short wasMaxFiles; + short wasEditH, wasEditV; + short wasMapH, wasMapV; + short wasMapWide, wasMapHigh; + short wasToolsH, wasToolsV; + short wasLinkH, wasLinkV; + short wasCoordH, wasCoordV; + short isMapLeft, isMapTop; + short wasNumNeighbors; + short wasDepthPref; + short wasToolGroup; + short smWarnings; + short wasFloor, wasSuite; + Boolean wasZooms, wasMusicOn; + Boolean wasAutoEdit, wasDoColorFade; + Boolean wasMapOpen, wasToolsOpen; + Boolean wasCoordOpen, wasQuickTrans; + Boolean wasIdleMusic, wasGameMusic; + Boolean wasEscPauseKey; + Boolean wasDoAutoDemo, wasScreen2; + Boolean wasDoBackground, wasHouseChecks; + Boolean wasPrettyMap, wasBitchDialogs; +} prefsInfo; + +//-------------------------------------------------------------- Prototypes + +void DoAbout (void); // --- About.c + +void LoadCursors (void); // --- AnimCursor.c +void DisposCursors (void); +void IncrementCursor (void); +void DecrementCursor (void); +void SpinCursor (short); +void BackSpinCursor (short); + +void ColorText (StringPtr, long); // --- ColorUtils.c +void ColorRect (Rect *, long); +void ColorOval (Rect *, long); +void ColorRegion (RgnHandle, long); +void ColorLine (short, short, short, short, long); +void HiliteRect (Rect *, short, short); +void ColorFrameRect (Rect *, long); +void ColorFrameWHRect (short, short, short, short, long); +void ColorFrameOval (Rect *, long); +void LtGrayForeColor (void); +void GrayForeColor (void); +void DkGrayForeColor (void); +void RestoreColorsSlam (void); + +void MonitorWait (void); // --- DebugUtils.c +void DisplayRect (Rect *); +void FlashRect (Rect *); +void CheckLegitRect(Rect *, Rect *); +void DisplayLong (long); +void DisplayShort (short); +void FlashLong (long); +void FlashShort (short); +void DoBarGraph (short, short, short, short); +short BetaOkay (void); +void DebugNum (long); +void DisplayCTSeed (CGrafPtr); +void FillScreenRed (void); +void DumpToResEditFile (Ptr, long); + +void HandleEvent (void); // --- Event.c +void HiliteAllWindows (void); +void IgnoreThisClick (void); + +short WhatsOurDepth (void); // --- Environs.c +void SwitchToDepth (short, Boolean); +void CheckOurEnvirons (void); +//void ReflectSecondMonitorEnvirons (Boolean, Boolean, Boolean); +void HandleDepthSwitching (void); +void RestoreColorDepth (void); +void CheckMemorySize (void); +void SetAppMemorySize (long); + +Boolean CheckFileError (short, const PLPasStr &); // --- File Error.c + +Boolean SavePrefs (prefsInfo *, short); // --- Prefs.c +Boolean LoadPrefs (prefsInfo *, short); + +void PasStringCopy (StringPtr, StringPtr); // --- StringUtils.c +short WhichStringFirst (StringPtr, StringPtr); +void PasStringCopyNum (StringPtr, StringPtr, short); +void PasStringConcat (StringPtr, const PLPasStr &); +void GetLineOfText (StringPtr, short, StringPtr); +void WrapText (StringPtr, short); +void GetFirstWordOfString (StringPtr, StringPtr); +void CollapseStringToWidth (StringPtr, short); +void GetChooserName (StringPtr); +StringPtr GetLocalizedString (short, StringPtr); + +Point MyGetGlobalMouse (void); // --- Utilities.c +void ToolBoxInit (void); +void FindOurDevice (void); +short RandomInt (short); +long RandomLong (long); +void InitRandomLongQUS (void); +UInt32 RandomLongQUS (void); +//void CenterAlert (short); +void RedAlert (short); +//void CreateOffScreenBitMap (Rect *, GrafPtr *); +//void CreateOffScreenPixMap (Rect *, CGrafPtr *); +//void KillOffScreenPixMap (CGrafPtr); +//void KillOffScreenBitMap (GrafPtr); +void LoadGraphic (short); +void LoadScaledGraphic (short, Rect *); +//void PlotSICN (Rect *, SICNHand, long); +void LargeIconPlot (Rect *, short); +void DrawCIcon (short, short, short); +char KeyMapOffsetFromRawKey (char); +long LongSquareRoot (long); +//void HideMenuBarOld (void); +//void ShowMenuBarOld (void); +Boolean WaitForInputEvent (short); +void WaitCommandQReleased (void); +char GetKeyMapFromMessage (intptr_t); +void GetKeyName (intptr_t, StringPtr); +Boolean OptionKeyDown (void); +long ExtractCTSeed (CGrafPtr); +//void ForceCTSeed (CGrafPtr, long); +void DelayTicks (long); +void UnivGetSoundVolume (short *, Boolean); +void UnivSetSoundVolume (short, Boolean); + +Boolean ValidInstallation (Boolean); // --- Validate.c + +void GetWindowLeftTop (WindowPtr, short *, short *); // --- WindowUtils.c +void GetWindowRect (WindowPtr, Rect *); +void GetLocalWindowRect (WindowPtr, Rect *); +//void FlagWindowFloating (WindowPtr); +//Boolean IsWindowFloating (WindowPtr); +void OpenMessageWindow (const PLPasStr&); +void SetMessageWindowMessage (StringPtr); +void CloseMessageWindow (void); +void CloseThisWindow (WindowPtr *); + +#ifdef powerc +// extern pascal void SetSoundVol(short level); // for old Sound Manager +// extern pascal void GetSoundVol(short *level) +// THREEWORDINLINE(0x4218, 0x10B8, 0x0260); +#endif + +#include "GliderDefines.h" +#include "GliderStructs.h" +#include "GliderVars.h" +#include "GliderProtos.h" \ No newline at end of file diff --git a/GpApp/FileError.cpp b/GpApp/FileError.cpp new file mode 100644 index 0000000..07ac86a --- /dev/null +++ b/GpApp/FileError.cpp @@ -0,0 +1,101 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// FileError.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLNumberFormatting.h" +#include "PLTextUtils.h" +#include "PLPasStr.h" +#include "Externs.h" + + +#define rFileErrorAlert 140 +#define rFileErrorStrings 140 + + +//============================================================== Functions +//-------------------------------------------------------------- CheckFileError + +// Given a result code (returned from a previous file operation) thisÉ +// function cheks to see if the result code is an error and, if it isÉ +// a common error for which I have a string message, I bring up anÉ +// alert with the error message. If it is an unusual error, I stillÉ +// bring up an alert but with "Miscellaneous file error" and theÉ +// error ID. + +Boolean CheckFileError (short resultCode, const PLPasStr &fileName) +{ + short dummyInt, stringIndex; + Str255 errMessage, errNumString; + + if (resultCode == noErr) // No problems? Then cruise + return(true); + + switch (resultCode) + { + case dirFulErr: + stringIndex = 2; + break; + case dskFulErr: + stringIndex = 3; + break; + case ioErr: + stringIndex = 4; + break; + case bdNamErr: + stringIndex = 5; + break; + case fnOpnErr: + stringIndex = 6; + break; + case mFulErr: + stringIndex = 7; + break; + case tmfoErr: + stringIndex = 8; + break; + case wPrErr: + stringIndex = 9; + break; + case fLckdErr: + stringIndex = 10; + break; + case vLckdErr: + stringIndex = 11; + break; + case fBsyErr: + stringIndex = 12; + break; + case dupFNErr: + stringIndex = 13; + break; + case opWrErr: + stringIndex = 14; + break; + case volOffLinErr: + stringIndex = 15; + break; + case permErr: + stringIndex = 16; + break; + case wrPermErr: + stringIndex = 17; + break; + default: + stringIndex = 1; + break; + } + InitCursor(); + + GetIndString(errMessage, rFileErrorStrings, stringIndex); + NumToString((long)resultCode, errNumString); + ParamText(errMessage, errNumString, fileName, PSTR("")); + +// CenterAlert(rFileErrorAlert); + dummyInt = Alert(rFileErrorAlert, 0L); + + return(false); +} diff --git a/GpApp/GameOver.cpp b/GpApp/GameOver.cpp new file mode 100644 index 0000000..d553cc2 --- /dev/null +++ b/GpApp/GameOver.cpp @@ -0,0 +1,508 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// GameOver.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLToolUtils.h" +#include "PLPasStr.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(); +} + diff --git a/GpApp/GameOver.h b/GpApp/GameOver.h new file mode 100644 index 0000000..b71723e --- /dev/null +++ b/GpApp/GameOver.h @@ -0,0 +1,12 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// GameOver.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +extern GWorldPtr angelSrcMap; +extern GWorldPtr angelMaskMap; diff --git a/GpApp/GliderDefines.h b/GpApp/GliderDefines.h new file mode 100644 index 0000000..175eb3d --- /dev/null +++ b/GpApp/GliderDefines.h @@ -0,0 +1,625 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// GliderDefines.h +//---------------------------------------------------------------------------- +//============================================================================ + + +//============================================================== Defines + +//#define CREATEDEMODATA +//#define COMPILEDEMO +//#define CAREFULDEBUG +#define COMPILENOCP +#define COMPILEQT +#define BUILD_ARCADE_VERSION 1 + +#define kYellowUnaccounted 1 +#define kYellowFailedResOpen 2 +#define kYellowFailedResAdd 3 +#define kYellowFailedResCreate 4 +#define kYellowNoHouses 5 +#define kYellowNewerVersion 6 +#define kYellowNoBackground 7 +#define kYellowIllegalRoomNum 8 +#define kYellowNoBoundsRes 9 +#define kYellowScrapError 10 +#define kYellowNoMemory 11 +#define kYellowFailedWrite 12 +#define kYellowNoMusic 13 +#define kYellowFailedSound 14 +#define kYellowAppleEventErr 15 +#define kYellowOpenedOldHouse 16 +#define kYellowLostAllHouses 17 +#define kYellowFailedSaveGame 18 +#define kYellowSavedTimeWrong 19 +#define kYellowSavedVersWrong 20 +#define kYellowSavedRoomsWrong 21 +#define kYellowQTMovieNotLoaded 22 +#define kYellowNoRooms 23 +#define kYellowCantOrderLinks 24 + +#define kSwitchIfNeeded 0 +#define kSwitchTo256Colors 1 +#define kSwitchTo16Grays 2 + +#define kProdGameScoreMode -4 +#define kKickGameScoreMode -3 +#define kPlayGameScoreMode -2 +#define kPlayWholeScoreMode -1 +#define kPlayChorus 4 +#define kPlayRefrainSparse1 5 +#define kPlayRefrainSparse2 6 + +#define kHitWallSound 0 // ¥¥¥¥¥¥ +#define kFadeInSound 1 // ¥¥ +#define kFadeOutSound 2 // ¥¥¥¥¥¥ +#define kBeepsSound 3 // ¥¥ +#define kBuzzerSound 4 // ¥¥¥¥¥¥ +#define kDingSound 5 // +#define kEnergizeSound 6 // ¥¥¥¥¥¥ +#define kFollowSound 7 // ¥¥ ¥¥ +#define kMicrowavedSound 8 // ¥¥ ¥¥ +#define kSwitchSound 9 // ¥¥ ¥¥ +#define kBirdSound 10 // ¥¥¥¥¥¥ +#define kCuckooSound 11 // +#define kTikSound 12 // ¥¥ ¥¥ +#define kTokSound 13 // ¥¥ ¥¥ +#define kBlowerOn 14 // ¥¥ ¥¥ +#define kBlowerOff 15 // ¥¥ ¥¥ +#define kCaughtFireSound 16 // ¥¥¥¥¥¥ +#define kScoreTikSound 17 // +#define kThrustSound 18 // ¥¥¥ ¥¥ +#define kFizzleSound 19 // ¥¥¥¥ ¥¥ +#define kFireBandSound 20 // ¥¥ ¥¥ ¥¥ +#define kBandReboundSound 21 // ¥¥ ¥¥¥¥ +#define kGreaseSpillSound 22 // ¥¥ ¥¥¥ +#define kChordSound 23 // +#define kVCRSound 24 // ¥¥¥¥¥¥¥ +#define kFoilHitSound 25 // ¥¥ ¥¥ +#define kShredSound 26 // ¥¥ ¥¥ +#define kToastLaunchSound 27 // ¥¥ ¥¥ +#define kToastLandSound 28 // ¥¥¥¥¥¥¥ +#define kMacOnSound 29 // +#define kMacBeepSound 30 // +#define kMacOffSound 31 // +#define kTVOnSound 32 // +#define kTVOffSound 33 // ¥¥¥¥¥¥ +#define kCoffeeSound 34 // ¥¥ +#define kMysticSound 35 // ¥¥¥¥¥¥ +#define kZapSound 36 // ¥¥ +#define kPopSound 37 // ¥¥¥¥¥¥ +#define kEnemyInSound 38 // +#define kEnemyOutSound 39 // ¥¥¥¥¥¥ +#define kPaperCrunchSound 40 // ¥¥ ¥¥ +#define kBounceSound 41 // ¥¥ ¥¥ +#define kDripSound 42 // ¥¥ ¥¥ +#define kDropSound 43 // ¥¥¥¥¥¥ +#define kFishOutSound 44 // +#define kFishInSound 45 // ¥¥ ¥¥ +#define kDontExitSound 46 // ¥¥ ¥¥ +#define kSizzleSound 47 // ¥¥ ¥¥ +#define kPaper1Sound 48 // ¥¥ ¥¥ +#define kPaper2Sound 49 // ¥¥¥¥¥¥ +#define kPaper3Sound 50 // +#define kPaper4Sound 51 // ¥¥¥ ¥¥ +#define kTypingSound 52 // ¥¥¥¥ ¥¥ +#define kCarriageSound 53 // ¥¥ ¥¥ ¥¥ +#define kChord2Sound 54 // ¥¥ ¥¥¥¥ +#define kPhoneRingSound 55 // ¥¥ ¥¥¥ +#define kChime1Sound 56 // +#define kChime2Sound 57 // ¥¥¥¥¥¥¥ +#define kWebTwangSound 58 // ¥¥ ¥¥ +#define kTransOutSound 59 // ¥¥ ¥¥ +#define kTransInSound 60 // ¥¥ ¥¥ +#define kBonusSound 61 // ¥¥¥¥¥¥¥ +#define kHissSound 62 // +#define kTriggerSound 63 + +#define kHitWallPriority 100 // ¥¥¥¥¥¥ +#define kScoreTikPriority 101 // ¥¥ +#define kBandReboundPriority 102 // ¥¥¥¥¥¥ +#define kDontExitPriority 103 // ¥¥ +#define kTikPriority 200 // ¥¥¥¥¥¥ +#define kTokPriority 201 // +#define kMysticPriority 202 // ¥¥¥¥¥¥ +#define kChime1Priority 203 // ¥¥ ¥¥ +#define kChime2Priority 204 // ¥¥ ¥¥ +#define kThrustPriority 300 // ¥¥ ¥¥ +#define kFireBandPriority 301 // ¥¥¥¥¥¥ +#define kChordPriority 302 // +#define kVCRPriority 303 // ¥¥ ¥¥ +#define kToastLaunchPriority 304 // ¥¥ ¥¥ +#define kToastLandPriority 305 // ¥¥ ¥¥ +#define kCoffeePriority 306 // ¥¥ ¥¥ +#define kBouncePriority 307 // ¥¥¥¥¥¥ +#define kDripPriority 308 // +#define kDropPriority 309 // ¥¥¥ ¥¥ +#define kWebTwangPriority 310 // ¥¥¥¥ ¥¥ +#define kHissPriority 311 // ¥¥ ¥¥ ¥¥ +#define kFoilHitPriority 400 // ¥¥ ¥¥¥¥ +#define kMacOnPriority 401 // ¥¥ ¥¥¥ +#define kMacOffPriority 402 // +#define kMacBeepPriority 403 // ¥¥¥¥¥¥¥ +#define kTVOnPriority 404 // ¥¥ ¥¥ +#define kTVOffPriority 405 // ¥¥ ¥¥ +#define kZapPriority 406 // ¥¥ ¥¥ +#define kPopPriority 407 // ¥¥¥¥¥¥¥ +#define kEnemyInPriority 408 // +#define kEnemyOutPriority 409 // +#define kPaperCrunchPriority 410 // +#define kFishOutPriority 411 // +#define kFishInPriority 412 // +#define kSizzlePriority 413 +#define kPhoneRingPriority 500 +#define kSwitchPriority 700 +#define kBlowerOnPriority 701 +#define kBlowerOffPriority 702 +#define kFizzlePriority 703 +#define kBeepsPriority 800 +#define kBuzzerPriority 801 +#define kDingPriority 802 +#define kEnergizePriority 803 +#define kBirdPriority 804 +#define kCuckooPriority 805 +#define kGreaseSpillPriority 806 +#define kPapersPriority 807 +#define kTypingPriority 808 +#define kCarriagePriority 809 +#define kChord2Priority 810 +#define kMicrowavedPriority 811 +#define kBonusPriority 812 +#define kFadeInPriority 900 +#define kFadeOutPriority 901 +#define kCaughtFirePriority 902 +#define kShredPriority 903 +#define kFollowPriority 904 +#define kTransInPriority 905 +#define kTransOutPriority 906 +#define kTriggerPriority 999 + +#define kArrowCursor 0 +#define kBeamCursor 1 +#define kHandCursor 2 + +#define kAppleMenuID 128 +#define kGameMenuID 129 +#define kOptionsMenuID 130 +#define kHouseMenuID 131 + +#define kSplashMode 0 +#define kEditMode 1 +#define kPlayMode 2 + +#define kIdleSplashMode 0 +#define kIdleDemoMode 1 +#define kIdleSplashTicks 7200L // 2 minutes +#define kIdleLastMode 1 + +#define kRoomAbove 1 +#define kRoomBelow 2 +#define kRoomToRight 3 +#define kRoomToLeft 4 + +#define kBumpUp 1 +#define kBumpDown 2 +#define kBumpRight 3 +#define kBumpLeft 4 + +#define kAbove 1 +#define kToRight 2 +#define kBelow 3 +#define kToLeft 4 +#define kBottomCorner 5 +#define kTopCorner 6 + +#define kCentralRoom 0 +#define kNorthRoom 1 +#define kNorthEastRoom 2 +#define kEastRoom 3 +#define kSouthEastRoom 4 +#define kSouthRoom 5 +#define kSouthWestRoom 6 +#define kWestRoom 7 +#define kNorthWestRoom 8 + +#define kSimpleRoom 2000 +#define kPaneledRoom 2001 +#define kBasement 2002 +#define kChildsRoom 2003 +#define kAsianRoom 2004 +#define kUnfinishedRoom 2005 +#define kSwingersRoom 2006 +#define kBathroom 2007 +#define kLibrary 2008 +#define kGarden 2009 +#define kSkywalk 2010 +#define kDirt 2011 +#define kMeadow 2012 +#define kField 2013 +#define kRoof 2014 +#define kSky 2015 +#define kStratosphere 2016 +#define kStars 2017 + +#define kMapRoomHeight 20 +#define kMapRoomWidth 32 + +#define kMaxScores 10 +#define kMaxRoomObs 24 +#define kMaxSparkles 3 +#define kNumSparkleModes 5 +#define kMaxFlyingPts 3 +#define kMaxFlyingPointsLoop 24 +#define kMaxCandles 20 +#define kMaxTikis 8 +#define kMaxCoals 8 +#define kMaxPendulums 8 +#define kMaxHotSpots 56 +#define kMaxSavedMaps 24 +#define kMaxRubberBands 2 +#define kMaxGrease 16 +#define kMaxStars 4 +#define kMaxShredded 4 +#define kMaxDynamicObs 18 +#define kMaxMasterObjects 216 // kMaxRoomObs * 9 +#define kMaxViewWidth 1536 +#define kMaxViewHeight 1026 + +#define kSelectTool 0 + +#define kBlowerMode 1 +#define kFurnitureMode 2 +#define kBonusMode 3 +#define kTransportMode 4 +#define kSwitchMode 5 +#define kLightMode 6 +#define kApplianceMode 7 +#define kEnemyMode 8 +#define kClutterMode 9 + +#define kIgnoreIt 0 // ¥¥¥¥¥¥ +#define kLiftIt 1 // ¥¥ ¥¥ +#define kDropIt 2 // ¥¥¥¥¥¥¥¥ +#define kPushItLeft 3 // ¥¥ ¥¥ +#define kPushItRight 4 // ¥¥ ¥¥ +#define kDissolveIt 5 // +#define kRewardIt 6 // ¥¥¥¥¥¥ +#define kMoveItUp 7 // ¥¥ ¥¥ +#define kMoveItDown 8 // ¥¥ +#define kSwitchIt 9 // ¥¥ ¥¥ +#define kShredIt 10 // ¥¥¥¥¥¥ +#define kStrumIt 11 // +#define kTriggerIt 12 // ¥¥¥¥¥¥¥¥ +#define kBurnIt 13 // ¥¥ +#define kSlideIt 14 // ¥¥ +#define kTransportIt 15 // ¥¥ +#define kIgnoreLeftWall 16 // ¥¥ +#define kIgnoreRightWall 17 // +#define kMailItLeft 18 // ¥¥¥¥¥¥ +#define kMailItRight 19 // ¥¥ +#define kDuctItDown 20 // ¥¥ +#define kDuctItUp 21 // ¥¥ +#define kMicrowaveIt 22 // ¥¥¥¥¥¥ +#define kIgnoreGround 23 // +#define kBounceIt 24 // +#define kChimeIt 25 // ¥¥ +#define kWebIt 26 // ¥¥ +#define kSoundIt 27 + +#define kFloorVent 0x01 // Blowers +#define kCeilingVent 0x02 +#define kFloorBlower 0x03 +#define kCeilingBlower 0x04 +#define kSewerGrate 0x05 +#define kLeftFan 0x06 +#define kRightFan 0x07 +#define kTaper 0x08 +#define kCandle 0x09 +#define kStubby 0x0A +#define kTiki 0x0B +#define kBBQ 0x0C +#define kInvisBlower 0x0D +#define kGrecoVent 0x0E +#define kSewerBlower 0x0F +#define kLiftArea 0x10 + +#define kTable 0x11 // Furniture +#define kShelf 0x12 +#define kCabinet 0x13 +#define kFilingCabinet 0x14 +#define kWasteBasket 0x15 +#define kMilkCrate 0x16 +#define kCounter 0x17 +#define kDresser 0x18 +#define kDeckTable 0x19 +#define kStool 0x1A +#define kTrunk 0x1B +#define kInvisObstacle 0x1C +#define kManhole 0x1D +#define kBooks 0x1E +#define kInvisBounce 0x1F + +#define kRedClock 0x21 // Prizes +#define kBlueClock 0x22 +#define kYellowClock 0x23 +#define kCuckoo 0x24 +#define kPaper 0x25 +#define kBattery 0x26 +#define kBands 0x27 +#define kGreaseRt 0x28 +#define kGreaseLf 0x29 +#define kFoil 0x2A +#define kInvisBonus 0x2B +#define kStar 0x2C +#define kSparkle 0x2D +#define kHelium 0x2E +#define kSlider 0x2F + +#define kUpStairs 0x31 // Transport +#define kDownStairs 0x32 +#define kMailboxLf 0x33 +#define kMailboxRt 0x34 +#define kFloorTrans 0x35 +#define kCeilingTrans 0x36 +#define kDoorInLf 0x37 +#define kDoorInRt 0x38 +#define kDoorExRt 0x39 +#define kDoorExLf 0x3A +#define kWindowInLf 0x3B +#define kWindowInRt 0x3C +#define kWindowExRt 0x3D +#define kWindowExLf 0x3E +#define kInvisTrans 0x3F +#define kDeluxeTrans 0x40 + +#define kLightSwitch 0x41 // Switches +#define kMachineSwitch 0x42 +#define kThermostat 0x43 +#define kPowerSwitch 0x44 +#define kKnifeSwitch 0x45 +#define kInvisSwitch 0x46 +#define kTrigger 0x47 +#define kLgTrigger 0x48 +#define kSoundTrigger 0x49 + +#define kCeilingLight 0x51 // Lights +#define kLightBulb 0x52 +#define kTableLamp 0x53 +#define kHipLamp 0x54 +#define kDecoLamp 0x55 +#define kFlourescent 0x56 +#define kTrackLight 0x57 +#define kInvisLight 0x58 + +#define kShredder 0x61 // Appliances +#define kToaster 0x62 +#define kMacPlus 0x63 +#define kGuitar 0x64 +#define kTV 0x65 +#define kCoffee 0x66 +#define kOutlet 0x67 +#define kVCR 0x68 +#define kStereo 0x69 +#define kMicrowave 0x6A +#define kCinderBlock 0x6B +#define kFlowerBox 0x6C +#define kCDs 0x6D +#define kCustomPict 0x6E + +#define kBalloon 0x71 // Enemies +#define kCopterLf 0x72 +#define kCopterRt 0x73 +#define kDartLf 0x74 +#define kDartRt 0x75 +#define kBall 0x76 +#define kDrip 0x77 +#define kFish 0x78 +#define kCobweb 0x79 + +#define kOzma 0x81 // Clutter +#define kMirror 0x82 +#define kMousehole 0x83 +#define kFireplace 0x84 +#define kFlower 0x85 +#define kWallWindow 0x86 +#define kBear 0x87 +#define kCalendar 0x88 +#define kVase1 0x89 +#define kVase2 0x8A +#define kBulletin 0x8B +#define kCloud 0x8C +#define kFaucet 0x8D +#define kRug 0x8E +#define kChimes 0x8F + +#define kNumSrcRects 0x90 + +#define kTableThick 8 +#define kShelfThick 6 +#define kToggle 0 +#define kForceOn 1 +#define kForceOff 2 +#define kOneShot 3 +#define kNumTrackLights 3 +#define kNumOutletPicts 4 +#define kNumCandleFlames 5 +#define kNumTikiFlames 5 +#define kNumBBQCoals 4 +#define kNumPendulums 3 +#define kNumBreadPicts 6 +#define kNumBalloonFrames 8 +#define kNumCopterFrames 10 +#define kNumDartFrames 4 +#define kNumBallFrames 2 +#define kNumDripFrames 6 +#define kNumFishFrames 8 +#define kNumFlowers 6 + +#define kNumMarqueePats 7 +#define kObjectNameStrings 1007 + +#define kSwitchLinkOnly 3 +#define kTriggerLinkOnly 4 +#define kTransportLinkOnly 5 + +#define kFloorVentTop 305 +#define kCeilingVentTop 8 +#define kFloorBlowerTop 304 +#define kCeilingBlowerTop 5 +#define kSewerGrateTop 303 +#define kCeilingTransTop 6 +#define kFloorTransTop 302 +#define kStairsTop 28 +#define kCounterBottom 304 +#define kDresserBottom 293 +#define kCeilingLightTop 4 +#define kHipLampTop 23 +#define kDecoLampTop 91 +#define kFlourescentTop 12 +#define kTrackLightTop 5 + +#define kDoorInTop 0 +#define kDoorInLfLeft 0 +#define kDoorInRtLeft 368 +#define kDoorExTop 0 +#define kDoorExLfLeft 0 +#define kDoorExRtLeft 496 +#define kWindowInTop 64 +#define kWindowInLfLeft 0 +#define kWindowInRtLeft 492 +#define kWindowExTop 64 +#define kWindowExLfLeft 0 +#define kWindowExRtLeft 496 + +#define kNumTiles 8 +#define kTileWide 64 +#define kTileHigh 322 +#define kRoomWide 512 // kNumTiles * kTileWide +#define kFloorSupportTall 44 +#define kVertLocalOffset 322 // kTileHigh - 39 (was 283, then 295) + +#define kCeilingLimit 8 +#define kFloorLimit 312 +#define kRoofLimit 122 +#define kLeftWallLimit 12 +#define kNoLeftWallLimit -24 // 0 - (kGliderWide / 2) +#define kRightWallLimit 500 +#define kNoRightWallLimit 536 // kRoomWide + (kGliderWide / 2) +#define kNoCeilingLimit -10 +#define kNoFloorLimit 332 + +#define kScoreboardHigh 0 +#define kScoreboardLow 1 +#define kScoreboardTall 20 + +#define kHouseVersion 0x0200 +#define kNewHouseVersion 0x0300 +#define kBaseBackgroundID 2000 +#define kFirstOutdoorBack 2009 +#define kNumBackgrounds 18 +#define kUserBackground 3000 +#define kUserStructureRange 3300 +#define kSplash8BitPICT 1000 +#define kRoomIsEmpty -1 +#define kObjectIsEmpty -1 +#define kNoObjectSelected -1 +#define kInitialGliderSelected -2 +#define kLeftGliderSelected -3 +#define kRightGliderSelected -4 +#define kWindoidWDEF 2048 +#define kWindoidGrowWDEF 2064 +#define kTicksPerFrame 2 +#define kStarPictID 1995 +#define kNumUndergroundFloors 8 +#define kRoomVisitScore 100 +#define kRedClockPoints 100 +#define kBlueClockPoints 300 +#define kYellowClockPoints 500 +#define kCuckooClockPoints 1000 +#define kStarPoints 5000 +#define kRedOrangeColor8 23 // actually, 18 +#define kMaxNumRoomsH 128 +#define kMaxNumRoomsV 64 +#define kStartSparkle 4 +#define kLengthOfZap 30 + +#define kGliderWide 48 +#define kGliderHigh 20 +#define kHalfGliderWide 24 +#define kGliderBurningHigh 26 +#define kShadowHigh 9 +#define kShadowTop 306 +#define kFaceRight TRUE +#define kFaceLeft FALSE +#define kPlayer1 TRUE +#define kPlayer2 FALSE +#define kNumGliderSrcRects 31 +#define kNumShadowSrcRects 2 +#define kFirstAboutFaceFrame 18 +#define kLastAboutFaceFrame 20 +#define kWasBurning 2 +#define kLeftFadeOffset 7 +#define kLastFadeSequence 16 +#define kGliderFoil2PictID 3963 +#define kGlider2PictID 3974 +#define kGliderFoilPictID 3976 +#define kGliderPictID 3999 +#define kGliderStartsDown 32 + +#define kGliderNormal 0 // ¥¥ ¥¥ +#define kGliderFadingIn 1 // ¥¥¥ ¥¥¥ +#define kGliderFadingOut 2 // ¥¥ ¥¥ ¥¥ +#define kGliderGoingUp 3 // ¥¥ ¥¥ +#define kGliderComingUp 4 // ¥¥ ¥¥ +#define kGliderGoingDown 5 // +#define kGliderComingDown 6 // ¥¥¥¥¥¥ +#define kGliderFaceLeft 7 // ¥¥ ¥¥ +#define kGliderFaceRight 8 // ¥¥ ¥¥ +#define kGliderBurning 9 // ¥¥ ¥¥ +#define kGliderTransporting 10 // ¥¥¥¥¥¥ +#define kGliderDuctingDown 11 // +#define kGliderDuctingUp 12 // ¥¥¥¥¥¥¥ +#define kGliderDuctingIn 13 // ¥¥ ¥¥ +#define kGliderMailInLeft 14 // ¥¥ ¥¥ +#define kGliderMailOutLeft 15 // ¥¥ ¥¥ +#define kGliderMailInRight 16 // ¥¥¥¥¥¥¥ +#define kGliderMailOutRight 17 // +#define kGliderGoingFoil 18 // ¥¥¥¥¥¥¥¥ +#define kGliderLosingFoil 19 // ¥¥ +#define kGliderShredding 20 // ¥¥¥¥ +#define kGliderInLimbo 21 // ¥¥ +#define kGliderIdle 22 // ¥¥¥¥¥¥¥¥ +#define kGliderTransportingIn 23 + +#define kPlayerIsDeadForever -69 +#define kPlayerMailedOut -12 +#define kPlayerDuckedOut -11 +#define kPlayerTransportedOut -10 +#define kPlayerEscapingDownStairs -9 +#define kPlayerEscapingUpStairs -8 +#define kPlayerEscapedDownStairs -7 +#define kPlayerEscapedUpStairs -6 +#define kPlayerEscapedDown -5 +#define kPlayerEscapedUp -4 +#define kPlayerEscapedLeft -3 +#define kPlayerEscapedRight -2 +#define kNoOneEscaped -1 + +#define kLinkedToOther 0 +#define kLinkedToLeftMailbox 1 +#define kLinkedToRightMailbox 2 +#define kLinkedToCeilingDuct 3 +#define kLinkedToFloorDuct 4 + +#define kResumeGameMode 0 +#define kNewGameMode 1 + +#define kNormalTitleMode 0 +#define kEscapedTitleMode 1 +#define kSavingTitleMode 2 + +#define kScoreboardPictID 1997 + +#define kDemoLength 6702 diff --git a/GpApp/GliderProtos.h b/GpApp/GliderProtos.h new file mode 100644 index 0000000..45bfdc5 --- /dev/null +++ b/GpApp/GliderProtos.h @@ -0,0 +1,530 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// GliderProtos.h +//---------------------------------------------------------------------------- +//============================================================================ + + +//-------------------------------------------------------------- Prototypes + +void SetUpAppleEvents (void); // --- AppleEvents.c + +void BringUpBanner (void); // --- Banner.c +SInt16 CountStarsInHouse (void); +void DisplayStarsRemaining (void); + +void SetCoordinateHVD (SInt16, SInt16, SInt16); // --- Coordinate.c +void DeltaCoordinateD (SInt16); +void UpdateCoordWindow (void); +void OpenCoordWindow (void); +void CloseCoordWindow (void); +void ToggleCoordinateWindow (void); + +void NilSavedMaps (void); // --- DynamicMaps.c +SInt16 BackUpToSavedMap (Rect *, SInt16, SInt16); +SInt16 ReBackUpSavedMap (Rect *, SInt16, SInt16); +void RestoreFromSavedMap (SInt16, SInt16, Boolean); +void AddSparkle (Rect *); +void AddFlyingPoint (Rect *, SInt16, SInt16, SInt16); +void ReBackUpFlames (SInt16, SInt16); +void AddCandleFlame (SInt16, SInt16, SInt16, SInt16); +void ReBackUpTikiFlames (SInt16, SInt16); +void AddTikiFlame (SInt16, SInt16, SInt16, SInt16); +void ReBackUpBBQCoals (SInt16, SInt16); +void AddBBQCoals (SInt16, SInt16, SInt16, SInt16); +void ReBackUpPendulum (SInt16, SInt16); +void AddPendulum (SInt16, SInt16, SInt16, SInt16); +void ReBackUpStar (SInt16, SInt16); +void AddStar (SInt16, SInt16, SInt16, SInt16); +void StopPendulum (SInt16, SInt16); +void StopStar (SInt16, SInt16); +void AddAShreddedGlider (Rect *); +void RemoveShreds (void); +void ZeroFlamesAndTheLike (void); + +void CheckDynamicCollision (SInt16, gliderPtr, Boolean); // --- Dynamics.c +Boolean DidBandHitDynamic (SInt16); +void RenderToast (SInt16); +void RenderBalloon (SInt16); +void RenderCopter (SInt16); +void RenderDart (SInt16); +void RenderBall (SInt16); +void RenderDrip (SInt16); +void RenderFish (SInt16); +void HandleSparkleObject (SInt16); +void HandleToast (SInt16); +void HandleMacPlus (SInt16); +void HandleTV (SInt16); +void HandleCoffee (SInt16); +void HandleOutlet (SInt16); +void HandleVCR (SInt16); +void HandleStereo (SInt16); +void HandleMicrowave (SInt16); + +void HandleBalloon (SInt16); // --- Dynamics2.c +void HandleCopter (SInt16); +void HandleDart (SInt16); +void HandleBall (SInt16); +void HandleDrip (SInt16); +void HandleFish (SInt16); + +void HandleDynamics (void); // --- Dynamics3.c +void RenderDynamics (void); +void ZeroDinahs (void); +SInt16 AddDynamicObject (SInt16, Rect *, objectType *, SInt16, SInt16, Boolean); + +void DoGameOver (void); // --- GameOver.c +void FlagGameOver (void); +void DoDiedGameOver (void); + +void HandleGrease (void); // --- Grease.c +SInt16 ReBackUpGrease (SInt16, SInt16); +SInt16 AddGrease (SInt16, SInt16, SInt16, SInt16, SInt16, Boolean); +void SpillGrease (SInt16, SInt16); +void RedrawAllGrease (void); + +void DoHighScores (void); // --- HighScores.c +void SortHighScores (void); +void ZeroHighScores (void); +void ZeroAllButHighestScore (void); +Boolean TestHighScore (void); +Boolean WriteScoresToDisk (void); +Boolean ReadScoresFromDisk (void); + +Boolean CreateNewHouse (void); // --- House.c +Boolean InitializeEmptyHouse (void); +SInt16 RealRoomNumberCount (void); +SInt16 GetFirstRoomNumber (void); +void WhereDoesGliderBegin (Rect *, SInt16); +Boolean HouseHasOriginalPicts (void); +SInt16 CountHouseLinks (void); +void GenerateLinksList (void); +void SortRoomsObjects (SInt16); +void SortHouseObjects (void); +SInt16 CountRoomsVisited (void); +void GenerateRetroLinks (void); +void DoGoToDialog (void); +void ConvertHouseVer1To2 (void); +void ShiftWholeHouse (SInt16); + +void DoHouseInfo (void); // --- HouseInfo.c + +Boolean OpenHouse (void); // --- HouseIO.c +Boolean OpenSpecificHouse (FSSpec *); +Boolean SaveHouseAs (void); +Boolean ReadHouse (void); +Boolean WriteHouse (Boolean); +Boolean CloseHouse (void); +void OpenHouseResFork (void); +void CloseHouseResFork (void); +Boolean QuerySaveChanges (void); +void YellowAlert (SInt16, SInt16); + +Boolean KeepObjectLegal (void); // --- HouseLegal.c +void CheckHouseForProblems (void); + +Boolean SectGlider (gliderPtr, Rect *, Boolean); // --- Interactions.c +void HandleSwitches (hotPtr); +void HandleInteraction (void); +void FlagStillOvers (gliderPtr); + +void InitializeMenus (void); // --- InterfaceInit.c +void GetExtraCursors (void); +void VariableInit (void); + +void GetDemoInput (gliderPtr); // --- Input.c +void GetInput (gliderPtr); + +SInt16 MergeFloorSuite (SInt16, SInt16); // --- Link.c +void ExtractFloorSuite (SInt16, SInt16 *, SInt16 *); +void UpdateLinkControl (void); +void UpdateLinkWindow (void); +void OpenLinkWindow (void); +void CloseLinkWindow (void); +void HandleLinkClick (Point); + +void RedrawSplashScreen (void); // --- MainWindow.c +void UpdateMainWindow (void); +void UpdateMenuBarWindow (void); +void OpenMainWindow (void); +void CloseMainWindow (void); +void ZoomBetweenWindows (void); +void UpdateEditWindowTitle (void); +void HandleMainClick (Point, Boolean); +//void WashColorIn (void); + +void CenterMapOnRoom (SInt16, SInt16); // --- Map.c +Boolean ThisRoomVisibleOnMap (void); +void FindNewActiveRoomRect (void); +void FlagMapRoomsForUpdate (void); +void UpdateMapWindow (void); +void ResizeMapWindow (SInt16, SInt16); +void OpenMapWindow (void); +void CloseMapWindow (void); +void ToggleMapWindow (void); +void HandleMapClick (EventRecord *); +void MoveRoom (Point); + +void DoMarquee (void); // --- Marquee.c +void StartMarquee (Rect *); +void StartMarqueeHandled (Rect *, SInt16, SInt16); +void StopMarquee (void); +void PauseMarquee (void); +void ResumeMarquee (void); +void DragOutMarqueeRect (Point, Rect *); +void DragMarqueeRect (Point, Rect *, Boolean, Boolean); +void DragMarqueeHandle (Point, SInt16 *); +void DragMarqueeCorner (Point, SInt16 *, SInt16 *, Boolean); +Boolean MarqueeHasHandles (SInt16 *, SInt16 *); +Boolean PtInMarqueeHandle (Point); +void SetMarqueeGliderRect (SInt16, SInt16); +void InitMarquee (void); + +void UpdateClipboardMenus (void); // --- Menu.c +void DoAppleMenu (SInt16); +void DoGameMenu (SInt16); +void DoOptionsMenu (SInt16); +void DoHouseMenu (SInt16); +void DoMenuChoice (long); +void UpdateMenus (Boolean); +void UpdateMapCheckmark (Boolean); +void UpdateToolsCheckmark (Boolean); +void UpdateCoordinateCheckmark (Boolean); +#ifdef COMPILEDEMO +void DoNotInDemo (void); +#endif +void OpenCloseEditWindows (void); + +void StartGliderFadingIn (gliderPtr); // --- Modes.c +void StartGliderTransportingIn (gliderPtr); +void StartGliderFadingOut (gliderPtr); +void StartGliderGoingUpStairs (gliderPtr); +void StartGliderGoingDownStairs (gliderPtr); +void StartGliderMailingIn (gliderPtr, Rect *, hotPtr); +void StartGliderMailingOut (gliderPtr); +void StartGliderDuctingDown (gliderPtr, Rect *, hotPtr); +void StartGliderDuctingUp (gliderPtr, Rect *, hotPtr); +void StartGliderDuctingIn (gliderPtr); +void StartGliderTransporting (gliderPtr, hotPtr); +void FlagGliderNormal (gliderPtr); +void FlagGliderShredding (gliderPtr, Rect *); +void FlagGliderBurning (gliderPtr); +void FlagGliderFaceLeft (gliderPtr); +void FlagGliderFaceRight (gliderPtr); +void FlagGliderInLimbo (gliderPtr, Boolean); +void UndoGliderLimbo (gliderPtr); +void ToggleGliderFacing (gliderPtr); +void InsureGliderFacingRight (gliderPtr); +void InsureGliderFacingLeft (gliderPtr); +void ReadyGliderForTripUpStairs (gliderPtr); +void ReadyGliderForTripDownStairs (gliderPtr); +void StartGliderFoilGoing (gliderPtr); +void StartGliderFoilLosing (gliderPtr); +void TagGliderIdle (gliderPtr); + +OSErr StartMusic (void); // --- Music.c +void StopTheMusic (void); +void ToggleMusicWhilePlaying (void); +void SetMusicalMode (SInt16); +void InitMusic (void); +void KillMusic (void); +long MusicBytesNeeded (void); +void TellHerNoMusic (void); + +Boolean AddNewObject (Point, SInt16, Boolean); // --- ObjectAdd.c +SInt16 FindObjectSlotInRoom (SInt16); +Boolean DoesRoomNumHaveObject (SInt16, SInt16); +void ShoutNoMoreObjects (void); + +void DrawSimpleBlowers (SInt16, Rect *); // --- ObjectDraw.c +void DrawTiki (Rect *, SInt16); +void DrawInvisibleBlower (Rect *); +void DrawLiftArea (Rect *); +void DrawTable (Rect *, SInt16); +void DrawShelf (Rect *); +void DrawCabinet (Rect *); +void DrawSimpleFurniture (SInt16, Rect *); +void DrawCounter (Rect *); +void DrawDresser (Rect *); +void DrawDeckTable (Rect *, SInt16); +void DrawStool (Rect *, SInt16); +void DrawInvisObstacle (Rect *); +void DrawInvisBounce (Rect *); +void DrawRedClock (Rect *); +void DrawBlueClock (Rect *); +void DrawYellowClock (Rect *); +void DrawCuckoo (Rect *); +void DrawSimplePrizes (SInt16, Rect *); +void DrawGreaseRt (Rect *, SInt16, Boolean); +void DrawGreaseLf (Rect *, SInt16, Boolean); +void DrawFoil (Rect *); +void DrawInvisBonus (Rect *); +void DrawSlider (Rect *); + +void DrawMailboxLeft (Rect *, SInt16); // --- ObjectDraw2.c +void DrawMailboxRight (Rect *, SInt16); +void DrawSimpleTransport (SInt16, Rect *); +void DrawInvisTransport (Rect *); +void DrawLightSwitch (Rect *, Boolean); +void DrawMachineSwitch (Rect *, Boolean); +void DrawThermostat (Rect *, Boolean); +void DrawPowerSwitch (Rect *, Boolean); +void DrawKnifeSwitch (Rect *, Boolean); +void DrawInvisibleSwitch (Rect *); +void DrawTrigger (Rect *); +void DrawSoundTrigger (Rect *); +void DrawSimpleLight (SInt16, Rect *); +void DrawFlourescent (Rect *); +void DrawSimpleAppliance (SInt16, Rect *); +void DrawMacPlus (Rect *, Boolean, Boolean); +void DrawTrackLight (Rect *); +void DrawInvisLight (Rect *); +void DrawTV (Rect *, Boolean, Boolean); +void DrawCoffee (Rect *, Boolean, Boolean); +void DrawOutlet (Rect *); +void DrawVCR (Rect *, Boolean, Boolean); +void DrawStereo (Rect *, Boolean, Boolean); +void DrawMicrowave (Rect *, Boolean, Boolean); +void DrawBalloon (Rect *); +void DrawCopter (Rect *); +void DrawDart (Rect *, SInt16); +void DrawBall (SInt16, Rect *); +void DrawFish (SInt16, Rect *); +void DrawDrip (Rect *); +void DrawMirror (Rect *); +void DrawSimpleClutter (SInt16, Rect *); +void DrawFlower (Rect *, SInt16); +void DrawWallWindow (Rect *); +void DrawCalendar (Rect *); +void DrawBulletin (Rect *); +void DrawPictObject (SInt16, Rect *); +void DrawPictWithMaskObject (SInt16, Rect *); +void DrawPictSansWhiteObject (SInt16, Rect *); +void DrawCustPictSansWhite (SInt16, Rect *); + +void DrawARoomsObjects (SInt16, Boolean); // --- ObjectDrawAll.c + +void DoSelectionClick (Point, Boolean); // --- ObjectEdit.c +void DoNewObjectClick (Point); +void DeleteObject (void); +void DuplicateObject (void); +void MoveObject (SInt16, Boolean); +void DeselectObject (void); +Boolean ObjectHasHandle (SInt16 *, SInt16 *); +void HandleBlowerGlider (void); +void SelectNextObject (void); +void SelectPrevObject (void); +void GetThisRoomsObjRects (void); +void DrawThisRoomsObjects (void); +void HiliteAllObjects (void); +void GoToObjectInRoom (SInt16, SInt16, SInt16); +void GoToObjectInRoomNum (SInt16, SInt16); + +void DoObjectInfo (void); // --- ObjectInfo.c + +void GetObjectRect (objectPtr, Rect *); // --- ObjectRects.c +SInt16 CreateActiveRects (SInt16); +SInt16 VerticalRoomOffset (SInt16); +void OffsetRectRoomRelative (Rect *, SInt16); +SInt16 GetUpStairsRightEdge (void); +SInt16 GetDownStairsLeftEdge (void); + +SInt16 GetRoomLinked (objectType *); // --- Objects.c +Boolean ObjectIsLinkTransport (objectType *); +Boolean ObjectIsLinkSwitch (objectType *); +void ListAllLocalObjects (void); +Boolean SetObjectState (SInt16, SInt16, SInt16, SInt16); +Boolean GetObjectState (SInt16, SInt16); +void BringSendFrontBack (Boolean); +Boolean IsThisValid (SInt16, SInt16); +void AddTempManholeRect (Rect *); + +void NewGame (SInt16); // --- Play.c +void DoDemoGame (void); +void HideGlider (gliderPtr); +void StrikeChime (void); +void RestoreEntireGameScreen (void); + +void HandleGlider (gliderPtr); // --- Player.c +void FinishGliderUpStairs (gliderPtr); +void FinishGliderDownStairs (gliderPtr); +void FinishGliderDuctingIn (gliderPtr); +void DeckGliderInFoil (gliderPtr); +void RemoveFoilFromGlider (gliderPtr); +void OffsetGlider (gliderPtr, SInt16); +void OffAMortal (gliderPtr); + +void AddRectToWorkRects (Rect *); // --- Render.c +void AddRectToBackRects (Rect *); +void AddRectToWorkRectsWhole (Rect *); +void RenderGlider (gliderPtr, Boolean); +void CopyRectsQD (void); +void DirectWork2Main8 (Rect *); +void DirectBack2Work8 (Rect *); +void DirectGeneric2Work8 (long, long, Rect *, Rect *); +void DirectWork2Main4 (Rect *); +void DirectBack2Work4 (Rect *); +void DirectGeneric2Work4 (long, long, Rect *, Rect *); +void CopyRectsAssm (void); +void DirectFillBack8 (Rect *, Byte); +void DirectFillWork8 (Rect *, Byte); +void DirectFillBack4 (Rect *, Byte); +void DirectFillWork4 (Rect *, Byte); +void RenderFrame (void); +void InitGarbageRects (void); +void CopyRectBackToWork (Rect *); +void CopyRectWorkToBack (Rect *); +void CopyRectWorkToMain (Rect *); +void CopyRectMainToWork (Rect *); +void CopyRectMainToBack (Rect *); +void AddToMirrorRegion (Rect *); +void ZeroMirrorRegion (void); + +void SetInitialTiles (SInt16, Boolean); // --- Room.c +Boolean CreateNewRoom (SInt16, SInt16); +void DoRoomInfo (void); +void ReadyBackground (SInt16, SInt16 *); +void ReflectCurrentRoom (Boolean); +void CopyRoomToThisRoom (SInt16); +void CopyThisRoomToRoom (void); +void ForceThisRoom (SInt16); +Boolean RoomExists (SInt16, SInt16, SInt16 *); +Boolean RoomNumExists (SInt16); +void DeleteRoom (Boolean); +SInt16 DoesNeighborRoomExist (SInt16); +void SelectNeighborRoom (SInt16); +SInt16 GetNeighborRoomNumber (SInt16); +Boolean GetRoomFloorSuite (SInt16, SInt16 *, SInt16 *); +SInt16 GetRoomNumber (SInt16, SInt16); +Boolean IsRoomAStructure (SInt16); +void DetermineRoomOpenings (void); +SInt16 GetOriginalBounding (SInt16); +SInt16 GetNumberOfLights (SInt16); +Boolean IsShadowVisible (void); +Boolean DoesRoomHaveFloor (void); +Boolean DoesRoomHaveCeiling (void); + +void ReadyLevel (void); // --- RoomGraphics.c +void DrawLocale (void); +void RedrawRoomLighting (void); + +Boolean PictIDExists (SInt16); // --- RoomInfo.c + +void HandleBands (void); // --- RubberBands.c +Boolean AddBand (gliderPtr, SInt16, SInt16, Boolean); +void KillAllBands (void); + +void SaveGame2 (void); // --- SavedGames.c +Boolean OpenSavedGame (void); +void SaveGame (Boolean); + +void RefreshScoreboard (SInt16); // --- Scoreboard.c +void HandleDynamicScoreboard (void); +void QuickGlidersRefresh (void); +void QuickScoreRefresh (void); +void QuickBatteryRefresh (Boolean); +void QuickBandsRefresh (Boolean); +void QuickFoilRefresh (Boolean); +void HandleScore (void); +void AdjustScoreboardHeight (void); +void BlackenScoreboard (void); + +//void PutRoomScrap (void); // --- Scrap.c +//void PutObjectScrap (void); +void GetRoomScrap (void); +void GetObjectScrap (void); +//void SeeIfValidScrapAvailable (Boolean); +Boolean HasDragManager (void); +//Boolean DragRoom (EventRecord *, Rect *, SInt16); + +void DoLoadHouse (void); // --- SelectHouse.c +void BuildHouseList (void); +void AddExtraHouse (FSSpec *); + +void DoSettingsMain (void); // --- Settings.c + +void PlayPrioritySound (SInt16, SInt16); // --- Sound.c +void FlushAnyTriggerPlaying (void); +void PlaySound0 (SInt16, SInt16); +void PlaySound1 (SInt16, SInt16); +void PlaySound2 (SInt16, SInt16); +OSErr LoadTriggerSound (SInt16); +void DumpTriggerSound (void); +void InitSound (void); +void KillSound (void); +long SoundBytesNeeded (void); +void TellHerNoSounds (void); +void BitchAboutSM3 (void); + +void InitScoreboardMap (void); // --- StructuresInit.c +void InitGliderMap (void); +void InitBlowers (void); +void InitFurniture (void); +void InitPrizes (void); +void InitTransports (void); +void InitSwitches (void); +void InitLights (void); +void InitAppliances (void); +void InitEnemies (void); + +void CreateOffscreens (void); // --- StructuresInit2.c +void CreatePointers (void); +void InitSrcRects (void); + +void UpdateToolsWindow (void); // --- Tools.c +void EraseSelectedTool (void); +void SelectTool (SInt16); +void OpenToolsWindow (void); +void CloseToolsWindow (void); +void ToggleToolsWindow (void); +void HandleToolsClick (Point); +void NextToolMode (void); +void PrevToolMode (void); +void SetSpecificToolMode (SInt16); + +SInt16 WhatAreWeLinkedTo (SInt16, Byte); // --- Transit.c +void ReadyGliderFromTransit (gliderPtr, SInt16); +void MoveRoomToRoom (gliderPtr, SInt16); +void TransportRoomToRoom (gliderPtr); +void MoveDuctToDuct (gliderPtr); +void MoveMailToMail (gliderPtr); +void ForceKillGlider (void); +void FollowTheLeader (void); + +void PourScreenOn (Rect *); // --- Transitions.c +void WipeScreenOn (SInt16, Rect *); +void DumpScreenOn (Rect *); +//void DissBits (Rect *); +//void DissBitsChunky (Rect *); +//void FillColorNoise (Rect *); +//void FillSnow (Rect *); + +void ToggleToaster (SInt16); // --- Trip.c +void ToggleMacPlus (SInt16); +void ToggleTV (SInt16); +void ToggleCoffee (SInt16); +void ToggleOutlet (SInt16); +void ToggleVCR (SInt16); +void ToggleStereos (SInt16); +void ToggleMicrowave (SInt16); +void ToggleBalloon (SInt16); +void ToggleCopter (SInt16); +void ToggleDart (SInt16); +void ToggleBall (SInt16); +void ToggleDrip (SInt16); +void ToggleFish (SInt16); +void TriggerSwitch (SInt16); +void TriggerToast (SInt16); +void TriggerOutlet (SInt16); +void TriggerDrip (SInt16); +void TriggerFish (SInt16); +void TriggerBalloon (SInt16); +void TriggerCopter (SInt16); +void TriggerDart (SInt16); +void UpdateOutletsLighting (SInt16, SInt16); + +void ArmTrigger (hotPtr); // --- Triggers.c +void HandleTriggers (void); +void ZeroTriggers (void); + diff --git a/GpApp/GliderStructs.h b/GpApp/GliderStructs.h new file mode 100644 index 0000000..3c569ba --- /dev/null +++ b/GpApp/GliderStructs.h @@ -0,0 +1,347 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// GliderStructs.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +typedef struct +{ + Point topLeft; // 4 + short distance; // 2 + Boolean initial; // 1 + Boolean state; // 1 F. lf. dn. rt. up + Byte vector; // 1 | x | x | x | x | 8 | 4 | 2 | 1 | + Byte tall; // 1 +} blowerType; // total = 10 + +typedef struct +{ + Rect bounds; // 8 + short pict; // 2 +} furnitureType; // total = 10 + +typedef struct +{ + Point topLeft; // 4 + short length; // 2 grease spill + short points; // 2 invis bonus + Boolean state; // 1 + Boolean initial; // 1 +} bonusType; // total = 10 + +typedef struct +{ + Point topLeft; // 4 + short tall; // 2 invis transport + short where; // 2 + Byte who; // 1 + Byte wide; // 1 +} transportType; // total = 10 + +typedef struct +{ + Point topLeft; // 4 + short delay; // 2 + short where; // 2 + Byte who; // 1 + Byte type; // 1 +} switchType; // total = 10 + +typedef struct +{ + Point topLeft; // 4 + short length; // 2 + Byte byte0; // 1 + Byte byte1; // 1 + Boolean initial; // 1 + Boolean state; // 1 +} lightType; // total = 10 + +typedef struct +{ + Point topLeft; // 4 + short height; // 2 toaster, pict ID + Byte byte0; // 1 + Byte delay; // 1 + Boolean initial; // 1 + Boolean state; // 1 +} applianceType; // total = 10 + +typedef struct +{ + Point topLeft; // 4 + short length; // 2 + Byte delay; // 1 + Byte byte0; // 1 + Boolean initial; // 1 + Boolean state; // 1 +} enemyType; // total = 10 + +typedef struct +{ + Rect bounds; // 8 + short pict; // 2 +} clutterType; // total = 10 + +typedef struct +{ + short what; // 2 + union + { + blowerType a; + furnitureType b; + bonusType c; + transportType d; + switchType e; + lightType f; + applianceType g; + enemyType h; + clutterType i; + } data; // 10 +} objectType, *objectPtr; // total = 12 + +typedef struct +{ + Str31 banner; // 32 = 32 + Str15 names[kMaxScores]; // 16 * 10 = 160 + Int32 scores[kMaxScores]; // 4 * 10 = 40 + UInt32 timeStamps[kMaxScores]; // 4 * 10 = 40 + short levels[kMaxScores]; // 2 * 10 = 20 +} scoresType; // total = 292 + +typedef struct +{ + short version; // 2 + short wasStarsLeft; // 2 + UInt32 timeStamp; // 4 + Point where; // 4 + Int32 score; // 4 + Int32 unusedLong; // 4 + Int32 unusedLong2; // 4 + short energy; // 2 + short bands; // 2 + short roomNumber; // 2 + short gliderState; // 2 + short numGliders; // 2 + short foil; // 2 + short unusedShort; // 2 + Boolean facing; // 1 + Boolean showFoil; // 1 +} gameType; // total = 40 + +typedef struct +{ + short unusedShort; // 2 + Byte unusedByte; // 1 + Boolean visited; // 1 + objectType objects[kMaxRoomObs]; // 24 * 12 +} savedRoom, *saveRoomPtr; // total = 292 + +typedef struct +{ + FSSpec house; // 70 + short version; // 2 + short wasStarsLeft; // 2 + long timeStamp; // 4 + Point where; // 4 + long score; // 4 + long unusedLong; // 4 + long unusedLong2; // 4 + short energy; // 2 + short bands; // 2 + short roomNumber; // 2 + short gliderState; // 2 + short numGliders; // 2 + short foil; // 2 + short nRooms; // 2 + Boolean facing; // 1 + Boolean showFoil; // 1 + savedRoom savedData[1]; // 4 +} game2Type, *gamePtr; // total = 114 + +typedef struct +{ + Str27 name; // 28 + short bounds; // 2 + Byte leftStart; // 1 + Byte rightStart; // 1 + Byte unusedByte; // 1 + Boolean visited; // 1 + short background; // 2 + short tiles[kNumTiles]; // 2 * 8 + short floor, suite; // 2 + 2 + short openings; // 2 + short numObjects; // 2 + objectType objects[kMaxRoomObs]; // 24 * 12 +} roomType, *roomPtr; // total = 348 + +typedef struct +{ + short version; // 2 + short unusedShort; // 2 + long timeStamp; // 4 + long flags; // 4 (bit 0 = wardBit) + Point initial; // 4 + Str255 banner; // 256 + Str255 trailer; // 256 + scoresType highScores; // 292 + gameType savedGame; // 40 + Boolean hasGame; // 1 + Boolean unusedBoolean; // 1 + short firstRoom; // 2 + short nRooms; // 2 + roomType rooms[1]; // 348 * nRooms +} houseType, *housePtr, **houseHand; // total = 866 + + +typedef struct +{ + Rect src, mask, dest, whole; + Rect destShadow, wholeShadow; + Rect clip, enteredRect; + Int32 leftKey, rightKey; + Int32 battKey, bandKey; + short hVel, vVel; + short wasHVel, wasVVel; + short vDesiredVel, hDesiredVel; + short mode, frame, wasMode; + Boolean facing, tipped; + Boolean sliding, ignoreLeft, ignoreRight; + Boolean fireHeld, which; + Boolean heldLeft, heldRight; + Boolean dontDraw, ignoreGround; +} gliderType, *gliderPtr; + +typedef struct +{ + Rect bounds; + short action; + short who; + Boolean isOn, stillOver; + Boolean doScrutinize; +} hotObject, *hotPtr; + +typedef struct +{ + Rect dest; + GWorldPtr map; + short where; + short who; +} savedType, *savedPtr; + +typedef struct +{ + Rect bounds; + short mode; +} sparkleType, *sparklePtr; + +typedef struct +{ + Rect dest, whole; + short start; + short stop; + short mode; + short loops; + short hVel, vVel; +} flyingPtType, *flyingPtPtr; + +typedef struct +{ + Rect dest, src; + short mode; + short who; +} flameType, *flamePtr; + +typedef struct +{ + Rect dest, src; + short mode, where; + short who, link; + Boolean toOrFro, active; +} pendulumType, *pendulumPtr; + +typedef struct +{ + Boolean left; + Boolean top; + Boolean right; + Boolean bottom; +} boundsType, *boundsPtr, **boundsHand; + +typedef struct +{ + Rect dest; + short mode, count; + short hVel, vVel; +} bandType, *bandPtr; + +typedef struct +{ + short srcRoom, srcObj; + short destRoom, destObj; +} linksType, *linksPtr; + +typedef struct +{ + Rect dest; + short mapNum, mode; + short who, where; + short start, stop; + short frame, hotNum; + Boolean isRight; +} greaseType, *greasePtr; + +typedef struct +{ + Rect dest, src; + short mode, who; + short link, where; +} starType, *starPtr; + +typedef struct +{ + Rect bounds; + short frame; +} shredType, *shredPtr; + +typedef struct +{ + Rect dest; + Rect whole; + short hVel, vVel; + short type, count; + short frame, timer; + short position, room; + Byte byte0, byte1; + Boolean moving, active; +} dynaType, *dynaPtr; + +typedef struct +{ + short roomNum; // room # object in (real number) + short objectNum; // obj. # in house (real number) + short roomLink; // room # object linked to (if any) + short objectLink; // obj. # object linked to (if any) + short localLink; // index in master list if exists + short hotNum; // index into active rects (if any) + short dynaNum; // index into dinahs (if any) + objectType theObject; // actual object data +} objDataType, *objDataPtr; + +typedef struct +{ + Int32 frame; + char key; + char padding; +} demoType, *demoPtr; + +typedef struct +{ + short room; + short object; +} retroLink, *retroLinkPtr; + + diff --git a/GpApp/GliderVars.h b/GpApp/GliderVars.h new file mode 100644 index 0000000..5c5285e --- /dev/null +++ b/GpApp/GliderVars.h @@ -0,0 +1,59 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// GliderVars.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLMovies.h" + + +extern Rect blowerSrcRect; +extern Rect flame[], tikiFlame[]; +extern Rect coals[]; +extern Rect furnitureSrcRect; +extern Rect tableSrc, shelfSrc, hingeSrc, handleSrc, knobSrc; +extern Rect leftFootSrc, rightFootSrc, deckSrc; +extern Rect bonusSrcRect; +extern Rect pointsSrcRect; +extern Rect starSrc[], sparkleSrc[]; +extern Rect digits[], pendulumSrc[], greaseSrcRt[], greaseSrcLf[]; +extern Rect transSrcRect; +extern Rect switchSrcRect; +extern Rect lightSwitchSrc[], machineSwitchSrc[], thermostatSrc[]; +extern Rect powerSrc[], knifeSwitchSrc[]; +extern Rect lightSrcRect; +extern Rect flourescentSrc1, flourescentSrc2; +extern Rect trackLightSrc[]; +extern Rect applianceSrcRect, toastSrcRect, shredSrcRect; // Appliances +extern Rect plusScreen1, plusScreen2, tvScreen1, tvScreen2; +extern Rect coffeeLight1, coffeeLight2, vcrTime1, vcrTime2; +extern Rect stereoLight1, stereoLight2, microOn, microOff; +extern Rect outletSrc[]; +extern Rect balloonSrcRect, copterSrcRect, dartSrcRect; // Enemies +extern Rect ballSrcRect, dripSrcRect, enemySrcRect; +extern Rect fishSrcRect; +extern Rect balloonSrc[], copterSrc[], dartSrc[]; +extern Rect ballSrc[], dripSrc[], fishSrc[]; +extern Rect clutterSrcRect; +extern Rect flowerSrc[]; +extern Rect *srcRects; + +extern Movie theMovie; +extern Rect movieRect; +extern Boolean hasMovie, tvInRoom; + +extern gliderType theGlider, theGlider2; +extern objDataPtr masterObjects; +extern Rect workSrcRect; +extern Rect backSrcRect; +extern Rect mainWindowRect, houseRect; +extern houseHand thisHouse; +extern roomPtr thisRoom; +extern WindowPtr mainWindow, coordWindow; +extern long theScore; +extern short playOriginH, playOriginV; +extern short thisRoomNumber, theMode, batteryTotal, bandsTotal; +extern short foilTotal, mortals, numMasterObjects, previousRoom; +extern Boolean fileDirty, gameDirty, showFoil, doZooms, isPlayMusicGame; + diff --git a/GpApp/GpApp.props b/GpApp/GpApp.props new file mode 100644 index 0000000..b82aa3f --- /dev/null +++ b/GpApp/GpApp.props @@ -0,0 +1,12 @@ + + + + + + + + GP_APP_DLL;GP_APP_DLL_EXPORT;%(PreprocessorDefinitions) + + + + \ No newline at end of file diff --git a/GpApp/GpApp.vcxproj b/GpApp/GpApp.vcxproj new file mode 100644 index 0000000..b492b47 --- /dev/null +++ b/GpApp/GpApp.vcxproj @@ -0,0 +1,204 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {6233C3F2-5781-488E-B190-4FA8836F5A77} + GpApp + 10.0.17763.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + DynamicLibrary + true + v141 + MultiByte + + + DynamicLibrary + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {6ec62b0f-9353-40a4-a510-3788f1368b33} + + + + + + \ No newline at end of file diff --git a/GpApp/GpApp.vcxproj.filters b/GpApp/GpApp.vcxproj.filters new file mode 100644 index 0000000..10d281f --- /dev/null +++ b/GpApp/GpApp.vcxproj.filters @@ -0,0 +1,214 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/GpApp/GpAppInterface.cpp b/GpApp/GpAppInterface.cpp new file mode 100644 index 0000000..cf166ab --- /dev/null +++ b/GpApp/GpAppInterface.cpp @@ -0,0 +1,57 @@ +#include "GpAppInterface.h" + +#include "DisplayDeviceManager.h" +#include "HostFileSystem.h" +#include "HostDisplayDriver.h" +#include "HostSystemServices.h" + +int gpAppMain(); + +class GpAppInterfaceImpl final : public GpAppInterface +{ +public: + int ApplicationMain() override; + void PL_IncrementTickCounter(uint32_t count) override; + void PL_HostFileSystem_SetInstance(PortabilityLayer::HostFileSystem *instance) override; + void PL_HostDisplayDriver_SetInstance(PortabilityLayer::HostDisplayDriver *instance) override; + void PL_HostSystemServices_SetInstance(PortabilityLayer::HostSystemServices *instance) override; + void PL_InstallHostSuspendHook(PortabilityLayer::HostSuspendHook_t hook, void *context) override; +}; + + +int GpAppInterfaceImpl::ApplicationMain() +{ + return gpAppMain(); +} + +void GpAppInterfaceImpl::PL_IncrementTickCounter(uint32_t count) +{ + PortabilityLayer::DisplayDeviceManager::GetInstance()->IncrementTickCount(count); +} + +void GpAppInterfaceImpl::PL_HostFileSystem_SetInstance(PortabilityLayer::HostFileSystem *instance) +{ + PortabilityLayer::HostFileSystem::SetInstance(instance); +} + +void GpAppInterfaceImpl::PL_HostDisplayDriver_SetInstance(PortabilityLayer::HostDisplayDriver *instance) +{ + PortabilityLayer::HostDisplayDriver::SetInstance(instance); +} + +void GpAppInterfaceImpl::PL_HostSystemServices_SetInstance(PortabilityLayer::HostSystemServices *instance) +{ + PortabilityLayer::HostSystemServices::SetInstance(instance); +} + +void GpAppInterfaceImpl::PL_InstallHostSuspendHook(PortabilityLayer::HostSuspendHook_t hook, void *context) +{ + PortabilityLayer::InstallHostSuspendHook(hook, context); +} + +static GpAppInterfaceImpl gs_application; + +extern "C" GpAppInterface *GpAppInterface_Get() +{ + return &gs_application; +} diff --git a/GpApp/Grease.cpp b/GpApp/Grease.cpp new file mode 100644 index 0000000..8a04045 --- /dev/null +++ b/GpApp/Grease.cpp @@ -0,0 +1,302 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Grease.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Environ.h" +#include "MainWindow.h" +#include "Objects.h" +#include "RectUtils.h" +#include "Room.h" + + +#define kGreaseIdle 0 +#define kGreaseFalling 1 +#define kGreaseSpreading 2 +#define kGreaseSpiltIdle 3 + + +void BackupGrease (Rect *, short, Boolean); + + +greasePtr grease; +short numGrease; + +extern hotPtr hotSpots; +extern savedType savedMaps[]; +extern Point shieldPt; +extern Rect greaseSrcRt[], greaseSrcLf[], shieldRect; + + +//============================================================== Functions +//-------------------------------------------------------------- HandleGrease + +// Goes through all grease objects currently on screen and handlesÉ +// them. If they're upright, nothing happens, but if they're inÉ +// the course of falling or spilling, this function will handleÉ +// advancing the spill, etc. + +void HandleGrease (void) +{ + Rect src; + short i; + + if (numGrease == 0) + return; + + for (i = 0; i < numGrease; i++) + { + if (grease[i].mode == kGreaseFalling) + { + grease[i].frame++; + if (grease[i].frame >= 3) // grease completely tipped + { + grease[i].frame = 3; + grease[i].mode = kGreaseSpreading; + hotSpots[grease[i].hotNum].action = kSlideIt; + hotSpots[grease[i].hotNum].isOn = true; + if (grease[i].isRight) + QSetRect(&src, 0, -2, 2, 0); + else + QSetRect(&src, -2, -2, 0, 0); + QOffsetRect(&src, -playOriginH, -playOriginV); + QOffsetRect(&src, grease[i].start, grease[i].dest.bottom); + hotSpots[grease[i].hotNum].bounds = src; + } + + QSetRect(&src, 0, 0, 32, 27); + QOffsetRect(&src, 0, grease[i].frame * 27); + CopyBits((BitMap *)*GetGWorldPixMap(savedMaps[grease[i].mapNum].map), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &src, &grease[i].dest, + srcCopy, nil); + CopyBits((BitMap *)*GetGWorldPixMap(savedMaps[grease[i].mapNum].map), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &src, &grease[i].dest, + srcCopy, nil); + + AddRectToWorkRects(&grease[i].dest); + if (grease[i].isRight) + QOffsetRect(&grease[i].dest, 2, 0); + else + QOffsetRect(&grease[i].dest, -2, 0); + } + else if (grease[i].mode == kGreaseSpreading) + { + if (grease[i].isRight) + { + QSetRect(&src, 0, -2, 2, 0); + QOffsetRect(&src, grease[i].start, grease[i].dest.bottom); + grease[i].start += 2; + hotSpots[grease[i].hotNum].bounds.right += 2; + } + else + { + QSetRect(&src, -2, -2, 0, 0); + QOffsetRect(&src, grease[i].start, grease[i].dest.bottom); + grease[i].start -= 2; + hotSpots[grease[i].hotNum].bounds.left -= 2; + } + + { + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + + SetGWorld(backSrcMap, nil); + PaintRect(&src); + + SetGWorld(workSrcMap, nil); + PaintRect(&src); + AddRectToWorkRects(&src); + + SetGWorld(wasCPort, wasWorld); + } + + if (grease[i].isRight) + { + if (grease[i].start >= grease[i].stop) + grease[i].mode = kGreaseSpiltIdle; + } + else + { + if (grease[i].start <= grease[i].stop) + grease[i].mode = kGreaseSpiltIdle; + } + } + } +} + +//-------------------------------------------------------------- BackupGrease +// This makes copies of the region of the screen the grease is aboutÉ +// to be drawn to. It is called in the "set up" when a player hasÉ +// just entered a new room. The "grease jar falling over" animationÉ +// is set up here. + +void BackupGrease (Rect *src, short index, Boolean isRight) +{ + Rect dest; + short i; + + QSetRect(&dest, 0, 0, 32, 27); + for (i = 0; i < 4; i++) + { + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + (BitMap *)*GetGWorldPixMap(savedMaps[index].map), + src, &dest, srcCopy, nil); + + if (isRight) + { + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(savedMaps[index].map), + &greaseSrcRt[i], &greaseSrcRt[i], &dest); + QOffsetRect(src, 2, 0); + } + else + { + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(savedMaps[index].map), + &greaseSrcLf[i], &greaseSrcLf[i], &dest); + QOffsetRect(src, -2, 0); + } + QOffsetRect(&dest, 0, 27); + } + +} + +//-------------------------------------------------------------- ReBackUpGrease +// Just like th eabove function but it is called while the player isÉ +// active in a room and has changed the lighting situation (like turnedÉ +// off or on the lights). It assumes certain data strucutures areÉ +// already declared from an earlier call to the above funciton. + +short ReBackUpGrease (short where, short who) +{ + Rect src; + short i; + + for (i = 0; i < numGrease; i++) + { + if ((grease[i].where == where) && (grease[i].who == who)) + { + if ((grease[i].mode == kGreaseIdle) || (grease[i].mode == kGreaseFalling)) + { + src = grease[i].dest; + BackupGrease(&src, grease[i].mapNum, grease[i].isRight); + } + return (i); + } + } + + return (-1); +} + +//-------------------------------------------------------------- AddGrease + +// Called when a new room is being set up during a game. This addsÉ +// another jar of grease to the queue of jars to be handled. + +short AddGrease (short where, short who, short h, short v, + short distance, Boolean isRight) +{ + Rect src, bounds; + short savedNum; + + if (numGrease >= kMaxGrease) + return (-1); + + QSetRect(&src, 0, 0, 32, 27); + QOffsetRect(&src, h, v); + + QSetRect(&bounds, 0, 0, 32, 27 * 4); + savedNum = BackUpToSavedMap(&bounds, where, who); + if (savedNum != -1) + { + BackupGrease (&src, savedNum, isRight); + if (isRight) + QOffsetRect(&src, -8, 0); + else + QOffsetRect(&src, 8, 0); + grease[numGrease].who = who; + grease[numGrease].where = where; + grease[numGrease].dest = src; + grease[numGrease].mapNum = savedNum; + grease[numGrease].mode = kGreaseIdle; + grease[numGrease].frame = -1; + if (isRight) + { + grease[numGrease].isRight = true; + grease[numGrease].start = src.right + 4; + grease[numGrease].stop = src.right + distance; + } + else + { + grease[numGrease].isRight = false; + grease[numGrease].start = src.left - 4; + grease[numGrease].stop = src.left - distance; + } + numGrease++; + + return (numGrease - 1); + } + else + return (-1); +} + +//-------------------------------------------------------------- SpillGrease + +// A player has knocked a jar of grease over - this function flags that. + +void SpillGrease (short who, short index) +{ + if (grease[who].mode == kGreaseIdle) + { + grease[who].mode = kGreaseFalling; + grease[who].hotNum = index; + PlayPrioritySound(kGreaseSpillSound, kGreaseSpillPriority); + } +} + +//-------------------------------------------------------------- RedrawAllGrease +// Called to redraw all the black lines of spilt grease. + +void RedrawAllGrease (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + Rect src; + short i; + + if (numGrease == 0) + return; + + for (i = 0; i < numGrease; i++) + { + src = hotSpots[grease[i].hotNum].bounds; + if ((grease[i].where == thisRoomNumber) && + ((src.bottom - src.top) == 2) && + (grease[i].mode != kGreaseIdle)) + { + QOffsetRect(&src, playOriginH, playOriginV); + + GetGWorld(&wasCPort, &wasWorld); + + SetGWorld(backSrcMap, nil); + PaintRect(&src); + + SetGWorld(workSrcMap, nil); + PaintRect(&src); + AddRectToWorkRects(&src); + + SetGWorld(wasCPort, wasWorld); + } + } +} + diff --git a/GpApp/HighScores.cpp b/GpApp/HighScores.cpp new file mode 100644 index 0000000..d59df57 --- /dev/null +++ b/GpApp/HighScores.cpp @@ -0,0 +1,856 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// HighScores.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLFolders.h" +#include "PLNumberFormatting.h" +#include "PLScript.h" +#include "PLSound.h" +#include "PLStringCompare.h" +#include "DialogUtils.h" +#include "Externs.h" +#include "Environ.h" +#include "House.h" +#include "MainWindow.h" +#include "RectUtils.h" +#include "Utilities.h" + + +#define kHighScoresPictID 1994 +#define kHighScoresMaskID 1998 +#define kHighNameDialogID 1020 +#define kHighBannerDialogID 1021 +#define kHighNameItem 2 +#define kNameNCharsItem 5 +#define kHighBannerItem 2 +#define kBannerScoreNCharsItem 5 + + +void DrawHighScores (void); +void UpdateNameDialog (DialogPtr); +Boolean NameFilter (DialogPtr, EventRecord *, short *); +void GetHighScoreName (short); +void UpdateBannerDialog (DialogPtr); +Boolean BannerFilter (DialogPtr, EventRecord *, short *); +void GetHighScoreBanner (void); +Boolean CreateScoresFolder (long *); +Boolean FindHighScoresFolder (short *, long *); +Boolean OpenHighScoresFile (FSSpec *, short *); + + +Str31 highBanner; +Str15 highName; +short lastHighScore; +Boolean keyStroke; + +extern short splashOriginH, splashOriginV; +extern Boolean quickerTransitions, resumedSavedGame; + + +//============================================================== Functions +//-------------------------------------------------------------- DoHighScores +// Handles fading in and cleaning up the high scores screen. + +void DoHighScores (void) +{ + Rect tempRect; + + SpinCursor(3); + SetPort((GrafPtr)workSrcMap); + PaintRect(&workSrcRect); + QSetRect(&tempRect, 0, 0, 640, 480); + QOffsetRect(&tempRect, splashOriginH, splashOriginV); + LoadScaledGraphic(kStarPictID, &tempRect); +// if (quickerTransitions) +// DissBitsChunky(&workSrcRect); +// else +// DissBits(&workSrcRect); + SpinCursor(3); + SetPort((GrafPtr)workSrcMap); + DrawHighScores(); + SpinCursor(3); +// if (quickerTransitions) +// DissBitsChunky(&workSrcRect); +// else +// DissBits(&workSrcRect); + InitCursor(); + DelayTicks(60); + WaitForInputEvent(30); + + RedrawSplashScreen(); +} + +//-------------------------------------------------------------- DrawHighScores +// Draws the actual scores on the screen. + +#define kScoreSpacing 18 +#define kScoreWide 352 +#define kKimsLifted 4 + +void DrawHighScores (void) +{ + GWorldPtr tempMap, tempMask; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + houseType *thisHousePtr; + Rect tempRect, tempRect2; + Str255 tempStr; + short scoreLeft, bannerWidth, i, dropIt; + char wasState; + + scoreLeft = ((thisMac.screen.right - thisMac.screen.left) - kScoreWide) / 2; + dropIt = 129 + splashOriginV; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&tempRect, 0, 0, 332, 30); + theErr = CreateOffScreenGWorld(&tempMap, &tempRect, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(kHighScoresPictID); + + theErr = CreateOffScreenGWorld(&tempMask, &tempRect, 1); + SetGWorld(tempMask, nil); + LoadGraphic(kHighScoresMaskID); + + tempRect2 = tempRect; + QOffsetRect(&tempRect2, scoreLeft + (kScoreWide - 332) / 2, dropIt - 60); + + CopyMask((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(tempMask), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &tempRect, &tempRect, &tempRect2); + + DisposeGWorld(tempMap); + DisposeGWorld(tempMask); + + SetGWorld(wasCPort, wasWorld); + + TextFont(applFont); + TextFace(bold); + TextSize(14); + + PasStringCopy(PSTR("¥ "), tempStr); + PasStringConcat(tempStr, thisHouseName); + PasStringConcat(tempStr, PSTR(" ¥")); + MoveTo(scoreLeft + ((kScoreWide - StringWidth(tempStr)) / 2) - 1, dropIt - 66); + ForeColor(blackColor); + DrawString(tempStr); + MoveTo(scoreLeft + ((kScoreWide - StringWidth(tempStr)) / 2), dropIt - 65); + ForeColor(cyanColor); + DrawString(tempStr); + ForeColor(blackColor); + + TextFont(applFont); + TextFace(bold); + TextSize(12); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + // message for score #1 + PasStringCopy(thisHousePtr->highScores.banner, tempStr); + bannerWidth = StringWidth(tempStr); + ForeColor(blackColor); + MoveTo(scoreLeft + (kScoreWide - bannerWidth) / 2, dropIt - kKimsLifted); + DrawString(tempStr); + ForeColor(yellowColor); + MoveTo(scoreLeft + (kScoreWide - bannerWidth) / 2, dropIt - kKimsLifted - 1); + DrawString(tempStr); + + QSetRect(&tempRect, 0, 0, bannerWidth + 8, kScoreSpacing); + QOffsetRect(&tempRect, scoreLeft - 3 + (kScoreWide - bannerWidth) / 2, + dropIt + 5 - kScoreSpacing - kKimsLifted); + ForeColor(blackColor); + FrameRect(&tempRect); + QOffsetRect(&tempRect, -1, -1); + ForeColor(yellowColor); + FrameRect(&tempRect); + + for (i = 0; i < kMaxScores; i++) + { + if (thisHousePtr->highScores.scores[i] > 0L) + { + SpinCursor(1); + NumToString((long)i + 1L, tempStr); // draw placing number + ForeColor(blackColor); + if (i == 0) + MoveTo(scoreLeft + 1, dropIt - kScoreSpacing - kKimsLifted); + else + MoveTo(scoreLeft + 1, dropIt + (i * kScoreSpacing)); + DrawString(tempStr); + if (i == lastHighScore) + ForeColor(whiteColor); + else + ForeColor(cyanColor); + if (i == 0) + MoveTo(scoreLeft + 0, dropIt - 1 - kScoreSpacing - kKimsLifted); + else + MoveTo(scoreLeft + 0, dropIt - 1 + (i * kScoreSpacing)); + DrawString(tempStr); + // draw high score name + PasStringCopy(thisHousePtr->highScores.names[i], tempStr); + ForeColor(blackColor); + if (i == 0) + MoveTo(scoreLeft + 31, dropIt - kScoreSpacing - kKimsLifted); + else + MoveTo(scoreLeft + 31, dropIt + (i * kScoreSpacing)); + DrawString(tempStr); + if (i == lastHighScore) + ForeColor(whiteColor); + else + ForeColor(yellowColor); + if (i == 0) + MoveTo(scoreLeft + 30, dropIt - 1 - kScoreSpacing - kKimsLifted); + else + MoveTo(scoreLeft + 30, dropIt - 1 + (i * kScoreSpacing)); + DrawString(tempStr); + // draw level number + NumToString(thisHousePtr->highScores.levels[i], tempStr); + ForeColor(blackColor); + if (i == 0) + MoveTo(scoreLeft + 161, dropIt - kScoreSpacing - kKimsLifted); + else + MoveTo(scoreLeft + 161, dropIt + (i * kScoreSpacing)); + DrawString(tempStr); + if (i == lastHighScore) + ForeColor(whiteColor); + else + ForeColor(yellowColor); + if (i == 0) + MoveTo(scoreLeft + 160, dropIt - 1 - kScoreSpacing - kKimsLifted); + else + MoveTo(scoreLeft + 160, dropIt - 1 + (i * kScoreSpacing)); + DrawString(tempStr); + // draw word "rooms" + if (thisHousePtr->highScores.levels[i] == 1) + GetLocalizedString(6, tempStr); + else + GetLocalizedString(7, tempStr); + ForeColor(blackColor); + if (i == 0) + MoveTo(scoreLeft + 193, dropIt - kScoreSpacing - kKimsLifted); + else + MoveTo(scoreLeft + 193, dropIt + (i * kScoreSpacing)); + DrawString(tempStr); + ForeColor(cyanColor); + if (i == 0) + MoveTo(scoreLeft + 192, dropIt - 1 - kScoreSpacing - kKimsLifted); + else + MoveTo(scoreLeft + 192, dropIt - 1 + (i * kScoreSpacing)); + DrawString(tempStr); + // draw high score points + NumToString(thisHousePtr->highScores.scores[i], tempStr); + ForeColor(blackColor); + if (i == 0) + MoveTo(scoreLeft + 291, dropIt - kScoreSpacing - kKimsLifted); + else + MoveTo(scoreLeft + 291, dropIt + (i * kScoreSpacing)); + DrawString(tempStr); + if (i == lastHighScore) + ForeColor(whiteColor); + else + ForeColor(yellowColor); + if (i == 0) + MoveTo(scoreLeft + 290, dropIt - 1 - kScoreSpacing - kKimsLifted); + else + MoveTo(scoreLeft + 290, dropIt - 1 + (i * kScoreSpacing)); + DrawString(tempStr); + } + } + + ForeColor(blueColor); + TextFont(applFont); + TextFace(bold); + TextSize(9); + MoveTo(scoreLeft + 80, dropIt - 1 + (10 * kScoreSpacing)); + GetLocalizedString(8, tempStr); + DrawString(tempStr); + + ForeColor(blackColor); + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- SortHighScores +// This does a simple sort of the high scores. + +void SortHighScores (void) +{ + scoresType tempScores; + houseType *thisHousePtr; + long greatest; + short i, h, which; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + for (h = 0; h < kMaxScores; h++) + { + greatest = -1L; + which = -1; + for (i = 0; i < kMaxScores; i++) + { + if (thisHousePtr->highScores.scores[i] > greatest) + { + greatest = thisHousePtr->highScores.scores[i]; + which = i; + } + } + if (which != -1) + { + PasStringCopy(thisHousePtr->highScores.names[which], tempScores.names[h]); + tempScores.scores[h] = thisHousePtr->highScores.scores[which]; + tempScores.timeStamps[h] = thisHousePtr->highScores.timeStamps[which]; + tempScores.levels[h] = thisHousePtr->highScores.levels[which]; + thisHousePtr->highScores.scores[which] = -1L; + } + } + PasStringCopy(thisHousePtr->highScores.banner, tempScores.banner); + thisHousePtr->highScores = tempScores; + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- ZeroHighScores +// This funciton goes through and resets or "zeros" all high scores. + +void ZeroHighScores (void) +{ + houseType *thisHousePtr; + short i; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + PasStringCopy(thisHouseName, thisHousePtr->highScores.banner); + for (i = 0; i < kMaxScores; i++) + { + PasStringCopy(PSTR("--------------"), thisHousePtr->highScores.names[i]); + thisHousePtr->highScores.scores[i] = 0L; + thisHousePtr->highScores.timeStamps[i] = 0L; + thisHousePtr->highScores.levels[i] = 0; + } + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- ZeroAllButHighestScore +// Like the above, but this function preserves the highest score. + +void ZeroAllButHighestScore (void) +{ + houseType *thisHousePtr; + short i; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + for (i = 1; i < kMaxScores; i++) + { + PasStringCopy(PSTR("--------------"), thisHousePtr->highScores.names[i]); + thisHousePtr->highScores.scores[i] = 0L; + thisHousePtr->highScores.timeStamps[i] = 0L; + thisHousePtr->highScores.levels[i] = 0; + } + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- TestHighScore +// This function is called after a game ends in order to test theÉ +// current high score against the high score list. It returns trueÉ +// if the player is on the high score list now. + +Boolean TestHighScore (void) +{ + houseType *thisHousePtr; + short placing, i; + char wasState; + + if (resumedSavedGame) + return (false); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + lastHighScore = -1; + placing = -1; + + for (i = 0; i < kMaxScores; i++) + { + if (theScore > thisHousePtr->highScores.scores[i]) + { + placing = i; + lastHighScore = i; + break; + } + } + + if (placing != -1) + { + FlushEvents(everyEvent, 0); + GetHighScoreName(placing + 1); + PasStringCopy(highName, thisHousePtr->highScores.names[kMaxScores - 1]); + if (placing == 0) + { + GetHighScoreBanner(); + PasStringCopy(highBanner, thisHousePtr->highScores.banner); + } + thisHousePtr->highScores.scores[kMaxScores - 1] = theScore; + GetDateTime(&thisHousePtr->highScores.timeStamps[kMaxScores - 1]); + thisHousePtr->highScores.levels[kMaxScores - 1] = CountRoomsVisited(); + SortHighScores(); + gameDirty = true; + } + + HSetState((Handle)thisHouse, wasState); + + if (placing != -1) + { + DoHighScores(); + return (true); + } + else + return (false); +} + +//-------------------------------------------------------------- UpdateNameDialog +// Redraws the "Enter High Score Name" dialog. + +void UpdateNameDialog (DialogPtr theDialog) +{ + short nChars; + + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + + nChars = GetDialogStringLen(theDialog, kHighNameItem); + SetDialogNumToStr(theDialog, kNameNCharsItem, (long)nChars); +} + +//-------------------------------------------------------------- NameFilter +// Dialog filter for the "Enter High Score Name" dialog. + +Boolean NameFilter (DialogPtr dial, EventRecord *event, short *item) +{ + short nChars; + + if (keyStroke) + { + nChars = GetDialogStringLen(dial, kHighNameItem); + SetDialogNumToStr(dial, kNameNCharsItem, (long)nChars); + keyStroke = false; + } + + switch (event->what) + { + case keyDown: + keyStroke = true; + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + PlayPrioritySound(kCarriageSound, kCarriagePriority); + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kTabKeyASCII: + SelectDialogItemText(dial, kHighNameItem, 0, 1024); + return(false); + break; + + default: + PlayPrioritySound(kTypingSound, kTypingPriority); + return(false); + } + break; + + case updateEvt: + BeginUpdate(GetDialogWindow(dial)); + UpdateNameDialog(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- GetHighScoreName +// Brings up a dialog to get player's name (due to a high score). + +void GetHighScoreName (short place) +{ + DialogPtr theDial; + Str255 scoreStr, placeStr, tempStr; + short item; + Boolean leaving; + ModalFilterUPP nameFilterUPP; + + nameFilterUPP = NewModalFilterUPP(NameFilter); + + InitCursor(); + NumToString(theScore, scoreStr); + NumToString((long)place, placeStr); + ParamText(scoreStr, placeStr, thisHouseName, PSTR("")); + PlayPrioritySound(kEnergizeSound, kEnergizePriority); + BringUpDialog(&theDial, kHighNameDialogID); + FlushEvents(everyEvent, 0); + SetDialogString(theDial, kHighNameItem, highName); + SelectDialogItemText(theDial, kHighNameItem, 0, 1024); + leaving = false; + + while (!leaving) + { + ModalDialog(nameFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogString(theDial, kHighNameItem, tempStr); + PasStringCopyNum(tempStr, highName, 15); + leaving = true; + } + } + + DisposeDialog(theDial); + DisposeModalFilterUPP(nameFilterUPP); +} + +//-------------------------------------------------------------- UpdateBannerDialog +// Redraws the "Enter Message" dialog. + +void UpdateBannerDialog (DialogPtr theDialog) +{ + short nChars; + + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + + nChars = GetDialogStringLen(theDialog, kHighBannerItem); + SetDialogNumToStr(theDialog, kBannerScoreNCharsItem, (long)nChars); +} + +//-------------------------------------------------------------- BannerFilter +// Dialog filter for the "Enter Message" dialog. + +Boolean BannerFilter (DialogPtr dial, EventRecord *event, short *item) +{ + short nChars; + + if (keyStroke) + { + nChars = GetDialogStringLen(dial, kHighBannerItem); + SetDialogNumToStr(dial, kBannerScoreNCharsItem, (long)nChars); + keyStroke = false; + } + + switch (event->what) + { + + case keyDown: + keyStroke = true; + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + PlayPrioritySound(kCarriageSound, kCarriagePriority); + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kTabKeyASCII: + SelectDialogItemText(dial, kHighBannerItem, 0, 1024); + return(false); + break; + + default: + PlayPrioritySound(kTypingSound, kTypingPriority); + return(false); + } + break; + + case updateEvt: + BeginUpdate(GetDialogWindow(dial)); + UpdateBannerDialog(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- GetHighScoreBanner +// A player who gets the #1 slot gets to enter a short message (thatÉ +// appears across the top of the high scores list). This dialogÉ +// gets that message. + +void GetHighScoreBanner (void) +{ + DialogPtr theDial; + Str255 tempStr; + short item; + Boolean leaving; + ModalFilterUPP bannerFilterUPP; + + bannerFilterUPP = NewModalFilterUPP(BannerFilter); + + PlayPrioritySound(kEnergizeSound, kEnergizePriority); + BringUpDialog(&theDial, kHighBannerDialogID); + SetDialogString(theDial, kHighBannerItem, highBanner); + SelectDialogItemText(theDial, kHighBannerItem, 0, 1024); + leaving = false; + + while (!leaving) + { + ModalDialog(bannerFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogString(theDial, kHighBannerItem, tempStr); + PasStringCopyNum(tempStr, highBanner, 31); + leaving = true; + } + } + + DisposeDialog(theDial); + DisposeModalFilterUPP(bannerFilterUPP); +} + +//-------------------------------------------------------------- CreateScoresFolder + +Boolean CreateScoresFolder (long *scoresDirID) +{ + FSSpec scoresSpec; + long prefsDirID; + OSErr theErr; + short volRefNum; + + theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, + &volRefNum, &prefsDirID); + if (!CheckFileError(theErr, PSTR("Prefs Folder"))) + return (false); + + theErr = FSMakeFSSpec(volRefNum, prefsDirID, PSTR("G-PRO Scores Ä"), &scoresSpec); + + theErr = FSpDirCreate(&scoresSpec, smSystemScript, scoresDirID); + if (!CheckFileError(theErr, PSTR("High Scores Folder"))) + return (false); + + return (true); +} + +//-------------------------------------------------------------- FindHighScoresFolder + +Boolean FindHighScoresFolder (short *volRefNum, long *scoresDirID) +{ + CInfoPBRec theBlock; + Str255 nameString; + long prefsDirID; + OSErr theErr; + short count; + Boolean foundIt; + + theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, + volRefNum, &prefsDirID); + if (!CheckFileError(theErr, PSTR("Prefs Folder"))) + return (false); + + PasStringCopy(PSTR("G-PRO Scores Ä"), nameString); + count = 1; + foundIt = false; + + theBlock.dirInfo.ioCompletion = nil; + theBlock.dirInfo.ioVRefNum = *volRefNum; + theBlock.dirInfo.ioNamePtr = nameString; + + while ((theErr == noErr) && (!foundIt)) + { + theBlock.dirInfo.ioFDirIndex = count; + theBlock.dirInfo.ioDrDirID = prefsDirID; + theErr = PBGetCatInfo(&theBlock, false); + if (theErr == noErr) + { + if ((theBlock.dirInfo.ioFlAttrib & 0x10) == 0x10) + { + if (EqualString(theBlock.dirInfo.ioNamePtr, PSTR("G-PRO Scores Ä"), + true, true)) + { + foundIt = true; + *scoresDirID = theBlock.dirInfo.ioDrDirID; + } + } + count++; + } + } + + if (theErr == fnfErr) + { + if (CreateScoresFolder(scoresDirID)) + return (true); + else + return (false); + } + else + return (true); +} + +//-------------------------------------------------------------- OpenHighScoresFile + +Boolean OpenHighScoresFile (FSSpec *scoreSpec, short *scoresRefNum) +{ + OSErr theErr; + + theErr = FSpOpenDF(scoreSpec, fsCurPerm, scoresRefNum); + if (theErr == fnfErr) + { + theErr = FSpCreate(scoreSpec, 'ozm5', 'gliS', smSystemScript); + if (!CheckFileError(theErr, PSTR("New High Scores File"))) + return (false); + theErr = FSpOpenDF(scoreSpec, fsCurPerm, scoresRefNum); + if (!CheckFileError(theErr, PSTR("High Score"))) + return (false); + } + else if (!CheckFileError(theErr, PSTR("High Score"))) + return (false); + + return (true); +} + +//-------------------------------------------------------------- WriteScoresToDisk + +Boolean WriteScoresToDisk (void) +{ + scoresType *theScores; + FSSpec scoreSpec; + long dirID, byteCount; + OSErr theErr; + short volRefNum, scoresRefNum; + char wasState; + + if (!FindHighScoresFolder(&volRefNum, &dirID)) + { + SysBeep(1); + return (false); + } + + theErr = FSMakeFSSpec(volRefNum, dirID, thisHouseName, &scoreSpec); + if (!OpenHighScoresFile(&scoreSpec, &scoresRefNum)) + { + SysBeep(1); + return (false); + } + + theErr = SetFPos(scoresRefNum, fsFromStart, 0L); + if (!CheckFileError(theErr, PSTR("High Scores File"))) + { + theErr = FSClose(scoresRefNum); + return(false); + } + + byteCount = sizeof(scoresType); + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + theScores = &((*thisHouse)->highScores); + + theErr = FSWrite(scoresRefNum, &byteCount, (Ptr)theScores); + if (!CheckFileError(theErr, PSTR("High Scores File"))) + { + HSetState((Handle)thisHouse, wasState); + theErr = FSClose(scoresRefNum); + return(false); + } + HSetState((Handle)thisHouse, wasState); + + theErr = SetEOF(scoresRefNum, byteCount); + if (!CheckFileError(theErr, PSTR("High Scores File"))) + { + theErr = FSClose(scoresRefNum); + return(false); + } + + theErr = FSClose(scoresRefNum); + if (!CheckFileError(theErr, PSTR("High Scores File"))) + return(false); + + return (true); +} + +//-------------------------------------------------------------- ReadScoresFromDisk + +Boolean ReadScoresFromDisk (void) +{ + scoresType *theScores; + FSSpec scoreSpec; + long dirID, byteCount; + OSErr theErr; + short volRefNum, scoresRefNum; + char wasState; + + if (!FindHighScoresFolder(&volRefNum, &dirID)) + { + SysBeep(1); + return (false); + } + + theErr = FSMakeFSSpec(volRefNum, dirID, thisHouseName, &scoreSpec); + if (!OpenHighScoresFile(&scoreSpec, &scoresRefNum)) + { + SysBeep(1); + return (false); + } + + theErr = GetEOF(scoresRefNum, &byteCount); + if (!CheckFileError(theErr, PSTR("High Scores File"))) + { + theErr = FSClose(scoresRefNum); + return (false); + } + + theErr = SetFPos(scoresRefNum, fsFromStart, 0L); + if (!CheckFileError(theErr, PSTR("High Scores File"))) + { + theErr = FSClose(scoresRefNum); + return (false); + } + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + theScores = &((*thisHouse)->highScores); + + theErr = FSRead(scoresRefNum, &byteCount, theScores); + if (!CheckFileError(theErr, PSTR("High Scores File"))) + { + HSetState((Handle)thisHouse, wasState); + theErr = FSClose(scoresRefNum); + return (false); + } + HSetState((Handle)thisHouse, wasState); + + theErr = FSClose(scoresRefNum); + if (!CheckFileError(theErr, PSTR("High Scores File"))) + return(false); + + return (true); +} + diff --git a/GpApp/House.cpp b/GpApp/House.cpp new file mode 100644 index 0000000..ec0abbe --- /dev/null +++ b/GpApp/House.cpp @@ -0,0 +1,860 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// House.c +//---------------------------------------------------------------------------- +//============================================================================ + +#include "PLAppleEvents.h" +#include "PLNavigation.h" +#include "PLNumberFormatting.h" +#include "PLPasStr.h" +#include "PLResources.h" +#include "PLSound.h" +#include "DialogUtils.h" +#include "Externs.h" +#include "House.h" +#include "RectUtils.h" + + +#define kGoToDialogID 1043 + + +void UpdateGoToDialog (DialogPtr); +Boolean GoToFilter (DialogPtr, EventRecord *, short *); + + +houseHand thisHouse; +linksPtr linksList; +Str32 thisHouseName; +short srcLocations[kMaxRoomObs]; +short destLocations[kMaxRoomObs]; +short wasFloor, wasSuite; +retroLink retroLinkList[kMaxRoomObs]; +Boolean houseUnlocked; + + +extern gameType smallGame; +extern short numberRooms, mapLeftRoom, mapTopRoom, numStarsRemaining; +extern Boolean houseOpen, noRoomAtAll; +extern Boolean twoPlayerGame, wardBitSet, phoneBitSet; + + +//============================================================== Functions +//-------------------------------------------------------------- CreateNewHouse +// Called to create a new house file. + +#ifndef COMPILEDEMO +Boolean CreateNewHouse (void) +{ + AEKeyword theKeyword; + DescType actualType; + Size actualSize; + NavReplyRecord theReply; + NavDialogOptions dialogOptions; + FSSpec tempSpec; + FSSpec theSpec; + OSErr theErr; + + theErr = NavGetDefaultDialogOptions(&dialogOptions); + theErr = NavPutFile(nil, &theReply, &dialogOptions, nil, 'gliH', 'ozm5', nil); + if (theErr == userCanceledErr) + return false; + if (!theReply.validRecord) + return (false); + + theErr = AEGetNthPtr(&(theReply.selection), 1, typeFSS, &theKeyword, + &actualType, &theSpec, sizeof(FSSpec), &actualSize); + + if (theReply.replacing) + { + theErr = FSMakeFSSpec(theSpec.vRefNum, theSpec.parID, + theSpec.name, &tempSpec); + if (!CheckFileError(theErr, theSpec.name)) + return (false); + + theErr = FSpDelete(&tempSpec); + if (!CheckFileError(theErr, theSpec.name)) + return (false); + } + + if (houseOpen) + { + if (!CloseHouse()) + return (false); + } + + theErr = FSpCreate(&theSpec, 'ozm5', 'gliH', theReply.keyScript); + if (!CheckFileError(theErr, PSTR("New House"))) + return (false); + HCreateResFile(theSpec.vRefNum, theSpec.parID, theSpec.name); + if (ResError() != noErr) + YellowAlert(kYellowFailedResCreate, ResError()); + + PasStringCopy(theSpec.name, thisHouseName); + AddExtraHouse(&theSpec); + BuildHouseList(); + InitCursor(); + if (!OpenHouse()) + return (false); + + return (true); +} +#endif + +//-------------------------------------------------------------- InitializeEmptyHouse + +// Initializes all the structures for an empty (new) house. + +#ifndef COMPILEDEMO +Boolean InitializeEmptyHouse (void) +{ + houseType *thisHousePtr; + Str255 tempStr; + + if (thisHouse != nil) + DisposeHandle((Handle)thisHouse); + + thisHouse = (houseHand)NewHandle(sizeof(houseType)); + + if (thisHouse == nil) + { + YellowAlert(kYellowUnaccounted, 1); + return (false); + } + + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + thisHousePtr->version = kHouseVersion; + thisHousePtr->firstRoom = -1; + thisHousePtr->timeStamp = 0L; + thisHousePtr->flags = 0L; + thisHousePtr->initial.h = 32; + thisHousePtr->initial.v = 32; + ZeroHighScores(); + + GetLocalizedString(11, tempStr); + PasStringCopy(tempStr, thisHousePtr->banner); + GetLocalizedString(12, tempStr); + PasStringCopy(tempStr, thisHousePtr->trailer); + thisHousePtr->hasGame = false; + thisHousePtr->nRooms = 0; + + wardBitSet = false; + phoneBitSet = false; + + HUnlock((Handle)thisHouse); + + numberRooms = 0; + mapLeftRoom = 60; + mapTopRoom = 50; + thisRoomNumber = kRoomIsEmpty; + previousRoom = -1; + houseUnlocked = true; + OpenMapWindow(); + UpdateMapWindow(); + noRoomAtAll = true; + fileDirty = true; + UpdateMenus(false); + ReflectCurrentRoom(true); + + return (true); +} +#endif + +//-------------------------------------------------------------- RealRoomNumberCount + +// Returns the real number of rooms in a house (some rooms may stillÉ +// be place-holders - they were deleted earlier and are flagged asÉ +// deleted but still occupy space in the file). + +short RealRoomNumberCount (void) +{ + short realRoomCount, i; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + realRoomCount = (*thisHouse)->nRooms; + if (realRoomCount != 0) + { + for (i = 0; i < (*thisHouse)->nRooms; i++) + { + if ((*thisHouse)->rooms[i].suite == kRoomIsEmpty) + realRoomCount--; + } + } + HSetState((Handle)thisHouse, wasState); + + return (realRoomCount); +} + +//-------------------------------------------------------------- GetFirstRoomNumber + +// Returns the room number (indicee into house file) of the room whereÉ +// the player is to begin. + +short GetFirstRoomNumber (void) +{ + short firstRoom; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + if ((*thisHouse)->nRooms <= 0) + { + firstRoom = -1; + noRoomAtAll = true; + } + else + { + firstRoom = (*thisHouse)->firstRoom; + if ((firstRoom >= (*thisHouse)->nRooms) || (firstRoom < 0)) + firstRoom = 0; + } + HSetState((Handle)thisHouse, wasState); + + return (firstRoom); +} + +//-------------------------------------------------------------- WhereDoesGliderBegin + +// Returns a rectangle indicating where in the first room the player'sÉ +// glider is to appear. + +void WhereDoesGliderBegin (Rect *theRect, short mode) +{ + Point initialPt; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + if (mode == kResumeGameMode) + initialPt = smallGame.where; + else if (mode == kNewGameMode) + initialPt = (*thisHouse)->initial; + + HSetState((Handle)thisHouse, wasState); + QSetRect(theRect, 0, 0, kGliderWide, kGliderHigh); + QOffsetRect(theRect, initialPt.h, initialPt.v); +} + +//-------------------------------------------------------------- HouseHasOriginalPicts + +// Returns true is the current house has custom artwork imbedded. + +Boolean HouseHasOriginalPicts (void) +{ + short nPicts; + + nPicts = Count1Resources('PICT'); + return (nPicts > 0); +} + +//-------------------------------------------------------------- CountHouseLinks + +// Counts up the number of linked objects in a house. + +short CountHouseLinks (void) +{ + houseType *thisHousePtr; + short numRooms, numLinks; + short r, i, what; + char wasState; + + numLinks = 0; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + numRooms = thisHousePtr->nRooms; + + for (r = 0; r < numRooms; r++) + { + for (i = 0; i < kMaxRoomObs; i++) + { + what = thisHousePtr->rooms[r].objects[i].what; + switch (what) + { + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + if (thisHousePtr->rooms[r].objects[i].data.e.where != -1) + numLinks++; + break; + + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kInvisTrans: + case kDeluxeTrans: + if (thisHousePtr->rooms[r].objects[i].data.d.where != -1) + numLinks++; + break; + } + } + } + + HSetState((Handle)thisHouse, wasState); + + return (numLinks); +} + +//-------------------------------------------------------------- GenerateLinksList + +// Generates a list of all objects that have links and what roomsÉ +// and objects they are linked to. It is called in order to preserveÉ +// the links if the objects or rooms in a house are to be shuffledÉ +// around. + +#ifndef COMPILEDEMO +void GenerateLinksList (void) +{ + houseType *thisHousePtr; + objectType thisObject; + short numLinks, numRooms, r, i, what; + short floor, suite, roomLinked, objectLinked; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + numRooms = thisHousePtr->nRooms; + + numLinks = 0; + + for (r = 0; r < numRooms; r++) + { + for (i = 0; i < kMaxRoomObs; i++) + { + what = thisHousePtr->rooms[r].objects[i].what; + switch (what) + { + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + thisObject = thisHousePtr->rooms[r].objects[i]; + if (thisObject.data.e.where != -1) + { + ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); + roomLinked = GetRoomNumber(floor, suite); + objectLinked = (short)thisObject.data.e.who; + linksList[numLinks].srcRoom = r; + linksList[numLinks].srcObj = i; + linksList[numLinks].destRoom = roomLinked; + linksList[numLinks].destObj = objectLinked; + numLinks++; + } + break; + + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kInvisTrans: + case kDeluxeTrans: + thisObject = thisHousePtr->rooms[r].objects[i]; + if (thisObject.data.d.where != -1) + { + ExtractFloorSuite(thisObject.data.d.where, &floor, &suite); + roomLinked = GetRoomNumber(floor, suite); + objectLinked = (short)thisObject.data.d.who; + linksList[numLinks].srcRoom = r; + linksList[numLinks].srcObj = i; + linksList[numLinks].destRoom = roomLinked; + linksList[numLinks].destObj = objectLinked; + numLinks++; + } + break; + } + } + } + + HSetState((Handle)thisHouse, wasState); +} +#endif + +//-------------------------------------------------------------- SortRoomObjects + +// I'm a little fuzzy on what this does. + +#ifndef COMPILEDEMO +void SortRoomsObjects (short which) +{ + short probe, probe2, room, obj; + Boolean busy, looking; + + busy = true; + probe = 0; + + do + { + if ((*thisHouse)->rooms[which].objects[probe].what == kObjectIsEmpty) + { + looking = true; + probe2 = probe + 1; // begin by looking at the next object + do + { + if ((*thisHouse)->rooms[which].objects[probe2].what != kObjectIsEmpty) + { + (*thisHouse)->rooms[which].objects[probe] = + (*thisHouse)->rooms[which].objects[probe2]; + (*thisHouse)->rooms[which].objects[probe2].what = kObjectIsEmpty; + if (srcLocations[probe2] != -1) + linksList[srcLocations[probe2]].srcObj = probe; + if (destLocations[probe2] != -1) + { + linksList[destLocations[probe2]].destObj = probe; + room = linksList[destLocations[probe2]].srcRoom; + obj = linksList[destLocations[probe2]].srcObj; + (*thisHouse)->rooms[room].objects[obj].data.e.who = static_cast(probe); + } + fileDirty = true; + looking = false; + } + probe2++; + if ((probe2 >= kMaxRoomObs) && (looking)) + { + looking = false; + busy = false; + } + } + while (looking); + } + probe++; + if (probe >= (kMaxRoomObs - 1)) + busy = false; + } + while (busy); +} +#endif + +//-------------------------------------------------------------- SortHouseObjects + +// I'm a little fuzzy on what this does exactly either. + +#ifndef COMPILEDEMO +void SortHouseObjects (void) +{ + houseType *thisHousePtr; + short numLinks, numRooms, r, i, l; + char wasState; + + SpinCursor(3); + + CopyThisRoomToRoom(); + + numLinks = CountHouseLinks(); + if (numLinks == 0) + return; + + linksList = nil; + linksList = (linksPtr)NewPtr(sizeof(linksType) * numLinks); + if (linksList == nil) + RedAlert(kErrNoMemory); + + GenerateLinksList(); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + numRooms = thisHousePtr->nRooms; + + for (r = 0; r < numRooms; r++) + { + for (i = 0; i < kMaxRoomObs; i++) // initialize arrays + { + srcLocations[i] = -1; + destLocations[i] = -1; + } + + for (i = 0; i < kMaxRoomObs; i++) // walk object list + { + for (l = 0; l < numLinks; l++) // walk link list + { + if ((linksList[l].srcRoom == r) && (linksList[l].srcObj == i)) + srcLocations[i] = l; + if ((linksList[l].destRoom == r) && (linksList[l].destObj == i)) + destLocations[i] = l; + } + } + SortRoomsObjects(r); + + if ((r & 0x0007) == 0x0007) + IncrementCursor(); + } + + SpinCursor(3); + HSetState((Handle)thisHouse, wasState); + if (linksList != nil) + DisposePtr((Ptr)linksList); + ForceThisRoom(thisRoomNumber); +} +#endif + +//-------------------------------------------------------------- CountRoomsVisited + +// Goes through and counts the number of rooms a player has been to inÉ +// the current game. + +short CountRoomsVisited (void) +{ + houseType *thisHousePtr; + short numRooms, r, count; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + numRooms = thisHousePtr->nRooms; + count = 0; + + for (r = 0; r < numRooms; r++) + { + if (thisHousePtr->rooms[r].visited) + count++; + } + + HSetState((Handle)thisHouse, wasState); + return (count); +} + +//-------------------------------------------------------------- GenerateRetroLinks + +// Walk entire house looking for objects which are linked to objectsÉ +// in the current room. + +void GenerateRetroLinks (void) +{ + houseType *thisHousePtr; + objectType thisObject; + short i, r, numRooms, floor, suite; + short what, roomLinked, objectLinked; + char wasState; + + for (i = 0; i < kMaxRoomObs; i++) // Initialize array. + retroLinkList[i].room = -1; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + numRooms = thisHousePtr->nRooms; + + for (r = 0; r < numRooms; r++) + { + for (i = 0; i < kMaxRoomObs; i++) + { + what = thisHousePtr->rooms[r].objects[i].what; + switch (what) + { + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + thisObject = thisHousePtr->rooms[r].objects[i]; + if (thisObject.data.e.where != -1) + { + ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); + roomLinked = GetRoomNumber(floor, suite); + if (roomLinked == thisRoomNumber) + { + objectLinked = (short)thisObject.data.e.who; + if (retroLinkList[objectLinked].room == -1) + { + retroLinkList[objectLinked].room = r; + retroLinkList[objectLinked].object = i; + } + } + } + break; + + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kInvisTrans: + case kDeluxeTrans: + thisObject = thisHousePtr->rooms[r].objects[i]; + if (thisObject.data.d.where != -1) + { + ExtractFloorSuite(thisObject.data.d.where, &floor, &suite); + roomLinked = GetRoomNumber(floor, suite); + if (roomLinked == thisRoomNumber) + { + objectLinked = (short)thisObject.data.d.who; + if (retroLinkList[objectLinked].room == -1) + { + retroLinkList[objectLinked].room = r; + retroLinkList[objectLinked].object = i; + } + } + } + break; + } + } + } + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- UpdateGoToDialog +// Redraws the "Go To Room..." dialog. + +void UpdateGoToDialog (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 10, kRedOrangeColor8); +} + +//-------------------------------------------------------------- GoToFilter +// Dialog filter for the "Go To Room..." dialog. + +Boolean GoToFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + default: + return(false); + } + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateGoToDialog(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- DoGoToDialog + +// "Go To Room..." dialog. + + void DoGoToDialog (void) + { + #define kGoToFirstButt 2 + #define kGoToPrevButt 3 + #define kGoToFSButt 4 + #define kFloorEditText 5 + #define kSuiteEditText 6 + DialogPtr theDialog; + long tempLong; + short item, roomToGoTo; + Boolean leaving, canceled; + ModalFilterUPP goToFilterUPP; + + goToFilterUPP = NewModalFilterUPP(GoToFilter); + BringUpDialog(&theDialog, kGoToDialogID); + + if (GetFirstRoomNumber() == thisRoomNumber) + MyDisableControl(theDialog, kGoToFirstButt); + if ((!RoomNumExists(previousRoom)) || (previousRoom == thisRoomNumber)) + MyDisableControl(theDialog, kGoToPrevButt); + + SetDialogNumToStr(theDialog, kFloorEditText, (long)wasFloor); + SetDialogNumToStr(theDialog, kSuiteEditText, (long)wasSuite); + SelectDialogItemText(theDialog, kFloorEditText, 0, 1024); + + leaving = false; + canceled = false; + + while (!leaving) + { + ModalDialog(goToFilterUPP, &item); + + if (item == kOkayButton) + { + roomToGoTo = -1; + canceled = true; + leaving = true; + } + else if (item == kGoToFirstButt) + { + roomToGoTo = GetFirstRoomNumber(); + leaving = true; + } + else if (item == kGoToPrevButt) + { + roomToGoTo = previousRoom; + leaving = true; + } + else if (item == kGoToFSButt) + { + GetDialogNumFromStr(theDialog, kFloorEditText, &tempLong); + wasFloor = (short)tempLong; + GetDialogNumFromStr(theDialog, kSuiteEditText, &tempLong); + wasSuite = (short)tempLong; + roomToGoTo = GetRoomNumber(wasFloor, wasSuite); + leaving = true; + } + } + + DisposeDialog(theDialog); + DisposeModalFilterUPP(goToFilterUPP); + + if (!canceled) + { + if (RoomNumExists(roomToGoTo)) + { + DeselectObject(); + CopyRoomToThisRoom(roomToGoTo); + ReflectCurrentRoom(false); + } + else + SysBeep(1); + } +} + +//-------------------------------------------------------------- ConvertHouseVer1To2 + +// This function goes through an old version 1 house and converts itÉ +// to version 2. + +void ConvertHouseVer1To2 (void) +{ + Str255 roomStr, message; + short wasRoom, floor, suite; + short i, h, numRooms; + char wasState; + + CopyThisRoomToRoom(); + wasRoom = thisRoomNumber; + GetLocalizedString(13, message); + OpenMessageWindow(message); + + SpinCursor(3); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + numRooms = (*thisHouse)->nRooms; + for (i = 0; i < numRooms; i++) + { + if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) + { + NumToString((long)i, roomStr); + GetLocalizedString(14, message); + PasStringConcat(message, roomStr); + SetMessageWindowMessage(message); + SpinCursor(1); + + ForceThisRoom(i); + for (h = 0; h < kMaxRoomObs; h++) + { + switch (thisRoom->objects[h].what) + { + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kInvisTrans: + case kDeluxeTrans: + if (thisRoom->objects[h].data.d.where != -1) + { + ExtractFloorSuite(thisRoom->objects[h].data.d.where, &floor, &suite); + floor += kNumUndergroundFloors; + thisRoom->objects[h].data.d.where = MergeFloorSuite(floor, suite); + } + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + if (thisRoom->objects[h].data.e.where != -1) + { + ExtractFloorSuite(thisRoom->objects[h].data.e.where, &floor, &suite); + floor += kNumUndergroundFloors; + thisRoom->objects[h].data.e.where = MergeFloorSuite(floor, suite); + } + break; + } + } + CopyThisRoomToRoom(); + } + } + + (*thisHouse)->version = kHouseVersion; + HSetState((Handle)thisHouse, wasState); + + InitCursor(); + CloseMessageWindow(); + ForceThisRoom(wasRoom); +} + +//-------------------------------------------------------------- ShiftWholeHouse + +void ShiftWholeHouse (short howFar) +{ + short wasRoom; + short i, h, numRooms; + char wasState; + + OpenMessageWindow(PSTR("Shifting Whole HouseÉ")); + SpinCursor(3); + + CopyThisRoomToRoom(); + wasRoom = thisRoomNumber; + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + numRooms = (*thisHouse)->nRooms; + + for (i = 0; i < numRooms; i++) + { + if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) + { + SpinCursor(1); + + ForceThisRoom(i); + for (h = 0; h < kMaxRoomObs; h++) + { + } + CopyThisRoomToRoom(); + } + } + + HSetState((Handle)thisHouse, wasState); + ForceThisRoom(wasRoom); + + InitCursor(); + CloseMessageWindow(); +} + diff --git a/GpApp/House.h b/GpApp/House.h new file mode 100644 index 0000000..51a39c7 --- /dev/null +++ b/GpApp/House.h @@ -0,0 +1,12 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// House.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLMacTypes.h" + + +extern Str32 thisHouseName; +extern Boolean houseUnlocked; diff --git a/GpApp/HouseIO.cpp b/GpApp/HouseIO.cpp new file mode 100644 index 0000000..9114376 --- /dev/null +++ b/GpApp/HouseIO.cpp @@ -0,0 +1,707 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// HouseIO.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLAliases.h" +#include "PLMovies.h" +#include "PLResources.h" +#include "PLStringCompare.h" +#include "PLTextUtils.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "House.h" +#include "ObjectEdit.h" + + +#define kSaveChangesAlert 1002 +#define kSaveChanges 1 +#define kDiscardChanges 2 + + +void LoopMovie (void); +void OpenHouseMovie (void); +void CloseHouseMovie (void); +Boolean IsFileReadOnly (FSSpec *); + + +Movie theMovie; +Rect movieRect; +short houseRefNum, houseResFork, wasHouseVersion; +Boolean houseOpen, fileDirty, gameDirty; +Boolean changeLockStateOfHouse, saveHouseLocked, houseIsReadOnly; +Boolean hasMovie, tvInRoom; + +extern FSSpecPtr theHousesSpecs; +extern short thisHouseIndex, tvWithMovieNumber; +extern short numberRooms, housesFound; +extern Boolean noRoomAtAll, quitting, wardBitSet; +extern Boolean phoneBitSet, bannerStarCountOn; + + +//============================================================== Functions +//-------------------------------------------------------------- LoopMovie + +void LoopMovie (void) +{ + Handle theLoop; + UserData theUserData; + short theCount; + + theLoop = NewHandle(sizeof(long)); + (** (long **) theLoop) = 0; + theUserData = GetMovieUserData(theMovie); + theCount = CountUserDataType(theUserData, 'LOOP'); + while (theCount--) + { + RemoveUserData(theUserData, 'LOOP', 1); + } + AddUserData(theUserData, theLoop, 'LOOP'); +} + +//-------------------------------------------------------------- OpenHouseMovie + +void OpenHouseMovie (void) +{ +#ifdef COMPILEQT + TimeBase theTime; + FSSpec theSpec; + FInfo finderInfo; + Handle spaceSaver; + OSErr theErr; + short movieRefNum; + Boolean dataRefWasChanged; + + if (thisMac.hasQT) + { + theSpec = theHousesSpecs[thisHouseIndex]; + PasStringConcat(theSpec.name, PSTR(".mov")); + + theErr = FSpGetFInfo(&theSpec, &finderInfo); + if (theErr != noErr) + return; + + theErr = OpenMovieFile(&theSpec, &movieRefNum, fsCurPerm); + if (theErr != noErr) + { + YellowAlert(kYellowQTMovieNotLoaded, theErr); + return; + } + + theErr = NewMovieFromFile(&theMovie, movieRefNum, nil, theSpec.name, + newMovieActive, &dataRefWasChanged); + if (theErr != noErr) + { + YellowAlert(kYellowQTMovieNotLoaded, theErr); + theErr = CloseMovieFile(movieRefNum); + return; + } + theErr = CloseMovieFile(movieRefNum); + + spaceSaver = NewHandle(307200L); + if (spaceSaver == nil) + { + YellowAlert(kYellowQTMovieNotLoaded, 749); + CloseHouseMovie(); + return; + } + + GoToBeginningOfMovie(theMovie); + theErr = LoadMovieIntoRam(theMovie, + GetMovieTime(theMovie, 0L), GetMovieDuration(theMovie), 0); + if (theErr != noErr) + { + YellowAlert(kYellowQTMovieNotLoaded, theErr); + DisposeHandle(spaceSaver); + CloseHouseMovie(); + return; + } + DisposeHandle(spaceSaver); + + theErr = PrerollMovie(theMovie, 0, 0x000F0000); + if (theErr != noErr) + { + YellowAlert(kYellowQTMovieNotLoaded, theErr); + CloseHouseMovie(); + return; + } + + theTime = GetMovieTimeBase(theMovie); + SetTimeBaseFlags(theTime, loopTimeBase); + SetMovieMasterTimeBase(theMovie, theTime, nil); + LoopMovie(); + + GetMovieBox(theMovie, &movieRect); + + hasMovie = true; + } +#endif +} + +//-------------------------------------------------------------- CloseHouseMovie + +void CloseHouseMovie (void) +{ +#ifdef COMPILEQT + OSErr theErr; + + if ((thisMac.hasQT) && (hasMovie)) + { + theErr = LoadMovieIntoRam(theMovie, + GetMovieTime(theMovie, 0L), GetMovieDuration(theMovie), flushFromRam); + DisposeMovie(theMovie); + } +#endif + hasMovie = false; +} + +//-------------------------------------------------------------- OpenHouse +// Opens a house (whatever current selection is). Returns true if all went well. + +Boolean OpenHouse (void) +{ + OSErr theErr; + Boolean targetIsFolder, wasAliased; + + if (houseOpen) + { + if (!CloseHouse()) + return(false); + } + if ((housesFound < 1) || (thisHouseIndex == -1)) + return(false); + + theErr = ResolveAliasFile(&theHousesSpecs[thisHouseIndex], true, + &targetIsFolder, &wasAliased); + if (!CheckFileError(theErr, thisHouseName)) + return (false); + + #ifdef COMPILEDEMO + if (!EqualString(theHousesSpecs[thisHouseIndex].name, "\pDemo House", false, true)) + return (false); + #endif + + houseIsReadOnly = IsFileReadOnly(&theHousesSpecs[thisHouseIndex]); + + theErr = FSpOpenDF(&theHousesSpecs[thisHouseIndex], fsCurPerm, &houseRefNum); + if (!CheckFileError(theErr, thisHouseName)) + return (false); + + houseOpen = true; + OpenHouseResFork(); + + hasMovie = false; + tvInRoom = false; + tvWithMovieNumber = -1; + OpenHouseMovie(); + + return (true); +} + +//-------------------------------------------------------------- OpenSpecificHouse +// Opens the specific house passed in. + +#ifndef COMPILEDEMO +Boolean OpenSpecificHouse (FSSpec *specs) +{ + short i; + Boolean itOpened; + + if ((housesFound < 1) || (thisHouseIndex == -1)) + return (false); + + itOpened = true; + + for (i = 0; i < housesFound; i++) + { + if ((theHousesSpecs[i].vRefNum == specs->vRefNum) && + (theHousesSpecs[i].parID == specs->parID) && + (EqualString(theHousesSpecs[i].name, specs->name, false, true))) + { + thisHouseIndex = i; + PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); + if (OpenHouse()) + itOpened = ReadHouse(); + else + itOpened = false; + break; + } + } + + return (itOpened); +} +#endif + +//-------------------------------------------------------------- SaveHouseAs + +#ifndef COMPILEDEMO +Boolean SaveHouseAs (void) +{ + // TEMP - fix this later -- use NavServices (see House.c) +/* + StandardFileReply theReply; + FSSpec oldHouse; + OSErr theErr; + Boolean noProblems; + Str255 tempStr; + + noProblems = true; + + GetLocalizedString(15, tempStr); + StandardPutFile(tempStr, thisHouseName, &theReply); + if (theReply.sfGood) + { + oldHouse = theHousesSpecs[thisHouseIndex]; + + CloseHouseResFork(); // close this house file + theErr = FSClose(houseRefNum); + if (theErr != noErr) + { + CheckFileError(theErr, "\pPreferences"); + return(false); + } + // create new house file + theErr = FSpCreate(&theReply.sfFile, 'ozm5', 'gliH', theReply.sfScript); + if (!CheckFileError(theErr, theReply.sfFile.name)) + return (false); + HCreateResFile(theReply.sfFile.vRefNum, theReply.sfFile.parID, + theReply.sfFile.name); + if (ResError() != noErr) + YellowAlert(kYellowFailedResCreate, ResError()); + PasStringCopy(theReply.sfFile.name, thisHouseName); + // open new house data fork + theErr = FSpOpenDF(&theReply.sfFile, fsRdWrPerm, &houseRefNum); + if (!CheckFileError(theErr, thisHouseName)) + return (false); + + houseOpen = true; + + noProblems = WriteHouse(false); // write out house data + if (!noProblems) + return(false); + + BuildHouseList(); + if (OpenSpecificHouse(&theReply.sfFile)) // open new house again + { + } + else + { + if (OpenSpecificHouse(&oldHouse)) + { + YellowAlert(kYellowOpenedOldHouse, 0); + } + else + { + YellowAlert(kYellowLostAllHouses, 0); + noProblems = false; + } + } + } + + + return (noProblems); + */ + return false; +} +#endif + +//-------------------------------------------------------------- ReadHouse +// With a house open, this function reads in the actual bits of dataÉ +// into memory. + +Boolean ReadHouse (void) +{ + long byteCount; + OSErr theErr; + short whichRoom; + + if (!houseOpen) + { + YellowAlert(kYellowUnaccounted, 2); + return (false); + } + + if (gameDirty || fileDirty) + { + if (houseIsReadOnly) + { + if (!WriteScoresToDisk()) + { + YellowAlert(kYellowFailedWrite, 0); + return(false); + } + } + else if (!WriteHouse(false)) + return(false); + } + + theErr = GetEOF(houseRefNum, &byteCount); + if (theErr != noErr) + { + CheckFileError(theErr, thisHouseName); + return(false); + } + + #ifdef COMPILEDEMO + if (byteCount != 16526L) + return (false); + #endif + + if (thisHouse != nil) + DisposeHandle((Handle)thisHouse); + + thisHouse = (houseHand)NewHandle(byteCount); + if (thisHouse == nil) + { + YellowAlert(kYellowNoMemory, 10); + return(false); + } + MoveHHi((Handle)thisHouse); + + theErr = SetFPos(houseRefNum, fsFromStart, 0L); + if (theErr != noErr) + { + CheckFileError(theErr, thisHouseName); + return(false); + } + + HLock((Handle)thisHouse); + theErr = FSRead(houseRefNum, &byteCount, *thisHouse); + if (theErr != noErr) + { + CheckFileError(theErr, thisHouseName); + HUnlock((Handle)thisHouse); + return(false); + } + + numberRooms = (*thisHouse)->nRooms; + #ifdef COMPILEDEMO + if (numberRooms != 45) + return (false); + #endif + if ((numberRooms < 1) || (byteCount == 0L)) + { + numberRooms = 0; + noRoomAtAll = true; + YellowAlert(kYellowNoRooms, 0); + HUnlock((Handle)thisHouse); + return(false); + } + + wasHouseVersion = (*thisHouse)->version; + if (wasHouseVersion >= kNewHouseVersion) + { + YellowAlert(kYellowNewerVersion, 0); + HUnlock((Handle)thisHouse); + return(false); + } + + houseUnlocked = (((*thisHouse)->timeStamp & 0x00000001) == 0); + #ifdef COMPILEDEMO + if (houseUnlocked) + return (false); + #endif + changeLockStateOfHouse = false; + saveHouseLocked = false; + + whichRoom = (*thisHouse)->firstRoom; + #ifdef COMPILEDEMO + if (whichRoom != 0) + return (false); + #endif + + wardBitSet = (((*thisHouse)->flags & 0x00000001) == 0x00000001); + phoneBitSet = (((*thisHouse)->flags & 0x00000002) == 0x00000002); + bannerStarCountOn = (((*thisHouse)->flags & 0x00000004) == 0x00000000); + + HUnlock((Handle)thisHouse); + + noRoomAtAll = (RealRoomNumberCount() == 0); + thisRoomNumber = -1; + previousRoom = -1; + if (!noRoomAtAll) + CopyRoomToThisRoom(whichRoom); + + if (houseIsReadOnly) + { + houseUnlocked = false; + if (ReadScoresFromDisk()) + { + } + } + + objActive = kNoObjectSelected; + ReflectCurrentRoom(true); + gameDirty = false; + fileDirty = false; + UpdateMenus(false); + + return (true); +} + +//-------------------------------------------------------------- WriteHouse +// This function writes out the house data to disk. + +Boolean WriteHouse (Boolean checkIt) +{ + UInt32 timeStamp; + long byteCount; + OSErr theErr; + + if (!houseOpen) + { + YellowAlert(kYellowUnaccounted, 4); + return (false); + } + + theErr = SetFPos(houseRefNum, fsFromStart, 0L); + if (theErr != noErr) + { + CheckFileError(theErr, thisHouseName); + return(false); + } + + CopyThisRoomToRoom(); + + if (checkIt) + CheckHouseForProblems(); + + HLock((Handle)thisHouse); + byteCount = GetHandleSize((Handle)thisHouse); + + if (fileDirty) + { + GetDateTime(&timeStamp); + timeStamp &= 0x7FFFFFFF; + + if (changeLockStateOfHouse) + houseUnlocked = !saveHouseLocked; + + if (houseUnlocked) // house unlocked + timeStamp &= 0x7FFFFFFE; + else + timeStamp |= 0x00000001; + (*thisHouse)->timeStamp = (long)timeStamp; + (*thisHouse)->version = wasHouseVersion; + } + + theErr = FSWrite(houseRefNum, &byteCount, *thisHouse); + if (theErr != noErr) + { + CheckFileError(theErr, thisHouseName); + HUnlock((Handle)thisHouse); + return(false); + } + + theErr = SetEOF(houseRefNum, byteCount); + if (theErr != noErr) + { + CheckFileError(theErr, thisHouseName); + HUnlock((Handle)thisHouse); + return(false); + } + + HUnlock((Handle)thisHouse); + + if (changeLockStateOfHouse) + { + changeLockStateOfHouse = false; + ReflectCurrentRoom(true); + } + + gameDirty = false; + fileDirty = false; + UpdateMenus(false); + return (true); +} + +//-------------------------------------------------------------- CloseHouse +// This function closes the current house that is open. + +Boolean CloseHouse (void) +{ + OSErr theErr; + + if (!houseOpen) + return (true); + + if (gameDirty) + { + if (houseIsReadOnly) + { + if (!WriteScoresToDisk()) + YellowAlert(kYellowFailedWrite, 0); + } + else if (!WriteHouse(theMode == kEditMode)) + YellowAlert(kYellowFailedWrite, 0); + } + else if (fileDirty) + { +#ifndef COMPILEDEMO + if (!QuerySaveChanges()) // false signifies user canceled + return(false); +#endif + } + + CloseHouseResFork(); + CloseHouseMovie(); + + theErr = FSClose(houseRefNum); + if (theErr != noErr) + { + CheckFileError(theErr, thisHouseName); + return(false); + } + + houseOpen = false; + + return (true); +} + +//-------------------------------------------------------------- OpenHouseResFork +// Opens the resource fork of the current house that is open. + +void OpenHouseResFork (void) +{ + if (houseResFork == -1) + { + houseResFork = FSpOpenResFile(&theHousesSpecs[thisHouseIndex], fsCurPerm); + if (houseResFork == -1) + YellowAlert(kYellowFailedResOpen, ResError()); + else + UseResFile(houseResFork); + } +} + +//-------------------------------------------------------------- CloseHouseResFork +// Closes the resource fork of the current house that is open. + +void CloseHouseResFork (void) +{ + if (houseResFork != -1) + { + CloseResFile(houseResFork); + houseResFork = -1; + } +} + +//-------------------------------------------------------------- QuerySaveChanges +// If changes were made, this function will present the user with aÉ +// dialog asking them if they would like to save the changes. + +#ifndef COMPILEDEMO +Boolean QuerySaveChanges (void) +{ + short hitWhat; + Boolean whoCares; + + if (!fileDirty) + return(true); + + InitCursor(); +// CenterAlert(kSaveChangesAlert); + ParamText(thisHouseName, PSTR(""), PSTR(""), PSTR("")); + hitWhat = Alert(kSaveChangesAlert, nil); + if (hitWhat == kSaveChanges) + { + if (wasHouseVersion < kHouseVersion) + ConvertHouseVer1To2(); + wasHouseVersion = kHouseVersion; + if (WriteHouse(true)) + return (true); + else + return (false); + } + else if (hitWhat == kDiscardChanges) + { + fileDirty = false; + if (!quitting) + { + whoCares = CloseHouse(); + if (OpenHouse()) + whoCares = ReadHouse(); + } + UpdateMenus(false); + return (true); + } + else + return (false); +} +#endif + +//-------------------------------------------------------------- YellowAlert +// This is a dialog used to present an error code and explanationÉ +// to the user when a non-lethal error has occurred. Ideally, ofÉ +// course, this never is called. + +void YellowAlert (short whichAlert, short identifier) +{ + #define kYellowAlert 1006 + Str255 errStr, errNumStr; + short whoCares; + + InitCursor(); + + GetIndString(errStr, kYellowAlert, whichAlert); + NumToString((long)identifier, errNumStr); + +// CenterAlert(kYellowAlert); + ParamText(errStr, errNumStr, PSTR(""), PSTR("")); + + whoCares = Alert(kYellowAlert, nil); +} + +//-------------------------------------------------------------- IsFileReadOnly + +Boolean IsFileReadOnly (FSSpec *theSpec) +{ + return false; + /* + Str255 tempStr; + ParamBlockRec theBlock; + HParamBlockRec hBlock; + VolumeParam *volPtr; + OSErr theErr; + + volPtr = (VolumeParam *)&theBlock; + volPtr->ioCompletion = nil; + volPtr->ioVolIndex = 0; + volPtr->ioNamePtr = tempStr; + volPtr->ioVRefNum = theSpec->vRefNum; + + theErr = PBGetVInfo(&theBlock, false); + if (CheckFileError(theErr, "\pRead/Write")) + { + if (((volPtr->ioVAtrb & 0x0080) == 0x0080) || + ((volPtr->ioVAtrb & 0x8000) == 0x8000)) + return (true); // soft/hard locked bits + else + { + hBlock.fileParam.ioCompletion = nil; + hBlock.fileParam.ioVRefNum = theSpec->vRefNum; + hBlock.fileParam.ioFVersNum = 0; + hBlock.fileParam.ioFDirIndex = 0; + hBlock.fileParam.ioNamePtr = theSpec->name; + hBlock.fileParam.ioDirID = theSpec->parID; + + theErr = PBHGetFInfo(&hBlock, false); + if (CheckFileError(theErr, "\pRead/Write")) + { + if ((hBlock.fileParam.ioFlAttrib & 0x0001) == 0x0001) + return (true); + else + return (false); + } + else + return (false); + } + } + else + return (false); + */ +} + diff --git a/GpApp/HouseInfo.cpp b/GpApp/HouseInfo.cpp new file mode 100644 index 0000000..67d7301 --- /dev/null +++ b/GpApp/HouseInfo.cpp @@ -0,0 +1,344 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// HouseInfo.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLNumberFormatting.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "DialogUtils.h" + + +#define kHouseInfoDialogID 1001 +#define kBannerTextItem 4 +#define kLockHouseButton 6 +#define kClearScoresButton 9 +#define kTrailerTextItem 11 +#define kNoPhoneCheck 14 +#define kBannerNCharsItem 15 +#define kTrailerNCharsItem 16 +#define kHouseSizeItem 18 +#define kLockHouseAlert 1029 +#define kZeroScoresAlert 1032 + + +long CountTotalHousePoints (void); +void UpdateHouseInfoDialog (DialogPtr); +Boolean HouseFilter (DialogPtr, EventRecord *, short *); +Boolean WarnLockingHouse (void); +void HowToZeroScores (void); + + +Str255 banner, trailer; +Rect houseEditText1, houseEditText2; +short houseCursorIs; +Boolean keyHit, tempPhoneBit; + +extern Cursor beamCursor; +extern Boolean noRoomAtAll, changeLockStateOfHouse, saveHouseLocked; +extern Boolean phoneBitSet; + +#ifndef COMPILEDEMO + + +//============================================================== Functions +//-------------------------------------------------------------- CountTotalHousePoints + +// The following functions all handle the "House Info" dialog in the editor. + +long CountTotalHousePoints (void) +{ + long pointTotal; + short numRooms, h, i; + char wasState; + + pointTotal = (long)RealRoomNumberCount() * (long)kRoomVisitScore; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + numRooms = (*thisHouse)->nRooms; + for (i = 0; i < numRooms; i++) + { + if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) + { + for (h = 0; h < kMaxRoomObs; h++) + { + switch ((*thisHouse)->rooms[i].objects[h].what) + { + case kRedClock: + pointTotal += kRedClockPoints; + break; + + case kBlueClock: + pointTotal += kBlueClockPoints; + break; + + case kYellowClock: + pointTotal += kYellowClockPoints; + break; + + case kCuckoo: + pointTotal += kCuckooClockPoints; + break; + + case kStar: + pointTotal += kStarPoints; + break; + + case kInvisBonus: + pointTotal += (*thisHouse)->rooms[i].objects[h].data.c.points; + break; + + default: + break; + } + } + } + } + + HSetState((Handle)thisHouse, wasState); + + return (pointTotal); +} + +//-------------------------------------------------------------- UpdateHouseInfoDialog + +void UpdateHouseInfoDialog (DialogPtr theDialog) +{ + short nChars; + + DrawDialog(theDialog); + nChars = GetDialogStringLen(theDialog, kBannerTextItem); + SetDialogNumToStr(theDialog, kBannerNCharsItem, (long)nChars); + nChars = GetDialogStringLen(theDialog, kTrailerTextItem); + SetDialogNumToStr(theDialog, kTrailerNCharsItem, (long)nChars); + SetDialogNumToStr(theDialog, kHouseSizeItem, CountTotalHousePoints()); + FrameDialogItemC(theDialog, 10, kRedOrangeColor8); + SetDialogItemValue(theDialog, kNoPhoneCheck, (short)tempPhoneBit); +} + +//-------------------------------------------------------------- HouseFilter + +Boolean HouseFilter (DialogPtr dial, EventRecord *event, short *item) +{ + Point mouseIs; + short nChars; + + if (keyHit) + { + nChars = GetDialogStringLen(dial, kBannerTextItem); + SetDialogNumToStr(dial, kBannerNCharsItem, (long)nChars); + nChars = GetDialogStringLen(dial, kTrailerTextItem); + SetDialogNumToStr(dial, kTrailerNCharsItem, (long)nChars); + keyHit = false; + } + + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + default: + keyHit = true; + return(false); + } + break; + + case mouseDown: + return(false); + break; + + case mouseUp: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateHouseInfoDialog(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + mouseIs = event->where; + GlobalToLocal(&mouseIs); + if ((PtInRect(mouseIs, &houseEditText1)) || + (PtInRect(mouseIs, &houseEditText2))) + { + if (houseCursorIs != kBeamCursor) + { + SetCursor(&beamCursor); + houseCursorIs = kBeamCursor; + } + } + else + { + if (houseCursorIs != kArrowCursor) + { + InitCursor(); + houseCursorIs = kArrowCursor; + } + } + return(false); + break; + } +} + +//-------------------------------------------------------------- DoHouseInfo + +void DoHouseInfo (void) +{ + DialogPtr houseInfoDialog; + Str255 versStr, loVers, nRoomsStr; + long h, v; + short item, numRooms, version; + char wasState; + Boolean leaving; + ModalFilterUPP houseFilterUPP; + + houseFilterUPP = NewModalFilterUPP(HouseFilter); + tempPhoneBit = phoneBitSet; + + wasState = HGetState((Handle)thisHouse); + numRooms = RealRoomNumberCount(); + HLock((Handle)thisHouse); + PasStringCopy((*thisHouse)->banner, banner); + PasStringCopy((*thisHouse)->trailer, trailer); + version = (*thisHouse)->version; + if (!noRoomAtAll) + { + h = (long)(*thisHouse)->rooms[(*thisHouse)->firstRoom].suite; + v = (long)(*thisHouse)->rooms[(*thisHouse)->firstRoom].floor; + } + HSetState((Handle)thisHouse, wasState); + + NumToString((long)version >> 8, versStr); // Convert version to two stringsÉ + NumToString((long)version % 0x0100, loVers); // the 1's and 1/10th's part. + NumToString((long)numRooms, nRoomsStr); // Number of rooms -> string. + + ParamText(versStr, loVers, nRoomsStr, PSTR("")); + +// CenterDialog(kHouseInfoDialogID); + houseInfoDialog = GetNewDialog(kHouseInfoDialogID, nil, kPutInFront); + if (houseInfoDialog == nil) + RedAlert(kErrDialogDidntLoad); + SetPort((GrafPtr)houseInfoDialog); + ShowWindow(GetDialogWindow(houseInfoDialog)); + + SetDialogString(houseInfoDialog, kBannerTextItem, banner); + SetDialogString(houseInfoDialog, kTrailerTextItem, trailer); + SelectDialogItemText(houseInfoDialog, kBannerTextItem, 0, 1024); + GetDialogItemRect(houseInfoDialog, kBannerTextItem, &houseEditText1); + GetDialogItemRect(houseInfoDialog, kTrailerTextItem, &houseEditText2); + houseCursorIs = kArrowCursor; + leaving = false; + + while (!leaving) + { + ModalDialog(houseFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogString(houseInfoDialog, kBannerTextItem, banner); + GetDialogString(houseInfoDialog, kTrailerTextItem, trailer); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + PasStringCopyNum(banner, (*thisHouse)->banner, 255); + PasStringCopyNum(trailer, (*thisHouse)->trailer, 255); + if (tempPhoneBit != phoneBitSet) + { + phoneBitSet = tempPhoneBit; + if (phoneBitSet) + (*thisHouse)->flags = (*thisHouse)->flags | 0x00000002; + else + (*thisHouse)->flags = (*thisHouse)->flags & 0xFFFFDFFD; + } + HSetState((Handle)thisHouse, wasState); + + fileDirty = true; + UpdateMenus(false); + leaving = true; + } + else if (item == kCancelButton) + leaving = true; + else if (item == kLockHouseButton) + { + if (WarnLockingHouse()) + { + changeLockStateOfHouse = true; + saveHouseLocked = true; + fileDirty = true; + UpdateMenus(false); + } + } + else if (item == kClearScoresButton) + HowToZeroScores(); + else if (item == kNoPhoneCheck) + { + tempPhoneBit = !tempPhoneBit; + SetDialogItemValue(houseInfoDialog, kNoPhoneCheck, (short)tempPhoneBit); + } + } + InitCursor(); + DisposeDialog(houseInfoDialog); + DisposeModalFilterUPP(houseFilterUPP); +} + +//-------------------------------------------------------------- WarnLockingHouse + +Boolean WarnLockingHouse (void) +{ + short hitWhat; + +// CenterAlert(kLockHouseAlert); + hitWhat = Alert(kLockHouseAlert, nil); + + return (hitWhat == 1); +} + +//-------------------------------------------------------------- HowToZeroScores + +void HowToZeroScores (void) +{ + short hitWhat; + +// CenterAlert(kZeroScoresAlert); + hitWhat = Alert(kZeroScoresAlert, nil); + + switch (hitWhat) + { + case 2: // zero all + ZeroHighScores(); + fileDirty = true; + UpdateMenus(false); + break; + + case 3: // zero all but highest + ZeroAllButHighestScore(); + fileDirty = true; + UpdateMenus(false); + break; + } +} + +#endif + diff --git a/GpApp/HouseLegal.cpp b/GpApp/HouseLegal.cpp new file mode 100644 index 0000000..ac8e711 --- /dev/null +++ b/GpApp/HouseLegal.cpp @@ -0,0 +1,1219 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// HouseLegal.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLNumberFormatting.h" +#include "PLStringCompare.h" +#include "Externs.h" +#include "ObjectEdit.h" +#include "RectUtils.h" + + +void WrapBannerAndTrailer (void); +void ValidateNumberOfRooms (void); +void CheckDuplicateFloorSuite (void); +void CompressHouse (void); +void LopOffExtraRooms (void); +void ValidateRoomNumbers (void); +void CountUntitledRooms (void); +void CheckRoomNameLength (void); +void MakeSureNumObjectsJives (void); +void KeepAllObjectsLegal (void); +void CheckForStaircasePairs (void); + + +short houseErrors, wasRoom; +Boolean isHouseChecks; + +extern short numberRooms; + + +//============================================================== Functions +//-------------------------------------------------------------- KeepObjectLegal + +// Does a test of the current object active for any illegal boundsÉ +// or values. It corrects the erros and returns true if any changesÉ +// were made. + +Boolean KeepObjectLegal (void) +{ + objectType *theObject; + Rect bounds, roomRect; + short direction, dist; + char wasState; + Boolean unchanged; + + unchanged = true; +#ifndef COMPILEDEMO + + theObject = &thisRoom->objects[objActive]; + + if (objActive == kInitialGliderSelected) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + if ((*thisHouse)->initial.h < 0) + (*thisHouse)->initial.h = 0; + if ((*thisHouse)->initial.v < 0) + (*thisHouse)->initial.v = 0; + if ((*thisHouse)->initial.h > (kRoomWide - kGliderWide)) + (*thisHouse)->initial.h = kRoomWide - kGliderWide; + if ((*thisHouse)->initial.v > (kTileHigh - kGliderHigh)) + (*thisHouse)->initial.v = kTileHigh - kGliderHigh; + HSetState((Handle)thisHouse, wasState); + return (true); + } + + QSetRect(&roomRect, 0, 0, kRoomWide, kTileHigh); + + switch (theObject->what) + { + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kLeftFan: + case kRightFan: + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + case kInvisBlower: + case kGrecoVent: + case kSewerBlower: + case kLiftArea: + GetObjectRect(&thisRoom->objects[objActive], &bounds); + if (ForceRectInRect(&bounds, &roomRect)) + { + theObject->data.a.topLeft.h = bounds.left; + theObject->data.a.topLeft.v = bounds.top; + unchanged = false; + if (theObject->what == kLiftArea) + { + theObject->data.a.distance = RectWide(&bounds); + theObject->data.a.tall = RectTall(&bounds) / 2; + } + } + if ((theObject->what == kStubby) && (theObject->data.a.topLeft.h % 2 == 0)) + { + theObject->data.a.topLeft.h--; + unchanged = false; + } + if (((theObject->what == kTaper) || (theObject->what == kCandle) || + (theObject->what == kTiki) || (theObject->what == kBBQ)) && + (theObject->data.a.topLeft.h % 2 != 0)) + { + theObject->data.a.topLeft.h--; + unchanged = false; + } + if ((theObject->what == kFloorVent) && (theObject->data.a.topLeft.v != kFloorVentTop)) + { + theObject->data.a.topLeft.v = kFloorVentTop; + theObject->data.a.distance += 2; + } + if ((theObject->what == kFloorBlower) && + (theObject->data.a.topLeft.v != kFloorBlowerTop)) + { + theObject->data.a.topLeft.v = kFloorBlowerTop; + theObject->data.a.distance += 2; + } + if ((theObject->what == kSewerGrate) && + (theObject->data.a.topLeft.v != kSewerGrateTop)) + { + theObject->data.a.topLeft.v = kSewerGrateTop; + theObject->data.a.distance += 2; + } + if ((theObject->what == kFloorTrans) && + (theObject->data.a.topLeft.v != kFloorTransTop)) + { + theObject->data.a.topLeft.v = kFloorTransTop; + theObject->data.a.distance += 2; + } + if (ObjectHasHandle(&direction, &dist)) + { + switch (direction) + { + case kAbove: + dist = bounds.top - dist; + if ((theObject->what == kFloorVent) || + (theObject->what == kFloorBlower) || + (theObject->what == kTaper) || + (theObject->what == kCandle) || + (theObject->what == kStubby)) + { + if (dist < 36) + { + theObject->data.a.distance += dist - 36; + unchanged = false; + } + } + else + { + if (dist < 0) + { + theObject->data.a.distance += dist; + unchanged = false; + } + } + break; + + case kToRight: + dist = bounds.right + dist; + if (dist > kRoomWide) + { + theObject->data.a.distance += (kRoomWide - dist); + unchanged = false; + } + break; + + case kBelow: + dist = bounds.bottom + dist; + if (dist > kTileHigh) + { + theObject->data.a.distance += (kTileHigh - dist); + unchanged = false; + } + break; + + case kToLeft: + dist = bounds.left - dist; + if (dist < 0) + { + theObject->data.a.distance += dist; + unchanged = false; + } + break; + } + } + break; + + case kTable: + case kShelf: + case kCabinet: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kCounter: + case kDresser: + case kDeckTable: + case kStool: + case kTrunk: + case kInvisObstacle: + case kManhole: + case kBooks: + case kInvisBounce: + GetObjectRect(&thisRoom->objects[objActive], &bounds); + if (ForceRectInRect(&bounds, &roomRect)) + { + theObject->data.b.bounds = bounds; + unchanged = false; + } + if ((theObject->what == kManhole) && + (((bounds.left - 3) % 64) != 0)) + { + theObject->data.b.bounds.left = + (((bounds.left + 29) / 64) * 64) + 3; + theObject->data.b.bounds.right = + theObject->data.b.bounds.left + + RectWide(&srcRects[kManhole]); + unchanged = false; + } + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kGreaseRt: + case kGreaseLf: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + case kSlider: + GetObjectRect(&thisRoom->objects[objActive], &bounds); + if (ForceRectInRect(&bounds, &roomRect)) + { + theObject->data.c.topLeft.h = bounds.left; + theObject->data.c.topLeft.v = bounds.top; + unchanged = false; + } + if ((theObject->what == kGreaseRt) && + (bounds.right + theObject->data.c.length > kRoomWide)) + { + theObject->data.c.length = kRoomWide - bounds.right; + unchanged = false; + } + else if ((theObject->what == kGreaseLf) && + (bounds.left - theObject->data.c.length < 0)) + { + theObject->data.c.length = bounds.left; + unchanged = false; + } + else if ((theObject->what == kSlider) && + (bounds.left + theObject->data.c.length > kRoomWide)) + { + theObject->data.c.length = kRoomWide - bounds.left; + unchanged = false; + } + if (theObject->data.c.topLeft.h % 2 != 0) + { + theObject->data.c.topLeft.h--; + unchanged = false; + } + if ((theObject->what != kStar) && + (theObject->data.c.length % 2 != 0)) + { + theObject->data.c.length--; + unchanged = false; + } + break; + + case kUpStairs: + case kDownStairs: + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kDoorInLf: + case kDoorInRt: + case kDoorExRt: + case kDoorExLf: + case kWindowInLf: + case kWindowInRt: + case kWindowExRt: + case kWindowExLf: + case kInvisTrans: + case kDeluxeTrans: + GetObjectRect(&thisRoom->objects[objActive], &bounds); + if (ForceRectInRect(&bounds, &roomRect)) + { + theObject->data.d.topLeft.h = bounds.left; + theObject->data.d.topLeft.v = bounds.top; + unchanged = false; + if (theObject->what == kDeluxeTrans) + { + theObject->data.d.tall = ((RectWide(&bounds) / 4) << 8) + + (RectTall(&bounds) / 4); + } + } + if ((theObject->what == kDoorInLf) || + (theObject->what == kDoorInRt)) + { + if (theObject->data.d.topLeft.h + + HalfRectWide(&srcRects[kDoorInLf]) > (kRoomWide / 2)) + { + theObject->data.d.topLeft.h = kDoorInRtLeft; + theObject->what = kDoorInRt; + } + else + { + theObject->data.d.topLeft.h = kDoorInLfLeft; + theObject->what = kDoorInLf; + } + } + if ((theObject->what == kDoorExRt) || + (theObject->what == kDoorExLf)) + { + if (theObject->data.d.topLeft.h + + HalfRectWide(&srcRects[kDoorExRt]) > (kRoomWide / 2)) + { + theObject->data.d.topLeft.h = kDoorExRtLeft; + theObject->what = kDoorExRt; + } + else + { + theObject->data.d.topLeft.h = kDoorExLfLeft; + theObject->what = kDoorExLf; + } + } + if ((theObject->what == kWindowInLf) || + (theObject->what == kWindowInRt)) + { + if (theObject->data.d.topLeft.h + + HalfRectWide(&srcRects[kWindowInLf]) > (kRoomWide / 2)) + { + theObject->data.d.topLeft.h = kWindowInRtLeft; + theObject->what = kWindowInRt; + } + else + { + theObject->data.d.topLeft.h = kWindowInLfLeft; + theObject->what = kWindowInLf; + } + } + if ((theObject->what == kWindowExRt) || + (theObject->what == kWindowExLf)) + { + if (theObject->data.d.topLeft.h + + HalfRectWide(&srcRects[kWindowExRt]) > (kRoomWide / 2)) + { + theObject->data.d.topLeft.h = kWindowExRtLeft; + theObject->what = kWindowExRt; + } + else + { + theObject->data.d.topLeft.h = kWindowExLfLeft; + theObject->what = kWindowExLf; + } + } + + if ((theObject->what == kInvisTrans) && + ((theObject->data.d.topLeft.v + + theObject->data.d.tall) > kTileHigh)) + { + theObject->data.d.tall = kTileHigh - + theObject->data.d.topLeft.v; + unchanged = false; + } + if ((theObject->what == kInvisTrans) && + (theObject->data.d.wide < 0)) + { + theObject->data.d.wide = 0; + unchanged = false; + } + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + GetObjectRect(&thisRoom->objects[objActive], &bounds); + if (ForceRectInRect(&bounds, &roomRect)) + { + theObject->data.e.topLeft.h = bounds.left; + theObject->data.e.topLeft.v = bounds.top; + unchanged = false; + } + if (theObject->data.e.topLeft.h % 2 != 0) + { + theObject->data.e.topLeft.h--; + unchanged = false; + } + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + GetObjectRect(&thisRoom->objects[objActive], &bounds); + if (ForceRectInRect(&bounds, &roomRect)) + { + if ((theObject->what == kFlourescent) || (theObject->what == kTrackLight)) + { + if (theObject->data.f.topLeft.h < bounds.left) + theObject->data.f.topLeft.h = bounds.left; + + if (theObject->data.f.topLeft.v < bounds.top) + theObject->data.f.topLeft.v = bounds.top; + + if ((theObject->data.f.topLeft.h + theObject->data.f.length) > bounds.right) + theObject->data.f.length = bounds.right - theObject->data.f.topLeft.h; + } + else + { + theObject->data.f.topLeft.h = bounds.left; + theObject->data.f.topLeft.v = bounds.top; + } + unchanged = false; + } + if (((theObject->what == kFlourescent) || + (theObject->what == kTrackLight)) && + ((bounds.right > kRoomWide) || (bounds.left < 0))) + { + if (theObject->data.f.topLeft.h < 0) + { + theObject->data.f.topLeft.h = 0; + unchanged = false; + } + if (bounds.left < 0) + { + bounds.left = 0; + unchanged = false; + } + if (theObject->data.f.topLeft.h > kRoomWide) + { + theObject->data.f.topLeft.h = kRoomWide; + unchanged = false; + } + if (bounds.right > kRoomWide) + { + bounds.right = kRoomWide; + unchanged = false; + } + theObject->data.f.length = kRoomWide - bounds.left; + } + break; + + case kShredder: + case kToaster: + case kMacPlus: + case kGuitar: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kStereo: + case kMicrowave: + case kCinderBlock: + case kFlowerBox: + case kCDs: + case kCustomPict: + GetObjectRect(&thisRoom->objects[objActive], &bounds); + if (ForceRectInRect(&bounds, &roomRect)) + { + theObject->data.g.topLeft.h = bounds.left; + theObject->data.g.topLeft.v = bounds.top; + unchanged = false; + } + if ((theObject->what == kToaster) && + (bounds.top - theObject->data.g.height < 0)) + { + theObject->data.g.height = bounds.top; + unchanged = false; + } + if ((theObject->what == kTV) && + (theObject->data.g.topLeft.h % 2 == 0)) + { + theObject->data.g.topLeft.h--; + unchanged = false; + } + if (((theObject->what == kToaster) || + (theObject->what == kMacPlus) || + (theObject->what == kCoffee) || + (theObject->what == kOutlet) || + (theObject->what == kVCR) || + (theObject->what == kStereo) || + (theObject->what == kMicrowave)) && + (theObject->data.g.topLeft.h % 2 != 0)) + { + theObject->data.g.topLeft.h--; + unchanged = false; + } + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kBall: + case kDrip: + case kFish: + case kCobweb: + GetObjectRect(&thisRoom->objects[objActive], &bounds); + if (ForceRectInRect(&bounds, &roomRect)) + { + theObject->data.h.topLeft.h = bounds.left; + theObject->data.h.topLeft.v = bounds.top; + unchanged = false; + } + if (((theObject->what == kBall) || + (theObject->what == kFish)) && + (bounds.top - theObject->data.h.length < 0)) + { + theObject->data.h.length = bounds.top; + unchanged = false; + } + if ((theObject->what == kDrip) && + (bounds.bottom + theObject->data.h.length > kTileHigh)) + { + theObject->data.h.length = kTileHigh - bounds.bottom; + unchanged = false; + } + if (((theObject->what == kBalloon) || + (theObject->what == kCopterLf) || + (theObject->what == kCopterRt) || + (theObject->what == kBall) || + (theObject->what == kDrip) || + (theObject->what == kFish)) && + (theObject->data.h.topLeft.h % 2 != 0)) + { + theObject->data.h.topLeft.h--; + unchanged = false; + } + break; + + case kOzma: + case kMirror: + case kMousehole: + case kFireplace: + case kFlower: + case kWallWindow: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + case kChimes: + GetObjectRect(&thisRoom->objects[objActive], &bounds); + if (ForceRectInRect(&bounds, &roomRect)) + { + theObject->data.i.bounds = bounds; + unchanged = false; + } + if (theObject->what == kMirror) + { + if (theObject->data.i.bounds.left % 2 != 0) + { + theObject->data.i.bounds.left--; + unchanged = false; + } + if (theObject->data.i.bounds.right % 2 != 0) + { + theObject->data.i.bounds.right--; + unchanged = false; + } + } + break; + + } + +#endif + + return (unchanged); +} + +//-------------------------------------------------------------- WrapBannerAndTrailer + +// Tries to wrap around the text of the banner and trailer messages. + +#ifndef COMPILEDEMO +void WrapBannerAndTrailer (void) +{ + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + WrapText((*thisHouse)->banner, 40); + WrapText((*thisHouse)->trailer, 64); + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- ValidateNumberOfRooms + +// Makes sure the number of room count and actual number of rooms match. + +void ValidateNumberOfRooms (void) +{ + long countedRooms, reportsRooms; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + reportsRooms = (long)(*thisHouse)->nRooms; + countedRooms = (GetHandleSize((Handle)thisHouse) - + sizeof(houseType)) / sizeof(roomType); + if (reportsRooms != countedRooms) + { + (*thisHouse)->nRooms = (short)countedRooms; + numberRooms = (*thisHouse)->nRooms; + houseErrors++; + } + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- CheckDuplicateFloorSuite + +// Error check, looks for rooms with the same floor suite (stacked). + +void CheckDuplicateFloorSuite (void) +{ + #define kRoomsTimesSuites 8192 + short i, numRooms, bitPlace; + char *pidgeonHoles; + char wasState; + + pidgeonHoles = (char *)NewPtrClear(sizeof(char) * kRoomsTimesSuites); + if (pidgeonHoles == nil) + return; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + numRooms = (*thisHouse)->nRooms; + for (i = 0; i < numRooms; i++) + { + if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) + { + bitPlace = (((*thisHouse)->rooms[i].floor + 7) * 128) + + (*thisHouse)->rooms[i].suite; + if ((bitPlace < 0) || (bitPlace >= 8192)) + DebugStr(PSTR("Blew array")); + if (pidgeonHoles[bitPlace] != 0) + { + houseErrors++; + (*thisHouse)->rooms[i].suite = kRoomIsEmpty; + } + else + pidgeonHoles[bitPlace]++; + } + } + + HSetState((Handle)thisHouse, wasState); + + DisposePtr((Ptr)pidgeonHoles); +} + +//-------------------------------------------------------------- CompressHouse + +// Removes place-holder (deleted) rooms from the middle of the file. + +void CompressHouse (void) +{ + short wasFirstRoom, roomNumber, probe; + char wasState; + Boolean compressing, probing; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + wasFirstRoom = (*thisHouse)->firstRoom; + compressing = true; + roomNumber = (*thisHouse)->nRooms - 1; // start with last room + do + { + if ((*thisHouse)->rooms[roomNumber].suite != kRoomIsEmpty) + { // if not an empty roomÉ + probe = 0; // start looking for empty slot + probing = true; + do + { // test room at probe to see if empty + if ((*thisHouse)->rooms[probe].suite == kRoomIsEmpty) + { // if it is, copy room there + (*thisHouse)->rooms[probe] = (*thisHouse)->rooms[roomNumber]; + (*thisHouse)->rooms[roomNumber].suite = kRoomIsEmpty; + if (roomNumber == wasFirstRoom) + (*thisHouse)->firstRoom = probe; + if (roomNumber == wasRoom) + wasRoom = probe; + probing = false; + } + probe++; // bump probe up to next room + if ((probing) && (probe >= roomNumber)) + { // we reached the current room + probing = false; // we can look no further + compressing = false; // so we can compress no more + } + } + while (probing); + } + roomNumber--; // go on to room preceding + if (roomNumber <= 0) // stop if we reach the first room + compressing = false; + } + while (compressing); + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- LopOffExtraRooms + +// Deletes all empty rooms hanging off the end of the house file. + +void LopOffExtraRooms (void) +{ + long newSize; + short r, count; + char wasState; + Str255 message; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + count = 0; + r = (*thisHouse)->nRooms; // begin at last room + do + { + r--; // look for trailing empties + if ((*thisHouse)->rooms[r].suite == kRoomIsEmpty) + count++; + else + r = 0; + } + while (r > 0); + + if (count > 0) // if there were trailing emptiesÉ + { + r = (*thisHouse)->nRooms - count; + newSize = sizeof(houseType) + (sizeof(roomType) * (long)r); + HUnlock((Handle)thisHouse); // resize house handle (shrink) + SetHandleSize((Handle)thisHouse, newSize); + if (MemError() != noErr) // problem? + { + ForeColor(redColor); + GetLocalizedString(16, message); + SetMessageWindowMessage(message); + } + HLock((Handle)thisHouse); // reflect new room count + (*thisHouse)->nRooms -= count; + numberRooms = (*thisHouse)->nRooms; + } + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- ValidateRoomNumbers + +// Error check - ensures that the floor and suite numbers are within legal ranges. + +void ValidateRoomNumbers (void) +{ + short i, numRooms; + char wasState; + Str255 message; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + numRooms = (*thisHouse)->nRooms; + if (numRooms < 0) + { + (*thisHouse)->nRooms = 0; + numRooms = 0; + } + for (i = 0; i < numRooms; i++) + { + if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) + { + if (((*thisHouse)->rooms[i].floor > 56) || + ((*thisHouse)->rooms[i].floor < -7)) + { + (*thisHouse)->rooms[i].suite = kRoomIsEmpty; + ForeColor(redColor); + GetLocalizedString(17, message); + SetMessageWindowMessage(message); + houseErrors++; + ForeColor(blackColor); + } + if (((*thisHouse)->rooms[i].suite >= 128) || + ((*thisHouse)->rooms[i].suite < 0)) + { + (*thisHouse)->rooms[i].suite = kRoomIsEmpty; + ForeColor(redColor); + GetLocalizedString(18, message); + SetMessageWindowMessage(message); + houseErrors++; + ForeColor(blackColor); + } + } + } + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- CountUntitledRooms + +// Returns the number of rooms left "Untitled". + +void CountUntitledRooms (void) +{ + short i, numRooms; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + numRooms = (*thisHouse)->nRooms; + for (i = 0; i < numRooms; i++) + { + if (((*thisHouse)->rooms[i].suite != kRoomIsEmpty) && + (EqualString((*thisHouse)->rooms[i].name, PSTR("Untitled Room"), false, true))) + houseErrors++; + } + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- CheckRoomNameLength + +// Error check - ensures the length of the room name is legal. + +void CheckRoomNameLength (void) +{ + short i, numRooms; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + numRooms = (*thisHouse)->nRooms; + for (i = 0; i < numRooms; i++) + { + (*thisHouse)->rooms[i].unusedByte = 0; + + if (((*thisHouse)->rooms[i].suite != kRoomIsEmpty) && + ((*thisHouse)->rooms[i].name[0] > 27)) + { + (*thisHouse)->rooms[i].name[0] = 27; + houseErrors++; + } + } + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- MakeSureNumObjectsJives + +// Error check - ensures the actual count of objects equals number of objects. + +void MakeSureNumObjectsJives (void) +{ + short i, h, numRooms, count; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + numRooms = (*thisHouse)->nRooms; + for (i = 0; i < numRooms; i++) + { + if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) + { + count = 0; + for (h = 0; h < kMaxRoomObs; h++) + { + if ((*thisHouse)->rooms[i].objects[h].what != kObjectIsEmpty) + count++; + } + if (count != (*thisHouse)->rooms[i].numObjects) + { + houseErrors++; + (*thisHouse)->rooms[i].numObjects = count; + } + } + } + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- KeepAllObjectsLegal + +// Repeatedly calls KeepObjectLegal() on ALL objects in a house. Wow! + +void KeepAllObjectsLegal (void) +{ + short i, h, numRooms; + char wasState; + Str255 message; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + numRooms = (*thisHouse)->nRooms; + for (i = 0; i < numRooms; i++) + { + if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) + { + ForceThisRoom(i); + for (h = 0; h < kMaxRoomObs; h++) + { + objActive = h; + if (thisRoom->objects[objActive].what != kObjectIsEmpty) + { + if (!KeepObjectLegal()) + { + ForeColor(redColor); + GetLocalizedString(19, message); + SetMessageWindowMessage(message); + houseErrors++; + ForeColor(blackColor); + DelayTicks(60); + } + } + } + CopyThisRoomToRoom(); + } + } + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- CheckForStaircasePairs + +// Ensures that for every up-stair there is a down-stair. + +void CheckForStaircasePairs (void) +{ + short i, h, g, numRooms, neighbor; + char wasState; + Boolean hasStairs; + Str255 message; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + numRooms = (*thisHouse)->nRooms; + for (i = 0; i < numRooms; i++) + { + if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) + { + for (h = 0; h < kMaxRoomObs; h++) + { + if ((*thisHouse)->rooms[i].objects[h].what == kUpStairs) + { + thisRoomNumber = i; + neighbor = GetNeighborRoomNumber(kNorthRoom); + if (neighbor == kRoomIsEmpty) + { + ForeColor(redColor); + GetLocalizedString(20, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + } + else + { + hasStairs = false; + for (g = 0; g < kMaxRoomObs; g++) + { + if ((*thisHouse)->rooms[neighbor].objects[g].what == + kDownStairs) + hasStairs = true; + } + if (!hasStairs) + { + ForeColor(redColor); + GetLocalizedString(21, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + } + } + } + else if ((*thisHouse)->rooms[i].objects[h].what == kDownStairs) + { + thisRoomNumber = i; + neighbor = GetNeighborRoomNumber(kSouthRoom); + if (neighbor == kRoomIsEmpty) + { + ForeColor(redColor); + GetLocalizedString(22, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + } + else + { + hasStairs = false; + for (g = 0; g < kMaxRoomObs; g++) + { + if ((*thisHouse)->rooms[neighbor].objects[g].what == + kUpStairs) + hasStairs = true; + } + if (!hasStairs) + { + ForeColor(redColor); + GetLocalizedString(23, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + } + } + } + } + } + } + + HSetState((Handle)thisHouse, wasState); +} +#endif + +//-------------------------------------------------------------- CheckHouseForProblems + +// Calls all the above functions and reports (and corrects) errors. + +void CheckHouseForProblems (void) +{ +#ifndef COMPILEDEMO + Str255 message, message2; + short wasActive; + + houseErrors = 0; + CopyThisRoomToRoom(); + wasRoom = thisRoomNumber; + wasActive = objActive; + GetLocalizedString(24, message); + OpenMessageWindow(message); + + SpinCursor(3); + GetLocalizedString(25, message); + SetMessageWindowMessage(message); + WrapBannerAndTrailer(); + + if (isHouseChecks) + { + SpinCursor(3); + GetLocalizedString(26, message); + SetMessageWindowMessage(message); + ValidateNumberOfRooms(); + if (houseErrors != 0) + { + GetLocalizedString(27, message); + SetMessageWindowMessage(message); + DelayTicks(60); + houseErrors = 0; + } + } + + if (isHouseChecks) + { + SpinCursor(3); + houseErrors = 0; + CheckDuplicateFloorSuite(); + if (houseErrors != 0) + { + NumToString((long)houseErrors, message); + GetLocalizedString(28, message2); + PasStringConcat(message, message2); + ForeColor(redColor); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(45); + } + } + + SpinCursor(3); + CompressHouse(); + SpinCursor(3); + LopOffExtraRooms(); + + if (isHouseChecks) + { + SpinCursor(3); + ValidateRoomNumbers(); + if (houseErrors != 0) + { + NumToString((long)houseErrors, message); + GetLocalizedString(29, message2); + PasStringConcat(message, message2); + ForeColor(redColor); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + } + } + + if (isHouseChecks) + { + SpinCursor(3); + houseErrors = 0; + CountUntitledRooms(); + if (houseErrors != 0) + { + NumToString((long)houseErrors, message); + GetLocalizedString(30, message2); + PasStringConcat(message, message2); + ForeColor(blueColor); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(45); + } + } + + if (isHouseChecks) + { + SpinCursor(3); + houseErrors = 0; + CheckRoomNameLength(); + if (houseErrors != 0) + { + NumToString((long)houseErrors, message); + GetLocalizedString(31, message2); + PasStringConcat(message, message2); + ForeColor(blueColor); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(45); + } + } + + if (isHouseChecks) + { + SpinCursor(3); + houseErrors = 0; + MakeSureNumObjectsJives(); + if (houseErrors != 0) + { + NumToString((long)houseErrors, message); + GetLocalizedString(32, message2); + PasStringConcat(message, message2); + ForeColor(redColor); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + } + } + + if (isHouseChecks) + { + SpinCursor(3); + houseErrors = 0; + GetLocalizedString(33, message); + SetMessageWindowMessage(message); + KeepAllObjectsLegal(); + if (houseErrors != 0) + { + NumToString((long)houseErrors, message); + GetLocalizedString(34, message2); + PasStringConcat(message, message2); + ForeColor(redColor); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + } + } + + if (isHouseChecks) + { + SpinCursor(3); + houseErrors = 0; + CheckForStaircasePairs(); + } + + if (isHouseChecks) + { + SpinCursor(3); + if (CountStarsInHouse() < 1) + { + ForeColor(redColor); + GetLocalizedString(35, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + } + } + + InitCursor(); + CloseMessageWindow(); + ForceThisRoom(wasRoom); + objActive = wasActive; +#endif +} + diff --git a/GpApp/Input.cpp b/GpApp/Input.cpp new file mode 100644 index 0000000..76ce835 --- /dev/null +++ b/GpApp/Input.cpp @@ -0,0 +1,399 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Input.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLToolUtils.h" +#include "PLDialogs.h" +#include "Externs.h" +#include "MainWindow.h" +#include "RectUtils.h" + + +#define kNormalThrust 5 +#define kHyperThrust 8 +#define kHeliumLift 4 +#define kEscPausePictID 1015 +#define kTabPausePictID 1016 +#define kSavingGameDial 1042 + + +void LogDemoKey (char); +void DoCommandKey (void); +void DoPause (void); +void DoBatteryEngaged (gliderPtr); +void DoHeliumEngaged (gliderPtr); +Boolean QuerySaveGame (void); + + +demoPtr demoData; +KeyMap theKeys; +DialogPtr saveDial; +short demoIndex, batteryFrame; +Boolean isEscPauseKey, paused, batteryWasEngaged; + +extern long gameFrame; +extern short otherPlayerEscaped; +extern Boolean quitting, playing, onePlayerLeft, twoPlayerGame, demoGoing; + + +//============================================================== Functions +//-------------------------------------------------------------- LogDemoKey + +void LogDemoKey (char keyIs) +{ + demoData[demoIndex].frame = gameFrame; + demoData[demoIndex].key = keyIs; + demoIndex++; +} + +//-------------------------------------------------------------- DoCommandKey + +void DoCommandKey (void) +{ + if (BitTst(&theKeys, kQKeyMap)) + { + playing = false; + paused = false; + if ((!twoPlayerGame) && (!demoGoing)) + { + if (QuerySaveGame()) + SaveGame2(); // New save game. + } + } + else if ((BitTst(&theKeys, kSKeyMap)) && (!twoPlayerGame)) + { + RefreshScoreboard(kSavingTitleMode); + SaveGame2(); // New save game. + HideCursor(); + CopyRectWorkToMain(&workSrcRect); + RefreshScoreboard(kNormalTitleMode); + } +} + +//-------------------------------------------------------------- DoPause + +void DoPause (void) +{ + Rect bounds; + + SetPort((GrafPtr)mainWindow); + QSetRect(&bounds, 0, 0, 214, 54); + CenterRectInRect(&bounds, &houseRect); + if (isEscPauseKey) + LoadScaledGraphic(kEscPausePictID, &bounds); + else + LoadScaledGraphic(kTabPausePictID, &bounds); + + do + { + GetKeys(theKeys); + } + while ((isEscPauseKey && BitTst(&theKeys, kEscKeyMap)) || + (!isEscPauseKey && BitTst(&theKeys, kTabKeyMap))); + + paused = true; + while (paused) + { + GetKeys(theKeys); + if ((isEscPauseKey && BitTst(&theKeys, kEscKeyMap)) || + (!isEscPauseKey && BitTst(&theKeys, kTabKeyMap))) + paused = false; + else if (BitTst(&theKeys, kCommandKeyMap)) + DoCommandKey(); + } + + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &bounds, &bounds, srcCopy, nil); + + do + { + GetKeys(theKeys); + } + while ((isEscPauseKey && BitTst(&theKeys, kEscKeyMap)) || + (!isEscPauseKey && BitTst(&theKeys, kTabKeyMap))); +} + +//-------------------------------------------------------------- DoBatteryEngaged + +void DoBatteryEngaged (gliderPtr thisGlider) +{ + if (thisGlider->facing == kFaceLeft) + { + if (thisGlider->tipped) + thisGlider->hVel += kHyperThrust; + else + thisGlider->hVel -= kHyperThrust; + } + else + { + if (thisGlider->tipped) + thisGlider->hVel -= kHyperThrust; + else + thisGlider->hVel += kHyperThrust; + } + + batteryTotal--; + + if (batteryTotal == 0) + { + QuickBatteryRefresh(false); + PlayPrioritySound(kFizzleSound, kFizzlePriority); + } + else + { + if (!batteryWasEngaged) + batteryFrame = 0; + if (batteryFrame == 0) + PlayPrioritySound(kThrustSound, kThrustPriority); + batteryFrame++; + if (batteryFrame >= 4) + batteryFrame = 0; + batteryWasEngaged = true; + } +} + +//-------------------------------------------------------------- DoHeliumEngaged + +void DoHeliumEngaged (gliderPtr thisGlider) +{ + thisGlider->vDesiredVel = -kHeliumLift; + batteryTotal++; + + if (batteryTotal == 0) + { + QuickBatteryRefresh(false); + PlayPrioritySound(kFizzleSound, kFizzlePriority); + batteryWasEngaged = false; + } + else + { + if (!batteryWasEngaged) + batteryFrame = 0; + if (batteryFrame == 0) + PlayPrioritySound(kHissSound, kHissPriority); + batteryFrame++; + if (batteryFrame >= 4) + batteryFrame = 0; + batteryWasEngaged = true; + } +} + +//-------------------------------------------------------------- GetDemoInput + + void GetDemoInput (gliderPtr thisGlider) + { + if (thisGlider->which == kPlayer1) + { + GetKeys(theKeys); + +#if BUILD_ARCADE_VERSION + + if ((BitTst(&theKeys, thisGlider->leftKey)) || + (BitTst(&theKeys, thisGlider->rightKey)) || + (BitTst(&theKeys, thisGlider->battKey)) || + (BitTst(&theKeys, thisGlider->bandKey))) + { + playing = false; + paused = false; + } + +#else + + if (BitTst(&theKeys, kCommandKeyMap)) + DoCommandKey(); + +#endif + } + + if (thisGlider->mode == kGliderBurning) + { + if (thisGlider->facing == kFaceLeft) + thisGlider->hDesiredVel -= kNormalThrust; + else + thisGlider->hDesiredVel += kNormalThrust; + } + else + { + thisGlider->heldLeft = false; + thisGlider->heldRight = false; + thisGlider->tipped = false; + + if (gameFrame == (long)demoData[demoIndex].frame) + { + switch (demoData[demoIndex].key) + { + case 0: // left key + thisGlider->hDesiredVel += kNormalThrust; + thisGlider->tipped = (thisGlider->facing == kFaceLeft); + thisGlider->heldRight = true; + thisGlider->fireHeld = false; + break; + + case 1: // right key + thisGlider->hDesiredVel -= kNormalThrust; + thisGlider->tipped = (thisGlider->facing == kFaceRight); + thisGlider->heldLeft = true; + thisGlider->fireHeld = false; + break; + + case 2: // battery key + if (batteryTotal > 0) + DoBatteryEngaged(thisGlider); + else + DoHeliumEngaged(thisGlider); + thisGlider->fireHeld = false; + break; + + case 3: // rubber band key + if (!thisGlider->fireHeld) + { + if (AddBand(thisGlider, thisGlider->dest.left + 24, + thisGlider->dest.top + 10, thisGlider->facing)) + { + bandsTotal--; + if (bandsTotal <= 0) + QuickBandsRefresh(false); + + thisGlider->fireHeld = true; + } + } + break; + } + + demoIndex++; + } + else + thisGlider->fireHeld = false; + + if ((isEscPauseKey && BitTst(&theKeys, kEscKeyMap)) || + (!isEscPauseKey && BitTst(&theKeys, kTabKeyMap))) + { + DoPause(); + } + } + } + +//-------------------------------------------------------------- GetInput + +void GetInput (gliderPtr thisGlider) +{ + if (thisGlider->which == kPlayer1) + { + GetKeys(theKeys); + if (BitTst(&theKeys, kCommandKeyMap)) + DoCommandKey(); + } + + if (thisGlider->mode == kGliderBurning) + { + if (thisGlider->facing == kFaceLeft) + thisGlider->hDesiredVel -= kNormalThrust; + else + thisGlider->hDesiredVel += kNormalThrust; + } + else + { + thisGlider->heldLeft = false; + thisGlider->heldRight = false; + if (BitTst(&theKeys, thisGlider->rightKey)) // right key + { + #ifdef CREATEDEMODATA + LogDemoKey(0); + #endif + if (BitTst(&theKeys, thisGlider->leftKey)) + { + ToggleGliderFacing(thisGlider); + thisGlider->heldLeft = true; + } + else + { + thisGlider->hDesiredVel += kNormalThrust; + thisGlider->tipped = (thisGlider->facing == kFaceLeft); + thisGlider->heldRight = true; + } + } + else if (BitTst(&theKeys, thisGlider->leftKey)) // left key + { + #ifdef CREATEDEMODATA + LogDemoKey(1); + #endif + thisGlider->hDesiredVel -= kNormalThrust; + thisGlider->tipped = (thisGlider->facing == kFaceRight); + thisGlider->heldLeft = true; + } + else + thisGlider->tipped = false; + + if ((BitTst(&theKeys, thisGlider->battKey)) && (batteryTotal != 0) && + (thisGlider->mode == kGliderNormal)) + { + #ifdef CREATEDEMODATA + LogDemoKey(2); + #endif + if (batteryTotal > 0) + DoBatteryEngaged(thisGlider); + else + DoHeliumEngaged(thisGlider); + } + else + batteryWasEngaged = false; + + if ((BitTst(&theKeys, thisGlider->bandKey)) && (bandsTotal > 0) && + (thisGlider->mode == kGliderNormal)) + { + #ifdef CREATEDEMODATA + LogDemoKey(3); + #endif + if (!thisGlider->fireHeld) + { + if (AddBand(thisGlider, thisGlider->dest.left + 24, + thisGlider->dest.top + 10, thisGlider->facing)) + { + bandsTotal--; + if (bandsTotal <= 0) + QuickBandsRefresh(false); + + thisGlider->fireHeld = true; + } + } + } + else + thisGlider->fireHeld = false; + + if ((otherPlayerEscaped != kNoOneEscaped) && + (BitTst(&theKeys, kDeleteKeyMap)) && + (thisGlider->which) && (!onePlayerLeft)) + { + ForceKillGlider(); + } + + if ((isEscPauseKey && BitTst(&theKeys, kEscKeyMap)) || + (!isEscPauseKey && BitTst(&theKeys, kTabKeyMap))) + { + DoPause(); + } + } +} + +//-------------------------------------------------------------- QuerySaveGame + +Boolean QuerySaveGame (void) +{ + #define kSaveGameAlert 1041 + #define kYesSaveGameButton 1 + short hitWhat; + + InitCursor(); + FlushEvents(everyEvent, 0); +// CenterAlert(kSaveGameAlert); + hitWhat = Alert(kSaveGameAlert, nil); + if (hitWhat == kYesSaveGameButton) + return (true); + else + return (false); +} + diff --git a/GpApp/Interactions.cpp b/GpApp/Interactions.cpp new file mode 100644 index 0000000..739cd9d --- /dev/null +++ b/GpApp/Interactions.cpp @@ -0,0 +1,1777 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Interactions.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "RectUtils.h" + + +#define kFloorVentLift -6 +#define kCeilingVentDrop 8 +#define kFanStrength 12 +#define kBatterySupply 50 // about 2 rooms worth of thrust +#define kHeliumSupply 150 +#define kBandsSupply 8 +#define kFoilSupply 8 + + +Boolean GliderHitTop (gliderPtr, Rect *); +Boolean GliderInRect (gliderPtr, Rect *); +void BounceGlider (gliderPtr, Rect *); +void CheckEscapeUpTwo (gliderPtr); +void CheckEscapeUp (gliderPtr); +void CheckEscapeDownTwo (gliderPtr); +void CheckEscapeDown (gliderPtr); +void CheckRoofCollision (gliderPtr); +void CheckEscapeLeftTwo (gliderPtr); +void CheckEscapeLeft (gliderPtr); +void CheckEscapeRightTwo (gliderPtr); +void CheckEscapeRight (gliderPtr); +void CheckGliderInRoom (gliderPtr); +void HandleRewards (gliderPtr, hotPtr); +void HandleMicrowaveAction (hotPtr, gliderPtr); +void HandleHotSpotCollision (gliderPtr, hotPtr, short); +void CheckForHotSpots (void); +void WebGlider (gliderPtr, Rect *); + + +short otherPlayerEscaped, activeRectEscaped; + +extern hotPtr hotSpots; +extern short nHotSpots, leftThresh, rightThresh, thisTiles[]; +extern short localNumbers[], thisBackground, numStarsRemaining; +extern Boolean leftOpen, rightOpen, topOpen, bottomOpen, evenFrame; +extern Boolean twoPlayerGame, newState, onePlayerLeft, playerDead; + + +//============================================================== Functions +//-------------------------------------------------------------- GliderHitSides + +Boolean GliderHitTop (gliderPtr thisGlider, Rect *theRect) +{ + Rect glideBounds; + short offset; + Boolean hitTop; + + glideBounds.left = thisGlider->dest.left + 5; + glideBounds.top = thisGlider->dest.top + 5; + glideBounds.right = thisGlider->dest.right - 5; + glideBounds.bottom = thisGlider->dest.bottom - 5; + + glideBounds.left -= thisGlider->wasHVel; + glideBounds.right -= thisGlider->wasHVel; + + if (theRect->bottom < glideBounds.top) + hitTop = false; + else if (theRect->top > glideBounds.bottom) + hitTop = false; + else if (theRect->right < glideBounds.left) + hitTop = false; + else if (theRect->left > glideBounds.right) + hitTop = false; + else + hitTop = true; + + if (!hitTop) + { + PlayPrioritySound(kFoilHitSound, kFoilHitPriority); + foilTotal--; + if (foilTotal <= 0) + StartGliderFoilLosing(thisGlider); + + glideBounds.left += thisGlider->wasHVel; + glideBounds.right += thisGlider->wasHVel; + if (thisGlider->hVel > 0) + offset = 2 + glideBounds.right - theRect->left; + else + offset = 2 + glideBounds.left - theRect->right; + + thisGlider->hVel = -thisGlider->hVel - offset; + } + + return (hitTop); +} + +//-------------------------------------------------------------- SectGlider + +Boolean SectGlider (gliderPtr thisGlider, Rect *theRect, Boolean scrutinize) +{ + Rect glideBounds; + Boolean itHit; + + glideBounds = thisGlider->dest; + if (thisGlider->mode == kGliderBurning) + glideBounds.top += 6; + + if (scrutinize) + { + glideBounds.left += 5; + glideBounds.top += 5; + glideBounds.right -= 5; + glideBounds.bottom -= 5; + } + + if (theRect->bottom < glideBounds.top) + itHit = false; + else if (theRect->top > glideBounds.bottom) + itHit = false; + else if (theRect->right < glideBounds.left) + itHit = false; + else if (theRect->left > glideBounds.right) + itHit = false; + else + itHit = true; + + return (itHit); +} + +//-------------------------------------------------------------- GliderInRect + +Boolean GliderInRect (gliderPtr thisGlider, Rect *theRect) +{ + Rect glideBounds; + + glideBounds = thisGlider->dest; + + if (glideBounds.top < theRect->top) + return (false); + else if (glideBounds.bottom > theRect->bottom) + return (false); + else if (glideBounds.left < theRect->left) + return (false); + else if (glideBounds.right > theRect->right) + return (false); + else + return (true); +} + +//-------------------------------------------------------------- BounceGlider + +void BounceGlider (gliderPtr thisGlider, Rect *theRect) +{ + Rect glideBounds; + + glideBounds = thisGlider->dest; + if ((theRect->right - glideBounds.left) < (glideBounds.right - theRect->left)) + thisGlider->hVel = theRect->right - glideBounds.left; + else + thisGlider->hVel = theRect->left - glideBounds.right; + if (foilTotal > 0) + PlayPrioritySound(kFoilHitSound, kFoilHitPriority); + else + PlayPrioritySound(kHitWallSound, kHitWallPriority); +} + +//-------------------------------------------------------------- CheckEscapeUpTwo + +void CheckEscapeUpTwo (gliderPtr thisGlider) +{ + short offset, leftTile, rightTile; + + if (topOpen) + { + if (thisGlider->dest.top < kNoCeilingLimit) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + otherPlayerEscaped = kPlayerEscapedUp; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + else if (otherPlayerEscaped == kPlayerEscapedUp) + { + otherPlayerEscaped = kNoOneEscaped; + MoveRoomToRoom(thisGlider, kAbove); + } + else + { + PlayPrioritySound(kDontExitSound, kDontExitPriority); + offset = kNoCeilingLimit - thisGlider->dest.top; + thisGlider->vVel = -thisGlider->vVel + offset; + } + } + } + else if (thisBackground == kDirt) + { + leftTile = thisGlider->dest.left >> 6; // Ö 64 + rightTile = thisGlider->dest.right >> 6; // Ö 64 + + if ((leftTile >= 0) && (leftTile < 8) && + (rightTile >= 0) && (rightTile < 8)) + { + if (((thisTiles[leftTile] == 5) || + (thisTiles[leftTile] == 6)) && + ((thisTiles[rightTile] == 5) || + (thisTiles[rightTile] == 6))) + { + if (thisGlider->dest.top < kNoCeilingLimit) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + otherPlayerEscaped = kPlayerEscapedUp; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + else if (otherPlayerEscaped == kPlayerEscapedUp) + { + otherPlayerEscaped = kNoOneEscaped; + MoveRoomToRoom(thisGlider, kAbove); + } + else + { + PlayPrioritySound(kDontExitSound, kDontExitPriority); + offset = kNoCeilingLimit - thisGlider->dest.top; + thisGlider->vVel = -thisGlider->vVel + offset; + } + } + } + else + thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; + } + else + thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; + } + else + thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; +} + +//-------------------------------------------------------------- CheckEscapeUp + +void CheckEscapeUp (gliderPtr thisGlider) +{ + short leftTile, rightTile; + + if (topOpen) + { + if (thisGlider->dest.top < kNoCeilingLimit) + { + MoveRoomToRoom(thisGlider, kAbove); + } + } + else if (thisBackground == kDirt) + { + leftTile = thisGlider->dest.left >> 6; // Ö 64 + rightTile = thisGlider->dest.right >> 6; // Ö 64 + + if ((leftTile >= 0) && (leftTile < 8) && + (rightTile >= 0) && (rightTile < 8)) + { + if (((thisTiles[leftTile] == 5) || + (thisTiles[leftTile] == 6)) && + ((thisTiles[rightTile] == 5) || + (thisTiles[rightTile] == 6))) + { + if (thisGlider->dest.top < kNoCeilingLimit) + MoveRoomToRoom(thisGlider, kAbove); + } + else + thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; + } + else + thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; + } + else + thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; +} + +//-------------------------------------------------------------- CheckEscapeDownTwo + +void CheckEscapeDownTwo (gliderPtr thisGlider) +{ + short offset, leftTile, rightTile; + + if (bottomOpen) + { + if (thisGlider->dest.bottom > kNoFloorLimit) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + otherPlayerEscaped = kPlayerEscapedDown; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + else if (otherPlayerEscaped == kPlayerEscapedDown) + { + otherPlayerEscaped = kNoOneEscaped; + MoveRoomToRoom(thisGlider, kBelow); + } + else + { + PlayPrioritySound(kDontExitSound, kDontExitPriority); + offset = kNoFloorLimit - thisGlider->dest.bottom; + thisGlider->vVel = -thisGlider->vVel + offset; + } + } + } + else if (thisBackground == kDirt) + { + leftTile = thisGlider->dest.left >> 6; // Ö 64 + rightTile = thisGlider->dest.right >> 6; // Ö 64 + + if ((leftTile >= 0) && (leftTile < 8) && + (rightTile >= 0) && (rightTile < 8)) + { + if (((thisTiles[leftTile] == 2) || + (thisTiles[leftTile] == 3)) && + ((thisTiles[rightTile] == 2) || + (thisTiles[rightTile] == 3))) + { + if (thisGlider->dest.bottom > kNoFloorLimit) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + otherPlayerEscaped = kPlayerEscapedDown; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + else if (otherPlayerEscaped == kPlayerEscapedDown) + { + otherPlayerEscaped = kNoOneEscaped; + MoveRoomToRoom(thisGlider, kBelow); + } + else + { + PlayPrioritySound(kDontExitSound, kDontExitPriority); + offset = kNoFloorLimit - thisGlider->dest.bottom; + thisGlider->vVel = -thisGlider->vVel + offset; + } + } + } + else + { + if (thisGlider->ignoreGround) + { + if (thisGlider->dest.bottom > kNoFloorLimit) + MoveRoomToRoom(thisGlider, kBelow); + } + else + { + thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } + } + } + else + { + if (thisGlider->ignoreGround) + { + if (thisGlider->dest.bottom > kNoFloorLimit) + MoveRoomToRoom(thisGlider, kBelow); + } + else + { + thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } +} + +//-------------------------------------------------------------- CheckEscapeDown + +void CheckEscapeDown (gliderPtr thisGlider) +{ + short leftTile, rightTile; + + if (bottomOpen) + { + if (thisGlider->dest.bottom > kNoFloorLimit) + { + MoveRoomToRoom(thisGlider, kBelow); + } + } + else if (thisBackground == kDirt) + { + leftTile = thisGlider->dest.left >> 6; // Ö 64 + rightTile = thisGlider->dest.right >> 6; // Ö 64 + + if ((leftTile >= 0) && (leftTile < 8) && (rightTile >= 0) && (rightTile < 8)) + { + if (((thisTiles[leftTile] == 2) || (thisTiles[leftTile] == 3)) && + ((thisTiles[rightTile] == 2) || (thisTiles[rightTile] == 3))) + { + if (thisGlider->dest.bottom > kNoFloorLimit) + MoveRoomToRoom(thisGlider, kBelow); + } + else + { + if (thisGlider->ignoreGround) + { + if (thisGlider->dest.bottom > kNoFloorLimit) + MoveRoomToRoom(thisGlider, kBelow); + } + else + { + thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } + } + else + { + if (thisGlider->ignoreGround) + { + if (thisGlider->dest.bottom > kNoFloorLimit) + MoveRoomToRoom(thisGlider, kBelow); + } + else + { + thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } + } + else + { + if (thisGlider->ignoreGround) + { + if (thisGlider->dest.bottom > kNoFloorLimit) + MoveRoomToRoom(thisGlider, kBelow); + } + else + { + thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } +} + +//-------------------------------------------------------------- CheckRoofCollision + +void CheckRoofCollision (gliderPtr thisGlider) +{ + short offset, tileOver; + + offset = (thisGlider->dest.left + kHalfGliderWide) >> 6; // Ö 64 + if ((offset >= 0) && (offset <= 7) && (!thisGlider->sliding)) + { + tileOver = thisTiles[offset]; + if (tileOver == 1) + { + if (((thisGlider->dest.left + kHalfGliderWide) - (offset << 6)) > + (250 - thisGlider->dest.bottom)) + { + thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } + else if (tileOver == 2) + { + if (((thisGlider->dest.left + kHalfGliderWide) - (offset << 6)) > + (186 - thisGlider->dest.bottom)) + { + thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } + else if (tileOver == 5) + { + if ((64 - ((thisGlider->dest.left + kHalfGliderWide) - (offset << 6))) > + (186 - thisGlider->dest.bottom)) + { + thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } + else if (tileOver == 6) + { + if ((64 - ((thisGlider->dest.left + kHalfGliderWide) - (offset << 6))) > + (250 - thisGlider->dest.bottom)) + { + thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } + else + { + thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } +} + +//-------------------------------------------------------------- CheckEscapeLeftTwo + +void CheckEscapeLeftTwo (gliderPtr thisGlider) +{ + short offset; + + if (leftThresh == kLeftWallLimit) + { + if (thisGlider->ignoreLeft) + { + if (thisGlider->dest.left < kNoLeftWallLimit) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + otherPlayerEscaped = kPlayerEscapedLeft; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + else if (otherPlayerEscaped == kPlayerEscapedLeft) + { + otherPlayerEscaped = kNoOneEscaped; + MoveRoomToRoom(thisGlider, kToLeft); + } + else + { + PlayPrioritySound(kDontExitSound, kDontExitPriority); + offset = kNoLeftWallLimit - thisGlider->dest.left; + thisGlider->hVel = -thisGlider->hVel + offset; + } + } + } + else + { + if (foilTotal > 0) + PlayPrioritySound(kFoilHitSound, kFoilHitPriority); + else + PlayPrioritySound(kHitWallSound, kHitWallPriority); + offset = kLeftWallLimit - thisGlider->dest.left; + thisGlider->hVel = -thisGlider->hVel + offset; + } + } + else + { + if (otherPlayerEscaped == kNoOneEscaped) + { + otherPlayerEscaped = kPlayerEscapedLeft; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + else if (otherPlayerEscaped == kPlayerEscapedLeft) + { + otherPlayerEscaped = kNoOneEscaped; + MoveRoomToRoom(thisGlider, kToLeft); + } + else + { + PlayPrioritySound(kDontExitSound, kDontExitPriority); + offset = kNoLeftWallLimit - thisGlider->dest.left; + thisGlider->hVel = -thisGlider->hVel + offset; + } + } +} + +//-------------------------------------------------------------- CheckEscapeLeft + +void CheckEscapeLeft (gliderPtr thisGlider) +{ + short offset; + + if (leftThresh == kLeftWallLimit) + { + if (thisGlider->ignoreLeft) + { + if (thisGlider->dest.left < kNoLeftWallLimit) + MoveRoomToRoom(thisGlider, kToLeft); + } + else + { + if (foilTotal > 0) + PlayPrioritySound(kFoilHitSound, kFoilHitPriority); + else + PlayPrioritySound(kHitWallSound, kHitWallPriority); + offset = kLeftWallLimit - thisGlider->dest.left; + thisGlider->hVel = -thisGlider->hVel + offset; + } + } + else + MoveRoomToRoom(thisGlider, kToLeft); +} + +//-------------------------------------------------------------- CheckEscapeRightTwo + +void CheckEscapeRightTwo (gliderPtr thisGlider) +{ + short offset; + + if (rightThresh == kRightWallLimit) + { + if (thisGlider->ignoreRight) + { + if (thisGlider->dest.right > kNoRightWallLimit) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + otherPlayerEscaped = kPlayerEscapedRight; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + else if (otherPlayerEscaped == kPlayerEscapedRight) + { + otherPlayerEscaped = kNoOneEscaped; + MoveRoomToRoom(thisGlider, kToRight); + } + else + { + PlayPrioritySound(kDontExitSound, kDontExitPriority); + offset = kNoRightWallLimit - thisGlider->dest.right; + thisGlider->hVel = -thisGlider->hVel + offset; + } + } + } + else + { + if (foilTotal > 0) + PlayPrioritySound(kFoilHitSound, kFoilHitPriority); + else + PlayPrioritySound(kHitWallSound, kHitWallPriority); + offset = kRightWallLimit - thisGlider->dest.right; + thisGlider->hVel = -thisGlider->hVel + offset; + } + } + else + { + if (otherPlayerEscaped == kNoOneEscaped) + { + otherPlayerEscaped = kPlayerEscapedRight; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + else if (otherPlayerEscaped == kPlayerEscapedRight) + { + otherPlayerEscaped = kNoOneEscaped; + MoveRoomToRoom(thisGlider, kToRight); + } + else + { + PlayPrioritySound(kDontExitSound, kDontExitPriority); + offset = kNoRightWallLimit - thisGlider->dest.right; + thisGlider->hVel = -thisGlider->hVel + offset; + } + } +} + +//-------------------------------------------------------------- CheckEscapeRight + +void CheckEscapeRight (gliderPtr thisGlider) +{ + short offset; + + if (rightThresh == kRightWallLimit) + { + if (thisGlider->ignoreRight) + { + if (thisGlider->dest.right > kNoRightWallLimit) + MoveRoomToRoom(thisGlider, kToRight); + } + else + { + if (foilTotal > 0) + PlayPrioritySound(kFoilHitSound, kFoilHitPriority); + else + PlayPrioritySound(kHitWallSound, kHitWallPriority); + offset = kRightWallLimit - thisGlider->dest.right; + thisGlider->hVel = -thisGlider->hVel + offset; + } + } + else + MoveRoomToRoom(thisGlider, kToRight); +} + +//-------------------------------------------------------------- CheckGliderInRoom + +void CheckGliderInRoom (gliderPtr thisGlider) +{ + if ((thisGlider->mode == kGliderNormal) || + (thisGlider->mode == kGliderFaceLeft) || + (thisGlider->mode == kGliderFaceRight) || + (thisGlider->mode == kGliderBurning)) + { + if (thisGlider->dest.top < kCeilingLimit) + { + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if ((twoPlayerGame) && (!onePlayerLeft)) + CheckEscapeUpTwo(thisGlider); + else + CheckEscapeUp(thisGlider); + } + else if (thisGlider->dest.bottom > kFloorLimit) + { + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if ((twoPlayerGame) && (!onePlayerLeft)) + CheckEscapeDownTwo(thisGlider); + else + CheckEscapeDown(thisGlider); + } + else if ((thisBackground == kRoof) && (thisGlider->dest.bottom > kRoofLimit)) + CheckRoofCollision(thisGlider); + + if (thisGlider->dest.left < leftThresh) + { + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if((twoPlayerGame) && (!onePlayerLeft)) + CheckEscapeLeftTwo(thisGlider); + else + CheckEscapeLeft(thisGlider); + } + else if (thisGlider->dest.right > rightThresh) + { + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if ((twoPlayerGame) && (!onePlayerLeft)) + CheckEscapeRightTwo(thisGlider); + else + CheckEscapeRight(thisGlider); + } + } +} + +//-------------------------------------------------------------- HandleRewards + +void HandleRewards (gliderPtr thisGlider, hotPtr who) +{ + Rect bounds; + short whoLinked, points; + + whoLinked = who->who; + bounds = who->bounds; + + switch (masterObjects[whoLinked].theObject.what) + { + case kRedClock: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kBeepsSound, kBeepsPriority); + RestoreFromSavedMap(thisRoomNumber, + masterObjects[whoLinked].objectNum, false); + AddFlyingPoint(&bounds, 100, thisGlider->hVel / 2, thisGlider->vVel / 2); + thisGlider->hVel /= 4; + thisGlider->vVel /= 4; + theScore += kRedClockPoints; + RedrawAllGrease(); + } + who->isOn = false; + break; + + case kBlueClock: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kBuzzerSound, kBuzzerPriority); + RestoreFromSavedMap(thisRoomNumber, + masterObjects[whoLinked].objectNum, false); + AddFlyingPoint(&bounds, 300, thisGlider->hVel / 2, thisGlider->vVel / 2); + thisGlider->hVel /= 4; + thisGlider->vVel /= 4; + theScore += kBlueClockPoints; + RedrawAllGrease(); + } + who->isOn = false; + break; + + case kYellowClock: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kDingSound, kDingPriority); + RestoreFromSavedMap(thisRoomNumber, + masterObjects[whoLinked].objectNum, false); + AddFlyingPoint(&bounds, 500, thisGlider->hVel / 2, thisGlider->vVel / 2); + thisGlider->hVel /= 4; + thisGlider->vVel /= 4; + theScore += kYellowClockPoints; + RedrawAllGrease(); + } + who->isOn = false; + break; + + case kCuckoo: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kCuckooSound, kCuckooPriority); + RestoreFromSavedMap(thisRoomNumber, + masterObjects[whoLinked].objectNum, false); + StopPendulum(thisRoomNumber, masterObjects[whoLinked].objectNum); + AddFlyingPoint(&bounds, 1000, thisGlider->hVel / 2, thisGlider->vVel / 2); + thisGlider->hVel /= 4; + thisGlider->vVel /= 4; + theScore += kCuckooClockPoints; + RedrawAllGrease(); + } + who->isOn = false; + break; + + case kPaper: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kEnergizeSound, kEnergizePriority); + RestoreFromSavedMap(thisRoomNumber, + masterObjects[whoLinked].objectNum, false); + AddSparkle(&bounds); + thisGlider->hVel /= 2; + thisGlider->vVel /= 2; + mortals++; + if ((twoPlayerGame) && (!onePlayerLeft)) + mortals++; + QuickGlidersRefresh(); + RedrawAllGrease(); + } + who->isOn = false; + break; + + case kBattery: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kEnergizeSound, kEnergizePriority); + RestoreFromSavedMap(thisRoomNumber, + masterObjects[whoLinked].objectNum, false); + AddSparkle(&bounds); + thisGlider->hVel /= 2; + thisGlider->vVel /= 2; + if (batteryTotal > 0) // positive number means battery power + batteryTotal += kBatterySupply; + else // negative number means helium gas + batteryTotal = kBatterySupply; + if ((twoPlayerGame) && (!onePlayerLeft)) + batteryTotal += kBatterySupply; + QuickBatteryRefresh(false); + RedrawAllGrease(); + } + who->isOn = false; + break; + + case kBands: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kEnergizeSound, kEnergizePriority); + RestoreFromSavedMap(thisRoomNumber, + masterObjects[whoLinked].objectNum, false); + AddSparkle(&bounds); + thisGlider->hVel /= 2; + thisGlider->vVel /= 2; + bandsTotal += kBandsSupply; + if ((twoPlayerGame) && (!onePlayerLeft)) + bandsTotal += kBandsSupply; + QuickBandsRefresh(false); + RedrawAllGrease(); + } + who->isOn = false; + break; + + case kGreaseRt: + case kGreaseLf: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + SpillGrease(masterObjects[whoLinked].dynaNum, + masterObjects[whoLinked].hotNum); + who->isOn = false; + break; + + case kFoil: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kEnergizeSound, kEnergizePriority); + RestoreFromSavedMap(thisRoomNumber, + masterObjects[whoLinked].objectNum, false); + AddSparkle(&bounds); + thisGlider->hVel /= 2; + thisGlider->vVel /= 2; + foilTotal += kFoilSupply; + if ((twoPlayerGame) && (!onePlayerLeft)) + foilTotal += kFoilSupply; + StartGliderFoilGoing(thisGlider); + RedrawAllGrease(); + } + who->isOn = false; + break; + + case kInvisBonus: + points = masterObjects[whoLinked].theObject.data.c.points; + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kBonusSound, kBonusPriority); + AddFlyingPoint(&bounds, points, thisGlider->hVel / 2, thisGlider->vVel / 2); + thisGlider->hVel /= 4; + thisGlider->vVel /= 4; + theScore += points; + } + who->isOn = false; + break; + + case kStar: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kEnergizeSound, kEnergizePriority); + RestoreFromSavedMap(thisRoomNumber, + masterObjects[whoLinked].objectNum, false); + AddSparkle(&bounds); + StopStar(thisRoomNumber, masterObjects[whoLinked].objectNum); + numStarsRemaining--; + if (numStarsRemaining <= 0) + FlagGameOver(); + else + DisplayStarsRemaining(); + RedrawAllGrease(); + theScore += kStarPoints; + } + who->isOn = false; + break; + + case kSparkle: + break; + + case kHelium: + if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, + 0, whoLinked)) + { + PlayPrioritySound(kEnergizeSound, kEnergizePriority); + RestoreFromSavedMap(thisRoomNumber, + masterObjects[whoLinked].objectNum, false); + AddSparkle(&bounds); + thisGlider->hVel /= 2; + thisGlider->vVel /= 2; + if (batteryTotal < 0) // if negative, it is already helium gas + batteryTotal -= kHeliumSupply; + else // if positive, it is battery power + batteryTotal = -kHeliumSupply; + if ((twoPlayerGame) && (!onePlayerLeft)) + batteryTotal -= kHeliumSupply; + QuickBatteryRefresh(false); + RedrawAllGrease(); + } + who->isOn = false; + break; + + case kSlider: + break; + } +} + +//-------------------------------------------------------------- HandleSwitches + +void HandleSwitches (hotPtr who) +{ + Rect newRect, bounds; + short whoLinked, roomLinked, objectLinked, linkIndex; + + if (who->stillOver) + return; + + whoLinked = who->who; // what is switch's obj. # + roomLinked = masterObjects[whoLinked].roomLink; + objectLinked = masterObjects[whoLinked].objectLink; + linkIndex = masterObjects[whoLinked].localLink; + // change state of linked obj. + if (SetObjectState(roomLinked, objectLinked, + masterObjects[whoLinked].theObject.data.e.type, linkIndex)) + { + newRect = who->bounds; + QOffsetRect(&newRect, playOriginH, playOriginV); + switch (masterObjects[whoLinked].theObject.what) + { + case kLightSwitch: + PlayPrioritySound(kSwitchSound, kSwitchPriority); + DrawLightSwitch(&newRect, newState); + break; + + case kMachineSwitch: + PlayPrioritySound(kSwitchSound, kSwitchPriority); + DrawMachineSwitch(&newRect, newState); + break; + + case kThermostat: + PlayPrioritySound(kSwitchSound, kSwitchPriority); + DrawThermostat(&newRect, newState); + break; + + case kPowerSwitch: + PlayPrioritySound(kSwitchSound, kSwitchPriority); + DrawPowerSwitch(&newRect, newState); + break; + + case kKnifeSwitch: + PlayPrioritySound(kSwitchSound, kSwitchPriority); + DrawKnifeSwitch(&newRect, newState); + break; + + case kInvisSwitch: + break; + } + CopyRectBackToWork(&newRect); + AddRectToWorkRects(&newRect); + + if (linkIndex != -1) + { + switch (masterObjects[linkIndex].theObject.what) + { + case kRedClock: + case kBlueClock: + case kYellowClock: + case kPaper: + case kBattery: + case kBands: + case kFoil: + case kStar: + case kHelium: + RestoreFromSavedMap(roomLinked, objectLinked, true); + AddSparkle(&bounds); + break; + + case kCuckoo: + RestoreFromSavedMap(roomLinked, objectLinked, true); + StopPendulum(roomLinked, objectLinked); + break; + + case kGreaseRt: + case kGreaseLf: + SpillGrease(masterObjects[linkIndex].dynaNum, + masterObjects[linkIndex].hotNum); + break; + + case kInvisBonus: + case kSlider: + break; + + case kDeluxeTrans: + break; + + case kSoundTrigger: + PlayPrioritySound(kTriggerSound, kTriggerPriority); + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + RedrawRoomLighting(); + break; + + case kShredder: + break; + + case kToaster: + ToggleToaster(masterObjects[linkIndex].dynaNum); + break; + + case kMacPlus: + ToggleMacPlus(masterObjects[linkIndex].dynaNum); + break; + + case kGuitar: + PlayPrioritySound(kChordSound, kChordPriority); + break; + + case kTV: + ToggleTV(masterObjects[linkIndex].dynaNum); + break; + + case kCoffee: + ToggleCoffee(masterObjects[linkIndex].dynaNum); + break; + + case kOutlet: + ToggleOutlet(masterObjects[linkIndex].dynaNum); + break; + + case kVCR: + ToggleVCR(masterObjects[linkIndex].dynaNum); + break; + + case kStereo: + ToggleStereos(masterObjects[linkIndex].dynaNum); + break; + + case kMicrowave: + ToggleMicrowave(masterObjects[linkIndex].dynaNum); + break; + + case kBalloon: + ToggleBalloon(masterObjects[linkIndex].dynaNum); + break; + + case kCopterLf: + case kCopterRt: + ToggleCopter(masterObjects[linkIndex].dynaNum); + break; + + case kDartLf: + case kDartRt: + ToggleDart(masterObjects[linkIndex].dynaNum); + break; + + case kBall: + ToggleBall(masterObjects[linkIndex].dynaNum); + break; + + case kDrip: + ToggleDrip(masterObjects[linkIndex].dynaNum); + break; + + case kFish: + ToggleFish(masterObjects[linkIndex].dynaNum); + break; + } + } + } + + who->stillOver = true; +} + +//-------------------------------------------------------------- HandleMicrowaveAction + +void HandleMicrowaveAction (hotPtr who, gliderPtr thisGlider) +{ + short whoLinked, kills; + Boolean killed; + + if (who->stillOver) + return; + + killed = false; + whoLinked = who->who; // what is microwave's obj. # + if (masterObjects[whoLinked].theObject.data.g.state) + { + kills = (short)masterObjects[whoLinked].theObject.data.g.byte0; + if (((kills & 0x0001) == 0x0001) && (bandsTotal > 0)) + { + bandsTotal = 0; + killed = true; + QuickBandsRefresh(false); + } + if (((kills & 0x0002) == 0x0002) && (batteryTotal != 0)) + { + batteryTotal = 0; + killed = true; + QuickBatteryRefresh(false); + } + if (((kills & 0x0004) == 0x0004) && (foilTotal > 0)) + { + foilTotal = 0; + killed = true; + StartGliderFoilLosing(thisGlider); + } + } + + if (killed) + PlayPrioritySound(kMicrowavedSound, kMicrowavedPriority); +} + +//-------------------------------------------------------------- HandleHotSpotCollision + +void HandleHotSpotCollision (gliderPtr thisGlider, hotPtr who, short index) +{ + switch (who->action) + { + case kLiftIt: + thisGlider->vDesiredVel = kFloorVentLift; + break; + + case kDropIt: + thisGlider->vDesiredVel = kCeilingVentDrop; + break; + + case kPushItLeft: + thisGlider->hDesiredVel += -kFanStrength; + break; + + case kPushItRight: + thisGlider->hDesiredVel += kFanStrength; + break; + + case kDissolveIt: + if (thisGlider->mode != kGliderFadingOut) + { + if ((foilTotal > 0) || (thisGlider->mode == kGliderLosingFoil)) + { + if (GliderHitTop(thisGlider, &(who->bounds))) + { + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else + { + if (foilTotal > 0) + { + foilTotal--; + if (foilTotal <= 0) + StartGliderFoilLosing(thisGlider); + } + } + } + else + { + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + } + break; + + case kRewardIt: + HandleRewards(thisGlider, who); + break; + + case kMoveItUp: + if (!thisGlider->heldRight && GliderInRect(thisGlider, &who->bounds)) + { + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if ((twoPlayerGame) && (!onePlayerLeft)) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + if ((thisGlider->mode != kGliderGoingUp) && + (thisGlider->mode != kGliderInLimbo)) + { + otherPlayerEscaped = kPlayerEscapingUpStairs; + RefreshScoreboard(kEscapedTitleMode); + StartGliderGoingUpStairs(thisGlider); + } + } + else if (otherPlayerEscaped == kPlayerEscapedUpStairs) + { + if ((thisGlider->mode != kGliderGoingUp) && + (thisGlider->mode != kGliderInLimbo)) + { + StartGliderGoingUpStairs(thisGlider); + } + } + } + else + StartGliderGoingUpStairs(thisGlider); + } + break; + + case kMoveItDown: + if (!thisGlider->heldLeft && GliderInRect(thisGlider, &who->bounds)) + { + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if ((twoPlayerGame) && (!onePlayerLeft)) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + if ((thisGlider->mode != kGliderGoingDown) && + (thisGlider->mode != kGliderInLimbo)) + { + otherPlayerEscaped = kPlayerEscapingDownStairs; + RefreshScoreboard(kEscapedTitleMode); + StartGliderGoingDownStairs(thisGlider); + } + } + else if (otherPlayerEscaped == kPlayerEscapedDownStairs) + { + if ((thisGlider->mode != kGliderGoingDown) && + (thisGlider->mode != kGliderInLimbo)) + { + StartGliderGoingDownStairs(thisGlider); + } + } + } + else + StartGliderGoingDownStairs(thisGlider); + } + break; + + case kSwitchIt: + HandleSwitches(who); + break; + + case kShredIt: + if ((thisGlider->mode != kGliderShredding) && + (GliderInRect(thisGlider, &who->bounds))) + { + if ((foilTotal > 0) || (thisGlider->mode == kGliderLosingFoil)) + { + PlayPrioritySound(kFoilHitSound, kFoilHitPriority); + if (foilTotal > 0) + { + foilTotal--; + if (foilTotal <= 0) + StartGliderFoilLosing(thisGlider); + } + } + else + FlagGliderShredding(thisGlider, &who->bounds); + } + break; + + case kStrumIt: + if (!who->stillOver) + { + PlayPrioritySound(kChordSound, kChordPriority); + who->stillOver = true; + } + break; + + case kTriggerIt: + case kLgTrigger: + ArmTrigger(who); + break; + + case kBurnIt: + if ((thisGlider->mode != kGliderBurning) && + (thisGlider->mode != kGliderFadingOut)) + { + if ((foilTotal > 0) || (thisGlider->mode == kGliderLosingFoil)) + { + thisGlider->vDesiredVel = kFloorVentLift; + if (foilTotal > 0) + { + PlayPrioritySound(kSizzleSound, kSizzlePriority); + foilTotal--; + if (foilTotal <= 0) + StartGliderFoilLosing(thisGlider); + } + } + else + FlagGliderBurning(thisGlider); + } + break; + + case kSlideIt: + thisGlider->sliding = true; + thisGlider->vVel = who->bounds.top - thisGlider->dest.bottom; + break; + + case kTransportIt: + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if ((GliderInRect(thisGlider, &who->bounds)) && + (thisGlider->mode != kGliderTransporting) && + (thisGlider->mode != kGliderFadingOut)) + { + if ((twoPlayerGame) && (!onePlayerLeft)) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + if (thisGlider->mode != kGliderInLimbo) + { + activeRectEscaped = index; + StartGliderTransporting(thisGlider, who); + } + } + else if (otherPlayerEscaped == kPlayerTransportedOut) + { + if ((thisGlider->mode != kGliderInLimbo) && + (activeRectEscaped == index)) + { + StartGliderTransporting(thisGlider, who); + } + } + } + else + StartGliderTransporting(thisGlider, who); + } + break; + + case kIgnoreLeftWall: + thisGlider->ignoreLeft = true; + break; + + case kIgnoreRightWall: + thisGlider->ignoreRight = true; + break; + + case kMailItLeft: // mailbox open to right + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if ((GliderInRect(thisGlider, &who->bounds)) && + (thisGlider->mode != kGliderMailOutRight) && + (thisGlider->mode != kGliderMailInLeft) && + (thisGlider->mode != kGliderFadingOut) && + (((thisGlider->facing == kFaceRight) && (!thisGlider->tipped)) || + ((thisGlider->facing == kFaceLeft) && (thisGlider->tipped)))) + { + if ((twoPlayerGame) && (!onePlayerLeft)) // two gliders to handle + { + if (otherPlayerEscaped == kNoOneEscaped) // other glider in room + { + if (thisGlider->mode != kGliderInLimbo) // this glider is active + { + activeRectEscaped = index; + StartGliderMailingIn(thisGlider, &who->bounds, who); + thisGlider->mode = kGliderMailInLeft; + } + } + else if (otherPlayerEscaped == kPlayerMailedOut) + { // other glider left here + if ((thisGlider->mode != kGliderInLimbo) && + (activeRectEscaped == index)) + { // []_ <--G + StartGliderMailingIn(thisGlider, &who->bounds, who); + thisGlider->mode = kGliderMailInLeft; + } + } + } + else // only 1 glider in game + { + StartGliderMailingIn(thisGlider, &who->bounds, who); + thisGlider->mode = kGliderMailInLeft; + } + } + break; + + case kMailItRight: // mailbox open to left + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if ((GliderInRect(thisGlider, &who->bounds)) && + (thisGlider->mode != kGliderMailOutLeft) && + (thisGlider->mode != kGliderMailInRight) && + (thisGlider->mode != kGliderFadingOut) && + (((thisGlider->facing == kFaceRight) && (thisGlider->tipped)) || + ((thisGlider->facing == kFaceLeft) && (!thisGlider->tipped)))) + { + if ((twoPlayerGame) && (!onePlayerLeft)) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + if (thisGlider->mode != kGliderInLimbo) + { + activeRectEscaped = index; + StartGliderMailingIn(thisGlider, &who->bounds, who); + thisGlider->mode = kGliderMailInRight; + } + } + else if (otherPlayerEscaped == kPlayerMailedOut) + { + if ((thisGlider->mode != kGliderInLimbo) && + (activeRectEscaped == index)) + { + StartGliderMailingIn(thisGlider, &who->bounds, who); + thisGlider->mode = kGliderMailInRight; + } + } + } + else + { + StartGliderMailingIn(thisGlider, &who->bounds, who); + thisGlider->mode = kGliderMailInRight; + } + } + break; + + case kDuctItDown: + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if ((GliderInRect(thisGlider, &who->bounds)) && + (thisGlider->mode != kGliderDuctingDown) && + (thisGlider->mode != kGliderFadingOut)) + { + if ((twoPlayerGame) && (!onePlayerLeft)) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + if (thisGlider->mode != kGliderInLimbo) + { + activeRectEscaped = index; + StartGliderDuctingDown(thisGlider, &who->bounds, who); + } + } + else if (otherPlayerEscaped == kPlayerDuckedOut) + { + if ((thisGlider->mode != kGliderInLimbo) && + (activeRectEscaped == index)) + StartGliderDuctingDown(thisGlider, &who->bounds, who); + } + } + else + StartGliderDuctingDown(thisGlider, &who->bounds, who); + } + break; + + case kDuctItUp: + if (thisGlider->mode == kGliderBurning) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + else if ((GliderInRect(thisGlider, &who->bounds)) && + (thisGlider->mode != kGliderDuctingUp) && + (thisGlider->mode != kGliderDuctingIn) && + (thisGlider->mode != kGliderFadingOut) && + (!who->stillOver)) + { + if ((twoPlayerGame) && (!onePlayerLeft)) + { + if (otherPlayerEscaped == kNoOneEscaped) + { + if (thisGlider->mode != kGliderInLimbo) + { + activeRectEscaped = index; + StartGliderDuctingUp(thisGlider, &who->bounds, who); + } + } + else if (otherPlayerEscaped == kPlayerDuckedOut) + { + if ((thisGlider->mode != kGliderInLimbo) && + (activeRectEscaped == index)) + StartGliderDuctingUp(thisGlider, &who->bounds, who); + } + } + else + { + StartGliderDuctingUp(thisGlider, &who->bounds, who); + who->stillOver = true; + } + } + break; + + case kMicrowaveIt: + if (GliderInRect(thisGlider, &who->bounds)) + HandleMicrowaveAction(who, thisGlider); + break; + + case kIgnoreGround: + thisGlider->ignoreGround = true; + break; + + case kBounceIt: + BounceGlider(thisGlider, &who->bounds); + break; + + case kChimeIt: + if (!who->stillOver) + { + StrikeChime(); + who->stillOver = true; + } + break; + + case kWebIt: + if ((GliderInRect(thisGlider, &who->bounds)) && + (thisGlider->mode != kGliderBurning)) + WebGlider(thisGlider, &who->bounds); + else if ((thisGlider->mode == kGliderBurning) && + (GliderInRect(thisGlider, &who->bounds))) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + break; + + case kSoundIt: + if (!who->stillOver) + { + PlayPrioritySound(kTriggerSound, kTriggerPriority); + who->stillOver = true; + } + break; + } +} + +//-------------------------------------------------------------- CheckForHotSpots + +void CheckForHotSpots (void) +{ + short i; + Boolean hitObject; + + for (i = 0; i < nHotSpots; i++) + { + if (hotSpots[i].isOn) + { + if (twoPlayerGame) + { + hitObject = false; + if (SectGlider(&theGlider, &hotSpots[i].bounds, + hotSpots[i].doScrutinize)) + { + if (onePlayerLeft) + { + if (playerDead == kPlayer2) + { + HandleHotSpotCollision(&theGlider, &hotSpots[i], i); + hitObject = true; + } + } + else + { + HandleHotSpotCollision(&theGlider, &hotSpots[i], i); + hitObject = true; + } + } + + if (SectGlider(&theGlider2, &hotSpots[i].bounds, + hotSpots[i].doScrutinize)) + { + if (onePlayerLeft) + { + if (playerDead == kPlayer1) + { + HandleHotSpotCollision(&theGlider2, &hotSpots[i], i); + hitObject = true; + } + } + else + { + HandleHotSpotCollision(&theGlider2, &hotSpots[i], i); + hitObject = true; + } + } + if (!hitObject) + hotSpots[i].stillOver = false; + } + else + { + if (SectGlider(&theGlider, &hotSpots[i].bounds, + hotSpots[i].doScrutinize)) + HandleHotSpotCollision(&theGlider, &hotSpots[i], i); + else + hotSpots[i].stillOver = false; + } + } + } +} + +//-------------------------------------------------------------- HandleInteraction + +void HandleInteraction (void) +{ + CheckForHotSpots(); + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == kPlayer1) + CheckGliderInRoom(&theGlider2); + else + CheckGliderInRoom(&theGlider); + } + else + { + CheckGliderInRoom(&theGlider); + CheckGliderInRoom(&theGlider2); + } + } + else + CheckGliderInRoom(&theGlider); +} + +//-------------------------------------------------------------- FlagStillOvers + +void FlagStillOvers (gliderPtr thisGlider) +{ + short i; + + for (i = 0; i < nHotSpots; i++) + { + if (hotSpots[i].isOn) + { + if (SectGlider(thisGlider, &hotSpots[i].bounds, + hotSpots[i].doScrutinize)) + hotSpots[i].stillOver = true; + else + hotSpots[i].stillOver = false; + } + else + hotSpots[i].stillOver = false; + } +} + +//-------------------------------------------------------------- WebGlider + +void WebGlider (gliderPtr thisGlider, Rect *webBounds) +{ + #define kKillWebbedGlider 150 + short hDist, vDist; + + if ((thisGlider->mode == kGliderBurning) && (GliderInRect(thisGlider, webBounds))) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + return; + } + + hDist = ((webBounds->right - thisGlider->dest.right) + + (webBounds->left - thisGlider->dest.left)) >> 3; + vDist = ((webBounds->bottom - thisGlider->dest.bottom) + + (webBounds->top - thisGlider->dest.top)) >> 3; + + if (thisGlider->hDesiredVel != 0) + { + if (evenFrame) + { + thisGlider->hVel = hDist; + thisGlider->vVel = vDist; + PlayPrioritySound(kWebTwangSound, kWebTwangPriority); + } + } + else + { + thisGlider->hDesiredVel = 0; + thisGlider->vDesiredVel = 0; + } + + thisGlider->wasMode++; + if (thisGlider->wasMode >= kKillWebbedGlider) + { + thisGlider->wasMode = 0; + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } +} + diff --git a/GpApp/InterfaceInit.cpp b/GpApp/InterfaceInit.cpp new file mode 100644 index 0000000..0ca097c --- /dev/null +++ b/GpApp/InterfaceInit.cpp @@ -0,0 +1,220 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// InterfaceInit.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Environ.h" +#include "Map.h" +#include "RectUtils.h" +#include "Tools.h" + + +#define kHandCursorID 128 +#define kVertCursorID 129 +#define kHoriCursorID 130 +#define kDiagCursorID 131 + + +extern RgnHandle mirrorRgn; +extern WindowPtr mapWindow, toolsWindow, linkWindow; +extern WindowPtr menuWindow; +extern Rect shieldRect, boardSrcRect, localRoomsDest[]; +extern CursHandle handCursorH, beamCursorH, vertCursorH, horiCursorH; +extern CursHandle diagCursorH; +extern Cursor handCursor, beamCursor, vertCursor, horiCursor; +extern Cursor diagCursor; +extern MenuHandle appleMenu, gameMenu, optionsMenu, houseMenu; +extern Point shieldPt; +extern long incrementModeTime; +extern UInt32 doubleTime; +extern short fadeInSequence[], idleMode; +extern short toolSelected, lastBackground, wasFlower, numExtraHouses; +extern short houseResFork, lastHighScore, maxFiles, willMaxFiles; +extern Boolean quitting, playing, fadeGraysOut; +extern Boolean houseOpen, newRoomNow, evenFrame, menusUp, demoGoing; +extern Boolean twoPlayerGame, paused, hasMirror, splashDrawn; + + +//============================================================== Functions +//-------------------------------------------------------------- InitializeMenus + +// The menus are loaded from disk and the menu bar set up and drawn. + +void InitializeMenus (void) +{ + appleMenu = GetMenu(kAppleMenuID); + if (appleMenu == nil) + RedAlert(kErrFailedResourceLoad); + AppendResMenu(appleMenu, 'DRVR'); + InsertMenu(appleMenu, 0); + + gameMenu = GetMenu(kGameMenuID); + if (gameMenu == nil) + RedAlert(kErrFailedResourceLoad); + InsertMenu(gameMenu, 0); + + optionsMenu = GetMenu(kOptionsMenuID); + if (optionsMenu == nil) + RedAlert(kErrFailedResourceLoad); + InsertMenu(optionsMenu, 0); + + menusUp = true; + DrawMenuBar(); + + houseMenu = GetMenu(kHouseMenuID); + if (houseMenu == nil) + RedAlert(kErrFailedResourceLoad); + + UpdateMenus(false); +} + +//-------------------------------------------------------------- GetExtraCursors + +// Extra cursors (custom cursors) like the "hand" and various roomÉ +// editing cursors are loaded up. + +void GetExtraCursors (void) +{ + handCursorH = GetCursor(kHandCursorID); + if (handCursorH == nil) + RedAlert(kErrFailedResourceLoad); + HLock((Handle)handCursorH); + handCursor = **handCursorH; + + beamCursorH = GetCursor(iBeamCursor); + if (beamCursorH == nil) + RedAlert(kErrFailedResourceLoad); + HLock((Handle)beamCursorH); + beamCursor = **beamCursorH; + + vertCursorH = GetCursor(kVertCursorID); + if (vertCursorH == nil) + RedAlert(kErrFailedResourceLoad); + HLock((Handle)vertCursorH); + vertCursor = **vertCursorH; + + horiCursorH = GetCursor(kHoriCursorID); + if (horiCursorH == nil) + RedAlert(kErrFailedResourceLoad); + HLock((Handle)horiCursorH); + horiCursor = **horiCursorH; + + diagCursorH = GetCursor(kDiagCursorID); + if (diagCursorH == nil) + RedAlert(kErrFailedResourceLoad); + HLock((Handle)diagCursorH); + diagCursor = **diagCursorH; +} + +//-------------------------------------------------------------- VariableInit + +// All the simple interface variables are intialized here - Booleans,É +// shorts, a few Rects, etc. + +void VariableInit (void) +{ + short i; + + shieldPt.h = 0; + shieldPt.v = 0; + shieldRect = thisMac.screen; + + menusUp = false; + quitting = false; + houseOpen = false; + newRoomNow = false; + playing = false; + evenFrame = false; + if (thisMac.isDepth == 8) + fadeGraysOut = true; + else + fadeGraysOut = false; + twoPlayerGame = false; + paused = false; + hasMirror = false; + demoGoing = false; +// scrapIsARoom = true; + splashDrawn = false; + +#ifndef COMPILEDEMO +// SeeIfValidScrapAvailable(false); +#endif + + theGlider.which = kPlayer1; + theGlider2.leftKey = kControlKeyMap; + theGlider2.rightKey = kCommandKeyMap; + theGlider2.battKey = kOptionKeyMap; + theGlider2.bandKey = kShiftKeyMap; + theGlider2.which = kPlayer2; + + theMode = kSplashMode; + thisRoomNumber = 0; + previousRoom = -1; + toolSelected = kSelectTool; + houseResFork = -1; + lastBackground = kBaseBackgroundID; + wasFlower = RandomInt(kNumFlowers); + lastHighScore = -1; + idleMode = kIdleSplashMode; + incrementModeTime = TickCount() + kIdleSplashTicks; + willMaxFiles = maxFiles; + numExtraHouses = 0; + + fadeInSequence[0] = 4; // 4 + fadeInSequence[1] = 5; + fadeInSequence[2] = 6; + fadeInSequence[3] = 7; + fadeInSequence[4] = 5; // 5 + fadeInSequence[5] = 6; + fadeInSequence[6] = 7; + fadeInSequence[7] = 8; + fadeInSequence[8] = 6; // 6 + fadeInSequence[9] = 7; + fadeInSequence[10] = 8; + fadeInSequence[11] = 9; + fadeInSequence[12] = 7; // 7 + fadeInSequence[13] = 8; + fadeInSequence[14] = 9; + fadeInSequence[15] = 10; + + doubleTime = GetDblTime(); + + mirrorRgn = nil; + mainWindow = nil; + mapWindow = nil; + toolsWindow = nil; + linkWindow = nil; + coordWindow = nil; + toolSrcMap = nil; + nailSrcMap = nil; + menuWindow = nil; + + houseRect = thisMac.screen; + houseRect.bottom -= kScoreboardTall; + if (houseRect.right > kMaxViewWidth) + houseRect.right = kMaxViewWidth; + if (houseRect.bottom > kMaxViewHeight) + houseRect.bottom = kMaxViewHeight; + + playOriginH = (RectWide(&thisMac.screen) - kRoomWide) / 2; + playOriginV = (RectTall(&thisMac.screen) - kTileHigh) / 2; + + for (i = 0; i < 9; i++) + { + QSetRect(&localRoomsDest[i], 0, 0, kRoomWide, kTileHigh); + QOffsetRect(&localRoomsDest[i], playOriginH, playOriginV); + } + QOffsetRect(&localRoomsDest[kNorthRoom], 0, -kVertLocalOffset); + QOffsetRect(&localRoomsDest[kNorthEastRoom], kRoomWide, -kVertLocalOffset); + QOffsetRect(&localRoomsDest[kEastRoom], kRoomWide, 0); + QOffsetRect(&localRoomsDest[kSouthEastRoom], kRoomWide, kVertLocalOffset); + QOffsetRect(&localRoomsDest[kSouthRoom], 0, kVertLocalOffset); + QOffsetRect(&localRoomsDest[kSouthWestRoom], -kRoomWide, kVertLocalOffset); + QOffsetRect(&localRoomsDest[kWestRoom], -kRoomWide, 0); + QOffsetRect(&localRoomsDest[kNorthWestRoom], -kRoomWide, -kVertLocalOffset); +} + diff --git a/GpApp/Link.cpp b/GpApp/Link.cpp new file mode 100644 index 0000000..0bb9171 --- /dev/null +++ b/GpApp/Link.cpp @@ -0,0 +1,397 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Link.c +//---------------------------------------------------------------------------- +//============================================================================ + +#include "PLControlDefinitions.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "ObjectEdit.h" +#include "RectUtils.h" + + +#define kLinkControlID 130 +#define kUnlinkControlID 131 + + +void DoLink (void); +void DoUnlink (void); + + +Rect linkWindowRect; +ControlHandle linkControl, unlinkControl; +WindowPtr linkWindow; +short isLinkH, isLinkV, linkRoom, linkType; +Byte linkObject; +Boolean isLinkOpen, linkerIsSwitch; + + +//============================================================== Functions +//-------------------------------------------------------------- MergeFloorSuite + +short MergeFloorSuite (short floor, short suite) +{ + return ((suite * 100) + floor); +} + +//-------------------------------------------------------------- ExtractFloorSuite + +void ExtractFloorSuite (short combo, short *floor, short *suite) +{ + if ((*thisHouse)->version < 0x0200) // old floor/suite combo + { + *floor = (combo / 100) - kNumUndergroundFloors; + *suite = combo % 100; + } + else + { + *suite = combo / 100; + *floor = (combo % 100) - kNumUndergroundFloors; + } +} + +//-------------------------------------------------------------- UpdateLinkControl + +void UpdateLinkControl (void) +{ +#ifndef COMPILEDEMO + if (linkWindow == nil) + return; + + switch (linkType) + { + case kSwitchLinkOnly: + if (objActive == kNoObjectSelected) + HiliteControl(linkControl, kControlInactive); + else + switch (thisRoom->objects[objActive].what) + { + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kLeftFan: + case kRightFan: + case kInvisBlower: + case kGrecoVent: + case kSewerBlower: + case kLiftArea: + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kFoil: + case kInvisBonus: + case kHelium: + case kDeluxeTrans: + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + case kShredder: + case kToaster: + case kMacPlus: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kStereo: + case kMicrowave: + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kBall: + case kDrip: + case kFish: + HiliteControl(linkControl, kControlActive); + break; + + default: + HiliteControl(linkControl, kControlInactive); + break; + } + break; + + case kTriggerLinkOnly: + if (objActive == kNoObjectSelected) + HiliteControl(linkControl, kControlInactive); + else + switch (thisRoom->objects[objActive].what) + { + case kGreaseRt: + case kGreaseLf: + case kToaster: + case kGuitar: + case kCoffee: + case kOutlet: + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kDrip: + case kFish: + HiliteControl(linkControl, kControlActive); + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + if (linkRoom == thisRoomNumber) + HiliteControl(linkControl, kControlActive); + break; + + default: + HiliteControl(linkControl, kControlInactive); + break; + } + break; + + case kTransportLinkOnly: + if (objActive == kNoObjectSelected) + HiliteControl(linkControl, kControlInactive); + else + switch (thisRoom->objects[objActive].what) + { + case kMailboxLf: + case kMailboxRt: + case kCeilingTrans: + case kInvisTrans: + case kDeluxeTrans: + case kInvisLight: + case kOzma: + case kMirror: + case kFireplace: + case kWallWindow: + case kCalendar: + case kBulletin: + case kCloud: + HiliteControl(linkControl, kControlActive); + break; + + default: + HiliteControl(linkControl, kControlInactive); + break; + } + break; + } +#endif +} + +//-------------------------------------------------------------- UpdateLinkWindow + +void UpdateLinkWindow (void) +{ +#ifndef COMPILEDEMO + if (linkWindow == nil) + return; + + SetPortWindowPort(linkWindow); + DrawControls(linkWindow); + UpdateLinkControl(); +#endif +} + +//-------------------------------------------------------------- OpenLinkWindow + +void OpenLinkWindow (void) +{ +#ifndef COMPILEDEMO + Rect src, dest; + Point globalMouse; + + if (linkWindow == nil) + { + QSetRect(&linkWindowRect, 0, 0, 129, 30); + if (thisMac.hasColor) + linkWindow = NewCWindow(nil, &linkWindowRect, + PSTR("Link"), false, kWindoidWDEF, kPutInFront, true, 0L); + else + linkWindow = NewWindow(nil, &linkWindowRect, + PSTR("Link"), false, kWindoidWDEF, kPutInFront, true, 0L); + + MoveWindow(linkWindow, isLinkH, isLinkV, true); + globalMouse = MyGetGlobalMouse(); + QSetRect(&src, 0, 0, 1, 1); + QOffsetRect(&src, globalMouse.h, globalMouse.v); + GetWindowRect(linkWindow, &dest); + BringToFront(linkWindow); + ShowHide(linkWindow, true); +// FlagWindowFloating(linkWindow); TEMP - use flaoting windows + HiliteAllWindows(); + + linkControl = GetNewControl(kLinkControlID, linkWindow); + if (linkControl == nil) + RedAlert(kErrFailedResourceLoad); + + unlinkControl = GetNewControl(kUnlinkControlID, linkWindow); + if (unlinkControl == nil) + RedAlert(kErrFailedResourceLoad); + + linkRoom = -1; + linkObject = 255; + + isLinkOpen = true; + } +#endif +} + +//-------------------------------------------------------------- CloseLinkWindow + +void CloseLinkWindow (void) +{ +#ifndef COMPILEDEMO + if (linkWindow != nil) + DisposeWindow(linkWindow); + + linkWindow = nil; + isLinkOpen = false; +#endif +} + +//-------------------------------------------------------------- DoLink + +#ifndef COMPILEDEMO +void DoLink (void) +{ + short floor, suite; + char wasState; + + if (GetRoomFloorSuite(thisRoomNumber, &floor, &suite)) + { + floor += kNumUndergroundFloors; + if (thisRoomNumber == linkRoom) + { + if (linkerIsSwitch) + { + thisRoom->objects[linkObject].data.e.where = + MergeFloorSuite(floor, suite); + thisRoom->objects[linkObject].data.e.who = + objActive; + } + else + { + thisRoom->objects[linkObject].data.d.where = + MergeFloorSuite(floor, suite); + thisRoom->objects[linkObject].data.d.who = + objActive; + } + } + else + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + if (linkerIsSwitch) + { + (*thisHouse)->rooms[linkRoom].objects[linkObject].data.e.where = + MergeFloorSuite(floor, suite); + (*thisHouse)->rooms[linkRoom].objects[linkObject].data.e.who = + objActive; + } + else // linker is transport + { + (*thisHouse)->rooms[linkRoom].objects[linkObject].data.d.where = + MergeFloorSuite(floor, suite); + (*thisHouse)->rooms[linkRoom].objects[linkObject].data.d.who = + objActive; + } + HSetState((Handle)thisHouse, wasState); + } + fileDirty = true; + UpdateMenus(false); + CloseLinkWindow(); + } +} +#endif + +//-------------------------------------------------------------- DoUnlink + +#ifndef COMPILEDEMO +void DoUnlink (void) +{ + char wasState; + + if (thisRoomNumber == linkRoom) + { + if (linkerIsSwitch) + { + thisRoom->objects[linkObject].data.e.where = -1; + thisRoom->objects[linkObject].data.e.who = 255; + } + else + { + thisRoom->objects[linkObject].data.d.where = -1; + thisRoom->objects[linkObject].data.d.who = 255; + } + } + else + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + if (linkerIsSwitch) + { + (*thisHouse)->rooms[linkRoom].objects[linkObject].data.e.where = -1; + (*thisHouse)->rooms[linkRoom].objects[linkObject].data.e.who = 255; + } + else + { + (*thisHouse)->rooms[linkRoom].objects[linkObject].data.d.where = -1; + (*thisHouse)->rooms[linkRoom].objects[linkObject].data.d.who = 255; + } + HSetState((Handle)thisHouse, wasState); + } + fileDirty = true; + UpdateMenus(false); + CloseLinkWindow(); +} +#endif + +//-------------------------------------------------------------- HandleLinkClick + +void HandleLinkClick (Point wherePt) +{ +#ifndef COMPILEDEMO + ControlHandle theControl; + short part; + + if (linkWindow == nil) + return; + + SetPortWindowPort(linkWindow); + GlobalToLocal(&wherePt); + + part = FindControl(wherePt, linkWindow, &theControl); + if ((theControl != nil) && (part != 0)) + { + part = TrackControl(theControl, wherePt, nil); + if (part != 0) + { + if (theControl == linkControl) + DoLink(); + else if (theControl == unlinkControl) + DoUnlink(); + + if (thisRoomNumber == linkRoom) + CopyThisRoomToRoom(); + GenerateRetroLinks(); + } + } +#endif +} + diff --git a/GpApp/Main.cpp b/GpApp/Main.cpp new file mode 100644 index 0000000..2abae42 --- /dev/null +++ b/GpApp/Main.cpp @@ -0,0 +1,389 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Glider PRO 1.0.4 +// by john calhoun +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLApplication.h" +#include "Externs.h" +#include "Environ.h" +#include "House.h" + + +#define kPrefsVersion 0x0034 + + +void ReadInPrefs (void); +void WriteOutPrefs (void); +int main(int argc, const char **argv); + + +short isVolume, wasVolume; +short isDepthPref, dataResFile, numSMWarnings; +Boolean quitting, doZooms, quickerTransitions, isUseSecondScreen; + + +extern Str31 highBanner; +extern Str15 leftName, rightName, batteryName, bandName; +extern Str15 highName; +//extern long encryptedNumber; +extern short maxFiles, numNeighbors, houseRefNum, willMaxFiles; +extern short isEditH, isEditV, isMapH, isMapV; +extern short isToolsH, isToolsV, isCoordH, isCoordV; +extern short isLinkH, isLinkV, toolMode, mapLeftRoom, mapTopRoom; +extern short mapRoomsWide, mapRoomsHigh, wasFloor, wasSuite; +extern Boolean isMusicOn, isSoundOn, isPlayMusicIdle, isHouseChecks; +extern Boolean houseOpen, isDoColorFade, isEscPauseKey; +extern Boolean autoRoomEdit, doAutoDemo, doBackground; +extern Boolean isMapOpen, isToolsOpen, isCoordOpen; +extern Boolean doPrettyMap, doBitchDialogs; +//extern Boolean didValidation; + +//============================================================== Functions +//-------------------------------------------------------------- ReadInPrefs + +// Called only once when game launches - reads in the preferences savedÉ +// from the last time Glider PRO was launched. If no prefs are found,É +// it assigns default settings. + +void ReadInPrefs (void) +{ + prefsInfo thePrefs; + + if (LoadPrefs(&thePrefs, kPrefsVersion)) + { +#ifdef COMPILEDEMO + PasStringCopy("\pDemo House", thisHouseName); +#else + PasStringCopy(thePrefs.wasDefaultName, thisHouseName); +#endif + PasStringCopy(thePrefs.wasLeftName, leftName); + PasStringCopy(thePrefs.wasRightName, rightName); + PasStringCopy(thePrefs.wasBattName, batteryName); + PasStringCopy(thePrefs.wasBandName, bandName); + PasStringCopy(thePrefs.wasHighName, highName); + PasStringCopy(thePrefs.wasHighBanner, highBanner); + theGlider.leftKey = thePrefs.wasLeftMap; + theGlider.rightKey = thePrefs.wasRightMap; + theGlider.battKey = thePrefs.wasBattMap; + theGlider.bandKey = thePrefs.wasBandMap; +#ifndef COMPILEDEMO +#ifndef COMPILENOCP + encryptedNumber = thePrefs.encrypted; +#endif // COMPILENOCP +#endif // COMPILEDEMO + isVolume = thePrefs.wasVolume; + isDepthPref = thePrefs.wasDepthPref; + isMusicOn = thePrefs.wasMusicOn; + doZooms = thePrefs.wasZooms; + quickerTransitions = thePrefs.wasQuickTrans; + isDoColorFade = thePrefs.wasDoColorFade; + isPlayMusicIdle = thePrefs.wasIdleMusic; + isPlayMusicGame = thePrefs.wasGameMusic; + isHouseChecks = thePrefs.wasHouseChecks; + maxFiles = thePrefs.wasMaxFiles; + if ((maxFiles < 12) || (maxFiles > 500)) + maxFiles = 12; + isEditH = thePrefs.wasEditH; + isEditV = thePrefs.wasEditV; + isMapH = thePrefs.wasMapH; + isMapV = thePrefs.wasMapV; + mapRoomsWide = thePrefs.wasMapWide; + mapRoomsHigh = thePrefs.wasMapHigh; + isToolsH = thePrefs.wasToolsH; + isToolsV = thePrefs.wasToolsV; + isLinkH = thePrefs.wasLinkH; + isLinkV = thePrefs.wasLinkV; + isCoordH = thePrefs.wasCoordH; + isCoordV = thePrefs.wasCoordV; + mapLeftRoom = thePrefs.isMapLeft; + mapTopRoom = thePrefs.isMapTop; + wasFloor = thePrefs.wasFloor; + wasSuite = thePrefs.wasSuite; + numSMWarnings = thePrefs.smWarnings; + autoRoomEdit = thePrefs.wasAutoEdit; + isMapOpen = thePrefs.wasMapOpen; + isToolsOpen = thePrefs.wasToolsOpen; + isCoordOpen = thePrefs.wasCoordOpen; + numNeighbors = thePrefs.wasNumNeighbors; + toolMode = thePrefs.wasToolGroup; + doAutoDemo = thePrefs.wasDoAutoDemo; + isEscPauseKey = thePrefs.wasEscPauseKey; + isUseSecondScreen = thePrefs.wasScreen2; + if (thisMac.numScreens < 2) + isUseSecondScreen = false; + doBackground = thePrefs.wasDoBackground; + doPrettyMap = thePrefs.wasPrettyMap; + doBitchDialogs = thePrefs.wasBitchDialogs; + } + else + { +#ifdef COMPILEDEMO + PasStringCopy("\pDemo House", thisHouseName); +#else + PasStringCopy(PSTR("Slumberland"), thisHouseName); +#endif + PasStringCopy(PSTR("lf arrow"), leftName); + PasStringCopy(PSTR("rt arrow"), rightName); + PasStringCopy(PSTR("dn arrow"), batteryName); + PasStringCopy(PSTR("up arrow"), bandName); + PasStringCopy(PSTR("Your Name"), highName); + PasStringCopy(PSTR("Your Message Here"), highBanner); + theGlider.leftKey = kLeftArrowKeyMap; + theGlider.rightKey = kRightArrowKeyMap; + theGlider.battKey = kDownArrowKeyMap; + theGlider.bandKey = kUpArrowKeyMap; + + UnivGetSoundVolume(&isVolume, thisMac.hasSM3); + if (isVolume < 1) + isVolume = 1; + else if (isVolume > 3) + isVolume = 3; + + isDepthPref = kSwitchIfNeeded; + isSoundOn = true; + isMusicOn = true; + isPlayMusicIdle = true; + isPlayMusicGame = true; + isHouseChecks = true; + doZooms = true; + quickerTransitions = false; + numNeighbors = 9; + isDoColorFade = true; + maxFiles = 48; + willMaxFiles = 48; + isEditH = 3; + isEditV = 41; + isMapH = 3; +// isMapV = qd.screenBits.bounds.bottom - 100; + isMapV = 100; + mapRoomsWide = 15; + mapRoomsHigh = 4; +// isToolsH = qd.screenBits.bounds.right - 120; + isToolsH = 100; + isToolsV = 35; + isLinkH = 50; + isLinkV = 80; +// isCoordH = qd.screenBits.bounds.right - 55; + isCoordH = 50; + isCoordV = 204; + mapLeftRoom = 60; + mapTopRoom = 50; + wasFloor = 0; + wasSuite = 0; + numSMWarnings = 0; + autoRoomEdit = true; + isMapOpen = true; + isToolsOpen = true; + isCoordOpen = false; + toolMode = kBlowerMode; + doAutoDemo = true; + isEscPauseKey = false; + isUseSecondScreen = false; + doBackground = false; + doPrettyMap = false; + doBitchDialogs = true; + } + + if ((numNeighbors > 1) && (thisMac.screen.right <= 512)) + numNeighbors = 1; + + UnivGetSoundVolume(&wasVolume, thisMac.hasSM3); + UnivSetSoundVolume(isVolume, thisMac.hasSM3); + + if (isVolume == 0) + isSoundOn = false; + else + isSoundOn = true; +} + +//-------------------------------------------------------------- WriteOutPrefs + +// Called just before Glider PRO quits. This function writes outÉ +// the user preferences to disk. + +void WriteOutPrefs (void) +{ + prefsInfo thePrefs; + + UnivGetSoundVolume(&isVolume, thisMac.hasSM3); + +#ifdef COMPILEDEMO + PasStringCopy("\pDemo House", thePrefs.wasDefaultName); +#else + PasStringCopy(thisHouseName, thePrefs.wasDefaultName); +#endif + PasStringCopy(leftName, thePrefs.wasLeftName); + PasStringCopy(rightName, thePrefs.wasRightName); + PasStringCopy(batteryName, thePrefs.wasBattName); + PasStringCopy(bandName, thePrefs.wasBandName); + PasStringCopy(highName, thePrefs.wasHighName); + PasStringCopy(highBanner, thePrefs.wasHighBanner); + thePrefs.wasLeftMap = theGlider.leftKey; + thePrefs.wasRightMap = theGlider.rightKey; + thePrefs.wasBattMap = theGlider.battKey; + thePrefs.wasBandMap = theGlider.bandKey; +#ifndef COMPILEDEMO +#ifndef COMPILENOCP + thePrefs.encrypted = encryptedNumber; + thePrefs.fakeLong = Random(); +#endif // COMPILENOCP +#endif // COMPILEDEMO + thePrefs.wasVolume = isVolume; + thePrefs.wasDepthPref = isDepthPref; + thePrefs.wasMusicOn = isMusicOn; + thePrefs.wasZooms = doZooms; + thePrefs.wasQuickTrans = quickerTransitions; + thePrefs.wasDoColorFade = isDoColorFade; + thePrefs.wasIdleMusic = isPlayMusicIdle; + thePrefs.wasGameMusic = isPlayMusicGame; + thePrefs.wasHouseChecks = isHouseChecks; + thePrefs.wasMaxFiles = willMaxFiles; + thePrefs.wasEditH = isEditH; + thePrefs.wasEditV = isEditV; + thePrefs.wasMapH = isMapH; + thePrefs.wasMapV = isMapV; + thePrefs.wasMapWide = mapRoomsWide; + thePrefs.wasMapHigh = mapRoomsHigh; + thePrefs.wasToolsH = isToolsH; + thePrefs.wasToolsV = isToolsV; + thePrefs.isMapLeft = mapLeftRoom; + thePrefs.isMapTop = mapTopRoom; + thePrefs.wasFloor = wasFloor; + thePrefs.wasSuite = wasSuite; + thePrefs.wasLinkH = isLinkH; + thePrefs.wasLinkV = isLinkV; + thePrefs.wasCoordH = isCoordH; + thePrefs.wasCoordV = isCoordV; + thePrefs.smWarnings = numSMWarnings; + thePrefs.wasAutoEdit = autoRoomEdit; + thePrefs.wasMapOpen = isMapOpen; + thePrefs.wasToolsOpen = isToolsOpen; + thePrefs.wasCoordOpen = isCoordOpen; + thePrefs.wasNumNeighbors = numNeighbors; + thePrefs.wasToolGroup = toolMode; + thePrefs.wasDoAutoDemo = doAutoDemo; + thePrefs.wasEscPauseKey = isEscPauseKey; + thePrefs.wasScreen2 = isUseSecondScreen; + thePrefs.wasDoBackground = doBackground; + thePrefs.wasPrettyMap = doPrettyMap; + thePrefs.wasBitchDialogs = doBitchDialogs; + + if (!SavePrefs(&thePrefs, kPrefsVersion)) + SysBeep(1); + + UnivSetSoundVolume(wasVolume, thisMac.hasSM3); +} + +//-------------------------------------------------------------- main +// Here is main(). The first function called when Glider PRO comes up. + +int gpAppMain() +{ +// long wasSeed; + long theErr; + OSErr fileErr; + Boolean whoCares, copyGood; + + PL_Init(); + + ToolBoxInit(); + CheckOurEnvirons(); + if (!thisMac.hasColor) + RedAlert(kErrNeedColorQD); + if (!thisMac.hasSystem7) + RedAlert(kErrNeedSystem7); + if (thisMac.numScreens == 0) + RedAlert(kErrNeed16Or256Colors); +// dataResFile = OpenResFile("\pMermaid"); + SetUpAppleEvents(); + LoadCursors(); + ReadInPrefs(); + +#if defined COMPILEDEMO + copyGood = true; +#elif defined COMPILENOCP +// didValidation = false; + copyGood = true; +#else + didValidation = false; + copyGood = ValidInstallation(true); + if (!copyGood) + encryptedNumber = 0L; + else if (didValidation) + WriteOutPrefs(); SpinCursor(3); +#endif + +// if ((thisMac.numScreens > 1) && (isUseSecondScreen)) +// ReflectSecondMonitorEnvirons(false, true, true); + HandleDepthSwitching(); + VariableInit(); SpinCursor(2); + CheckMemorySize(); + GetExtraCursors(); SpinCursor(2); + InitMarquee(); + CreatePointers(); SpinCursor(2); + InitSrcRects(); + CreateOffscreens(); SpinCursor(2); + OpenMainWindow(); + + if (thisMac.hasQT) + { + theErr = EnterMovies(); + if (theErr != noErr) + thisMac.hasQT = false; + } + + InitSound(); SpinCursor(2); + InitMusic(); SpinCursor(2); + BuildHouseList(); + if (OpenHouse()) + whoCares = ReadHouse(); + + PlayPrioritySound(kBirdSound, kBirdPriority); + DelayTicks(6); + InitializeMenus(); InitCursor(); + +#if BUILD_ARCADE_VERSION +// HideMenuBarOld(); +#endif + +// if ((isDoColorFade) && (thisMac.isDepth == 8)) +// { +// wasSeed = ExtractCTSeed((CGrafPtr)mainWindow); +// WashColorIn(); +// ForceCTSeed((CGrafPtr)mainWindow, wasSeed); +// } +// if ((!thisMac.hasSM3) && (numSMWarnings < 3)) +// { +// numSMWarnings++; +// BitchAboutSM3(); +// } + + while (!quitting) // this is the main loop + HandleEvent(); +/* +#if BUILD_ARCADE_VERSION + ShowMenuBarOld(); +#endif +*/ + KillMusic(); + KillSound(); + if (houseOpen) + { + if (!CloseHouse()) + { + CloseHouseResFork(); + fileErr = FSClose(houseRefNum); + houseOpen = false; + } + } + WriteOutPrefs(); + RestoreColorDepth(); + PL_DEAD(FlushEvents(everyEvent, 0)); +// theErr = LoadScrap(); + + return 0; +} + diff --git a/GpApp/MainWindow.cpp b/GpApp/MainWindow.cpp new file mode 100644 index 0000000..88f2b46 --- /dev/null +++ b/GpApp/MainWindow.cpp @@ -0,0 +1,602 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// MainWindow.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLNumberFormatting.h" +#include "PLToolUtils.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "House.h" +#include "RectUtils.h" + + +#define kMainWindowID 128 +#define kEditWindowID 129 +#define kMenuWindowID 130 + + +void DrawOnSplash (void); +void SetPaletteToGrays (void); +void HardDrawMainWindow (void); +void RestoreColorsSlam (void); + + +CTabHandle theCTab; +PixMapHandle thePMap; +ColorSpec * wasColors; +ColorSpec * newColors; +CursHandle handCursorH, beamCursorH, vertCursorH, horiCursorH; +CursHandle diagCursorH; +Cursor handCursor, beamCursor, vertCursor, horiCursor; +Cursor diagCursor; +Rect workSrcRect; +GWorldPtr workSrcMap; +Rect mainWindowRect; +WindowPtr mainWindow, menuWindow; +short isEditH, isEditV; +short playOriginH, playOriginV; +short splashOriginH, splashOriginV; +short theMode; +Boolean fadeGraysOut, isDoColorFade, splashDrawn; + +extern GDHandle thisGDevice; +extern short toolSelected; +extern Boolean noRoomAtAll, isUseSecondScreen; +extern Boolean quickerTransitions, houseIsReadOnly; + + +//============================================================== Functions +//-------------------------------------------------------------- DrawOnSplash + +// Draws additional text on top of splash screen. + +void DrawOnSplash (void) +{ + Str255 houseLoadedStr; + + PasStringCopy(PSTR("House: "), houseLoadedStr); + PasStringConcat(houseLoadedStr, thisHouseName); + if ((thisMac.hasQT) && (hasMovie)) + PasStringConcat(houseLoadedStr, PSTR(" (QT)")); + TextSize(9); + TextFace(1); + TextFont(applFont); + MoveTo(splashOriginH + 436, splashOriginV + 314); + if (thisMac.isDepth == 4) + { + ForeColor(whiteColor); + DrawString(houseLoadedStr); + ForeColor(blackColor); + } + else + { + if (houseIsReadOnly) + ColorText(houseLoadedStr, 5L); + else + ColorText(houseLoadedStr, 28L); + } + + #if defined(powerc) || defined(__powerc) + TextSize(12); + TextFace(0); + TextFont(systemFont); + ForeColor(blackColor); + MoveTo(splashOriginH + 5, splashOriginV + 457); + DrawString("\pPowerPC Native!"); + ForeColor(whiteColor); + MoveTo(splashOriginH + 4, splashOriginV + 456); + DrawString("\pPowerPC Native!"); + ForeColor(blackColor); + #endif +} + +//-------------------------------------------------------------- RedrawSplashScreen + +void RedrawSplashScreen (void) +{ + Rect tempRect; + + SetPort((GrafPtr)workSrcMap); + PaintRect(&workSrcRect); + QSetRect(&tempRect, 0, 0, 640, 460); + QOffsetRect(&tempRect, splashOriginH, splashOriginV); + LoadScaledGraphic(kSplash8BitPICT, &tempRect); + DrawOnSplash(); + SetPortWindowPort(mainWindow); +// if (quickerTransitions) +// DissBitsChunky(&workSrcRect); +// else +// DissBits(&workSrcRect); + CopyRectMainToWork(&workSrcRect); +} + +//-------------------------------------------------------------- UpdateMainWindow + +// Redraws the main window (depends on mode were in - splash, editing, playing). + +void UpdateMainWindow (void) +{ + Rect tempRect; + RgnHandle dummyRgn; + + dummyRgn = NewRgn(); + SetPortWindowPort(mainWindow); + + if (theMode == kEditMode) + { + PauseMarquee(); + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &mainWindowRect, &mainWindowRect, srcCopy, + GetPortVisibleRegion(GetWindowPort(mainWindow), dummyRgn)); + ResumeMarquee(); + } + else if ((theMode == kSplashMode) || (theMode == kPlayMode)) + { + SetPort((GrafPtr)workSrcMap); + PaintRect(&workSrcRect); + QSetRect(&tempRect, 0, 0, 640, 460); + QOffsetRect(&tempRect, splashOriginH, splashOriginV); + LoadScaledGraphic(kSplash8BitPICT, &tempRect); + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &workSrcRect, &mainWindowRect, srcCopy, + GetPortVisibleRegion(GetWindowPort(mainWindow), dummyRgn)); + SetPortWindowPort(mainWindow); + + DrawOnSplash(); + } + + DisposeRgn(dummyRgn); + splashDrawn = true; +} + +//-------------------------------------------------------------- UpdateMenuBarWindow +// Ugly kludge to cover over the menu bar when playing game on 2nd monitor. + +void UpdateMenuBarWindow (void) +{ + Rect bounds; + + if (menuWindow == nil) + return; + + GetLocalWindowRect(menuWindow, &bounds); + PaintRect(&bounds); +} + +//-------------------------------------------------------------- OpenMainWindow +// Opens up the main window (how it does this depends on mode were in). + +void OpenMainWindow (void) +{ +// long wasSeed; + short whichRoom; + + if (mainWindow != nil) + { + YellowAlert(kYellowUnaccounted, 6); + return; + } + + if (theMode == kEditMode) + { + if (menuWindow != nil) + DisposeWindow(menuWindow); + menuWindow = nil; + + QSetRect(&mainWindowRect, 0, 0, 512, 322); + mainWindow = GetNewCWindow(kEditWindowID, nil, kPutInFront); + SizeWindow(mainWindow, mainWindowRect.right, + mainWindowRect.bottom, false); + + if (OptionKeyDown()) + { + isEditH = 3; + isEditV = 41; + } + MoveWindow(mainWindow, isEditH, isEditV, true); + ShowWindow(mainWindow); + SetPortWindowPort(mainWindow); + ClipRect(&mainWindowRect); + ForeColor(blackColor); + BackColor(whiteColor); + + whichRoom = GetFirstRoomNumber(); + CopyRoomToThisRoom(whichRoom); + ReflectCurrentRoom(false); + } + else + { + if (menuWindow == nil) + { + menuWindow = GetNewCWindow(kMenuWindowID, nil, kPutInFront); + SizeWindow(menuWindow, RectWide(&thisMac.screen), 20, false); + MoveWindow(menuWindow, thisMac.screen.left, + thisMac.screen.top, true); + ShowWindow(menuWindow); + } + mainWindowRect = thisMac.screen; + ZeroRectCorner(&mainWindowRect); + mainWindowRect.bottom -= 20; // thisMac.menuHigh + mainWindow = GetNewCWindow(kMainWindowID, nil, kPutInFront); + SizeWindow(mainWindow, mainWindowRect.right - mainWindowRect.left, + mainWindowRect.bottom - mainWindowRect.top, false); + MoveWindow(mainWindow, thisMac.screen.left, + thisMac.screen.top + 20, true); // thisMac.menuHigh + ShowWindow(mainWindow); + SetPortWindowPort(mainWindow); + ClipRect(&mainWindowRect); +// CopyRgn(mainWindow->clipRgn, mainWindow->visRgn); + ForeColor(blackColor); + BackColor(whiteColor); + PaintRect(&mainWindowRect); + + splashOriginH = ((thisMac.screen.right - thisMac.screen.left) - 640) / 2; + if (splashOriginH < 0) + splashOriginH = 0; + splashOriginV = ((thisMac.screen.bottom - thisMac.screen.top) - 480) / 2; + if (splashOriginV < 0) + splashOriginV = 0; + + SetPort((GrafPtr)workSrcMap); + PaintRect(&workSrcRect); + LoadGraphic(kSplash8BitPICT); + +// if ((fadeGraysOut) && (isDoColorFade)) +// { +// wasSeed = ExtractCTSeed((CGrafPtr)mainWindow); +// SetPortWindowPort(mainWindow); +// SetPaletteToGrays(); +// HardDrawMainWindow(); +// fadeGraysOut = false; +// ForceCTSeed((CGrafPtr)mainWindow, wasSeed); +// } + + SetPortWindowPort(mainWindow); + } +} + +//-------------------------------------------------------------- CloseMainWindow + +// Closes the main window. + +void CloseMainWindow (void) +{ + if (mainWindow != nil) + DisposeWindow(mainWindow); + mainWindow = nil; +} + +//-------------------------------------------------------------- ZoomBetweenWindows +// Zooms from one window size to another. Just for effect. + +/* +#ifndef COMPILEDEMO +void ZoomBetweenWindows (void) +{ + Rect aRect; + short h, v; + + if (theMode == kEditMode) + { + QSetRect(&aRect, 0, 0, 512, 342); + QOffsetRect(&aRect, isEditH, isEditV); + ZoomRectToRect(&(thisMac.screen), &aRect); + } + else + { + aRect = mainWindow->portRect; + GetWindowLeftTop(mainWindow, &h, &v); + QOffsetRect(&aRect, h, v); + ZoomRectToRect(&aRect, &(thisMac.screen)); + } +} +#endif +*/ + +//-------------------------------------------------------------- UpdateEditWindowTitle +// Handles changing the title across the top of the main window. OnlyÉ +// relevant when editing a house (room title displayed in window title). + +#ifndef COMPILEDEMO +void UpdateEditWindowTitle (void) +{ + Str255 newTitle, tempStr; + + if (mainWindow == nil) + return; + + PasStringCopy(thisHouseName, newTitle); + PasStringConcat(newTitle, PSTR(" - ")); + if (noRoomAtAll) + PasStringConcat(newTitle, PSTR("No rooms")); + else if (houseUnlocked) + { + PasStringConcat(newTitle, thisRoom->name); + PasStringConcat(newTitle, PSTR(" (")); + NumToString((long)thisRoom->floor, tempStr); + PasStringConcat(newTitle, tempStr); + PasStringConcat(newTitle, PSTR(", ")); + NumToString((long)thisRoom->suite, tempStr); + PasStringConcat(newTitle, tempStr); + PasStringConcat(newTitle, PSTR(")")); + } + else + PasStringConcat(newTitle, PSTR("House Locked")); + SetWTitle(mainWindow, newTitle); +} +#endif + +//-------------------------------------------------------------- HandleMainClick + +// Handle a mouse click in the main window (relevant only when editing). + +void HandleMainClick (Point wherePt, Boolean isDoubleClick) +{ + KeyMap theseKeys; + + if ((theMode != kEditMode) || (mainWindow == nil) || + (!houseUnlocked)) + return; + + SetPortWindowPort(mainWindow); + GlobalToLocal(&wherePt); + + if (toolSelected == kSelectTool) + DoSelectionClick(wherePt, isDoubleClick); + else + DoNewObjectClick(wherePt); + + GetKeys(theseKeys); + if (!BitTst(&theseKeys, kShiftKeyMap)) + { + EraseSelectedTool(); + SelectTool(kSelectTool); + } +} + +//-------------------------------------------------------------- ShowMenuBarOld +// Displays the menu bar (after having been hidden). +/* +void ShowMenuBarOld (void) +{ + Rect theRect; + GrafPtr wasPort, tempPort; + RgnHandle worldRgn, menuBarRgn; + + if (LMGetMBarHeight() == 0) + { + GetPort(&wasPort); + tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); + OpenPort(tempPort); + SetPort((GrafPtr)tempPort); + + LMSetMBarHeight(thisMac.menuHigh); + + theRect = (**GetGrayRgn()).rgnBBox; + UnionRect(&theRect, &qd.screenBits.bounds, &theRect); + worldRgn = NewRgn(); + OpenRgn(); + FrameRoundRect(&theRect, 16, 16); + CloseRgn(worldRgn); + + theRect = qd.screenBits.bounds; + theRect.bottom = theRect.top + thisMac.menuHigh; + menuBarRgn = NewRgn(); + RectRgn(menuBarRgn, &theRect); + + SectRgn(worldRgn, menuBarRgn, menuBarRgn); // /------------------\ + DisposeRgn(worldRgn); // |__________________| + + UnionRgn(tempPort->visRgn, menuBarRgn, tempPort->visRgn); + DiffRgn(tempPort->visRgn, menuBarRgn, tempPort->visRgn); + DisposeRgn(menuBarRgn); + + ClosePort(tempPort); + SetPort((GrafPtr)wasPort); + + DrawMenuBar(); + } +} +*/ +//-------------------------------------------------------------- HideMenuBarOld +// Hides the menu bar - completely erasing it from the screen. +/* +void HideMenuBarOld (void) +{ + Rect theRect; + RgnHandle worldRgn, menuBarRgn; + GrafPtr wasPort, tempPort; + + if (LMGetMBarHeight() != 0) + { + GetPort(&wasPort); + tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); + OpenPort(tempPort); + SetPort((GrafPtr)tempPort); + + LMSetMBarHeight(0); + + theRect = (**GetGrayRgn()).rgnBBox; + UnionRect(&theRect, &qd.screenBits.bounds, &theRect); + worldRgn = NewRgn(); + OpenRgn(); + FrameRoundRect(&theRect, 16, 16); + CloseRgn(worldRgn); + + theRect = qd.screenBits.bounds; + theRect.bottom = theRect.top + thisMac.menuHigh; + menuBarRgn = NewRgn(); + RectRgn(menuBarRgn, &theRect); + + SectRgn(worldRgn, menuBarRgn, menuBarRgn); // /------------------\ + DisposeRgn(worldRgn); // |__________________| + + UnionRgn(tempPort->visRgn, menuBarRgn, tempPort->visRgn); + DisposeRgn(menuBarRgn); + + PaintRect(&theRect); + + ClosePort(tempPort); + SetPort((GrafPtr)wasPort); + } +} +*/ +//-------------------------------------------------------------- SetPaletteToGrays + +// Sets up a gray palette corresponding in luminance to the standard colorÉ +// palette. This is to facilitate the gray->color fade when the game comes up. +/* +void SetPaletteToGrays (void) +{ + GDHandle theDevice; + long longGray; + short i; + char wasState; + + wasState = HGetState((Handle)thisGDevice); + HLock((Handle)thisGDevice); + thePMap = (*thisGDevice)->gdPMap; + HSetState((Handle)thisGDevice, wasState); + + theCTab = (*thePMap)->pmTable; + wasColors = nil; + wasColors = (ColorSpec*)NewPtr(sizeof(ColorSpec) * 256); + if (wasColors == nil) + RedAlert(kErrNoMemory); + + newColors = nil; + newColors = (ColorSpec*)NewPtr(sizeof(ColorSpec) * 256); + if (newColors == nil) + RedAlert(kErrNoMemory); + + for (i = 0; i < 256; i++) + { + wasColors[i] = (*theCTab)->ctTable[i]; + newColors[i] = (*theCTab)->ctTable[i]; + + if (i != 5) + { + longGray = ((long)newColors[i].rgb.red * 3L) / 10L + + ((long)newColors[i].rgb.green * 6L) / 10L + + ((long)newColors[i].rgb.blue * 1L) / 10L; + + newColors[i].rgb.red = (unsigned short)longGray; + newColors[i].rgb.green = (unsigned short)longGray; + newColors[i].rgb.blue = (unsigned short)longGray; + } + } + + theDevice = GetGDevice(); + SetGDevice(thisGDevice); + SetEntries(0, 255, newColors); + SetGDevice(theDevice); +} +*/ +//-------------------------------------------------------------- HardDrawMainWindow +// Ignores the ToolBox - this function draws direct to screen in order toÉ +// circumvent the Toolbox's attempt to color-match to the current palette. +/* +void HardDrawMainWindow (void) +{ + PixMapHandle pixMapH; + Point offsetPt; + long srcRowBytes, destRowBytes; + long src; + long dest; + short i, w; + SInt8 mode; + char wasState; + + wasState = HGetState((Handle)thisGDevice); + HLock((Handle)thisGDevice); + pixMapH = (**thisGDevice).gdPMap; + HSetState((Handle)thisGDevice, wasState); + + srcRowBytes = (long)((*(workSrcMap->portPixMap))->rowBytes & 0x7FFF); + destRowBytes = (**pixMapH).rowBytes & 0x7FFF; + src = (long)((*(workSrcMap->portPixMap))->baseAddr); + dest = (long)((**pixMapH).baseAddr) + splashOriginH + + ((splashOriginV + thisMac.menuHigh) * destRowBytes); + + offsetPt.h = 0; + offsetPt.v = 0; + ShieldCursor(&mainWindowRect, offsetPt); + mode = true32b; + SwapMMUMode(&mode); + for (i = 0; i < 460; i++) + { + for (w = 0; w < 160; w++) + { + *(long *)dest = *(long *)src; + dest += 4L; + src += 4L; + } + src -= 640; + dest -= 640; + src += srcRowBytes; + dest += destRowBytes; + } + SwapMMUMode(&mode); + ShowCursor(); +} +*/ +//-------------------------------------------------------------- WashColorIn +// Slowly walks the palette from its gray luminance state to the full colorÉ +// palette. In this way, color appears to slowly wash in. +/* +void WashColorIn (void) +{ + #define kGray2ColorSteps 180 + GDHandle theDevice; + long longDelta; + short i, c; + + theDevice = GetGDevice(); + SetGDevice(thisGDevice); + + for (i = 0; i < kGray2ColorSteps; i++) + { + for (c = 0; c < 256; c++) + { + if (c != 5) + { + longDelta = (((long)wasColors[c].rgb.red - + (long)newColors[c].rgb.red) / + (long)(kGray2ColorSteps - i)) + (long)newColors[c].rgb.red; + newColors[c].rgb.red = (unsigned short)longDelta; + + longDelta = (((long)wasColors[c].rgb.green - + (long)newColors[c].rgb.green) / + (long)(kGray2ColorSteps - i)) + + (long)newColors[c].rgb.green; + newColors[c].rgb.green = (unsigned short)longDelta; + + longDelta = (((long)wasColors[c].rgb.blue - + (long)newColors[c].rgb.blue) / + (long)(kGray2ColorSteps - i)) + + (long)newColors[c].rgb.blue; + newColors[c].rgb.blue = (unsigned short)longDelta; + } + } + SetEntries(0, 255, newColors); + if (Button()) + break; + } + + SetEntries(0, 255, wasColors); + SetGDevice(theDevice); + + RestoreColorsSlam(); + + if (wasColors != nil) + DisposePtr((Ptr)wasColors); + if (newColors != nil) + DisposePtr((Ptr)newColors); +} +*/ diff --git a/GpApp/MainWindow.h b/GpApp/MainWindow.h new file mode 100644 index 0000000..46bfe37 --- /dev/null +++ b/GpApp/MainWindow.h @@ -0,0 +1,11 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// MainWindow.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +extern GWorldPtr workSrcMap; diff --git a/GpApp/Map.cpp b/GpApp/Map.cpp new file mode 100644 index 0000000..bace10e --- /dev/null +++ b/GpApp/Map.cpp @@ -0,0 +1,797 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Map.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLControlDefinitions.h" +#include "PLResources.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "House.h" +#include "RectUtils.h" +#include "Utilities.h" + + +#define kMapRoomsHigh 9 // was 7 +#define kMapRoomsWide 9 // was 7 +#define kMapScrollBarWidth 16 +#define kHScrollRef 5L +#define kVScrollRef 27L +#define kMapGroundValue 56 +#define kNewRoomAlert 1004 +#define kYesDoNewRoom 1 +#define kThumbnailPictID 1010 + + +void LoadGraphicPlus (short, Rect *); +void RedrawMapContents (void); +void LiveHScrollAction (ControlHandle, short); +void LiveVScrollAction (ControlHandle, short); +Boolean QueryNewRoom (void); +void CreateNailOffscreen (void); +void KillNailOffscreen (void); + +Rect nailSrcRect, activeRoomRect, wasActiveRoomRect; +Rect mapHScrollRect, mapVScrollRect, mapCenterRect; +Rect mapWindowRect; +GWorldPtr nailSrcMap; +WindowPtr mapWindow; +ControlHandle mapHScroll, mapVScroll; +short isMapH, isMapV, mapRoomsHigh, mapRoomsWide; +short mapLeftRoom, mapTopRoom; +Boolean isMapOpen, doPrettyMap; + +extern Boolean doBitchDialogs; + + +//============================================================== Functions +//-------------------------------------------------------------- ThisRoomVisibleOnMap + +#ifndef COMPILEDEMO +Boolean ThisRoomVisibleOnMap (void) +{ + short h, v; + + h = thisRoom->suite; + v = kMapGroundValue - thisRoom->floor; + + if ((h < mapLeftRoom) || (v < mapTopRoom) || + (h >= (mapLeftRoom + mapRoomsWide)) || + (v >= (mapTopRoom + mapRoomsHigh))) + return (false); + else + return (true); +} +#endif + +//-------------------------------------------------------------- CenterMapOnRoom + +#ifndef COMPILEDEMO +void CenterMapOnRoom (short h, short v) +{ + if (mapWindow == nil) + return; + + mapLeftRoom = h - (mapRoomsWide / 2); + mapTopRoom = (kMapGroundValue - v) - (mapRoomsHigh / 2); + + if (mapLeftRoom < 0) + mapLeftRoom = 0; + else if (mapLeftRoom > (kMaxNumRoomsH - mapRoomsWide)) + mapLeftRoom = kMaxNumRoomsH - mapRoomsWide; + + if (mapTopRoom < 0) + mapTopRoom = 0; + else if (mapTopRoom > (kMaxNumRoomsV - mapRoomsHigh)) + mapTopRoom = kMaxNumRoomsV - mapRoomsHigh; + + if (mapWindow != nil) + { + SetControlValue(mapHScroll, mapLeftRoom); + SetControlValue(mapVScroll, mapTopRoom); + } +} +#endif + +//-------------------------------------------------------------- FlagMapRoomsForUpdate + +#ifndef COMPILEDEMO +void FlagMapRoomsForUpdate (void) +{ + if (mapWindow == nil) + return; + +// SetPortWindowPort(mapWindow); + InvalWindowRect(mapWindow, &wasActiveRoomRect); + InvalWindowRect(mapWindow, &activeRoomRect); +} +#endif + +//-------------------------------------------------------------- FindNewActiveRoomRect + +#ifndef COMPILEDEMO +void FindNewActiveRoomRect (void) +{ + Rect aRoom; + short h, i; + short floor, suite, whoCares; + char wasState; + Boolean activeRoomVisible; + + if (mapWindow == nil) + return; + + activeRoomVisible = false; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + for (i = 0; i < mapRoomsHigh; i++) + { + for (h = 0; h < mapRoomsWide; h++) + { + QSetRect(&aRoom, 0, 0, kMapRoomWidth, kMapRoomHeight); + QOffsetRect(&aRoom, kMapRoomWidth * h, kMapRoomHeight * i); + + suite = h + mapLeftRoom; + floor = kMapGroundValue - (i + mapTopRoom); + if ((RoomExists(suite, floor, &whoCares)) && (houseUnlocked)) + { + if (whoCares == thisRoomNumber) + { + wasActiveRoomRect = activeRoomRect; + activeRoomRect = aRoom; + activeRoomVisible = true; + } + } + } + } + + HSetState((Handle)thisHouse, wasState); + + if (activeRoomVisible) + { + activeRoomRect.right++; + activeRoomRect.bottom++; + InsetRect(&activeRoomRect, -1, -1); + } +} +#endif + +//-------------------------------------------------------------- LoadGraphicPlus + +void LoadGraphicPlus (short resID, Rect *theRect) +{ + PicHandle thePicture; + + thePicture = GetPicture(resID); + if (thePicture == nil) + { + thePicture = (PicHandle)GetResource('Date', resID); + if (thePicture == nil) + { + return; + } + } + DrawPicture(thePicture, theRect); + ReleaseResource((Handle)thePicture); +} + +//-------------------------------------------------------------- RedrawMapContents + +#ifndef COMPILEDEMO +void RedrawMapContents (void) +{ + Rect newClip, aRoom, src; + RgnHandle wasClip; + short h, i, groundLevel; + short floor, suite, whoCares, type; + char wasState; + Boolean activeRoomVisible; + + if (mapWindow == nil) + return; + + activeRoomVisible = false; + groundLevel = kMapGroundValue - mapTopRoom; + + newClip.left = mapWindowRect.left; + newClip.top = mapWindowRect.top; + newClip.right = mapWindowRect.right + 2 - kMapScrollBarWidth; + newClip.bottom = mapWindowRect.bottom + 2 - kMapScrollBarWidth; + + SetPort((GrafPtr)mapWindow); + wasClip = NewRgn(); + if (wasClip != nil) + { + GetClip(wasClip); + ClipRect(&newClip); + } + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + for (i = 0; i < mapRoomsHigh; i++) + { + for (h = 0; h < mapRoomsWide; h++) + { + QSetRect(&aRoom, 0, 0, kMapRoomWidth, kMapRoomHeight); + QOffsetRect(&aRoom, kMapRoomWidth * h, kMapRoomHeight * i); + + suite = h + mapLeftRoom; + floor = kMapGroundValue - (i + mapTopRoom); + if ((RoomExists(suite, floor, &whoCares)) && (houseUnlocked)) + { + PenNormal(); + type = (*thisHouse)->rooms[whoCares].background - kBaseBackgroundID; + if (type > kNumBackgrounds) + { + if (!doPrettyMap) + type = kNumBackgrounds; // Draw "?" thumbnail. + } + ForeColor(blackColor); + if (type > kNumBackgrounds) // Do a "pretty" thumbnail. + { + LoadGraphicPlus(type + kBaseBackgroundID, &aRoom); + } + else + { + QSetRect(&src, 0, 0, kMapRoomWidth, kMapRoomHeight); + QOffsetRect(&src, 0, type * kMapRoomHeight); + CopyBits((BitMap *)*GetGWorldPixMap(nailSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mapWindow)), + &src, &aRoom, srcCopy, nil); + } + + if (whoCares == thisRoomNumber) + { + activeRoomRect = aRoom; + activeRoomVisible = true; + } + } + else + { + Pattern dummyPat; + + PenPat(GetQDGlobalsGray(&dummyPat)); + if (i >= groundLevel) + ForeColor(greenColor); + else + ForeColor(blueColor); + PaintRect(&aRoom); + } + } + } + + HSetState((Handle)thisHouse, wasState); + + ForeColor(blackColor); + PenNormal(); + + for (i = 1; i < mapRoomsWide; i++) + { + MoveTo(i * kMapRoomWidth, 0); + Line(0, mapRoomsHigh * kMapRoomHeight); + } + + for (i = 1; i < mapRoomsHigh; i++) + { + MoveTo(0, i * kMapRoomHeight); + Line(mapRoomsWide * kMapRoomWidth, 0); + } + + if (activeRoomVisible) + { + ForeColor(redColor); + activeRoomRect.right++; + activeRoomRect.bottom++; + FrameRect(&activeRoomRect); + InsetRect(&activeRoomRect, 1, 1); + FrameRect(&activeRoomRect); + ForeColor(blackColor); + InsetRect(&activeRoomRect, -1, -1); + } + + if (wasClip != nil) + { + SetClip(wasClip); + DisposeRgn(wasClip); + } +} +#endif + +//-------------------------------------------------------------- UpdateMapWindow + +void UpdateMapWindow (void) +{ + #ifndef COMPILEDEMO + if (mapWindow == nil) + return; + + SetControlValue(mapHScroll, mapLeftRoom); + SetControlValue(mapVScroll, mapTopRoom); + + SetPortWindowPort(mapWindow); + DrawControls(mapWindow); + DrawGrowIcon(mapWindow); + RedrawMapContents(); + #endif +} + +//-------------------------------------------------------------- ResizeMapWindow + +void ResizeMapWindow (short newH, short newV) +{ +#ifndef COMPILEDEMO + if ((newH == 0) && (newV == 0)) + return; + + SetPortWindowPort(mapWindow); + mapRoomsWide = newH / kMapRoomWidth; + if (mapRoomsWide < 3) + mapRoomsWide = 3; + mapRoomsHigh = newV / kMapRoomHeight; + if (mapRoomsHigh < 3) + mapRoomsHigh = 3; + QSetRect(&mapWindowRect, 0, 0, + mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth - 2, + mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth - 2); + EraseRect(&mapWindowRect); + SizeWindow(mapWindow, mapWindowRect.right, mapWindowRect.bottom, true); + + SetControlMaximum(mapHScroll, kMaxNumRoomsH - mapRoomsWide); + MoveControl(mapHScroll, 0, mapWindowRect.bottom - kMapScrollBarWidth + 2); + SizeControl(mapHScroll, mapWindowRect.right - kMapScrollBarWidth + 3, + kMapScrollBarWidth); + mapLeftRoom = GetControlValue(mapHScroll); + + SetControlMaximum(mapVScroll, kMaxNumRoomsV - mapRoomsHigh); + MoveControl(mapVScroll, mapWindowRect.right - kMapScrollBarWidth + 2, 0); + SizeControl(mapVScroll, kMapScrollBarWidth, + mapWindowRect.bottom - kMapScrollBarWidth + 3); + mapTopRoom = GetControlValue(mapVScroll); + + InvalWindowRect(mapWindow, &mapWindowRect); +#endif +} + +//-------------------------------------------------------------- OpenMapWindow + +void OpenMapWindow (void) +{ +#ifndef COMPILEDEMO + Rect src, dest; + Point globalMouse; + + if (mapWindow == nil) + { + CreateNailOffscreen(); + QSetRect(&mapWindowRect, 0, 0, + mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth - 2, + mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth - 2); + mapWindow = NewCWindow(nil, &mapWindowRect, + PSTR("Map"), false, kWindoidGrowWDEF, kPutInFront, true, 0L); + + if (mapWindow == nil) + RedAlert(kErrNoMemory); + +// if (OptionKeyDown()) +// { +// isMapH = 3; +// isMapV = qd.screenBits.bounds.bottom - 100; +// } + MoveWindow(mapWindow, isMapH, isMapV, true); + globalMouse = MyGetGlobalMouse(); + QSetRect(&wasActiveRoomRect, 0, 0, 1, 1); + QSetRect(&activeRoomRect, 0, 0, 1, 1); + QSetRect(&src, 0, 0, 1, 1); + QOffsetRect(&src, globalMouse.h, globalMouse.v); + GetWindowRect(mapWindow, &dest); + BringToFront(mapWindow); + ShowHide(mapWindow, true); +// FlagWindowFloating(mapWindow); TEMP - use flaoting windows + HiliteAllWindows(); + + SetPort((GrafPtr)mapWindow); + SetOrigin(1, 1); + QSetRect(&mapHScrollRect, -1, mapRoomsHigh * kMapRoomHeight, + mapRoomsWide * kMapRoomWidth + 1, + mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth); + QSetRect(&mapVScrollRect, mapRoomsWide * kMapRoomWidth, -1, + mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth, + mapRoomsHigh * kMapRoomHeight + 1); + mapHScroll = NewControl(mapWindow, &mapHScrollRect, PSTR(""), true, mapLeftRoom, + 0, kMaxNumRoomsH - mapRoomsWide, scrollBarProc, kHScrollRef); + if (mapHScroll == nil) + RedAlert(kErrNoMemory); + + mapVScroll = NewControl(mapWindow, &mapVScrollRect, PSTR(""), true, mapTopRoom, + 0, kMaxNumRoomsV - mapRoomsHigh, scrollBarProc, kVScrollRef); + if (mapVScroll == nil) + RedAlert(kErrNoMemory); + + QSetRect(&mapCenterRect, -16, -16, 0, 0); + QOffsetRect(&mapCenterRect, mapWindowRect.right + 2, + mapWindowRect.bottom + 2); + + CenterMapOnRoom(thisRoom->suite, thisRoom->floor); + } + + UpdateMapCheckmark(true); +#endif +} + +//-------------------------------------------------------------- CloseMapWindow + +void CloseMapWindow (void) +{ +#ifndef COMPILEDEMO + CloseThisWindow(&mapWindow); + UpdateMapCheckmark(false); +#endif +} + +//-------------------------------------------------------------- ToggleMapWindow + +void ToggleMapWindow (void) +{ +#ifndef COMPILEDEMO + if (mapWindow == nil) + { + OpenMapWindow(); + isMapOpen = true; + } + else + { + CloseMapWindow(); + isMapOpen = false; + } +#endif +} + +//-------------------------------------------------------------- LiveHScrollAction +#ifndef COMPILEDEMO + +void LiveHScrollAction (ControlHandle theControl, short thePart) +{ + short wasValue, newValue; + + switch (thePart) + { + case kControlUpButtonPart: + wasValue = GetControlValue(theControl); + SetControlValue(theControl, wasValue - 1); + if (GetControlValue(theControl) != wasValue) + { + mapLeftRoom = GetControlValue(theControl); + RedrawMapContents(); + } + break; + + case kControlDownButtonPart: + wasValue = GetControlValue(theControl); + SetControlValue(theControl, wasValue + 1); + if (GetControlValue(theControl) != wasValue) + { + mapLeftRoom = GetControlValue(theControl); + RedrawMapContents(); + } + break; + + case kControlPageUpPart: + wasValue = GetControlValue(theControl); + newValue = wasValue - (mapRoomsWide / 2); + SetControlValue(theControl, newValue); + if (GetControlValue(theControl) != wasValue) + { + mapLeftRoom = GetControlValue(theControl); + RedrawMapContents(); + } + break; + + case kControlPageDownPart: + wasValue = GetControlValue(theControl); + newValue = wasValue + (mapRoomsWide / 2); + SetControlValue(theControl, newValue); + if (GetControlValue(theControl) != wasValue) + { + mapLeftRoom = GetControlValue(theControl); + RedrawMapContents(); + } + break; + + case kControlIndicatorPart: + break; + } +} +#endif + +//-------------------------------------------------------------- LiveVScrollAction +#ifndef COMPILEDEMO + +void LiveVScrollAction (ControlHandle theControl, short thePart) +{ + short wasValue, newValue; + + switch (thePart) + { + case kControlUpButtonPart: + wasValue = GetControlValue(theControl); + SetControlValue(theControl, wasValue - 1); + if (GetControlValue(theControl) != wasValue) + { + mapTopRoom = GetControlValue(theControl); + RedrawMapContents(); + } + break; + + case kControlDownButtonPart: + wasValue = GetControlValue(theControl); + SetControlValue(theControl, wasValue + 1); + if (GetControlValue(theControl) != wasValue) + { + mapTopRoom = GetControlValue(theControl); + RedrawMapContents(); + } + break; + + case kControlPageUpPart: + wasValue = GetControlValue(theControl); + newValue = wasValue - (mapRoomsHigh / 2); + SetControlValue(theControl, newValue); + if (GetControlValue(theControl) != wasValue) + { + mapTopRoom = GetControlValue(theControl); + RedrawMapContents(); + } + break; + + case kControlPageDownPart: + wasValue = GetControlValue(theControl); + newValue = wasValue + (mapRoomsHigh / 2); + SetControlValue(theControl, newValue); + if (GetControlValue(theControl) != wasValue) + { + mapTopRoom = GetControlValue(theControl); + RedrawMapContents(); + } + break; + + case kControlIndicatorPart: + break; + } +} +#endif + +//-------------------------------------------------------------- HandleMapClick + +void HandleMapClick (EventRecord *theEvent) +{ +#ifndef COMPILEDEMO + Rect aRoom; + ControlHandle whichControl; + Point wherePt, globalWhere; + long controlRef; + short whichPart, localH, localV; + short roomH, roomV, itsNumber; + ControlActionUPP scrollHActionUPP, scrollVActionUPP; + + wherePt = theEvent->where; + + scrollHActionUPP = NewControlActionUPP(LiveHScrollAction); + scrollVActionUPP = NewControlActionUPP(LiveVScrollAction); + + if (mapWindow == nil) + return; + + SetPortWindowPort(mapWindow); + globalWhere = wherePt; + GlobalToLocal(&wherePt); + wherePt.h -= 1; + wherePt.v -= 1; + + whichPart = FindControl(wherePt, mapWindow, &whichControl); + if (whichPart == 0) // User clicked in map content area. + { + localH = wherePt.h / kMapRoomWidth; + localV = wherePt.v / kMapRoomHeight; + + if ((localH >= mapRoomsWide) || (localV >= mapRoomsHigh)) + return; + + roomH = localH + mapLeftRoom; + roomV = kMapGroundValue - (localV + mapTopRoom); + + if (RoomExists(roomH, roomV, &itsNumber)) + { + CopyRoomToThisRoom(itsNumber); + DeselectObject(); + ReflectCurrentRoom(false); + + if (thisMac.hasDrag) + { + SetPortWindowPort(mainWindow); + QSetRect(&aRoom, 0, 0, kMapRoomWidth, kMapRoomHeight); + CenterRectOnPoint(&aRoom, globalWhere); +// if (DragRoom(theEvent, &aRoom, itsNumber)) +// { // TEMP disabled. +// } + } + } + else + { + if (doBitchDialogs) + { + if (QueryNewRoom()) + { + if (!CreateNewRoom(roomH, roomV)) + { + YellowAlert(kYellowUnaccounted, 11); + return; + } + else + { + DeselectObject(); + ReflectCurrentRoom(false); + } + } + else + return; + } + else + { + if (!CreateNewRoom(roomH, roomV)) + { + YellowAlert(kYellowUnaccounted, 11); + return; + } + else + { + DeselectObject(); + ReflectCurrentRoom(false); + } + } + } + } + else + { + controlRef = GetControlReference(whichControl); + if (controlRef == kHScrollRef) + { + switch (whichPart) + { + case kControlUpButtonPart: + case kControlDownButtonPart: + case kControlPageUpPart: + case kControlPageDownPart: + if (TrackControl(whichControl, wherePt, scrollHActionUPP)) + { + + } + break; + + case kControlIndicatorPart: + if (TrackControl(whichControl, wherePt, nil)) + { + mapLeftRoom = GetControlValue(whichControl); + RedrawMapContents(); + } + break; + } + } + else if (controlRef == kVScrollRef) + { + switch (whichPart) + { + case kControlUpButtonPart: + case kControlDownButtonPart: + case kControlPageUpPart: + case kControlPageDownPart: + if (TrackControl(whichControl, wherePt, scrollVActionUPP)) + { + + } + break; + + case kControlIndicatorPart: + if (TrackControl(whichControl, wherePt, nil)) + { + mapTopRoom = GetControlValue(whichControl); + RedrawMapContents(); + } + break; + } + } + } + + DisposeControlActionUPP(scrollHActionUPP); + DisposeControlActionUPP(scrollVActionUPP); +#endif +} + +//-------------------------------------------------------------- QueryNewRoom + +#ifndef COMPILEDEMO +Boolean QueryNewRoom (void) +{ + short hitWhat; + +// CenterAlert(kNewRoomAlert); + hitWhat = Alert(kNewRoomAlert, nil); + if (hitWhat == kYesDoNewRoom) + return (true); + else + return (false); +} +#endif + +//-------------------------------------------------------------- CreateNailOffscreen + +#ifndef COMPILEDEMO +void CreateNailOffscreen (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + if (nailSrcMap == nil) + { + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&nailSrcRect, 0, 0, kMapRoomWidth, kMapRoomHeight * (kNumBackgrounds + 1)); + theErr = CreateOffScreenGWorld(&nailSrcMap, &nailSrcRect, kPreferredDepth); + SetGWorld(nailSrcMap, nil); + LoadGraphic(kThumbnailPictID); + + SetGWorld(wasCPort, wasWorld); + } +} +#endif + +//-------------------------------------------------------------- KillNailOffscreen + +#ifndef COMPILEDEMO +void KillNailOffscreen (void) +{ + if (nailSrcMap != nil) + { +// KillOffScreenPixMap(nailSrcMap); + DisposeGWorld(nailSrcMap); + nailSrcMap = nil; + } +} +#endif + +//-------------------------------------------------------------- MoveRoom + +void MoveRoom (Point wherePt) +{ + short localH, localV; + short roomH, roomV, itsNumber; + + localH = wherePt.h / kMapRoomWidth; + localV = wherePt.v / kMapRoomHeight; + + if ((localH >= mapRoomsWide) || (localV >= mapRoomsHigh)) + return; + + roomH = localH + mapLeftRoom; + roomV = kMapGroundValue - (localV + mapTopRoom); + + if (RoomExists(roomH, roomV, &itsNumber)) + { + + } + else + { + thisRoom->floor = roomV; + thisRoom->suite = roomH; + fileDirty = true; + UpdateMenus(false); + RedrawMapContents(); + } +} + diff --git a/GpApp/Map.h b/GpApp/Map.h new file mode 100644 index 0000000..a9ed724 --- /dev/null +++ b/GpApp/Map.h @@ -0,0 +1,12 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Map.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +extern GWorldPtr nailSrcMap; +extern WindowPtr mapWindow; diff --git a/GpApp/Marquee.cpp b/GpApp/Marquee.cpp new file mode 100644 index 0000000..7e9d70d --- /dev/null +++ b/GpApp/Marquee.cpp @@ -0,0 +1,511 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Marquee.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Marquee.h" +#include "Objects.h" +#include "ObjectEdit.h" +#include "RectUtils.h" + + +#define kMarqueePatListID 128 +#define kHandleSideLong 9 + + +void DrawGliderMarquee (void); +void DrawMarquee (void); + + +marquee theMarquee; +Rect marqueeGliderRect; +Boolean gliderMarqueeUp; + + +extern Cursor handCursor, vertCursor, horiCursor, diagCursor; +extern Rect leftStartGliderSrc; + + +//============================================================== Functions +//-------------------------------------------------------------- DoMarquee + +void DoMarquee (void) +{ + if ((!theMarquee.active) || (theMarquee.paused)) + return; + + SetPortWindowPort(mainWindow); + PenMode(patXor); + PenPat(&theMarquee.pats[theMarquee.index]); + DrawMarquee(); + theMarquee.index++; + if (theMarquee.index >= kNumMarqueePats) + theMarquee.index = 0; + PenPat(&theMarquee.pats[theMarquee.index]); + DrawMarquee(); + PenNormal(); +} + +//-------------------------------------------------------------- StartMarquee + +void StartMarquee (Rect *theRect) +{ + if (theMarquee.active) + StopMarquee(); + + if (objActive == kNoObjectSelected) + return; + + SetPortWindowPort(mainWindow); + theMarquee.bounds = *theRect; + theMarquee.active = true; + theMarquee.paused = false; + theMarquee.handled = false; + PenMode(patXor); + PenPat(&theMarquee.pats[theMarquee.index]); + DrawMarquee(); + PenNormal(); + SetCoordinateHVD(theMarquee.bounds.left, theMarquee.bounds.top, -1); +} + +//-------------------------------------------------------------- StartMarqueeHandled + +void StartMarqueeHandled (Rect *theRect, short direction, short dist) +{ + if (theMarquee.active) + StopMarquee(); + + if (objActive == kNoObjectSelected) + return; + + SetPortWindowPort(mainWindow); + theMarquee.bounds = *theRect; + theMarquee.active = true; + theMarquee.paused = false; + theMarquee.handled = true; + QSetRect(&theMarquee.handle, 0, 0, kHandleSideLong, kHandleSideLong); + QOffsetRect(&theMarquee.handle, kHandleSideLong / -2, kHandleSideLong / -2); + switch (direction) + { + case kAbove: + QOffsetRect(&theMarquee.handle, theMarquee.bounds.left, + theMarquee.bounds.top); + QOffsetRect(&theMarquee.handle, HalfRectWide(&theMarquee.bounds), -dist); + break; + + case kToRight: + QOffsetRect(&theMarquee.handle, theMarquee.bounds.right, + theMarquee.bounds.top); + QOffsetRect(&theMarquee.handle, dist, HalfRectTall(&theMarquee.bounds)); + break; + + case kBelow: + QOffsetRect(&theMarquee.handle, theMarquee.bounds.left, + theMarquee.bounds.bottom); + QOffsetRect(&theMarquee.handle, HalfRectWide(&theMarquee.bounds), dist); + break; + + case kToLeft: + QOffsetRect(&theMarquee.handle, theMarquee.bounds.left, + theMarquee.bounds.top); + QOffsetRect(&theMarquee.handle, -dist, HalfRectTall(&theMarquee.bounds)); + break; + + case kBottomCorner: + QOffsetRect(&theMarquee.handle, theMarquee.bounds.right, + theMarquee.bounds.bottom); + break; + + case kTopCorner: + QOffsetRect(&theMarquee.handle, theMarquee.bounds.right, + theMarquee.bounds.top); + break; + } + theMarquee.direction = direction; + theMarquee.dist = dist; + + PenMode(patXor); + PenPat(&theMarquee.pats[theMarquee.index]); + DrawMarquee(); + PenNormal(); + SetCoordinateHVD(theMarquee.bounds.left, theMarquee.bounds.top, dist); +} + +//-------------------------------------------------------------- StopMarquee + +void StopMarquee (void) +{ + if (gliderMarqueeUp) + { + DrawGliderMarquee(); + gliderMarqueeUp = false; + } + + if (!theMarquee.active) + return; + + SetPortWindowPort(mainWindow); + PenMode(patXor); + PenPat(&theMarquee.pats[theMarquee.index]); + DrawMarquee(); + PenNormal(); + theMarquee.active = false; + SetCoordinateHVD(-1, -1, -1); +} + +//-------------------------------------------------------------- PauseMarquee + +void PauseMarquee (void) +{ + if (!theMarquee.active) + return; + + theMarquee.paused = true; + StopMarquee(); +} + +//-------------------------------------------------------------- ResumeMarquee + +void ResumeMarquee (void) +{ + if (!theMarquee.paused) + return; + + if (theMarquee.handled) + { + StartMarqueeHandled(&theMarquee.bounds, theMarquee.direction, theMarquee.dist); + HandleBlowerGlider(); + } + else + StartMarquee(&theMarquee.bounds); +} + +//-------------------------------------------------------------- DragOutMarqueeRect + +void DragOutMarqueeRect (Point start, Rect *theRect) +{ + Point wasPt, newPt; + + SetPortWindowPort(mainWindow); + InitCursor(); + QSetRect(theRect, start.h, start.v, start.h, start.v); + PenMode(patXor); + PenPat(&theMarquee.pats[theMarquee.index]); + FrameRect(theRect); + wasPt = start; + + while (WaitMouseUp()) + { + GetMouse(&newPt); + if (DeltaPoint(wasPt, newPt)) + { + FrameRect(theRect); + QSetRect(theRect, start.h, start.v, newPt.h, newPt.v); + NormalizeRect(theRect); + FrameRect(theRect); + wasPt = newPt; + } + } + FrameRect(theRect); + PenNormal(); +} + +//-------------------------------------------------------------- DragMarqueeRect + +void DragMarqueeRect (Point start, Rect *theRect, Boolean lockH, Boolean lockV) +{ + Point wasPt, newPt; + short deltaH, deltaV; + + SetCursor(&handCursor); + StopMarquee(); + PenMode(patXor); + PenPat(&theMarquee.pats[theMarquee.index]); + theMarquee.bounds = *theRect; + FrameRect(&theMarquee.bounds); + + wasPt = start; + while (WaitMouseUp()) + { + GetMouse(&newPt); + if (DeltaPoint(wasPt, newPt)) + { + if (lockV) + deltaH = 0; + else + deltaH = newPt.h - wasPt.h; + if (lockH) + deltaV = 0; + else + deltaV = newPt.v - wasPt.v; + FrameRect(&theMarquee.bounds); + QOffsetRect(&theMarquee.bounds, deltaH, deltaV); + FrameRect(&theMarquee.bounds); + wasPt = newPt; + SetCoordinateHVD(theMarquee.bounds.left, theMarquee.bounds.top, -2); + } + } + FrameRect(&theMarquee.bounds); + *theRect = theMarquee.bounds; + PenNormal(); + InitCursor(); +} + +//-------------------------------------------------------------- DragMarqueeHandle + +void DragMarqueeHandle (Point start, short *dragged) +{ + Point wasPt, newPt; + short deltaH, deltaV; + + if ((theMarquee.direction == kAbove) || (theMarquee.direction == kBelow)) + SetCursor(&vertCursor); + else + SetCursor(&horiCursor); + StopMarquee(); + PenMode(patXor); + PenPat(&theMarquee.pats[theMarquee.index]); + FrameRect(&theMarquee.bounds); + PaintRect(&theMarquee.handle); + + wasPt = start; + while (WaitMouseUp()) + { + GetMouse(&newPt); + if (DeltaPoint(wasPt, newPt)) + { + switch (theMarquee.direction) + { + case kAbove: + deltaH = 0; + deltaV = newPt.v - wasPt.v; + *dragged -= deltaV; + if (*dragged <= 0) + { + deltaV += *dragged; + *dragged = 0; + } + DeltaCoordinateD(*dragged); + break; + + case kToRight: + deltaH = newPt.h - wasPt.h; + deltaV = 0; + *dragged += deltaH; + if (*dragged <= 0) + { + deltaH -= *dragged; + *dragged = 0; + } + DeltaCoordinateD(*dragged); + break; + + case kBelow: + deltaH = 0; + deltaV = newPt.v - wasPt.v; + *dragged += deltaV; + if (*dragged <= 0) + { + deltaV -= *dragged; + *dragged = 0; + } + DeltaCoordinateD(*dragged); + break; + + case kToLeft: + deltaH = newPt.h - wasPt.h; + deltaV = 0; + *dragged -= deltaH; + if (*dragged <= 0) + { + deltaH += *dragged; + *dragged = 0; + } + DeltaCoordinateD(*dragged); + break; + } + + PaintRect(&theMarquee.handle); + QOffsetRect(&theMarquee.handle, deltaH, deltaV); + PaintRect(&theMarquee.handle); + wasPt = newPt; + } + } + FrameRect(&theMarquee.bounds); + PaintRect(&theMarquee.handle); + PenNormal(); + InitCursor(); +} + +//-------------------------------------------------------------- DragMarqueeCorner + +void DragMarqueeCorner (Point start, short *hDragged, short *vDragged, Boolean isTop) +{ + Point wasPt, newPt; + short deltaH, deltaV; + + SetCursor(&diagCursor); + StopMarquee(); + PenMode(patXor); + PenPat(&theMarquee.pats[theMarquee.index]); + FrameRect(&theMarquee.bounds); + PaintRect(&theMarquee.handle); + + wasPt = start; + while (WaitMouseUp()) + { + GetMouse(&newPt); + if (DeltaPoint(wasPt, newPt)) + { + deltaH = newPt.h - wasPt.h; + if (isTop) + deltaV = wasPt.v - newPt.v; + else + deltaV = newPt.v - wasPt.v; + *hDragged += deltaH; + if (*hDragged <= 0) + { + deltaH -= *hDragged; + *hDragged = 0; + } + *vDragged += deltaV; + if (*vDragged <= 0) + { + deltaV -= *vDragged; + *vDragged = 0; + } + FrameRect(&theMarquee.bounds); + PaintRect(&theMarquee.handle); + if (isTop) + { + QOffsetRect(&theMarquee.handle, deltaH, -deltaV); + theMarquee.bounds.right += deltaH; + theMarquee.bounds.top -= deltaV; + } + else + { + QOffsetRect(&theMarquee.handle, deltaH, deltaV); + theMarquee.bounds.right += deltaH; + theMarquee.bounds.bottom += deltaV; + } + FrameRect(&theMarquee.bounds); + PaintRect(&theMarquee.handle); + wasPt = newPt; + } + } + FrameRect(&theMarquee.bounds); + PaintRect(&theMarquee.handle); + PenNormal(); + InitCursor(); +} + +//-------------------------------------------------------------- MarqueeHasHandles + +Boolean MarqueeHasHandles (short *direction, short *dist) +{ + if (theMarquee.handled) + { + *direction = theMarquee.direction; + *dist = theMarquee.dist; + return (true); + } + else + { + *direction = 0; + *dist = 0; + return (false); + } +} + +//-------------------------------------------------------------- PtInMarqueeHandle + +Boolean PtInMarqueeHandle (Point where) +{ + return (PtInRect(where, &theMarquee.handle)); +} + +//-------------------------------------------------------------- DrawGliderMarquee + +void DrawGliderMarquee (void) +{ + CopyBits((BitMap *)*GetGWorldPixMap(blowerMaskMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &leftStartGliderSrc, + &marqueeGliderRect, + srcXor, nil); +} + +//-------------------------------------------------------------- SetMarqueeGliderCenter + +void SetMarqueeGliderRect (short h, short v) +{ + marqueeGliderRect = leftStartGliderSrc; + ZeroRectCorner(&marqueeGliderRect); + QOffsetRect(&marqueeGliderRect, h - kHalfGliderWide, v - kGliderHigh); + + DrawGliderMarquee(); + gliderMarqueeUp = true; +} + +//-------------------------------------------------------------- DrawMarquee + +void DrawMarquee (void) +{ + FrameRect(&theMarquee.bounds); + if (theMarquee.handled) + { + PaintRect(&theMarquee.handle); + switch (theMarquee.direction) + { + case kAbove: + MoveTo(theMarquee.handle.left + (kHandleSideLong / 2), + theMarquee.handle.bottom); + LineTo(theMarquee.handle.left + (kHandleSideLong / 2), + theMarquee.bounds.top - 1); + break; + + case kToRight: + MoveTo(theMarquee.handle.left, + theMarquee.handle.top + (kHandleSideLong / 2)); + LineTo(theMarquee.bounds.right, + theMarquee.handle.top + (kHandleSideLong / 2)); + break; + + case kBelow: + MoveTo(theMarquee.handle.left + (kHandleSideLong / 2), + theMarquee.handle.top - 1); + LineTo(theMarquee.handle.left + (kHandleSideLong / 2), + theMarquee.bounds.bottom); + break; + + case kToLeft: + MoveTo(theMarquee.handle.right, + theMarquee.handle.top + (kHandleSideLong / 2)); + LineTo(theMarquee.bounds.left, + theMarquee.handle.top + (kHandleSideLong / 2)); + break; + } + } + + if (gliderMarqueeUp) + DrawGliderMarquee(); +} + +//-------------------------------------------------------------- InitMarquee + +void InitMarquee (void) +{ + short i; + + for (i = 0; i < kNumMarqueePats; i++) + GetIndPattern(&theMarquee.pats[i], kMarqueePatListID, i + 1); + theMarquee.index = 0; + theMarquee.active = false; + theMarquee.paused = false; + theMarquee.handled = false; + gliderMarqueeUp = false; +} + diff --git a/GpApp/Marquee.h b/GpApp/Marquee.h new file mode 100644 index 0000000..09d324c --- /dev/null +++ b/GpApp/Marquee.h @@ -0,0 +1,24 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Marquee.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#pragma once + + +#include "PLQuickdraw.h" + + +typedef struct +{ + Pattern pats[kNumMarqueePats]; + Rect bounds, handle; + short index, direction, dist; + Boolean active, paused, handled; +} marquee; + + +extern marquee theMarquee; + diff --git a/GpApp/Menu.cpp b/GpApp/Menu.cpp new file mode 100644 index 0000000..da07779 --- /dev/null +++ b/GpApp/Menu.cpp @@ -0,0 +1,814 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Menu.c +//---------------------------------------------------------------------------- +//============================================================================ + + +//#include +#include "PLNumberFormatting.h" +#include "PLPasStr.h" +#include "PLToolUtils.h" +#include "DialogUtils.h" +#include "Externs.h" +#include "House.h" +#include "ObjectEdit.h" + + +#define kSheWantsNewGame 1 +#define kSheWantsResumeGame 2 + + +void UpdateMenusEditMode (void); +void UpdateMenusNonEditMode (void); +void UpdateMenusHouseOpen (void); +void UpdateMenusHouseClosed (void); +void UpdateResumeDialog (DialogPtr); +Boolean ResumeFilter (DialogPtr, EventRecord *, short *); +short QueryResumeGame (void); +void HeyYourPissingAHighScore (void); + + +MenuHandle appleMenu, gameMenu, optionsMenu, houseMenu; +Boolean menusUp, resumedSavedGame; + + +extern long incrementModeTime; +extern short demoHouseIndex, wasHouseVersion; +extern short splashOriginH, splashOriginV, numberRooms; +extern Boolean quitting, noRoomAtAll, twoPlayerGame; +extern Boolean isMapOpen, isToolsOpen, isPlayMusicIdle; +extern Boolean isCoordOpen, failedMusic, splashDrawn; +extern Boolean houseOpen; + + +//============================================================== Functions +//-------------------------------------------------------------- UpdateMenusEditMode +// Sets the menus to reflect that user is in edit mode. + +void UpdateMenusEditMode (void) +{ + DisableMenuItem(gameMenu, iNewGame); + DisableMenuItem(gameMenu, iTwoPlayer); + DisableMenuItem(gameMenu, iOpenSavedGame); + DisableMenuItem(optionsMenu, iHighScores); + DisableMenuItem(optionsMenu, iHelp); + CheckMenuItem(optionsMenu, iEditor, true); +} + +//-------------------------------------------------------------- UpdateMenusNonEditMode +// Sets the menus to reflect that user is NOT in edit mode. + +void UpdateMenusNonEditMode (void) +{ + if ((noRoomAtAll) || (!houseOpen) || (numberRooms <= 0)) + { + DisableMenuItem(gameMenu, iNewGame); + DisableMenuItem(gameMenu, iTwoPlayer); + DisableMenuItem(gameMenu, iOpenSavedGame); + if (houseOpen) + { + EnableMenuItem(gameMenu, iLoadHouse); + EnableMenuItem(optionsMenu, iHighScores); + } + else + { + DisableMenuItem(gameMenu, iLoadHouse); + DisableMenuItem(optionsMenu, iHighScores); + } + } + else + { + EnableMenuItem(gameMenu, iNewGame); + EnableMenuItem(gameMenu, iTwoPlayer); + EnableMenuItem(gameMenu, iOpenSavedGame); + EnableMenuItem(gameMenu, iLoadHouse); + EnableMenuItem(optionsMenu, iHighScores); + } + if (demoHouseIndex == -1) + DisableMenuItem(optionsMenu, iHelp); + else + EnableMenuItem(optionsMenu, iHelp); + CheckMenuItem(optionsMenu, iEditor, false); +} + +//-------------------------------------------------------------- UpdateMenusHouseOpen +// Sets the menus to reflect that a house is currently open. + +void UpdateMenusHouseOpen (void) +{ + EnableMenuItem(gameMenu, iLoadHouse); + if ((fileDirty) && (houseUnlocked)) + EnableMenuItem(houseMenu, iSave); + else + DisableMenuItem(houseMenu, iSave); + if (houseUnlocked) + { + // EnableMenuItem(houseMenu, iSaveAs); + EnableMenuItem(houseMenu, iHouse); + } + else + { + // DisableMenuItem(houseMenu, iSaveAs); + DisableMenuItem(houseMenu, iHouse); + } + if ((noRoomAtAll) || (!houseUnlocked)) + DisableMenuItem(houseMenu, iRoom); + else + EnableMenuItem(houseMenu, iRoom); + if ((objActive == kNoObjectSelected) || (!houseUnlocked)) + { + DisableMenuItem(houseMenu, iObject); + DisableMenuItem(houseMenu, iBringForward); + DisableMenuItem(houseMenu, iSendBack); + } + else + { + EnableMenuItem(houseMenu, iObject); + if ((objActive == kInitialGliderSelected) || + (objActive == kLeftGliderSelected) || + (objActive == kRightGliderSelected)) + { + DisableMenuItem(houseMenu, iBringForward); + DisableMenuItem(houseMenu, iSendBack); + } + else + { + EnableMenuItem(houseMenu, iBringForward); + EnableMenuItem(houseMenu, iSendBack); + } + } +} + +//-------------------------------------------------------------- UpdateMenusHouseClosed +// Sets the menus to reflect that a house is NOT currently open. + +void UpdateMenusHouseClosed (void) +{ + DisableMenuItem(gameMenu, iLoadHouse); + DisableMenuItem(houseMenu, iSave); + // DisableMenuItem(houseMenu, iSaveAs); + DisableMenuItem(houseMenu, iHouse); + DisableMenuItem(houseMenu, iRoom); + DisableMenuItem(houseMenu, iObject); + DisableMenuItem(houseMenu, iCut); + DisableMenuItem(houseMenu, iCopy); + DisableMenuItem(houseMenu, iPaste); + DisableMenuItem(houseMenu, iClear); + DisableMenuItem(houseMenu, iDuplicate); +} + +//-------------------------------------------------------------- UpdateClipboardMenus +// Set the Cut/Copy/Paste menus to reflect if we have data in theÉ +// Mac's "clipboard" or not. + +void UpdateClipboardMenus (void) +{ + Str255 title; + + if (!houseOpen) + return; + + if (houseUnlocked) + { + if (objActive > kNoObjectSelected) + { + GetLocalizedString(36, title); + SetMenuItemText(houseMenu, iCut, title); + GetLocalizedString(37, title); + SetMenuItemText(houseMenu, iCopy, title); + GetLocalizedString(38, title); + SetMenuItemText(houseMenu, iClear, title); + EnableMenuItem(houseMenu, iDuplicate); + } + else + { + GetLocalizedString(39, title); + SetMenuItemText(houseMenu, iCut, title); + GetLocalizedString(40, title); + SetMenuItemText(houseMenu, iCopy, title); + GetLocalizedString(41, title); + SetMenuItemText(houseMenu, iClear, title); + DisableMenuItem(houseMenu, iDuplicate); + } + + EnableMenuItem(houseMenu, iCut); + EnableMenuItem(houseMenu, iCopy); +// if (hasScrap) +// { +// EnableMenuItem(houseMenu, iPaste); +// if (scrapIsARoom) +// { +// GetLocalizedString(42, title); +// SetMenuItemText(houseMenu, iPaste, title); +// } +// else +// { +// GetLocalizedString(43, title); +// SetMenuItemText(houseMenu, iPaste, title); +// } +// } +// else + { + DisableMenuItem(houseMenu, iPaste); + GetLocalizedString(44, title); + SetMenuItemText(houseMenu, iPaste, title); + } + EnableMenuItem(houseMenu, iClear); + EnableMenuItem(houseMenu, iGoToRoom); + EnableMenuItem(houseMenu, iMapWindow); + EnableMenuItem(houseMenu, iObjectWindow); + EnableMenuItem(houseMenu, iCoordinateWindow); + } + else + { + DisableMenuItem(houseMenu, iCut); + DisableMenuItem(houseMenu, iCopy); + DisableMenuItem(houseMenu, iPaste); + DisableMenuItem(houseMenu, iClear); + DisableMenuItem(houseMenu, iDuplicate); + DisableMenuItem(houseMenu, iGoToRoom); + DisableMenuItem(houseMenu, iMapWindow); + DisableMenuItem(houseMenu, iObjectWindow); + DisableMenuItem(houseMenu, iCoordinateWindow); + } +} + +//-------------------------------------------------------------- UpdateMenus +// Called whenever a significant change to the environment has takenÉ +// place and some of the menu states may have changes (for example,É +// a menui was grayed out before becuase it wasn't an option - nowÉ +// perhaps the situation has changed and we want the menu to be "usable"). + +void UpdateMenus (Boolean newMode) +{ + if (!menusUp) + return; + + if (newMode) + { + if (theMode == kEditMode) + InsertMenu(houseMenu, 0); + else + DeleteMenu(kHouseMenuID); + } + + if (theMode == kEditMode) + { + UpdateMenusEditMode(); + if (houseOpen) + { + UpdateMenusHouseOpen(); + UpdateClipboardMenus(); + } + else + UpdateMenusHouseClosed(); + UpdateLinkControl(); + } + else + UpdateMenusNonEditMode(); + + DrawMenuBar(); +} + +//-------------------------------------------------------------- DoAppleMenu +// Handle the Apple menu (About box and desk accessories). + +void DoAppleMenu (short theItem) +{ +// Str255 daName; +// GrafPtr wasPort; +// short daNumber; + + switch (theItem) + { + case iAbout: + DoAbout(); + break; + + default: +// GetMenuItemText(appleMenu, theItem, daName); +// GetPort(&wasPort); +// daNumber = OpenDeskAccesory(daName); +// SetPort((GrafPtr)wasPort); + break; + } +} + +//-------------------------------------------------------------- DoGameMenu +// Handle the user selecting an item from the Game menu. + +void DoGameMenu (short theItem) +{ + switch (theItem) + { + case iNewGame: + twoPlayerGame = false; + resumedSavedGame = false; + NewGame(kNewGameMode); + break; + + case iTwoPlayer: + twoPlayerGame = true; + resumedSavedGame = false; + NewGame(kNewGameMode); + break; + + case iOpenSavedGame: + resumedSavedGame = true; + HeyYourPissingAHighScore(); + if (OpenSavedGame()) + { + twoPlayerGame = false; + NewGame(kResumeGameMode); + } + break; + + case iLoadHouse: +#ifdef COMPILEDEMO + DoNotInDemo(); +#else + if (splashDrawn) + { + DoLoadHouse(); + OpenCloseEditWindows(); + UpdateMenus(false); + incrementModeTime = TickCount() + kIdleSplashTicks; + if ((theMode == kSplashMode) || (theMode == kPlayMode)) + { + Rect updateRect; + + SetRect(&updateRect, splashOriginH + 474, splashOriginV + 304, splashOriginH + 474 + 166, splashOriginV + 304 + 12); + InvalWindowRect(mainWindow, &updateRect); + } + } +#endif + break; + + case iQuit: +#ifndef COMPILEDEMO + quitting = true; + if (!QuerySaveChanges()) + quitting = false; +#else + quitting = true; +#endif + break; + + default: + break; + } +} + +//-------------------------------------------------------------- DoOptionsMenu +// Handle the user selecting an item from the Options menu. + +void DoOptionsMenu (short theItem) +{ +#ifndef COMPILEDEMO + OSErr theErr; +#endif + + switch (theItem) + { + case iEditor: +#ifdef COMPILEDEMO + DoNotInDemo(); +#else + if (theMode == kEditMode) // switching to splash mode + { + if (fileDirty) + SortHouseObjects(); + if (!QuerySaveChanges()) + break; + theMode = kSplashMode; + CloseMapWindow(); + CloseToolsWindow(); + CloseCoordWindow(); + CloseLinkWindow(); + DeselectObject(); + StopMarquee(); + if (isPlayMusicIdle) + { + theErr = StartMusic(); + if (theErr != noErr) + { + YellowAlert(kYellowNoMusic, theErr); + failedMusic = true; + } + } + CloseMainWindow(); + OpenMainWindow(); + incrementModeTime = TickCount() + kIdleSplashTicks; + } + else if (theMode == kSplashMode) // switching to edit mode + { + theMode = kEditMode; + StopTheMusic(); + CloseMainWindow(); + OpenMainWindow(); + OpenCloseEditWindows(); + } + InitCursor(); + UpdateMenus(true); +#endif + break; + + case iHighScores: + DoHighScores(); + incrementModeTime = TickCount() + kIdleSplashTicks; + break; + + case iPrefs: + DoSettingsMain(); + incrementModeTime = TickCount() + kIdleSplashTicks; + break; + + case iHelp: + DoDemoGame(); + break; + } +} + +//-------------------------------------------------------------- DoHouseMenu +// Handle the user selecting an item from the House menu (only in Edit mode). + +void DoHouseMenu (short theItem) +{ +#ifndef COMPILEDEMO + short direction, dist; + Boolean whoCares; + + switch (theItem) + { + case iNewHouse: + if (CreateNewHouse()) + { + whoCares = InitializeEmptyHouse(); + OpenCloseEditWindows(); + } + break; + + case iSave: + DeselectObject(); + if (fileDirty) + SortHouseObjects(); + if ((fileDirty) && (houseUnlocked)) + { +// SaveGame(false); + if (wasHouseVersion < kHouseVersion) + ConvertHouseVer1To2(); + wasHouseVersion = kHouseVersion; + whoCares = WriteHouse(true); + ForceThisRoom(thisRoomNumber); + ReadyBackground(thisRoom->background, thisRoom->tiles); + GetThisRoomsObjRects(); + DrawThisRoomsObjects(); + } + break; + +// case iSaveAs: +// whoCares = SaveHouseAs(); +// break; + + case iHouse: + if (houseUnlocked) + DoHouseInfo(); + break; + + case iRoom: + if (houseUnlocked) + DoRoomInfo(); + break; + + case iObject: + if (houseUnlocked) + { + DoObjectInfo(); + if (ObjectHasHandle(&direction, &dist)) + { + StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); + HandleBlowerGlider(); + } + else + StartMarquee(&roomObjectRects[objActive]); + } + break; + + case iCut: + if (houseUnlocked) + { + if (objActive > kNoObjectSelected) + { +// PutObjectScrap(); + DeleteObject(); + } + else + { +// PutRoomScrap(); + DeleteRoom(false); + } + UpdateClipboardMenus(); + } + break; + + case iCopy: + if (houseUnlocked) + { +// if (objActive > kNoObjectSelected) +// PutObjectScrap(); +// else +// PutRoomScrap(); + UpdateClipboardMenus(); + } + break; + + case iPaste: + if (houseUnlocked) + { +/* if (scrapIsARoom) + GetRoomScrap(); + else + GetObjectScrap(); + UpdateClipboardMenus(); +*/ + } + break; + + case iClear: + if (houseUnlocked) + { + if (objActive > kNoObjectSelected) + DeleteObject(); + else + DeleteRoom(false); + UpdateClipboardMenus(); + } + break; + + case iDuplicate: + if (houseUnlocked) + DuplicateObject(); + break; + + case iBringForward: + if (houseUnlocked) + BringSendFrontBack(true); + break; + + case iSendBack: + if (houseUnlocked) + BringSendFrontBack(false); + break; + + case iGoToRoom: + if (houseUnlocked) + DoGoToDialog(); + break; + + case iMapWindow: + if (houseUnlocked) + ToggleMapWindow(); + break; + + case iObjectWindow: + if (houseUnlocked) + ToggleToolsWindow(); + break; + + case iCoordinateWindow: + if (houseUnlocked) + ToggleCoordinateWindow(); + break; + } +#endif +} + +//-------------------------------------------------------------- DoMenuChoice +// Users has selected a menu item - determin which menu was selectedÉ +// and call the appropriate function above. + +void DoMenuChoice (long menuChoice) +{ + short theMenu, theItem; + + if (menuChoice == 0) + return; + + theMenu = HiWord(menuChoice); + theItem = LoWord(menuChoice); + + switch (theMenu) + { + case kAppleMenuID: + DoAppleMenu(theItem); + break; + + case kGameMenuID: + DoGameMenu(theItem); + break; + + case kOptionsMenuID: + DoOptionsMenu(theItem); + break; + + case kHouseMenuID: + DoHouseMenu(theItem); + break; + } + + HiliteMenu(0); +} + +//-------------------------------------------------------------- UpdateMapCheckmark +// Checks or unchecks the Map Window item (to indicate if open or not). + +void UpdateMapCheckmark (Boolean checkIt) +{ + if (!menusUp) + return; + + CheckMenuItem(houseMenu, iMapWindow, checkIt); +} + +//-------------------------------------------------------------- UpdateToolsCheckmark +// Checks or unchecks the Tools Window item (to indicate if open or not). + +void UpdateToolsCheckmark (Boolean checkIt) +{ + if (!menusUp) + return; + + CheckMenuItem(houseMenu, iObjectWindow, checkIt); +} + +//-------------------------------------------------------------- UpdateCoordinateCheckmark +// Checks or unchecks the Coordinates Window item (to indicate if open or not). + +void UpdateCoordinateCheckmark (Boolean checkIt) +{ + if (!menusUp) + return; + + CheckMenuItem(houseMenu, iCoordinateWindow, checkIt); +} + +//-------------------------------------------------------------- UpdateResumeDialog +// Update function for Resume dialog (below). + +void UpdateResumeDialog (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); +} + +//-------------------------------------------------------------- ResumeFilter +// Dialog filter for the Resume dialog (below). + +Boolean ResumeFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + default: + return(false); + } + break; + + case updateEvt: + if ((WindowPtr)event->message == GetDialogWindow(dial)) + { + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateResumeDialog(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + } + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- QueryResumeGame +// Dialog that asks user whether they want to resume a saved game orÉ +// begin a new one. It displays a little info on the state of theirÉ +// saved game (number of glider left, points, etc.). + +short QueryResumeGame (void) +{ + #define kResumeGameDial 1025 + DialogPtr theDial; + houseType *thisHousePtr; + Str255 scoreStr, glidStr; + long hadPoints; + short hitWhat, hadGliders; + char wasState; + Boolean leaving; + ModalFilterUPP resumeFilterUPP; + + resumeFilterUPP = NewModalFilterUPP(ResumeFilter); + + wasState = HGetState((Handle)thisHouse); // get score & num. gliders + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + hadPoints = thisHousePtr->savedGame.score; + hadGliders = thisHousePtr->savedGame.numGliders; + HSetState((Handle)thisHouse, wasState); + NumToString(hadPoints, scoreStr); // param text strings + NumToString((long)hadGliders, glidStr); + if (hadGliders == 1) + ParamText(glidStr, PSTR(""), scoreStr, PSTR("")); + else + ParamText(glidStr, PSTR("s"), scoreStr, PSTR("")); + +// CenterDialog(kResumeGameDial); + theDial = GetNewDialog(kResumeGameDial, nil, kPutInFront); + if (theDial == nil) + RedAlert(kErrDialogDidntLoad); + SetPort((GrafPtr)theDial); + + ShowWindow(GetDialogWindow(theDial)); + DrawDefaultButton(theDial); + leaving = false; + + while (!leaving) + { + ModalDialog(resumeFilterUPP, &hitWhat); + if ((hitWhat == kSheWantsNewGame) || (hitWhat == kSheWantsResumeGame)) + { + leaving = true; + } + } + DisposeDialog(theDial); + DisposeModalFilterUPP(resumeFilterUPP); + + return (hitWhat); +} + +//-------------------------------------------------------------- DoNotInDemo +// Only compiled for "demo version" of Glider PRO. It brings up aÉ +// dialog that says, essentially, "x" feature is not implemented inÉ +// the demo version. + +#ifdef COMPILEDEMO +void DoNotInDemo (void) +{ + #define kNotInDemoAlert 1037 + short whoCares; + +// CenterAlert(kNotInDemoAlert); + whoCares = Alert(kNotInDemoAlert, nil); +} +#endif + +//-------------------------------------------------------------- HeyYourPissingAHighScore + +void HeyYourPissingAHighScore (void) +{ + #define kNoHighScoreAlert 1046 + short whoCares; + +// CenterAlert(kNoHighScoreAlert); + whoCares = Alert(kNoHighScoreAlert, nil); +} + +//-------------------------------------------------------------- OpenCloseEditWindows +// Function goes through and either closes or opens all the variousÉ +// editing windows (in response to switching in or out of editor). + +void OpenCloseEditWindows (void) +{ + if (theMode == kEditMode) + { + if (houseUnlocked) + { + if (isMapOpen) + OpenMapWindow(); + if (isToolsOpen) + OpenToolsWindow(); + if (isCoordOpen) + OpenCoordWindow(); + } + else + { + CloseMapWindow(); + CloseToolsWindow(); + CloseCoordWindow(); + } + } +} + diff --git a/GpApp/Modes.cpp b/GpApp/Modes.cpp new file mode 100644 index 0000000..03f7a3b --- /dev/null +++ b/GpApp/Modes.cpp @@ -0,0 +1,640 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Modes.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "RectUtils.h" + + +short saidFollow; + +extern Rect gliderSrc[]; +extern Rect transRect; +extern short fadeInSequence[], linkedToWhat; +extern short rightClip, leftClip, transRoom; +extern Boolean hasMirror, shadowVisible, firstPlayer, twoPlayerGame; +extern Boolean onePlayerLeft, playerDead; + +//============================================================== Functions +//-------------------------------------------------------------- StartGliderFadingIn + +void StartGliderFadingIn (gliderPtr thisGlider) +{ + if (foilTotal <= 0) + showFoil = false; + + thisGlider->mode = kGliderFadingIn; + thisGlider->whole = thisGlider->dest; + thisGlider->frame = 0; + thisGlider->dontDraw = false; + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = + gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; + thisGlider->mask = + gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; + } +} + +//-------------------------------------------------------------- StartGliderTransportingIn + +void StartGliderTransportingIn (gliderPtr thisGlider) +{ + if (foilTotal <= 0) + showFoil = false; + + thisGlider->mode = kGliderTransportingIn; + thisGlider->whole = thisGlider->dest; + thisGlider->frame = 0; + thisGlider->dontDraw = false; + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = + gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; + thisGlider->mask = + gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; + } +} + +//-------------------------------------------------------------- StartGliderFadingOut + +void StartGliderFadingOut (gliderPtr thisGlider) +{ + Rect tempBounds; + + if (thisGlider->mode == kGliderFadingOut) + return; + + if (thisGlider->mode == kGliderGoingFoil) + DeckGliderInFoil(thisGlider); + else if (thisGlider->mode == kGliderLosingFoil) + RemoveFoilFromGlider(thisGlider); + + if (RectTall(&thisGlider->dest) > kGliderHigh) + { + tempBounds = thisGlider->dest; + QOffsetRect(&tempBounds, playOriginH, playOriginV); + AddRectToWorkRects(&tempBounds); + if (hasMirror) + { + tempBounds = thisGlider->dest; + QOffsetRect(&tempBounds, playOriginH - 20, playOriginV - 16); + AddRectToWorkRects(&tempBounds); + } + thisGlider->dest.right = thisGlider->dest.left + kGliderWide; + thisGlider->dest.top = thisGlider->dest.bottom - kGliderHigh; + } + thisGlider->mode = kGliderFadingOut; + thisGlider->whole = thisGlider->dest; + thisGlider->frame = kLastFadeSequence - 1; + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = + gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; + thisGlider->mask = + gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; + } +} + +//-------------------------------------------------------------- StartGliderGoingUpStairs + +void StartGliderGoingUpStairs (gliderPtr thisGlider) +{ + if (thisGlider->mode == kGliderGoingFoil) + DeckGliderInFoil(thisGlider); + else if (thisGlider->mode == kGliderLosingFoil) + RemoveFoilFromGlider(thisGlider); + + if (thisGlider->mode == kGliderBurning) + thisGlider->frame = kWasBurning; + else + thisGlider->frame = 0; + + thisGlider->mode = kGliderGoingUp; +} + +//-------------------------------------------------------------- StartGliderGoingDownStairs + +void StartGliderGoingDownStairs (gliderPtr thisGlider) +{ + if (thisGlider->mode == kGliderGoingFoil) + DeckGliderInFoil(thisGlider); + else if (thisGlider->mode == kGliderLosingFoil) + RemoveFoilFromGlider(thisGlider); + + if (thisGlider->mode == kGliderBurning) + thisGlider->frame = kWasBurning; + else + thisGlider->frame = 0; + + thisGlider->mode = kGliderGoingDown; + rightClip = GetUpStairsRightEdge(); +} + +//-------------------------------------------------------------- StartGliderMailingIn + +void StartGliderMailingIn (gliderPtr thisGlider, Rect *bounds, hotPtr who) +{ + short topSought, whoLinked; + Byte objLinked; + char wasState; + + PlayPrioritySound(kTransOutSound, kTransOutPriority); + + whoLinked = who->who; + transRoom = masterObjects[whoLinked].roomLink; + objLinked = masterObjects[whoLinked].objectLink; + linkedToWhat = WhatAreWeLinkedTo(transRoom, objLinked); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + GetObjectRect(&(*thisHouse)->rooms[transRoom].objects[objLinked], &transRect); + HSetState((Handle)thisHouse, wasState); + + thisGlider->frame = 0; + thisGlider->clip = *bounds; + topSought = bounds->bottom - RectTall(&thisGlider->dest); + thisGlider->clip.top = topSought; +} + +//-------------------------------------------------------------- StartGliderMailingOut + +void StartGliderMailingOut (gliderPtr thisGlider) +{ + if (thisGlider->mode == kGliderGoingFoil) + DeckGliderInFoil(thisGlider); + else if (thisGlider->mode == kGliderLosingFoil) + RemoveFoilFromGlider(thisGlider); + + if (linkedToWhat == kLinkedToLeftMailbox) + { + thisGlider->facing = kFaceLeft; + thisGlider->mode = kGliderMailOutLeft; + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + else + { + thisGlider->facing = kFaceRight; + thisGlider->mode = kGliderMailOutRight; + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + } + + thisGlider->hVel = 0; + thisGlider->vVel = 0; + thisGlider->hDesiredVel = 0; + thisGlider->vDesiredVel = 0; + thisGlider->tipped = false; + thisGlider->dontDraw = false; +} + +//-------------------------------------------------------------- StartGliderDuctingDown + +void StartGliderDuctingDown (gliderPtr thisGlider, Rect *bounds, hotPtr who) +{ + short leftSought, whoLinked; + Byte objLinked; + char wasState; + + PlayPrioritySound(kTransOutSound, kTransOutPriority); + + if (thisGlider->mode == kGliderGoingFoil) + DeckGliderInFoil(thisGlider); + else if (thisGlider->mode == kGliderLosingFoil) + RemoveFoilFromGlider(thisGlider); + + whoLinked = who->who; + transRoom = masterObjects[whoLinked].roomLink; + objLinked = masterObjects[whoLinked].objectLink; + linkedToWhat = WhatAreWeLinkedTo(transRoom, objLinked); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + GetObjectRect(&(*thisHouse)->rooms[transRoom].objects[objLinked], &transRect); + HSetState((Handle)thisHouse, wasState); + + thisGlider->frame = 0; + thisGlider->clip = *bounds; + leftSought = bounds->left + ((RectWide(bounds) - kGliderWide) / 2); + thisGlider->clip.left = leftSought; + + thisGlider->mode = kGliderDuctingDown; +} + +//-------------------------------------------------------------- StartGliderDuctingUp + +void StartGliderDuctingUp (gliderPtr thisGlider, Rect *bounds, hotPtr who) +{ + short leftSought, whoLinked; + Byte objLinked; + char wasState; + + PlayPrioritySound(kTransOutSound, kTransOutPriority); + + if (thisGlider->mode == kGliderGoingFoil) + DeckGliderInFoil(thisGlider); + else if (thisGlider->mode == kGliderLosingFoil) + RemoveFoilFromGlider(thisGlider); + + whoLinked = who->who; + transRoom = masterObjects[whoLinked].roomLink; + objLinked = masterObjects[whoLinked].objectLink; + linkedToWhat = WhatAreWeLinkedTo(transRoom, objLinked); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + GetObjectRect(&(*thisHouse)->rooms[transRoom].objects[objLinked], &transRect); + HSetState((Handle)thisHouse, wasState); + + thisGlider->frame = 0; + thisGlider->clip = *bounds; + leftSought = bounds->left + ((RectWide(bounds) - kGliderWide) / 2); + thisGlider->clip.left = leftSought; + + thisGlider->mode = kGliderDuctingUp; +} + +//-------------------------------------------------------------- StartGliderDuctingIn + +void StartGliderDuctingIn (gliderPtr thisGlider) +{ + thisGlider->mode = kGliderDuctingIn; + thisGlider->whole = thisGlider->dest; + thisGlider->dontDraw = false; +} + +//-------------------------------------------------------------- StartGliderTransporting + +void StartGliderTransporting (gliderPtr thisGlider, hotPtr who) +{ + short whoLinked; + Byte objLinked; + char wasState; + + PlayPrioritySound(kTransOutSound, kTransOutPriority); + + if (thisGlider->mode == kGliderGoingFoil) + DeckGliderInFoil(thisGlider); + else if (thisGlider->mode == kGliderLosingFoil) + RemoveFoilFromGlider(thisGlider); + + whoLinked = who->who; + transRoom = masterObjects[whoLinked].roomLink; + objLinked = masterObjects[whoLinked].objectLink; + linkedToWhat = WhatAreWeLinkedTo(transRoom, objLinked); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + GetObjectRect(&(*thisHouse)->rooms[transRoom].objects[objLinked], &transRect); + HSetState((Handle)thisHouse, wasState); + + thisGlider->dest.right = thisGlider->dest.left + kGliderWide; + thisGlider->dest.bottom = thisGlider->dest.top + kGliderHigh; + thisGlider->destShadow.right = thisGlider->destShadow.left + kGliderWide; + thisGlider->destShadow.bottom = thisGlider->destShadow.top + kShadowHigh; + thisGlider->mode = kGliderTransporting; + thisGlider->whole = thisGlider->dest; + thisGlider->frame = kLastFadeSequence - 1; + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = + gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; + thisGlider->mask = + gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; + } +} + +//-------------------------------------------------------------- FlagGliderNormal + +void FlagGliderNormal (gliderPtr thisGlider) +{ + thisGlider->dest.right = thisGlider->dest.left + kGliderWide; + thisGlider->dest.bottom = thisGlider->dest.top + kGliderHigh; + thisGlider->destShadow.right = thisGlider->destShadow.left + kGliderWide; + thisGlider->destShadow.bottom = thisGlider->destShadow.top + kShadowHigh; + thisGlider->mode = kGliderNormal; + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + else + { + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + } + thisGlider->hVel = 0; + thisGlider->vVel = 0; + thisGlider->hDesiredVel = 0; + thisGlider->vDesiredVel = 0; + thisGlider->tipped = false; + thisGlider->ignoreLeft = false; + thisGlider->ignoreRight = false; + thisGlider->ignoreGround = false; + thisGlider->dontDraw = false; + thisGlider->frame = 0; + shadowVisible = IsShadowVisible(); +} + +//-------------------------------------------------------------- FlagGliderShredding + +void FlagGliderShredding (gliderPtr thisGlider, Rect *bounds) +{ + PlayPrioritySound(kCaughtFireSound, kCaughtFirePriority); + thisGlider->dest.left = bounds->left + 36; + thisGlider->dest.right = thisGlider->dest.left + kGliderWide; + thisGlider->dest.bottom = thisGlider->dest.top + kGliderHigh; + if (thisGlider->dest.left > thisGlider->whole.left) + { + thisGlider->whole.right = thisGlider->dest.right; + thisGlider->wholeShadow.right = thisGlider->dest.right; + } + else + { + thisGlider->whole.left = thisGlider->dest.left; + thisGlider->wholeShadow.left = thisGlider->dest.left; + } + thisGlider->destShadow.left = thisGlider->dest.left; + thisGlider->destShadow.right = thisGlider->destShadow.left + kGliderWide; + thisGlider->destShadow.bottom = thisGlider->destShadow.top + kShadowHigh; + thisGlider->mode = kGliderShredding; + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + else + { + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + } + thisGlider->hVel = 0; + thisGlider->vVel = 0; + thisGlider->hDesiredVel = 0; + thisGlider->vDesiredVel = 0; + thisGlider->frame = bounds->bottom - 3; + thisGlider->tipped = false; +} + +//-------------------------------------------------------------- FlagGliderBurning + +void FlagGliderBurning (gliderPtr thisGlider) +{ + #define kFramesToBurn 60 + + PlayPrioritySound(kCaughtFireSound, kCaughtFirePriority); + + thisGlider->dest.right = thisGlider->dest.left + kGliderWide; + thisGlider->dest.top = thisGlider->dest.bottom - kGliderBurningHigh; + thisGlider->destShadow.right = thisGlider->destShadow.left + kGliderWide; + thisGlider->destShadow.bottom = thisGlider->destShadow.top + kShadowHigh; + thisGlider->mode = kGliderBurning; + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[25]; + thisGlider->mask = gliderSrc[25]; + } + else + { + thisGlider->src = gliderSrc[21]; + thisGlider->mask = gliderSrc[21]; + } + thisGlider->hVel = 0; + thisGlider->vVel = 0; + thisGlider->hDesiredVel = 0; + thisGlider->vDesiredVel = 0; + thisGlider->frame = 0; + thisGlider->wasMode = kFramesToBurn; // used to count down burning + thisGlider->tipped = false; +} + +//-------------------------------------------------------------- FlagGliderFaceLeft + +void FlagGliderFaceLeft (gliderPtr thisGlider) +{ + thisGlider->mode = kGliderFaceLeft; + thisGlider->frame = kLastAboutFaceFrame; + thisGlider->src = gliderSrc[kLastAboutFaceFrame]; + thisGlider->mask = gliderSrc[kLastAboutFaceFrame]; +} + +//-------------------------------------------------------------- FlagGliderFaceRight + +void FlagGliderFaceRight (gliderPtr thisGlider) +{ + thisGlider->mode = kGliderFaceRight; + thisGlider->frame = kFirstAboutFaceFrame; + thisGlider->src = gliderSrc[kFirstAboutFaceFrame]; + thisGlider->mask = gliderSrc[kFirstAboutFaceFrame]; +} + +//-------------------------------------------------------------- FlagGliderInLimbo + +void FlagGliderInLimbo (gliderPtr thisGlider, Boolean sayIt) +{ + thisGlider->wasMode = thisGlider->mode; + thisGlider->mode = kGliderInLimbo; + if ((sayIt) && (saidFollow < 3)) + { + PlayPrioritySound(kFollowSound, kFollowPriority); + saidFollow++; + } + firstPlayer = thisGlider->which; +} + +//-------------------------------------------------------------- UndoGliderLimbo + +void UndoGliderLimbo (gliderPtr thisGlider) +{ + if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) + return; + + if (thisGlider->mode == kGliderInLimbo) + thisGlider->mode = thisGlider->wasMode; + thisGlider->dontDraw = false; +} + +//-------------------------------------------------------------- ToggleGliderFacing + +void ToggleGliderFacing (gliderPtr thisGlider) +{ + if (thisGlider->mode != kGliderNormal) + return; + + if (thisGlider->facing == kFaceLeft) + FlagGliderFaceRight(thisGlider); + else + FlagGliderFaceLeft(thisGlider); +} + +//-------------------------------------------------------------- InsureGliderFacingRight + +void InsureGliderFacingRight (gliderPtr thisGlider) +{ + if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) + return; + + if ((thisGlider->facing == kFaceLeft) && (thisGlider->mode != kGliderBurning)) + FlagGliderFaceRight(thisGlider); +} + +//-------------------------------------------------------------- InsureGliderFacingLeft + +void InsureGliderFacingLeft (gliderPtr thisGlider) +{ + if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) + return; + + if ((thisGlider->facing == kFaceRight) && (thisGlider->mode != kGliderBurning)) + FlagGliderFaceLeft(thisGlider); +} + +//-------------------------------------------------------------- ReadyGliderForTripUpStairs + +void ReadyGliderForTripUpStairs (gliderPtr thisGlider) +{ + #define kVGliderAppearsComingUp 100 + + if ((twoPlayerGame) && (thisGlider->which == playerDead) && (onePlayerLeft)) + return; + + thisGlider->facing = kFaceLeft; + thisGlider->mode = kGliderComingUp; + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + thisGlider->hVel = 0; + thisGlider->vVel = 0; + thisGlider->hDesiredVel = 0; + thisGlider->vDesiredVel = 0; + thisGlider->tipped = false; + + rightClip = GetUpStairsRightEdge(); + thisGlider->dest = thisGlider->src; + ZeroRectCorner(&thisGlider->dest); + QOffsetRect(&thisGlider->dest, rightClip, kVGliderAppearsComingUp); + thisGlider->whole = thisGlider->dest; + thisGlider->destShadow.left = thisGlider->dest.left; + thisGlider->destShadow.right = thisGlider->dest.right; + thisGlider->wholeShadow = thisGlider->destShadow; + + FinishGliderUpStairs(thisGlider); +} + +//-------------------------------------------------------------- ReadyGliderForTripDownStairs + +void ReadyGliderForTripDownStairs (gliderPtr thisGlider) +{ + #define kVGliderAppearsComingDown 100 + + if ((twoPlayerGame) && (thisGlider->which == playerDead) && (onePlayerLeft)) + return; + + thisGlider->facing = kFaceRight; + thisGlider->mode = kGliderComingDown; + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + thisGlider->hVel = 0; + thisGlider->vVel = 0; + thisGlider->hDesiredVel = 0; + thisGlider->vDesiredVel = 0; + thisGlider->tipped = false; + + leftClip = GetDownStairsLeftEdge(); + thisGlider->dest = thisGlider->src; + ZeroRectCorner(&thisGlider->dest); + QOffsetRect(&thisGlider->dest, leftClip - kGliderWide, kVGliderAppearsComingDown); + thisGlider->whole = thisGlider->dest; + thisGlider->destShadow.left = thisGlider->dest.left; + thisGlider->destShadow.right = thisGlider->dest.right; + thisGlider->wholeShadow = thisGlider->destShadow; + + FinishGliderDownStairs(thisGlider); +} + +//-------------------------------------------------------------- StartGliderFoilGoing + +void StartGliderFoilGoing (gliderPtr thisGlider) +{ + if ((thisGlider->mode == kGliderGoingFoil) || (thisGlider->mode == kGliderInLimbo)) + return; + + QuickFoilRefresh(false); + + thisGlider->mode = kGliderGoingFoil; + thisGlider->whole = thisGlider->dest; + thisGlider->frame = 0; + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; + thisGlider->mask = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[10 - thisGlider->frame]; + thisGlider->mask = gliderSrc[10 - thisGlider->frame]; + } +} + +//-------------------------------------------------------------- StartGliderFoilLosing + +void StartGliderFoilLosing (gliderPtr thisGlider) +{ + if ((thisGlider->mode == kGliderLosingFoil) || + (thisGlider->mode == kGliderInLimbo)) + return; + + QuickFoilRefresh(false); + PlayPrioritySound(kFizzleSound, kFizzlePriority); + + thisGlider->mode = kGliderLosingFoil; + thisGlider->whole = thisGlider->dest; + thisGlider->frame = 0; + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; + thisGlider->mask = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[10 - thisGlider->frame]; + thisGlider->mask = gliderSrc[10 - thisGlider->frame]; + } +} + +//-------------------------------------------------------------- TagGliderIdle + +void TagGliderIdle (gliderPtr thisGlider) +{ + if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) + return; + + thisGlider->wasMode = thisGlider->mode; + thisGlider->mode = kGliderIdle; + thisGlider->hVel = 30; // used for 30 frame delay +} + diff --git a/GpApp/Music.cpp b/GpApp/Music.cpp new file mode 100644 index 0000000..f6d9962 --- /dev/null +++ b/GpApp/Music.cpp @@ -0,0 +1,416 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Music.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLResources.h" +#include "PLSound.h" +#include "Environ.h" +#include "Externs.h" + + +#define kBaseBufferMusicID 2000 +#define kMaxMusic 7 +#define kLastMusicPiece 16 +#define kLastGamePiece 6 + + +void MusicCallBack (SndChannelPtr, SndCommand *); +OSErr LoadMusicSounds (void); +OSErr DumpMusicSounds (void); +OSErr OpenMusicChannel (void); +OSErr CloseMusicChannel (void); + + +SndCallBackUPP musicCallBackUPP; +SndChannelPtr musicChannel; +Ptr theMusicData[kMaxMusic]; +short musicSoundID, musicCursor; +short musicScore[kLastMusicPiece]; +short gameScore[kLastGamePiece]; +short musicMode; +Boolean isMusicOn, isPlayMusicIdle, isPlayMusicGame; +Boolean failedMusic, dontLoadMusic; + +extern Boolean isSoundOn; + + +//============================================================== Functions +//-------------------------------------------------------------- StartMusic + +OSErr StartMusic (void) +{ + SndCommand theCommand; + OSErr theErr; + short soundVolume; + + theErr = noErr; + + if (dontLoadMusic) + return(theErr); + + UnivGetSoundVolume(&soundVolume, thisMac.hasSM3); + + if ((soundVolume != 0) && (!failedMusic)) + { + theCommand.cmd = bufferCmd; + theCommand.param1 = 0; + theCommand.param2 = (intptr_t)(theMusicData[musicSoundID]); + theErr = SndDoCommand(musicChannel, &theCommand, false); + if (theErr != noErr) + return (theErr); + + // GP: No idea what "1964" means + theCommand.cmd = nullCmd; + theCommand.param1 = 1964; + theCommand.param2 = 0; + theErr = SndDoCommand(musicChannel, &theCommand, false); + if (theErr != noErr) + return (theErr); + + musicCursor++; + if (musicCursor >= kLastMusicPiece) + musicCursor = 0; + musicSoundID = musicScore[musicCursor]; + + theCommand.cmd = bufferCmd; + theCommand.param1 = 0; + theCommand.param2 = (intptr_t)(theMusicData[musicSoundID]); + theErr = SndDoCommand(musicChannel, &theCommand, false); + if (theErr != noErr) + return (theErr); + + theCommand.cmd = callBackCmd; + theCommand.param1 = 0; + theCommand.param2 = 0; + theErr = SndDoCommand(musicChannel, &theCommand, false); + + isMusicOn = true; + } + + return (theErr); +} + +//-------------------------------------------------------------- StopTheMusic + +void StopTheMusic (void) +{ + SndCommand theCommand; + OSErr theErr; + + if (dontLoadMusic) + return; + + theErr = noErr; + if ((isMusicOn) && (!failedMusic)) + { + theCommand.cmd = flushCmd; + theCommand.param1 = 0; + theCommand.param2 = 0L; + theErr = SndDoImmediate(musicChannel, &theCommand); + + theCommand.cmd = quietCmd; + theCommand.param1 = 0; + theCommand.param2 = 0L; + theErr = SndDoImmediate(musicChannel, &theCommand); + + isMusicOn = false; + } +} + +//-------------------------------------------------------------- ToggleMusicWhilePlaying + +void ToggleMusicWhilePlaying (void) +{ + OSErr theErr; + + if (dontLoadMusic) + return; + + if (isPlayMusicGame) + { + if (!isMusicOn) + theErr = StartMusic(); + } + else + { + if (isMusicOn) + StopTheMusic(); + } +} + +//-------------------------------------------------------------- SetMusicalPiece + +void SetMusicalMode (short newMode) +{ + if (dontLoadMusic) + return; + + switch (newMode) + { + case kKickGameScoreMode: + musicCursor = 2; + break; + + case kProdGameScoreMode: + musicCursor = -1; + break; + + default: + musicMode = newMode; + musicCursor = 0; + break; + } +} + +//-------------------------------------------------------------- MusicCallBack + +void MusicCallBack (SndChannelPtr theChannel, SndCommand *theCommand) +{ + OSErr theErr; + +// gameA5 = theCommand.param2; +// thisA5 = SetA5(gameA5); + + switch (musicMode) + { + case kPlayGameScoreMode: + musicCursor++; + if (musicCursor >= kLastGamePiece) + musicCursor = 1; + musicSoundID = gameScore[musicCursor]; + if (musicSoundID < 0) + { + musicCursor += musicSoundID; + musicSoundID = gameScore[musicCursor]; + } + break; + + case kPlayWholeScoreMode: + musicCursor++; + if (musicCursor >= kLastMusicPiece - 1) + musicCursor = 0; + musicSoundID = musicScore[musicCursor]; + break; + + default: + musicSoundID = musicMode; + break; + } + + theCommand->cmd = bufferCmd; + theCommand->param1 = 0; + theCommand->param2 = (intptr_t)(theMusicData[musicSoundID]); + theErr = SndDoCommand(musicChannel, theCommand, false); + + theCommand->cmd = callBackCmd; + theCommand->param1 = 0; + theCommand->param2 = 0; + theErr = SndDoCommand(musicChannel, theCommand, false); +} + +//-------------------------------------------------------------- LoadMusicSounds + +OSErr LoadMusicSounds (void) +{ + Handle theSound; + long soundDataSize; + OSErr theErr; + short i; + + theErr = noErr; + + for (i = 0; i < kMaxMusic; i++) + theMusicData[i] = nil; + + for (i = 0; i < kMaxMusic; i++) + { + theSound = GetResource('snd ', i + kBaseBufferMusicID); + if (theSound == nil) + return (MemError()); + + HLock(theSound); + soundDataSize = GetHandleSize(theSound) - 20L; + HUnlock(theSound); + + theMusicData[i] = NewPtr(soundDataSize); + if (theMusicData[i] == nil) + return (MemError()); + + HLock(theSound); + BlockMove((Ptr)(static_cast(*theSound) + 20L), theMusicData[i], soundDataSize); + ReleaseResource(theSound); + } + return (theErr); +} + +//-------------------------------------------------------------- DumpMusicSounds + +OSErr DumpMusicSounds (void) +{ + OSErr theErr; + short i; + + theErr = noErr; + + for (i = 0; i < kMaxMusic; i++) + { + if (theMusicData[i] != nil) + DisposePtr(theMusicData[i]); + theMusicData[i] = nil; + } + + return (theErr); +} + +//-------------------------------------------------------------- OpenMusicChannel + +OSErr OpenMusicChannel (void) +{ + OSErr theErr; + + musicCallBackUPP = NewSndCallBackProc(MusicCallBack); + + theErr = noErr; + + if (musicChannel != nil) + return (theErr); + + musicChannel = nil; + theErr = SndNewChannel(&musicChannel, + sampledSynth, initNoInterp + initMono, + (SndCallBackUPP)musicCallBackUPP); + + return (theErr); +} + +//-------------------------------------------------------------- CloseMusicChannel + +OSErr CloseMusicChannel (void) +{ + OSErr theErr; + + theErr = noErr; + + if (musicChannel != nil) + theErr = SndDisposeChannel(musicChannel, true); + musicChannel = nil; + + DisposeSndCallBackUPP(musicCallBackUPP); + + return (theErr); +} + +//-------------------------------------------------------------- InitMusic + +void InitMusic (void) +{ + OSErr theErr; + + if (dontLoadMusic) + return; + + musicChannel = nil; + + failedMusic = false; + isMusicOn = false; + theErr = LoadMusicSounds(); + if (theErr != noErr) + { + YellowAlert(kYellowNoMusic, theErr); + failedMusic = true; + return; + } + theErr = OpenMusicChannel(); + + musicScore[0] = 0; + musicScore[1] = 1; + musicScore[2] = 2; + musicScore[3] = 3; + musicScore[4] = 4; + musicScore[5] = 4; + musicScore[6] = 0; + musicScore[7] = 1; + musicScore[8] = 2; + musicScore[9] = 3; + musicScore[10] = kPlayChorus; + musicScore[11] = kPlayChorus; + musicScore[12] = kPlayRefrainSparse1; + musicScore[13] = kPlayRefrainSparse2; + musicScore[14] = kPlayChorus; + musicScore[15] = kPlayChorus; + + gameScore[0] = kPlayRefrainSparse2; + gameScore[1] = kPlayRefrainSparse1; + gameScore[2] = -1; + gameScore[3] = kPlayRefrainSparse2; + gameScore[4] = kPlayChorus; + gameScore[5] = kPlayChorus; + + musicCursor = 0; + musicSoundID = musicScore[musicCursor]; + musicMode = kPlayWholeScoreMode; + + if (isPlayMusicIdle) + { + theErr = StartMusic(); + if (theErr != noErr) + { + YellowAlert(kYellowNoMusic, theErr); + failedMusic = true; + } + } +} + +//-------------------------------------------------------------- KillMusic + +void KillMusic (void) +{ + OSErr theErr; + + if (dontLoadMusic) + return; + + theErr = DumpMusicSounds(); + theErr = CloseMusicChannel(); +} + +//-------------------------------------------------------------- MusicBytesNeeded + +long MusicBytesNeeded (void) +{ + Handle theSound; + long totalBytes; + short i; + + totalBytes = 0L; + SetResLoad(false); + for (i = 0; i < kMaxMusic; i++) + { + theSound = GetResource('snd ', i + kBaseBufferMusicID); + if (theSound == nil) + { + SetResLoad(true); + return ((long)ResError()); + } + totalBytes += GetMaxResourceSize(theSound); +// ReleaseResource(theSound); + } + SetResLoad(true); + return totalBytes; +} + +//-------------------------------------------------------------- TellHerNoMusic + +void TellHerNoMusic (void) +{ + #define kNoMemForMusicAlert 1038 + short hitWhat; + +// CenterAlert(kNoMemForMusicAlert); + hitWhat = Alert(kNoMemForMusicAlert, nil); +} + diff --git a/GpApp/ObjectAdd.cpp b/GpApp/ObjectAdd.cpp new file mode 100644 index 0000000..4008c61 --- /dev/null +++ b/GpApp/ObjectAdd.cpp @@ -0,0 +1,1084 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// ObjectAdd.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLToolUtils.h" +#include "Externs.h" +#include "ObjectEdit.h" +#include "RectUtils.h" + + +#define kNoMoreObjectsAlert 1008 +#define kNoMoreSpecialAlert 1028 +#define kMaxSoundTriggers 1 +#define kMaxStairs 1 +#define kMouseholeBottom 295 +#define kFireplaceBottom 297 +#define kManholeSits 322 +#define kGrecoVentTop 303 +#define kSewerBlowerTop 292 + + +short FindEmptyObjectSlot (void); +short HowManyCandleObjects (void); +short HowManyTikiObjects (void); +short HowManyBBQObjects (void); +short HowManyCuckooObjects (void); +short HowManyBandsObjects (void); +short HowManyGreaseObjects (void); +short HowManyStarsObjects (void); +short HowManySoundObjects (void); +short HowManyUpStairsObjects (void); +short HowManyDownStairsObjects (void); +short HowManyShredderObjects (void); +short HowManyDynamicObjects (void); +void ShoutNoMoreSpecialObjects (void); + + +short wasFlower; + + +//============================================================== Functions +//-------------------------------------------------------------- AddNewObject + +Boolean AddNewObject (Point where, short what, Boolean showItNow) +{ + KeyMap theseKeys; + Rect srcRect, newRect; + short direction, dist; + Boolean handled, drawWholeRoom; + +#ifndef COMPILEDEMO + + objActive = FindEmptyObjectSlot(); + if (objActive == -1) + { + ShoutNoMoreObjects(); + return (false); + } + + drawWholeRoom = false; + + switch (what) + { + case kFloorVent: + case kFloorBlower: + case kSewerGrate: + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + case kInvisBlower: + case kGrecoVent: + case kSewerBlower: + case kLiftArea: + if (((what == kTaper) || (what == kCandle) || (what == kStubby)) && + (HowManyCandleObjects() >= kMaxCandles)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + else if ((what == kTiki) && (HowManyTikiObjects() >= kMaxTikis)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + else if ((what == kBBQ) && (HowManyBBQObjects() >= kMaxCoals)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + srcRect = srcRects[what]; + thisRoom->objects[objActive].data.a.topLeft.h = where.h - HalfRectWide(&srcRect); + QSetRect(&newRect, 0, 0, RectWide(&srcRect), RectTall(&srcRect)); + if (what == kFloorVent) + thisRoom->objects[objActive].data.a.topLeft.v = kFloorVentTop; + else if (what == kFloorBlower) + thisRoom->objects[objActive].data.a.topLeft.v = kFloorBlowerTop; + else if ((what == kTaper) || (what == kCandle) || (what == kStubby) || + (what == kTiki) || (what == kBBQ) || (what == kInvisBlower) || + (what == kLiftArea)) + thisRoom->objects[objActive].data.a.topLeft.v = where.v - HalfRectTall(&srcRect); + else if (what == kGrecoVent) + thisRoom->objects[objActive].data.a.topLeft.v = kGrecoVentTop; + else if (what == kSewerBlower) + thisRoom->objects[objActive].data.a.topLeft.v = kSewerBlowerTop; + QOffsetRect(&newRect, thisRoom->objects[objActive].data.a.topLeft.h, + thisRoom->objects[objActive].data.a.topLeft.v); + thisRoom->objects[objActive].data.a.distance = 64; + thisRoom->objects[objActive].data.a.initial = true; + thisRoom->objects[objActive].data.a.state = true; + thisRoom->objects[objActive].data.a.vector = 0x01; + if (what == kLiftArea) + thisRoom->objects[objActive].data.a.tall = 0x10; + else + thisRoom->objects[objActive].data.a.tall = 0x00; + break; + + case kCeilingVent: + case kCeilingBlower: + srcRect = srcRects[what]; + thisRoom->objects[objActive].data.a.topLeft.h = where.h - HalfRectWide(&srcRect); + QSetRect(&newRect, 0, 0, RectWide(&srcRect), RectTall(&srcRect)); + if (what == kCeilingVent) + thisRoom->objects[objActive].data.a.topLeft.v = kCeilingVentTop; + else if (what == kCeilingBlower) + thisRoom->objects[objActive].data.a.topLeft.v = kCeilingBlowerTop; + QOffsetRect(&newRect, thisRoom->objects[objActive].data.a.topLeft.h, + thisRoom->objects[objActive].data.a.topLeft.v); + thisRoom->objects[objActive].data.a.distance = 32; + thisRoom->objects[objActive].data.a.initial = true; + thisRoom->objects[objActive].data.a.state = true; + thisRoom->objects[objActive].data.a.vector = 0x04; + break; + + case kLeftFan: + thisRoom->objects[objActive].data.a.topLeft.h = + where.h - HalfRectWide(&srcRects[kLeftFan]); + thisRoom->objects[objActive].data.a.topLeft.v = + where.v - HalfRectTall(&srcRects[kLeftFan]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[kLeftFan]), + RectTall(&srcRects[kLeftFan])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.a.topLeft.h, + thisRoom->objects[objActive].data.a.topLeft.v); + thisRoom->objects[objActive].data.a.distance = 32; + thisRoom->objects[objActive].data.a.initial = true; + thisRoom->objects[objActive].data.a.state = true; + thisRoom->objects[objActive].data.a.vector = 0x08; + break; + + case kRightFan: + thisRoom->objects[objActive].data.a.topLeft.h = + where.h - HalfRectWide(&srcRects[kRightFan]); + thisRoom->objects[objActive].data.a.topLeft.v = + where.v - HalfRectTall(&srcRects[kRightFan]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[kRightFan]), RectTall(&srcRects[kRightFan])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.a.topLeft.h, + thisRoom->objects[objActive].data.a.topLeft.v); + thisRoom->objects[objActive].data.a.distance = 32; + thisRoom->objects[objActive].data.a.initial = true; + thisRoom->objects[objActive].data.a.state = true; + thisRoom->objects[objActive].data.a.vector = 0x02; + break; + + case kTable: + case kShelf: + case kCabinet: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kCounter: + case kDresser: + case kDeckTable: + case kStool: + case kTrunk: + case kInvisObstacle: + case kBooks: + case kInvisBounce: + newRect = srcRects[what]; + CenterRectOnPoint(&newRect, where); + if (what == kCounter) + newRect.bottom = kCounterBottom; + else if (what == kDresser) + newRect.bottom = kDresserBottom; + thisRoom->objects[objActive].data.b.bounds = newRect; + thisRoom->objects[objActive].data.b.pict = 0; + break; + + case kManhole: + newRect = srcRects[kManhole]; + CenterRectOnPoint(&newRect, where); + newRect.left = (((newRect.left - 3) / 64) * 64) + 3; + newRect.right = newRect.left + RectWide(&srcRects[kManhole]); + newRect.bottom = kManholeSits; + newRect.top = newRect.bottom - RectTall(&srcRects[kManhole]); + thisRoom->objects[objActive].data.b.bounds = newRect; + thisRoom->objects[objActive].data.b.pict = 0; + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kFoil: + case kStar: + case kSparkle: + case kHelium: + if ((what == kCuckoo) && (HowManyCuckooObjects() >= kMaxPendulums)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + else if ((what == kBands) && (HowManyBandsObjects() >= kMaxRubberBands)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + else if ((what == kStar) && (HowManyStarsObjects() >= kMaxStars)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + else if ((what == kSparkle) && (HowManyDynamicObjects() >= kMaxDynamicObs)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + thisRoom->objects[objActive].data.c.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.c.topLeft.v = + where.v - HalfRectTall(&srcRects[what]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.c.topLeft.h, + thisRoom->objects[objActive].data.c.topLeft.v); + thisRoom->objects[objActive].data.c.length = 0; + thisRoom->objects[objActive].data.c.points = 0; + thisRoom->objects[objActive].data.c.state = true; + thisRoom->objects[objActive].data.c.initial = true; + break; + + case kGreaseRt: + case kGreaseLf: + if (HowManyGreaseObjects() >= kMaxGrease) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + thisRoom->objects[objActive].data.c.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.c.topLeft.v = + where.v - HalfRectTall(&srcRects[what]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.c.topLeft.h, + thisRoom->objects[objActive].data.c.topLeft.v); + thisRoom->objects[objActive].data.c.length = 64; + thisRoom->objects[objActive].data.c.points = 0; + thisRoom->objects[objActive].data.c.state = true; + thisRoom->objects[objActive].data.c.initial = true; + break; + + case kInvisBonus: + thisRoom->objects[objActive].data.c.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.c.topLeft.v = + where.v - HalfRectTall(&srcRects[what]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.c.topLeft.h, + thisRoom->objects[objActive].data.c.topLeft.v); + thisRoom->objects[objActive].data.c.length = 0; + thisRoom->objects[objActive].data.c.points = 100; + thisRoom->objects[objActive].data.c.state = true; + thisRoom->objects[objActive].data.c.initial = true; + break; + + case kSlider: + thisRoom->objects[objActive].data.c.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.c.topLeft.v = + where.v - HalfRectTall(&srcRects[what]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.c.topLeft.h, + thisRoom->objects[objActive].data.c.topLeft.v); + thisRoom->objects[objActive].data.c.length = 64; + thisRoom->objects[objActive].data.c.points = 0; + thisRoom->objects[objActive].data.c.state = true; + thisRoom->objects[objActive].data.c.initial = true; + break; + + case kUpStairs: + case kDownStairs: + if ((what == kUpStairs) && (HowManyUpStairsObjects() >= kMaxStairs)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + else if ((what == kDownStairs) && (HowManyDownStairsObjects() >= kMaxStairs)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + thisRoom->objects[objActive].data.d.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.d.topLeft.v = kStairsTop; + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.d.topLeft.h, + thisRoom->objects[objActive].data.d.topLeft.v); + thisRoom->objects[objActive].data.d.tall = 0; + thisRoom->objects[objActive].data.d.where = -1; + thisRoom->objects[objActive].data.d.who = 255; + thisRoom->objects[objActive].data.d.wide = 0; + break; + + case kMailboxLf: + case kMailboxRt: + thisRoom->objects[objActive].data.d.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.d.topLeft.v = + where.v - HalfRectTall(&srcRects[what]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.d.topLeft.h, + thisRoom->objects[objActive].data.d.topLeft.v); + thisRoom->objects[objActive].data.d.tall = 0; + thisRoom->objects[objActive].data.d.where = -1; + thisRoom->objects[objActive].data.d.who = 255; + thisRoom->objects[objActive].data.d.wide = 0; + break; + + case kFloorTrans: + thisRoom->objects[objActive].data.d.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.d.topLeft.v = kFloorTransTop; + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.d.topLeft.h, + thisRoom->objects[objActive].data.d.topLeft.v); + thisRoom->objects[objActive].data.d.tall = 0; + thisRoom->objects[objActive].data.d.where = -1; + thisRoom->objects[objActive].data.d.who = 255; + thisRoom->objects[objActive].data.d.wide = 0; + break; + + case kCeilingTrans: + thisRoom->objects[objActive].data.d.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.d.topLeft.v = kCeilingTransTop; + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.d.topLeft.h, + thisRoom->objects[objActive].data.d.topLeft.v); + thisRoom->objects[objActive].data.d.tall = 0; + thisRoom->objects[objActive].data.d.where = -1; + thisRoom->objects[objActive].data.d.who = 255; + thisRoom->objects[objActive].data.d.wide = 0; + break; + + case kDoorInLf: + case kDoorInRt: + case kDoorExRt: + case kDoorExLf: + case kWindowInLf: + case kWindowInRt: + case kWindowExRt: + case kWindowExLf: + if ((what == kDoorInLf) || (what == kDoorInRt)) + { + if (where.h > (kRoomWide / 2)) + { + what = kDoorInRt; + thisRoom->objects[objActive].what = kDoorInRt; + thisRoom->objects[objActive].data.d.topLeft.h = kDoorInRtLeft; + thisRoom->objects[objActive].data.d.topLeft.v = kDoorInTop; + } + else + { + what = kDoorInLf; + thisRoom->objects[objActive].what = kDoorInLf; + thisRoom->objects[objActive].data.d.topLeft.h = kDoorInLfLeft; + thisRoom->objects[objActive].data.d.topLeft.v = kDoorInTop; + } + } + else if ((what == kDoorExRt) || (what == kDoorExLf)) + { + if (where.h > (kRoomWide / 2)) + { + what = kDoorExRt; + thisRoom->objects[objActive].what = kDoorExRt; + thisRoom->objects[objActive].data.d.topLeft.h = kDoorExRtLeft; + thisRoom->objects[objActive].data.d.topLeft.v = kDoorExTop; + } + else + { + what = kDoorExLf; + thisRoom->objects[objActive].what = kDoorExLf; + thisRoom->objects[objActive].data.d.topLeft.h = kDoorExLfLeft; + thisRoom->objects[objActive].data.d.topLeft.v = kDoorExTop; + } + } + else if ((what == kWindowInLf) || (what == kWindowInRt)) + { + if (where.h > (kRoomWide / 2)) + { + what = kWindowInRt; + thisRoom->objects[objActive].what = kWindowInRt; + thisRoom->objects[objActive].data.d.topLeft.h = kWindowInRtLeft; + thisRoom->objects[objActive].data.d.topLeft.v = kWindowInTop; + } + else + { + what = kWindowInLf; + thisRoom->objects[objActive].what = kWindowInLf; + thisRoom->objects[objActive].data.d.topLeft.h = kWindowInLfLeft; + thisRoom->objects[objActive].data.d.topLeft.v = kWindowInTop; + } + } + else if ((what == kWindowExRt) || (what == kWindowExLf)) + { + if (where.h > (kRoomWide / 2)) + { + what = kWindowExRt; + thisRoom->objects[objActive].what = kWindowExRt; + thisRoom->objects[objActive].data.d.topLeft.h = kWindowExRtLeft; + thisRoom->objects[objActive].data.d.topLeft.v = kWindowExTop; + } + else + { + what = kWindowExLf; + thisRoom->objects[objActive].what = kWindowExLf; + thisRoom->objects[objActive].data.d.topLeft.h = kWindowExLfLeft; + thisRoom->objects[objActive].data.d.topLeft.v = kWindowExTop; + } + } + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.d.topLeft.h, + thisRoom->objects[objActive].data.d.topLeft.v); + thisRoom->objects[objActive].data.d.tall = 0; + thisRoom->objects[objActive].data.d.where = -1; + thisRoom->objects[objActive].data.d.who = 255; + thisRoom->objects[objActive].data.d.wide = 0; + drawWholeRoom = true; + break; + + case kInvisTrans: + newRect = srcRects[what]; + CenterRectOnPoint(&newRect, where); + thisRoom->objects[objActive].data.d.topLeft.h = newRect.left; + thisRoom->objects[objActive].data.d.topLeft.v = newRect.top; + thisRoom->objects[objActive].data.d.tall = newRect.bottom - newRect.top; + thisRoom->objects[objActive].data.d.where = -1; + thisRoom->objects[objActive].data.d.who = 255; + thisRoom->objects[objActive].data.d.wide = 0; + break; + + case kDeluxeTrans: + newRect = srcRects[what]; + CenterRectOnPoint(&newRect, where); + thisRoom->objects[objActive].data.d.topLeft.h = newRect.left; + thisRoom->objects[objActive].data.d.topLeft.v = newRect.top; + thisRoom->objects[objActive].data.d.tall = 0x1010; // 64 x 64 + thisRoom->objects[objActive].data.d.where = -1; + thisRoom->objects[objActive].data.d.who = 255; + thisRoom->objects[objActive].data.d.wide = 0x10; // Initially on + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + if ((what == kSoundTrigger) && (HowManySoundObjects() >= kMaxSoundTriggers)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + thisRoom->objects[objActive].data.e.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.e.topLeft.v = + where.v - HalfRectTall(&srcRects[what]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.e.topLeft.h, + thisRoom->objects[objActive].data.e.topLeft.v); + thisRoom->objects[objActive].data.e.delay = 0; + if (what == kSoundTrigger) + thisRoom->objects[objActive].data.e.where = 3000; + else + thisRoom->objects[objActive].data.e.where = -1; + thisRoom->objects[objActive].data.e.who = 255; + if ((what == kTrigger) || (what == kLgTrigger)) + thisRoom->objects[objActive].data.e.type = kOneShot; + else + thisRoom->objects[objActive].data.e.type = kToggle; + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + if (what == kCeilingLight) + { + thisRoom->objects[objActive].data.f.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.f.topLeft.v = kCeilingLightTop; + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, + thisRoom->objects[objActive].data.f.topLeft.v); + thisRoom->objects[objActive].data.f.length = 64; + } + else if (what == kHipLamp) + { + thisRoom->objects[objActive].data.f.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.f.topLeft.v = kHipLampTop; + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, + thisRoom->objects[objActive].data.f.topLeft.v); + thisRoom->objects[objActive].data.f.length = 0; + } + else if (what == kDecoLamp) + { + thisRoom->objects[objActive].data.f.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.f.topLeft.v = kDecoLampTop; + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, + thisRoom->objects[objActive].data.f.topLeft.v); + thisRoom->objects[objActive].data.f.length = 0; + } + else if (what == kFlourescent) + { + thisRoom->objects[objActive].data.f.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.f.topLeft.v = kFlourescentTop; + newRect = srcRects[what]; + QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, + thisRoom->objects[objActive].data.f.topLeft.v); + thisRoom->objects[objActive].data.f.length = 64; + } + else if (what == kTrackLight) + { + thisRoom->objects[objActive].data.f.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.f.topLeft.v = kTrackLightTop; + newRect = srcRects[what]; + QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, + thisRoom->objects[objActive].data.f.topLeft.v); + thisRoom->objects[objActive].data.f.length = 64; + } + else + { + thisRoom->objects[objActive].data.f.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.f.topLeft.v = + where.v - HalfRectTall(&srcRects[what]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, + thisRoom->objects[objActive].data.f.topLeft.v); + thisRoom->objects[objActive].data.f.length = 0; + } + thisRoom->objects[objActive].data.f.initial = true; + thisRoom->objects[objActive].data.f.state = true; + thisRoom->objects[objActive].data.f.byte0 = 0; + thisRoom->objects[objActive].data.f.byte1 = 0; + drawWholeRoom = true; + break; + + case kShredder: + case kToaster: + case kMacPlus: + case kGuitar: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kStereo: + case kMicrowave: + case kCinderBlock: + case kFlowerBox: + case kCDs: + case kCustomPict: + if ((what != kGuitar) && (what != kCinderBlock) && (what != kFlowerBox) && + (what != kCDs) && (what != kCustomPict) && + (HowManyShredderObjects() >= kMaxShredded)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + thisRoom->objects[objActive].data.g.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.g.topLeft.v = + where.v - HalfRectTall(&srcRects[what]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.g.topLeft.h, + thisRoom->objects[objActive].data.g.topLeft.v); + if (what == kToaster) + { + thisRoom->objects[objActive].data.g.height = 64; + thisRoom->objects[objActive].data.g.delay = 10 + RandomInt(10); + } + else if (what == kOutlet) + { + thisRoom->objects[objActive].data.g.height = 0; + thisRoom->objects[objActive].data.g.delay = 10 + RandomInt(10); + } + else if (what == kCustomPict) + { + thisRoom->objects[objActive].data.g.height = 10000; + thisRoom->objects[objActive].data.g.delay = 0; + } + else + { + thisRoom->objects[objActive].data.g.height = 0; + thisRoom->objects[objActive].data.g.delay = 0; + } + if (what == kMicrowave) + thisRoom->objects[objActive].data.g.byte0 = 7; + else + thisRoom->objects[objActive].data.g.byte0 = 0; + thisRoom->objects[objActive].data.g.initial = true; + thisRoom->objects[objActive].data.g.state = true; + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kCobweb: + if ((what != kCobweb) && (HowManyDynamicObjects() >= kMaxDynamicObs)) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + if (what == kDartLf) + { + thisRoom->objects[objActive].data.h.topLeft.h = + kRoomWide - RectWide(&srcRects[what]); + } + else if (what == kDartRt) + { + thisRoom->objects[objActive].data.h.topLeft.h = 0; + } + else + { + thisRoom->objects[objActive].data.h.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + } + if ((what == kDartLf) || (what == kDartRt) || (what == kCobweb)) + { + thisRoom->objects[objActive].data.h.topLeft.v = + where.v - HalfRectTall(&srcRects[what]); + } + else + { + thisRoom->objects[objActive].data.h.topLeft.v = + (kTileHigh / 2) - HalfRectTall(&srcRects[what]); + } + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.h.topLeft.h, + thisRoom->objects[objActive].data.h.topLeft.v); + thisRoom->objects[objActive].data.h.length = 0; + if (what == kCobweb) + thisRoom->objects[objActive].data.h.delay = 0; + else + thisRoom->objects[objActive].data.h.delay = 10 + RandomInt(10); + thisRoom->objects[objActive].data.h.byte0 = 0; + thisRoom->objects[objActive].data.h.initial = true; + thisRoom->objects[objActive].data.h.state = true; + break; + + case kBall: + case kDrip: + case kFish: + if (HowManyDynamicObjects() >= kMaxDynamicObs) + { + ShoutNoMoreSpecialObjects(); + return (false); + } + thisRoom->objects[objActive].data.h.topLeft.h = + where.h - HalfRectWide(&srcRects[what]); + thisRoom->objects[objActive].data.h.topLeft.v = + where.v - HalfRectTall(&srcRects[what]); + QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), + RectTall(&srcRects[what])); + QOffsetRect(&newRect, thisRoom->objects[objActive].data.h.topLeft.h, + thisRoom->objects[objActive].data.h.topLeft.v); + thisRoom->objects[objActive].data.h.length = 64; + if (what == kBall) + thisRoom->objects[objActive].data.h.delay = 0; + else + thisRoom->objects[objActive].data.h.delay = 10 + RandomInt(10); + thisRoom->objects[objActive].data.h.byte0 = 0; + thisRoom->objects[objActive].data.h.initial = true; + thisRoom->objects[objActive].data.h.state = true; + break; + + case kMousehole: + newRect = srcRects[what]; + CenterRectOnPoint(&newRect, where); + newRect.bottom = kMouseholeBottom; + newRect.top = newRect.bottom - RectTall(&srcRects[what]); + thisRoom->objects[objActive].data.i.bounds = newRect; + thisRoom->objects[objActive].data.i.pict = 0; + break; + + case kFireplace: + newRect = srcRects[what]; + CenterRectOnPoint(&newRect, where); + newRect.bottom = kFireplaceBottom; + newRect.top = newRect.bottom - RectTall(&srcRects[what]); + thisRoom->objects[objActive].data.i.bounds = newRect; + thisRoom->objects[objActive].data.i.pict = 0; + break; + + case kFlower: + GetKeys(theseKeys); + if (!BitTst(&theseKeys, kShiftKeyMap)) + wasFlower = RandomInt(kNumFlowers); + newRect = flowerSrc[wasFlower]; + CenterRectOnPoint(&newRect, where); + thisRoom->objects[objActive].data.i.bounds = newRect; + thisRoom->objects[objActive].data.i.pict = wasFlower; + break; + + case kOzma: + case kMirror: + case kWallWindow: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + case kChimes: + newRect = srcRects[what]; + CenterRectOnPoint(&newRect, where); + thisRoom->objects[objActive].data.i.bounds = newRect; + thisRoom->objects[objActive].data.i.pict = 0; + break; + + default: + return (false); + break; + } + + thisRoom->objects[objActive].what = what; + thisRoom->numObjects++; + if (KeepObjectLegal()) + { + } + fileDirty = true; + UpdateMenus(false); + handled = ObjectHasHandle(&direction, &dist); + + if (showItNow) + { + if (drawWholeRoom) + ReadyBackground(thisRoom->background, thisRoom->tiles); + GetThisRoomsObjRects(); + DrawThisRoomsObjects(); + InvalWindowRect(mainWindow, &mainWindowRect); + + if (handled) + { + StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); + HandleBlowerGlider(); + } + else + StartMarquee(&roomObjectRects[objActive]); + } + +#endif + + return (true); +} + +//-------------------------------------------------------------- FindEmptyObjectSlot + +#ifndef COMPILEDEMO +short FindEmptyObjectSlot (void) +{ + short i, emptySlot; + + emptySlot = -1; + for (i = 0; i < kMaxRoomObs; i++) + if (thisRoom->objects[i].what == kObjectIsEmpty) + { + emptySlot = i; + break; + } + + return (emptySlot); +} + +//-------------------------------------------------------------- FindObjectSlotInRoom + +short FindObjectSlotInRoom (short roomNumber) +{ + roomType *testRoomPtr; + short i, emptySlot; + char wasState; + + emptySlot = -1; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNumber]); + + for (i = 0; i < kMaxRoomObs; i++) + if (testRoomPtr->objects[i].what == kObjectIsEmpty) + { + emptySlot = i; + break; + } + + + HSetState((Handle)thisHouse, wasState); + + return (emptySlot); +} + +//-------------------------------------------------------------- DoesRoomNumHaveObject + +Boolean DoesRoomNumHaveObject (short room, short what) +{ + roomType *testRoomPtr; + short i; + char wasState; + Boolean hasIt; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[room]); + + hasIt = false; + + for (i = 0; i < kMaxRoomObs; i++) + if (testRoomPtr->objects[i].what == what) + { + hasIt = true; + break; + } + + + HSetState((Handle)thisHouse, wasState); + + return (hasIt); +} + +//-------------------------------------------------------------- ShoutNoMoreObjects + +void ShoutNoMoreObjects (void) +{ + short hitWhat; + +// CenterAlert(kNoMoreObjectsAlert); + hitWhat = Alert(kNoMoreObjectsAlert, nil); +} + +//-------------------------------------------------------------- HowManyCandleObjects + +short HowManyCandleObjects (void) +{ + short i, aCandle; + + aCandle = 0; + for (i = 0; i < kMaxRoomObs; i++) + if ((thisRoom->objects[i].what == kTaper) || + (thisRoom->objects[i].what == kCandle) || + (thisRoom->objects[i].what == kStubby)) + aCandle++; + + return (aCandle); +} + +//-------------------------------------------------------------- HowManyTikiObjects + +short HowManyTikiObjects (void) +{ + short i, aTiki; + + aTiki = 0; + for (i = 0; i < kMaxRoomObs; i++) + if (thisRoom->objects[i].what == kTiki) + aTiki++; + + return (aTiki); +} + +//-------------------------------------------------------------- HowManyBBQObjects + +short HowManyBBQObjects (void) +{ + short i, aBBQ; + + aBBQ = 0; + for (i = 0; i < kMaxRoomObs; i++) + if (thisRoom->objects[i].what == kBBQ) + aBBQ++; + + return (aBBQ); +} + +//-------------------------------------------------------------- HowManyCuckooObjects + +short HowManyCuckooObjects (void) +{ + short i, aCuckoo; + + aCuckoo = 0; + for (i = 0; i < kMaxRoomObs; i++) + if (thisRoom->objects[i].what == kCuckoo) + aCuckoo++; + + return (aCuckoo); +} + +//-------------------------------------------------------------- HowManyBandsObjects + +short HowManyBandsObjects (void) +{ + short i, aBands; + + aBands = 0; + for (i = 0; i < kMaxRoomObs; i++) + if (thisRoom->objects[i].what == kBands) + aBands++; + + return (aBands); +} + +//-------------------------------------------------------------- HowManyGreaseObjects + +short HowManyGreaseObjects (void) +{ + short i, aGrease; + + aGrease = 0; + for (i = 0; i < kMaxRoomObs; i++) + if ((thisRoom->objects[i].what == kGreaseRt) || + (thisRoom->objects[i].what == kGreaseLf)) + aGrease++; + + return (aGrease); +} + +//-------------------------------------------------------------- HowManyStarsObjects + +short HowManyStarsObjects (void) +{ + short i, aStar; + + aStar = 0; + for (i = 0; i < kMaxRoomObs; i++) + if (thisRoom->objects[i].what == kStar) + aStar++; + + return (aStar); +} + +//-------------------------------------------------------------- HowManySoundObjects + +short HowManySoundObjects (void) +{ + short i, aSound; + + aSound = 0; + for (i = 0; i < kMaxRoomObs; i++) + if (thisRoom->objects[i].what == kSoundTrigger) + aSound++; + + return (aSound); +} + +//-------------------------------------------------------------- HowManyUpStairsObjects + +short HowManyUpStairsObjects (void) +{ + short i, aStair; + + aStair = 0; + for (i = 0; i < kMaxRoomObs; i++) + if (thisRoom->objects[i].what == kUpStairs) + aStair++; + + return (aStair); +} + +//-------------------------------------------------------------- HowManyDownStairsObjects + +short HowManyDownStairsObjects (void) +{ + short i, aStair; + + aStair = 0; + for (i = 0; i < kMaxRoomObs; i++) + if (thisRoom->objects[i].what == kDownStairs) + aStair++; + + return (aStair); +} + +//-------------------------------------------------------------- HowManyShredderObjects + +short HowManyShredderObjects (void) +{ + short i, aShredder; + + aShredder = 0; + for (i = 0; i < kMaxRoomObs; i++) + if (thisRoom->objects[i].what == kShredder) + aShredder++; + + return (aShredder); +} + +//-------------------------------------------------------------- HowManyDynamicObjects + +short HowManyDynamicObjects (void) +{ + short i, aDinah; + + aDinah = 0; + for (i = 0; i < kMaxRoomObs; i++) + if ((thisRoom->objects[i].what == kSparkle) || + (thisRoom->objects[i].what == kToaster) || + (thisRoom->objects[i].what == kMacPlus) || + (thisRoom->objects[i].what == kTV) || + (thisRoom->objects[i].what == kCoffee) || + (thisRoom->objects[i].what == kOutlet) || + (thisRoom->objects[i].what == kVCR) || + (thisRoom->objects[i].what == kStereo) || + (thisRoom->objects[i].what == kMicrowave) || + (thisRoom->objects[i].what == kBalloon) || + (thisRoom->objects[i].what == kCopterLf) || + (thisRoom->objects[i].what == kCopterRt) || + (thisRoom->objects[i].what == kDartLf) || + (thisRoom->objects[i].what == kDartRt) || + (thisRoom->objects[i].what == kBall) || + (thisRoom->objects[i].what == kDrip) || + (thisRoom->objects[i].what == kFish)) + aDinah++; + + return (aDinah); +} + +//-------------------------------------------------------------- ShoutNoMoreSpecialObjects + +void ShoutNoMoreSpecialObjects (void) +{ + short hitWhat; + +// CenterAlert(kNoMoreSpecialAlert); + hitWhat = Alert(kNoMoreSpecialAlert, nil); +} + +#endif + diff --git a/GpApp/ObjectDraw.cpp b/GpApp/ObjectDraw.cpp new file mode 100644 index 0000000..4d8d765 --- /dev/null +++ b/GpApp/ObjectDraw.cpp @@ -0,0 +1,1406 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// ObjectDraw.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Environ.h" +#include "Objects.h" +#include "RectUtils.h" +#include "Room.h" + + +#define k8WhiteColor 0 +#define kYellowColor 5 +#define kGoldColor 11 +#define k8RedColor 35 +#define kPaleVioletColor 42 +#define k8LtTanColor 52 +#define k8BambooColor 53 +#define kDarkFleshColor 58 +#define k8TanColor 94 +#define k8PissYellowColor 95 +#define k8OrangeColor 59 +#define k8BrownColor 137 +#define k8Red4Color 143 +#define k8SkyColor 150 +#define k8EarthBlueColor 170 +#define k8DkRedColor 222 +#define k8DkRed2Color 223 +#define kIntenseGreenColor 225 +#define kIntenseBlueColor 235 +#define k8PumpkinColor 101 +#define k8LtstGrayColor 245 +#define k8LtstGray2Color 246 +#define k8LtstGray3Color 43 +#define k8LtstGray4Color 247 +#define k8LtstGray5Color 248 +#define k8LtGrayColor 249 +#define k8GrayColor 250 +#define k8Gray2Color 251 +#define k8DkGrayColor 252 +#define k8DkGray2Color 253 +#define k8DkGray3Color 172 +#define k8DkstGrayColor 254 +#define k8BlackColor 255 + + +void DrawClockDigit (short, Rect *); +void DrawClockHands (Point, short, short); +void DrawLargeClockHands (Point, short, short); + + +//============================================================== Functions +//-------------------------------------------------------------- DrawSimpleBlowers + +void DrawSimpleBlowers (short what, Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), + (BitMap *)*GetGWorldPixMap(blowerMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], &srcRects[what], theRect); +} + +//-------------------------------------------------------------- DrawTiki + +void DrawTiki (Rect *theRect, short down) +{ +#define kTikiPoleBase 300 + long darkGrayC, lightWoodC, darkWoodC; + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + if (thisMac.isDepth == 4) + { + darkGrayC = 14; + lightWoodC = 6; + darkWoodC = 9; + } + else + { + darkGrayC = k8DkstGrayColor; + lightWoodC = k8BambooColor; + darkWoodC = k8PissYellowColor; + } + + if (theRect->bottom < kTikiPoleBase + down) + { + ColorLine(theRect->left + 11, theRect->bottom - 1, + theRect->left + 11, kTikiPoleBase + down - 1, darkGrayC); + ColorLine(theRect->left + 12, theRect->bottom - 1, + theRect->left + 12, kTikiPoleBase + down, lightWoodC); + ColorLine(theRect->left + 13, theRect->bottom - 1, + theRect->left + 13, kTikiPoleBase + down, darkWoodC); + ColorLine(theRect->left + 14, theRect->bottom - 1, + theRect->left + 14, kTikiPoleBase + down, darkWoodC); + ColorLine(theRect->left + 15, theRect->bottom - 1, + theRect->left + 15, kTikiPoleBase + down - 1, darkGrayC); + } + + SetGWorld(wasCPort, wasWorld); + + CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), + (BitMap *)*GetGWorldPixMap(blowerMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kTiki], &srcRects[kTiki], theRect); +} + +//-------------------------------------------------------------- DrawInvisibleBlower + +void DrawInvisibleBlower (Rect *theRect) +{ + Rect tempRect; + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + QSetRect(&tempRect, 0, 0, 24, 24); + QOffsetRect(&tempRect, theRect->left, theRect->top); + + ColorFrameRect(&tempRect, 192); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawLiftArea + +void DrawLiftArea (Rect *theRect) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + ColorFrameRect(theRect, 192); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawTable + +void DrawTable (Rect *tableTop, short down) +{ + #define kTableBaseTop 296 + #define kTableShadowTop 312 + #define kTableShadowOffset 12 + Rect tempRect; + long brownC, tanC, dkRedC, blackC; + short hCenter, vShadow; + CGrafPtr wasCPort; + GDHandle wasWorld; + Pattern dummyPattern; + + if (thisMac.isDepth == 4) + { + brownC = 11; + tanC = 9; + dkRedC = 14; + blackC = 15; + } + else + { + brownC = k8BrownColor; + tanC = k8TanColor; + dkRedC = k8DkRed2Color; + blackC = k8BlackColor; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + QSetRect(&tempRect, tableTop->left, 0, tableTop->right, + RectWide(tableTop) / 10); + QOffsetRect(&tempRect, 0, + -HalfRectTall(&tempRect) + kTableShadowTop + down); + QOffsetRect(&tempRect, kTableShadowOffset, -kTableShadowOffset); + PenPat(GetQDGlobalsGray(&dummyPattern)); + PenMode(patOr); + if (thisMac.isDepth == 4) + ColorOval(&tempRect, 15); + else + ColorOval(&tempRect, k8DkstGrayColor); + PenNormal(); + + InsetRect(tableTop, 0, 1); + ColorRect(tableTop, brownC); + InsetRect(tableTop, 0, -1); + + ColorLine(tableTop->left, tableTop->top + 1, + tableTop->left, tableTop->top + 1, k8WhiteColor); + ColorLine(tableTop->left + 1, tableTop->top, + tableTop->right - 2, tableTop->top, k8WhiteColor); + ColorLine(tableTop->right - 1, tableTop->top + 1, + tableTop->right - 1, tableTop->top + 1, k8WhiteColor); + + ColorLine(tableTop->left + 1, tableTop->top + 1, + tableTop->right - 2, tableTop->top + 1, tanC); + ColorLine(tableTop->left, tableTop->top + 2, + tableTop->left, tableTop->bottom - 2, tanC); + + ColorLine(tableTop->left + 1, tableTop->bottom - 1, + tableTop->right - 2, tableTop->bottom - 1, blackC); + ColorLine(tableTop->right - 1, tableTop->top + 2, + tableTop->right - 1, tableTop->bottom - 2, blackC); + + ColorLine(tableTop->left + 1, tableTop->bottom - 2, + tableTop->right - 2, tableTop->bottom - 2, dkRedC); + + if (tableTop->bottom < kTableBaseTop + down) + { + hCenter = (tableTop->left + tableTop->right) / 2; + + ColorLine(hCenter - 3, tableTop->bottom, + hCenter - 3, kTableBaseTop + down, blackC); + ColorLine(hCenter - 2, tableTop->bottom, + hCenter - 2, kTableBaseTop + down, k8LtGrayColor); + ColorLine(hCenter - 1, tableTop->bottom, + hCenter - 1, kTableBaseTop + down, k8GrayColor); + ColorLine(hCenter, tableTop->bottom, + hCenter, kTableBaseTop + down, k8DkGrayColor); + ColorLine(hCenter + 1, tableTop->bottom, + hCenter + 1, kTableBaseTop + down, blackC); + + vShadow = tableTop->bottom + RectWide(tableTop) / 4 - 2; + if (vShadow > kTableBaseTop + down) + { + ColorLine(hCenter - 2, tableTop->bottom, + hCenter - 2, kTableBaseTop + down, k8DkGrayColor); + ColorLine(hCenter - 1, tableTop->bottom, + hCenter - 1, kTableBaseTop + down, k8DkGrayColor); + ColorLine(hCenter, tableTop->bottom, + hCenter, kTableBaseTop + down, blackC); + } + else + { + ColorLine(hCenter - 2, tableTop->bottom, + hCenter - 2, vShadow, k8DkGrayColor); + ColorLine(hCenter - 1, tableTop->bottom, + hCenter - 1, vShadow + 1, k8DkGrayColor); + ColorLine(hCenter, tableTop->bottom, + hCenter, vShadow + 2, blackC); + } + } + + SetGWorld(wasCPort, wasWorld); + + tempRect = tableSrc; + QOffsetRect(&tempRect, -HalfRectWide(&tableSrc) + tableTop->left + + HalfRectWide(tableTop), kTableBaseTop + down); + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &tableSrc, &tableSrc, &tempRect); +} + +//-------------------------------------------------------------- DrawShelf + +void DrawShelf (Rect *shelfTop) +{ + #define kBracketInset 18 + #define kShelfDeep 4 + #define kBracketThick 5 + #define kShelfShadowOff 12 + Rect tempRect; + long brownC, ltTanC, tanC, dkRedC, blackC; + RgnHandle shadowRgn; + CGrafPtr wasCPort; + GDHandle wasWorld; + Pattern dummyPattern; + + if (thisMac.isDepth == 4) + { + brownC = 11; + ltTanC = 7; + tanC = 9; + dkRedC = 14; + blackC = 15; + } + else + { + brownC = k8BrownColor; + ltTanC = k8LtTanColor; + tanC = k8TanColor; + dkRedC = k8DkRed2Color; + blackC = k8BlackColor; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + MoveTo(shelfTop->left, shelfTop->bottom); + shadowRgn = NewRgn(); + if (shadowRgn == nil) + RedAlert(kErrUnnaccounted); + OpenRgn(); + Line(kShelfShadowOff, kShelfShadowOff); + Line(RectWide(shelfTop) - kShelfDeep, 0); + Line(0, -kShelfThick + 1); + Line(-kShelfShadowOff, -kShelfShadowOff); + LineTo(shelfTop->left, shelfTop->bottom); + CloseRgn(shadowRgn); + PenPat(GetQDGlobalsGray(&dummyPattern)); + PenMode(patOr); + if (thisMac.isDepth == 4) + ColorRegion(shadowRgn, 15); + else + ColorRegion(shadowRgn, k8DkstGrayColor); + PenNormal(); + DisposeRgn(shadowRgn); + + InsetRect(shelfTop, 0, 1); + ColorRect(shelfTop, brownC); + InsetRect(shelfTop, 0, -1); + + ColorLine(shelfTop->left + 1, shelfTop->top, + shelfTop->left + 1 + kShelfDeep, shelfTop->top, ltTanC); + ColorLine(shelfTop->left, shelfTop->top + 1, + shelfTop->left + kShelfDeep, shelfTop->top + 1, tanC); + ColorLine(shelfTop->left, shelfTop->top + 2, + shelfTop->left + kShelfDeep, shelfTop->top + 2, tanC); + ColorLine(shelfTop->left, shelfTop->top + 3, + shelfTop->left + kShelfDeep, shelfTop->top + 3, tanC); + ColorLine(shelfTop->left + 1, shelfTop->bottom - 1, + shelfTop->left + 1 + kShelfDeep, shelfTop->bottom - 1, dkRedC); + ColorLine(shelfTop->left + 2 + kShelfDeep, shelfTop->bottom - 1, + shelfTop->right - 2, shelfTop->bottom - 1, blackC); + ColorLine(shelfTop->left + 2 + kShelfDeep, shelfTop->top, + shelfTop->right - 2, shelfTop->top, tanC); + ColorLine(shelfTop->right - 1, shelfTop->top + 1, + shelfTop->right - 1, shelfTop->bottom - 2, blackC); + + SetGWorld(wasCPort, wasWorld); + + tempRect = shelfSrc; + ZeroRectCorner(&tempRect); + QOffsetRect(&tempRect, shelfTop->left + kBracketInset, shelfTop->bottom); + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &shelfSrc, &shelfSrc, &tempRect); + + ZeroRectCorner(&tempRect); + QOffsetRect(&tempRect, shelfTop->right - kBracketInset - kShelfDeep - + kBracketThick, shelfTop->bottom); + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &shelfSrc, &shelfSrc, &tempRect); +} + +//-------------------------------------------------------------- DrawCabinet + +void DrawCabinet (Rect *cabinet) +{ + #define kCabinetDeep 4 + #define kCabinetShadowOff 6 + Rect tempRect; + long brownC, dkGrayC, ltTanC, tanC, dkRedC, blackC; + RgnHandle shadowRgn; + CGrafPtr wasCPort; + GDHandle wasWorld; + Pattern dummyPattern; + + if (thisMac.isDepth == 4) + { + brownC = 11; + dkGrayC = 14; + ltTanC = 7; + tanC = 9; + dkRedC = 14; + blackC = 15; + } + else + { + brownC = k8BrownColor; + dkGrayC = k8DkstGrayColor; + ltTanC = k8LtTanColor; + tanC = k8TanColor; + dkRedC = k8DkRed2Color; + blackC = k8BlackColor; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + MoveTo(cabinet->left, cabinet->bottom); + shadowRgn = NewRgn(); + if (shadowRgn == nil) + RedAlert(kErrUnnaccounted); + OpenRgn(); + Line(kCabinetShadowOff, kCabinetShadowOff); + Line(RectWide(cabinet), 0); + Line(0, -RectTall(cabinet) + kCabinetDeep); + Line(-kCabinetShadowOff, -kCabinetShadowOff); + LineTo(cabinet->left, cabinet->bottom); + CloseRgn(shadowRgn); + PenPat(GetQDGlobalsGray(&dummyPattern)); + PenMode(patOr); + if (thisMac.isDepth == 4) + ColorRegion(shadowRgn, 15); + else + ColorRegion(shadowRgn, dkGrayC); + PenNormal(); + DisposeRgn(shadowRgn); + + InsetRect(cabinet, 1, 1); // fill bulk of cabinet brown + ColorRect(cabinet, brownC); + InsetRect(cabinet, -1, -1); + + tempRect = *cabinet; // add lighter left side + tempRect.right = tempRect.left + kCabinetDeep; + ColorRect(&tempRect, tanC); + // hilight top edge + ColorLine(cabinet->left + 1, cabinet->top + 1, + cabinet->left + kCabinetDeep, cabinet->top + 1, ltTanC); + ColorLine(cabinet->left + kCabinetDeep, cabinet->top + 1, + cabinet->right - 3, cabinet->top + 1, tanC); + // shadow bottom edge + + ColorLine(cabinet->left + kCabinetDeep + 3, cabinet->top + 5, + cabinet->left + kCabinetDeep + 3, cabinet->bottom - 6, tanC); + ColorLine(cabinet->left + kCabinetDeep + 4, cabinet->top + 5, + cabinet->left + kCabinetDeep + 4, cabinet->bottom - 6, tanC); + ColorLine(cabinet->left + kCabinetDeep + 9, cabinet->top + 10, + cabinet->left + kCabinetDeep + 9, cabinet->bottom - 11, dkGrayC); + + ColorLine(cabinet->right - 4, cabinet->top + 6, + cabinet->right - 4, cabinet->bottom - 5, dkRedC); + ColorLine(cabinet->right - 5, cabinet->top + 5, + cabinet->right - 5, cabinet->bottom - 6, dkGrayC); + ColorLine(cabinet->right - 10, cabinet->top + 10, + cabinet->right - 10, cabinet->bottom - 11, tanC); + + ColorLine(cabinet->left + kCabinetDeep + 4, cabinet->top + 4, + cabinet->left + kCabinetDeep + 4, cabinet->top + 4, ltTanC); + ColorLine(cabinet->left + kCabinetDeep + 5, cabinet->top + 4, + cabinet->right - 6, cabinet->top + 4, tanC); + ColorLine(cabinet->left + kCabinetDeep + 10, cabinet->top + 9, + cabinet->right - 11, cabinet->top + 9, dkGrayC); + + ColorLine(cabinet->right - 5, cabinet->bottom - 5, + cabinet->right - 5, cabinet->bottom - 5, dkRedC); + ColorLine(cabinet->left + kCabinetDeep + 6, cabinet->bottom - 4, + cabinet->right - 5, cabinet->bottom - 4, dkRedC); + ColorLine(cabinet->left + kCabinetDeep + 5, cabinet->bottom - 5, + cabinet->right - 6, cabinet->bottom - 5, dkGrayC); + + ColorLine(cabinet->left + kCabinetDeep + 10, cabinet->bottom - 10, + cabinet->right - 11, cabinet->bottom - 10, tanC); + + SetGWorld(wasCPort, wasWorld); + + tempRect = hingeSrc; + ZeroRectCorner(&tempRect); + QOffsetRect(&tempRect, cabinet->left + kCabinetDeep + 2, cabinet->top + 10); + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &hingeSrc, &hingeSrc, &tempRect); + + tempRect = hingeSrc; + ZeroRectCorner(&tempRect); + QOffsetRect(&tempRect, cabinet->left + kCabinetDeep + 2, cabinet->bottom - 26); + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &hingeSrc, &hingeSrc, &tempRect); + + tempRect = handleSrc; + ZeroRectCorner(&tempRect); + QOffsetRect(&tempRect, cabinet->right - 8, cabinet->top + + HalfRectTall(cabinet) - HalfRectTall(&handleSrc)); + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &handleSrc, &handleSrc, &tempRect); + + FrameRect(cabinet); +} + +//-------------------------------------------------------------- DrawSimpleFurniture + +void DrawSimpleFurniture (short what, Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], &srcRects[what], theRect); +} + +//-------------------------------------------------------------- DrawCounter + +void DrawCounter (Rect *counter) +{ + #define kCounterFooterHigh 12 + #define kCounterStripWide 6 + #define kCounterStripTall 29 + #define kCounterPanelDrop 12 + Rect tempRect; + RgnHandle shadowRgn; + long brownC, dkGrayC, tanC, blackC, dkstRedC; + short nRects, width, i; + CGrafPtr wasCPort; + GDHandle wasWorld; + Pattern dummyPattern; + + if (thisMac.isDepth == 4) + { + brownC = 11; + dkGrayC = 14; + tanC = 9; + blackC = 15; + dkstRedC = 15; + } + else + { + brownC = k8BrownColor; + dkGrayC = k8DkstGrayColor; + tanC = k8TanColor; + blackC = k8BlackColor; + dkstRedC = k8DkRed2Color; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + MoveTo(counter->right - 2, counter->bottom); + shadowRgn = NewRgn(); + if (shadowRgn == nil) + RedAlert(kErrUnnaccounted); + OpenRgn(); + Line(10, -10); + Line(0, -RectTall(counter) + 29); + Line(2, 0); + Line(0, -7); + Line(-12, -12); + LineTo(counter->right - 2, counter->bottom); + CloseRgn(shadowRgn); + PenPat(GetQDGlobalsGray(&dummyPattern)); + PenMode(patOr); + if (thisMac.isDepth == 4) + ColorRegion(shadowRgn, 15); + else + ColorRegion(shadowRgn, dkGrayC); + PenNormal(); + DisposeRgn(shadowRgn); + + InsetRect(counter, 2, 2); + ColorRect(counter, brownC); + InsetRect(counter, -2, -2); + + tempRect = *counter; + tempRect.top = tempRect.bottom - kCounterFooterHigh; + tempRect.left += 2; + tempRect.right -= 2; + ColorRect(&tempRect, dkGrayC); + ColorLine(counter->left + 2, counter->bottom - kCounterFooterHigh, + counter->right - 3, counter->bottom - kCounterFooterHigh, blackC); + ColorLine(counter->left + 2, counter->bottom - kCounterFooterHigh + 1, + counter->right - 3, counter->bottom - kCounterFooterHigh + 1, blackC); + ColorLine(counter->right - 3, counter->bottom - kCounterFooterHigh, + counter->right - 3, counter->bottom - 1, blackC); + ColorLine(counter->left + 2, counter->bottom - kCounterFooterHigh, + counter->left + 2, counter->bottom - 1, k8DkGrayColor); + + ColorLine(counter->right - 2, counter->top, + counter->right - 2, counter->bottom - kCounterFooterHigh - 1, dkstRedC); + ColorLine(counter->left + 1, counter->top + 8, + counter->left + 1, counter->bottom - kCounterFooterHigh - 1, tanC); + + if (thisMac.isDepth == 4) + { + ColorLine(counter->left - 1, counter->top, + counter->right, counter->top, 1); + ColorLine(counter->left - 1, counter->top + 1, + counter->right, counter->top + 1, 2); + ColorLine(counter->left - 1, counter->top + 2, + counter->right, counter->top + 2, 3); + ColorLine(counter->left - 1, counter->top + 3, + counter->right, counter->top + 3, 4); + ColorLine(counter->left - 1, counter->top + 4, + counter->right, counter->top + 4, 5); + ColorLine(counter->left - 1, counter->top + 5, + counter->right, counter->top + 5, 5); + ColorLine(counter->left - 1, counter->top + 6, + counter->right, counter->top + 6, 5); + ColorLine(counter->left - 1, counter->top, + counter->left - 1, counter->top + 6, 1); + } + else + { + ColorLine(counter->left - 1, counter->top, + counter->right, counter->top, k8LtstGrayColor); + ColorLine(counter->left - 1, counter->top + 1, + counter->right, counter->top + 1, k8LtstGray2Color); + ColorLine(counter->left - 1, counter->top + 2, + counter->right, counter->top + 2, k8LtstGray3Color); + ColorLine(counter->left - 1, counter->top + 3, + counter->right, counter->top + 3, k8LtstGray4Color); + ColorLine(counter->left - 1, counter->top + 4, + counter->right, counter->top + 4, k8LtstGray5Color); + ColorLine(counter->left - 1, counter->top + 5, + counter->right, counter->top + 5, k8LtstGray5Color); + ColorLine(counter->left - 1, counter->top + 6, + counter->right, counter->top + 6, k8LtstGray5Color); + ColorLine(counter->left - 1, counter->top, + counter->left - 1, counter->top + 6, k8LtstGrayColor); + } + + ColorLine(counter->right, counter->top, + counter->right, counter->top + 6, k8LtGrayColor); + ColorLine(counter->left + 1, counter->top + 7, + counter->right - 2, counter->top + 7, dkstRedC); + ColorLine(counter->left + 1, counter->top + 8, + counter->right - 2, counter->top + 8, dkstRedC); + + SetGWorld(wasCPort, wasWorld); + + nRects = RectWide(counter) / 40; + if (nRects == 0) + nRects = 1; + width = ((RectWide(counter) - kCounterStripWide) / nRects) - kCounterStripWide; + QSetRect(&tempRect, 0, 0, width, RectTall(counter) - kCounterStripTall); + QOffsetRect(&tempRect, counter->left + kCounterStripWide, + counter->top + kCounterPanelDrop); + for (i = 0; i < nRects; i++) + { + HiliteRect(&tempRect, tanC, dkstRedC); + InsetRect(&tempRect, 4, 4); + HiliteRect(&tempRect, dkstRedC, tanC); + InsetRect(&tempRect, -4, -4); + QOffsetRect(&tempRect, kCounterStripWide + width, 0); + } +} + +//-------------------------------------------------------------- DrawDresser + +void DrawDresser (Rect *dresser) +{ + #define kDresserTopThick 4 + #define kDresserCrease 9 + #define kDresserDrawerDrop 12 + #define kDresserSideSpare 14 + Rect tempRect, dest; + long yellowC, brownC, dkGrayC, ltTanC, dkstRedC; + RgnHandle shadowRgn; + short nRects, height, i; + CGrafPtr wasCPort; + GDHandle wasWorld; + Pattern dummyPattern; + + if (thisMac.isDepth == 4) + { + yellowC = 9; + brownC = 11; + dkGrayC = 14; + ltTanC = 7; + dkstRedC = 15; + } + else + { + yellowC = k8PissYellowColor; + brownC = k8BrownColor; + dkGrayC = k8DkstGrayColor; + ltTanC = k8LtTanColor; + dkstRedC = k8DkRed2Color; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + MoveTo(dresser->left + 10, dresser->bottom + 9); + shadowRgn = NewRgn(); + if (shadowRgn == nil) + RedAlert(kErrUnnaccounted); + OpenRgn(); + Line(RectWide(dresser) - 11, 0); + Line(9, -9); + Line(0, -RectTall(dresser) + 12); + Line(-9, -9); + Line(-RectWide(dresser) + 11, 0); + LineTo(dresser->left + 10, dresser->bottom + 9); + CloseRgn(shadowRgn); + PenPat(GetQDGlobalsGray(&dummyPattern)); + PenMode(patOr); + if (thisMac.isDepth == 4) + ColorRegion(shadowRgn, 15); + else + ColorRegion(shadowRgn, k8DkstGrayColor); + PenNormal(); + DisposeRgn(shadowRgn); + + InsetRect(dresser, 2, 2); + ColorRect(dresser, k8PumpkinColor); + HiliteRect(dresser, k8OrangeColor, dkstRedC); + InsetRect(dresser, -2, -2); + + tempRect = *dresser; + tempRect.bottom = tempRect.top + kDresserTopThick; + ColorRect(&tempRect, k8PissYellowColor); + HiliteRect(&tempRect, ltTanC, dkstRedC); + ColorLine(dresser->left + 2, dresser->top + kDresserTopThick, + dresser->right - 3, dresser->top + kDresserTopThick, k8Red4Color); + + ColorLine(dresser->left + kDresserCrease, dresser->top + kDresserTopThick + 1, + dresser->left + kDresserCrease, dresser->bottom - 4, k8Red4Color); + ColorLine(dresser->right - kDresserCrease, dresser->top + kDresserTopThick + 1, + dresser->right - kDresserCrease, dresser->bottom - 4, k8OrangeColor); + + nRects = RectTall(dresser) / 30; + if (nRects == 0) + nRects = 1; + height = (RectTall(dresser) - 14) / nRects - 4; + QSetRect(&tempRect, 0, 0, RectWide(dresser) - kDresserSideSpare, height); + QOffsetRect(&tempRect, dresser->left + 7, dresser->top + 10); + for (i = 0; i < nRects; i++) + { + ColorLine(tempRect.left + 1, tempRect.bottom, + tempRect.right, tempRect.bottom, dkstRedC); + ColorLine(tempRect.right, tempRect.top + 1, + tempRect.right, tempRect.bottom, dkstRedC); + ColorRect(&tempRect, yellowC); + HiliteRect(&tempRect, ltTanC, brownC); + InsetRect(&tempRect, 1, 1); + HiliteRect(&tempRect, ltTanC, brownC); + InsetRect(&tempRect, -1, -1); + + QSetRect(&dest, -4, -4, 4, 4); + QOffsetRect(&dest, HalfRectTall(&tempRect), HalfRectTall(&tempRect)); + QOffsetRect(&dest, tempRect.left, tempRect.top); + CopyBits((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &knobSrc, &dest, srcCopy, nil); + + QSetRect(&dest, -4, -4, 4, 4); + QOffsetRect(&dest, -HalfRectTall(&tempRect), HalfRectTall(&tempRect)); + QOffsetRect(&dest, tempRect.right, tempRect.top); + CopyBits((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &knobSrc, &dest, srcCopy, nil); + + QOffsetRect(&tempRect, 0, kDresserTopThick + height); + } + + SetGWorld(wasCPort, wasWorld); + + dest = leftFootSrc; + ZeroRectCorner(&dest); + QOffsetRect(&dest, dresser->left + 6, dresser->bottom - 2); + + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &leftFootSrc, &leftFootSrc, &dest); + + dest = rightFootSrc; + ZeroRectCorner(&dest); + QOffsetRect(&dest, dresser->right - 19, dresser->bottom - 2); + + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &rightFootSrc, &rightFootSrc, &dest); +} + +//-------------------------------------------------------------- DrawDeckTable + +void DrawDeckTable (Rect *tableTop, short down) +{ + #define kTableBaseTop 296 + #define kTableShadowTop 312 + #define kTableShadowOffset 12 + + Rect tempRect; + long bambooC, brownC, dkGrayC; + short hCenter, vShadow; + CGrafPtr wasCPort; + GDHandle wasWorld; + Pattern dummyPattern; + + if (thisMac.isDepth == 4) + { + bambooC = 6; + brownC = 11; + dkGrayC = 14; + } + else + { + bambooC = k8BambooColor; + brownC = k8BrownColor; + dkGrayC = k8DkstGrayColor; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + QSetRect(&tempRect, tableTop->left, 0, tableTop->right, + RectWide(tableTop) / 10); + QOffsetRect(&tempRect, 0, + -HalfRectTall(&tempRect) + kTableShadowTop + down); + QOffsetRect(&tempRect, kTableShadowOffset, -kTableShadowOffset); + PenPat(GetQDGlobalsGray(&dummyPattern)); + PenMode(patOr); + ColorOval(&tempRect, dkGrayC); + PenNormal(); + + InsetRect(tableTop, 0, 1); + ColorRect(tableTop, kGoldColor); + InsetRect(tableTop, 0, -1); + + ColorLine(tableTop->left, tableTop->top + 1, + tableTop->left, tableTop->top + 1, k8WhiteColor); + ColorLine(tableTop->left + 1, tableTop->top, + tableTop->right - 2, tableTop->top, k8WhiteColor); + ColorLine(tableTop->right - 1, tableTop->top + 1, + tableTop->right - 1, tableTop->top + 1, k8WhiteColor); + + ColorLine(tableTop->left + 1, tableTop->top + 1, + tableTop->right - 2, tableTop->top + 1, kYellowColor); + ColorLine(tableTop->left, tableTop->top + 2, + tableTop->left, tableTop->bottom - 2, kYellowColor); + + ColorLine(tableTop->left + 1, tableTop->bottom - 1, + tableTop->right - 2, tableTop->bottom - 1, brownC); + ColorLine(tableTop->right - 1, tableTop->top + 2, + tableTop->right - 1, tableTop->bottom - 2, brownC); + + ColorLine(tableTop->left + 1, tableTop->bottom - 2, + tableTop->right - 2, tableTop->bottom - 2, bambooC); + + if (tableTop->bottom < kTableBaseTop + down) + { + hCenter = (tableTop->left + tableTop->right) / 2; + + ColorLine(hCenter - 3, tableTop->bottom, + hCenter - 3, kTableBaseTop + down, dkGrayC); + ColorLine(hCenter - 2, tableTop->bottom, + hCenter - 2, kTableBaseTop + down, k8WhiteColor); + ColorLine(hCenter - 1, tableTop->bottom, + hCenter - 1, kTableBaseTop + down, k8WhiteColor); + ColorLine(hCenter, tableTop->bottom, + hCenter, kTableBaseTop + down, k8LtGrayColor); + ColorLine(hCenter + 1, tableTop->bottom, + hCenter + 1, kTableBaseTop + down, dkGrayC); + + vShadow = tableTop->bottom + RectWide(tableTop) / 4 - 2; + if (vShadow > kTableBaseTop + down) + { + ColorLine(hCenter - 2, tableTop->bottom, + hCenter - 2, kTableBaseTop + down, k8LtGrayColor); + ColorLine(hCenter - 1, tableTop->bottom, + hCenter - 1, kTableBaseTop + down, k8LtGrayColor); + ColorLine(hCenter, tableTop->bottom, + hCenter, kTableBaseTop + down, dkGrayC); + } + else + { + ColorLine(hCenter - 2, tableTop->bottom, + hCenter - 2, vShadow, k8LtGrayColor); + ColorLine(hCenter - 1, tableTop->bottom, + hCenter - 1, vShadow + 1, k8LtGrayColor); + ColorLine(hCenter, tableTop->bottom, + hCenter, vShadow + 2, dkGrayC); + } + } + + SetGWorld(wasCPort, wasWorld); + + tempRect = deckSrc; + ZeroRectCorner(&tempRect); + QOffsetRect(&tempRect, -HalfRectWide(&deckSrc) + tableTop->left + + HalfRectWide(tableTop), kTableBaseTop + down); + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &deckSrc, &deckSrc, &tempRect); +} + +//-------------------------------------------------------------- DrawStool + +void DrawStool (Rect *theRect, short down) +{ + #define kStoolBase 304 + long grayC, dkGrayC; + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + if (thisMac.isDepth == 4) + { + grayC = 13; + dkGrayC = 14; + } + else + { + grayC = k8DkGray2Color; + dkGrayC = k8DkstGrayColor; + } + + if (theRect->bottom < kStoolBase + down) + { + ColorLine(theRect->left + 21, theRect->bottom - 1, + theRect->left + 21, kStoolBase + down - 1, k8DkGrayColor); + ColorLine(theRect->left + 22, theRect->bottom - 1, + theRect->left + 22, kStoolBase + down, k8Gray2Color); + ColorLine(theRect->left + 23, theRect->bottom - 1, + theRect->left + 23, kStoolBase + down, k8DkGrayColor); + ColorLine(theRect->left + 24, theRect->bottom - 1, + theRect->left + 24, kStoolBase + down, k8DkGray3Color); + ColorLine(theRect->left + 25, theRect->bottom - 1, + theRect->left + 25, kStoolBase + down, grayC); + ColorLine(theRect->left + 26, theRect->bottom - 1, + theRect->left + 26, kStoolBase + down - 1, dkGrayC); + } + + SetGWorld(wasCPort, wasWorld); + + CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), + (BitMap *)*GetGWorldPixMap(furnitureMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kStool], &srcRects[kStool], theRect); +} + +//-------------------------------------------------------------- DrawInvisObstacle + +void DrawInvisObstacle (Rect *theRect) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + ColorFrameRect(theRect, k8BrownColor); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawInvisBounce + +void DrawInvisBounce (Rect *theRect) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + ColorFrameRect(theRect, k8RedColor); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawRedClock + +void DrawRedClock (Rect *theRect) +{ + DateTimeRec timeRec; + Rect dest; + short hour, minutes; + + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kRedClock], &srcRects[kRedClock], theRect); + + GetTime(&timeRec); + hour = timeRec.hour % 12; + if (hour == 0) + hour = 12; + minutes = timeRec.minute; + + QSetRect(&dest, 0, 0, 4, 6); + QOffsetRect(&dest, theRect->left + 5, theRect->top + 7); + if (hour > 9) + DrawClockDigit(hour / 10, &dest); + QOffsetRect(&dest, 4, 0); + DrawClockDigit(hour % 10, &dest); + QOffsetRect(&dest, 6, 0); + DrawClockDigit(minutes / 10, &dest); + QOffsetRect(&dest, 4, 0); + DrawClockDigit(minutes % 10, &dest); +} + +//-------------------------------------------------------------- DrawClockDigit + +void DrawClockDigit (short number, Rect *dest) +{ + CopyBits((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &digits[number], dest, srcCopy, nil); +} + +//-------------------------------------------------------------- DrawBlueClock + +void DrawBlueClock (Rect *theRect) +{ + DateTimeRec timeRec; + Point dest; + short hour, minutes; + + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kBlueClock], &srcRects[kBlueClock], theRect); + + dest.h = theRect->left + 13; + dest.v = theRect->top + 13; + GetTime(&timeRec); + hour = timeRec.hour % 12; + minutes = ((timeRec.minute + 2) / 5) % 12; + DrawClockHands(dest, minutes, hour); +} + +//-------------------------------------------------------------- DrawYellowClock + +void DrawYellowClock (Rect *theRect) +{ + DateTimeRec timeRec; + Point dest; + short hour, minutes; + + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kYellowClock], &srcRects[kYellowClock], theRect); + + dest.h = theRect->left + 13; + dest.v = theRect->top + 15; + GetTime(&timeRec); + hour = timeRec.hour % 12; + minutes = ((timeRec.minute + 2) / 5) % 12; + DrawClockHands(dest, minutes, hour); +} + +//-------------------------------------------------------------- DrawCuckoo + +void DrawCuckoo (Rect *theRect) +{ + DateTimeRec timeRec; + Point dest; + short hour, minutes; + + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kCuckoo], &srcRects[kCuckoo], theRect); + + dest.h = theRect->left + 19; + dest.v = theRect->top + 31; + GetTime(&timeRec); + hour = timeRec.hour % 12; + minutes = ((timeRec.minute + 2) / 5) % 12; + DrawLargeClockHands(dest, minutes, hour); +} + +//-------------------------------------------------------------- DrawClockHands + +void DrawClockHands (Point where, short bigHand, short littleHand) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + MoveTo(where.h, where.v); + switch (bigHand) + { + case 0: + Line(0, -6); + break; + + case 1: + Line(3, -5); + break; + + case 2: + Line(5, -3); + break; + + case 3: + Line(6, 0); + break; + + case 4: + Line(5, 3); + break; + + case 5: + Line(3, 5); + break; + + case 6: + Line(0, 6); + break; + + case 7: + Line(-3, 5); + break; + + case 8: + Line(-5, 3); + break; + + case 9: + Line(-6, 0); + break; + + case 10: + Line(-5, -3); + break; + + case 11: + Line(-3, -5); + break; + } + + MoveTo(where.h, where.v); + switch (littleHand) + { + case 0: + Line(0, -4); + break; + + case 1: + Line(2, -3); + break; + + case 2: + Line(3, -2); + break; + + case 3: + Line(4, 0); + break; + + case 4: + Line(3, 2); + break; + + case 5: + Line(2, 3); + break; + + case 6: + Line(0, 4); + break; + + case 7: + Line(-2, 3); + break; + + case 8: + Line(-3, 2); + break; + + case 9: + Line(-4, 0); + break; + + case 10: + Line(-3, -2); + break; + + case 11: + Line(-2, -3); + break; + } + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawClockHands + +void DrawLargeClockHands (Point where, short bigHand, short littleHand) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + ForeColor(whiteColor); + + MoveTo(where.h, where.v); + switch (bigHand) + { + case 0: + Line(0, -10); + break; + + case 1: + Line(5, -9); + break; + + case 2: + Line(9, -5); + break; + + case 3: + Line(10, 0); + break; + + case 4: + Line(9, 5); + break; + + case 5: + Line(5, 9); + break; + + case 6: + Line(0, 10); + break; + + case 7: + Line(-5, 9); + break; + + case 8: + Line(-9, 5); + break; + + case 9: + Line(-10, 0); + break; + + case 10: + Line(-9, -5); + break; + + case 11: + Line(-5, -9); + break; + } + + MoveTo(where.h, where.v); + switch (littleHand) + { + case 0: + Line(0, -6); + break; + + case 1: + Line(3, -5); + break; + + case 2: + Line(5, -3); + break; + + case 3: + Line(6, 0); + break; + + case 4: + Line(5, 3); + break; + + case 5: + Line(3, 5); + break; + + case 6: + Line(0, 6); + break; + + case 7: + Line(-3, 5); + break; + + case 8: + Line(-5, 3); + break; + + case 9: + Line(-6, 0); + break; + + case 10: + Line(-5, -3); + break; + + case 11: + Line(-3, -5); + break; + } + + ForeColor(blackColor); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawSimplePrizes + +void DrawSimplePrizes (short what, Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], &srcRects[what], theRect); +} + +//-------------------------------------------------------------- DrawGreaseRt + +void DrawGreaseRt (Rect *theRect, short distance, Boolean state) +{ + Rect spill, dest; + CGrafPtr wasCPort; + GDHandle wasWorld; + + dest = *theRect; + if (state) // grease upright + { + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &greaseSrcRt[0], &greaseSrcRt[0], &dest); + } + else // grease spilled + { + QOffsetRect(&dest, 6, 0); + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &greaseSrcRt[3], &greaseSrcRt[3], &dest); + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + QSetRect(&spill, 0, -2, distance - 5, 0); + QOffsetRect(&spill, dest.right - 1, dest.bottom); + PaintRect(&spill); + SetGWorld(wasCPort, wasWorld); + } +} + +//-------------------------------------------------------------- DrawGreaseLf + +void DrawGreaseLf (Rect *theRect, short distance, Boolean state) +{ + Rect spill, dest; + CGrafPtr wasCPort; + GDHandle wasWorld; + + dest = *theRect; + if (state) // grease upright + { + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &greaseSrcLf[0], &greaseSrcLf[0], &dest); + } + else // grease spilled + { + QOffsetRect(&dest, -6, 0); + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &greaseSrcLf[3], &greaseSrcLf[3], &dest); + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + QSetRect(&spill, -distance + 5, -2, 0, 0); + QOffsetRect(&spill, dest.left + 1, dest.bottom); + PaintRect(&spill); + SetGWorld(wasCPort, wasWorld); + } +} + +//-------------------------------------------------------------- DrawBands + +void DrawFoil (Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), + (BitMap *)*GetGWorldPixMap(bonusMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kFoil], &srcRects[kFoil], theRect); +} + +//-------------------------------------------------------------- DrawInvisBonus + +void DrawInvisBonus (Rect *theRect) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + ColorFrameOval(theRect, 227); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawSlider + +void DrawSlider (Rect *theRect) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + FrameRect(theRect); + SetGWorld(wasCPort, wasWorld); +} + diff --git a/GpApp/ObjectDraw2.cpp b/GpApp/ObjectDraw2.cpp new file mode 100644 index 0000000..f03ebd8 --- /dev/null +++ b/GpApp/ObjectDraw2.cpp @@ -0,0 +1,1438 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// ObjectDraw2.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLResources.h" +#include "PLTextUtils.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "Objects.h" +#include "RectUtils.h" +#include "Room.h" +#include "Utilities.h" + + +#define k8WhiteColor 0 +#define kIntenseYellowColor 5 +#define kPaleVioletColor 42 +#define kDarkFleshColor 58 +#define k8TanColor 94 +#define k8PissYellowColor 95 +#define k8BrownColor 137 +#define k8SkyColor 150 +#define k8EarthBlueColor 170 +#define k8DkRed2Color 223 +#define kIntenseGreenColor 225 +#define kIntenseBlueColor 235 +#define k8LtstGrayColor 245 +#define k8LtstGray4Color 247 +#define k8LtstGray5Color 248 +#define k8LtGrayColor 249 +#define k8Gray2Color 251 +#define k8DkGrayColor 252 +#define k8DkGray2Color 253 + +#define kBBQMaskID 3900 +#define kUpStairsMaskID 3901 +#define kTrunkMaskID 3902 +#define kMailboxRightMaskID 3903 +#define kMailboxLeftMaskID 3904 +#define kDoorInLeftMaskID 3905 +#define kDoorInRightMaskID 3906 +#define kWindowInLeftMaskID 3907 +#define kWindowInRightMaskID 3908 +#define kHipLampMaskID 3909 +#define kDecoLampMaskID 3910 +#define kGuitarMaskID 3911 +#define kTVMaskID 3912 +#define kVCRMaskID 3913 +#define kStereoMaskID 3914 +#define kMicrowaveMaskID 3915 +#define kFireplaceMaskID 3916 +#define kBearMaskID 3917 +#define kVase1MaskID 3918 +#define kVase2MaskID 3919 +#define kManholeMaskID 3920 +#define kBooksMaskID 3922 +#define kCloudMaskID 3921 +#define kRugMaskID 3923 +#define kChimesMaskID 3924 +#define kCinderMaskID 3925 +#define kFlowerBoxMaskID 3926 +#define kCobwebMaskID 3927 +#define kCobwebPictID 3958 +#define kFlowerBoxPictID 3959 +#define kCinderPictID 3960 +#define kChimesPictID 3961 +#define kRugPictID 3962 +#define kBooksPictID 3964 +#define kCloudPictID 3965 +#define kBulletinPictID 3966 +#define kManholePictID 3967 +#define kVase2PictID 3968 +#define kVase1PictID 3969 +#define kCalendarPictID 3970 +#define kMicrowavePictID 3971 +#define kBearPictID 3972 +#define kFireplacePictID 3973 +#define kOzmaPictID 3975 +#define kWindowExRightPictID 3977 +#define kWindowExLeftPictID 3978 +#define kWindowInRightPictID 3979 +#define kWindowInLeftPictID 3980 +#define kDoorExLeftPictID 3981 +#define kDoorExRightPictID 3982 +#define kDoorInRightPictID 3983 +#define kDoorInLeftPictID 3984 +#define kMailboxRightPictID 3985 +#define kMailboxLeftPictID 3986 +#define kTrunkPictID 3987 +#define kBBQPictID 3988 +#define kStereoPictID 3989 +#define kVCRPictID 3990 +#define kGuitarPictID 3991 +#define kTVPictID 3992 +#define kDecoLampPictID 3993 +#define kHipLampPictID 3994 +#define kFilingCabinetPictID 3995 +#define kDownStairsPictID 3996 +#define kUpStairsPictID 3997 + +#define kMailboxBase 296 +#define kMonthStringID 1005 + + +//============================================================== Functions +//-------------------------------------------------------------- DrawMailboxLeft + +void DrawMailboxLeft (Rect *theRect, short down) +{ + Rect bounds; + GWorldPtr tempMap; + GWorldPtr tempMask; + long darkGrayC, lightWoodC, darkWoodC; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + if (thisMac.isDepth == 4) + { + darkGrayC = 13; + lightWoodC = 9; + darkWoodC = 11; + } + else + { + darkGrayC = k8DkGray2Color; + lightWoodC = k8PissYellowColor; + darkWoodC = k8BrownColor; + } + + if (theRect->bottom < down + kMailboxBase) + { + ColorLine(theRect->left + 49, theRect->bottom, + theRect->left + 49, down + kMailboxBase, darkGrayC); + ColorLine(theRect->left + 50, theRect->bottom, + theRect->left + 50, down + kMailboxBase + 1, lightWoodC); + ColorLine(theRect->left + 51, theRect->bottom, + theRect->left + 51, down + kMailboxBase + 2, lightWoodC); + ColorLine(theRect->left + 52, theRect->bottom, + theRect->left + 52, down + kMailboxBase + 3, lightWoodC); + ColorLine(theRect->left + 53, theRect->bottom, + theRect->left + 53, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 54, theRect->bottom, + theRect->left + 54, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 55, theRect->bottom, + theRect->left + 55, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 56, theRect->bottom, + theRect->left + 56, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 57, theRect->bottom, + theRect->left + 57, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 58, theRect->bottom, + theRect->left + 58, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 59, theRect->bottom, + theRect->left + 59, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 60, theRect->bottom, + theRect->left + 60, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 61, theRect->bottom, + theRect->left + 61, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 62, theRect->bottom, + theRect->left + 62, down + kMailboxBase + 3, darkGrayC); + } + + SetGWorld(wasCPort, wasWorld); + + bounds = srcRects[kMailboxLf]; + theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(kMailboxLeftPictID); + + theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); + SetGWorld(tempMask, nil); + LoadGraphic(kMailboxLeftMaskID); + + CopyMask((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(tempMask), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kMailboxLf], &srcRects[kMailboxLf], theRect); + + SetGWorld(wasCPort, wasWorld); + + DisposeGWorld(tempMap); + DisposeGWorld(tempMask); +// SetPort((GrafPtr)backSrcMap); +} + +//-------------------------------------------------------------- DrawMailboxRight + +void DrawMailboxRight (Rect *theRect, short down) +{ + Rect bounds; + GWorldPtr tempMap; + GWorldPtr tempMask; + long darkGrayC, lightWoodC, darkWoodC; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + if (thisMac.isDepth == 4) + { + darkGrayC = 13; + lightWoodC = 9; + darkWoodC = 11; + } + else + { + darkGrayC = k8DkGray2Color; + lightWoodC = k8PissYellowColor; + darkWoodC = k8BrownColor; + } + + if (theRect->bottom < down + kMailboxBase) + { + ColorLine(theRect->left + 34, theRect->bottom, + theRect->left + 34, down + kMailboxBase, darkGrayC); + ColorLine(theRect->left + 35, theRect->bottom, + theRect->left + 35, down + kMailboxBase + 1, lightWoodC); + ColorLine(theRect->left + 36, theRect->bottom, + theRect->left + 36, down + kMailboxBase + 2, lightWoodC); + ColorLine(theRect->left + 37, theRect->bottom, + theRect->left + 37, down + kMailboxBase + 3, lightWoodC); + ColorLine(theRect->left + 38, theRect->bottom, + theRect->left + 38, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 39, theRect->bottom, + theRect->left + 39, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 40, theRect->bottom, + theRect->left + 40, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 41, theRect->bottom, + theRect->left + 41, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 42, theRect->bottom, + theRect->left + 42, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 43, theRect->bottom, + theRect->left + 43, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 44, theRect->bottom, + theRect->left + 44, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 45, theRect->bottom, + theRect->left + 45, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 46, theRect->bottom, + theRect->left + 46, down + kMailboxBase + 3, darkWoodC); + ColorLine(theRect->left + 47, theRect->bottom, + theRect->left + 47, down + kMailboxBase + 3, darkGrayC); + } + + SetGWorld(wasCPort, wasWorld); + + bounds = srcRects[kMailboxRt]; + theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(kMailboxRightPictID); + + theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); + SetGWorld(tempMask, nil); + LoadGraphic(kMailboxRightMaskID); + + CopyMask((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(tempMask), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kMailboxRt], &srcRects[kMailboxRt], theRect); + + SetGWorld(wasCPort, wasWorld); + + DisposeGWorld(tempMap); + DisposeGWorld(tempMask); +// SetPort((GrafPtr)backSrcMap); +} + +//-------------------------------------------------------------- DrawSimpleTransport + +void DrawSimpleTransport (short what, Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(transSrcMap), + (BitMap *)*GetGWorldPixMap(transMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], &srcRects[what], theRect); +} + +//-------------------------------------------------------------- DrawInvisTransport + +void DrawInvisTransport (Rect *theRect) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + ColorFrameRect(theRect, 32); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawLightSwitch + +void DrawLightSwitch (Rect *theRect, Boolean state) +{ + if (state) + { + CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &lightSwitchSrc[0], theRect, srcCopy, nil); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &lightSwitchSrc[1], theRect, srcCopy, nil); + } +} + +//-------------------------------------------------------------- DrawMachineSwitch + +void DrawMachineSwitch (Rect *theRect, Boolean state) +{ + if (state) + CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &machineSwitchSrc[0], theRect, srcCopy, nil); + else + CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &machineSwitchSrc[1], theRect, srcCopy, nil); +} + +//-------------------------------------------------------------- DrawThermostat + +void DrawThermostat (Rect *theRect, Boolean state) +{ + if (state) + CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &thermostatSrc[0], theRect, srcCopy, nil); + else + CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &thermostatSrc[1], theRect, srcCopy, nil); +} + +//-------------------------------------------------------------- DrawPowerSwitch + +void DrawPowerSwitch (Rect *theRect, Boolean state) +{ + if (state) + CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &powerSrc[0], theRect, srcCopy, nil); + else + CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &powerSrc[1], theRect, srcCopy, nil); +} + +//-------------------------------------------------------------- DrawKnifeSwitch + +void DrawKnifeSwitch (Rect *theRect, Boolean state) +{ + if (state) + CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &knifeSwitchSrc[0], theRect, srcCopy, nil); + else + CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &knifeSwitchSrc[1], theRect, srcCopy, nil); +} + +//-------------------------------------------------------------- DrawInvisibleSwitch + +void DrawInvisibleSwitch (Rect *theRect) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + ColorFrameRect(theRect, kIntenseGreenColor); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawTrigger + +void DrawTrigger (Rect *theRect) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + ColorFrameRect(theRect, kIntenseBlueColor); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawSoundTrigger + +void DrawSoundTrigger (Rect *theRect) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + ColorFrameRect(theRect, kIntenseYellowColor); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawSimpleLight + +void DrawSimpleLight (short what, Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), + (BitMap *)*GetGWorldPixMap(lightMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], &srcRects[what], theRect); +} + +//-------------------------------------------------------------- DrawFlourescent + +void DrawFlourescent (Rect *theRect) +{ + Rect partRect; + long grayC, gray2C, gray3C, gray4C, violetC; + CGrafPtr wasCPort; + GDHandle wasWorld; + + if (thisMac.isDepth == 4) + { + grayC = 7L; + gray2C = 5L; + gray3C = 4L; + gray4C = 1L; + violetC = 3L; + } + else + { + grayC = k8LtGrayColor; + gray2C = k8LtstGray5Color; + gray3C = k8LtstGray4Color; + gray4C = k8LtstGrayColor; + violetC = kPaleVioletColor; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + ColorLine(theRect->left + 16, theRect->top, + theRect->right - 17, theRect->top, grayC); + ColorLine(theRect->left + 16, theRect->top + 1, + theRect->right - 17, theRect->top + 1, gray2C); + ColorLine(theRect->left + 16, theRect->top + 2, + theRect->right - 17, theRect->top + 2, gray2C); + ColorLine(theRect->left + 16, theRect->top + 3, + theRect->right - 17, theRect->top + 3, gray3C); + ColorLine(theRect->left + 16, theRect->top + 4, + theRect->right - 17, theRect->top + 4, gray4C); + ColorLine(theRect->left + 16, theRect->top + 5, + theRect->right - 17, theRect->top + 5, violetC); + ColorLine(theRect->left + 16, theRect->top + 6, + theRect->right - 17, theRect->top + 6, k8WhiteColor); + ColorLine(theRect->left + 16, theRect->top + 7, + theRect->right - 17, theRect->top + 7, k8WhiteColor); + ColorLine(theRect->left + 16, theRect->top + 8, + theRect->right - 17, theRect->top + 8, k8WhiteColor); + ColorLine(theRect->left + 16, theRect->top + 9, + theRect->right - 17, theRect->top + 9, k8WhiteColor); + ColorLine(theRect->left + 16, theRect->top + 10, + theRect->right - 17, theRect->top + 10, k8WhiteColor); + ColorLine(theRect->left + 16, theRect->top + 11, + theRect->right - 17, theRect->top + 11, violetC); + + SetGWorld(wasCPort, wasWorld); + + partRect = flourescentSrc1; + ZeroRectCorner(&partRect); + QOffsetRect(&partRect, theRect->left, theRect->top); + + CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), + (BitMap *)*GetGWorldPixMap(lightMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &flourescentSrc1, &flourescentSrc1, &partRect); + + partRect = flourescentSrc2; + ZeroRectCorner(&partRect); + QOffsetRect(&partRect, -partRect.right, 0); + QOffsetRect(&partRect, theRect->right, theRect->top); + + CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), + (BitMap *)*GetGWorldPixMap(lightMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &flourescentSrc2, &flourescentSrc2, &partRect); +} + +//-------------------------------------------------------------- DrawTrackLight + +void DrawTrackLight (Rect *theRect) +{ + #define kTrackLightSpacing 64 + Rect partRect; + long grayC, gray2C, gray3C, gray4C; + short which, howMany, i, spread; + CGrafPtr wasCPort; + GDHandle wasWorld; + + if (thisMac.isDepth == 4) + { + grayC = 7L; + gray2C = 8L; + gray3C = 4L; + gray4C = 11L; + } + else + { + grayC = k8LtGrayColor; + gray2C = k8Gray2Color; + gray3C = k8LtstGray4Color; + gray4C = k8DkGrayColor; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + ColorLine(theRect->left, theRect->top - 3, + theRect->right - 1, theRect->top - 3, gray2C); + ColorLine(theRect->left, theRect->top - 2, + theRect->right - 1, theRect->top - 2, grayC); + ColorLine(theRect->left, theRect->top - 1, + theRect->right - 1, theRect->top - 1, grayC); + ColorLine(theRect->left, theRect->top, + theRect->right - 1, theRect->top, gray3C); + ColorLine(theRect->left, theRect->top + 1, + theRect->right - 1, theRect->top + 1, gray4C); + ColorLine(theRect->left, theRect->top + 2, + theRect->right - 1, theRect->top + 2, gray3C); + + SetGWorld(wasCPort, wasWorld); + + partRect = trackLightSrc[0]; // left most track light + ZeroRectCorner(&partRect); + QOffsetRect(&partRect, theRect->left, theRect->top); + which = 0; + CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), + (BitMap *)*GetGWorldPixMap(lightMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &trackLightSrc[which], &trackLightSrc[which], &partRect); + + partRect = trackLightSrc[0]; // right most track light + ZeroRectCorner(&partRect); + QOffsetRect(&partRect, -partRect.right, 0); + QOffsetRect(&partRect, theRect->right, theRect->top); + which = 2; + CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), + (BitMap *)*GetGWorldPixMap(lightMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &trackLightSrc[which], &trackLightSrc[which], &partRect); + + howMany = ((RectWide(theRect) - RectWide(&trackLightSrc[0])) / + kTrackLightSpacing) - 1; + if (howMany > 0) + { + which = 0; + spread = (RectWide(theRect) - RectWide(&trackLightSrc[0])) / (howMany + 1); + for (i = 0; i < howMany; i++) + { + partRect = trackLightSrc[0]; // filler track lights + ZeroRectCorner(&partRect); + QOffsetRect(&partRect, theRect->left, theRect->top); + QOffsetRect(&partRect, spread * (i + 1), 0); + which++; + if (which >= kNumTrackLights) + which = 0; + CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), + (BitMap *)*GetGWorldPixMap(lightMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &trackLightSrc[which], &trackLightSrc[which], &partRect); + } + } +} + +//-------------------------------------------------------------- DrawInvisLight + +void DrawInvisLight (Rect *theRect) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + ColorFrameOval(theRect, 17); + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawSimpleAppliance + +void DrawSimpleAppliance (short what, Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(applianceMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], &srcRects[what], theRect); +} + +//-------------------------------------------------------------- DrawMacPlus + +void DrawMacPlus (Rect *theRect, Boolean isOn, Boolean isLit) +{ + Rect screen; + + if (isLit) + { + CopyMask((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(applianceMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kMacPlus], &srcRects[kMacPlus], theRect); + } + + screen = plusScreen1; + ZeroRectCorner(&screen); + QOffsetRect(&screen, theRect->left + 10, theRect->top + 7); + if (isOn) + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &plusScreen2, &screen, srcCopy, nil); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &plusScreen1, &screen, srcCopy, nil); + } +} + +//-------------------------------------------------------------- DrawTV + +void DrawTV (Rect *theRect, Boolean isOn, Boolean isLit) +{ + Rect bounds; + GWorldPtr tempMap; + GWorldPtr tempMask; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + if (isLit) + { + GetGWorld(&wasCPort, &wasWorld); + + bounds = srcRects[kTV]; + theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(kTVPictID); + + theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); + SetGWorld(tempMask, nil); + LoadGraphic(kTVMaskID); + + CopyMask((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(tempMask), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kTV], &srcRects[kTV], theRect); + + SetGWorld(wasCPort, wasWorld); + + DisposeGWorld(tempMap); + DisposeGWorld(tempMask); +// SetPort((GrafPtr)backSrcMap); + } + + bounds = tvScreen1; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, theRect->left + 17, theRect->top + 10); + if (isOn) + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &tvScreen2, &bounds, srcCopy, nil); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &tvScreen1, &bounds, srcCopy, nil); + } +} + +//-------------------------------------------------------------- DrawCoffee + +void DrawCoffee (Rect *theRect, Boolean isOn, Boolean isLit) +{ + Rect light; + + if (isLit) + { + CopyMask((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(applianceMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kCoffee], &srcRects[kCoffee], theRect); + } + + light = coffeeLight1; + ZeroRectCorner(&light); + QOffsetRect(&light, theRect->left + 32, theRect->top + 57); + if (isOn) + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &coffeeLight2, &light, srcCopy, nil); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &coffeeLight1, &light, srcCopy, nil); + } +} + +//-------------------------------------------------------------- DrawOutlet + +void DrawOutlet (Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(applianceMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kOutlet], &srcRects[kOutlet], theRect); +} + +//-------------------------------------------------------------- DrawVCR + +void DrawVCR (Rect *theRect, Boolean isOn, Boolean isLit) +{ + Rect bounds; + GWorldPtr tempMap; + GWorldPtr tempMask; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + if (isLit) + { + GetGWorld(&wasCPort, &wasWorld); + + bounds = srcRects[kVCR]; + theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(kVCRPictID); + + theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); + SetGWorld(tempMask, nil); + LoadGraphic(kVCRMaskID); + + CopyMask((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(tempMask), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kVCR], &srcRects[kVCR], theRect); + + SetGWorld(wasCPort, wasWorld); + + DisposeGWorld(tempMap); + DisposeGWorld(tempMask); + +// SetPort((GrafPtr)backSrcMap); + } + + bounds = vcrTime1; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, theRect->left + 64, theRect->top + 6); + if (isOn) + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &vcrTime2, &bounds, srcCopy, nil); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &vcrTime1, &bounds, srcCopy, nil); + } +} + +//-------------------------------------------------------------- DrawStereo + +void DrawStereo (Rect *theRect, Boolean isOn, Boolean isLit) +{ + Rect bounds; + GWorldPtr tempMap; + GWorldPtr tempMask; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + + if (isLit) + { + GetGWorld(&wasCPort, &wasWorld); + + bounds = srcRects[kStereo]; + theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(kStereoPictID); + + theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); + SetGWorld(tempMask, nil); + LoadGraphic(kStereoMaskID); + + CopyMask((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(tempMask), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kStereo], &srcRects[kStereo], theRect); + + SetGWorld(wasCPort, wasWorld); + + DisposeGWorld(tempMap); + DisposeGWorld(tempMask); + +// SetPort((GrafPtr)backSrcMap); + } + + bounds = stereoLight1; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, theRect->left + 56, theRect->top + 20); + if (isOn) + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &stereoLight2, &bounds, srcCopy, nil); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &stereoLight1, &bounds, srcCopy, nil); + } +} + +//-------------------------------------------------------------- DrawMicrowave + +void DrawMicrowave (Rect *theRect, Boolean isOn, Boolean isLit) +{ + Rect bounds; + GWorldPtr tempMap; + GWorldPtr tempMask; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + + if (isLit) + { + GetGWorld(&wasCPort, &wasWorld); + + bounds = srcRects[kMicrowave]; + theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(kMicrowavePictID); + + theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); + SetGWorld(tempMask, nil); + LoadGraphic(kMicrowaveMaskID); + + CopyMask((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(tempMask), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[kMicrowave], &srcRects[kMicrowave], theRect); + + SetGWorld(wasCPort, wasWorld); + + DisposeGWorld(tempMap); + DisposeGWorld(tempMask); + +// SetPort((GrafPtr)backSrcMap); + } + + bounds = microOn; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, theRect->left + 14, theRect->top + 13); + if (isOn) + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOn, &bounds, srcCopy, nil); + QOffsetRect(&bounds, 16, 0); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOn, &bounds, srcCopy, nil); + QOffsetRect(&bounds, 16, 0); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOn, &bounds, srcCopy, nil); + } + else if (isLit) + { + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOff, &bounds, srcCopy, nil); + QOffsetRect(&bounds, 16, 0); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOff, &bounds, srcCopy, nil); + QOffsetRect(&bounds, 16, 0); + CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + µOff, &bounds, srcCopy, nil); + } +} + +//-------------------------------------------------------------- DrawBalloon + +void DrawBalloon (Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(balloonSrcMap), + (BitMap *)*GetGWorldPixMap(balloonMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &balloonSrc[1], &balloonSrc[1], theRect); +} + +//-------------------------------------------------------------- DrawCopter + +void DrawCopter (Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(copterSrcMap), + (BitMap *)*GetGWorldPixMap(copterMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &copterSrc[1], &copterSrc[1], theRect); +} + +//-------------------------------------------------------------- DrawDart + +void DrawDart (Rect *theRect, short which) +{ + if (which == kDartLf) + { + CopyMask((BitMap *)*GetGWorldPixMap(dartSrcMap), + (BitMap *)*GetGWorldPixMap(dartMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &dartSrc[0], &dartSrc[0], theRect); + } + else + { + CopyMask((BitMap *)*GetGWorldPixMap(dartSrcMap), + (BitMap *)*GetGWorldPixMap(dartMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &dartSrc[2], &dartSrc[2], theRect); + } +} + +//-------------------------------------------------------------- DrawBall + +void DrawBall (short what, Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(ballSrcMap), + (BitMap *)*GetGWorldPixMap(ballMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], &srcRects[what], theRect); +} + +//-------------------------------------------------------------- DrawFish + +void DrawFish (short what, Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(enemySrcMap), + (BitMap *)*GetGWorldPixMap(enemyMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], &srcRects[what], theRect); +} + +//-------------------------------------------------------------- DrawDrip + +void DrawDrip (Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(dripSrcMap), + (BitMap *)*GetGWorldPixMap(dripMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &dripSrc[3], &dripSrc[3], theRect); +} + +//-------------------------------------------------------------- DrawMirror + +void DrawMirror (Rect *mirror) +{ + Rect tempRect; + long grayC; + CGrafPtr wasCPort; + GDHandle wasWorld; + + if (thisMac.isDepth == 4) + { + grayC = 13; + } + else + { + grayC = k8DkGray2Color; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + tempRect = *mirror; + ColorRect(&tempRect, k8WhiteColor); + ColorFrameRect(&tempRect, grayC); + InsetRect(&tempRect, 1, 1); + ColorFrameRect(&tempRect, k8EarthBlueColor); + InsetRect(&tempRect, 1, 1); + ColorFrameRect(&tempRect, k8EarthBlueColor); + InsetRect(&tempRect, 1, 1); + ColorFrameRect(&tempRect, grayC); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawSimpleClutter + +void DrawSimpleClutter (short what, Rect *theRect) +{ + CopyMask((BitMap *)*GetGWorldPixMap(clutterSrcMap), + (BitMap *)*GetGWorldPixMap(clutterMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], &srcRects[what], theRect); +} + +//-------------------------------------------------------------- DrawFlower + +void DrawFlower (Rect *theRect, short which) +{ + CopyMask((BitMap *)*GetGWorldPixMap(clutterSrcMap), + (BitMap *)*GetGWorldPixMap(clutterMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &flowerSrc[which], &flowerSrc[which], theRect); +} + +//-------------------------------------------------------------- DrawWallWindow + +void DrawWallWindow (Rect *window) +{ + #define kWindowSillThick 7 + Rect tempRect, tempRect2; + long brownC, tanC, dkstRedC; + short halfWay; + CGrafPtr wasCPort; + GDHandle wasWorld; + + if (thisMac.isDepth == 4) + { + brownC = 11; + tanC = 9; + dkstRedC = 15; + } + else + { + brownC = k8BrownColor; + tanC = k8TanColor; + dkstRedC = k8DkRed2Color; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + tempRect = *window; + InsetRect(&tempRect, 3, 0); + ColorRect(&tempRect, brownC); + HiliteRect(&tempRect, tanC, dkstRedC); + + tempRect = *window; // top sill + tempRect.bottom = tempRect.top + kWindowSillThick; + tempRect.left++; + tempRect.right--; + ColorRect(&tempRect, brownC); + HiliteRect(&tempRect, tanC, dkstRedC); + tempRect.left--; + tempRect.right++; + tempRect.top += 2; + tempRect.bottom -= 2; + ColorRect(&tempRect, brownC); + HiliteRect(&tempRect, tanC, dkstRedC); + + tempRect = *window; // bottom sill + tempRect.top = tempRect.bottom - kWindowSillThick; + QOffsetRect(&tempRect, 0, -4); + tempRect.left++; + tempRect.right--; + ColorRect(&tempRect, brownC); + HiliteRect(&tempRect, tanC, dkstRedC); + tempRect.left--; + tempRect.right++; + tempRect.top += 2; + tempRect.bottom -= 2; + ColorRect(&tempRect, brownC); + HiliteRect(&tempRect, tanC, dkstRedC); + + tempRect = *window; // inside frame + tempRect.left += 8; + tempRect.right -= 8; + tempRect.top += 11; + tempRect.bottom -= 15; + HiliteRect(&tempRect, dkstRedC, tanC); + + halfWay = (tempRect.top + tempRect.bottom) / 2; + + tempRect2 = tempRect; // top pane + tempRect2.bottom = halfWay + 2; + InsetRect(&tempRect2, 5, 5); + HiliteRect(&tempRect2, dkstRedC, tanC); + InsetRect(&tempRect2, 1, 1); + if (thisMac.isDepth == 4) + ColorRect(&tempRect2, 5); + else + ColorRect(&tempRect2, k8SkyColor); + + tempRect2 = tempRect; // bottom pane + tempRect2.top = halfWay - 3; + InsetRect(&tempRect2, 5, 5); + HiliteRect(&tempRect2, dkstRedC, tanC); + InsetRect(&tempRect2, 1, 1); + if (thisMac.isDepth == 4) + ColorRect(&tempRect2, 5); + else + ColorRect(&tempRect2, k8SkyColor); + + ColorLine(tempRect2.left - 5, tempRect2.top - 7, + tempRect2.right + 5, tempRect2.top - 7, tanC); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawCalendar + +void DrawCalendar (Rect *theRect) +{ + DateTimeRec timeRec; + Rect bounds; + PicHandle thePicture; + Str255 monthStr; + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + thePicture = GetPicture(kCalendarPictID); + if (thePicture == nil) + RedAlert(kErrFailedGraphicLoad); + + HLock((Handle)thePicture); + bounds = (*thePicture)->picFrame; + HUnlock((Handle)thePicture); + QOffsetRect(&bounds, -bounds.left, -bounds.top); + QOffsetRect(&bounds, theRect->left, theRect->top); + DrawPicture(thePicture, &bounds); + ReleaseResource((Handle)thePicture); + + SetPort((GrafPtr)backSrcMap); + TextFace(bold); + TextFont(applFont); + TextSize(9); + GetTime(&timeRec); + GetIndString(monthStr, kMonthStringID, timeRec.month); + MoveTo(theRect->left + ((64 - StringWidth(monthStr)) / 2), theRect->top + 55); + ColorText(monthStr, kDarkFleshColor); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawBulletin + +void DrawBulletin (Rect *theRect) +{ + Rect bounds; + PicHandle thePicture; + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + thePicture = GetPicture(kBulletinPictID); + if (thePicture == nil) + RedAlert(kErrFailedGraphicLoad); + + HLock((Handle)thePicture); + bounds = (*thePicture)->picFrame; + HUnlock((Handle)thePicture); + QOffsetRect(&bounds, -bounds.left, -bounds.top); + QOffsetRect(&bounds, theRect->left, theRect->top); + DrawPicture(thePicture, &bounds); + ReleaseResource((Handle)thePicture); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawPictObject + +void DrawPictObject (short what, Rect *theRect) +{ + Rect bounds; + PicHandle thePicture; + short pictID; + CGrafPtr wasCPort; + GDHandle wasWorld; + + switch (what) + { + case kFilingCabinet: + pictID = kFilingCabinetPictID; + break; + + case kDownStairs: + pictID = kDownStairsPictID; + break; + + case kDoorExRt: + pictID = kDoorExRightPictID; + break; + + case kDoorExLf: + pictID = kDoorExLeftPictID; + break; + + case kWindowExRt: + pictID = kWindowExRightPictID; + break; + + case kWindowExLf: + pictID = kWindowExLeftPictID; + break; + + case kOzma: + pictID = kOzmaPictID; + break; + } + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + thePicture = GetPicture(pictID); + if (thePicture == nil) + RedAlert(kErrFailedGraphicLoad); + + bounds = srcRects[what]; + QOffsetRect(&bounds, theRect->left, theRect->top); + DrawPicture(thePicture, &bounds); + ReleaseResource((Handle)thePicture); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- DrawPictWithMaskObject + +void DrawPictWithMaskObject (short what, Rect *theRect) +{ + Rect bounds; + GWorldPtr tempMap; + GWorldPtr tempMask; + short pictID, maskID; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + switch (what) + { + case kCobweb: + pictID = kCobwebPictID; + maskID = kCobwebMaskID; + break; + + case kCloud: + pictID = kCloudPictID; + maskID = kCloudMaskID; + break; + } + + bounds = srcRects[what]; + theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(pictID); + + theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); + SetGWorld(tempMask, nil); + LoadGraphic(maskID); + + CopyMask((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(tempMask), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], &srcRects[what], theRect); + + SetGWorld(wasCPort, wasWorld); + + DisposeGWorld(tempMap); + DisposeGWorld(tempMask); + +// SetPort((GrafPtr)backSrcMap); +} + +//-------------------------------------------------------------- DrawPictSansWhiteObject + +void DrawPictSansWhiteObject (short what, Rect *theRect) +{ + Rect bounds; + CGrafPtr tempMap; + short pictID; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + switch (what) + { + case kBBQ: + pictID = kBBQPictID; + break; + + case kTrunk: + pictID = kTrunkPictID; + break; + + case kManhole: + pictID = kManholePictID; + break; + + case kBooks: + pictID = kBooksPictID; + break; + + case kUpStairs: + pictID = kUpStairsPictID; + break; + + case kDoorInLf: + pictID = kDoorInLeftPictID; + break; + + case kDoorInRt: + pictID = kDoorInRightPictID; + break; + + case kWindowInLf: + pictID = kWindowInLeftPictID; + break; + + case kWindowInRt: + pictID = kWindowInRightPictID; + break; + + case kHipLamp: + pictID = kHipLampPictID; + break; + + case kDecoLamp: + pictID = kDecoLampPictID; + break; + + case kGuitar: + pictID = kGuitarPictID; + break; + + case kCinderBlock: + pictID = kCinderPictID; + break; + + case kFlowerBox: + pictID = kFlowerBoxPictID; + break; + + case kFireplace: + pictID = kFireplacePictID; + break; + + case kBear: + pictID = kBearPictID; + break; + + case kVase1: + pictID = kVase1PictID; + break; + + case kVase2: + pictID = kVase2PictID; + break; + + case kRug: + pictID = kRugPictID; + break; + + case kChimes: + pictID = kChimesPictID; + break; + } + + bounds = srcRects[what]; + theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(pictID); + + CopyBits((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &srcRects[what], theRect, transparent, nil); + + SetGWorld(wasCPort, wasWorld); + + DisposeGWorld(tempMap); +// SetPort((GrafPtr)backSrcMap); +} +//-------------------------------------------------------------- DrawCustPictSansWhite + +void DrawCustPictSansWhite (short pictID, Rect *theRect) +{ + Rect bounds; + GWorldPtr tempMap; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + bounds = *theRect; + ZeroRectCorner(&bounds); + theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); + SetGWorld(tempMap, nil); + LoadGraphic(pictID); + + CopyBits((BitMap *)*GetGWorldPixMap(tempMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &bounds, theRect, transparent, nil); + + SetGWorld(wasCPort, wasWorld); + + DisposeGWorld(tempMap); +// SetPort((GrafPtr)backSrcMap); +} + diff --git a/GpApp/ObjectDrawAll.cpp b/GpApp/ObjectDrawAll.cpp new file mode 100644 index 0000000..cacae68 --- /dev/null +++ b/GpApp/ObjectDrawAll.cpp @@ -0,0 +1,966 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// ObjectDrawAll.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Environ.h" +#include "RectUtils.h" + + +extern Rect localRoomsDest[], movieRect; +extern short localNumbers[]; +extern short numLights, tvWithMovieNumber; +extern Boolean tvOn; + + +//============================================================== Functions +//-------------------------------------------------------------- DrawARoomsObjects + +void DrawARoomsObjects (short neighbor, Boolean redraw) +{ + objectType thisObject; + Rect whoCares, itsRect, rectA, rectB, testRect; + RgnHandle theRgn; + short i, legit, dynamicNum, n; + short floor, suite, room, obj; + char wasState; + Boolean isLit; + + if (localNumbers[neighbor] == kRoomIsEmpty) + return; + + testRect = houseRect; + ZeroRectCorner(&testRect); + isLit = (numLights > 0); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + for (i = 0; i < kMaxRoomObs; i++) + { + dynamicNum = -1; + legit = -1; + + if (IsThisValid(localNumbers[neighbor], i)) + { + thisObject = (*thisHouse)->rooms[localNumbers[neighbor]].objects[i]; + switch (thisObject.what) + { + case kObjectIsEmpty: + break; + + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kLeftFan: + case kRightFan: + case kGrecoVent: + case kSewerBlower: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawSimpleBlowers(thisObject.what, &itsRect); + break; + + case kTaper: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (isLit) + DrawSimpleBlowers(thisObject.what, &itsRect); + if (neighbor == kCentralRoom) + { + if (redraw) + ReBackUpFlames(localNumbers[neighbor], i); + else + AddCandleFlame(localNumbers[neighbor], i, + itsRect.left + 10, itsRect.top + 7); + } + else + { + QSetRect(&rectA, 0, 0, 16, 15); + QOffsetRect(&rectA, itsRect.left + 10 - 8, itsRect.top + 7 - 15); + rectB = localRoomsDest[kCentralRoom]; + rectB.top -= kFloorSupportTall; + rectB.bottom += kFloorSupportTall; + if (!SectRect(&rectA, &rectB, &whoCares)) + { + if (redraw) + ReBackUpFlames(localNumbers[neighbor], i); + else + AddCandleFlame(localNumbers[neighbor], i, + itsRect.left + 10, itsRect.top + 7); + } + } + } + break; + + case kCandle: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (isLit) + DrawSimpleBlowers(thisObject.what, &itsRect); + if (neighbor == kCentralRoom) + { + if (redraw) + ReBackUpFlames(localNumbers[neighbor], i); + else + AddCandleFlame(localNumbers[neighbor], i, + itsRect.left + 14, itsRect.top + 7); + } + else + { + QSetRect(&rectA, 0, 0, 16, 15); + QOffsetRect(&rectA, itsRect.left + 14 - 8, itsRect.top + 7 - 15); + rectB = localRoomsDest[kCentralRoom]; + rectB.top -= kFloorSupportTall; + rectB.bottom += kFloorSupportTall; + if (!SectRect(&rectA, &rectB, &whoCares)) + { + if (redraw) + ReBackUpFlames(localNumbers[neighbor], i); + else + AddCandleFlame(localNumbers[neighbor], i, + itsRect.left + 14, itsRect.top + 7); + } + } + } + break; + + case kStubby: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (isLit) + DrawSimpleBlowers(thisObject.what, &itsRect); + if (neighbor == kCentralRoom) + { + if (redraw) + ReBackUpFlames(localNumbers[neighbor], i); + else + AddCandleFlame(localNumbers[neighbor], i, + itsRect.left + 9, itsRect.top + 7); + } + else + { + QSetRect(&rectA, 0, 0, 16, 15); + QOffsetRect(&rectA, itsRect.left + 9 - 8, itsRect.top + 7 - 15); + rectB = localRoomsDest[kCentralRoom]; + rectB.top -= kFloorSupportTall; + rectB.bottom += kFloorSupportTall; + if (!SectRect(&rectA, &rectB, &whoCares)) + { + if (redraw) + ReBackUpFlames(localNumbers[neighbor], i); + else + AddCandleFlame(localNumbers[neighbor], i, + itsRect.left + 9, itsRect.top + 7); + } + } + } + break; + + case kTiki: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (isLit) + DrawTiki(&itsRect, playOriginV + VerticalRoomOffset(neighbor)); + if (redraw) + ReBackUpTikiFlames(localNumbers[neighbor], i); + else + AddTikiFlame(localNumbers[neighbor], i, + itsRect.left + 10, itsRect.top - 9); + break; + + case kBBQ: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (isLit) + DrawPictSansWhiteObject(thisObject.what, &itsRect); + if (redraw) + ReBackUpBBQCoals(localNumbers[neighbor], i); + else + AddBBQCoals(localNumbers[neighbor], i, + itsRect.left + 16, itsRect.top + 9); + } + break; + + case kInvisBlower: + case kLiftArea: + break; + + case kTable: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (isLit) + DrawTable(&itsRect, playOriginV); + break; + + case kShelf: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (isLit) + DrawShelf(&itsRect); + break; + + case kCabinet: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawCabinet(&itsRect); + break; + + case kFilingCabinet: + case kOzma: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawPictObject(thisObject.what, &itsRect); + break; + + case kWasteBasket: + case kMilkCrate: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawSimpleFurniture(thisObject.what, &itsRect); + break; + + case kCounter: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawCounter(&itsRect); + break; + + case kDresser: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (isLit) + DrawDresser(&itsRect); + break; + + case kDeckTable: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (isLit) + DrawDeckTable(&itsRect, playOriginV); + break; + + case kStool: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (isLit) + DrawStool(&itsRect, playOriginV + VerticalRoomOffset(neighbor)); + break; + + case kInvisObstacle: + break; + + case kManhole: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + AddTempManholeRect(&itsRect); + if (isLit) + DrawPictSansWhiteObject(thisObject.what, &itsRect); + } + break; + + case kInvisBounce: + break; + + case kRedClock: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (redraw) + legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); + else + legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); + if (legit != -1) + DrawRedClock(&itsRect); + } + break; + + case kBlueClock: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (redraw) + legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); + else + legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); + if (legit != -1) + DrawBlueClock(&itsRect); + } + break; + + case kYellowClock: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (redraw) + legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); + else + legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); + if (legit != -1) + DrawYellowClock(&itsRect); + } + break; + + case kCuckoo: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (redraw) + legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); + else + legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); + if (legit != -1) + { + DrawCuckoo(&itsRect); + if (redraw) + ReBackUpPendulum(localNumbers[neighbor], i); + else + AddPendulum(localNumbers[neighbor], i, + itsRect.left + 4, itsRect.top + 46); + } + } + break; + + case kPaper: + case kBattery: + case kBands: + case kHelium: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (redraw) + legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); + else + legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); + if (legit != -1) + DrawSimplePrizes(thisObject.what, &itsRect); + } + break; + + case kGreaseRt: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (thisObject.data.c.state) // standing + { + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (redraw) + dynamicNum = ReBackUpGrease(localNumbers[neighbor], i); + else + dynamicNum = AddGrease(localNumbers[neighbor], i, + itsRect.left, itsRect.top, + thisObject.data.c.length, true); + if (dynamicNum != -1) + DrawGreaseRt(&itsRect, thisObject.data.c.length, true); + } + } + else // fallen + DrawGreaseRt(&itsRect, thisObject.data.c.length, false); + break; + + case kGreaseLf: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (thisObject.data.c.state) + { + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (redraw) + dynamicNum = ReBackUpGrease(localNumbers[neighbor], i); + else + dynamicNum = AddGrease(localNumbers[neighbor], i, + itsRect.left, itsRect.top, + thisObject.data.c.length, false); + if (dynamicNum != -1) + DrawGreaseLf(&itsRect, thisObject.data.c.length, true); + } + } + else + DrawGreaseLf(&itsRect, thisObject.data.c.length, false); + break; + + case kFoil: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (redraw) + legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); + else + legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); + if (legit != -1) + DrawFoil(&itsRect); + } + break; + + case kInvisBonus: + case kSlider: + break; + + case kStar: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (redraw) + legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); + else + legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); + if (legit != -1) + { + if (redraw) + ReBackUpStar(localNumbers[neighbor], i); + else + AddStar(localNumbers[neighbor], i, itsRect.left, + itsRect.top); + DrawSimplePrizes(thisObject.what, &itsRect); + } + } + break; + + case kSparkle: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if ((!redraw) && (neighbor == kCentralRoom)) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kSparkle, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.c.state); + } + } + break; + + case kUpStairs: + case kDoorInLf: + case kDoorInRt: + case kWindowInLf: + case kWindowInRt: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + DrawPictSansWhiteObject(thisObject.what, &itsRect); + break; + + case kDownStairs: + case kDoorExRt: + case kDoorExLf: + case kWindowExRt: + case kWindowExLf: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + DrawPictObject(thisObject.what, &itsRect); + break; + + case kMailboxLf: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + DrawMailboxLeft(&itsRect, playOriginV + VerticalRoomOffset(neighbor)); + break; + + case kMailboxRt: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + DrawMailboxRight(&itsRect, playOriginV + VerticalRoomOffset(neighbor)); + break; + + case kFloorTrans: + case kCeilingTrans: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + DrawSimpleTransport(thisObject.what, &itsRect); + break; + + case kInvisTrans: + case kDeluxeTrans: + break; + + case kLightSwitch: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); + room = GetRoomNumber(floor, suite); + obj = (short)thisObject.data.e.who; + DrawLightSwitch(&itsRect, GetObjectState(room, obj)); + } + dynamicNum = masterObjects[i].hotNum; + break; + + case kMachineSwitch: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); + room = GetRoomNumber(floor, suite); + obj = (short)thisObject.data.e.who; + DrawMachineSwitch(&itsRect, GetObjectState(room, obj)); + } + dynamicNum = masterObjects[i].hotNum; + break; + + case kThermostat: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); + room = GetRoomNumber(floor, suite); + obj = (short)thisObject.data.e.who; + DrawThermostat(&itsRect, GetObjectState(room, obj)); + } + dynamicNum = masterObjects[i].hotNum; + break; + + case kPowerSwitch: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); + room = GetRoomNumber(floor, suite); + obj = (short)thisObject.data.e.who; + DrawPowerSwitch(&itsRect, GetObjectState(room, obj)); + } + dynamicNum = masterObjects[i].hotNum; + break; + + case kKnifeSwitch: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); + room = GetRoomNumber(floor, suite); + obj = (short)thisObject.data.e.who; + DrawKnifeSwitch(&itsRect, GetObjectState(room, obj)); + } + dynamicNum = masterObjects[i].hotNum; + break; + + case kInvisSwitch: + dynamicNum = masterObjects[i].hotNum; + break; + + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawSimpleLight(thisObject.what, &itsRect); + break; + + case kTrunk: + case kBooks: + case kHipLamp: + case kDecoLamp: + case kGuitar: + case kCinderBlock: + case kFlowerBox: + case kFireplace: + case kBear: + case kVase1: + case kVase2: + case kRug: + case kChimes: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawPictSansWhiteObject(thisObject.what, &itsRect); + break; + + case kCustomPict: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawCustPictSansWhite(thisObject.data.g.height, &itsRect); + break; + + case kFlourescent: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawFlourescent(&itsRect); + break; + + case kTrackLight: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawTrackLight(&itsRect); + break; + + case kInvisLight: + break; + + case kShredder: + case kCDs: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawSimpleAppliance(thisObject.what, &itsRect); + break; + + case kToaster: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + DrawSimpleAppliance(thisObject.what, &itsRect); + if ((!redraw) && (neighbor == kCentralRoom)) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kToaster, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.g.state); + } + } + break; + + case kMacPlus: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + DrawMacPlus(&itsRect, thisObject.data.g.state, isLit); + if (!redraw) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kMacPlus, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.g.state); + } + } + break; + + case kTV: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { +#ifdef COMPILEQT + if ((thisMac.hasQT) && (hasMovie) && (neighbor == kCentralRoom) && + (!tvInRoom)) + { + whoCares = tvScreen1; + ZeroRectCorner(&whoCares); + OffsetRect(&whoCares, itsRect.left + 17, itsRect.top + 10); + GetMovieBox(theMovie, &movieRect); + CenterRectInRect(&movieRect, &whoCares); + SetMovieBox(theMovie, &movieRect); + theRgn = NewRgn(); + RectRgn(theRgn, &whoCares); + SetMovieDisplayClipRgn(theMovie, theRgn); + DisposeRgn(theRgn); + tvOn = thisObject.data.g.state; + } +#endif + DrawTV(&itsRect, thisObject.data.g.state, isLit); + if (!redraw) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kTV, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.g.state); +#ifdef COMPILEQT + if ((thisMac.hasQT) && (hasMovie) && (neighbor == kCentralRoom) && + (!tvInRoom)) + { + tvWithMovieNumber = dynamicNum; + tvInRoom = true; + } +#endif + } + } + break; + + case kCoffee: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + DrawCoffee(&itsRect, thisObject.data.g.state, isLit); + if (!redraw) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kCoffee, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.g.state); + } + } + break; + + case kOutlet: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + if (isLit) + DrawOutlet(&itsRect); + if (!redraw) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kOutlet, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.g.state); + } + } + break; + + case kVCR: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + DrawVCR(&itsRect, thisObject.data.g.state, isLit); + if (!redraw) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kVCR, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.g.state); + } + } + break; + + case kStereo: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + DrawStereo(&itsRect, isPlayMusicGame, isLit); + if (!redraw) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kStereo, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.g.state); + } + } + break; + + case kMicrowave: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + DrawMicrowave(&itsRect, thisObject.data.g.state, isLit); + if (!redraw) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kMicrowave, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.g.state); + } + } + break; + + case kBalloon: + if ((neighbor == kCentralRoom) && (!redraw)) + { + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + QOffsetRect(&itsRect, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kBalloon, &itsRect, &thisObject, + localNumbers[neighbor], i, thisObject.data.h.state); + } + break; + + case kCopterLf: + if ((neighbor == kCentralRoom) && (!redraw)) + { + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + QOffsetRect(&itsRect, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kCopterLf, &itsRect, &thisObject, + localNumbers[neighbor], i, thisObject.data.h.state); + } + break; + + case kCopterRt: + if ((neighbor == kCentralRoom) && (!redraw)) + { + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + QOffsetRect(&itsRect, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kCopterRt, &itsRect, &thisObject, + localNumbers[neighbor], i, thisObject.data.h.state); + } + break; + + case kDartLf: + if ((neighbor == kCentralRoom) && (!redraw)) + { + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + QOffsetRect(&itsRect, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kDartLf, &itsRect, &thisObject, + localNumbers[neighbor], i, thisObject.data.h.state); + } + break; + + case kDartRt: + if ((neighbor == kCentralRoom) && (!redraw)) + { + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + QOffsetRect(&itsRect, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kDartRt, &itsRect, &thisObject, + localNumbers[neighbor], i, thisObject.data.h.state); + } + break; + + case kBall: + if ((neighbor == kCentralRoom) && (!redraw)) + { + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + QOffsetRect(&itsRect, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kBall, &itsRect, &thisObject, + localNumbers[neighbor], i, thisObject.data.h.state); + } + break; + + case kDrip: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + DrawDrip(&itsRect); + if ((!redraw) && (neighbor == kCentralRoom)) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kDrip, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.h.state); + } + } + break; + + case kFish: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + { + DrawFish(thisObject.what, &itsRect); + if ((!redraw) && (neighbor == kCentralRoom)) + { + rectA = itsRect; + QOffsetRect(&rectA, -playOriginH, -playOriginV); + dynamicNum = AddDynamicObject(kFish, &rectA, &thisObject, + localNumbers[neighbor], i, thisObject.data.h.state); + } + } + break; + + case kCobweb: + case kCloud: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawPictWithMaskObject(thisObject.what, &itsRect); + break; + + case kMirror: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawMirror(&itsRect); + if ((neighbor == kCentralRoom) && (!redraw)) + { + InsetRect(&itsRect, 4, 4); + AddToMirrorRegion(&itsRect); + } + break; + + case kMousehole: + case kFaucet: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawSimpleClutter(thisObject.what, &itsRect); + break; + + case kFlower: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawFlower(&itsRect, thisObject.data.i.pict); + break; + + case kWallWindow: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if (SectRect(&itsRect, &testRect, &whoCares)) + DrawWallWindow(&itsRect); + break; + + case kCalendar: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawCalendar(&itsRect); + break; + + case kBulletin: + GetObjectRect(&thisObject, &itsRect); + OffsetRectRoomRelative(&itsRect, neighbor); + if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) + DrawBulletin(&itsRect); + break; + + } + } + + if (!redraw) // set up links + { + for (n = 0; n < numMasterObjects; n++) + { + if ((masterObjects[n].objectNum == i) && + (masterObjects[n].roomNum == localNumbers[neighbor])) + masterObjects[n].dynaNum = dynamicNum; + } + } + } + + HSetState((Handle)thisHouse, wasState); +} + diff --git a/GpApp/ObjectEdit.cpp b/GpApp/ObjectEdit.cpp new file mode 100644 index 0000000..f9da849 --- /dev/null +++ b/GpApp/ObjectEdit.cpp @@ -0,0 +1,2811 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// ObjectEdit.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLSound.h" +#include "PLToolUtils.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "House.h" +#include "MainWindow.h" +#include "Marquee.h" +#include "ObjectEdit.h" +#include "Objects.h" +#include "Play.h" +#include "RectUtils.h" +#include "Room.h" + + +short FindObjectSelected (Point); +void DragHandle (Point); +void DragObject (Point); +void AddObjectPairing (void); +Boolean ObjectIsUpBlower (objectType *); + + +Rect roomObjectRects[kMaxRoomObs]; +Rect initialGliderRect; +Rect leftStartGliderSrc, rightStartGliderSrc; +Rect leftStartGliderDest, rightStartGliderDest; +short objActive; +Boolean isFirstRoom; + + +extern retroLink retroLinkList[]; +extern Rect gliderSrc[kNumGliderSrcRects]; +extern short toolSelected, toolMode; +extern Boolean noRoomAtAll; + + +//============================================================== Functions +//-------------------------------------------------------------- FindObjectSelected + +#ifndef COMPILEDEMO +short FindObjectSelected (Point where) +{ + short found, i; + + found = kNoObjectSelected; + + if (PtInRect(where, &initialGliderRect)) + return (kInitialGliderSelected); + else if (PtInRect(where, &leftStartGliderDest)) + return (kLeftGliderSelected); + else if (PtInRect(where, &rightStartGliderDest)) + return (kRightGliderSelected); + + for (i = kMaxRoomObs - 1; i >= 0; i--) + { + if (PtInRect(where, &roomObjectRects[i])) + { + found = i; + break; + } + } + return (found); +} +#endif + +//-------------------------------------------------------------- DoSelectionClick + +void DoSelectionClick (Point where, Boolean isDoubleClick) +{ +#ifndef COMPILEDEMO + short direction, dist; + + StopMarquee(); + + if ((PtInMarqueeHandle(where)) && (objActive != kNoObjectSelected)) + { + if (StillDown()) + DragHandle(where); + if (ObjectHasHandle(&direction, &dist)) + { + StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); + HandleBlowerGlider(); + } + else + StartMarquee(&roomObjectRects[objActive]); + } + else + { + objActive = FindObjectSelected(where); + if (objActive == kNoObjectSelected) + { + if (isDoubleClick) + DoRoomInfo(); + } + else + { + if (isDoubleClick) + { + DoObjectInfo(); + if (ObjectHasHandle(&direction, &dist)) + { + StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); + HandleBlowerGlider(); + } + else + StartMarquee(&roomObjectRects[objActive]); + } + else + { + if (StillDown()) + DragObject(where); + if (ObjectHasHandle(&direction, &dist)) + { + StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); + HandleBlowerGlider(); + } + else + { + if (objActive == kInitialGliderSelected) + StartMarquee(&initialGliderRect); + else if (objActive == kLeftGliderSelected) + StartMarquee(&leftStartGliderDest); + else if (objActive == kRightGliderSelected) + StartMarquee(&rightStartGliderDest); + else + StartMarquee(&roomObjectRects[objActive]); + } + } + } + } + UpdateMenus(false); +#endif +} + +//-------------------------------------------------------------- DragHandle + +#ifndef COMPILEDEMO +void DragHandle (Point where) +{ + short hDelta, vDelta; + Boolean whoCares; + + switch (thisRoom->objects[objActive].what) + { + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + case kGrecoVent: + case kSewerBlower: + vDelta = thisRoom->objects[objActive].data.a.distance; + DragMarqueeHandle(where, &vDelta); + thisRoom->objects[objActive].data.a.distance = vDelta; + whoCares = KeepObjectLegal(); + break; + + case kLiftArea: + hDelta = thisRoom->objects[objActive].data.a.distance; + vDelta = thisRoom->objects[objActive].data.a.tall * 2; + DragMarqueeCorner(where, &hDelta, &vDelta, false); + thisRoom->objects[objActive].data.a.distance = hDelta; + thisRoom->objects[objActive].data.a.tall = vDelta / 2; + whoCares = KeepObjectLegal(); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + break; + + case kLeftFan: + case kRightFan: + hDelta = thisRoom->objects[objActive].data.a.distance; + DragMarqueeHandle(where, &hDelta); + thisRoom->objects[objActive].data.a.distance = hDelta; + whoCares = KeepObjectLegal(); + break; + + case kInvisBlower: + if (((thisRoom->objects[objActive].data.a.vector & 0x0F) == 1) || + ((thisRoom->objects[objActive].data.a.vector & 0x0F) == 4)) + { + vDelta = thisRoom->objects[objActive].data.a.distance; + DragMarqueeHandle(where, &vDelta); + thisRoom->objects[objActive].data.a.distance = vDelta; + } + else + { + hDelta = thisRoom->objects[objActive].data.a.distance; + DragMarqueeHandle(where, &hDelta); + thisRoom->objects[objActive].data.a.distance = hDelta; + } + whoCares = KeepObjectLegal(); + break; + + case kTable: + case kShelf: + case kDeckTable: + hDelta = RectWide(&thisRoom->objects[objActive].data.b.bounds); + DragMarqueeHandle(where, &hDelta); + thisRoom->objects[objActive].data.b.bounds.right = + thisRoom->objects[objActive].data.b.bounds.left + hDelta; + whoCares = KeepObjectLegal(); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + break; + + case kCabinet: + case kInvisObstacle: + case kInvisBounce: + hDelta = RectWide(&thisRoom->objects[objActive].data.b.bounds); + vDelta = RectTall(&thisRoom->objects[objActive].data.b.bounds); + DragMarqueeCorner(where, &hDelta, &vDelta, false); + thisRoom->objects[objActive].data.b.bounds.right = + thisRoom->objects[objActive].data.b.bounds.left + hDelta; + thisRoom->objects[objActive].data.b.bounds.bottom = + thisRoom->objects[objActive].data.b.bounds.top + vDelta; + whoCares = KeepObjectLegal(); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + break; + + case kCounter: + case kDresser: + hDelta = RectWide(&thisRoom->objects[objActive].data.b.bounds); + vDelta = RectTall(&thisRoom->objects[objActive].data.b.bounds); + DragMarqueeCorner(where, &hDelta, &vDelta, true); + thisRoom->objects[objActive].data.b.bounds.right = + thisRoom->objects[objActive].data.b.bounds.left + hDelta; + thisRoom->objects[objActive].data.b.bounds.top = + thisRoom->objects[objActive].data.b.bounds.bottom - vDelta; + whoCares = KeepObjectLegal(); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + break; + + case kGreaseRt: + case kGreaseLf: + case kSlider: + hDelta = thisRoom->objects[objActive].data.c.length; + DragMarqueeHandle(where, &hDelta); + thisRoom->objects[objActive].data.c.length = hDelta; + whoCares = KeepObjectLegal(); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + break; + + case kInvisTrans: + hDelta = thisRoom->objects[objActive].data.d.wide; + vDelta = thisRoom->objects[objActive].data.d.tall; + DragMarqueeCorner(where, &hDelta, &vDelta, false); + if (hDelta > 127) + hDelta = 127; + thisRoom->objects[objActive].data.d.wide = (Byte)hDelta; + thisRoom->objects[objActive].data.d.tall = vDelta; + whoCares = KeepObjectLegal(); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + break; + + case kDeluxeTrans: + hDelta = ((thisRoom->objects[objActive].data.d.tall & 0xFF00) >> 8) * 4; + vDelta = (thisRoom->objects[objActive].data.d.tall & 0x00FF) * 4; + DragMarqueeCorner(where, &hDelta, &vDelta, false); + if (hDelta < 64) + hDelta = 64; + if (vDelta < 32) + vDelta = 32; + thisRoom->objects[objActive].data.d.tall = ((hDelta / 4) << 8) + (vDelta / 4); + whoCares = KeepObjectLegal(); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + break; + + case kFlourescent: + case kTrackLight: + hDelta = thisRoom->objects[objActive].data.f.length; + DragMarqueeHandle(where, &hDelta); + thisRoom->objects[objActive].data.f.length = hDelta; + whoCares = KeepObjectLegal(); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + break; + + case kToaster: + vDelta = thisRoom->objects[objActive].data.g.height; + DragMarqueeHandle(where, &vDelta); + thisRoom->objects[objActive].data.g.height = vDelta; + whoCares = KeepObjectLegal(); + break; + + case kBall: + case kDrip: + case kFish: + vDelta = thisRoom->objects[objActive].data.h.length; + DragMarqueeHandle(where, &vDelta); + thisRoom->objects[objActive].data.h.length = vDelta; + whoCares = KeepObjectLegal(); + break; + + case kMirror: + case kWallWindow: + hDelta = RectWide(&thisRoom->objects[objActive].data.i.bounds); + vDelta = RectTall(&thisRoom->objects[objActive].data.i.bounds); + DragMarqueeCorner(where, &hDelta, &vDelta, false); + thisRoom->objects[objActive].data.i.bounds.right = + thisRoom->objects[objActive].data.i.bounds.left + hDelta; + thisRoom->objects[objActive].data.i.bounds.bottom = + thisRoom->objects[objActive].data.i.bounds.top + vDelta; + whoCares = KeepObjectLegal(); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + break; + + } + + fileDirty = true; + UpdateMenus(false); +} +#endif + +//-------------------------------------------------------------- DragObject + +#ifndef COMPILEDEMO +void DragObject (Point where) +{ + Rect newRect, wasRect; + short deltaH, deltaV, increment; + char wasState; + Boolean invalAll; + + if (objActive == kInitialGliderSelected) + { + wasRect = initialGliderRect; + newRect = initialGliderRect; + DragMarqueeRect(where, &newRect, false, false); + } + else if (objActive == kLeftGliderSelected) + { + wasRect = leftStartGliderDest; + newRect = leftStartGliderDest; + DragMarqueeRect(where, &newRect, false, true); + } + else if (objActive == kRightGliderSelected) + { + wasRect = rightStartGliderDest; + newRect = rightStartGliderDest; + DragMarqueeRect(where, &newRect, false, true); + } + else + { + wasRect = roomObjectRects[objActive]; + newRect = roomObjectRects[objActive]; + switch (thisRoom->objects[objActive].what) + { + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kGrecoVent: + case kSewerBlower: + case kManhole: + case kUpStairs: + case kDownStairs: + case kCeilingLight: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kFloorTrans: + case kCeilingTrans: + case kDoorInLf: + case kDoorInRt: + case kDoorExRt: + case kDoorExLf: + case kWindowInLf: + case kWindowInRt: + case kWindowExRt: + case kWindowExLf: + case kBalloon: + case kCopterLf: + case kCopterRt: + case kMousehole: + case kFireplace: + DragMarqueeRect(where, &newRect, true, false); + invalAll = false; + break; + + case kDartLf: + case kDartRt: + DragMarqueeRect(where, &newRect, false, true); + invalAll = false; + break; + + case kTiki: + case kTable: + case kShelf: + case kCabinet: + case kDeckTable: + case kStool: + case kInvisObstacle: + case kInvisBounce: + case kGreaseRt: + case kGreaseLf: + case kSlider: + case kMailboxLf: + case kMailboxRt: + case kInvisTrans: + case kDeluxeTrans: + case kMirror: + case kWallWindow: + DragMarqueeRect(where, &newRect, false, false); + invalAll = true; + break; + + case kCounter: + case kDresser: + case kTrackLight: + DragMarqueeRect(where, &newRect, true, false); + invalAll = true; + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + case kLeftFan: + case kRightFan: + case kTaper: + case kCandle: + case kStubby: + case kBBQ: + case kInvisBlower: + case kLiftArea: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kTrunk: + case kBooks: + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + case kLightBulb: + case kTableLamp: + case kInvisLight: + case kShredder: + case kToaster: + case kMacPlus: + case kGuitar: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kStereo: + case kMicrowave: + case kCinderBlock: + case kFlowerBox: + case kCDs: + case kCustomPict: + case kBall: + case kDrip: + case kFish: + case kCobweb: + case kOzma: + case kFlower: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + case kChimes: + DragMarqueeRect(where, &newRect, false, false); + invalAll = false; + break; + } + } + + deltaH = newRect.left - wasRect.left; + deltaV = newRect.top - wasRect.top; + if ((deltaH != 0) || (deltaV != 0)) + { + fileDirty = true; + UpdateMenus(false); + } + + if (objActive == kInitialGliderSelected) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + (*thisHouse)->initial.h += deltaH; + (*thisHouse)->initial.v += deltaV; + HSetState((Handle)thisHouse, wasState); + } + else if (objActive == kLeftGliderSelected) + { + increment = thisRoom->leftStart + deltaV; + if (increment > 255) + increment = 255; + else if (increment < 0) + increment = 0; + thisRoom->leftStart = (Byte)increment; + QSetRect(&leftStartGliderDest, 0, 0, 48, 16); + QOffsetRect(&leftStartGliderDest, 0, + kGliderStartsDown + (short)thisRoom->leftStart); + } + else if (objActive == kRightGliderSelected) + { + increment = thisRoom->rightStart + deltaV; + if (increment > 255) + increment = 255; + else if (increment < 0) + increment = 0; + thisRoom->rightStart = (Byte)increment; + QSetRect(&rightStartGliderDest, 0, 0, 48, 16); + QOffsetRect(&rightStartGliderDest, 0, + kGliderStartsDown + (short)thisRoom->rightStart); + } + else + { + switch (thisRoom->objects[objActive].what) + { + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kGrecoVent: + case kSewerBlower: + thisRoom->objects[objActive].data.a.topLeft.h += deltaH; + break; + + case kLeftFan: + case kRightFan: + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + case kInvisBlower: + case kLiftArea: + thisRoom->objects[objActive].data.a.topLeft.h += deltaH; + thisRoom->objects[objActive].data.a.topLeft.v += deltaV; + break; + + case kTable: + case kShelf: + case kCabinet: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kDeckTable: + case kStool: + case kTrunk: + case kInvisObstacle: + case kBooks: + case kInvisBounce: + thisRoom->objects[objActive].data.b.bounds.left += deltaH; + thisRoom->objects[objActive].data.b.bounds.right += deltaH; + thisRoom->objects[objActive].data.b.bounds.top += deltaV; + thisRoom->objects[objActive].data.b.bounds.bottom += deltaV; + break; + + case kCounter: + case kDresser: + case kManhole: + thisRoom->objects[objActive].data.b.bounds.left += deltaH; + thisRoom->objects[objActive].data.b.bounds.right += deltaH; + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kGreaseRt: + case kGreaseLf: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + case kSlider: + thisRoom->objects[objActive].data.c.topLeft.h += deltaH; + thisRoom->objects[objActive].data.c.topLeft.v += deltaV; + break; + + case kUpStairs: + case kDownStairs: + case kFloorTrans: + case kCeilingTrans: + case kDoorInLf: + case kDoorInRt: + case kDoorExRt: + case kDoorExLf: + case kWindowInLf: + case kWindowInRt: + case kWindowExRt: + case kWindowExLf: + thisRoom->objects[objActive].data.d.topLeft.h += deltaH; + break; + + case kMailboxLf: + case kMailboxRt: + case kInvisTrans: + case kDeluxeTrans: + thisRoom->objects[objActive].data.d.topLeft.h += deltaH; + thisRoom->objects[objActive].data.d.topLeft.v += deltaV; + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + thisRoom->objects[objActive].data.e.topLeft.h += deltaH; + thisRoom->objects[objActive].data.e.topLeft.v += deltaV; + break; + + case kCeilingLight: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + thisRoom->objects[objActive].data.f.topLeft.h += deltaH; + break; + + case kLightBulb: + case kTableLamp: + case kInvisLight: + thisRoom->objects[objActive].data.f.topLeft.h += deltaH; + thisRoom->objects[objActive].data.f.topLeft.v += deltaV; + break; + + case kShredder: + case kToaster: + case kMacPlus: + case kGuitar: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kStereo: + case kMicrowave: + case kCinderBlock: + case kFlowerBox: + case kCDs: + case kCustomPict: + thisRoom->objects[objActive].data.g.topLeft.h += deltaH; + thisRoom->objects[objActive].data.g.topLeft.v += deltaV; + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + thisRoom->objects[objActive].data.h.topLeft.h += deltaH; + break; + + case kDartLf: + case kDartRt: + thisRoom->objects[objActive].data.h.topLeft.v += deltaV; + break; + + case kBall: + case kDrip: + case kFish: + case kCobweb: + thisRoom->objects[objActive].data.h.topLeft.h += deltaH; + thisRoom->objects[objActive].data.h.topLeft.v += deltaV; + break; + + case kOzma: + case kMirror: + case kFlower: + case kWallWindow: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + case kChimes: + thisRoom->objects[objActive].data.i.bounds.left += deltaH; + thisRoom->objects[objActive].data.i.bounds.right += deltaH; + thisRoom->objects[objActive].data.i.bounds.top += deltaV; + thisRoom->objects[objActive].data.i.bounds.bottom += deltaV; + break; + + case kMousehole: + case kFireplace: + thisRoom->objects[objActive].data.i.bounds.left += deltaH; + thisRoom->objects[objActive].data.i.bounds.right += deltaH; + break; + } + } + + if (KeepObjectLegal()) + { + } + GetThisRoomsObjRects(); + if (invalAll) + InvalWindowRect(mainWindow, &mainWindowRect); + else + { + InvalWindowRect(mainWindow, &wasRect); + if (objActive == kInitialGliderSelected) + InvalWindowRect(mainWindow, &initialGliderRect); + else if (objActive == kLeftGliderSelected) + InvalWindowRect(mainWindow, &leftStartGliderDest); + else if (objActive == kRightGliderSelected) + InvalWindowRect(mainWindow, &rightStartGliderDest); + else + InvalWindowRect(mainWindow, &roomObjectRects[objActive]); + } + + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); +} +#endif + +//-------------------------------------------------------------- DoNewObjectClick + +void DoNewObjectClick (Point where) +{ +#ifndef COMPILEDEMO + short whatObject; + + StopMarquee(); + objActive = kNoObjectSelected; + + whatObject = toolSelected + ((toolMode - 1) * 0x0010); + if (AddNewObject(where, whatObject, true)) + IgnoreThisClick(); + UpdateMenus(false); + + AddObjectPairing(); +#endif +} + +//-------------------------------------------------------------- AddObjectPairing + +void AddObjectPairing (void) +{ + roomType *testRoomPtr; + short roomNum, emptySlot; + char wasState; + Str255 message; + + if (thisRoom->objects[objActive].what == kDoorInRt) + { + roomNum = DoesNeighborRoomExist(kRoomToRight); + if (roomNum != -1) + { + emptySlot = FindObjectSlotInRoom(roomNum); + if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kDoorExLf))) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNum]); + + testRoomPtr->objects[emptySlot].what = kDoorExLf; + testRoomPtr->objects[emptySlot].data.d.topLeft.h = kDoorExLfLeft; + testRoomPtr->objects[emptySlot].data.d.topLeft.v = kDoorExTop; + testRoomPtr->objects[emptySlot].data.d.tall = 0; + testRoomPtr->objects[emptySlot].data.d.where = -1; + testRoomPtr->objects[emptySlot].data.d.who = 255; + testRoomPtr->objects[emptySlot].data.d.wide = 0; + + testRoomPtr->numObjects++; + HSetState((Handle)thisHouse, wasState); + + GetLocalizedString(45, message); + OpenMessageWindow(message); + ForeColor(blueColor); + GetLocalizedString(46, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + CloseMessageWindow(); + } + } + } + else if (thisRoom->objects[objActive].what == kDoorInLf) + { + roomNum = DoesNeighborRoomExist(kRoomToLeft); + if (roomNum != -1) + { + emptySlot = FindObjectSlotInRoom(roomNum); + if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kDoorExRt))) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNum]); + + testRoomPtr->objects[emptySlot].what = kDoorExRt; + testRoomPtr->objects[emptySlot].data.d.topLeft.h = kDoorExRtLeft; + testRoomPtr->objects[emptySlot].data.d.topLeft.v = kDoorExTop; + testRoomPtr->objects[emptySlot].data.d.tall = 0; + testRoomPtr->objects[emptySlot].data.d.where = -1; + testRoomPtr->objects[emptySlot].data.d.who = 255; + testRoomPtr->objects[emptySlot].data.d.wide = 0; + + testRoomPtr->numObjects++; + + HSetState((Handle)thisHouse, wasState); + + GetLocalizedString(45, message); + OpenMessageWindow(message); + ForeColor(blueColor); + GetLocalizedString(46, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + CloseMessageWindow(); + } + } + } + else if (thisRoom->objects[objActive].what == kDoorExRt) + { + roomNum = DoesNeighborRoomExist(kRoomToRight); + if (roomNum != -1) + { + emptySlot = FindObjectSlotInRoom(roomNum); + if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kDoorInLfLeft))) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNum]); + + testRoomPtr->objects[emptySlot].what = kDoorInLf; + testRoomPtr->objects[emptySlot].data.d.topLeft.h = kDoorInLfLeft; + testRoomPtr->objects[emptySlot].data.d.topLeft.v = kDoorInTop; + testRoomPtr->objects[emptySlot].data.d.tall = 0; + testRoomPtr->objects[emptySlot].data.d.where = -1; + testRoomPtr->objects[emptySlot].data.d.who = 255; + testRoomPtr->objects[emptySlot].data.d.wide = 0; + + testRoomPtr->numObjects++; + + HSetState((Handle)thisHouse, wasState); + + GetLocalizedString(45, message); + OpenMessageWindow(message); + ForeColor(blueColor); + GetLocalizedString(47, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + CloseMessageWindow(); + } + } + } + else if (thisRoom->objects[objActive].what == kDoorExLf) + { + roomNum = DoesNeighborRoomExist(kRoomToLeft); + if (roomNum != -1) + { + emptySlot = FindObjectSlotInRoom(roomNum); + if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kDoorInRtLeft))) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNum]); + + testRoomPtr->objects[emptySlot].what = kDoorInRt; + testRoomPtr->objects[emptySlot].data.d.topLeft.h = kDoorInRtLeft; + testRoomPtr->objects[emptySlot].data.d.topLeft.v = kDoorInTop; + testRoomPtr->objects[emptySlot].data.d.tall = 0; + testRoomPtr->objects[emptySlot].data.d.where = -1; + testRoomPtr->objects[emptySlot].data.d.who = 255; + testRoomPtr->objects[emptySlot].data.d.wide = 0; + + testRoomPtr->numObjects++; + + HSetState((Handle)thisHouse, wasState); + + GetLocalizedString(45, message); + OpenMessageWindow(message); + ForeColor(blueColor); + GetLocalizedString(47, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + CloseMessageWindow(); + } + } + } + else if (thisRoom->objects[objActive].what == kWindowInLf) + { + roomNum = DoesNeighborRoomExist(kRoomToLeft); + if (roomNum != -1) + { + emptySlot = FindObjectSlotInRoom(roomNum); + if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kWindowExRt))) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNum]); + + testRoomPtr->objects[emptySlot].what = kWindowExRt; + testRoomPtr->objects[emptySlot].data.d.topLeft.h = kWindowExRtLeft; + testRoomPtr->objects[emptySlot].data.d.topLeft.v = kWindowExTop; + testRoomPtr->objects[emptySlot].data.d.tall = 0; + testRoomPtr->objects[emptySlot].data.d.where = -1; + testRoomPtr->objects[emptySlot].data.d.who = 255; + testRoomPtr->objects[emptySlot].data.d.wide = 0; + + testRoomPtr->numObjects++; + + HSetState((Handle)thisHouse, wasState); + + GetLocalizedString(45, message); + OpenMessageWindow(message); + ForeColor(blueColor); + GetLocalizedString(48, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + CloseMessageWindow(); + } + } + } + else if (thisRoom->objects[objActive].what == kWindowInRt) + { + roomNum = DoesNeighborRoomExist(kRoomToRight); + if (roomNum != -1) + { + emptySlot = FindObjectSlotInRoom(roomNum); + if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kWindowExLf))) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNum]); + + testRoomPtr->objects[emptySlot].what = kWindowExLf; + testRoomPtr->objects[emptySlot].data.d.topLeft.h = kWindowExLfLeft; + testRoomPtr->objects[emptySlot].data.d.topLeft.v = kWindowExTop; + testRoomPtr->objects[emptySlot].data.d.tall = 0; + testRoomPtr->objects[emptySlot].data.d.where = -1; + testRoomPtr->objects[emptySlot].data.d.who = 255; + testRoomPtr->objects[emptySlot].data.d.wide = 0; + + testRoomPtr->numObjects++; + + HSetState((Handle)thisHouse, wasState); + + GetLocalizedString(45, message); + OpenMessageWindow(message); + ForeColor(blueColor); + GetLocalizedString(48, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + CloseMessageWindow(); + } + } + } + else if (thisRoom->objects[objActive].what == kWindowExRt) + { + roomNum = DoesNeighborRoomExist(kRoomToRight); + if (roomNum != -1) + { + emptySlot = FindObjectSlotInRoom(roomNum); + if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kWindowInLf))) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNum]); + + testRoomPtr->objects[emptySlot].what = kWindowInLf; + testRoomPtr->objects[emptySlot].data.d.topLeft.h = kWindowInLfLeft; + testRoomPtr->objects[emptySlot].data.d.topLeft.v = kWindowInTop; + testRoomPtr->objects[emptySlot].data.d.tall = 0; + testRoomPtr->objects[emptySlot].data.d.where = -1; + testRoomPtr->objects[emptySlot].data.d.who = 255; + testRoomPtr->objects[emptySlot].data.d.wide = 0; + + testRoomPtr->numObjects++; + + HSetState((Handle)thisHouse, wasState); + + GetLocalizedString(45, message); + OpenMessageWindow(message); + ForeColor(blueColor); + GetLocalizedString(49, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + CloseMessageWindow(); + } + } + } + else if (thisRoom->objects[objActive].what == kWindowExLf) + { + roomNum = DoesNeighborRoomExist(kRoomToLeft); + if (roomNum != -1) + { + emptySlot = FindObjectSlotInRoom(roomNum); + if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kWindowInRt))) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNum]); + + testRoomPtr->objects[emptySlot].what = kWindowInRt; + testRoomPtr->objects[emptySlot].data.d.topLeft.h = kWindowInRtLeft; + testRoomPtr->objects[emptySlot].data.d.topLeft.v = kWindowInTop; + testRoomPtr->objects[emptySlot].data.d.tall = 0; + testRoomPtr->objects[emptySlot].data.d.where = -1; + testRoomPtr->objects[emptySlot].data.d.who = 255; + testRoomPtr->objects[emptySlot].data.d.wide = 0; + + testRoomPtr->numObjects++; + + HSetState((Handle)thisHouse, wasState); + + GetLocalizedString(45, message); + OpenMessageWindow(message); + ForeColor(blueColor); + GetLocalizedString(49, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + CloseMessageWindow(); + } + } + } + else if (thisRoom->objects[objActive].what == kUpStairs) + { + roomNum = DoesNeighborRoomExist(kRoomAbove); + if (roomNum != -1) + { + emptySlot = FindObjectSlotInRoom(roomNum); + if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kDownStairs))) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNum]); + + testRoomPtr->objects[emptySlot].what = kDownStairs; + testRoomPtr->objects[emptySlot].data.d.topLeft.h = + thisRoom->objects[objActive].data.d.topLeft.h; + testRoomPtr->objects[emptySlot].data.d.topLeft.v = kStairsTop; + testRoomPtr->objects[emptySlot].data.d.tall = 0; + testRoomPtr->objects[emptySlot].data.d.where = -1; + testRoomPtr->objects[emptySlot].data.d.who = 255; + testRoomPtr->objects[emptySlot].data.d.wide = 0; + + testRoomPtr->numObjects++; + + HSetState((Handle)thisHouse, wasState); + + GetLocalizedString(45, message); + OpenMessageWindow(message); + ForeColor(blueColor); + GetLocalizedString(50, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + CloseMessageWindow(); + } + } + } + else if (thisRoom->objects[objActive].what == kDownStairs) + { + roomNum = DoesNeighborRoomExist(kRoomBelow); + if (roomNum != -1) + { + emptySlot = FindObjectSlotInRoom(roomNum); + if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kUpStairs))) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + testRoomPtr = &((*thisHouse)->rooms[roomNum]); + + testRoomPtr->objects[emptySlot].what = kUpStairs; + testRoomPtr->objects[emptySlot].data.d.topLeft.h = + thisRoom->objects[objActive].data.d.topLeft.h; + testRoomPtr->objects[emptySlot].data.d.topLeft.v = kStairsTop; + testRoomPtr->objects[emptySlot].data.d.tall = 0; + testRoomPtr->objects[emptySlot].data.d.where = -1; + testRoomPtr->objects[emptySlot].data.d.who = 255; + testRoomPtr->objects[emptySlot].data.d.wide = 0; + + testRoomPtr->numObjects++; + + HSetState((Handle)thisHouse, wasState); + + GetLocalizedString(45, message); + OpenMessageWindow(message); + ForeColor(blueColor); + GetLocalizedString(51, message); + SetMessageWindowMessage(message); + ForeColor(blackColor); + DelayTicks(60); + CloseMessageWindow(); + } + } + } +} + +//-------------------------------------------------------------- DeleteObject + +void DeleteObject (void) +{ +#ifndef COMPILEDEMO + short i; + + if ((theMode != kEditMode) || (objActive == kNoObjectSelected)) + return; + + if ((objActive == kInitialGliderSelected) || + (objActive == kLeftGliderSelected) || + (objActive == kRightGliderSelected)) + { + SysBeep(1); + return; + } + + for (i = 0; i < kMaxRoomObs; i++) + { + if ((retroLinkList[i].room == thisRoomNumber) && + (retroLinkList[i].object == objActive)) + retroLinkList[i].room = -1; + } + + thisRoom->objects[objActive].what = kObjectIsEmpty; + thisRoom->numObjects--; + fileDirty = true; + UpdateMenus(false); + InvalWindowRect(mainWindow, &mainWindowRect); + QSetRect(&roomObjectRects[objActive], -1, -1, 0, 0); + DeselectObject(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); +#endif +} + +//-------------------------------------------------------------- DuplicateObject + +void DuplicateObject (void) +{ + objectType tempObject; + Point placePt; + short direction, dist; + Boolean handled; + + tempObject = thisRoom->objects[objActive]; + + placePt.h = roomObjectRects[objActive].left + + HalfRectWide(&roomObjectRects[objActive]) + 64; + placePt.v = roomObjectRects[objActive].top + + HalfRectTall(&roomObjectRects[objActive]); + + StopMarquee(); + + if (AddNewObject(placePt, tempObject.what, false)) + { + switch (tempObject.what) + { + case kFloorVent: case kCeilingVent: case kFloorBlower: + case kCeilingBlower: case kSewerGrate: case kLeftFan: + case kRightFan: case kTaper: case kCandle: + case kStubby: case kTiki: case kBBQ: + case kInvisBlower: case kGrecoVent: case kSewerBlower: + thisRoom->objects[objActive].data.a.distance = tempObject.data.a.distance; + thisRoom->objects[objActive].data.a.initial = tempObject.data.a.initial; + thisRoom->objects[objActive].data.a.state = tempObject.data.a.state; + thisRoom->objects[objActive].data.a.vector = tempObject.data.a.vector; + thisRoom->objects[objActive].data.a.tall = tempObject.data.a.tall; + break; + + case kLiftArea: + thisRoom->objects[objActive].data.a.topLeft.h = tempObject.data.a.topLeft.h + 64; + thisRoom->objects[objActive].data.a.topLeft.v = tempObject.data.a.topLeft.v; + thisRoom->objects[objActive].data.a.distance = tempObject.data.a.distance; + thisRoom->objects[objActive].data.a.initial = tempObject.data.a.initial; + thisRoom->objects[objActive].data.a.state = tempObject.data.a.state; + thisRoom->objects[objActive].data.a.vector = tempObject.data.a.vector; + thisRoom->objects[objActive].data.a.tall = tempObject.data.a.tall; + break; + + case kFilingCabinet: case kWasteBasket: case kMilkCrate: + case kStool: case kTrunk: case kManhole: + case kBooks: + thisRoom->objects[objActive].data.b.pict = tempObject.data.b.pict; + break; + + case kTable: case kShelf: case kCabinet: + case kCounter: case kDresser: case kDeckTable: + case kInvisObstacle: case kInvisBounce: + thisRoom->objects[objActive].data.b.bounds = tempObject.data.b.bounds; + QOffsetRect(&thisRoom->objects[objActive].data.b.bounds, 64, 0); + thisRoom->objects[objActive].data.b.pict = tempObject.data.b.pict; + break; + + case kRedClock: case kBlueClock: case kYellowClock: + case kCuckoo: case kPaper: case kBattery: + case kBands: case kGreaseRt: case kGreaseLf: + case kFoil: case kInvisBonus: case kStar: + case kSparkle: case kHelium: + thisRoom->objects[objActive].data.c.length = tempObject.data.c.length; + thisRoom->objects[objActive].data.c.points = tempObject.data.c.points; + thisRoom->objects[objActive].data.c.state = tempObject.data.c.state; + thisRoom->objects[objActive].data.c.initial = tempObject.data.c.initial; + break; + + case kSlider: + thisRoom->objects[objActive].data.c.topLeft.h = tempObject.data.c.topLeft.h + 64; + thisRoom->objects[objActive].data.c.length = tempObject.data.c.length; + thisRoom->objects[objActive].data.c.points = tempObject.data.c.points; + thisRoom->objects[objActive].data.c.state = tempObject.data.c.state; + thisRoom->objects[objActive].data.c.initial = tempObject.data.c.initial; + break; + + case kUpStairs: case kDownStairs: case kMailboxLf: + case kMailboxRt: case kFloorTrans: case kCeilingTrans: + case kDoorInLf: case kDoorInRt: case kDoorExRt: + case kDoorExLf: case kWindowInLf: case kWindowInRt: + case kWindowExRt: case kWindowExLf: + thisRoom->objects[objActive].data.d.tall = tempObject.data.d.tall; + thisRoom->objects[objActive].data.d.where = tempObject.data.d.where; + thisRoom->objects[objActive].data.d.who = tempObject.data.d.who; + thisRoom->objects[objActive].data.d.wide = tempObject.data.d.wide; + break; + + case kInvisTrans: case kDeluxeTrans: + thisRoom->objects[objActive].data.d.topLeft.h = tempObject.data.d.topLeft.h + 64; + thisRoom->objects[objActive].data.d.topLeft.v = tempObject.data.d.topLeft.v; + thisRoom->objects[objActive].data.d.tall = tempObject.data.d.tall; + thisRoom->objects[objActive].data.d.where = tempObject.data.d.where; + thisRoom->objects[objActive].data.d.who = tempObject.data.d.who; + thisRoom->objects[objActive].data.d.wide = tempObject.data.d.wide; + break; + + case kLightSwitch: case kMachineSwitch: case kThermostat: + case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: + case kTrigger: case kLgTrigger: case kSoundTrigger: + thisRoom->objects[objActive].data.e.delay = tempObject.data.e.delay; + thisRoom->objects[objActive].data.e.where = tempObject.data.e.where; + thisRoom->objects[objActive].data.e.who = tempObject.data.e.who; + thisRoom->objects[objActive].data.e.type = tempObject.data.e.type; + break; + + case kCeilingLight: case kLightBulb: case kTableLamp: + case kHipLamp: case kDecoLamp: case kFlourescent: + case kTrackLight: case kInvisLight: + thisRoom->objects[objActive].data.f.length = tempObject.data.f.length; + thisRoom->objects[objActive].data.f.byte0 = tempObject.data.f.byte0; + thisRoom->objects[objActive].data.f.byte1 = tempObject.data.f.byte1; + thisRoom->objects[objActive].data.f.initial = tempObject.data.f.initial; + thisRoom->objects[objActive].data.f.state = tempObject.data.f.state; + break; + + case kShredder: case kToaster: case kMacPlus: + case kGuitar: case kTV: case kCoffee: + case kOutlet: case kVCR: case kStereo: + case kMicrowave: case kCinderBlock: case kFlowerBox: + case kCDs: + thisRoom->objects[objActive].data.g.height = tempObject.data.g.height; + thisRoom->objects[objActive].data.g.byte0 = tempObject.data.g.byte0; + thisRoom->objects[objActive].data.g.delay = tempObject.data.g.delay; + thisRoom->objects[objActive].data.g.initial = tempObject.data.g.initial; + thisRoom->objects[objActive].data.g.state = tempObject.data.g.state; + break; + + case kCustomPict: + thisRoom->objects[objActive].data.g.topLeft.h = + tempObject.data.g.topLeft.h + 64; + thisRoom->objects[objActive].data.g.topLeft.v = tempObject.data.g.topLeft.v; + thisRoom->objects[objActive].data.g.height = tempObject.data.g.height; + thisRoom->objects[objActive].data.g.byte0 = tempObject.data.g.byte0; + thisRoom->objects[objActive].data.g.delay = tempObject.data.g.delay; + thisRoom->objects[objActive].data.g.initial = tempObject.data.g.initial; + thisRoom->objects[objActive].data.g.state = tempObject.data.g.state; + break; + + case kBalloon: case kCopterLf: case kCopterRt: + case kDartLf: case kDartRt: case kBall: + case kDrip: case kFish: case kCobweb: + thisRoom->objects[objActive].data.h.length = tempObject.data.h.length; + thisRoom->objects[objActive].data.h.delay = tempObject.data.h.delay; + thisRoom->objects[objActive].data.h.byte0 = tempObject.data.h.byte0; + thisRoom->objects[objActive].data.h.initial = tempObject.data.h.initial; + thisRoom->objects[objActive].data.h.state = tempObject.data.h.state; + break; + + case kOzma: case kMousehole: case kFireplace: + case kBear: case kCalendar: case kVase1: + case kVase2: case kBulletin: case kCloud: + case kFaucet: case kRug: case kChimes: + thisRoom->objects[objActive].data.i.pict = tempObject.data.i.pict; + break; + + case kMirror: case kFlower: case kWallWindow: + thisRoom->objects[objActive].data.i.bounds = tempObject.data.i.bounds; + QOffsetRect(&thisRoom->objects[objActive].data.i.bounds, 64, 0); + thisRoom->objects[objActive].data.i.pict = tempObject.data.i.pict; + break; + } + + if (KeepObjectLegal()) + { + } + handled = ObjectHasHandle(&direction, &dist); + + ReadyBackground(thisRoom->background, thisRoom->tiles); + GetThisRoomsObjRects(); + DrawThisRoomsObjects(); + InvalWindowRect(mainWindow, &mainWindowRect); + + if (handled) + { + StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); + HandleBlowerGlider(); + } + else + StartMarquee(&roomObjectRects[objActive]); + } +} + +//-------------------------------------------------------------- MoveObject + +void MoveObject (short whichWay, Boolean shiftDown) +{ +#ifndef COMPILEDEMO + Rect wasRect; + short deltaH, deltaV, increment; + short dist, direction; + char wasState; + + if (theMode != kEditMode) + return; + + StopMarquee(); + + if (shiftDown) + increment = 10; + else + { + if (objActive == kInitialGliderSelected) + { + increment = 1; + } + else + { + if ((whichWay == kBumpRight) || (whichWay == kBumpLeft)) + { + switch (thisRoom->objects[objActive].what) + { + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kGreaseRt: + case kGreaseLf: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + case kSlider: + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + case kToaster: + case kMacPlus: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kStereo: + case kMicrowave: + case kBalloon: + case kCopterLf: + case kCopterRt: + case kBall: + case kDrip: + case kFish: + case kMirror: + increment = 2; + break; + + case kManhole: + increment = 64; + break; + + default: + increment = 1; + break; + } + } + else + increment = 1; + } + } + + switch (whichWay) + { + case kBumpUp: + deltaH = 0; + deltaV = -increment; + break; + + case kBumpDown: + deltaH = 0; + deltaV = increment; + break; + + case kBumpRight: + deltaH = increment; + deltaV = 0; + break; + + case kBumpLeft: + deltaH = -increment; + deltaV = 0; + break; + } + + if (objActive == kInitialGliderSelected) + { + wasRect = initialGliderRect; + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + (*thisHouse)->initial.h += deltaH; + (*thisHouse)->initial.v += deltaV; + HSetState((Handle)thisHouse, wasState); + } + else if (objActive == kLeftGliderSelected) + { + wasRect = leftStartGliderDest; + increment = thisRoom->leftStart + deltaV; + if (increment > 255) + increment = 255; + else if (increment < 0) + increment = 0; + thisRoom->leftStart = (Byte)increment; + QSetRect(&leftStartGliderDest, 0, 0, 48, 16); + QOffsetRect(&leftStartGliderDest, 0, + kGliderStartsDown + (short)thisRoom->leftStart); + } + else if (objActive == kRightGliderSelected) + { + wasRect = rightStartGliderDest; + increment = thisRoom->rightStart + deltaV; + if (increment > 255) + increment = 255; + else if (increment < 0) + increment = 0; + thisRoom->rightStart = (Byte)increment; + QSetRect(&rightStartGliderDest, 0, 0, 48, 16); + QOffsetRect(&rightStartGliderDest, kRoomWide - 48, + kGliderStartsDown + (short)thisRoom->rightStart); + } + else + { + wasRect = roomObjectRects[objActive]; + switch (thisRoom->objects[objActive].what) + { + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kGrecoVent: + case kSewerBlower: + thisRoom->objects[objActive].data.a.topLeft.h += deltaH; + break; + + case kLeftFan: + case kRightFan: + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + case kInvisBlower: + case kLiftArea: + thisRoom->objects[objActive].data.a.topLeft.h += deltaH; + thisRoom->objects[objActive].data.a.topLeft.v += deltaV; + break; + + case kTable: + case kShelf: + case kCabinet: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kDeckTable: + case kStool: + case kTrunk: + case kInvisObstacle: + case kBooks: + case kInvisBounce: + thisRoom->objects[objActive].data.b.bounds.left += deltaH; + thisRoom->objects[objActive].data.b.bounds.right += deltaH; + thisRoom->objects[objActive].data.b.bounds.top += deltaV; + thisRoom->objects[objActive].data.b.bounds.bottom += deltaV; + break; + + case kCounter: + case kDresser: + case kManhole: + thisRoom->objects[objActive].data.b.bounds.left += deltaH; + thisRoom->objects[objActive].data.b.bounds.right += deltaH; + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kGreaseRt: + case kGreaseLf: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + case kSlider: + thisRoom->objects[objActive].data.c.topLeft.h += deltaH; + thisRoom->objects[objActive].data.c.topLeft.v += deltaV; + break; + + case kUpStairs: + case kDownStairs: + case kFloorTrans: + case kCeilingTrans: + thisRoom->objects[objActive].data.d.topLeft.h += deltaH; + break; + + case kMailboxLf: + case kMailboxRt: + case kInvisTrans: + case kDeluxeTrans: + thisRoom->objects[objActive].data.d.topLeft.h += deltaH; + thisRoom->objects[objActive].data.d.topLeft.v += deltaV; + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + thisRoom->objects[objActive].data.e.topLeft.h += deltaH; + thisRoom->objects[objActive].data.e.topLeft.v += deltaV; + break; + + case kCeilingLight: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + thisRoom->objects[objActive].data.f.topLeft.h += deltaH; + break; + + case kLightBulb: + case kTableLamp: + case kInvisLight: + thisRoom->objects[objActive].data.f.topLeft.h += deltaH; + thisRoom->objects[objActive].data.f.topLeft.v += deltaV; + break; + + case kShredder: + case kToaster: + case kMacPlus: + case kGuitar: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kStereo: + case kMicrowave: + case kCinderBlock: + case kFlowerBox: + case kCDs: + case kCustomPict: + thisRoom->objects[objActive].data.g.topLeft.h += deltaH; + thisRoom->objects[objActive].data.g.topLeft.v += deltaV; + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + thisRoom->objects[objActive].data.h.topLeft.h += deltaH; + break; + + case kDartLf: + case kDartRt: + thisRoom->objects[objActive].data.h.topLeft.v += deltaV; + break; + + case kBall: + case kDrip: + case kFish: + case kCobweb: + thisRoom->objects[objActive].data.h.topLeft.h += deltaH; + thisRoom->objects[objActive].data.h.topLeft.v += deltaV; + break; + + case kOzma: + case kMirror: + case kFlower: + case kWallWindow: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + case kChimes: + thisRoom->objects[objActive].data.i.bounds.left += deltaH; + thisRoom->objects[objActive].data.i.bounds.right += deltaH; + thisRoom->objects[objActive].data.i.bounds.top += deltaV; + thisRoom->objects[objActive].data.i.bounds.bottom += deltaV; + break; + + case kMousehole: + case kFireplace: + thisRoom->objects[objActive].data.i.bounds.left += deltaH; + thisRoom->objects[objActive].data.i.bounds.right += deltaH; + break; + + } + } + + if (KeepObjectLegal()) + { + } + fileDirty = true; + UpdateMenus(false); + GetThisRoomsObjRects(); + + if (objActive == kInitialGliderSelected) + { + InvalWindowRect(mainWindow, &wasRect); + InvalWindowRect(mainWindow, &initialGliderRect); + } + else if (objActive == kLeftGliderSelected) + { + InvalWindowRect(mainWindow, &wasRect); + InvalWindowRect(mainWindow, &leftStartGliderDest); + } + else if (objActive == kRightGliderSelected) + { + InvalWindowRect(mainWindow, &wasRect); + InvalWindowRect(mainWindow, &rightStartGliderDest); + } + else + { + switch (thisRoom->objects[objActive].what) + { + case kTiki: + case kTable: + case kShelf: + case kCabinet: + case kDeckTable: + case kStool: + case kCounter: + case kDresser: + case kGreaseRt: + case kGreaseLf: + case kSlider: + case kMailboxLf: + case kMailboxRt: + case kTrackLight: + case kMirror: + case kWallWindow: + InvalWindowRect(mainWindow, &mainWindowRect); + break; + + default: + InvalWindowRect(mainWindow, &wasRect); + InvalWindowRect(mainWindow, &roomObjectRects[objActive]); + break; + } + } + + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + + if (ObjectHasHandle(&direction, &dist)) + { + StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); + HandleBlowerGlider(); + } + else + { + if (objActive == kInitialGliderSelected) + StartMarquee(&initialGliderRect); + else if (objActive == kLeftGliderSelected) + StartMarquee(&leftStartGliderDest); + else if (objActive == kRightGliderSelected) + StartMarquee(&rightStartGliderDest); + else + StartMarquee(&roomObjectRects[objActive]); + } +#endif +} + +//-------------------------------------------------------------- DeselectObject + +void DeselectObject (void) +{ +#ifndef COMPILEDEMO + if ((theMode != kEditMode) || (objActive == kNoObjectSelected)) + return; + + objActive = kNoObjectSelected; + StopMarquee(); + UpdateMenus(false); +#endif +} + +//-------------------------------------------------------------- ObjectHasHandle + +#ifndef COMPILEDEMO +Boolean ObjectHasHandle (short *direction, short *dist) +{ + if ((objActive == kInitialGliderSelected) || + (objActive == kNoObjectSelected)) + return (false); + + switch (thisRoom->objects[objActive].what) + { + case kFloorVent: + case kFloorBlower: + case kSewerGrate: + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + case kGrecoVent: + case kSewerBlower: + *direction = kAbove; + *dist = thisRoom->objects[objActive].data.a.distance; + return (true); + break; + + case kCeilingVent: + case kCeilingBlower: + *direction = kBelow; + *dist = thisRoom->objects[objActive].data.a.distance; + return (true); + break; + + case kLeftFan: + *direction = kToLeft; + *dist = thisRoom->objects[objActive].data.a.distance; + return (true); + break; + + case kRightFan: + *direction = kToRight; + *dist = thisRoom->objects[objActive].data.a.distance; + return (true); + break; + + case kInvisBlower: + switch (thisRoom->objects[objActive].data.a.vector & 0x0F) + { + case 1: // up + *direction = kAbove; + break; + + case 2: // right + *direction = kToRight; + break; + + case 4: // down + *direction = kBelow; + break; + + case 8: // left + *direction = kToLeft; + break; + } + *dist = thisRoom->objects[objActive].data.a.distance; + return (true); + break; + + case kTable: + case kShelf: + case kDeckTable: + *direction = kToRight; + *dist = 0; + return (true); + break; + + case kLiftArea: + case kCabinet: + case kInvisObstacle: + case kInvisBounce: + case kMirror: + case kWallWindow: + *direction = kBottomCorner; + *dist = 0; + return (true); + break; + + case kCounter: + case kDresser: + *direction = kTopCorner; + *dist = 0; + return (true); + break; + + case kGreaseRt: + *direction = kToRight; + *dist = thisRoom->objects[objActive].data.c.length; + return (true); + break; + + case kGreaseLf: + *direction = kToLeft; + *dist = thisRoom->objects[objActive].data.c.length; + return (true); + break; + + case kSlider: + *direction = kToRight; + *dist = 0; + return (true); + break; + + case kInvisTrans: + case kDeluxeTrans: + *direction = kBottomCorner; + *dist = 0; + return (true); + break; + + case kFlourescent: + case kTrackLight: + *direction = kToRight; + *dist = 0; + return (true); + break; + + case kToaster: + *direction = kAbove; + *dist = thisRoom->objects[objActive].data.g.height; + return (true); + break; + + case kBall: + case kFish: + *direction = kAbove; + *dist = thisRoom->objects[objActive].data.h.length; + return (true); + break; + + case kDrip: + *direction = kBelow; + *dist = thisRoom->objects[objActive].data.h.length; + return (true); + break; + + default: + return (false); + break; + } +} +#endif + +//-------------------------------------------------------------- ObjectIsUpBlower + +Boolean ObjectIsUpBlower (objectType *who) +{ + if ((who->what == kFloorVent) || (who->what == kFloorBlower) || + (who->what == kSewerGrate) || (who->what == kTaper) || + (who->what == kCandle) || (who->what == kStubby) || + (who->what == kTiki) || (who->what == kBBQ) || + (who->what == kGrecoVent) || (who->what == kSewerBlower)) + return (true); + else if ((who->what == kInvisBlower) || (who->what == kLiftArea)) + { + if ((who->data.a.vector & 0x01) == 0x01) + return (true); + else + return (false); + } + else + return (false); +} + +//-------------------------------------------------------------- HandleBlowerGlider + +void HandleBlowerGlider (void) +{ +#ifndef COMPILEDEMO + short direction, dist; + + if (ObjectIsUpBlower(&thisRoom->objects[objActive])) + { + if (ObjectHasHandle(&direction, &dist)) + { + SetMarqueeGliderRect(((roomObjectRects[objActive].right + + roomObjectRects[objActive].left) / 2), + roomObjectRects[objActive].top - dist); + } + } +#endif +} + +//-------------------------------------------------------------- SelectNextObject + +void SelectNextObject (void) +{ +#ifndef COMPILEDEMO + short direction, dist; + Boolean noneFound; + + if ((theMode != kEditMode) || (thisRoom->numObjects <= 0)) + return; + + noneFound = true; + + while (noneFound) + { + objActive++; + if (objActive >= kMaxRoomObs) + objActive = 0; + if (thisRoom->objects[objActive].what != kObjectIsEmpty) + noneFound = false; + } + + UpdateMenus(false); + if (ObjectHasHandle(&direction, &dist)) + { + StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); + HandleBlowerGlider(); + } + else + StartMarquee(&roomObjectRects[objActive]); +#endif +} + +//-------------------------------------------------------------- SelectPrevObject + +void SelectPrevObject (void) +{ +#ifndef COMPILEDEMO + short direction, dist; + Boolean noneFound; + + if ((theMode != kEditMode) || (thisRoom->numObjects <= 0)) + return; + + noneFound = true; + + while (noneFound) + { + objActive--; + if (objActive < 0) + objActive = kMaxRoomObs - 1; + if (thisRoom->objects[objActive].what != kObjectIsEmpty) + noneFound = false; + } + + UpdateMenus(false); + if (ObjectHasHandle(&direction, &dist)) + { + StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); + HandleBlowerGlider(); + } + else + StartMarquee(&roomObjectRects[objActive]); +#endif +} + +//-------------------------------------------------------------- GetThisRoomsObjRects + +#ifndef COMPILEDEMO +void GetThisRoomsObjRects (void) +{ + PicHandle thePict; + short i, wide, tall; + + isFirstRoom = (GetFirstRoomNumber() == thisRoomNumber); + + if ((isFirstRoom) && (!noRoomAtAll) && (houseUnlocked)) + WhereDoesGliderBegin(&initialGliderRect, kNewGameMode); + else + QSetRect(&initialGliderRect, 0, 0, 0, 0); + + QSetRect(&leftStartGliderDest, 0, 0, 48, 16); + QOffsetRect(&leftStartGliderDest, 0, + kGliderStartsDown + (short)thisRoom->leftStart); + + QSetRect(&rightStartGliderDest, 0, 0, 48, 16); + QOffsetRect(&rightStartGliderDest, kRoomWide - 48, + kGliderStartsDown + (short)thisRoom->rightStart); + + if ((noRoomAtAll) || (!houseUnlocked)) + { + return; + } + else + { + for (i = 0; i < kMaxRoomObs; i++) + { + switch (thisRoom->objects[i].what) + { + case kObjectIsEmpty: + QSetRect(&roomObjectRects[i], -2, -2, -1, -1); + break; + + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kLeftFan: + case kRightFan: + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + case kInvisBlower: + case kGrecoVent: + case kSewerBlower: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.a.topLeft.h, + thisRoom->objects[i].data.a.topLeft.v); + break; + + case kLiftArea: + QSetRect(&roomObjectRects[i], 0, 0, + thisRoom->objects[i].data.a.distance, + thisRoom->objects[i].data.a.tall * 2); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.a.topLeft.h, + thisRoom->objects[i].data.a.topLeft.v); + break; + + case kTable: + case kShelf: + case kCabinet: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kCounter: + case kDresser: + case kDeckTable: + case kStool: + case kTrunk: + case kInvisObstacle: + case kManhole: + case kBooks: + case kInvisBounce: + roomObjectRects[i] = thisRoom->objects[i].data.b.bounds; + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.c.topLeft.h, + thisRoom->objects[i].data.c.topLeft.v); + break; + + case kGreaseRt: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.c.topLeft.h, + thisRoom->objects[i].data.c.topLeft.v); + if (!thisRoom->objects[i].data.c.initial) + QOffsetRect(&roomObjectRects[i], 8, 0); + break; + + case kGreaseLf: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.c.topLeft.h, + thisRoom->objects[i].data.c.topLeft.v); + if (!thisRoom->objects[i].data.c.initial) + QOffsetRect(&roomObjectRects[i], -8, 0); + break; + + case kSlider: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.c.topLeft.h, + thisRoom->objects[i].data.c.topLeft.v); + roomObjectRects[i].right = roomObjectRects[i].left + + thisRoom->objects[i].data.c.length; + break; + + case kUpStairs: + case kDownStairs: + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kDoorInLf: + case kDoorInRt: + case kDoorExRt: + case kDoorExLf: + case kWindowInLf: + case kWindowInRt: + case kWindowExRt: + case kWindowExLf: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.d.topLeft.h, + thisRoom->objects[i].data.d.topLeft.v); + break; + + case kInvisTrans: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.d.topLeft.h, + thisRoom->objects[i].data.d.topLeft.v); + roomObjectRects[i].bottom = roomObjectRects[i].top + + thisRoom->objects[i].data.d.tall; + roomObjectRects[i].right += (short)thisRoom->objects[i].data.d.wide; + break; + + case kDeluxeTrans: // Uses a kludge to get width & height (x4) + wide = (thisRoom->objects[i].data.d.tall & 0xFF00) >> 8; + tall = thisRoom->objects[i].data.d.tall & 0x00FF; + QSetRect(&roomObjectRects[i], 0, 0, wide * 4, tall * 4); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.d.topLeft.h, + thisRoom->objects[i].data.d.topLeft.v); + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.e.topLeft.h, + thisRoom->objects[i].data.e.topLeft.v); + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kInvisLight: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.f.topLeft.h, + thisRoom->objects[i].data.f.topLeft.v); + break; + + case kFlourescent: + case kTrackLight: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + roomObjectRects[i].right = thisRoom->objects[i].data.f.length; + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.f.topLeft.h, + thisRoom->objects[i].data.f.topLeft.v); + break; + + case kShredder: + case kToaster: + case kMacPlus: + case kGuitar: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kStereo: + case kMicrowave: + case kCinderBlock: + case kFlowerBox: + case kCDs: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.g.topLeft.h, + thisRoom->objects[i].data.g.topLeft.v); + break; + + case kCustomPict: + thePict = GetPicture(thisRoom->objects[i].data.g.height); + if (thePict == nil) + { + thisRoom->objects[i].data.g.height = 10000; + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + } + else + { + HLock((Handle)thePict); + roomObjectRects[i] = (*thePict)->picFrame; + HUnlock((Handle)thePict); + } + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.g.topLeft.h, + thisRoom->objects[i].data.g.topLeft.v); + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kBall: + case kDrip: + case kFish: + case kCobweb: + roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; + ZeroRectCorner(&roomObjectRects[i]); + QOffsetRect(&roomObjectRects[i], + thisRoom->objects[i].data.h.topLeft.h, + thisRoom->objects[i].data.h.topLeft.v); + break; + + case kOzma: + case kMirror: + case kMousehole: + case kFireplace: + case kFlower: + case kWallWindow: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + case kChimes: + roomObjectRects[i] = thisRoom->objects[i].data.i.bounds; + break; + + default: + QSetRect(&roomObjectRects[i], -2, -2, -1, -1); + break; + + } + } + } +} +#endif + +//-------------------------------------------------------------- DrawThisRoomsObjects + +#ifndef COMPILEDEMO +void DrawThisRoomsObjects (void) +{ + Rect tempRect; + short i; + CGrafPtr wasCPort; + GDHandle wasWorld; + Pattern dummyPattern; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + if ((noRoomAtAll) || (!houseUnlocked)) + return; + else + { + if (GetNumberOfLights(thisRoomNumber) <= 0) + { + PenMode(srcOr); + PenPat(GetQDGlobalsGray(&dummyPattern)); + PaintRect(&backSrcRect); + PenNormal(); + } + + for (i = 0; i < kMaxRoomObs; i++) + { + switch (thisRoom->objects[i].what) + { + case kObjectIsEmpty: + break; + + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kLeftFan: + case kRightFan: + case kTaper: + case kCandle: + case kStubby: + case kGrecoVent: + case kSewerBlower: + DrawSimpleBlowers(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kTiki: + DrawTiki(&roomObjectRects[i], 0); + break; + + case kInvisBlower: + DrawInvisibleBlower(&roomObjectRects[i]); + break; + + case kLiftArea: + DrawLiftArea(&roomObjectRects[i]); + break; + + case kTable: + DrawTable(&roomObjectRects[i], 0); + break; + + case kShelf: + DrawShelf(&roomObjectRects[i]); + break; + + case kCabinet: + DrawCabinet(&roomObjectRects[i]); + break; + + case kFilingCabinet: + case kDownStairs: + case kDoorExRt: + case kDoorExLf: + case kWindowExRt: + case kWindowExLf: + case kOzma: + DrawPictObject(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kWasteBasket: + case kMilkCrate: + DrawSimpleFurniture(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kCounter: + DrawCounter(&roomObjectRects[i]); + break; + + case kDresser: + DrawDresser(&roomObjectRects[i]); + break; + + case kDeckTable: + DrawDeckTable(&roomObjectRects[i], 0); + break; + + case kStool: + DrawStool(&roomObjectRects[i], 0); + break; + + case kInvisObstacle: + DrawInvisObstacle(&roomObjectRects[i]); + break; + + case kInvisBounce: + DrawInvisBounce(&roomObjectRects[i]); + break; + + case kRedClock: + DrawRedClock(&roomObjectRects[i]); + break; + + case kBlueClock: + DrawBlueClock(&roomObjectRects[i]); + break; + + case kYellowClock: + DrawYellowClock(&roomObjectRects[i]); + break; + + case kCuckoo: + DrawCuckoo(&roomObjectRects[i]); + break; + + case kPaper: + case kBattery: + case kBands: + case kStar: + case kSparkle: + case kHelium: + DrawSimplePrizes(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kGreaseRt: + tempRect = roomObjectRects[i]; + if (!thisRoom->objects[i].data.c.initial) + QOffsetRect(&tempRect, -8, 0); + DrawGreaseRt(&tempRect, thisRoom->objects[i].data.c.length, + thisRoom->objects[i].data.c.initial); + break; + + case kGreaseLf: + tempRect = roomObjectRects[i]; + if (!thisRoom->objects[i].data.c.initial) + QOffsetRect(&tempRect, 8, 0); + DrawGreaseLf(&tempRect, thisRoom->objects[i].data.c.length, + thisRoom->objects[i].data.c.initial); + break; + + case kFoil: + DrawFoil(&roomObjectRects[i]); + break; + + case kInvisBonus: + DrawInvisBonus(&roomObjectRects[i]); + break; + + case kSlider: + DrawSlider(&roomObjectRects[i]); + break; + + case kBBQ: + case kTrunk: + case kManhole: + case kBooks: + case kUpStairs: + case kDoorInLf: + case kDoorInRt: + case kWindowInLf: + case kWindowInRt: + case kHipLamp: + case kDecoLamp: + case kGuitar: + case kCinderBlock: + case kFlowerBox: + case kFireplace: + case kBear: + case kVase1: + case kVase2: + case kRug: + case kChimes: + DrawPictSansWhiteObject(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kCustomPict: + DrawCustPictSansWhite(thisRoom->objects[i].data.g.height, + &roomObjectRects[i]); + break; + + case kMailboxLf: + DrawMailboxLeft(&roomObjectRects[i], 0); + break; + + case kMailboxRt: + DrawMailboxRight(&roomObjectRects[i], 0); + break; + + case kFloorTrans: + case kCeilingTrans: + DrawSimpleTransport(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kInvisTrans: + case kDeluxeTrans: + DrawInvisTransport(&roomObjectRects[i]); + break; + + case kLightSwitch: + DrawLightSwitch(&roomObjectRects[i], true); + break; + + case kMachineSwitch: + DrawMachineSwitch(&roomObjectRects[i], true); + break; + + case kThermostat: + DrawThermostat(&roomObjectRects[i], true); + break; + + case kPowerSwitch: + DrawPowerSwitch(&roomObjectRects[i], true); + break; + + case kKnifeSwitch: + DrawKnifeSwitch(&roomObjectRects[i], true); + break; + + case kInvisSwitch: + DrawInvisibleSwitch(&roomObjectRects[i]); + break; + + case kTrigger: + case kLgTrigger: + DrawTrigger(&roomObjectRects[i]); + break; + + case kSoundTrigger: + DrawSoundTrigger(&roomObjectRects[i]); + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + DrawSimpleLight(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kFlourescent: + DrawFlourescent(&roomObjectRects[i]); + break; + + case kTrackLight: + DrawTrackLight(&roomObjectRects[i]); + break; + + case kInvisLight: + DrawInvisLight(&roomObjectRects[i]); + break; + + case kShredder: + case kToaster: + case kCDs: + DrawSimpleAppliance(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kMacPlus: + DrawMacPlus(&roomObjectRects[i], + thisRoom->objects[i].data.g.initial, true); + break; + + case kTV: + DrawTV(&roomObjectRects[i], + thisRoom->objects[i].data.g.initial, true); + break; + + case kCoffee: + DrawCoffee(&roomObjectRects[i], + thisRoom->objects[i].data.g.initial, true); + break; + + case kOutlet: + DrawOutlet(&roomObjectRects[i]); + break; + + case kVCR: + DrawVCR(&roomObjectRects[i], + thisRoom->objects[i].data.g.initial, true); + break; + + case kStereo: + DrawStereo(&roomObjectRects[i], isPlayMusicGame, true); + break; + + case kMicrowave: + DrawMicrowave(&roomObjectRects[i], + thisRoom->objects[i].data.g.initial, true); + break; + + case kBalloon: + DrawBalloon(&roomObjectRects[i]); + break; + + case kCopterLf: + case kCopterRt: + DrawCopter(&roomObjectRects[i]); + break; + + case kDartLf: + case kDartRt: + DrawDart(&roomObjectRects[i], thisRoom->objects[i].what); + break; + + case kBall: + DrawBall(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kDrip: + DrawDrip(&roomObjectRects[i]); + break; + + case kFish: + DrawFish(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kCobweb: + case kCloud: + DrawPictWithMaskObject(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kMirror: + DrawMirror(&roomObjectRects[i]); + break; + + case kMousehole: + case kFaucet: + DrawSimpleClutter(thisRoom->objects[i].what, &roomObjectRects[i]); + break; + + case kFlower: + DrawFlower(&roomObjectRects[i], thisRoom->objects[i].data.i.pict); + break; + + case kWallWindow: + DrawWallWindow(&roomObjectRects[i]); + break; + + case kCalendar: + DrawCalendar(&roomObjectRects[i]); + break; + + case kBulletin: + DrawBulletin(&roomObjectRects[i]); + break; + + default: + break; + } + } + } + + SetGWorld(wasCPort, wasWorld); + + if (isFirstRoom) + { + CopyMask((BitMap *)*GetGWorldPixMap(glidSrcMap), + (BitMap *)*GetGWorldPixMap(glidMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &gliderSrc[0], &gliderSrc[0], &initialGliderRect); + } + + CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), + (BitMap *)*GetGWorldPixMap(blowerMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &leftStartGliderSrc, &leftStartGliderSrc, &leftStartGliderDest); + + CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), + (BitMap *)*GetGWorldPixMap(blowerMaskMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &rightStartGliderSrc, &rightStartGliderSrc, &rightStartGliderDest); + + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &backSrcRect, &backSrcRect, srcCopy, nil); +} +#endif + +//-------------------------------------------------------------- HiliteAllObjects + +void HiliteAllObjects (void) +{ +#ifndef COMPILEDEMO + KeyMap theseKeys; + short i; + Pattern dummyPattern; + + if (theMode != kEditMode) + return; + + PauseMarquee(); + SetPort((GrafPtr)mainWindow); + PenPat(GetQDGlobalsGray(&dummyPattern)); + PenMode(patXor); + + for (i = 0; i < kMaxRoomObs; i++) + FrameRect(&roomObjectRects[i]); + + do + { + GetKeys(theseKeys); + } + while ((BitTst(&theseKeys, kCommandKeyMap)) && + (BitTst(&theseKeys, kOptionKeyMap))); + + for (i = 0; i < kMaxRoomObs; i++) + FrameRect(&roomObjectRects[i]); + + PenNormal(); + ResumeMarquee(); +#endif +} + +//-------------------------------------------------------------- GoToObjectInRoom + +void GoToObjectInRoom (short object, short floor, short suite) +{ + #ifndef COMPILEDEMO + short itsNumber, direction, dist; + + if (RoomExists(suite, floor, &itsNumber)) + { + if (itsNumber != thisRoomNumber) + { + CopyRoomToThisRoom(itsNumber); + DeselectObject(); + ReflectCurrentRoom(false); + } + else + DeselectObject(); + + if (thisRoom->objects[object].what != kObjectIsEmpty) + { + objActive = object; + if (ObjectHasHandle(&direction, &dist)) + { + StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); + HandleBlowerGlider(); + } + else + StartMarquee(&roomObjectRects[objActive]); + UpdateMenus(false); + } + } + #endif +} + +//-------------------------------------------------------------- GoToObjectInRoomNum + +void GoToObjectInRoomNum (short object, short roomNum) +{ + short floor, suite; + + if (GetRoomFloorSuite(roomNum, &floor, &suite)) + GoToObjectInRoom(object, floor, suite); +} + diff --git a/GpApp/ObjectEdit.h b/GpApp/ObjectEdit.h new file mode 100644 index 0000000..5d29758 --- /dev/null +++ b/GpApp/ObjectEdit.h @@ -0,0 +1,15 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// ObjectEdit.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#pragma once + + +#include "PLQuickdraw.h" + + +extern Rect roomObjectRects[]; +extern short objActive; diff --git a/GpApp/ObjectInfo.cpp b/GpApp/ObjectInfo.cpp new file mode 100644 index 0000000..cfe09b4 --- /dev/null +++ b/GpApp/ObjectInfo.cpp @@ -0,0 +1,2568 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// ObjectInfo.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLNumberFormatting.h" +#include "PLSound.h" +#include "PLTextUtils.h" +#include "PLPasStr.h" +#include "DialogUtils.h" +#include "Externs.h" +#include "ObjectEdit.h" +#include "RectUtils.h" + + +#define kBlowerInfoDialogID 1007 +#define kFurnitureInfoDialogID 1010 +#define kSwitchInfoDialogID 1011 +#define kLightInfoDialogID 1013 +#define kApplianceInfoDialogID 1014 +#define kInvisBonusInfoDialogID 1015 +#define kGreaseInfoDialogID 1019 +#define kTransInfoDialogID 1022 +#define kEnemyInfoDialogID 1027 +#define kFlowerInfoDialogID 1033 +#define kTriggerInfoDialogID 1034 +#define kMicrowaveInfoDialogID 1035 +#define kCustPictInfoDialogID 1045 +#define kCustPictIDItem 7 +#define kInitialStateCheckbox 6 +#define kForceCheckbox 7 +#define kDirectionText 9 +#define kLeftFacingRadio 16 +#define kRightFacingRadio 17 +#define kToggleRadio 6 +#define kForceOnRadio 7 +#define kForceOffRadio 8 +#define kDelay3Item 6 +#define kDelayItem 8 +#define kDelayLabelItem 9 +#define k100PtRadio 6 +#define k300PtRadio 7 +#define k500PtRadio 8 +#define kGreaseItem 6 +#define kLinkTransButton 6 +#define kInitialStateCheckbox3 13 +#define kTransRoomText 8 +#define kTransObjectText 9 +#define kKillBandsCheckbox 8 +#define kKillBatteryCheckbox 9 +#define kKillFoilCheckbox 10 +#define kDelay2Item 7 +#define kDelay2LabelItem 8 +#define kDelay2LabelItem2 9 +#define kInitialStateCheckbox2 10 +#define kRadioFlower1 6 +#define kRadioFlower6 11 +#define kFlowerCancel 12 +#define kGotoButton1 11 +#define kGotoButton2 14 + + +void UpdateBlowerInfo (DialogPtr); +void UpdateFurnitureInfo (DialogPtr); +void UpdateCustPictInfo (DialogPtr); +void UpdateSwitchInfo (DialogPtr); +void UpdateTriggerInfo (DialogPtr); +void UpdateLightInfo (DialogPtr); +void UpdateApplianceInfo (DialogPtr); +void UpdateMicrowaveInfo (DialogPtr); +void UpdateGreaseInfo (DialogPtr); +void UpdateInvisBonusInfo (DialogPtr); +void UpdateTransInfo (DialogPtr); +void UpdateEnemyInfo (DialogPtr); +void UpdateFlowerInfo (DialogPtr); +Boolean BlowerFilter (DialogPtr, EventRecord *, short *); +Boolean FurnitureFilter (DialogPtr, EventRecord *, short *); +Boolean CustPictFilter (DialogPtr, EventRecord *, short *); +Boolean SwitchFilter (DialogPtr, EventRecord *, short *); +Boolean TriggerFilter (DialogPtr, EventRecord *, short *); +Boolean LightFilter (DialogPtr, EventRecord *, short *); +Boolean ApplianceFilter (DialogPtr, EventRecord *, short *); +Boolean MicrowaveFilter (DialogPtr, EventRecord *, short *); +Boolean GreaseFilter (DialogPtr, EventRecord *, short *); +Boolean InvisBonusFilter (DialogPtr, EventRecord *, short *); +Boolean TransFilter (DialogPtr, EventRecord *, short *); +Boolean EnemyFilter (DialogPtr, EventRecord *, short *); +Boolean FlowerFilter (DialogPtr, EventRecord *, short *); +void DoBlowerObjectInfo (short); +void DoFurnitureObjectInfo (void); +void DoCustPictObjectInfo (void); +void DoSwitchObjectInfo (void); +void DoTriggerObjectInfo (void); +void DoLightObjectInfo (void); +void DoApplianceObjectInfo (short); +void DoMicrowaveObjectInfo (void); +void DoGreaseObjectInfo (void); +void DoInvisBonusObjectInfo (void); +void DoTransObjectInfo (short); +void DoEnemyObjectInfo (short); +void DoFlowerObjectInfo (void); + + +short newDirection, newPoint; +Byte newType; + +extern retroLink retroLinkList[]; +extern short linkRoom, linkType, wasFlower; +extern Byte linkObject; +extern Boolean linkerIsSwitch; + + +#ifndef COMPILEDEMO + +//============================================================== Functions +//-------------------------------------------------------------- UpdateBlowerInfo + +void UpdateBlowerInfo (DialogPtr theDialog) +{ + #define kArrowheadLength 4 + Rect bounds; + + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 5, kRedOrangeColor8); + + if ((thisRoom->objects[objActive].what != kLeftFan) && + (thisRoom->objects[objActive].what != kRightFan)) + { + GetDialogItemRect(theDialog, 8, &bounds); + bounds.right += 2; + bounds.bottom += 2; + EraseRect(&bounds); + bounds.right -= 2; + bounds.bottom -= 2; + PenSize(2, 2); + + switch (newDirection) + { + case 1: // up + MoveTo(bounds.left + HalfRectWide(&bounds), bounds.top); + Line(0, RectTall(&bounds)); + MoveTo(bounds.left + HalfRectWide(&bounds), bounds.top); + Line(kArrowheadLength, kArrowheadLength); + MoveTo(bounds.left + HalfRectWide(&bounds), bounds.top); + Line(-kArrowheadLength, kArrowheadLength); + break; + + case 2: // right + MoveTo(bounds.right, bounds.top + HalfRectTall(&bounds)); + Line(-RectWide(&bounds), 0); + MoveTo(bounds.right, bounds.top + HalfRectTall(&bounds)); + Line(-kArrowheadLength, kArrowheadLength); + MoveTo(bounds.right, bounds.top + HalfRectTall(&bounds)); + Line(-kArrowheadLength, -kArrowheadLength); + break; + + case 4: // down + MoveTo(bounds.left + HalfRectWide(&bounds), bounds.top); + Line(0, RectTall(&bounds)); + MoveTo(bounds.left + HalfRectWide(&bounds), bounds.bottom); + Line(kArrowheadLength, -kArrowheadLength); + MoveTo(bounds.left + HalfRectWide(&bounds), bounds.bottom); + Line(-kArrowheadLength, -kArrowheadLength); + break; + + case 8: // left + MoveTo(bounds.left, bounds.top + HalfRectTall(&bounds)); + Line(RectWide(&bounds), 0); + MoveTo(bounds.left, bounds.top + HalfRectTall(&bounds)); + Line(kArrowheadLength, -kArrowheadLength); + MoveTo(bounds.left, bounds.top + HalfRectTall(&bounds)); + Line(kArrowheadLength, kArrowheadLength); + break; + + default: + break; + } + + PenNormal(); + + if ((thisRoom->objects[objActive].what == kInvisBlower) || + (thisRoom->objects[objActive].what == kLiftArea)) + { + switch (newDirection) + { + case 1: // up + EraseDialogItem(theDialog, 11); + FrameOvalDialogItem(theDialog, 12); + FrameOvalDialogItem(theDialog, 13); + FrameOvalDialogItem(theDialog, 14); + break; + + case 2: // right + FrameOvalDialogItem(theDialog, 11); + EraseDialogItem(theDialog, 12); + FrameOvalDialogItem(theDialog, 13); + FrameOvalDialogItem(theDialog, 14); + break; + + case 4: // down + FrameOvalDialogItem(theDialog, 11); + FrameOvalDialogItem(theDialog, 12); + EraseDialogItem(theDialog, 13); + FrameOvalDialogItem(theDialog, 14); + break; + + case 8: // left + FrameOvalDialogItem(theDialog, 11); + FrameOvalDialogItem(theDialog, 12); + FrameOvalDialogItem(theDialog, 13); + EraseDialogItem(theDialog, 14); + break; + } + } + } +} + +//-------------------------------------------------------------- UpdateFurnitureInfo + +void UpdateFurnitureInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 4, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateCustPictInfo + +void UpdateCustPictInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 5, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateSwitchInfo + +void UpdateSwitchInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + SelectFromRadioGroup(theDialog, newType + kToggleRadio, + kToggleRadio, kForceOffRadio); + FrameDialogItemC(theDialog, 4, kRedOrangeColor8); + FrameDialogItemC(theDialog, 13, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateTriggerInfo + +void UpdateTriggerInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 4, kRedOrangeColor8); + FrameDialogItemC(theDialog, 13, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateLightInfo + +void UpdateLightInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 5, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateApplianceInfo + +void UpdateApplianceInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 5, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateMicrowaveInfo + +void UpdateMicrowaveInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 5, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateGreaseInfo + +void UpdateGreaseInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 5, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateInvisBonusInfo + +void UpdateInvisBonusInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + SelectFromRadioGroup(theDialog, newPoint + k100PtRadio, + k100PtRadio, k500PtRadio); + FrameDialogItemC(theDialog, 4, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateTransInfo + +void UpdateTransInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 4, kRedOrangeColor8); + FrameDialogItemC(theDialog, 10, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateEnemyInfo + +void UpdateEnemyInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 4, kRedOrangeColor8); +} + +//-------------------------------------------------------------- UpdateFlowerInfo + +void UpdateFlowerInfo (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + FrameDialogItemC(theDialog, 4, kRedOrangeColor8); +} + +//-------------------------------------------------------------- BlowerFilter + +Boolean BlowerFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + case kTabKeyASCII: +// SelectDialogItemText(dial, kRoomNameItem, 0, 1024); + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + return(false); + break; + + case mouseUp: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateBlowerInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- FurnitureFilter + +Boolean FurnitureFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + default: + return(false); + } + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateFurnitureInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- CustPictFilter + +Boolean CustPictFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + default: + return(false); + } + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateCustPictInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- SwitchFilter + +Boolean SwitchFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + default: + return(false); + } + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateSwitchInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- TriggerFilter + +Boolean TriggerFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + case kTabKeyASCII: + SelectDialogItemText(dial, kDelay3Item, 0, 1024); + return(true); + break; + + default: + return(false); + } + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateTriggerInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- LightFilter + +Boolean LightFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + return(false); + break; + + case mouseUp: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateLightInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- ApplianceFilter + +Boolean ApplianceFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + case kTabKeyASCII: + SelectDialogItemText(dial, kDelayItem, 0, 1024); + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + return(false); + break; + + case mouseUp: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateApplianceInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- MicrowaveFilter + +Boolean MicrowaveFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + return(false); + break; + + case mouseUp: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateMicrowaveInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- GreaseFilter + +Boolean GreaseFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + default: + return(false); + } + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateGreaseInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- InvisBonusFilter + +Boolean InvisBonusFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + default: + return(false); + } + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateInvisBonusInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- TransFilter + +Boolean TransFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + default: + return(false); + } + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateTransInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- EnemyFilter + +Boolean EnemyFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + case kTabKeyASCII: + SelectDialogItemText(dial, kDelay2Item, 0, 1024); + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + return(false); + break; + + case mouseUp: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateEnemyInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- EnemyFilter + +Boolean FlowerFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + return(false); + break; + + case mouseUp: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateFlowerInfo(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- DoBlowerObjectInfo + +void DoBlowerObjectInfo (short what) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr, distStr; + short item, initial; + Boolean leaving, doReturn, leftFacing; + ModalFilterUPP blowerFilterUPP; + + blowerFilterUPP = NewModalFilterUPP(BlowerFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + NumToString(thisRoom->objects[objActive].data.a.distance, distStr); + ParamText(numberStr, kindStr, distStr, PSTR("")); + +// CenterDialog(kBlowerInfoDialogID); + infoDial = GetNewDialog(kBlowerInfoDialogID, nil, kPutInFront); + if (infoDial == nil) + RedAlert(kErrDialogDidntLoad); + SetPort((GrafPtr)infoDial); + + newDirection = thisRoom->objects[objActive].data.a.vector & 0x0F; + if (thisRoom->objects[objActive].data.a.initial) + SetDialogItemValue(infoDial, kInitialStateCheckbox, 1); + else + SetDialogItemValue(infoDial, kInitialStateCheckbox, 0); + + if ((what == kTaper) || (what == kCandle) || (what == kStubby) || + (what == kTiki) || (what == kBBQ)) + { + HideDialogItem(infoDial, kInitialStateCheckbox); + } + + if ((what == kLeftFan) || (what == kRightFan)) + { + if (what == kLeftFan) + { + SelectFromRadioGroup(infoDial, kLeftFacingRadio, + kLeftFacingRadio, kRightFacingRadio); + leftFacing = true; + } + else + { + SelectFromRadioGroup(infoDial, kRightFacingRadio, + kLeftFacingRadio, kRightFacingRadio); + leftFacing = false; + } + HideDialogItem(infoDial, kDirectionText); + } + else + { + HideDialogItem(infoDial, kLeftFacingRadio); + HideDialogItem(infoDial, kRightFacingRadio); + } + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 15); + + ShowWindow(GetDialogWindow(infoDial)); + + leaving = false; + doReturn = false; + + while (!leaving) + { + ModalDialog(blowerFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); + if (initial == 1) + thisRoom->objects[objActive].data.a.initial = true; + else + thisRoom->objects[objActive].data.a.initial = false; + thisRoom->objects[objActive].data.a.vector = (Byte)newDirection; + if ((what == kLeftFan) || (what == kRightFan)) + { + if (leftFacing) + thisRoom->objects[objActive].what = kLeftFan; + else + thisRoom->objects[objActive].what = kRightFan; + if (KeepObjectLegal()) + { + } + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + } + fileDirty = true; + UpdateMenus(false); + leaving = true; + } + else if (item == kCancelButton) + leaving = true; + else if (item == kInitialStateCheckbox) + ToggleDialogItemValue(infoDial, kInitialStateCheckbox); + else if (item == 15) // Linked From? button. + { + GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); + if (initial == 1) + thisRoom->objects[objActive].data.a.initial = true; + else + thisRoom->objects[objActive].data.a.initial = false; + thisRoom->objects[objActive].data.a.vector = (Byte)newDirection; + if ((what == kLeftFan) || (what == kRightFan)) + { + if (leftFacing) + thisRoom->objects[objActive].what = kLeftFan; + else + thisRoom->objects[objActive].what = kRightFan; + if (KeepObjectLegal()) + { + } + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + } + fileDirty = true; + UpdateMenus(false); + leaving = true; + doReturn = true; + } + else if (item == kLeftFacingRadio) + { + leftFacing = true; + SelectFromRadioGroup(infoDial, kLeftFacingRadio, kLeftFacingRadio, + kRightFacingRadio); + } + else if (item == kRightFacingRadio) + { + leftFacing = false; + SelectFromRadioGroup(infoDial, kRightFacingRadio, kLeftFacingRadio, + kRightFacingRadio); + } + else if ((thisRoom->objects[objActive].what == kInvisBlower) || + (thisRoom->objects[objActive].what == kLiftArea)) + { + switch (item) + { + case 11: + newDirection = 0x01; + break; + + case 12: + newDirection = 0x02; + break; + + case 13: + newDirection = 0x04; + break; + + case 14: + newDirection = 0x08; + break; + } + UpdateBlowerInfo(infoDial); + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(blowerFilterUPP); + + if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoFurnitureObjectInfo + +void DoFurnitureObjectInfo (void) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr; + short item; + Boolean leaving, doReturn; + ModalFilterUPP furnitureFilterUPP; + + furnitureFilterUPP = NewModalFilterUPP(FurnitureFilter); + + if (objActive == kInitialGliderSelected) + { + PasStringCopy(PSTR("-"), numberStr); + PasStringCopy(PSTR("Glider Begins"), kindStr); + } + else if (objActive == kLeftGliderSelected) + { + PasStringCopy(PSTR("-"), numberStr); + PasStringCopy(PSTR("New Glider (left)"), kindStr); + } + else if (objActive == kRightGliderSelected) + { + PasStringCopy(PSTR("-"), numberStr); + PasStringCopy(PSTR("New Glider (right)"), kindStr); + } + else + { + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + } + ParamText(numberStr, kindStr, PSTR(""), PSTR("")); + + BringUpDialog(&infoDial, kFurnitureInfoDialogID); + + if ((objActive < 0) || (retroLinkList[objActive].room == -1)) + HideDialogItem(infoDial, 6); + + leaving = false; + doReturn = false; + + while (!leaving) + { + ModalDialog(furnitureFilterUPP, &item); + + if (item == kOkayButton) + leaving = true; + else if (item == 6) // Linked From? button. + { + leaving = true; + doReturn = true; + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(furnitureFilterUPP); + + if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoCustPictObjectInfo + +void DoCustPictObjectInfo (void) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr; + long wasPict; + short item; + Boolean leaving; + ModalFilterUPP custPictFilterUPP; + + custPictFilterUPP = NewModalFilterUPP(CustPictFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + if (thisRoom->objects[objActive].what == kCustomPict) + ParamText(numberStr, kindStr, PSTR("PICT"), PSTR("10000")); + else + ParamText(numberStr, kindStr, PSTR("Sound"), PSTR("3000")); + + BringUpDialog(&infoDial, kCustPictInfoDialogID); + if (thisRoom->objects[objActive].what == kCustomPict) + { + wasPict = (long)(thisRoom->objects[objActive].data.g.height); + SetDialogNumToStr(infoDial, kCustPictIDItem, wasPict); + } + else + { + wasPict = (long)(thisRoom->objects[objActive].data.e.where); + SetDialogNumToStr(infoDial, kCustPictIDItem, wasPict); + } + SelectDialogItemText(infoDial, kCustPictIDItem, 0, 1024); + leaving = false; + + while (!leaving) + { + ModalDialog(custPictFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogNumFromStr(infoDial, kCustPictIDItem, &wasPict); + if (thisRoom->objects[objActive].what == kCustomPict) + { + if ((wasPict < 10000L) || (wasPict > 32767L)) + { + SysBeep(1); + wasPict = (long)(thisRoom->objects[objActive].data.g.height); + SetDialogNumToStr(infoDial, kCustPictIDItem, wasPict); + SelectDialogItemText(infoDial, kCustPictIDItem, 0, 1024); + } + else + { + thisRoom->objects[objActive].data.g.height = (short)wasPict; + if (KeepObjectLegal()) + { + } + fileDirty = true; + UpdateMenus(false); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + leaving = true; + } + } + else + { + if ((wasPict < 3000L) || (wasPict > 32767L)) + { + SysBeep(1); + wasPict = (long)(thisRoom->objects[objActive].data.e.where); + SetDialogNumToStr(infoDial, kCustPictIDItem, wasPict); + SelectDialogItemText(infoDial, kCustPictIDItem, 0, 1024); + } + else + { + thisRoom->objects[objActive].data.e.where = (short)wasPict; + fileDirty = true; + UpdateMenus(false); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + leaving = true; + } + } + } + else if (item == kCancelButton) + { + leaving = true; + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(custPictFilterUPP); +} + +//-------------------------------------------------------------- DoSwitchObjectInfo + +void DoSwitchObjectInfo (void) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr, roomStr, tempStr, objStr; + short item, floor, suite; + Boolean leaving, doLink, doGoTo, doReturn; + ModalFilterUPP switchFilterUPP; + + switchFilterUPP = NewModalFilterUPP(SwitchFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + if (thisRoom->objects[objActive].data.e.where == -1) + PasStringCopy(PSTR("none"), roomStr); + else + { + ExtractFloorSuite(thisRoom->objects[objActive].data.e.where, &floor, &suite); + NumToString((long)floor, roomStr); + PasStringConcat(roomStr, PSTR(" / ")); + NumToString((long)suite, tempStr); + PasStringConcat(roomStr, tempStr); + } + + if (thisRoom->objects[objActive].data.e.who == 255) + PasStringCopy(PSTR("none"), objStr); + else + NumToString((long)thisRoom->objects[objActive].data.e.who + 1, objStr); + + ParamText(numberStr, kindStr, roomStr, objStr); + newType = thisRoom->objects[objActive].data.e.type; + + BringUpDialog(&infoDial, kSwitchInfoDialogID); + leaving = false; + doLink = false; + doGoTo = false; + doReturn = false; + + if (thisRoom->objects[objActive].data.e.who == 255) + MyDisableControl(infoDial, kGotoButton2); + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 15); + + while (!leaving) + { + ModalDialog(switchFilterUPP, &item); + + if (item == kOkayButton) + { + thisRoom->objects[objActive].data.e.type = newType; + fileDirty = true; + UpdateMenus(false); + leaving = true; + } + else if (item == kCancelButton) + leaving = true; + else if (item == kToggleRadio) + { + SelectFromRadioGroup(infoDial, item, kToggleRadio, kForceOffRadio); + newType = kToggle; + } + else if (item == kForceOnRadio) + { + SelectFromRadioGroup(infoDial, item, kToggleRadio, kForceOffRadio); + newType = kForceOn; + } + else if (item == kForceOffRadio) + { + SelectFromRadioGroup(infoDial, item, kToggleRadio, kForceOffRadio); + newType = kForceOff; + } + else if (item == 9) + { + thisRoom->objects[objActive].data.e.type = newType; + fileDirty = true; + UpdateMenus(false); + leaving = true; + doLink = true; + } + else if (item == kGotoButton2) + { + thisRoom->objects[objActive].data.e.type = newType; + fileDirty = true; + UpdateMenus(false); + leaving = true; + doGoTo = true; + } + else if (item == 15) // Linked From? button. + { + thisRoom->objects[objActive].data.e.type = newType; + fileDirty = true; + UpdateMenus(false); + leaving = true; + doReturn = true; + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(switchFilterUPP); + + if (doLink) + { + linkType = kSwitchLinkOnly; + linkerIsSwitch = true; + OpenLinkWindow(); + linkRoom = thisRoomNumber; + linkObject = (Byte)objActive; + DeselectObject(); + } + else if (doGoTo) + { + GoToObjectInRoom((short)thisRoom->objects[objActive].data.e.who, floor, suite); + } + else if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoTriggerObjectInfo + +void DoTriggerObjectInfo (void) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr, roomStr, tempStr, objStr; + long delayIs; + short item, floor, suite; + Boolean leaving, doLink, doGoTo, doReturn; + ModalFilterUPP triggerFilterUPP; + + triggerFilterUPP = NewModalFilterUPP(TriggerFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + if (thisRoom->objects[objActive].data.e.where == -1) + PasStringCopy(PSTR("none"), roomStr); + else + { + ExtractFloorSuite(thisRoom->objects[objActive].data.e.where, &floor, &suite); + NumToString((long)floor, roomStr); + PasStringConcat(roomStr, PSTR(" / ")); + NumToString((long)suite, tempStr); + PasStringConcat(roomStr, tempStr); + } + + if (thisRoom->objects[objActive].data.e.who == 255) + PasStringCopy(PSTR("none"), objStr); + else + NumToString((long)thisRoom->objects[objActive].data.e.who + 1, objStr); + + ParamText(numberStr, kindStr, roomStr, objStr); + newType = thisRoom->objects[objActive].data.e.type; + + BringUpDialog(&infoDial, kTriggerInfoDialogID); + leaving = false; + doLink = false; + doGoTo = false; + doReturn = false; + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 15); + + if (thisRoom->objects[objActive].data.e.who == 255) + MyDisableControl(infoDial, kGotoButton2); + + SetDialogNumToStr(infoDial, kDelay3Item, + (long)thisRoom->objects[objActive].data.e.delay); + SelectDialogItemText(infoDial, kDelay3Item, 0, 1024); + + while (!leaving) + { + ModalDialog(triggerFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogNumFromStr(infoDial, kDelay3Item, &delayIs); + if ((delayIs < 0L) || (delayIs > 32767L)) + { + SysBeep(1); + SetDialogNumToStr(infoDial, kDelay3Item, + (long)thisRoom->objects[objActive].data.e.delay); + SelectDialogItemText(infoDial, kDelay3Item, 0, 1024); + } + else + { + thisRoom->objects[objActive].data.e.delay = (short)delayIs; + fileDirty = true; + UpdateMenus(false); + leaving = true; + } + } + else if (item == kCancelButton) + leaving = true; + else if (item == 9) + { + GetDialogNumFromStr(infoDial, kDelay3Item, &delayIs); + if ((delayIs < 0L) || (delayIs > 32767L)) + { + SysBeep(1); + SetDialogNumToStr(infoDial, kDelay3Item, + (long)thisRoom->objects[objActive].data.e.delay); + SelectDialogItemText(infoDial, kDelay3Item, 0, 1024); + } + else + { + thisRoom->objects[objActive].data.e.delay = (short)delayIs; + fileDirty = true; + UpdateMenus(false); + leaving = true; + doLink = true; + } + } + else if (item == kGotoButton2) + { + GetDialogNumFromStr(infoDial, kDelay3Item, &delayIs); + if ((delayIs < 0L) || (delayIs > 32767L)) + { + SysBeep(1); + SetDialogNumToStr(infoDial, kDelay3Item, + (long)thisRoom->objects[objActive].data.e.delay); + SelectDialogItemText(infoDial, kDelay3Item, 0, 1024); + } + else + { + thisRoom->objects[objActive].data.e.delay = (short)delayIs; + fileDirty = true; + UpdateMenus(false); + leaving = true; + doGoTo = true; + } + } + else if (item == 15) // Linked From? button. + { + GetDialogNumFromStr(infoDial, kDelay3Item, &delayIs); + if ((delayIs < 0L) || (delayIs > 32767L)) + { + SysBeep(1); + SetDialogNumToStr(infoDial, kDelay3Item, + (long)thisRoom->objects[objActive].data.e.delay); + SelectDialogItemText(infoDial, kDelay3Item, 0, 1024); + } + else + { + thisRoom->objects[objActive].data.e.delay = (short)delayIs; + fileDirty = true; + UpdateMenus(false); + leaving = true; + doReturn = true; + } + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(triggerFilterUPP); + + if (doLink) + { + linkType = kTriggerLinkOnly; + linkerIsSwitch = true; + OpenLinkWindow(); + linkRoom = thisRoomNumber; + linkObject = (Byte)objActive; + DeselectObject(); + } + else if (doGoTo) + { + GoToObjectInRoom((short)thisRoom->objects[objActive].data.e.who, floor, suite); + } + else if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoLightObjectInfo + +void DoLightObjectInfo (void) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr; + short item, initial; + Boolean leaving, doReturn; + ModalFilterUPP lightFilterUPP; + + lightFilterUPP = NewModalFilterUPP(LightFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + ParamText(numberStr, kindStr, PSTR(""), PSTR("")); + +// CenterDialog(kLightInfoDialogID); + infoDial = GetNewDialog(kLightInfoDialogID, nil, kPutInFront); + if (infoDial == nil) + RedAlert(kErrDialogDidntLoad); + SetPort((GrafPtr)infoDial); + + if (thisRoom->objects[objActive].data.f.initial) + SetDialogItemValue(infoDial, kInitialStateCheckbox, 1); + else + SetDialogItemValue(infoDial, kInitialStateCheckbox, 0); + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 8); + + ShowWindow(GetDialogWindow(infoDial)); + + leaving = false; + doReturn = false; + + while (!leaving) + { + ModalDialog(lightFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); + if (initial == 1) + thisRoom->objects[objActive].data.f.initial = true; + else + thisRoom->objects[objActive].data.f.initial = false; + + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + InvalWindowRect(mainWindow, &mainWindowRect); + fileDirty = true; + UpdateMenus(false); + leaving = true; + } + else if (item == kCancelButton) + leaving = true; + else if (item == kInitialStateCheckbox) + ToggleDialogItemValue(infoDial, kInitialStateCheckbox); + else if (item == 8) // Linked From? button. + { + GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); + if (initial == 1) + thisRoom->objects[objActive].data.f.initial = true; + else + thisRoom->objects[objActive].data.f.initial = false; + + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + InvalWindowRect(mainWindow, &mainWindowRect); + fileDirty = true; + UpdateMenus(false); + leaving = true; + doReturn = true; + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(lightFilterUPP); + + if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoApplianceObjectInfo + +void DoApplianceObjectInfo (short what) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr; + long delay; + short item, initial; + Boolean leaving, doReturn; + ModalFilterUPP applianceFilterUPP; + + applianceFilterUPP = NewModalFilterUPP(ApplianceFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + ParamText(numberStr, kindStr, PSTR(""), PSTR("")); + + BringUpDialog(&infoDial, kApplianceInfoDialogID); + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 10); + + if (thisRoom->objects[objActive].data.g.initial) + SetDialogItemValue(infoDial, kInitialStateCheckbox, 1); + else + SetDialogItemValue(infoDial, kInitialStateCheckbox, 0); + + if ((what == kShredder) || (what == kMacPlus) || (what == kTV) || + (what == kCoffee) || (what == kVCR) || (what == kMicrowave)) + { + HideDialogItem(infoDial, kDelayItem); + HideDialogItem(infoDial, kDelayLabelItem); + } + + delay = thisRoom->objects[objActive].data.g.delay; + SetDialogNumToStr(infoDial, kDelayItem, (long)delay); + SelectDialogItemText(infoDial, kDelayItem, 0, 1024); + + leaving = false; + doReturn = false; + + while (!leaving) + { + ModalDialog(applianceFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogNumFromStr(infoDial, kDelayItem, &delay); + if ((delay < 0L) || (delay > 255L)) + { + SysBeep(0); + delay = thisRoom->objects[objActive].data.g.delay; + SetDialogNumToStr(infoDial, kDelayItem, (long)delay); + SelectDialogItemText(infoDial, kDelayItem, 0, 1024); + } + else + { + thisRoom->objects[objActive].data.g.delay = (Byte)delay; + GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); + if (initial == 1) + thisRoom->objects[objActive].data.g.initial = true; + else + thisRoom->objects[objActive].data.g.initial = false; + fileDirty = true; + UpdateMenus(false); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + leaving = true; + } + } + else if (item == kCancelButton) + leaving = true; + else if (item == kInitialStateCheckbox) + ToggleDialogItemValue(infoDial, kInitialStateCheckbox); + else if (item == 10) // Linked From? button. + { + GetDialogNumFromStr(infoDial, kDelayItem, &delay); + if ((delay < 0L) || (delay > 255L)) + { + SysBeep(0); + delay = thisRoom->objects[objActive].data.g.delay; + SetDialogNumToStr(infoDial, kDelayItem, (long)delay); + SelectDialogItemText(infoDial, kDelayItem, 0, 1024); + } + else + { + thisRoom->objects[objActive].data.g.delay = (Byte)delay; + GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); + if (initial == 1) + thisRoom->objects[objActive].data.g.initial = true; + else + thisRoom->objects[objActive].data.g.initial = false; + fileDirty = true; + UpdateMenus(false); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + leaving = true; + doReturn = true; + } + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(applianceFilterUPP); + + if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoMicrowaveObjectInfo + +void DoMicrowaveObjectInfo (void) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr; + short item, initial, kills; + Boolean leaving, doReturn; + ModalFilterUPP microwaveFilterUPP; + + microwaveFilterUPP = NewModalFilterUPP(MicrowaveFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + ParamText(numberStr, kindStr, PSTR(""), PSTR("")); + + BringUpDialog(&infoDial, kMicrowaveInfoDialogID); + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 11); + + if (thisRoom->objects[objActive].data.g.initial) + SetDialogItemValue(infoDial, kInitialStateCheckbox, 1); + else + SetDialogItemValue(infoDial, kInitialStateCheckbox, 0); + + kills = (short)thisRoom->objects[objActive].data.g.byte0; + if ((kills & 0x0001) == 0x0001) + SetDialogItemValue(infoDial, kKillBandsCheckbox, 1); + else + SetDialogItemValue(infoDial, kKillBandsCheckbox, 0); + if ((kills & 0x0002) == 0x0002) + SetDialogItemValue(infoDial, kKillBatteryCheckbox, 1); + else + SetDialogItemValue(infoDial, kKillBatteryCheckbox, 0); + if ((kills & 0x0004) == 0x0004) + SetDialogItemValue(infoDial, kKillFoilCheckbox, 1); + else + SetDialogItemValue(infoDial, kKillFoilCheckbox, 0); + + leaving = false; + doReturn = false; + + while (!leaving) + { + ModalDialog(microwaveFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); + if (initial == 1) + thisRoom->objects[objActive].data.g.initial = true; + else + thisRoom->objects[objActive].data.g.initial = false; + kills = 0; + GetDialogItemValue(infoDial, kKillBandsCheckbox, &initial); + if (initial == 1) + kills += 1; + GetDialogItemValue(infoDial, kKillBatteryCheckbox, &initial); + if (initial == 1) + kills += 2; + GetDialogItemValue(infoDial, kKillFoilCheckbox, &initial); + if (initial == 1) + kills += 4; + thisRoom->objects[objActive].data.g.byte0 = (Byte)kills; + + fileDirty = true; + UpdateMenus(false); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + leaving = true; + } + else if (item == kCancelButton) + leaving = true; + else if (item == kInitialStateCheckbox) + ToggleDialogItemValue(infoDial, kInitialStateCheckbox); + else if (item == kKillBandsCheckbox) + ToggleDialogItemValue(infoDial, kKillBandsCheckbox); + else if (item == kKillBatteryCheckbox) + ToggleDialogItemValue(infoDial, kKillBatteryCheckbox); + else if (item == kKillFoilCheckbox) + ToggleDialogItemValue(infoDial, kKillFoilCheckbox); + else if (item == 11) // Linked From? button. + { + GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); + if (initial == 1) + thisRoom->objects[objActive].data.g.initial = true; + else + thisRoom->objects[objActive].data.g.initial = false; + kills = 0; + GetDialogItemValue(infoDial, kKillBandsCheckbox, &initial); + if (initial == 1) + kills += 1; + GetDialogItemValue(infoDial, kKillBatteryCheckbox, &initial); + if (initial == 1) + kills += 2; + GetDialogItemValue(infoDial, kKillFoilCheckbox, &initial); + if (initial == 1) + kills += 4; + thisRoom->objects[objActive].data.g.byte0 = (Byte)kills; + + fileDirty = true; + UpdateMenus(false); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + leaving = true; + doReturn = true; + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(microwaveFilterUPP); + + if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoGreaseObjectInfo + +void DoGreaseObjectInfo (void) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr; + short item; + Boolean leaving, wasSpilled, doReturn; + ModalFilterUPP greaseFilterUPP; + + greaseFilterUPP = NewModalFilterUPP(GreaseFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + ParamText(numberStr, kindStr, PSTR(""), PSTR("")); + + BringUpDialog(&infoDial, kGreaseInfoDialogID); + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 8); + + wasSpilled = !(thisRoom->objects[objActive].data.c.initial); + SetDialogItemValue(infoDial, kGreaseItem, (short)wasSpilled); + leaving = false; + doReturn = false; + + while (!leaving) + { + ModalDialog(greaseFilterUPP, &item); + + if (item == kOkayButton) + { + thisRoom->objects[objActive].data.c.initial = !wasSpilled; + fileDirty = true; + UpdateMenus(false); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + leaving = true; + } + else if (item == kCancelButton) + { + leaving = true; + } + else if (item == kGreaseItem) + { + wasSpilled = !wasSpilled; + SetDialogItemValue(infoDial, kGreaseItem, (short)wasSpilled); + } + else if (item == 8) // Linked From? button. + { + thisRoom->objects[objActive].data.c.initial = !wasSpilled; + fileDirty = true; + UpdateMenus(false); + InvalWindowRect(mainWindow, &mainWindowRect); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + leaving = true; + doReturn = true; + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(greaseFilterUPP); + + if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoInvisBonusObjectInfo + +void DoInvisBonusObjectInfo (void) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr; + short item; + Boolean leaving, doReturn; + ModalFilterUPP invisBonusFilterUPP; + + invisBonusFilterUPP = NewModalFilterUPP(InvisBonusFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + ParamText(numberStr, kindStr, PSTR(""), PSTR("")); + + switch (thisRoom->objects[objActive].data.c.points) + { + case 300: + newPoint = 1; + break; + + case 500: + newPoint = 2; + break; + + default: + newPoint = 0; + break; + } + + BringUpDialog(&infoDial, kInvisBonusInfoDialogID); + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 9); + + leaving = false; + doReturn = false; + + while (!leaving) + { + ModalDialog(invisBonusFilterUPP, &item); + + if (item == kOkayButton) + { + switch (newPoint) + { + case 0: + thisRoom->objects[objActive].data.c.points = 100; + break; + + case 1: + thisRoom->objects[objActive].data.c.points = 300; + break; + + case 2: + thisRoom->objects[objActive].data.c.points = 500; + break; + } + fileDirty = true; + UpdateMenus(false); + leaving = true; + } + else if (item == kCancelButton) + leaving = true; + else if (item == k100PtRadio) + { + SelectFromRadioGroup(infoDial, item, k100PtRadio, k500PtRadio); + newPoint = 0; + } + else if (item == k300PtRadio) + { + SelectFromRadioGroup(infoDial, item, k100PtRadio, k500PtRadio); + newPoint = 1; + } + else if (item == k500PtRadio) + { + SelectFromRadioGroup(infoDial, item, k100PtRadio, k500PtRadio); + newPoint = 2; + } + else if (item == 9) // Linked From? button. + { + switch (newPoint) + { + case 0: + thisRoom->objects[objActive].data.c.points = 100; + break; + + case 1: + thisRoom->objects[objActive].data.c.points = 300; + break; + + case 2: + thisRoom->objects[objActive].data.c.points = 500; + break; + } + fileDirty = true; + UpdateMenus(false); + leaving = true; + doReturn = true; + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(invisBonusFilterUPP); + + if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoTransObjectInfo + +void DoTransObjectInfo (short what) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr, roomStr, tempStr, objStr; + short item, floor, suite; + Boolean leaving, doLink, doGoTo, doReturn, wasState; + ModalFilterUPP transFilterUPP; + + transFilterUPP = NewModalFilterUPP(TransFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + if (thisRoom->objects[objActive].data.d.where == -1) + PasStringCopy(PSTR("none"), roomStr); + else + { + ExtractFloorSuite(thisRoom->objects[objActive].data.d.where, &floor, &suite); + NumToString((long)floor, roomStr); + PasStringConcat(roomStr, PSTR(" / ")); + NumToString((long)suite, tempStr); + PasStringConcat(roomStr, tempStr); + } + + if (thisRoom->objects[objActive].data.d.who == 255) + PasStringCopy(PSTR("none"), objStr); + else + NumToString((long)thisRoom->objects[objActive].data.d.who + 1, objStr); + + ParamText(numberStr, kindStr, roomStr, objStr); + + BringUpDialog(&infoDial, kTransInfoDialogID); + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 12); + if (what != kDeluxeTrans) + HideDialogItem(infoDial, kInitialStateCheckbox3); + else + { + wasState = (thisRoom->objects[objActive].data.d.wide & 0xF0) >> 4; + SetDialogItemValue(infoDial, kInitialStateCheckbox3, (short)wasState); + } + + leaving = false; + doLink = false; + doGoTo = false; + doReturn = false; + + if (thisRoom->objects[objActive].data.d.who == 255) + MyDisableControl(infoDial, kGotoButton1); + + while (!leaving) + { + ModalDialog(transFilterUPP, &item); + + if (item == kOkayButton) + { + if (what == kDeluxeTrans) + thisRoom->objects[objActive].data.d.wide = wasState << 4; + fileDirty = true; + UpdateMenus(false); + leaving = true; + } + else if (item == kCancelButton) + leaving = true; + else if (item == kLinkTransButton) + { + if (what == kDeluxeTrans) + thisRoom->objects[objActive].data.d.wide = wasState << 4; + fileDirty = true; + UpdateMenus(false); + leaving = true; + doLink = true; + } + else if (item == kGotoButton1) + { + if (what == kDeluxeTrans) + thisRoom->objects[objActive].data.d.wide = wasState << 4; + fileDirty = true; + UpdateMenus(false); + leaving = true; + doGoTo = true; + } + else if (item == 12) // Linked From? button. + { + if (what == kDeluxeTrans) + thisRoom->objects[objActive].data.d.wide = wasState << 4; + fileDirty = true; + UpdateMenus(false); + leaving = true; + doReturn = true; + } + else if (item == kInitialStateCheckbox3) + { + wasState = !wasState; + SetDialogItemValue(infoDial, kInitialStateCheckbox3, (short)wasState); + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(transFilterUPP); + + if (doLink) + { + linkType = kTransportLinkOnly; + linkerIsSwitch = false; + OpenLinkWindow(); + linkRoom = thisRoomNumber; + linkObject = (Byte)objActive; + DeselectObject(); + } + else if (doGoTo) + { + GoToObjectInRoom((short)thisRoom->objects[objActive].data.d.who, floor, suite); + } + else if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoEnemyObjectInfo + +void DoEnemyObjectInfo (short what) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr; + long delay; + short item, initial; + Boolean leaving, doReturn; + ModalFilterUPP enemyFilterUPP; + + enemyFilterUPP = NewModalFilterUPP(EnemyFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + ParamText(numberStr, kindStr, PSTR(""), PSTR("")); + + BringUpDialog(&infoDial, kEnemyInfoDialogID); + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 11); + + delay = thisRoom->objects[objActive].data.h.delay; + SetDialogNumToStr(infoDial, kDelay2Item, (long)delay); + SelectDialogItemText(infoDial, kDelay2Item, 0, 1024); + + if (thisRoom->objects[objActive].data.h.initial) + SetDialogItemValue(infoDial, kInitialStateCheckbox2, 1); + else + SetDialogItemValue(infoDial, kInitialStateCheckbox2, 0); + + if (what == kBall) + { + HideDialogItem(infoDial, kDelay2Item); + HideDialogItem(infoDial, 8); + HideDialogItem(infoDial, 9); + } + + leaving = false; + doReturn = false; + + while (!leaving) + { + ModalDialog(enemyFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogNumFromStr(infoDial, kDelay2Item, &delay); + if (((delay < 0L) || (delay > 255L)) && (what != kBall)) + { + SysBeep(0); + delay = thisRoom->objects[objActive].data.h.delay; + SetDialogNumToStr(infoDial, kDelay2Item, (long)delay); + SelectDialogItemText(infoDial, kDelay2Item, 0, 1024); + } + else + { + GetDialogItemValue(infoDial, kInitialStateCheckbox2, &initial); + if (initial == 1) + thisRoom->objects[objActive].data.h.initial = true; + else + thisRoom->objects[objActive].data.h.initial = false; + if (what != kBall) + thisRoom->objects[objActive].data.h.delay = (Byte)delay; + fileDirty = true; + UpdateMenus(false); + leaving = true; + } + } + else if (item == kCancelButton) + leaving = true; + else if (item == kInitialStateCheckbox2) + ToggleDialogItemValue(infoDial, kInitialStateCheckbox2); + else if (item == 11) // Linked From? button. + { + GetDialogNumFromStr(infoDial, kDelay2Item, &delay); + if (((delay < 0L) || (delay > 255L)) && (what != kBall)) + { + SysBeep(0); + delay = thisRoom->objects[objActive].data.h.delay; + SetDialogNumToStr(infoDial, kDelay2Item, (long)delay); + SelectDialogItemText(infoDial, kDelay2Item, 0, 1024); + } + else + { + GetDialogItemValue(infoDial, kInitialStateCheckbox2, &initial); + if (initial == 1) + thisRoom->objects[objActive].data.h.initial = true; + else + thisRoom->objects[objActive].data.h.initial = false; + if (what != kBall) + thisRoom->objects[objActive].data.h.delay = (Byte)delay; + fileDirty = true; + UpdateMenus(false); + leaving = true; + doReturn = true; + } + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(enemyFilterUPP); + + if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoFlowerObjectInfo + +void DoFlowerObjectInfo (void) +{ + DialogPtr infoDial; + Str255 numberStr, kindStr; + short item, flower; + Boolean leaving, doReturn; + ModalFilterUPP flowerFilterUPP; + + flowerFilterUPP = NewModalFilterUPP(FlowerFilter); + + NumToString(objActive + 1, numberStr); + GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); + ParamText(numberStr, kindStr, PSTR(""), PSTR("")); + + BringUpDialog(&infoDial, kFlowerInfoDialogID); + + if (retroLinkList[objActive].room == -1) + HideDialogItem(infoDial, 13); + + flower = thisRoom->objects[objActive].data.i.pict + kRadioFlower1; + SelectFromRadioGroup(infoDial, flower, kRadioFlower1, kRadioFlower6); + + leaving = false; + doReturn = false; + + while (!leaving) + { + ModalDialog(flowerFilterUPP, &item); + + if (item == kOkayButton) + { + flower -= kRadioFlower1; + if (flower != thisRoom->objects[objActive].data.i.pict) + { + InvalWindowRect(mainWindow, &thisRoom->objects[objActive].data.i.bounds); + thisRoom->objects[objActive].data.i.bounds.right = + thisRoom->objects[objActive].data.i.bounds.left + + RectWide(&flowerSrc[flower]); + thisRoom->objects[objActive].data.i.bounds.top = + thisRoom->objects[objActive].data.i.bounds.bottom - + RectTall(&flowerSrc[flower]); + thisRoom->objects[objActive].data.i.pict = flower; + InvalWindowRect(mainWindow, &thisRoom->objects[objActive].data.i.bounds); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + fileDirty = true; + UpdateMenus(false); + wasFlower = flower; + } + leaving = true; + } + else if ((item >= kRadioFlower1) && (item <= kRadioFlower6)) + { + flower = item; + SelectFromRadioGroup(infoDial, flower, kRadioFlower1, kRadioFlower6); + } + else if (item == kFlowerCancel) + { + leaving = true; + } + else if (item == 13) // Linked From? button. + { + flower -= kRadioFlower1; + if (flower != thisRoom->objects[objActive].data.i.pict) + { + InvalWindowRect(mainWindow, &thisRoom->objects[objActive].data.i.bounds); + thisRoom->objects[objActive].data.i.bounds.right = + thisRoom->objects[objActive].data.i.bounds.left + + RectWide(&flowerSrc[flower]); + thisRoom->objects[objActive].data.i.bounds.top = + thisRoom->objects[objActive].data.i.bounds.bottom - + RectTall(&flowerSrc[flower]); + thisRoom->objects[objActive].data.i.pict = flower; + InvalWindowRect(mainWindow, &thisRoom->objects[objActive].data.i.bounds); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + fileDirty = true; + UpdateMenus(false); + wasFlower = flower; + } + leaving = true; + doReturn = true; + } + } + + DisposeDialog(infoDial); + DisposeModalFilterUPP(flowerFilterUPP); + + if (doReturn) + { + GoToObjectInRoomNum(retroLinkList[objActive].object, + retroLinkList[objActive].room); + } +} + +//-------------------------------------------------------------- DoObjectInfo + +void DoObjectInfo (void) +{ + if ((objActive == kInitialGliderSelected) || + (objActive == kLeftGliderSelected) || + (objActive == kRightGliderSelected)) + { + DoFurnitureObjectInfo(); + return; + } + + switch (thisRoom->objects[objActive].what) + { + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kLeftFan: + case kRightFan: + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + case kInvisBlower: + case kGrecoVent: + case kSewerBlower: + case kLiftArea: + DoBlowerObjectInfo(thisRoom->objects[objActive].what); + break; + + case kTable: + case kShelf: + case kCabinet: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kCounter: + case kDresser: + case kDeckTable: + case kStool: + case kTrunk: + case kInvisObstacle: + case kManhole: + case kBooks: + case kInvisBounce: + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kFoil: + case kStar: + case kSparkle: + case kHelium: + case kSlider: + case kUpStairs: + case kDownStairs: + case kDoorInLf: + case kDoorInRt: + case kDoorExRt: + case kDoorExLf: + case kWindowInLf: + case kWindowInRt: + case kWindowExRt: + case kWindowExLf: + case kCinderBlock: + case kFlowerBox: + case kCDs: + case kGuitar: + case kStereo: + case kCobweb: + case kOzma: + case kMirror: + case kMousehole: + case kFireplace: + case kWallWindow: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + case kChimes: + DoFurnitureObjectInfo(); + break; + + case kGreaseRt: + case kGreaseLf: + DoGreaseObjectInfo(); + break; + + case kInvisBonus: + DoInvisBonusObjectInfo(); + break; + + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kInvisTrans: + case kDeluxeTrans: + DoTransObjectInfo(thisRoom->objects[objActive].what); + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + DoSwitchObjectInfo(); + break; + + case kTrigger: + case kLgTrigger: + DoTriggerObjectInfo(); + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + DoLightObjectInfo(); + break; + + case kShredder: + case kToaster: + case kMacPlus: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + DoApplianceObjectInfo(thisRoom->objects[objActive].what); + break; + + case kMicrowave: + DoMicrowaveObjectInfo(); + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kBall: + case kDrip: + case kFish: + DoEnemyObjectInfo(thisRoom->objects[objActive].what); + break; + + case kFlower: + DoFlowerObjectInfo(); + break; + + case kSoundTrigger: + case kCustomPict: + DoCustPictObjectInfo(); + break; + + default: + SysBeep(1); + break; + } +} + +#endif + diff --git a/GpApp/ObjectRects.cpp b/GpApp/ObjectRects.cpp new file mode 100644 index 0000000..e3f8ab1 --- /dev/null +++ b/GpApp/ObjectRects.cpp @@ -0,0 +1,1188 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// ObjectRects.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "RectUtils.h" + + +#define kFloorColumnWide 4 +#define kCeilingColumnWide 24 +#define kFanColumnThick 16 +#define kFanColumnDown 20 +#define kDeadlyFlameHeight 24 +#define kStoolThick 25 +#define kShredderActiveHigh 40 + + +short AddActiveRect (Rect *, short, short, Boolean, Boolean); + + +extern hotPtr hotSpots; +extern short nHotSpots, numChimes; + + +//============================================================== Functions +//-------------------------------------------------------------- GetObjectRect + +void GetObjectRect (objectPtr who, Rect *itsRect) +{ + PicHandle thePict; + short wide, tall; + + switch (who->what) + { + case kObjectIsEmpty: + QSetRect(itsRect, 0, 0, 0, 0); + break; + + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kSewerGrate: + case kLeftFan: + case kRightFan: + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + case kInvisBlower: + case kGrecoVent: + case kSewerBlower: + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, who->data.a.topLeft.h, who->data.a.topLeft.v); + break; + + case kLiftArea: + QSetRect(itsRect, 0, 0, who->data.a.distance, who->data.a.tall * 2); + QOffsetRect(itsRect, who->data.a.topLeft.h, who->data.a.topLeft.v); + break; + + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, who->data.a.topLeft.h, who->data.a.topLeft.v); + break; + + case kTable: + case kShelf: + case kCabinet: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kCounter: + case kDresser: + case kStool: + case kTrunk: + case kDeckTable: + case kInvisObstacle: + case kManhole: + case kBooks: + case kInvisBounce: + *itsRect = who->data.b.bounds; + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kGreaseRt: + case kGreaseLf: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, + who->data.c.topLeft.h, + who->data.c.topLeft.v); + break; + + case kSlider: + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, + who->data.c.topLeft.h, + who->data.c.topLeft.v); + itsRect->right = itsRect->left + who->data.c.length; + break; + + case kUpStairs: + case kDownStairs: + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kDoorInLf: + case kDoorInRt: + case kDoorExRt: + case kDoorExLf: + case kWindowInLf: + case kWindowInRt: + case kWindowExRt: + case kWindowExLf: + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, + who->data.d.topLeft.h, + who->data.d.topLeft.v); + break; + + case kInvisTrans: + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, + who->data.d.topLeft.h, + who->data.d.topLeft.v); + itsRect->bottom = itsRect->top + who->data.d.tall; + itsRect->right += (short)who->data.d.wide; + break; + + case kDeluxeTrans: + wide = (who->data.d.tall & 0xFF00) >> 8; // Get high byte + tall = who->data.d.tall & 0x00FF; // Get low byte + QSetRect(itsRect, 0, 0, wide * 4, tall * 4); // Scale by 4 + QOffsetRect(itsRect, + who->data.d.topLeft.h, + who->data.d.topLeft.v); + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, + who->data.e.topLeft.h, + who->data.e.topLeft.v); + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kInvisLight: + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, + who->data.f.topLeft.h, + who->data.f.topLeft.v); + break; + + case kFlourescent: + case kTrackLight: + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + itsRect->right = who->data.f.length; + QOffsetRect(itsRect, + who->data.f.topLeft.h, + who->data.f.topLeft.v); + break; + + case kShredder: + case kToaster: + case kMacPlus: + case kGuitar: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kStereo: + case kMicrowave: + case kCinderBlock: + case kFlowerBox: + case kCDs: + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, + who->data.g.topLeft.h, + who->data.g.topLeft.v); + break; + + case kCustomPict: + thePict = GetPicture(who->data.g.height); + if (thePict == nil) + { + who->data.g.height = 10000; + *itsRect = srcRects[who->what]; + } + else + { + HLock((Handle)thePict); + *itsRect = (*thePict)->picFrame; + HUnlock((Handle)thePict); + } + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, + who->data.g.topLeft.h, + who->data.g.topLeft.v); + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kBall: + case kDrip: + case kFish: + case kCobweb: + *itsRect = srcRects[who->what]; + ZeroRectCorner(itsRect); + QOffsetRect(itsRect, + who->data.h.topLeft.h, + who->data.h.topLeft.v); + break; + + case kOzma: + case kMirror: + case kMousehole: + case kFireplace: + case kFlower: + case kWallWindow: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + case kChimes: + *itsRect = who->data.i.bounds; + break; + } +} + +//-------------------------------------------------------------- AddActiveRect + +short AddActiveRect (Rect *bounds, short action, short who, Boolean isOn, + Boolean doScrutinize) +{ + if (nHotSpots >= kMaxHotSpots) + return (-1); + + hotSpots[nHotSpots].bounds = *bounds; // the active rect + hotSpots[nHotSpots].action = action; // what it does + hotSpots[nHotSpots].who = who; // local obj. linked to + hotSpots[nHotSpots].isOn = isOn; // is it active? + hotSpots[nHotSpots].stillOver = false; + hotSpots[nHotSpots].doScrutinize = doScrutinize; + nHotSpots++; + + return (nHotSpots - 1); +} + +//-------------------------------------------------------------- CreateActiveRects + +short CreateActiveRects (short who) +{ + objectType theObject; + Rect bounds; + short hotSpotNumber, wide, tall; + Boolean isOn; + + hotSpotNumber = -1; + theObject = masterObjects[who].theObject; + + switch (theObject.what) + { + case kObjectIsEmpty: + break; + + case kFloorVent: + QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kFloorVent]) - kFloorColumnWide / 2, 0); + QOffsetRect(&bounds, theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, + false); + break; + + case kCeilingVent: + QSetRect(&bounds, 0, 0, kCeilingColumnWide, theObject.data.a.distance); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kCeilingVent]) - kCeilingColumnWide / 2, + 0); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kDropIt, who, theObject.data.a.state, + false); + break; + + case kFloorBlower: + QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kFloorBlower]) - kFloorColumnWide / 2, + 0); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, + false); + break; + + case kCeilingBlower: + QSetRect(&bounds, 0, 0, kCeilingColumnWide, theObject.data.a.distance); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kCeilingBlower]) - kCeilingColumnWide / 2, + 0); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kDropIt, who, theObject.data.a.state, + false); + break; + + case kSewerGrate: + QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kSewerGrate]) - kFloorColumnWide / 2, + 0); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, + false); + break; + + case kLeftFan: + QSetRect(&bounds, 0, 0, 13, 43); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h + 16, + theObject.data.a.topLeft.v + 12); + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + QSetRect(&bounds, 0, 0, theObject.data.a.distance, kFanColumnThick); + QOffsetRect(&bounds, -(theObject.data.a.distance), kFanColumnDown); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kPushItLeft, who, + theObject.data.a.state, false); + break; + + case kRightFan: + QSetRect(&bounds, 0, 0, 13, 43); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h + 6, + theObject.data.a.topLeft.v + 12); + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + QSetRect(&bounds, 0, 0, theObject.data.a.distance, kFanColumnThick); + QOffsetRect(&bounds, RectWide(&srcRects[kRightFan]), kFanColumnDown); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kPushItRight, who, + theObject.data.a.state, false); + break; + + case kTaper: + QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kTaper]) - kFloorColumnWide / 2, + 0); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + if ((bounds.bottom - bounds.top) > kDeadlyFlameHeight) + { + bounds.bottom -= kDeadlyFlameHeight; + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, true, false); + bounds.bottom += kDeadlyFlameHeight; + bounds.top = bounds.bottom - kDeadlyFlameHeight + 2; + hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); + } + else + hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); + QSetRect(&bounds, 0, 0, 7, 48); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h + 6, + theObject.data.a.topLeft.v + 11); + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + break; + + case kCandle: + QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kCandle]) - kFloorColumnWide / 2, + 0); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h - 2, + theObject.data.a.topLeft.v); + if ((bounds.bottom - bounds.top) > kDeadlyFlameHeight) + { + bounds.bottom -= kDeadlyFlameHeight; + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, true, false); + bounds.bottom += kDeadlyFlameHeight; + bounds.top = bounds.bottom - kDeadlyFlameHeight + 2; + hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); + } + else + hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); + QSetRect(&bounds, 0, 0, 8, 20); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h + 9, + theObject.data.a.topLeft.v + 11); + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + break; + + case kStubby: + QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); + QOffsetRect(&bounds, + (HalfRectWide(&srcRects[kStubby]) - kFloorColumnWide / 2) - 1, + 0); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + if ((bounds.bottom - bounds.top) > kDeadlyFlameHeight) + { + bounds.bottom -= kDeadlyFlameHeight; + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, true, false); + bounds.bottom += kDeadlyFlameHeight; + bounds.top = bounds.bottom - kDeadlyFlameHeight + 2; + hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); + } + else + hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); + QSetRect(&bounds, 0, 0, 15, 26); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h + 1, + theObject.data.a.topLeft.v + 11); + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + break; + + case kTiki: + QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kTiki]) - kFloorColumnWide / 2, + 0); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + if ((bounds.bottom - bounds.top) > kDeadlyFlameHeight) + { + bounds.bottom -= kDeadlyFlameHeight; + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, true, false); + bounds.bottom += kDeadlyFlameHeight; + bounds.top = bounds.bottom - kDeadlyFlameHeight + 2; + hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); + } + else + hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); + QSetRect(&bounds, 0, 0, 15, 14); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h + 6, + theObject.data.a.topLeft.v + 6); + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + break; + + case kBBQ: + QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 8); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kBBQ]) - kFloorColumnWide / 2, 0); + QOffsetRect(&bounds, theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + if ((bounds.bottom - bounds.top) > kDeadlyFlameHeight) + { + bounds.bottom -= kDeadlyFlameHeight; + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, true, false); + bounds.bottom += kDeadlyFlameHeight; + bounds.top = bounds.bottom - kDeadlyFlameHeight + 2; + hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); + } + else + hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); + QSetRect(&bounds, 0, 0, 52, 17); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h + 6, + theObject.data.a.topLeft.v + 8); + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + break; + + case kInvisBlower: + switch (theObject.data.a.vector & 0x0F) + { + case 1: // up + QSetRect(&bounds, 0, -theObject.data.a.distance - 24, + kFloorColumnWide, 0); + QOffsetRect(&bounds, 12 - kFloorColumnWide / 2, 24); + QOffsetRect(&bounds, theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, + false); + break; + + case 2: // right + QSetRect(&bounds, 0, 0, theObject.data.a.distance + 24, + kFanColumnThick); + QOffsetRect(&bounds, 0, 12 - kFanColumnThick / 2); + QOffsetRect(&bounds, theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kPushItRight, who, + theObject.data.a.state, false); + break; + + case 4: // down + QSetRect(&bounds, 0, 0, kFloorColumnWide, + theObject.data.a.distance + 24); + QOffsetRect(&bounds, 12 - kFloorColumnWide / 2, 0); + QOffsetRect(&bounds, theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kDropIt, who, + theObject.data.a.state, false); + break; + + case 8: // left + QSetRect(&bounds, 0, 0, theObject.data.a.distance + 24, kFanColumnThick); + QOffsetRect(&bounds, -(theObject.data.a.distance), 12 - kFanColumnThick / 2); + QOffsetRect(&bounds, theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kPushItLeft, who, + theObject.data.a.state, false); + break; + } + break; + + case kGrecoVent: + QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kGrecoVent]) - kFloorColumnWide / 2, + 0); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, + theObject.data.a.state, false); + break; + + case kSewerBlower: + QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); + QOffsetRect(&bounds, + HalfRectWide(&srcRects[kSewerBlower]) - kFloorColumnWide / 2, + 0); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, + theObject.data.a.state, false); + break; + + case kLiftArea: + QSetRect(&bounds, 0, 0, theObject.data.a.distance, theObject.data.a.tall * 2); + QOffsetRect(&bounds, + theObject.data.a.topLeft.h, + theObject.data.a.topLeft.v); + switch (theObject.data.a.vector & 0x0F) + { + case 1: // up + hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, + false); + break; + + case 2: // right + hotSpotNumber = AddActiveRect(&bounds, kPushItRight, who, + theObject.data.a.state, false); + break; + + case 4: // down + hotSpotNumber = AddActiveRect(&bounds, kDropIt, who, + theObject.data.a.state, false); + break; + + case 8: // left + hotSpotNumber = AddActiveRect(&bounds, kPushItLeft, who, + theObject.data.a.state, false); + break; + } + break; + + case kTable: + case kShelf: + case kCabinet: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kCounter: + case kDresser: + case kDeckTable: + case kTrunk: + case kInvisObstacle: + bounds = theObject.data.b.bounds; + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + break; + + case kBooks: + bounds = theObject.data.b.bounds; + bounds.right -= 2; + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + break; + + case kManhole: + bounds = theObject.data.b.bounds; + bounds.left += kGliderWide + 3; + bounds.right -= kGliderWide + 3; + bounds.top = kFloorLimit - 1; + bounds.bottom = kTileHigh; + hotSpotNumber = AddActiveRect(&bounds, kIgnoreGround, who, true, false); + break; + + case kInvisBounce: + bounds = theObject.data.b.bounds; + hotSpotNumber = AddActiveRect(&bounds, kBounceIt, who, true, true); + break; + + case kStool: + bounds = theObject.data.b.bounds; + InsetRect(&bounds, 1, 1); + bounds.bottom = bounds.top + kStoolThick; + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kFoil: + case kInvisBonus: + case kStar: + case kHelium: + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, + theObject.data.c.topLeft.h, + theObject.data.c.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kRewardIt, who, + theObject.data.c.state, false); + break; + + case kGreaseRt: + if (theObject.data.c.state) + { + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, theObject.data.c.topLeft.h, + theObject.data.c.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kRewardIt, who, true, false); + } + else + { + QSetRect(&bounds, 0, -2, theObject.data.c.length - 5, 0); + QOffsetRect(&bounds, 32 - 1, 27); + QOffsetRect(&bounds, theObject.data.c.topLeft.h, + theObject.data.c.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kSlideIt, who, true, false); + } + break; + + case kGreaseLf: + if (theObject.data.c.state) + { + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, theObject.data.c.topLeft.h, + theObject.data.c.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kRewardIt, who, true, false); + } + else + { + QSetRect(&bounds, -theObject.data.c.length + 5, -2, 0, 0); + QOffsetRect(&bounds, 1, 27); + QOffsetRect(&bounds, theObject.data.c.topLeft.h, + theObject.data.c.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kSlideIt, who, true, false); + } + break; + + case kSparkle: + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, + theObject.data.c.topLeft.h, + theObject.data.c.topLeft.v); + break; + + case kSlider: + QSetRect(&bounds, 0, 0, theObject.data.c.length, 16); + QOffsetRect(&bounds, theObject.data.c.topLeft.h, + theObject.data.c.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kSlideIt, who, true, false); + break; + + case kUpStairs: + QSetRect(&bounds, 0, 0, 112, 32); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kMoveItUp, who, true, false); + break; + + case kDownStairs: + QSetRect(&bounds, -80, -56, 0, 0); + QOffsetRect(&bounds, srcRects[kDownStairs].right, 170); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kMoveItDown, who, true, false); + break; + + case kMailboxLf: + if (theObject.data.d.who != 255) + { + QSetRect(&bounds, -72, 0, 0, 40); + QOffsetRect(&bounds, 30, 16); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kMailItLeft, who, true, false); + } + break; + + case kMailboxRt: + if (theObject.data.d.who != 255) + { + QSetRect(&bounds, 0, 0, 72, 40); + QOffsetRect(&bounds, 79, 16); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kMailItRight, who, true, false); + } + break; + + case kFloorTrans: + if (theObject.data.d.who != 255) + { + QSetRect(&bounds, 0, -48, 76, 0); + QOffsetRect(&bounds, -8, RectTall(&srcRects[kFloorTrans])); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kDuctItDown, who, true, false); + } + break; + + case kCeilingTrans: + if (theObject.data.d.who != 255) + { + QSetRect(&bounds, 0, 0, 76, 48); + QOffsetRect(&bounds, -8, 0); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kDuctItUp, who, true, false); + } + break; + + case kDoorInLf: + QSetRect(&bounds, 0, 0, 16, 240); + QOffsetRect(&bounds, 0, 52); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kIgnoreLeftWall, who, true, false); + break; + + case kDoorInRt: + QSetRect(&bounds, 0, 0, 16, 240); + QOffsetRect(&bounds, 128, 52); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kIgnoreRightWall, who, true, false); + break; + + case kDoorExRt: + QSetRect(&bounds, 0, 0, 16, 240); + QOffsetRect(&bounds, 0, 52); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kIgnoreRightWall, who, true, false); + break; + + case kDoorExLf: + QSetRect(&bounds, 0, 0, 16, 240); + QOffsetRect(&bounds, 0, 52); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kIgnoreLeftWall, who, true, false); + break; + + case kWindowInLf: + QSetRect(&bounds, 0, 0, 16, 44); + QOffsetRect(&bounds, 0, 96); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kIgnoreLeftWall, who, true, false); + break; + + case kWindowInRt: + QSetRect(&bounds, 0, 0, 16, 44); + QOffsetRect(&bounds, 4, 96); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kIgnoreRightWall, who, true, false); + break; + + case kWindowExRt: + QSetRect(&bounds, 0, 0, 16, 44); + QOffsetRect(&bounds, 0, 96); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kIgnoreRightWall, who, true, false); + break; + + case kWindowExLf: + QSetRect(&bounds, 0, 0, 16, 44); + QOffsetRect(&bounds, 0, 96); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kIgnoreLeftWall, who, true, false); + break; + + case kInvisTrans: + if (theObject.data.d.who != 255) + { + QSetRect(&bounds, 0, 0, 64, 32); + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + bounds.bottom = bounds.top + theObject.data.d.tall; + bounds.right += (short)theObject.data.d.wide; + hotSpotNumber = AddActiveRect(&bounds, kTransportIt, who, true, false); + } + break; + + case kDeluxeTrans: + if (theObject.data.d.who != 255) + { + wide = (theObject.data.d.tall & 0xFF00) >> 8; // Get high byte + tall = theObject.data.d.tall & 0x00FF; // Get low byte + QSetRect(&bounds, 0, 0, wide * 4, tall * 4); // Scale by 4 + QOffsetRect(&bounds, + theObject.data.d.topLeft.h, + theObject.data.d.topLeft.v); + isOn = theObject.data.d.wide & 0x0F; + hotSpotNumber = AddActiveRect(&bounds, kTransportIt, who, isOn, false); + } + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, + theObject.data.e.topLeft.h, + theObject.data.e.topLeft.v); + if ((theObject.what == kTrigger) || (theObject.what == kLgTrigger)) + { + if (theObject.data.e.where != -1) + hotSpotNumber = AddActiveRect(&bounds, kTriggerIt, who, true, false); + } + else + { + if (theObject.data.e.where != -1) + hotSpotNumber = AddActiveRect(&bounds, kSwitchIt, who, true, false); + } + break; + + case kSoundTrigger: + QSetRect(&bounds, 0, 0, 48, 48); + QOffsetRect(&bounds, theObject.data.e.topLeft.h, theObject.data.e.topLeft.v); + if (LoadTriggerSound(theObject.data.e.where) == noErr) + hotSpotNumber = AddActiveRect(&bounds, kSoundIt, who, true, false); + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + break; + + case kShredder: + bounds = srcRects[theObject.what]; + bounds.bottom = bounds.top + kShredderActiveHigh; + bounds.right += 48; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, theObject.data.g.topLeft.h, + theObject.data.g.topLeft.v); + QOffsetRect(&bounds, -24, -36); + hotSpotNumber = AddActiveRect(&bounds, kShredIt, who, + theObject.data.g.state, true); + break; + + case kGuitar: + QSetRect(&bounds, 0, 0, 8, 96); + QOffsetRect(&bounds, theObject.data.g.topLeft.h + 34, + theObject.data.g.topLeft.v + 32); + hotSpotNumber = AddActiveRect(&bounds, kStrumIt, who, true, false); + break; + + case kOutlet: + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, + theObject.data.g.topLeft.h, + theObject.data.g.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kIgnoreIt, who, + theObject.data.g.state, false); + break; + + case kMicrowave: + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, + theObject.data.g.topLeft.h, + theObject.data.g.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + bounds.bottom = bounds.top; + bounds.top = 0; + hotSpotNumber = AddActiveRect(&bounds, kMicrowaveIt, who, true, true); + break; + + case kToaster: + case kMacPlus: + case kTV: + case kCoffee: + case kVCR: + case kStereo: + case kCinderBlock: + case kFlowerBox: + case kCDs: + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, + theObject.data.g.topLeft.h, + theObject.data.g.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + break; + + case kCustomPict: + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kBall: + case kDrip: + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, + theObject.data.h.topLeft.h, + theObject.data.h.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kIgnoreIt, who, true, false); + break; + + case kFish: + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, + theObject.data.h.topLeft.h, + theObject.data.h.topLeft.v); + hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); + break; + + case kCobweb: + bounds = srcRects[theObject.what]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, + theObject.data.h.topLeft.h, + theObject.data.h.topLeft.v); + InsetRect(&bounds, -24, -10); + hotSpotNumber = AddActiveRect(&bounds, kWebIt, who, true, true); + break; + + case kOzma: + case kMirror: + case kMousehole: + case kFireplace: + case kFlower: + case kWallWindow: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + break; + + case kChimes: + numChimes++; + bounds = srcRects[kChimes]; + ZeroRectCorner(&bounds); + QOffsetRect(&bounds, + theObject.data.i.bounds.left, + theObject.data.i.bounds.top); + hotSpotNumber = AddActiveRect(&bounds, kChimeIt, who, true, false); + break; + } + + return (hotSpotNumber); +} + +//-------------------------------------------------------------- VerticalRoomOffset + +short VerticalRoomOffset (short neighbor) +{ + short offset; + + offset = 0; + + switch (neighbor) + { + case kNorthRoom: + case kNorthEastRoom: + case kNorthWestRoom: + offset -= kVertLocalOffset; + break; + + case kSouthEastRoom: + case kSouthRoom: + case kSouthWestRoom: + offset += kVertLocalOffset; + break; + } + + return (offset); +} + +//-------------------------------------------------------------- OffsetRectRoomRelative + +void OffsetRectRoomRelative (Rect *theRect, short neighbor) +{ + QOffsetRect(theRect, playOriginH, playOriginV); + + switch (neighbor) + { + case kNorthRoom: + QOffsetRect(theRect, 0, -kVertLocalOffset); + break; + + case kNorthEastRoom: + QOffsetRect(theRect, kRoomWide, -kVertLocalOffset); + break; + + case kEastRoom: + QOffsetRect(theRect, kRoomWide, 0); + break; + + case kSouthEastRoom: + QOffsetRect(theRect, kRoomWide, kVertLocalOffset); + break; + + case kSouthRoom: + QOffsetRect(theRect, 0, kVertLocalOffset); + break; + + case kSouthWestRoom: + QOffsetRect(theRect, -kRoomWide, kVertLocalOffset); + break; + + case kWestRoom: + QOffsetRect(theRect, -kRoomWide, 0); + break; + + case kNorthWestRoom: + QOffsetRect(theRect, -kRoomWide, -kVertLocalOffset); + break; + } +} + +//-------------------------------------------------------------- GetUpStairsRightEdge + +short GetUpStairsRightEdge (void) +{ + objectType thisObject; + short i, rightEdge; + char wasState; + + rightEdge = kRoomWide; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + for (i = 0; i < kMaxRoomObs; i++) + { + thisObject = (*thisHouse)->rooms[thisRoomNumber].objects[i]; + if (thisObject.what == kDownStairs) + { + rightEdge = thisObject.data.d.topLeft.h + srcRects[kDownStairs].right - 1; + break; + } + } + + HSetState((Handle)thisHouse, wasState); + + return (rightEdge); +} + +//-------------------------------------------------------------- GetDownStairsLeftEdge + +short GetDownStairsLeftEdge (void) +{ + objectType thisObject; + short i, leftEdge; + char wasState; + + leftEdge = 0; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + for (i = 0; i < kMaxRoomObs; i++) + { + thisObject = (*thisHouse)->rooms[thisRoomNumber].objects[i]; + if (thisObject.what == kUpStairs) + { + leftEdge = thisObject.data.d.topLeft.h + 1; + break; + } + } + + HSetState((Handle)thisHouse, wasState); + + return (leftEdge); +} + diff --git a/GpApp/Objects.cpp b/GpApp/Objects.cpp new file mode 100644 index 0000000..6158186 --- /dev/null +++ b/GpApp/Objects.cpp @@ -0,0 +1,1001 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Objects.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "ObjectEdit.h" + + +#define kMaxTempManholes 8 + + +short GetObjectLinked (objectType *); +void ListOneRoomsObjects (short); + + +Rect blowerSrcRect; // Blowers +GWorldPtr blowerSrcMap; +GWorldPtr blowerMaskMap; +Rect flame[kNumCandleFlames], tikiFlame[kNumTikiFlames]; +Rect coals[kNumBBQCoals]; +Rect furnitureSrcRect; // Furniture +GWorldPtr furnitureSrcMap; +GWorldPtr furnitureMaskMap; +Rect tableSrc, shelfSrc, hingeSrc, handleSrc, knobSrc; +Rect leftFootSrc, rightFootSrc, deckSrc; +Rect bonusSrcRect; // Bonuses +GWorldPtr bonusSrcMap; +GWorldPtr bonusMaskMap; +Rect pointsSrcRect; +GWorldPtr pointsSrcMap; +GWorldPtr pointsMaskMap; +Rect starSrc[6], sparkleSrc[kNumSparkleModes]; +Rect digits[11], pendulumSrc[3], greaseSrcRt[4], greaseSrcLf[4]; +Rect transSrcRect; // Transport +GWorldPtr transSrcMap; +GWorldPtr transMaskMap; +Rect switchSrcRect; // Switches +GWorldPtr switchSrcMap; +Rect lightSwitchSrc[2], machineSwitchSrc[2], thermostatSrc[2]; +Rect powerSrc[2], knifeSwitchSrc[2]; +Rect lightSrcRect; // Lights +GWorldPtr lightSrcMap; +GWorldPtr lightMaskMap; +Rect flourescentSrc1, flourescentSrc2, trackLightSrc[kNumTrackLights]; +Rect applianceSrcRect, toastSrcRect, shredSrcRect; // Appliances +GWorldPtr applianceSrcMap, toastSrcMap, shredSrcMap; +GWorldPtr applianceMaskMap, toastMaskMap, shredMaskMap; +Rect plusScreen1, plusScreen2, tvScreen1, tvScreen2; +Rect coffeeLight1, coffeeLight2, vcrTime1, vcrTime2; +Rect stereoLight1, stereoLight2, microOn, microOff; +Rect outletSrc[kNumOutletPicts]; +Rect balloonSrcRect, copterSrcRect, dartSrcRect; // Enemies +Rect ballSrcRect, dripSrcRect, enemySrcRect; +Rect fishSrcRect; +GWorldPtr balloonSrcMap, copterSrcMap, dartSrcMap; +GWorldPtr ballSrcMap, dripSrcMap, enemySrcMap; +GWorldPtr fishSrcMap; +GWorldPtr balloonMaskMap, copterMaskMap, dartMaskMap; +GWorldPtr ballMaskMap, dripMaskMap, enemyMaskMap; +GWorldPtr fishMaskMap; +Rect balloonSrc[kNumBalloonFrames], copterSrc[kNumCopterFrames]; +Rect dartSrc[kNumDartFrames], ballSrc[kNumBallFrames]; +Rect dripSrc[kNumDripFrames], fishSrc[kNumFishFrames]; +GWorldPtr clutterSrcMap; // Clutter +GWorldPtr clutterMaskMap; +Rect clutterSrcRect; +Rect flowerSrc[kNumFlowers]; +Rect *srcRects; +Rect tempManholes[kMaxTempManholes]; +savedType savedMaps[kMaxSavedMaps]; +objDataPtr masterObjects; +hotPtr hotSpots; +short nLocalObj, nHotSpots, numMasterObjects, numLocalMasterObjects; +short numTempManholes, tvWithMovieNumber; +Boolean newState; + +extern linksPtr linksList; +extern short srcLocations[], destLocations[]; +extern short localNumbers[]; +extern short numNeighbors; + + +//============================================================== Functions +//-------------------------------------------------------------- IsThisValid + +Boolean IsThisValid (short where, short who) +{ + char wasState; + Boolean itsGood; + + itsGood = true; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + switch ((*thisHouse)->rooms[where].objects[who].what) + { + case kObjectIsEmpty: + itsGood = false; + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + itsGood = (*thisHouse)->rooms[where].objects[who].data.c.state; + break; + } + HSetState((Handle)thisHouse, wasState); + + return (itsGood); +} + +//-------------------------------------------------------------- GetRoomLinked + +short GetRoomLinked (objectType *who) +{ + short compoundRoomNumber, whereLinked; + short floor, suite; + + switch (who->what) + { + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kInvisTrans: + case kDeluxeTrans: + compoundRoomNumber = who->data.d.where; + if (compoundRoomNumber != -1) // is object linked + { + ExtractFloorSuite(compoundRoomNumber, &floor, &suite); + whereLinked = GetRoomNumber(floor, suite); + } + else + whereLinked = -1; // not linked + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + compoundRoomNumber = who->data.e.where; + if (compoundRoomNumber != -1) // is object linked + { + ExtractFloorSuite(compoundRoomNumber, &floor, &suite); + whereLinked = GetRoomNumber(floor, suite); + } + else + whereLinked = -1; // not linked + break; + + default: + whereLinked = -1; + break; + } + + return (whereLinked); +} + +//-------------------------------------------------------------- GetObjectLinked + +short GetObjectLinked (objectType *who) +{ + short whoLinked; + + switch (who->what) + { + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kInvisTrans: + case kDeluxeTrans: + if (who->data.d.who != 255) // is it linked? + whoLinked = (short)who->data.d.who; + else + whoLinked = -1; // object not linked + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + if (who->data.e.who != 255) // is it linked? + whoLinked = (short)who->data.e.who; + else + whoLinked = -1; // object not linked + break; + + default: + whoLinked = -1; + break; + } + + return (whoLinked); +} + +//-------------------------------------------------------------- ObjectIsLinkTransport + +Boolean ObjectIsLinkTransport (objectType *who) +{ + Boolean itIs; + + itIs = false; + if ((who->what == kMailboxLf) || (who->what == kMailboxRt) || + (who->what == kFloorTrans) || (who->what == kCeilingTrans) || + (who->what == kInvisTrans) || (who->what == kDeluxeTrans)) + { + itIs = true; + } + + return (itIs); +} + +//-------------------------------------------------------------- ObjectIsLinkSwitch + +Boolean ObjectIsLinkSwitch (objectType *who) +{ + Boolean itIs; + + itIs = false; + if ((who->what == kLightSwitch) || (who->what == kMachineSwitch) || + (who->what == kThermostat) || (who->what == kPowerSwitch) || + (who->what == kKnifeSwitch) || (who->what == kInvisSwitch) || + (who->what == kTrigger) || (who->what == kLgTrigger)) + { + itIs = true; + } + + return (itIs); +} + +//-------------------------------------------------------------- ListOneRoomsObjects + +void ListOneRoomsObjects (short where) +{ + objectType thisObject; + short roomNum, n; + char wasState; + + roomNum = localNumbers[where]; + if (roomNum == kRoomIsEmpty) + return; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + for (n = 0; n < kMaxRoomObs; n++) + { + if (numMasterObjects < kMaxMasterObjects) + { + thisObject = (*thisHouse)->rooms[roomNum].objects[n]; + + masterObjects[numMasterObjects].roomNum = roomNum; + masterObjects[numMasterObjects].objectNum = n; + masterObjects[numMasterObjects].roomLink = + GetRoomLinked(&thisObject); + masterObjects[numMasterObjects].objectLink = + GetObjectLinked(&thisObject); + masterObjects[numMasterObjects].localLink = -1; + + masterObjects[numMasterObjects].theObject = + (*thisHouse)->rooms[roomNum].objects[n]; + + if ((where == kCentralRoom) && (IsThisValid(roomNum, n))) + masterObjects[numMasterObjects].hotNum = CreateActiveRects(n); + else + masterObjects[numMasterObjects].hotNum = -1; + masterObjects[numMasterObjects].dynaNum = -1; + + numMasterObjects++; + + if (where == kCentralRoom) + numLocalMasterObjects++; + } + } + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- ListAllLocalObjects + +void ListAllLocalObjects (void) +{ + short i, n; + char wasState; + + numMasterObjects = 0; + numLocalMasterObjects = 0; + nHotSpots = 0; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + ListOneRoomsObjects(kCentralRoom); + + if (numNeighbors > 1) + { + ListOneRoomsObjects(kEastRoom); + ListOneRoomsObjects(kWestRoom); + } + + if (numNeighbors > 3) + { + ListOneRoomsObjects(kNorthRoom); + ListOneRoomsObjects(kNorthEastRoom); + ListOneRoomsObjects(kSouthEastRoom); + ListOneRoomsObjects(kSouthRoom); + ListOneRoomsObjects(kSouthWestRoom); + ListOneRoomsObjects(kNorthWestRoom); + } + + HSetState((Handle)thisHouse, wasState); + + for (i = 0; i < numMasterObjects; i++) // correlate links withÉ + { // index into this list + if ((masterObjects[i].roomLink != -1) && // if object has a link + (masterObjects[i].objectLink != -1)) + { + for (n = 0; n < numMasterObjects; n++) // search for the objectÉ + { // linked to in this list + if ((masterObjects[i].roomLink == masterObjects[n].roomNum) && + (masterObjects[i].objectLink == masterObjects[n].objectNum)) + { + masterObjects[i].localLink = n; // log the index + } + } + } + } +} + +//-------------------------------------------------------------- AddTempManholeRect + +void AddTempManholeRect (Rect *manHole) +{ + Rect tempRect; + + if (numTempManholes < kMaxTempManholes) + { + tempRect = *manHole; + tempRect.bottom = tempRect.top + kFloorSupportTall; + tempManholes[numTempManholes] = tempRect; + numTempManholes++; + } +} + +//-------------------------------------------------------------- SetObjectState + +Boolean SetObjectState (short room, short object, short action, short local) +{ + char wasState; + Boolean changed; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + switch ((*thisHouse)->rooms[room].objects[object].what) + { + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kLeftFan: + case kRightFan: + case kSewerGrate: + case kInvisBlower: + case kGrecoVent: + case kSewerBlower: + case kLiftArea: + switch (action) + { + case kToggle: + newState = !(*thisHouse)->rooms[room].objects[object].data.a.state; + (*thisHouse)->rooms[room].objects[object].data.a.state = newState; + changed = true; + break; + + case kForceOn: + changed = ((*thisHouse)->rooms[room].objects[object].data.a.state == false); + newState = true; + (*thisHouse)->rooms[room].objects[object].data.a.state = newState; + break; + + case kForceOff: + changed = ((*thisHouse)->rooms[room].objects[object].data.a.state == PL_TRUE); + newState = false; + (*thisHouse)->rooms[room].objects[object].data.a.state = newState; + break; + } + if ((changed) && (local != -1)) + { + masterObjects[local].theObject.data.a.state = newState; + if (room == thisRoomNumber) + thisRoom->objects[object].data.a.state = newState; + if (newState) + PlayPrioritySound(kBlowerOn, kBlowerOnPriority); + else + PlayPrioritySound(kBlowerOff, kBlowerOffPriority); + if (masterObjects[local].hotNum != -1) + hotSpots[masterObjects[local].hotNum].isOn = newState; + } + break; + + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + changed = false; // Cannot switch on/off these + break; + + case kTable: + case kShelf: + case kCabinet: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kCounter: + case kDresser: + case kStool: + case kTrunk: + case kDeckTable: + case kInvisObstacle: + case kManhole: + case kBooks: + case kInvisBounce: + changed = false; // Cannot switch on/off these + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kGreaseRt: + case kGreaseLf: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + changed = ((*thisHouse)->rooms[room].objects[object].data.c.state == PL_TRUE); + newState = false; + (*thisHouse)->rooms[room].objects[object].data.c.state = newState; + if ((changed) && (local != -1)) + { + masterObjects[local].theObject.data.a.state = false; + if (room == thisRoomNumber) + { + thisRoom->objects[object].data.c.state = false; + if (masterObjects[local].hotNum != -1) + hotSpots[masterObjects[local].hotNum].isOn = false; + } + } + break; + + case kSlider: + break; + + case kUpStairs: + case kDownStairs: + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kDoorInLf: + case kDoorInRt: + case kDoorExRt: + case kDoorExLf: + case kWindowInLf: + case kWindowInRt: + case kWindowExRt: + case kWindowExLf: + case kInvisTrans: + changed = false; + break; + + case kDeluxeTrans: + switch (action) + { + case kToggle: + newState = (*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F; + newState = !newState; + (*thisHouse)->rooms[room].objects[object].data.d.wide &= 0xF0; + (*thisHouse)->rooms[room].objects[object].data.d.wide += newState; + changed = true; + break; + + case kForceOn: + changed = (((*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F) == 0x00); + newState = true; + (*thisHouse)->rooms[room].objects[object].data.d.wide &= 0xF0; + (*thisHouse)->rooms[room].objects[object].data.d.wide += newState; + break; + + case kForceOff: + changed = (((*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F) != 0x00); + newState = false; + (*thisHouse)->rooms[room].objects[object].data.d.wide &= 0xF0; + (*thisHouse)->rooms[room].objects[object].data.d.wide += newState; + break; + } + if ((changed) && (local != -1)) + { + masterObjects[local].theObject.data.d.wide = + (*thisHouse)->rooms[room].objects[object].data.d.wide; + if (room == thisRoomNumber) + thisRoom->objects[object].data.d.wide = + (*thisHouse)->rooms[room].objects[object].data.d.wide; + if (masterObjects[local].hotNum != -1) + hotSpots[masterObjects[local].hotNum].isOn = newState; + } + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + changed = false; + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + switch (action) + { + case kToggle: + newState = !(*thisHouse)->rooms[room].objects[object].data.f.state; + (*thisHouse)->rooms[room].objects[object].data.f.state = newState; + changed = true; + break; + + case kForceOn: + changed = ((*thisHouse)->rooms[room].objects[object].data.f.state == false); + newState = true; + (*thisHouse)->rooms[room].objects[object].data.f.state = newState; + break; + + case kForceOff: + changed = ((*thisHouse)->rooms[room].objects[object].data.f.state == PL_TRUE); + newState = false; + (*thisHouse)->rooms[room].objects[object].data.f.state = newState; + break; + } + if ((changed) && (local != -1)) + { + masterObjects[local].theObject.data.f.state = newState; + if (room == thisRoomNumber) + thisRoom->objects[object].data.f.state = newState; + } + break; + + case kGuitar: // really no point to change this state + changed = false; + break; + + case kStereo: + newState = !isPlayMusicGame; + isPlayMusicGame = newState; + changed = true; + break; + + case kShredder: + case kToaster: + case kMacPlus: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kMicrowave: + switch (action) + { + case kToggle: + newState = !(*thisHouse)->rooms[room].objects[object].data.g.state; + (*thisHouse)->rooms[room].objects[object].data.g.state = newState; + changed = true; + break; + + case kForceOn: + changed = ((*thisHouse)->rooms[room].objects[object].data.g.state == false); + newState = true; + (*thisHouse)->rooms[room].objects[object].data.g.state = newState; + break; + + case kForceOff: + changed = ((*thisHouse)->rooms[room].objects[object].data.g.state == PL_TRUE); + newState = false; + (*thisHouse)->rooms[room].objects[object].data.g.state = newState; + break; + } + if ((changed) && (local != -1)) + { + masterObjects[local].theObject.data.g.state = newState; + if (room == thisRoomNumber) + { + thisRoom->objects[object].data.g.state = newState; + if ((*thisHouse)->rooms[room].objects[object].what == kShredder) + hotSpots[masterObjects[local].hotNum].isOn = newState; + } + } + break; + + case kCinderBlock: + case kFlowerBox: + case kCDs: + case kCustomPict: + changed = false; + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kBall: + case kDrip: + case kFish: + switch (action) + { + case kToggle: + newState = !(*thisHouse)->rooms[room].objects[object].data.h.state; + (*thisHouse)->rooms[room].objects[object].data.h.state = newState; + changed = true; + break; + + case kForceOn: + changed = ((*thisHouse)->rooms[room].objects[object].data.h.state == false); + newState = true; + (*thisHouse)->rooms[room].objects[object].data.h.state = newState; + break; + + case kForceOff: + changed = ((*thisHouse)->rooms[room].objects[object].data.h.state == PL_TRUE); + newState = false; + (*thisHouse)->rooms[room].objects[object].data.h.state = newState; + break; + } + if ((changed) && (local != -1)) + { + masterObjects[local].theObject.data.h.state = newState; + if (room == thisRoomNumber) + thisRoom->objects[object].data.h.state = newState; + } + break; + + case kCobweb: + changed = false; + break; + + case kOzma: + case kMirror: + case kMousehole: + case kFireplace: + case kFlower: + case kWallWindow: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + case kChimes: + changed = false; + break; + + } + HSetState((Handle)thisHouse, wasState); + + return (changed); +} + +//-------------------------------------------------------------- GetObjectState + +Boolean GetObjectState (short room, short object) +{ + char wasState; + Boolean theState; + + theState = true; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + switch ((*thisHouse)->rooms[room].objects[object].what) + { + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kLeftFan: + case kRightFan: + case kSewerGrate: + case kInvisBlower: + case kGrecoVent: + case kSewerBlower: + case kLiftArea: + theState = (*thisHouse)->rooms[room].objects[object].data.a.state; + break; + + case kTaper: + case kCandle: + case kStubby: + case kTiki: + case kBBQ: + break; + + case kTable: + case kShelf: + case kCabinet: + case kFilingCabinet: + case kWasteBasket: + case kMilkCrate: + case kCounter: + case kDresser: + case kDeckTable: + case kStool: + case kTrunk: + case kInvisObstacle: + case kManhole: + case kBooks: + case kInvisBounce: + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kGreaseRt: + case kGreaseLf: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + theState = (*thisHouse)->rooms[room].objects[object].data.c.state; + break; + + case kSlider: + break; + + case kUpStairs: + case kDownStairs: + case kMailboxLf: + case kMailboxRt: + case kFloorTrans: + case kCeilingTrans: + case kDoorInLf: + case kDoorInRt: + case kDoorExRt: + case kDoorExLf: + case kWindowInLf: + case kWindowInRt: + case kWindowExRt: + case kWindowExLf: + case kInvisTrans: + break; + + case kDeluxeTrans: + theState = (*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F; + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + case kSoundTrigger: + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + theState = (*thisHouse)->rooms[room].objects[object].data.f.state; + break; + + case kStereo: + theState = isPlayMusicGame; + break; + + case kShredder: + case kToaster: + case kMacPlus: + case kGuitar: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kMicrowave: + theState = (*thisHouse)->rooms[room].objects[object].data.g.state; + break; + + case kCinderBlock: + case kFlowerBox: + case kCDs: + case kCustomPict: + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kBall: + case kDrip: + case kFish: + theState = (*thisHouse)->rooms[room].objects[object].data.h.state; + break; + + case kCobweb: + break; + + case kOzma: + case kMirror: + case kMousehole: + case kFireplace: + case kFlower: + case kWallWindow: + case kBear: + case kCalendar: + case kVase1: + case kVase2: + case kBulletin: + case kCloud: + case kFaucet: + case kRug: + case kChimes: + break; + } + + HSetState((Handle)thisHouse, wasState); + + return (theState); +} + +//-------------------------------------------------------------- SendObjectToBack + +#ifndef COMPILEDEMO +void BringSendFrontBack (Boolean bringFront) +{ + houseType *thisHousePtr; + objectType savedObject; + short numLinks, i; + short srcRoom, srcObj; + short sorting[kMaxRoomObs]; + short sorted[kMaxRoomObs]; + char wasState; + + if (bringFront) // No need to bring to frontÉ + { // or send to back if the objectÉ + if (objActive == (kMaxRoomObs - 1)) // in question is already front- + return; // most or backmost. + } + else + { + if (objActive == 0) + return; + } + + CopyThisRoomToRoom(); // Any changes to room writtenÉ + // back to the house handle. + numLinks = CountHouseLinks(); // Determine space needed for all links. + if (numLinks != 0) // Create links list of ALL house links. + { + linksList = nil; + linksList = (linksPtr)NewPtr(sizeof(linksType) * numLinks); + if (linksList == nil) + { + YellowAlert(kYellowCantOrderLinks, MemError()); + return; + } + GenerateLinksList(); // Fill in links list with src/destÉ + } // data on objects and room numbers. + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); // Lock down house. + thisHousePtr = *thisHouse; // Get a pointer to house structure. + + for (i = 0; i < kMaxRoomObs; i++) // Set up an ordered array. + sorting[i] = i; + + savedObject = (*thisHouse)->rooms[thisRoomNumber].objects[objActive]; + + if (bringFront) + { + for (i = objActive; i < kMaxRoomObs - 1; i++) + { // Pull all objects down to fill hole. + (*thisHouse)->rooms[thisRoomNumber].objects[i] = + (*thisHouse)->rooms[thisRoomNumber].objects[i + 1]; + sorting[i] = sorting[i + 1]; + SpinCursor(2); + } + // Insert object at end of array. + (*thisHouse)->rooms[thisRoomNumber].objects[kMaxRoomObs - 1] = savedObject; + sorting[kMaxRoomObs - 1] = objActive; + } + else + { + for (i = objActive; i > 0; i--) + { // Move all objects up to fill hole. + (*thisHouse)->rooms[thisRoomNumber].objects[i] = + (*thisHouse)->rooms[thisRoomNumber].objects[i - 1]; + sorting[i] = sorting[i - 1]; + SpinCursor(2); + } + // Insert object at beginning of array. + (*thisHouse)->rooms[thisRoomNumber].objects[0] = savedObject; + sorting[0] = objActive; + } + + for (i = 0; i < kMaxRoomObs; i++) // Set up retro-ordered array. + sorted[sorting[i]] = i; + + for (i = 0; i < numLinks; i++) // Walk links list in order to assignÉ + { // corrected links to objects moved. + if (linksList[i].destRoom == thisRoomNumber) + { // Does link point to room we re-ordered? + srcRoom = linksList[i].srcRoom; // Room where-which an object is linked from. + if (srcRoom == thisRoomNumber) // Handle special case for local links. + srcObj = sorted[linksList[i].srcObj]; + else + srcObj = linksList[i].srcObj; + + switch ((*thisHouse)->rooms[srcRoom].objects[srcObj].what) + { + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + case kTrigger: + case kLgTrigger: + (*thisHouse)->rooms[srcRoom].objects[srcObj].data.d.who = + sorted[linksList[i].destObj]; + break; + + default: + (*thisHouse)->rooms[srcRoom].objects[srcObj].data.e.who = + sorted[linksList[i].destObj]; + break; + } + } + } + + HSetState((Handle)thisHouse, wasState); + if (linksList != nil) + DisposePtr((Ptr)linksList); + + ForceThisRoom(thisRoomNumber); + + fileDirty = true; + UpdateMenus(false); + InvalWindowRect(mainWindow, &mainWindowRect); + DeselectObject(); + GetThisRoomsObjRects(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + DrawThisRoomsObjects(); + GenerateRetroLinks(); + + InitCursor(); +} +#endif + diff --git a/GpApp/Objects.h b/GpApp/Objects.h new file mode 100644 index 0000000..32aa0aa --- /dev/null +++ b/GpApp/Objects.h @@ -0,0 +1,42 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Objects.h +//---------------------------------------------------------------------------- +//============================================================================ + + +extern GWorldPtr blowerSrcMap; +extern GWorldPtr blowerMaskMap; +extern GWorldPtr furnitureSrcMap; +extern GWorldPtr furnitureMaskMap; +extern GWorldPtr bonusSrcMap; +extern GWorldPtr bonusMaskMap; +extern GWorldPtr pointsSrcMap; +extern GWorldPtr pointsMaskMap; +extern GWorldPtr transSrcMap; +extern GWorldPtr transMaskMap; +extern GWorldPtr switchSrcMap; +extern GWorldPtr lightSrcMap; +extern GWorldPtr lightMaskMap; +extern GWorldPtr applianceSrcMap; +extern GWorldPtr applianceMaskMap; +extern GWorldPtr toastSrcMap; +extern GWorldPtr toastMaskMap; +extern GWorldPtr shredSrcMap; +extern GWorldPtr shredMaskMap; +extern GWorldPtr balloonSrcMap; +extern GWorldPtr balloonMaskMap; +extern GWorldPtr copterSrcMap; +extern GWorldPtr copterMaskMap; +extern GWorldPtr dartSrcMap; +extern GWorldPtr dartMaskMap; +extern GWorldPtr ballSrcMap; +extern GWorldPtr ballMaskMap; +extern GWorldPtr dripSrcMap; +extern GWorldPtr dripMaskMap; +extern GWorldPtr enemySrcMap; +extern GWorldPtr enemyMaskMap; +extern GWorldPtr fishSrcMap; +extern GWorldPtr fishMaskMap; +extern GWorldPtr clutterSrcMap; +extern GWorldPtr clutterMaskMap; diff --git a/GpApp/Play.cpp b/GpApp/Play.cpp new file mode 100644 index 0000000..f5a87d3 --- /dev/null +++ b/GpApp/Play.cpp @@ -0,0 +1,821 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Play.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLResources.h" +#include "Externs.h" +#include "Environ.h" +#include "House.h" +#include "MainWindow.h" +#include "RectUtils.h" +#include "Scoreboard.h" + + +#define kHouseBannerAlert 1009 +#define kInitialGliders 2 +#define kRingDelay 90 +#define kRingSpread 25000 // 25000 +#define kRingBaseDelay 5000 // 5000 +#define kChimeDelay 180 + + +typedef struct +{ + short nextRing; + short rings; + short delay; +} phoneType, *phonePtr; + + +void InitGlider (gliderPtr, short); +void SetHouseToFirstRoom (void); +void SetHouseToSavedRoom (void); +void HandlePlayEvent (void); +void PlayGame (void); +void HandleRoomVisitation (void); +void SetObjectsToDefaults (void); +void InitTelephone (void); +void HandleTelephone (void); +Boolean DoesStarCodeExist (short); +short GetNumStarsRemaining (short, short); + + +phoneType thePhone, theChimes; +Rect glidSrcRect, justRoomsRect; +GWorldPtr glidSrcMap, glid2SrcMap; +GWorldPtr glidMaskMap; +long gameFrame; +short batteryTotal, bandsTotal, foilTotal, mortals; +Boolean playing, evenFrame, twoPlayerGame, showFoil, demoGoing; +Boolean doBackground, playerSuicide, phoneBitSet, tvOn; + +extern WindowPtr menuWindow; +extern FSSpecPtr theHousesSpecs; +extern demoPtr demoData; +extern gameType smallGame; +extern Rect gliderSrc[kNumGliderSrcRects]; +extern Rect boardDestRect, boardSrcRect; +extern long incrementModeTime; +extern short numBands, otherPlayerEscaped, demoIndex, demoHouseIndex; +extern short splashOriginH, splashOriginV, countDown, thisHouseIndex; +extern short numStarsRemaining, numChimes, saidFollow; +extern Boolean quitting, isMusicOn, gameOver, hasMirror, onePlayerLeft; +extern Boolean isPlayMusicIdle, failedMusic, quickerTransitions; +extern Boolean switchedOut; + + +//============================================================== Functions +//-------------------------------------------------------------- NewGame + +void NewGame (short mode) +{ + Rect tempRect; + Size freeBytes, growBytes; + OSErr theErr; + Boolean wasPlayMusicPref; + + AdjustScoreboardHeight(); + gameOver = false; + theMode = kPlayMode; + if (isPlayMusicGame) + { + if (!isMusicOn) + { + theErr = StartMusic(); + if (theErr != noErr) + { + YellowAlert(kYellowNoMusic, theErr); + failedMusic = true; + } + } + SetMusicalMode(kPlayGameScoreMode); + } + else + { + if (isMusicOn) + StopTheMusic(); + } + if (mode != kResumeGameMode) + SetObjectsToDefaults(); + HideCursor(); + if (mode == kResumeGameMode) + SetHouseToSavedRoom(); + else if (mode == kNewGameMode) + SetHouseToFirstRoom(); + DetermineRoomOpenings(); + NilSavedMaps(); + + gameFrame = 0L; + numBands = 0; + demoIndex = 0; + saidFollow = 0; + otherPlayerEscaped = kNoOneEscaped; + onePlayerLeft = false; + playerSuicide = false; + + if (twoPlayerGame) // initialize glider(s) + { + InitGlider(&theGlider, kNewGameMode); + InitGlider(&theGlider2, kNewGameMode); + SetPort((GrafPtr)glidSrcMap); + LoadGraphic(kGliderPictID); + SetPort((GrafPtr)glid2SrcMap); + LoadGraphic(kGlider2PictID); + } + else + { + InitGlider(&theGlider, mode); + SetPort((GrafPtr)glidSrcMap); + LoadGraphic(kGliderPictID); + SetPort((GrafPtr)glid2SrcMap); + LoadGraphic(kGliderFoilPictID); + } + +#if !BUILD_ARCADE_VERSION +// HideMenuBarOld(); // TEMP +#endif + + SetPort((GrafPtr)mainWindow); // paint strip on screen black + tempRect = thisMac.screen; + tempRect.top = tempRect.bottom - 20; // thisMac.menuHigh + PaintRect(&tempRect); + +#ifdef COMPILEQT + if ((thisMac.hasQT) && (hasMovie)) + { + SetMovieGWorld(theMovie, (CGrafPtr)mainWindow, nil); + } +#endif + + SetPort((GrafPtr)workSrcMap); + PaintRect(&workSrcRect); +// if (quickerTransitions) +// DissBitsChunky(&workSrcRect); +// else +// DissBits(&workSrcRect); + +// DebugStr("\pIf screen isn't black, exit to shell."); // TEMP TEMP TEMP + + DrawLocale(); + RefreshScoreboard(kNormalTitleMode); +// if (quickerTransitions) +// DissBitsChunky(&justRoomsRect); +// else +// DissBits(&justRoomsRect); + if (mode == kNewGameMode) + { + BringUpBanner(); + DumpScreenOn(&justRoomsRect); + } + else if (mode == kResumeGameMode) + { + DisplayStarsRemaining(); + DumpScreenOn(&justRoomsRect); + } + else + { + DumpScreenOn(&justRoomsRect); + } + + InitGarbageRects(); + StartGliderFadingIn(&theGlider); + if (twoPlayerGame) + { + StartGliderFadingIn(&theGlider2); + TagGliderIdle(&theGlider2); + theGlider2.dontDraw = true; + } + InitTelephone(); + wasPlayMusicPref = isPlayMusicGame; + + freeBytes = MaxMem(&growBytes); + +#ifdef CREATEDEMODATA + SysBeep(1); +#endif + +#ifdef COMPILEQT + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom)) + { + SetMovieActive(theMovie, true); + if (tvOn) + { + StartMovie(theMovie); + MoviesTask(theMovie, 0); + } + } +#endif + + playing = true; // everything before this line is game set-up + PlayGame(); // everything following is after a game has ended + +#ifdef CREATEDEMODATA + DumpToResEditFile((Ptr)demoData, sizeof(demoType) * (long)demoIndex); +#endif + + isPlayMusicGame = wasPlayMusicPref; + ZeroMirrorRegion(); + +#ifdef COMPILEQT + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom)) + { + tvInRoom = false; + StopMovie(theMovie); + SetMovieActive(theMovie, false); + } +#endif + + twoPlayerGame = false; + theMode = kSplashMode; + InitCursor(); + if (isPlayMusicIdle) + { + if (!isMusicOn) + { + theErr = StartMusic(); + if (theErr != noErr) + { + YellowAlert(kYellowNoMusic, theErr); + failedMusic = true; + } + } + SetMusicalMode(kPlayWholeScoreMode); + } + else + { + if (isMusicOn) + StopTheMusic(); + } + NilSavedMaps(); + SetPortWindowPort(mainWindow); + BlackenScoreboard(); + UpdateMenus(false); + + if (!gameOver) + { + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + + InvalWindowRect(mainWindow, &mainWindowRect); + + SetGWorld(workSrcMap, nil); + PaintRect(&workSrcRect); + QSetRect(&tempRect, 0, 0, 640, 460); + QOffsetRect(&tempRect, splashOriginH, splashOriginV); + LoadScaledGraphic(kSplash8BitPICT, &tempRect); + + SetGWorld(wasCPort, wasWorld); + } + WaitCommandQReleased(); + demoGoing = false; + incrementModeTime = TickCount() + kIdleSplashTicks; +} + +//-------------------------------------------------------------- DoDemoGame + +void DoDemoGame (void) +{ + short wasHouseIndex; + Boolean whoCares; + + wasHouseIndex = thisHouseIndex; + whoCares = CloseHouse(); + thisHouseIndex = demoHouseIndex; + PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); + if (OpenHouse()) + { + whoCares = ReadHouse(); + demoGoing = true; + NewGame(kNewGameMode); + } + whoCares = CloseHouse(); + thisHouseIndex = wasHouseIndex; + PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); + if (OpenHouse()) + whoCares = ReadHouse(); + incrementModeTime = TickCount() + kIdleSplashTicks; +} + +//-------------------------------------------------------------- InitGlider + +void InitGlider (gliderPtr thisGlider, short mode) +{ + WhereDoesGliderBegin(&thisGlider->dest, mode); + + if (mode == kResumeGameMode) + numStarsRemaining = smallGame.wasStarsLeft; + else if (mode == kNewGameMode) + numStarsRemaining = CountStarsInHouse(); + + if (mode == kResumeGameMode) + { + theScore = smallGame.score; + mortals = smallGame.numGliders; + batteryTotal = smallGame.energy; + bandsTotal = smallGame.bands; + foilTotal = smallGame.foil; + thisGlider->mode = smallGame.gliderState; + thisGlider->facing = smallGame.facing; + showFoil = smallGame.showFoil; + + switch (thisGlider->mode) + { + case kGliderBurning: + FlagGliderBurning(thisGlider); + break; + + default: + FlagGliderNormal(thisGlider); + break; + } + } + else + { + theScore = 0L; + mortals = kInitialGliders; + if (twoPlayerGame) + mortals += kInitialGliders; + batteryTotal = 0; + bandsTotal = 0; + foilTotal = 0; + thisGlider->mode = kGliderNormal; + thisGlider->facing = kFaceRight; + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + showFoil = false; + } + + QSetRect(&thisGlider->destShadow, 0, 0, kGliderWide, kShadowHigh); + QOffsetRect(&thisGlider->destShadow, thisGlider->dest.left, kShadowTop); + thisGlider->wholeShadow = thisGlider->destShadow; + + thisGlider->hVel = 0; + thisGlider->vVel = 0; + thisGlider->hDesiredVel = 0; + thisGlider->vDesiredVel = 0; + + thisGlider->tipped = false; + thisGlider->sliding = false; + thisGlider->dontDraw = false; +} + +//-------------------------------------------------------------- SetHouseToFirstRoom + +void SetHouseToFirstRoom (void) +{ + short firstRoom; + + firstRoom = GetFirstRoomNumber(); + ForceThisRoom(firstRoom); +} + +//-------------------------------------------------------------- SetHouseToSavedRoom + +void SetHouseToSavedRoom (void) +{ + ForceThisRoom(smallGame.roomNumber); +} + +//-------------------------------------------------------------- HandlePlayEvent + +void HandlePlayEvent (void) +{ + EventRecord theEvent; + GrafPtr wasPort; + long sleep = 2; + + if (WaitNextEvent(everyEvent, &theEvent, sleep, nil)) + { + if ((theEvent.what == updateEvt) && + ((WindowPtr)theEvent.message == mainWindow)) + { + GetPort(&wasPort); + SetPortWindowPort(mainWindow); + BeginUpdate(mainWindow); + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &justRoomsRect, &justRoomsRect, srcCopy, nil); + RefreshScoreboard(kNormalTitleMode); + EndUpdate(mainWindow); + SetPort(wasPort); + } + else if ((theEvent.what == osEvt) && (theEvent.message & 0x01000000)) + { + if (theEvent.message & 0x00000001) // resume event + { + switchedOut = false; + ToggleMusicWhilePlaying(); + HideCursor(); +// HideMenuBarOld(); // TEMP + } + else // suspend event + { + InitCursor(); + switchedOut = true; + ToggleMusicWhilePlaying(); +// ShowMenuBarOld(); // TEMP replace with Carbon calls + } + } + } +} + +//-------------------------------------------------------------- PlayGame + +void PlayGame (void) +{ + while ((playing) && (!quitting)) + { + gameFrame++; + evenFrame = !evenFrame; + + if (doBackground) + { + do + { + HandlePlayEvent(); + } while (switchedOut); + } + + HandleTelephone(); + + if (twoPlayerGame) + { + HandleDynamics(); + if (!gameOver) + { + GetInput(&theGlider); + GetInput(&theGlider2); + HandleInteraction(); + } + HandleTriggers(); + HandleBands(); + if (!gameOver) + { + HandleGlider(&theGlider); + HandleGlider(&theGlider2); + } + if (playing) + { +#ifdef COMPILEQT + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) + MoviesTask(theMovie, 0); +#endif + RenderFrame(); + HandleDynamicScoreboard(); + } + } + else + { + HandleDynamics(); + if (!gameOver) + { + if (demoGoing) + GetDemoInput(&theGlider); + else + GetInput(&theGlider); + HandleInteraction(); + } + HandleTriggers(); + HandleBands(); + if (!gameOver) + HandleGlider(&theGlider); + if (playing) + { +#ifdef COMPILEQT + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) + MoviesTask(theMovie, 0); +#endif + RenderFrame(); + HandleDynamicScoreboard(); + } + } + + if (gameOver) + { + countDown--; + if (countDown <= 0) + { + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + + HideGlider(&theGlider); + RefreshScoreboard(kNormalTitleMode); + +#if BUILD_ARCADE_VERSION + // Need to paint over the scoreboard black. + + SetGWorld(boardSrcMap, nil); + PaintRect(&boardSrcRect); + + CopyBits((BitMap *)*GetGWorldPixMap(boardSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &boardSrcRect, &boardDestRect, srcCopy, 0L); + + { + Rect bounds; + PicHandle thePicture; + SInt16 hOffset; + + if (boardSrcRect.right >= 640) + hOffset = (RectWide(&boardSrcRect) - kMaxViewWidth) / 2; + else + hOffset = -576; + thePicture = GetPicture(kScoreboardPictID); + if (!thePicture) + RedAlert(kErrFailedGraphicLoad); + HLock((Handle)thePicture); + bounds = (*thePicture)->picFrame; + HUnlock((Handle)thePicture); + QOffsetRect(&bounds, -bounds.left, -bounds.top); + QOffsetRect(&bounds, hOffset, 0); + DrawPicture(thePicture, &bounds); + ReleaseResource((Handle)thePicture); + } +#else +// ShowMenuBarOld(); // TEMP +#endif + + if (mortals < 0) + DoDiedGameOver(); + else + DoGameOver(); + + SetGWorld(wasCPort, wasWorld); + } + } + } + +#if BUILD_ARCADE_VERSION + { + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + + SetGWorld(boardSrcMap, nil); + PaintRect(&boardSrcRect); + + CopyBits((BitMap *)*GetGWorldPixMap(boardSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &boardSrcRect, &boardDestRect, srcCopy, 0L); + + SetGWorld(wasCPort, wasWorld); + } + + { + Rect bounds; + PicHandle thePicture; + SInt16 hOffset; + + if (boardSrcRect.right >= 640) + hOffset = (RectWide(&boardSrcRect) - kMaxViewWidth) / 2; + else + hOffset = -576; + thePicture = GetPicture(kScoreboardPictID); + if (!thePicture) + RedAlert(kErrFailedGraphicLoad); + HLock((Handle)thePicture); + bounds = (*thePicture)->picFrame; + HUnlock((Handle)thePicture); + QOffsetRect(&bounds, -bounds.left, -bounds.top); + QOffsetRect(&bounds, hOffset, 0); + DrawPicture(thePicture, &bounds); + ReleaseResource((Handle)thePicture); + } + +#else + +// ShowMenuBarOld(); // TEMP + +#endif +} + +//-------------------------------------------------------------- SetObjectsToDefaults + +void SetObjectsToDefaults (void) +{ + houseType *thisHousePtr; + short numRooms; + short r, i; + char wasState; + Boolean initState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + numRooms = thisHousePtr->nRooms; + + for (r = 0; r < numRooms; r++) + { + thisHousePtr->rooms[r].visited = false; + for (i = 0; i < kMaxRoomObs; i++) + { + switch (thisHousePtr->rooms[r].objects[i].what) + { + case kFloorVent: + case kCeilingVent: + case kFloorBlower: + case kCeilingBlower: + case kLeftFan: + case kRightFan: + case kSewerGrate: + case kInvisBlower: + case kGrecoVent: + case kSewerBlower: + case kLiftArea: + thisHousePtr->rooms[r].objects[i].data.a.state = + thisHousePtr->rooms[r].objects[i].data.a.initial; + break; + + case kRedClock: + case kBlueClock: + case kYellowClock: + case kCuckoo: + case kPaper: + case kBattery: + case kBands: + case kGreaseRt: + case kGreaseLf: + case kFoil: + case kInvisBonus: + case kStar: + case kSparkle: + case kHelium: + thisHousePtr->rooms[r].objects[i].data.c.state = + thisHousePtr->rooms[r].objects[i].data.c.initial; + break; + + case kDeluxeTrans: + initState = (thisHousePtr->rooms[r].objects[i].data.d.wide & 0xF0) >> 4; + thisHousePtr->rooms[r].objects[i].data.d.wide &= 0xF0; + thisHousePtr->rooms[r].objects[i].data.d.wide += initState; + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + thisHousePtr->rooms[r].objects[i].data.f.state = + thisHousePtr->rooms[r].objects[i].data.f.initial; + break; + + case kStereo: + thisHousePtr->rooms[r].objects[i].data.g.state = isPlayMusicGame; + break; + + case kShredder: + case kToaster: + case kMacPlus: + case kGuitar: + case kTV: + case kCoffee: + case kOutlet: + case kVCR: + case kMicrowave: + thisHousePtr->rooms[r].objects[i].data.g.state = + thisHousePtr->rooms[r].objects[i].data.g.initial; + break; + + case kBalloon: + case kCopterLf: + case kCopterRt: + case kDartLf: + case kDartRt: + case kBall: + case kDrip: + case kFish: + thisHousePtr->rooms[r].objects[i].data.h.state = + thisHousePtr->rooms[r].objects[i].data.h.initial; + break; + + } + } + } + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- HideGlider + +void HideGlider (gliderPtr thisGlider) +{ + Rect tempRect; + + tempRect = thisGlider->whole; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + + if (hasMirror) + { + QOffsetRect(&tempRect, -20, -16); + CopyRectWorkToMain(&tempRect); + } + + tempRect = thisGlider->wholeShadow; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); +} + +//-------------------------------------------------------------- InitTelephone + +void InitTelephone (void) +{ + thePhone.nextRing = RandomInt(kRingSpread) + kRingBaseDelay; + thePhone.rings = RandomInt(3) + 3; + thePhone.delay = kRingDelay; + + theChimes.nextRing = RandomInt(kChimeDelay) + 1; +} + +//-------------------------------------------------------------- HandleTelephone + +void HandleTelephone (void) +{ + short delayTime; + + if (!phoneBitSet) + { + if (thePhone.nextRing == 0) + { + if (thePhone.delay == 0) + { + thePhone.delay = kRingDelay; + PlayPrioritySound(kPhoneRingSound, kPhoneRingPriority); + thePhone.rings--; + if (thePhone.rings == 0) + { + thePhone.nextRing = RandomInt(kRingSpread) + kRingBaseDelay; + thePhone.rings = RandomInt(3) + 3; + } + } + else + thePhone.delay--; + } + else + thePhone.nextRing--; + } + // handle also the wind chimes (if they are present) + + if (numChimes > 0) + { + if (theChimes.nextRing == 0) + { + if (RandomInt(2) == 0) + PlayPrioritySound(kChime1Sound, kChime1Priority); + else + PlayPrioritySound(kChime2Sound, kChime2Priority); + + delayTime = kChimeDelay / numChimes; + if (delayTime < 2) + delayTime = 2; + + theChimes.nextRing = RandomInt(delayTime) + 1; + } + else + theChimes.nextRing--; + } +} + +//-------------------------------------------------------------- StrikeChime + +void StrikeChime (void) +{ + theChimes.nextRing = 0; +} + +//-------------------------------------------------------------- RestoreEntireGameScreen + +void RestoreEntireGameScreen (void) +{ + Rect tempRect; + + HideCursor(); + +#if !BUILD_ARCADE_VERSION +// HideMenuBarOld(); // TEMP +#endif + + SetPort((GrafPtr)mainWindow); + tempRect = thisMac.screen; + PaintRect(&tempRect); + + DrawLocale(); + RefreshScoreboard(kNormalTitleMode); +// if (quickerTransitions) +// DissBitsChunky(&justRoomsRect); +// else +// DissBits(&justRoomsRect); +} + diff --git a/GpApp/Play.h b/GpApp/Play.h new file mode 100644 index 0000000..2851a12 --- /dev/null +++ b/GpApp/Play.h @@ -0,0 +1,13 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Play.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +extern GWorldPtr glidSrcMap; +extern GWorldPtr glid2SrcMap; +extern GWorldPtr glidMaskMap; diff --git a/GpApp/Player.cpp b/GpApp/Player.cpp new file mode 100644 index 0000000..1e9597f --- /dev/null +++ b/GpApp/Player.cpp @@ -0,0 +1,1605 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Player.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Play.h" +#include "RectUtils.h" + + +#define kGravity 3 +#define kHImpulse 2 +#define kVImpulse 2 +#define kMaxHVel 16 +#define kShredderCountdown -68 + + +void MoveGlider (gliderPtr); +void MoveGliderNormal (gliderPtr); +void MoveGliderBurning (gliderPtr); +void FadeGliderIn (gliderPtr); +void TransportGliderIn (gliderPtr); +void FadeGliderOut (gliderPtr); +void MoveGliderUpStairs (gliderPtr); +void MoveGliderDownStairs (gliderPtr); +void MoveGliderFaceLeft (gliderPtr); +void MoveGliderFaceRight (gliderPtr); +void TransportGliderOut (gliderPtr); +void MoveGliderDownDuct (gliderPtr); +void MoveGliderUpDuct (gliderPtr); +void MoveGliderInMailLeft (gliderPtr); +void MoveGliderInMailRight (gliderPtr); +void FinishGliderMailingLeft (gliderPtr); +void FinishGliderMailingRight (gliderPtr); +void MoveGliderFoilGoing (gliderPtr); +void MoveGliderFoilLosing (gliderPtr); +void MoveGliderShredding (gliderPtr); +void HandleIdleGlider (gliderPtr); + + +gliderType theGlider, theGlider2; +Rect shadowSrcRect; +GWorldPtr shadowSrcMap; +GWorldPtr shadowMaskMap; +Rect shadowSrc[kNumShadowSrcRects]; +Rect gliderSrc[kNumGliderSrcRects]; +Rect transRect; +long theScore; +short fadeInSequence[kLastFadeSequence]; +short rightClip, leftClip, transRoom; +Boolean shadowVisible, onePlayerLeft, playerDead; + + +extern short numShredded, otherPlayerEscaped; +extern Boolean playing, twoPlayerGame, gameOver, hasMirror; +extern Boolean takingTheStairs, playerSuicide; + + +//============================================================== Functions +//-------------------------------------------------------------- MoveGlider + +void MoveGlider (gliderPtr thisGlider) +{ + if (thisGlider->hVel > thisGlider->hDesiredVel) + { + thisGlider->hVel -= kHImpulse; + if (thisGlider->hVel < thisGlider->hDesiredVel) + thisGlider->hVel = thisGlider->hDesiredVel; + } + else if (thisGlider->hVel < thisGlider->hDesiredVel) + { + thisGlider->hVel += kHImpulse; + if (thisGlider->hVel > thisGlider->hDesiredVel) + thisGlider->hVel = thisGlider->hDesiredVel; + } + thisGlider->hDesiredVel = 0; + + if (thisGlider->vVel > thisGlider->vDesiredVel) + { + thisGlider->vVel -= kVImpulse; + if (thisGlider->vVel < thisGlider->vDesiredVel) + thisGlider->vVel = thisGlider->vDesiredVel; + } + else if (thisGlider->vVel < thisGlider->vDesiredVel) + { + thisGlider->vVel += kVImpulse; + if (thisGlider->vVel > thisGlider->vDesiredVel) + thisGlider->vVel = thisGlider->vDesiredVel; + } + thisGlider->vDesiredVel = kGravity; + + if (thisGlider->hVel < 0) + { + if (thisGlider->hVel < -kMaxHVel) + thisGlider->hVel = -kMaxHVel; + + thisGlider->wasHVel = thisGlider->hVel; + + thisGlider->whole.right = thisGlider->dest.right; + thisGlider->dest.left += thisGlider->hVel; + thisGlider->dest.right += thisGlider->hVel; + thisGlider->whole.left = thisGlider->dest.left; + + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + thisGlider->destShadow.left += thisGlider->hVel; + thisGlider->destShadow.right += thisGlider->hVel; + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + } + else + { + if (thisGlider->hVel > kMaxHVel) + thisGlider->hVel = kMaxHVel; + + thisGlider->wasHVel = thisGlider->hVel; + + thisGlider->whole.left = thisGlider->dest.left; + thisGlider->dest.left += thisGlider->hVel; + thisGlider->dest.right += thisGlider->hVel; + thisGlider->whole.right = thisGlider->dest.right; + + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + thisGlider->destShadow.left += thisGlider->hVel; + thisGlider->destShadow.right += thisGlider->hVel; + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + } + + if (thisGlider->vVel < 0) + { + thisGlider->wasVVel = thisGlider->vVel; + + thisGlider->whole.bottom = thisGlider->dest.bottom; + thisGlider->dest.top += thisGlider->vVel; + thisGlider->dest.bottom += thisGlider->vVel; + thisGlider->whole.top = thisGlider->dest.top; + } + else + { + thisGlider->wasVVel = thisGlider->vVel; + + thisGlider->whole.top = thisGlider->dest.top; + thisGlider->dest.top += thisGlider->vVel; + thisGlider->dest.bottom += thisGlider->vVel; + thisGlider->whole.bottom = thisGlider->dest.bottom; + } +} + +//-------------------------------------------------------------- MoveGliderNormal + +void MoveGliderNormal (gliderPtr thisGlider) +{ + if (thisGlider->facing == kFaceLeft) + { + if (thisGlider->sliding) + { + thisGlider->src = gliderSrc[30]; + thisGlider->mask = gliderSrc[30]; + thisGlider->sliding = false; + } + else + { + if (thisGlider->tipped) + { + thisGlider->src = gliderSrc[3]; + thisGlider->mask = gliderSrc[3]; + } + else + { + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + } + } + else + { + if (thisGlider->sliding) + { + thisGlider->src = gliderSrc[29]; + thisGlider->mask = gliderSrc[29]; + thisGlider->sliding = false; + } + else + { + if (thisGlider->tipped) + { + thisGlider->src = gliderSrc[1]; + thisGlider->mask = gliderSrc[1]; + } + else + { + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + } + } + } + + MoveGlider(thisGlider); +} + +//-------------------------------------------------------------- MoveGliderBurning + +void MoveGliderBurning (gliderPtr thisGlider) +{ + thisGlider->frame++; + if (thisGlider->frame > 3) + thisGlider->frame = 0; + + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[25 + thisGlider->frame]; + thisGlider->mask = gliderSrc[25 + thisGlider->frame]; + } + else + { + thisGlider->src = gliderSrc[21 + thisGlider->frame]; + thisGlider->mask = gliderSrc[21 + thisGlider->frame]; + } + + thisGlider->wasMode--; + if (thisGlider->wasMode <= 0) + { + StartGliderFadingOut(thisGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + } + MoveGlider(thisGlider); +} + +//-------------------------------------------------------------- FadeGliderIn + +void FadeGliderIn (gliderPtr thisGlider) +{ + if (thisGlider->frame == 0) + PlayPrioritySound(kFadeInSound, kFadeInPriority); + + thisGlider->frame++; + if (thisGlider->frame >= kLastFadeSequence) + { + FlagGliderNormal(thisGlider); + thisGlider->enteredRect = thisGlider->dest; + } + else + { + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + + kLeftFadeOffset]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; + } + } +} + +//-------------------------------------------------------------- TransportGliderIn + +void TransportGliderIn (gliderPtr thisGlider) +{ + if (thisGlider->frame == 0) + PlayPrioritySound(kTransInSound, kTransInPriority); + + thisGlider->frame++; + if (thisGlider->frame >= kLastFadeSequence) + { + FlagGliderNormal(thisGlider); + thisGlider->enteredRect = thisGlider->dest; + } + else + { + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + + kLeftFadeOffset]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; + } + } +} + +//-------------------------------------------------------------- FadeGliderOut + +void FadeGliderOut (gliderPtr thisGlider) +{ + thisGlider->frame--; + if (thisGlider->frame < 0) + OffAMortal(thisGlider); + else + { + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + + kLeftFadeOffset]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; + } + } +} + +//-------------------------------------------------------------- MoveGliderUpStairs + +void MoveGliderUpStairs (gliderPtr thisGlider) +{ + #define kClimbStairsSpeed -4 + short vNotClipped; + + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + else + { + thisGlider->src = gliderSrc[1]; + thisGlider->mask = gliderSrc[1]; + } + + thisGlider->whole.bottom = thisGlider->dest.bottom; + thisGlider->dest.top += kClimbStairsSpeed; + thisGlider->dest.bottom += kClimbStairsSpeed; + thisGlider->whole.top = thisGlider->dest.top; + + vNotClipped = thisGlider->dest.bottom - 29; + if (vNotClipped < kGliderHigh) + { + if (vNotClipped <= 0) + { + thisGlider->dest.top = thisGlider->dest.bottom; + thisGlider->src.top = thisGlider->src.bottom; + thisGlider->mask.top = thisGlider->mask.bottom; + takingTheStairs = true; + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == kPlayer1) + MoveRoomToRoom(&theGlider2, kAbove); + else + MoveRoomToRoom(&theGlider, kAbove); + } + else + { + if (otherPlayerEscaped == kPlayerEscapedUpStairs) + { + otherPlayerEscaped = kNoOneEscaped; + MoveRoomToRoom(thisGlider, kAbove); + } + else + { + otherPlayerEscaped = kPlayerEscapedUpStairs; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + } + } + else + MoveRoomToRoom(thisGlider, kAbove); + } + else + { + thisGlider->dest.top = thisGlider->dest.bottom - vNotClipped; + thisGlider->src.top = thisGlider->src.bottom - vNotClipped; + thisGlider->mask.top = thisGlider->mask.bottom - vNotClipped; + } + } +} + +//-------------------------------------------------------------- FinishGliderUpStairs + +void FinishGliderUpStairs (gliderPtr thisGlider) +{ + #define kVClimbStairsSpeed -4 + #define kHClimbStairsSpeed -4 + short hNotClipped; + + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + + thisGlider->whole.bottom = thisGlider->dest.bottom; + thisGlider->dest.top += kVClimbStairsSpeed; + thisGlider->dest.bottom += kVClimbStairsSpeed; + thisGlider->whole.top = thisGlider->dest.top; + + thisGlider->whole.right = thisGlider->dest.right; + thisGlider->dest.left += kHClimbStairsSpeed; + thisGlider->dest.right += kHClimbStairsSpeed; + thisGlider->whole.left = thisGlider->dest.left; + + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + thisGlider->destShadow.left += kHClimbStairsSpeed; + thisGlider->destShadow.right += kHClimbStairsSpeed; + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + + hNotClipped = rightClip - thisGlider->dest.left; + if (hNotClipped < kGliderWide) + { + thisGlider->dest.right = thisGlider->dest.left + hNotClipped; + thisGlider->src.right = thisGlider->src.left + hNotClipped; + thisGlider->mask.right = thisGlider->mask.left + hNotClipped; + thisGlider->destShadow.right = thisGlider->dest.right; + } + else + { + if (thisGlider->frame == kWasBurning) + FlagGliderBurning(thisGlider); + else + FlagGliderNormal(thisGlider); + thisGlider->hVel = kHClimbStairsSpeed; + thisGlider->hDesiredVel = kHClimbStairsSpeed; + thisGlider->vVel = kVClimbStairsSpeed; + thisGlider->vDesiredVel = kVClimbStairsSpeed; + thisGlider->enteredRect = thisGlider->dest; + } +} + +//-------------------------------------------------------------- MoveGliderDownStairs + +void MoveGliderDownStairs (gliderPtr thisGlider) +{ + #define kVDropStairsSpeed 4 + #define kHDropStairsSpeed 4 + short hNotClipped; + + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + else + { + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + } + + thisGlider->whole.left = thisGlider->dest.left; + thisGlider->dest.left += kHDropStairsSpeed; + thisGlider->dest.right += kHDropStairsSpeed; + thisGlider->whole.right = thisGlider->dest.right; + + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + thisGlider->destShadow.left += kHDropStairsSpeed; + thisGlider->destShadow.right += kHDropStairsSpeed; + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + + thisGlider->whole.top = thisGlider->dest.top; + thisGlider->dest.top += kVDropStairsSpeed; + thisGlider->dest.bottom += kVDropStairsSpeed; + thisGlider->whole.bottom = thisGlider->dest.bottom; + + hNotClipped = rightClip - thisGlider->dest.left; + if (hNotClipped < kGliderWide) + { + if (hNotClipped <= 0) + { + thisGlider->dest.right = thisGlider->dest.left; + thisGlider->src.right = thisGlider->src.left; + thisGlider->mask.right = thisGlider->mask.left; + thisGlider->destShadow.right = thisGlider->dest.right; + takingTheStairs = true; + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == kPlayer1) + MoveRoomToRoom(&theGlider2, kBelow); + else + MoveRoomToRoom(&theGlider, kBelow); + } + else + { + if (otherPlayerEscaped == kPlayerEscapedDownStairs) + { + otherPlayerEscaped = kNoOneEscaped; + MoveRoomToRoom(thisGlider, kBelow); + } + else + { + otherPlayerEscaped = kPlayerEscapedDownStairs; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + } + } + else + MoveRoomToRoom(thisGlider, kBelow); + } + else + { + thisGlider->dest.right = thisGlider->dest.left + hNotClipped; + thisGlider->src.right = thisGlider->src.left + hNotClipped; + thisGlider->mask.right = thisGlider->mask.left + hNotClipped; + thisGlider->destShadow.right = thisGlider->dest.right; + } + } +} + +//-------------------------------------------------------------- FinishGliderDownStairs + +void FinishGliderDownStairs (gliderPtr thisGlider) +{ + #define kVDropStairsSpeed 4 + #define kHDropStairsSpeed 4 + short hNotClipped; + + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + + thisGlider->whole.left = thisGlider->dest.left; + thisGlider->dest.left += kHDropStairsSpeed; + thisGlider->dest.right += kHDropStairsSpeed; + thisGlider->whole.right = thisGlider->dest.right; + + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + thisGlider->destShadow.left += kHDropStairsSpeed; + thisGlider->destShadow.right += kHDropStairsSpeed; + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + + thisGlider->whole.top = thisGlider->dest.top; + thisGlider->dest.top += kVDropStairsSpeed; + thisGlider->dest.bottom += kVDropStairsSpeed; + thisGlider->whole.bottom = thisGlider->dest.bottom; + + hNotClipped = thisGlider->dest.right - leftClip; + if (hNotClipped < kGliderWide) + { + thisGlider->dest.left = thisGlider->dest.right - hNotClipped; + thisGlider->src.left = thisGlider->src.right - hNotClipped; + thisGlider->mask.left = thisGlider->mask.right - hNotClipped; + thisGlider->destShadow.left = thisGlider->dest.left; + } + else + { + if (thisGlider->frame == kWasBurning) + FlagGliderBurning(thisGlider); + else + FlagGliderNormal(thisGlider); + thisGlider->hVel = kHDropStairsSpeed; + thisGlider->hDesiredVel = kHDropStairsSpeed; + thisGlider->vVel = kVDropStairsSpeed; + thisGlider->vDesiredVel = kVDropStairsSpeed; + thisGlider->enteredRect = thisGlider->dest; + } +} + +//-------------------------------------------------------------- MoveGliderFaceLeft + +void MoveGliderFaceLeft (gliderPtr thisGlider) +{ + thisGlider->src = gliderSrc[thisGlider->frame]; + thisGlider->mask = gliderSrc[thisGlider->frame]; + + MoveGlider(thisGlider); + + thisGlider->frame--; + if (thisGlider->frame < kFirstAboutFaceFrame) + { + thisGlider->mode = kGliderNormal; + thisGlider->facing = kFaceLeft; + } +} + +//-------------------------------------------------------------- MoveGliderFaceRight + +void MoveGliderFaceRight (gliderPtr thisGlider) +{ + thisGlider->src = gliderSrc[thisGlider->frame]; + thisGlider->mask = gliderSrc[thisGlider->frame]; + + MoveGlider(thisGlider); + + thisGlider->frame++; + if (thisGlider->frame > kLastAboutFaceFrame) + { + thisGlider->mode = kGliderNormal; + thisGlider->facing = kFaceRight; + } +} + +//-------------------------------------------------------------- TransportGliderOut + +void TransportGliderOut (gliderPtr thisGlider) +{ + Rect tempRect; + + thisGlider->frame--; + if (thisGlider->frame < 0) + { + tempRect = thisGlider->whole; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + tempRect = thisGlider->wholeShadow; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + thisGlider->dontDraw = true; + + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == kPlayer1) + TransportRoomToRoom(&theGlider2); + else + TransportRoomToRoom(&theGlider); + } + else + { + if (otherPlayerEscaped == kPlayerTransportedOut) + { + otherPlayerEscaped = kNoOneEscaped; + TransportRoomToRoom(thisGlider); + } + else + { + otherPlayerEscaped = kPlayerTransportedOut; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + } + } + else + { + TransportRoomToRoom(thisGlider); + } + } + else + { + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + + kLeftFadeOffset]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; + thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; + } + } +} + +//-------------------------------------------------------------- MoveGliderDownDuct + +void MoveGliderDownDuct (gliderPtr thisGlider) +{ + #define kVDropDuctSpeed 4 + Rect tempRect; + short vNotClipped; + + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + else + { + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + } + + if (thisGlider->dest.left < thisGlider->clip.left) + { + thisGlider->whole.left = thisGlider->dest.left; + thisGlider->dest.left++; + thisGlider->dest.right++; + thisGlider->whole.right = thisGlider->dest.right; + + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + thisGlider->destShadow.left++; + thisGlider->destShadow.right++; + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + } + else if (thisGlider->dest.left > thisGlider->clip.left) + { + thisGlider->whole.right = thisGlider->dest.right; + thisGlider->dest.left--; + thisGlider->dest.right--; + thisGlider->whole.left = thisGlider->dest.left; + + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + thisGlider->destShadow.left--; + thisGlider->destShadow.right--; + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + } + + thisGlider->whole.top = thisGlider->dest.top; + thisGlider->dest.top += kVDropDuctSpeed; + thisGlider->dest.bottom += kVDropDuctSpeed; + thisGlider->whole.bottom = thisGlider->dest.bottom; + + vNotClipped = 315 - thisGlider->dest.top; + if (vNotClipped < kGliderHigh) + { + if (vNotClipped <= 0) + { + tempRect = thisGlider->whole; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + tempRect = thisGlider->wholeShadow; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + thisGlider->dontDraw = true; + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == kPlayer1) + MoveDuctToDuct(&theGlider2); + else + MoveDuctToDuct(&theGlider); + } + else + { + if (otherPlayerEscaped == kPlayerDuckedOut) + { + otherPlayerEscaped = kNoOneEscaped; + MoveDuctToDuct(thisGlider); + } + else + { + otherPlayerEscaped = kPlayerDuckedOut; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + } + } + else + MoveDuctToDuct(thisGlider); + } + else + { + thisGlider->dest.bottom = thisGlider->dest.top + vNotClipped; + thisGlider->src.bottom = thisGlider->src.top + vNotClipped; + thisGlider->mask.bottom = thisGlider->mask.top + vNotClipped; + } + } +} + +//-------------------------------------------------------------- MoveGliderUpDuct + +void MoveGliderUpDuct (gliderPtr thisGlider) +{ + #define kVRiseDuctSpeed -4 + Rect tempRect; + short vNotClipped; + + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + else + { + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + } + + if (thisGlider->dest.left < thisGlider->clip.left) + { + thisGlider->whole.left = thisGlider->dest.left; + thisGlider->dest.left++; + thisGlider->dest.right++; + thisGlider->whole.right = thisGlider->dest.right; + + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + thisGlider->destShadow.left++; + thisGlider->destShadow.right++; + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + } + else if (thisGlider->dest.left > thisGlider->clip.left) + { + thisGlider->whole.right = thisGlider->dest.right; + thisGlider->dest.left--; + thisGlider->dest.right--; + thisGlider->whole.left = thisGlider->dest.left; + + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + thisGlider->destShadow.left--; + thisGlider->destShadow.right--; + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + } + + thisGlider->whole.bottom = thisGlider->dest.bottom; + thisGlider->dest.top += kVRiseDuctSpeed; + thisGlider->dest.bottom += kVRiseDuctSpeed; + thisGlider->whole.top = thisGlider->dest.top; + + vNotClipped = thisGlider->dest.bottom - (kCeilingTransTop + 1); + if (vNotClipped < kGliderHigh) + { + if (vNotClipped <= 0) + { + tempRect = thisGlider->whole; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + tempRect = thisGlider->wholeShadow; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + thisGlider->dontDraw = true; + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == kPlayer1) + MoveDuctToDuct(&theGlider2); + else + MoveDuctToDuct(&theGlider); + } + else + { + if (otherPlayerEscaped == kPlayerDuckedOut) + { + otherPlayerEscaped = kNoOneEscaped; + MoveDuctToDuct(thisGlider); + } + else + { + otherPlayerEscaped = kPlayerDuckedOut; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + } + } + else + MoveDuctToDuct(thisGlider); + } + else + { + thisGlider->dest.top = thisGlider->dest.bottom - vNotClipped; + thisGlider->src.top = thisGlider->src.bottom - vNotClipped; + thisGlider->mask.top = thisGlider->mask.bottom - vNotClipped; + } + } +} + +//-------------------------------------------------------------- FinishGliderMailingLeft + +void FinishGliderMailingLeft (gliderPtr thisGlider) +{ + #define kHPushMailSpeed -4 + short hNotClipped; + + if (thisGlider->dest.left == thisGlider->dest.right) + PlayPrioritySound(kTransInSound, kTransInPriority); + + thisGlider->whole.right = thisGlider->dest.right; + thisGlider->dest.left += kHPushMailSpeed; + thisGlider->dest.right += kHPushMailSpeed; + thisGlider->whole.left = thisGlider->dest.left; + + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + thisGlider->destShadow.left += kHPushMailSpeed; + thisGlider->destShadow.right += kHPushMailSpeed; + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + + hNotClipped = thisGlider->clip.right - thisGlider->dest.left; + if (hNotClipped < kGliderWide) + { + thisGlider->dest.right = thisGlider->dest.left + hNotClipped; + thisGlider->src.right = thisGlider->src.left + hNotClipped; + thisGlider->mask.right = thisGlider->mask.left + hNotClipped; + thisGlider->destShadow.right = thisGlider->dest.right; + } + else + { + if (thisGlider->frame == kWasBurning) + FlagGliderBurning(thisGlider); + else + FlagGliderNormal(thisGlider); + thisGlider->enteredRect = thisGlider->dest; + } +} + +//-------------------------------------------------------------- FinishGliderMailingRight + +void FinishGliderMailingRight (gliderPtr thisGlider) +{ + #define kHPushMailRtSpeed 4 + short hNotClipped; + + if (thisGlider->dest.left == thisGlider->dest.right) + PlayPrioritySound(kTransInSound, kTransInPriority); + + thisGlider->whole.left = thisGlider->dest.left; + thisGlider->dest.left += kHPushMailRtSpeed; + thisGlider->dest.right += kHPushMailRtSpeed; + thisGlider->whole.right = thisGlider->dest.right; + + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + thisGlider->destShadow.left += kHPushMailRtSpeed; + thisGlider->destShadow.right += kHPushMailRtSpeed; + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + + hNotClipped = thisGlider->dest.right - thisGlider->clip.left; + if (hNotClipped < kGliderWide) + { + thisGlider->dest.left = thisGlider->dest.right - hNotClipped; + thisGlider->src.left = thisGlider->src.right - hNotClipped; + thisGlider->mask.left = thisGlider->mask.right - hNotClipped; + thisGlider->destShadow.left = thisGlider->dest.left; + } + else + { + if (thisGlider->frame == kWasBurning) + FlagGliderBurning(thisGlider); + else + FlagGliderNormal(thisGlider); + thisGlider->enteredRect = thisGlider->dest; + } +} + +//-------------------------------------------------------------- FinishGliderDuctingIn + +void FinishGliderDuctingIn (gliderPtr thisGlider) +{ + #define kVDropStairsSpeed 4 + short vNotClipped; + + if (thisGlider->dest.top == thisGlider->dest.bottom) + PlayPrioritySound(kTransInSound, kTransInPriority); + + thisGlider->whole.top = thisGlider->dest.top; + thisGlider->dest.top += kVDropDuctSpeed; + thisGlider->dest.bottom += kVDropDuctSpeed; + thisGlider->whole.bottom = thisGlider->dest.bottom; + + vNotClipped = thisGlider->dest.bottom - (kCeilingTransTop + 1); + if (vNotClipped < kGliderHigh) + { + thisGlider->dest.top = thisGlider->dest.bottom - vNotClipped; + thisGlider->src.top = thisGlider->src.bottom - vNotClipped; + thisGlider->mask.top = thisGlider->mask.bottom - vNotClipped; + } + else + { + if (thisGlider->frame == kWasBurning) + FlagGliderBurning(thisGlider); + else + FlagGliderNormal(thisGlider); + thisGlider->enteredRect = thisGlider->dest; + FlagStillOvers(thisGlider); + } +} + +//-------------------------------------------------------------- MoveGliderInMailLeft + +void MoveGliderInMailLeft (gliderPtr thisGlider) +{ + #define kHMailPullSpeed 4 + #define kVMailDropSpeed 2 + Rect tempRect; + short fromIdealTop, hNotClipped; + + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + else + { + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + } + + if (thisGlider->dest.top < thisGlider->clip.top) + { + fromIdealTop = thisGlider->clip.top - thisGlider->dest.top; + if (fromIdealTop > kVMailDropSpeed) + fromIdealTop = kVMailDropSpeed; + + thisGlider->whole.top = thisGlider->dest.top; + thisGlider->dest.top += fromIdealTop; + thisGlider->dest.bottom += fromIdealTop; + thisGlider->whole.bottom = thisGlider->dest.bottom; + } + + thisGlider->whole.left = thisGlider->dest.left; + thisGlider->dest.left += kHMailPullSpeed; + thisGlider->dest.right += kHMailPullSpeed; + thisGlider->whole.right = thisGlider->dest.right; + + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + thisGlider->destShadow.left += kHMailPullSpeed; + thisGlider->destShadow.right += kHMailPullSpeed; + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + + hNotClipped = thisGlider->clip.right - thisGlider->dest.left; + if (hNotClipped < kGliderWide) + { + if (hNotClipped <= 0) + { + tempRect = thisGlider->whole; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + tempRect = thisGlider->wholeShadow; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + thisGlider->dontDraw = true; + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == kPlayer1) + MoveMailToMail(&theGlider2); + else + MoveMailToMail(&theGlider); + } + else + { + if (otherPlayerEscaped == kPlayerMailedOut) + { + otherPlayerEscaped = kNoOneEscaped; + MoveMailToMail(thisGlider); + } + else + { + otherPlayerEscaped = kPlayerMailedOut; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + } + } + else + MoveMailToMail(thisGlider); + } + else + { + thisGlider->dest.right = thisGlider->dest.left + hNotClipped; + thisGlider->src.right = thisGlider->src.left + hNotClipped; + thisGlider->mask.right = thisGlider->mask.left + hNotClipped; + thisGlider->destShadow.right = thisGlider->dest.right; + } + } +} + +//-------------------------------------------------------------- MoveGliderInMailRight + +void MoveGliderInMailRight (gliderPtr thisGlider) +{ + #define kHMailPullRtSpeed -4 + #define kVMailDropSpeed 2 + Rect tempRect; + short fromIdealTop, hNotClipped; + + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + else + { + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + } + + if (thisGlider->dest.top < thisGlider->clip.top) + { + fromIdealTop = thisGlider->clip.top - thisGlider->dest.top; + if (fromIdealTop > kVMailDropSpeed) + fromIdealTop = kVMailDropSpeed; + + thisGlider->whole.top = thisGlider->dest.top; + thisGlider->dest.top += fromIdealTop; + thisGlider->dest.bottom += fromIdealTop; + thisGlider->whole.bottom = thisGlider->dest.bottom; + } + + thisGlider->whole.right = thisGlider->dest.right; + thisGlider->dest.left += kHMailPullRtSpeed; + thisGlider->dest.right += kHMailPullRtSpeed; + thisGlider->whole.left = thisGlider->dest.left; + + thisGlider->wholeShadow.right = thisGlider->destShadow.right; + thisGlider->destShadow.left += kHMailPullRtSpeed; + thisGlider->destShadow.right += kHMailPullRtSpeed; + thisGlider->wholeShadow.left = thisGlider->destShadow.left; + + hNotClipped = thisGlider->dest.right - thisGlider->clip.left; + if (hNotClipped < kGliderWide) + { + if (hNotClipped <= 0) + { + tempRect = thisGlider->whole; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + tempRect = thisGlider->wholeShadow; + QOffsetRect(&tempRect, playOriginH, playOriginV); + CopyRectWorkToMain(&tempRect); + thisGlider->dontDraw = true; + if (twoPlayerGame) + { + if (onePlayerLeft) + { + if (playerDead == kPlayer1) + MoveMailToMail(&theGlider2); + else + MoveMailToMail(&theGlider); + } + else + { + if (otherPlayerEscaped == kPlayerMailedOut) + { + otherPlayerEscaped = kNoOneEscaped; + MoveMailToMail(thisGlider); + } + else + { + otherPlayerEscaped = kPlayerMailedOut; + RefreshScoreboard(kEscapedTitleMode); + FlagGliderInLimbo(thisGlider, true); + } + } + } + else + MoveMailToMail(thisGlider); + } + else + { + thisGlider->dest.left = thisGlider->dest.right - hNotClipped; + thisGlider->src.left = thisGlider->src.right - hNotClipped; + thisGlider->mask.left = thisGlider->mask.right - hNotClipped; + thisGlider->destShadow.left = thisGlider->dest.left; + } + } +} + +//-------------------------------------------------------------- DeckGliderInFoil + +void DeckGliderInFoil (gliderPtr thisGlider) +{ + showFoil = true; + + if (twoPlayerGame) + { + SetPort((GrafPtr)glidSrcMap); + LoadGraphic(kGliderFoilPictID); + SetPort((GrafPtr)glid2SrcMap); + LoadGraphic(kGliderFoil2PictID); + } + + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[(thisGlider->frame + 2) + + kLeftFadeOffset]; + thisGlider->mask = gliderSrc[(thisGlider->frame + 2) + + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[thisGlider->frame + 2]; + thisGlider->mask = gliderSrc[thisGlider->frame + 2]; + } +} + +//-------------------------------------------------------------- MoveGliderFoilGoing + +void MoveGliderFoilGoing (gliderPtr thisGlider) +{ + thisGlider->frame++; + if (thisGlider->frame > 8) + { + FlagGliderNormal(thisGlider); + } + else + { + if (thisGlider->frame < 5) + { + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[(10 - thisGlider->frame) + + kLeftFadeOffset]; + thisGlider->mask = gliderSrc[(10 - thisGlider->frame) + + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[10 - thisGlider->frame]; + thisGlider->mask = gliderSrc[10 - thisGlider->frame]; + } + } + else + DeckGliderInFoil(thisGlider); + } + MoveGlider(thisGlider); +} + +//-------------------------------------------------------------- xxxx + +void RemoveFoilFromGlider (gliderPtr thisGlider) +{ + showFoil = false; + + if (twoPlayerGame) + { + SetPort((GrafPtr)glidSrcMap); + LoadGraphic(kGliderPictID); + SetPort((GrafPtr)glid2SrcMap); + LoadGraphic(kGlider2PictID); + } + + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[(thisGlider->frame + 2) + + kLeftFadeOffset]; + thisGlider->mask = gliderSrc[(thisGlider->frame + 2) + + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[thisGlider->frame + 2]; + thisGlider->mask = gliderSrc[thisGlider->frame + 2]; + } +} + +//-------------------------------------------------------------- MoveGliderFoilLosing + +void MoveGliderFoilLosing (gliderPtr thisGlider) +{ + thisGlider->frame++; + if (thisGlider->frame > 8) + FlagGliderNormal(thisGlider); + else + { + if (thisGlider->frame < 5) + { + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[(10 - thisGlider->frame) + + kLeftFadeOffset]; + thisGlider->mask = gliderSrc[(10 - thisGlider->frame) + + kLeftFadeOffset]; + } + else + { + thisGlider->src = gliderSrc[10 - thisGlider->frame]; + thisGlider->mask = gliderSrc[10 - thisGlider->frame]; + } + } + else + RemoveFoilFromGlider(thisGlider); + } + MoveGlider(thisGlider); +} + +//-------------------------------------------------------------- MoveGliderShredding + +void MoveGliderShredding (gliderPtr thisGlider) +{ + #define kDropShredSlow 1 + #define kDropShredFast 4 + short vNotClipped; + + if (thisGlider->frame > 0) + { + if (thisGlider->facing == kFaceLeft) + { + thisGlider->src = gliderSrc[2]; + thisGlider->mask = gliderSrc[2]; + } + else + { + thisGlider->src = gliderSrc[0]; + thisGlider->mask = gliderSrc[0]; + } + + vNotClipped = thisGlider->frame - thisGlider->dest.top; + if (vNotClipped < kGliderHigh) + { + thisGlider->whole.top = thisGlider->dest.top; + thisGlider->dest.top += kDropShredSlow; + thisGlider->dest.bottom += kDropShredSlow; + thisGlider->whole.bottom = thisGlider->dest.bottom; + shadowVisible = false; + PlayPrioritySound(kShredSound, kShredPriority); + } + else + { + thisGlider->whole.top = thisGlider->dest.top; + thisGlider->dest.top += kDropShredFast; + thisGlider->dest.bottom += kDropShredFast; + thisGlider->whole.bottom = thisGlider->dest.bottom; + } + + vNotClipped = thisGlider->frame - thisGlider->dest.top; + if (vNotClipped < kGliderHigh) + { + if (vNotClipped <= 0) + { + AddAShreddedGlider(&thisGlider->dest); + thisGlider->frame = kShredderCountdown; + } + else + { + thisGlider->dest.bottom = thisGlider->dest.top + vNotClipped; + thisGlider->src.bottom = thisGlider->src.top + vNotClipped; + thisGlider->mask.bottom = thisGlider->mask.top + vNotClipped; + } + } + } + else + { + thisGlider->frame++; + if (thisGlider->frame >= 0) + OffAMortal(thisGlider); + } +} + +//-------------------------------------------------------------- HandleIdleGlider + +void HandleIdleGlider (gliderPtr thisGlider) +{ + thisGlider->hVel--; + if (thisGlider->hVel <= 0) + { + thisGlider->mode = thisGlider->wasMode; + thisGlider->dontDraw = false; + } +} + +//-------------------------------------------------------------- HandleGlider + +void HandleGlider (gliderPtr thisGlider) +{ + switch (thisGlider->mode) + { + case kGliderNormal: + MoveGliderNormal(thisGlider); + break; + + case kGliderFadingIn: + FadeGliderIn(thisGlider); + break; + + case kGliderFadingOut: + FadeGliderOut(thisGlider); + break; + + case kGliderGoingUp: + MoveGliderUpStairs(thisGlider); + break; + + case kGliderComingUp: + FinishGliderUpStairs(thisGlider); + break; + + case kGliderGoingDown: + MoveGliderDownStairs(thisGlider); + break; + + case kGliderComingDown: + FinishGliderDownStairs(thisGlider); + break; + + case kGliderFaceLeft: + MoveGliderFaceLeft(thisGlider); + break; + + case kGliderFaceRight: + MoveGliderFaceRight(thisGlider); + break; + + case kGliderBurning: + MoveGliderBurning(thisGlider); + break; + + case kGliderTransporting: + TransportGliderOut(thisGlider); + break; + + case kGliderDuctingDown: + MoveGliderDownDuct(thisGlider); + break; + + case kGliderDuctingUp: + MoveGliderUpDuct(thisGlider); + break; + + case kGliderDuctingIn: + FinishGliderDuctingIn(thisGlider); + break; + + case kGliderMailInLeft: + MoveGliderInMailLeft(thisGlider); + break; + + case kGliderMailOutLeft: // <-- G _[] + FinishGliderMailingLeft(thisGlider); + break; + + case kGliderMailInRight: + MoveGliderInMailRight(thisGlider); + break; + + case kGliderMailOutRight: // []_ G --> + FinishGliderMailingRight(thisGlider); + break; + + case kGliderGoingFoil: + MoveGliderFoilGoing(thisGlider); + break; + + case kGliderLosingFoil: + MoveGliderFoilLosing(thisGlider); + break; + + case kGliderShredding: + MoveGliderShredding(thisGlider); + break; + + case kGliderInLimbo: + break; + + case kGliderIdle: + HandleIdleGlider(thisGlider); + break; + + case kGliderTransportingIn: + TransportGliderIn(thisGlider); + break; + + } + + thisGlider->ignoreLeft = false; + thisGlider->ignoreRight = false; + thisGlider->ignoreGround = false; +} + +//-------------------------------------------------------------- OffsetGlider + +void OffsetGlider (gliderPtr thisGlider, short where) +{ + if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) + return; + + switch (where) + { + case kToRight: + thisGlider->dest.left += kRoomWide; + thisGlider->dest.right += kRoomWide; + thisGlider->destShadow.left += kRoomWide; + thisGlider->destShadow.right += kRoomWide; + thisGlider->whole = thisGlider->dest; + thisGlider->wholeShadow = thisGlider->destShadow; + break; + + case kToLeft: + thisGlider->dest.left -= kRoomWide; + thisGlider->dest.right -= kRoomWide; + thisGlider->destShadow.left -= kRoomWide; + thisGlider->destShadow.right -= kRoomWide; + thisGlider->whole = thisGlider->dest; + thisGlider->wholeShadow = thisGlider->destShadow; + break; + + case kAbove: + thisGlider->dest.top -= kTileHigh; + thisGlider->dest.bottom -= kTileHigh; + thisGlider->whole = thisGlider->dest; + break; + + case kBelow: + thisGlider->dest.top += kTileHigh; + thisGlider->dest.bottom += kTileHigh; + thisGlider->whole = thisGlider->dest; + break; + } +} + +//-------------------------------------------------------------- OffAMortal + +void OffAMortal (gliderPtr thisGlider) +{ + if (gameOver) + return; + + if (numShredded > 0) + RemoveShreds(); + + mortals--; + if (mortals < 0) + { + HideGlider(thisGlider); + if (twoPlayerGame) + { + if (mortals < -1) // both players are now dead + { + FlagGameOver(); + thisGlider->dontDraw = true; + } + else + { + FlagGliderInLimbo(thisGlider, false); + thisGlider->dontDraw = true; + onePlayerLeft = true; + playerDead = thisGlider->which; + } + } + else + { + FlagGameOver(); + thisGlider->dontDraw = true; + } + } + else + { + QuickGlidersRefresh(); + HideGlider(thisGlider); + } + + if (mortals >= 0) + { + if (thisGlider->mode == kGliderGoingFoil) + DeckGliderInFoil(thisGlider); + + FlagGliderNormal(thisGlider); + if (playerSuicide) + FollowTheLeader(); + else + { + StartGliderFadingIn(thisGlider); + thisGlider->dest = thisGlider->enteredRect; + thisGlider->whole = thisGlider->dest; + thisGlider->destShadow.left = thisGlider->dest.left; + thisGlider->destShadow.right = thisGlider->dest.right; + thisGlider->wholeShadow = thisGlider->destShadow; + } + } + else if ((mortals == -1) && (onePlayerLeft) && (!gameOver)) + { + switch (otherPlayerEscaped) + { + case kPlayerEscapedUp: + case kPlayerEscapingUpStairs: + case kPlayerEscapedUpStairs: + if (playerDead == kPlayer1) + MoveRoomToRoom(&theGlider2, kAbove); + else + MoveRoomToRoom(&theGlider, kAbove); + break; + + case kPlayerEscapedDown: + case kPlayerEscapingDownStairs: + case kPlayerEscapedDownStairs: + if (playerDead == kPlayer1) + MoveRoomToRoom(&theGlider2, kBelow); + else + MoveRoomToRoom(&theGlider, kBelow); + break; + + case kPlayerEscapedLeft: + if (playerDead == kPlayer1) + MoveRoomToRoom(&theGlider2, kToLeft); + else + MoveRoomToRoom(&theGlider, kToLeft); + break; + + case kPlayerEscapedRight: + if (playerDead == kPlayer1) + MoveRoomToRoom(&theGlider2, kToRight); + else + MoveRoomToRoom(&theGlider, kToRight); + break; + + case kPlayerTransportedOut: + if (playerDead == kPlayer1) + TransportRoomToRoom(&theGlider2); + else + TransportRoomToRoom(&theGlider); + break; + + case kPlayerMailedOut: + if (playerDead == kPlayer1) + MoveMailToMail(&theGlider2); + else + MoveMailToMail(&theGlider); + break; + + case kPlayerDuckedOut: + if (playerDead == kPlayer1) + MoveDuctToDuct(&theGlider2); + else + MoveDuctToDuct(&theGlider); + break; + + default: + break; + } + + otherPlayerEscaped = kPlayerIsDeadForever; + } +} + diff --git a/GpApp/Player.h b/GpApp/Player.h new file mode 100644 index 0000000..669f23a --- /dev/null +++ b/GpApp/Player.h @@ -0,0 +1,12 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Player.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +extern GWorldPtr shadowSrcMap; +extern GWorldPtr shadowMaskMap; diff --git a/Prefix.h b/GpApp/Prefix.h old mode 100755 new mode 100644 similarity index 100% rename from Prefix.h rename to GpApp/Prefix.h diff --git a/GpApp/Prefs.cpp b/GpApp/Prefs.cpp new file mode 100644 index 0000000..10cd308 --- /dev/null +++ b/GpApp/Prefs.cpp @@ -0,0 +1,269 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Prefs.c +//---------------------------------------------------------------------------- +//============================================================================ + +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" + + +#define kPrefCreatorType 'ozm5' +#define kPrefFileType 'gliP' +#define kPrefFileName PSTR("Glider Prefs") +#define kDefaultPrefFName PSTR("Preferences") +#define kPrefsStringsID 160 +#define kNewPrefsAlertID 160 +#define kPrefsFNameIndex 1 + + +Boolean CanUseFindFolder (void); +Boolean GetPrefsFPath (long *, short *); +Boolean CreatePrefsFolder (short *); +Boolean WritePrefs (long *, short *, prefsInfo *); +OSErr ReadPrefs (long *, short *, prefsInfo *); +Boolean DeletePrefs (long *, short *); +void BringUpDeletePrefsAlert (void); + + +//============================================================== Functions +//-------------------------------------------------------------- CanUseFindFolder + +Boolean CanUseFindFolder (void) +{ + return true; +} + +//-------------------------------------------------------------- GetPrefsFPath + +Boolean GetPrefsFPath (long *prefDirID, short *systemVolRef) +{ + OSErr theErr; + + theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, + systemVolRef, prefDirID); + if (theErr != noErr) + return(false); + + return(true); +} + +//-------------------------------------------------------------- CreatePrefsFolder + +Boolean CreatePrefsFolder (short *systemVolRef) +{ + HFileParam fileParamBlock; + Str255 folderName; + OSErr theErr; + + GetIndString(folderName, kPrefsStringsID, kPrefsFNameIndex); + + fileParamBlock.ioVRefNum = *systemVolRef; + fileParamBlock.ioDirID = 0; + fileParamBlock.ioNamePtr = folderName; + fileParamBlock.ioCompletion = nil; + + theErr = PBDirCreate(&fileParamBlock, false); + if (theErr != noErr) + { + CheckFileError(theErr, PSTR("Preferences")); + return(false); + } + return(true); +} + +//-------------------------------------------------------------- WritePrefs + +Boolean WritePrefs (long *prefDirID, short *systemVolRef, prefsInfo *thePrefs) +{ + OSErr theErr; + short fileRefNum; + long byteCount; + FSSpec theSpecs; + Str255 fileName; + + PasStringCopy(kPrefFileName, fileName); + + theErr = FSMakeFSSpec(*systemVolRef, *prefDirID, fileName, &theSpecs); + if (theErr != noErr) + { + if (theErr != fnfErr) + { + CheckFileError(theErr, PSTR("Preferences")); + return(false); + } + theErr = FSpCreate(&theSpecs, kPrefCreatorType, kPrefFileType, smSystemScript); + if (theErr != noErr) + { + CheckFileError(theErr, PSTR("Preferences")); + return(false); + } + } + theErr = FSpOpenDF(&theSpecs, fsRdWrPerm, &fileRefNum); + if (theErr != noErr) + { + CheckFileError(theErr, PSTR("Preferences")); + return(false); + } + + byteCount = sizeof(*thePrefs); + + theErr = FSWrite(fileRefNum, &byteCount, thePrefs); + if (theErr != noErr) + { + CheckFileError(theErr, PSTR("Preferences")); + return(false); + } + + theErr = FSClose(fileRefNum); + if (theErr != noErr) + { + CheckFileError(theErr, PSTR("Preferences")); + return(false); + } + + return(true); +} + +//-------------------------------------------------------------- SavePrefs + +Boolean SavePrefs (prefsInfo *thePrefs, short versionNow) +{ + long prefDirID; + short systemVolRef; + + thePrefs->prefVersion = versionNow; + + if (!GetPrefsFPath(&prefDirID, &systemVolRef)) + return(false); + + if (!WritePrefs(&prefDirID, &systemVolRef, thePrefs)) + return(false); + + return(true); +} + +//-------------------------------------------------------------- ReadPrefs + +OSErr ReadPrefs (long *prefDirID, short *systemVolRef, prefsInfo *thePrefs) +{ + OSErr theErr; + short fileRefNum; + long byteCount; + FSSpec theSpecs; + Str255 fileName; + + PasStringCopy(kPrefFileName, fileName); + + theErr = FSMakeFSSpec(*systemVolRef, *prefDirID, fileName, &theSpecs); + if (theErr != noErr) + { + if (theErr == fnfErr) + return(theErr); + else + { + CheckFileError(theErr, PSTR("Preferences")); + return(theErr); + } + } + + theErr = FSpOpenDF(&theSpecs, fsRdWrPerm, &fileRefNum); + if (theErr != noErr) + { + CheckFileError(theErr, PSTR("Preferences")); + return(theErr); + } + + byteCount = sizeof(*thePrefs); + + theErr = FSRead(fileRefNum, &byteCount, thePrefs); + if (theErr != noErr) + { + if (theErr == eofErr) + theErr = FSClose(fileRefNum); + else + { + CheckFileError(theErr, PSTR("Preferences")); + theErr = FSClose(fileRefNum); + } + return(theErr); + } + + theErr = FSClose(fileRefNum); + if (theErr != noErr) + { + CheckFileError(theErr, PSTR("Preferences")); + return(theErr); + } + + return(theErr); +} + +//-------------------------------------------------------------- DeletePrefs + +Boolean DeletePrefs (long *dirID, short *volRef) +{ + FSSpec theSpecs; + Str255 fileName; + OSErr theErr; + + PasStringCopy(kPrefFileName, fileName); + + theErr = FSMakeFSSpec(*volRef, *dirID, fileName, &theSpecs); + if (theErr != noErr) + return(false); + else + theErr = FSpDelete(&theSpecs); + + if (theErr != noErr) + return(false); + + return(true); +} + +//-------------------------------------------------------------- LoadPrefs + +Boolean LoadPrefs (prefsInfo *thePrefs, short versionNeed) +{ + long prefDirID; + OSErr theErr; + short systemVolRef; + Boolean noProblems; + + noProblems = GetPrefsFPath(&prefDirID, &systemVolRef); + if (!noProblems) + return(false); + + theErr = ReadPrefs(&prefDirID, &systemVolRef, thePrefs); + if (theErr == eofErr) + { + BringUpDeletePrefsAlert(); + noProblems = DeletePrefs(&prefDirID, &systemVolRef); + return (false); + } + else if (theErr != noErr) + return (false); + + if (thePrefs->prefVersion != versionNeed) + { + BringUpDeletePrefsAlert(); + noProblems = DeletePrefs(&prefDirID, &systemVolRef); + return(false); + } + + return (true); +} + +//-------------------------------------------------------------- BringUpDeletePrefsAlert + +void BringUpDeletePrefsAlert (void) +{ + short whoCares; + + InitCursor(); +// CenterAlert(kNewPrefsAlertID); + whoCares = Alert(kNewPrefsAlertID, nil); +} + diff --git a/GpApp/RectUtils.cpp b/GpApp/RectUtils.cpp new file mode 100644 index 0000000..c001c2b --- /dev/null +++ b/GpApp/RectUtils.cpp @@ -0,0 +1,318 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// 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); +} + diff --git a/GpApp/RectUtils.h b/GpApp/RectUtils.h new file mode 100644 index 0000000..7184e01 --- /dev/null +++ b/GpApp/RectUtils.h @@ -0,0 +1,33 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// RectUtils.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#pragma once + + +#include "PLQuickdraw.h" + + +void FrameWHRect (short, short, short, short); +void NormalizeRect (Rect *); +void ZeroRectCorner (Rect *); +void CenterRectOnPoint (Rect *, Point); +short HalfRectWide (Rect *); +short HalfRectTall (Rect *); +short RectWide (Rect *); +short RectTall (Rect *); +void GlobalToLocalRect (Rect *); +void LocalToGlobalRect (Rect *); +void CenterRectInRect (Rect *, Rect *); +void HOffsetRect (Rect *, short); +void VOffsetRect (Rect *, short); +Boolean IsRectLeftOfRect (Rect *, Rect *); +void QOffsetRect (Rect *, short, short); +void QSetRect (Rect *, short, short, short, short); +Boolean ForceRectInRect (Rect *, Rect *); +void QUnionSimilarRect (Rect *, Rect *, Rect *); +void FrameRectSansCorners (Rect *); +void SetEraseRect (short, short, short, short); diff --git a/GpApp/Render.cpp b/GpApp/Render.cpp new file mode 100644 index 0000000..94a3b87 --- /dev/null +++ b/GpApp/Render.cpp @@ -0,0 +1,772 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// 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; +} + diff --git a/GpApp/Room.cpp b/GpApp/Room.cpp new file mode 100644 index 0000000..a72e742 --- /dev/null +++ b/GpApp/Room.cpp @@ -0,0 +1,1207 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Room.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLResources.h" +#include "PLToolUtils.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "House.h" +#include "MainWindow.h" +#include "RectUtils.h" + + +#define kDeleteRoomAlert 1005 +#define kYesDoDeleteRoom 1 + + +Boolean QueryDeleteRoom (void); +void SetToNearestNeighborRoom (short, short); + + +roomPtr thisRoom; +Rect backSrcRect; +GWorldPtr backSrcMap; +short numberRooms, thisRoomNumber, previousRoom; +short leftThresh, rightThresh, lastBackground; +Boolean autoRoomEdit, newRoomNow, noRoomAtAll; +Boolean leftOpen, rightOpen, topOpen, bottomOpen; +Boolean doBitchDialogs; + +extern short tempTiles[]; + + +//============================================================== Functions +//-------------------------------------------------------------- SetInitialTiles + +#ifndef COMPILEDEMO +void SetInitialTiles (short background, Boolean doRoom) +{ + short i; + + if (background >= kUserBackground) + { + for (i = 0; i < kNumTiles; i++) + { + if (doRoom) + thisRoom->tiles[i] = i; + else + tempTiles[i] = i; + } + } + else + { + switch (background) + { + case kSimpleRoom: + case kPaneledRoom: + case kBasement: + case kChildsRoom: + case kAsianRoom: + case kUnfinishedRoom: + case kSwingersRoom: + case kBathroom: + case kLibrary: + for (i = 0; i < kNumTiles; i++) + { + if (doRoom) + thisRoom->tiles[i] = 1; + else + tempTiles[i] = 1; + } + if (doRoom) + { + thisRoom->tiles[0] = 0; + thisRoom->tiles[kNumTiles - 1] = kNumTiles - 1; + } + else + { + tempTiles[0] = 0; + tempTiles[kNumTiles - 1] = kNumTiles - 1; + } + break; + + case kSkywalk: + for (i = 0; i < kNumTiles; i++) + { + if (doRoom) + thisRoom->tiles[i] = i; + else + tempTiles[i] = i; + } + break; + + case kField: + case kGarden: + case kDirt: + for (i = 0; i < kNumTiles; i++) + { + if (doRoom) + thisRoom->tiles[i] = 0; + else + tempTiles[i] = 0; + } + break; + + case kMeadow: + for (i = 0; i < kNumTiles; i++) + { + if (doRoom) + thisRoom->tiles[i] = 1; + else + tempTiles[i] = 1; + } + break; + + case kRoof: + for (i = 0; i < kNumTiles; i++) + { + if (doRoom) + thisRoom->tiles[i] = 3; + else + tempTiles[i] = 3; + } + break; + + case kSky: + for (i = 0; i < kNumTiles; i++) + { + if (doRoom) + thisRoom->tiles[i] = 2; + else + tempTiles[i] = 2; + } + break; + + case kStratosphere: + case kStars: + for (i = 0; i < kNumTiles; i++) + { + if (doRoom) + thisRoom->tiles[i] = i; + else + tempTiles[i] = i; + } + break; + + default: + break; + } + } +} +#endif + +//-------------------------------------------------------------- CreateNewRoom + +#ifndef COMPILEDEMO +Boolean CreateNewRoom (short h, short v) +{ + KeyMap theKeys; + long howMuch; + OSErr theErr; + short i, availableRoom; + char wasState; + + CopyThisRoomToRoom(); // save off current room + + PasStringCopy(PSTR("Untitled Room"), thisRoom->name); + thisRoom->leftStart = 32; // fill out fields of new room + thisRoom->rightStart = 32; + thisRoom->bounds = 0; + thisRoom->unusedByte = 0; + thisRoom->visited = false; + thisRoom->background = lastBackground; + SetInitialTiles(thisRoom->background, true); + thisRoom->floor = v; + thisRoom->suite = h; + thisRoom->openings = 0; + thisRoom->numObjects = 0; + for (i = 0; i < kMaxRoomObs; i++) // zero out all objects + thisRoom->objects[i].what = kObjectIsEmpty; + + wasState = HGetState((Handle)thisHouse); + MoveHHi((Handle)thisHouse); + HLock((Handle)thisHouse); + availableRoom = -1; // assume no available rooms + if ((*thisHouse)->nRooms > 0) // look for an empty room + for (i = 0; i < (*thisHouse)->nRooms; i++) + if ((*thisHouse)->rooms[i].suite == kRoomIsEmpty) + { + availableRoom = i; + break; + } + + if (availableRoom == -1) // found no available rooms + { + HUnlock((Handle)thisHouse); + howMuch = sizeof(roomType); // add new room to end of house + theErr = PtrAndHand((Ptr)thisRoom, (Handle)thisHouse, howMuch); + if (theErr != noErr) + { + YellowAlert(kYellowUnaccounted, theErr); + MoveHHi((Handle)thisHouse); + HLock((Handle)thisHouse); + return (false); + } + MoveHHi((Handle)thisHouse); + HLock((Handle)thisHouse); + (*thisHouse)->nRooms++; // increment nRooms + numberRooms = (*thisHouse)->nRooms; + previousRoom = thisRoomNumber; + thisRoomNumber = numberRooms - 1; + } + else + { + previousRoom = thisRoomNumber; + thisRoomNumber = availableRoom; + } + + if (noRoomAtAll) + (*thisHouse)->firstRoom = thisRoomNumber; + + HSetState((Handle)thisHouse, wasState); + + CopyThisRoomToRoom(); + UpdateEditWindowTitle(); + noRoomAtAll = false; + fileDirty = true; + UpdateMenus(false); + + GetKeys(theKeys); + if (BitTst(&theKeys, kShiftKeyMap)) + newRoomNow = false; + else + newRoomNow = autoRoomEdit; // Flag to bring up RoomInfo + + return (true); +} +#endif + +//-------------------------------------------------------------- ReadyBackground + +void ReadyBackground (short theID, short *theTiles) +{ + Rect src, dest; + PicHandle thePicture; + short i; + + SetPort((GrafPtr)workSrcMap); + + if ((noRoomAtAll) || (!houseUnlocked)) + { + LtGrayForeColor(); + PaintRect(&workSrcRect); + ForeColor(blackColor); + MoveTo(10, 20); + if (houseUnlocked) + DrawString(PSTR("No rooms")); + else + DrawString(PSTR("Nothing to show")); + + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &workSrcRect, &workSrcRect, srcCopy, nil); + return; + } + + thePicture = GetPicture(theID); + if (thePicture == nil) + { + thePicture = (PicHandle)GetResource('Date', theID); + if (thePicture == nil) + { + YellowAlert(kYellowNoBackground, 0); + return; + } + } + + HLock((Handle)thePicture); + dest = (*thePicture)->picFrame; + HUnlock((Handle)thePicture); + QOffsetRect(&dest, -dest.left, -dest.top); + DrawPicture(thePicture, &dest); + ReleaseResource((Handle)thePicture); + + QSetRect(&src, 0, 0, kTileWide, kTileHigh); + QSetRect(&dest, 0, 0, kTileWide, kTileHigh); + for (i = 0; i < kNumTiles; i++) + { + src.left = theTiles[i] * kTileWide; + src.right = src.left + kTileWide; + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &src, &dest, srcCopy, nil); + QOffsetRect(&dest, kTileWide, 0); + } + + QSetRect(&src, 0, 0, kRoomWide, kTileHigh); + QSetRect(&dest, 0, 0, kRoomWide, kTileHigh); + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &src, &dest, srcCopy, nil); +} + +//-------------------------------------------------------------- ReflectCurrentRoom + +void ReflectCurrentRoom (Boolean forceMapRedraw) +{ +#ifndef COMPILEDEMO + if (theMode != kEditMode) + return; + + if ((noRoomAtAll) || (!houseUnlocked)) + { + CenterMapOnRoom(64, 1); + UpdateMapWindow(); + } + else + { + if ((!ThisRoomVisibleOnMap()) || (forceMapRedraw)) + { + CenterMapOnRoom(thisRoom->suite, thisRoom->floor); + UpdateMapWindow(); // whole map window redrawm + } + else + { + FindNewActiveRoomRect(); // find newly selected room rect + FlagMapRoomsForUpdate(); // redraw only the portions required + } + } + GenerateRetroLinks(); + UpdateEditWindowTitle(); + ReadyBackground(thisRoom->background, thisRoom->tiles); + GetThisRoomsObjRects(); + DrawThisRoomsObjects(); + InvalWindowRect(mainWindow, &mainWindowRect); +#endif +} + +//-------------------------------------------------------------- CopyRoomToThisRoom + +void CopyRoomToThisRoom (short roomNumber) +{ + if (roomNumber == -1) + return; + + CopyThisRoomToRoom(); // copy back to house + ForceThisRoom(roomNumber); // load new room from house +} + +//-------------------------------------------------------------- CopyThisRoomToRoom + +void CopyThisRoomToRoom (void) +{ + char tagByte; + + if ((noRoomAtAll) || (thisRoomNumber == -1)) + return; + + tagByte = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); // copy back to house + (*thisHouse)->rooms[thisRoomNumber] = *thisRoom; + HSetState((Handle)thisHouse, tagByte); +} + +//-------------------------------------------------------------- ForceThisRoom + +void ForceThisRoom (short roomNumber) +{ + char tagByte; + + if (roomNumber == -1) + return; + + tagByte = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + if (roomNumber < (*thisHouse)->nRooms) + *thisRoom = (*thisHouse)->rooms[roomNumber]; + else + YellowAlert(kYellowIllegalRoomNum, 0); + HSetState((Handle)thisHouse, tagByte); + + previousRoom = thisRoomNumber; + thisRoomNumber = roomNumber; +} + +//-------------------------------------------------------------- RoomExists + +Boolean RoomExists (short suite, short floor, short *roomNum) +{ + // pass in a suite and floor; returns true is it is a legitimate room + houseType *thisHousePtr; + short i; + char wasState; + Boolean foundIt; + + foundIt = false; + + if (suite < 0) + return (foundIt); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + for (i = 0; i < numberRooms; i++) + { + if ((thisHousePtr->rooms[i].floor == floor) && + (thisHousePtr->rooms[i].suite == suite)) + { + foundIt = true; + *roomNum = i; + break; + } + } + + HSetState((Handle)thisHouse, wasState); + + return (foundIt); +} + +//-------------------------------------------------------------- RoomNumExists + +Boolean RoomNumExists (short roomNum) +{ + short floor, suite, whoCares; + Boolean exists; + + exists = false; + if (GetRoomFloorSuite(roomNum, &floor, &suite)) + exists = RoomExists(suite, floor, &whoCares); + + return (exists); +} + +//-------------------------------------------------------------- DeleteRoom + +void DeleteRoom (Boolean doWarn) +{ +#ifndef COMPILEDEMO + short wasFloor, wasSuite; + char wasState; + Boolean firstDeleted; + + if ((theMode != kEditMode) || (noRoomAtAll)) + return; + + if (doWarn) + { + if (!QueryDeleteRoom()) + return; + } + + DeselectObject(); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + wasFloor = (*thisHouse)->rooms[thisRoomNumber].floor; + wasSuite = (*thisHouse)->rooms[thisRoomNumber].suite; + firstDeleted = ((*thisHouse)->firstRoom == thisRoomNumber); // is room "first" + thisRoom->suite = kRoomIsEmpty; + (*thisHouse)->rooms[thisRoomNumber].suite = kRoomIsEmpty; + HSetState((Handle)thisHouse, wasState); + + noRoomAtAll = (RealRoomNumberCount() == 0); // see if now no rooms + if (noRoomAtAll) + thisRoomNumber = kRoomIsEmpty; + else + SetToNearestNeighborRoom(wasFloor, wasSuite); + + if (firstDeleted) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + (*thisHouse)->firstRoom = thisRoomNumber; + HSetState((Handle)thisHouse, wasState); + } + + newRoomNow = false; + fileDirty = true; + UpdateMenus(false); + ReflectCurrentRoom(false); +#endif +} + +//-------------------------------------------------------------- QueryDeleteRoom + +#ifndef COMPILEDEMO +Boolean QueryDeleteRoom (void) +{ + short hitWhat; + +// CenterAlert(kDeleteRoomAlert); + hitWhat = Alert(kDeleteRoomAlert, nil); + if (hitWhat == kYesDoDeleteRoom) + return (true); + else + return (false); +} +#endif + +//-------------------------------------------------------------- DoesNeighborRoomExist + +short DoesNeighborRoomExist (short whichNeighbor) +{ +#ifndef COMPILEDEMO + short newH, newV, newRoomNumber; + + if (theMode != kEditMode) + return(-1); + + newH = thisRoom->suite; + newV = thisRoom->floor; + + switch (whichNeighbor) + { + case kRoomAbove: + newV++; + break; + + case kRoomBelow: + newV--; + break; + + case kRoomToRight: + newH++; + break; + + case kRoomToLeft: + newH--; + break; + } + + if (RoomExists(newH, newV, &newRoomNumber)) + return (newRoomNumber); + else + return (-1); +#endif +} + +//-------------------------------------------------------------- SelectNeighborRoom + +void SelectNeighborRoom (short whichNeighbor) +{ +#ifndef COMPILEDEMO + short newRoomNumber; + + newRoomNumber = DoesNeighborRoomExist(whichNeighbor); + + if (newRoomNumber != -1) + { + DeselectObject(); + CopyRoomToThisRoom(newRoomNumber); + ReflectCurrentRoom(false); + } +#endif +} + +//-------------------------------------------------------------- GetNeighborRoomNumber + +short GetNeighborRoomNumber (short which) +{ + short hDelta, vDelta, i; + short roomH, roomV; + short roomNum; + char wasState; + + switch (which) + { + case kCentralRoom: + hDelta = 0; + vDelta = 0; + break; + + case kNorthRoom: + hDelta = 0; + vDelta = 1; + break; + + case kNorthEastRoom: + hDelta = 1; + vDelta = 1; + break; + + case kEastRoom: + hDelta = 1; + vDelta = 0; + break; + + case kSouthEastRoom: + hDelta = 1; + vDelta = -1; + break; + + case kSouthRoom: + hDelta = 0; + vDelta = -1; + break; + + case kSouthWestRoom: + hDelta = -1; + vDelta = -1; + break; + + case kWestRoom: + hDelta = -1; + vDelta = 0; + break; + + case kNorthWestRoom: + hDelta = -1; + vDelta = 1; + break; + } + + roomNum = kRoomIsEmpty; + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + roomH = (*thisHouse)->rooms[thisRoomNumber].suite + hDelta; + roomV = (*thisHouse)->rooms[thisRoomNumber].floor + vDelta; + + for (i = 0; i < numberRooms; i++) + { + if (((*thisHouse)->rooms[i].suite == roomH) && + ((*thisHouse)->rooms[i].floor == roomV)) + { + roomNum = i; + break; + } + } + HSetState((Handle)thisHouse, wasState); + + return (roomNum); +} + +//-------------------------------------------------------------- SetToNearestNeighborRoom + +void SetToNearestNeighborRoom (short wasFloor, short wasSuite) +{ + // searches in a clockwise spiral pattern (from thisRoom) for aÉ + // legitimate neighboring room - then sets thisRoom to it + short distance, h, v; + short hStep, vStep; + short testRoomNum, testH, testV; + char wasState; + Boolean finished; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + + finished = false; + distance = 1; // we begin our walk a distance of one from source room + h = -1; // we begin with the neighbor to the leftÉ + v = 0; // and on the same floor + hStep = 0; // we don't 'walk' left or rightÉ + vStep = -1; // instead, we 'walk' up + + do + { + testH = wasSuite + h; + testV = wasFloor + v; + + if (RoomExists(testH, testV, &testRoomNum)) // if a legitimate room + { + CopyRoomToThisRoom(testRoomNum); + finished = true; + } + else + { + h += hStep; + v += vStep; + if ((h > distance) || (h < -distance) || (v > distance) || (v < -distance)) + { // we have walked beyond the bounds of our spiral + if ((hStep == -1) && (vStep == 0)) // we expand our spiral out + { + distance++; + hStep = 0; // begin travelling up again + vStep = -1; + } + else + { + h -= hStep; // first, back up a step + v -= vStep; + + if (hStep == 0) // we were travelling up or down + { + if (vStep == -1) // we were travelling upÉ + hStep = 1; // so begin travelling right + else // we were travelling downÉ + hStep = -1; // so begin travelling left + vStep = 0; + } + else + { + hStep = 0; // begin travelling down + vStep = 1; + } + h += hStep; // proceed a step now + v += vStep; + } + } + } + } while (!finished); + + HSetState((Handle)thisHouse, wasState); +} + +//-------------------------------------------------------------- GetRoomFloorSuite + +Boolean GetRoomFloorSuite (short room, short *floor, short *suite) +{ + char wasState; + Boolean isRoom; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + if ((*thisHouse)->rooms[room].suite == kRoomIsEmpty) + { + *floor = 0; + *suite = kRoomIsEmpty; + isRoom = false; + } + else + { + *suite = (*thisHouse)->rooms[room].suite; + *floor = (*thisHouse)->rooms[room].floor; + isRoom = true; + } + HSetState((Handle)thisHouse, wasState); + + return (isRoom); +} + +//-------------------------------------------------------------- GetRoomNumber + +short GetRoomNumber (short floor, short suite) +{ + // pass in a floor and suite; returns the room index into the house file + short roomNum, i; + char wasState; + + roomNum = kRoomIsEmpty; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + for (i = 0; i < numberRooms; i++) + { + if (((*thisHouse)->rooms[i].suite == suite) && + ((*thisHouse)->rooms[i].floor == floor)) + { + roomNum = i; + break; + } + } + HSetState((Handle)thisHouse, wasState); + + return (roomNum); +} + +//-------------------------------------------------------------- IsRoomAStructure + +Boolean IsRoomAStructure (short roomNum) +{ + char wasState; + Boolean isStructure; + + if (roomNum == kRoomIsEmpty) + return (false); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + if ((*thisHouse)->rooms[roomNum].background >= kUserBackground) + { + if ((*thisHouse)->rooms[roomNum].bounds != 0) + { + isStructure = (((*thisHouse)->rooms[roomNum].bounds & 32) == 32); + } + else + { + if ((*thisHouse)->rooms[roomNum].background < kUserStructureRange) + isStructure = true; + else + isStructure = false; + } + } + else + { + switch ((*thisHouse)->rooms[roomNum].background) + { + case kPaneledRoom: + case kSimpleRoom: + case kChildsRoom: + case kAsianRoom: + case kUnfinishedRoom: + case kSwingersRoom: + case kBathroom: + case kLibrary: + case kSkywalk: + case kRoof: + isStructure = true; + break; + + default: + isStructure = false; + break; + } + } + HSetState((Handle)thisHouse, wasState); + + return (isStructure); +} + +//-------------------------------------------------------------- DetermineRoomOpenings + +void DetermineRoomOpenings (void) +{ + short whichBack, leftTile, rightTile; + short boundsCode; + + whichBack = thisRoom->background; + leftTile = thisRoom->tiles[0]; + rightTile = thisRoom->tiles[kNumTiles - 1]; + + if (whichBack >= kUserBackground) + { + if (thisRoom->bounds != 0) + boundsCode = thisRoom->bounds >> 1; + else + boundsCode = GetOriginalBounding(whichBack); + leftOpen = ((boundsCode & 0x0001) == 0x0001); + rightOpen = ((boundsCode & 0x0004) == 0x0004); + + if (leftOpen) + leftThresh = kNoLeftWallLimit; + else + leftThresh = kLeftWallLimit; + + if (rightOpen) + rightThresh = kNoRightWallLimit; + else + rightThresh = kRightWallLimit; + } + else + { + switch (whichBack) + { + case kSimpleRoom: + case kPaneledRoom: + case kBasement: + case kChildsRoom: + case kAsianRoom: + case kUnfinishedRoom: + case kSwingersRoom: + case kBathroom: + case kLibrary: + case kSky: + if (leftTile == 0) + leftThresh = kLeftWallLimit; + else + leftThresh = kNoLeftWallLimit; + if (rightTile == (kNumTiles - 1)) + rightThresh = kRightWallLimit; + else + rightThresh = kNoRightWallLimit; + leftOpen = (leftTile != 0); + rightOpen = (rightTile != (kNumTiles - 1)); + break; + + case kDirt: + if (leftTile == 1) + leftThresh = kLeftWallLimit; + else + leftThresh = kNoLeftWallLimit; + if (rightTile == (kNumTiles - 1)) + rightThresh = kRightWallLimit; + else + rightThresh = kNoRightWallLimit; + leftOpen = (leftTile != 0); + rightOpen = (rightTile != (kNumTiles - 1)); + break; + + case kMeadow: + if (leftTile == 6) + leftThresh = kLeftWallLimit; + else + leftThresh = kNoLeftWallLimit; + if (rightTile == 7) + rightThresh = kRightWallLimit; + else + rightThresh = kNoRightWallLimit; + leftOpen = (leftTile != 6); + rightOpen = (rightTile != 7); + break; + + case kGarden: + case kSkywalk: + case kField: + case kStratosphere: + case kStars: + leftThresh = kNoLeftWallLimit; + rightThresh = kNoRightWallLimit; + leftOpen = true; + rightOpen = true; + break; + + default: + if (leftTile == 0) + leftThresh = kLeftWallLimit; + else + leftThresh = kNoLeftWallLimit; + + if (rightTile == (kNumTiles - 1)) + rightThresh = kRightWallLimit; + else + rightThresh = kNoRightWallLimit; + + leftOpen = (leftTile != 0); + rightOpen = (rightTile != (kNumTiles - 1)); + break; + } + } + + if (DoesRoomHaveFloor()) + bottomOpen = false; + else + bottomOpen = true; + + if (DoesRoomHaveCeiling()) + topOpen = false; + else + topOpen = true; +} + +//-------------------------------------------------------------- GetOriginalBounding + +short GetOriginalBounding (short theID) +{ + boundsHand boundsRes; + short boundCode; + + boundsRes = (boundsHand)GetResource('bnds', theID); + if (boundsRes == nil) + { + if (PictIDExists(theID)) + YellowAlert(kYellowNoBoundsRes, 0); + boundCode = 0; + } + else + { + boundCode = 0; + HLock((Handle)boundsRes); + if ((*boundsRes)->left) + boundCode += 1; + if ((*boundsRes)->top) + boundCode += 2; + if ((*boundsRes)->right) + boundCode += 4; + if ((*boundsRes)->bottom) + boundCode += 8; + HUnlock((Handle)boundsRes); + ReleaseResource((Handle)boundsRes); + } + + return (boundCode); +} + +//-------------------------------------------------------------- GetNumberOfLights + +short GetNumberOfLights (short where) +{ + houseType *thisHousePtr; + short i, count; + char wasState; + + if (theMode == kEditMode) + { + switch (thisRoom->background) + { + case kGarden: + case kSkywalk: + case kMeadow: + case kField: + case kRoof: + case kSky: + case kStratosphere: + case kStars: + count = 1; + break; + + case kDirt: + count = 0; + if ((thisRoom->tiles[0] == 0) && (thisRoom->tiles[1] == 0) && + (thisRoom->tiles[2] == 0) && (thisRoom->tiles[3] == 0) && + (thisRoom->tiles[4] == 0) && (thisRoom->tiles[5] == 0) && + (thisRoom->tiles[6] == 0) && (thisRoom->tiles[7] == 0)) + count = 1; + break; + + default: + count = 0; + break; + } + if (count == 0) + { + for (i = 0; i < kMaxRoomObs; i++) + { + switch (thisRoom->objects[i].what) + { + case kDoorInLf: + case kDoorInRt: + case kWindowInLf: + case kWindowInRt: + case kWallWindow: + count++; + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + if (thisRoom->objects[i].data.f.initial) + count++; + break; + } + } + } + } + else + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + switch (thisHousePtr->rooms[where].background) + { + case kGarden: + case kSkywalk: + case kMeadow: + case kField: + case kRoof: + case kSky: + case kStratosphere: + case kStars: + count = 1; + break; + + case kDirt: + count = 0; + if ((thisHousePtr->rooms[where].tiles[0] == 0) && + (thisHousePtr->rooms[where].tiles[1] == 0) && + (thisHousePtr->rooms[where].tiles[2] == 0) && + (thisHousePtr->rooms[where].tiles[3] == 0) && + (thisHousePtr->rooms[where].tiles[4] == 0) && + (thisHousePtr->rooms[where].tiles[5] == 0) && + (thisHousePtr->rooms[where].tiles[6] == 0) && + (thisHousePtr->rooms[where].tiles[7] == 0)) + count = 1; + break; + + default: + count = 0; + break; + } + if (count == 0) + { + for (i = 0; i < kMaxRoomObs; i++) + { + switch (thisHousePtr->rooms[where].objects[i].what) + { + case kDoorInLf: + case kDoorInRt: + case kWindowInLf: + case kWindowInRt: + case kWallWindow: + count++; + break; + + case kCeilingLight: + case kLightBulb: + case kTableLamp: + case kHipLamp: + case kDecoLamp: + case kFlourescent: + case kTrackLight: + case kInvisLight: + if (thisHousePtr->rooms[where].objects[i].data.f.state) + count++; + break; + } + } + } + HSetState((Handle)thisHouse, wasState); + } + return (count); +} + +//-------------------------------------------------------------- IsShadowVisible + +Boolean IsShadowVisible (void) +{ + short boundsCode; + Boolean hasFloor; + + if (thisRoom->background >= kUserBackground) + { + if (thisRoom->bounds != 0) // is this a version 2.0 house? + boundsCode = (thisRoom->bounds >> 1); + else + boundsCode = GetOriginalBounding(thisRoom->background); + hasFloor = ((boundsCode & 0x0008) != 0x0008); + } + else + { + switch (thisRoom->background) + { + case kRoof: + case kSky: + case kStratosphere: + case kStars: + hasFloor = false; + break; + + default: + hasFloor = true; + break; + } + } + + return (hasFloor); +} + +//-------------------------------------------------------------- DoesRoomHaveFloor + +Boolean DoesRoomHaveFloor (void) +{ + short boundsCode; + Boolean hasFloor; + + if (thisRoom->background >= kUserBackground) + { + if (thisRoom->bounds != 0) // is this a version 2.0 house? + boundsCode = (thisRoom->bounds >> 1); + else + boundsCode = GetOriginalBounding(thisRoom->background); + hasFloor = ((boundsCode & 0x0008) != 0x0008); + } + else + { + switch (thisRoom->background) + { + case kSky: + case kStratosphere: + case kStars: + hasFloor = false; + break; + + default: + hasFloor = true; + break; + } + } + + return (hasFloor); +} + +//-------------------------------------------------------------- DoesRoomHaveCeiling + +Boolean DoesRoomHaveCeiling (void) +{ + short boundsCode; + Boolean hasCeiling; + + if (thisRoom->background >= kUserBackground) + { + if (thisRoom->bounds != 0) // is this a version 2.0 house? + boundsCode = (thisRoom->bounds >> 1); + else + boundsCode = GetOriginalBounding(thisRoom->background); + hasCeiling = ((boundsCode & 0x0002) != 0x0002); + } + else + { + switch (thisRoom->background) + { + case kGarden: + case kMeadow: + case kField: + case kRoof: + case kSky: + case kStratosphere: + case kStars: + hasCeiling = false; + break; + + default: + hasCeiling = true; + break; + } + } + return (hasCeiling); +} + diff --git a/GpApp/Room.h b/GpApp/Room.h new file mode 100644 index 0000000..740fcc5 --- /dev/null +++ b/GpApp/Room.h @@ -0,0 +1,12 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Room.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +extern GWorldPtr backSrcMap; + diff --git a/GpApp/RoomGraphics.cpp b/GpApp/RoomGraphics.cpp new file mode 100644 index 0000000..724865d --- /dev/null +++ b/GpApp/RoomGraphics.cpp @@ -0,0 +1,461 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// RoomGraphics.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLResources.h" +#include "Externs.h" +#include "Environ.h" +#include "MainWindow.h" +#include "RectUtils.h" +#include "Room.h" + + +#define kManholeThruFloor 3957 + + +void LoadGraphicSpecial (short); +void DrawRoomBackground (short, short, short); +void DrawFloorSupport (void); +void ReadyBackMap (void); +void RestoreWorkMap (void); +void DrawLighting (void); + + +Rect suppSrcRect; +GWorldPtr suppSrcMap; +Rect localRoomsDest[9]; +Rect houseRect; +short numNeighbors, numLights, thisTiles[kNumTiles]; +short localNumbers[9], thisBackground; +Boolean isStructure[9], wardBitSet; + +extern Rect tempManholes[]; +extern short numTempManholes, tvWithMovieNumber; +extern Boolean shadowVisible, takingTheStairs; + + +//============================================================== Functions +//-------------------------------------------------------------- DrawLocale + +void DrawLocale (void) +{ + short i, roomV; + char wasState; + CGrafPtr wasCPort; + GDHandle wasWorld; + + ZeroFlamesAndTheLike(); + ZeroDinahs(); + KillAllBands(); + ZeroMirrorRegion(); + ZeroTriggers(); + numTempManholes = 0; + FlushAnyTriggerPlaying(); + DumpTriggerSound(); + tvInRoom = false; + tvWithMovieNumber = -1; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + roomV = (*thisHouse)->rooms[thisRoomNumber].floor; + HSetState((Handle)thisHouse, wasState); + + for (i = 0; i < 9; i++) + { + localNumbers[i] = GetNeighborRoomNumber(i); + isStructure[i] = IsRoomAStructure(localNumbers[i]); + } + ListAllLocalObjects(); + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + PaintRect(&backSrcRect); + + if (numNeighbors > 3) + { + numLights = GetNumberOfLights(localNumbers[kNorthWestRoom]); + DrawRoomBackground(localNumbers[kNorthWestRoom], kNorthWestRoom, roomV + 1); + DrawARoomsObjects(kNorthWestRoom, false); + + numLights = GetNumberOfLights(localNumbers[kNorthEastRoom]); + DrawRoomBackground(localNumbers[kNorthEastRoom], kNorthEastRoom, roomV + 1); + DrawARoomsObjects(kNorthEastRoom, false); + + numLights = GetNumberOfLights(localNumbers[kNorthRoom]); + DrawRoomBackground(localNumbers[kNorthRoom], kNorthRoom, roomV + 1); + DrawARoomsObjects(kNorthRoom, false); + + numLights = GetNumberOfLights(localNumbers[kSouthWestRoom]); + DrawRoomBackground(localNumbers[kSouthWestRoom], kSouthWestRoom, roomV - 1); + DrawARoomsObjects(kSouthWestRoom, false); + + numLights = GetNumberOfLights(localNumbers[kSouthEastRoom]); + DrawRoomBackground(localNumbers[kSouthEastRoom], kSouthEastRoom, roomV - 1); + DrawARoomsObjects(kSouthEastRoom, false); + + numLights = GetNumberOfLights(localNumbers[kSouthRoom]); + DrawRoomBackground(localNumbers[kSouthRoom], kSouthRoom, roomV - 1); + DrawARoomsObjects(kSouthRoom, false); + } + + if (numNeighbors > 1) + { + numLights = GetNumberOfLights(localNumbers[kWestRoom]); + DrawRoomBackground(localNumbers[kWestRoom], kWestRoom, roomV); + DrawARoomsObjects(kWestRoom, false); + DrawLighting(); + + numLights = GetNumberOfLights(localNumbers[kEastRoom]); + DrawRoomBackground(localNumbers[kEastRoom], kEastRoom, roomV); + DrawARoomsObjects(kEastRoom, false); + DrawLighting(); + } + + numLights = GetNumberOfLights(localNumbers[kCentralRoom]); + DrawRoomBackground(localNumbers[kCentralRoom], kCentralRoom, roomV); + DrawARoomsObjects(kCentralRoom, false); + DrawLighting(); + + if (numNeighbors > 3) + DrawFloorSupport(); + RestoreWorkMap(); + shadowVisible = IsShadowVisible(); + takingTheStairs = false; + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- LoadGraphicSpecial + +void LoadGraphicSpecial (short resID) +{ + Rect bounds; + PicHandle thePicture; + + thePicture = GetPicture(resID); + if (thePicture == nil) + { + thePicture = (PicHandle)GetResource('Date', resID); + if (thePicture == nil) + { + thePicture = GetPicture(2000); + if (thePicture == nil) + RedAlert(kErrFailedGraphicLoad); + } + } + + HLock((Handle)thePicture); + bounds = (*thePicture)->picFrame; + HUnlock((Handle)thePicture); + OffsetRect(&bounds, -bounds.left, -bounds.top); + DrawPicture(thePicture, &bounds); + + ReleaseResource((Handle)thePicture); +} + +//-------------------------------------------------------------- DrawRoomBackground + +void DrawRoomBackground (short who, short where, short elevation) +{ + Rect src, dest; + short i, pictID; + short tiles[kNumTiles]; + char wasState; + + if (where == kCentralRoom) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisBackground = (*thisHouse)->rooms[who].background; + for (i = 0; i < kNumTiles; i++) + thisTiles[i] = (*thisHouse)->rooms[who].tiles[i]; + HSetState((Handle)thisHouse, wasState); + } + + if ((numLights == 0) && (who != kRoomIsEmpty)) + { + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + PaintRect(&localRoomsDest[where]); + + SetGWorld(wasCPort, wasWorld); + return; + } + + if (who == kRoomIsEmpty) // This call should be smarter than this + { + if (wardBitSet) + { + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + + PaintRect(&localRoomsDest[where]); + + SetGWorld(wasCPort, wasWorld); + return; + } + + if (elevation > 1) + { + pictID = kSky; + for (i = 0; i < kNumTiles; i++) + tiles[i] = 2; + } + else if (elevation == 1) + { + pictID = kMeadow; + for (i = 0; i < kNumTiles; i++) + tiles[i] = 0; + } + else + { + pictID = kDirt; + for (i = 0; i < kNumTiles; i++) + tiles[i] = 0; + } + } + else + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + pictID = (*thisHouse)->rooms[who].background; + for (i = 0; i < kNumTiles; i++) + tiles[i] = (*thisHouse)->rooms[who].tiles[i]; + HSetState((Handle)thisHouse, wasState); + } + + SetPort((GrafPtr)workSrcMap); + LoadGraphicSpecial(pictID); + + QSetRect(&src, 0, 0, kTileWide, kTileHigh); + QSetRect(&dest, 0, 0, kTileWide, kTileHigh); + QOffsetRect(&dest, localRoomsDest[where].left, localRoomsDest[where].top); + for (i = 0; i < kNumTiles; i++) + { + src.left = tiles[i] * kTileWide; + src.right = src.left + kTileWide; + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &src, &dest, srcCopy, nil); + QOffsetRect(&dest, kTileWide, 0); + } +} + +//-------------------------------------------------------------- DrawFloorSupport + +void DrawFloorSupport (void) +{ + Rect src, dest, whoCares; + short i; + CGrafPtr wasCPort; + GDHandle wasWorld; + + GetGWorld(&wasCPort, &wasWorld); + SetGWorld(backSrcMap, nil); + src = suppSrcRect; + + if (isStructure[kNorthWestRoom]) + { + dest = suppSrcRect; // left room's ceiling + QOffsetRect(&dest, localRoomsDest[kWestRoom].left, + localRoomsDest[kCentralRoom].top - suppSrcRect.bottom); + CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &src, &dest, srcCopy, nil); + + for (i = 0; i < numTempManholes; i++) + if (SectRect(&dest, &tempManholes[i], &whoCares)) + { + tempManholes[i].top = dest.top; + tempManholes[i].bottom = dest.bottom; + LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); + } + } + + if (isStructure[kWestRoom]) + { + dest = suppSrcRect; // left room's floor + QOffsetRect(&dest, localRoomsDest[kWestRoom].left, + localRoomsDest[kCentralRoom].bottom); + CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &src, &dest, srcCopy, nil); + + for (i = 0; i < numTempManholes; i++) + if (SectRect(&dest, &tempManholes[i], &whoCares)) + { + tempManholes[i].top = dest.top; + tempManholes[i].bottom = dest.bottom; + LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); + } + } + + if (isStructure[kNorthRoom]) + { + dest = suppSrcRect; // directly above main room + QOffsetRect(&dest, localRoomsDest[kCentralRoom].left, + localRoomsDest[kCentralRoom].top - suppSrcRect.bottom); + CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &src, &dest, srcCopy, nil); + for (i = 0; i < numTempManholes; i++) + if (SectRect(&dest, &tempManholes[i], &whoCares)) + { + tempManholes[i].top = dest.top; + tempManholes[i].bottom = dest.bottom; + LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); + } + } + + if (isStructure[kCentralRoom]) + { + dest = suppSrcRect; // directly below main room + QOffsetRect(&dest, localRoomsDest[kCentralRoom].left, + localRoomsDest[kCentralRoom].bottom); + CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &src, &dest, srcCopy, nil); + + for (i = 0; i < numTempManholes; i++) + if (SectRect(&dest, &tempManholes[i], &whoCares)) + { + tempManholes[i].top = dest.top; + tempManholes[i].bottom = dest.bottom; + LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); + } + } + + if (isStructure[kNorthEastRoom]) + { + dest = suppSrcRect; + QOffsetRect(&dest, localRoomsDest[kEastRoom].left, + localRoomsDest[kCentralRoom].top - suppSrcRect.bottom); + CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &src, &dest, srcCopy, nil); + + for (i = 0; i < numTempManholes; i++) + if (SectRect(&dest, &tempManholes[i], &whoCares)) + { + tempManholes[i].top = dest.top; + tempManholes[i].bottom = dest.bottom; + LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); + } + } + + if (isStructure[kEastRoom]) + { + dest = suppSrcRect; + QOffsetRect(&dest, localRoomsDest[kEastRoom].left, + localRoomsDest[kCentralRoom].bottom); + CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &src, &dest, srcCopy, nil); + + for (i = 0; i < numTempManholes; i++) + if (SectRect(&dest, &tempManholes[i], &whoCares)) + { + tempManholes[i].top = dest.top; + tempManholes[i].bottom = dest.bottom; + LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); + } + } + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- ReadyBackMap + +void ReadyBackMap (void) +{ + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + (BitMap *)*GetGWorldPixMap(backSrcMap), + &workSrcRect, &workSrcRect, srcCopy, nil); +} + +//-------------------------------------------------------------- RestoreWorkMap + +void RestoreWorkMap (void) +{ + Rect dest; + + dest = backSrcRect; + + CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), + (BitMap *)*GetGWorldPixMap(workSrcMap), + &backSrcRect, &backSrcRect, srcCopy, nil); +} + +//-------------------------------------------------------------- ReadyLevel + +void ReadyLevel (void) +{ + NilSavedMaps(); + +#ifdef COMPILEQT + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom)) + { + tvInRoom = false; + tvWithMovieNumber = -1; + StopMovie(theMovie); + } +#endif + + DetermineRoomOpenings(); + DrawLocale(); + InitGarbageRects(); +} + +//-------------------------------------------------------------- DrawLighting + +void DrawLighting (void) +{ + if (numLights == 0) + return; + else + { + // for future construction + } +} + +//-------------------------------------------------------------- RedrawRoomLighting + +void RedrawRoomLighting (void) +{ + short roomV; + char wasState; + Boolean wasLit, isLit; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + roomV = (*thisHouse)->rooms[thisRoomNumber].floor; + HSetState((Handle)thisHouse, wasState); + + wasLit = numLights > 0; + numLights = GetNumberOfLights(localNumbers[kCentralRoom]); + isLit = numLights > 0; + if (wasLit != isLit) + { + DrawRoomBackground(localNumbers[kCentralRoom], kCentralRoom, roomV); + DrawARoomsObjects(kCentralRoom, true); + DrawLighting(); + UpdateOutletsLighting(localNumbers[kCentralRoom], numLights); + + if (numNeighbors > 3) + DrawFloorSupport(); + RestoreWorkMap(); + AddRectToWorkRects(&localRoomsDest[kCentralRoom]); + shadowVisible = IsShadowVisible(); + } +} + diff --git a/GpApp/RoomGraphics.h b/GpApp/RoomGraphics.h new file mode 100644 index 0000000..bda7b47 --- /dev/null +++ b/GpApp/RoomGraphics.h @@ -0,0 +1,11 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// RoomGraphics.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +extern GWorldPtr suppSrcMap; diff --git a/GpApp/RoomInfo.cpp b/GpApp/RoomInfo.cpp new file mode 100644 index 0000000..36cbb39 --- /dev/null +++ b/GpApp/RoomInfo.cpp @@ -0,0 +1,908 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// RoomInfo.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLNumberFormatting.h" +#include "PLResources.h" +#include "PLSound.h" +#include "PLPasStr.h" +#include "DialogUtils.h" +#include "Externs.h" +#include "RectUtils.h" +#include "Utilities.h" + + +#define kRoomInfoDialogID 1003 +#define kOriginalArtDialogID 1016 +#define kNoPICTFoundAlert 1036 +#define kRoomNameItem 3 +#define kRoomLocationBox 6 +#define kRoomTilesBox 10 +#define kRoomPopupItem 11 +#define kRoomDividerLine 12 +#define kRoomTilesBox2 15 +#define kRoomFirstCheck 17 +#define kLitUnlitText 18 +#define kMiniTileWide 16 +#define kBoundsButton 19 +#define kOriginalArtworkItem 19 +#define kPICTIDItem 5 +#define kFloorSupportCheck 12 + + +void UpdateRoomInfoDialog (DialogPtr); +void DragMiniTile (Point, short *); +void HiliteTileOver (Point); +Boolean RoomFilter (DialogPtr, EventRecord *, short *); +short ChooseOriginalArt (short); +void UpdateOriginalArt (DialogPtr); +Boolean OriginalArtFilter (DialogPtr, EventRecord *, short *); +Boolean PictIDExists (short); +short GetFirstPICT (void); +void BitchAboutPICTNotFound (void); + + +Rect tileSrc, tileDest, tileSrcRect, editTETextBox; +Rect leftBound, topBound, rightBound, bottomBound; +CGrafPtr tileSrcMap; +short tempTiles[kNumTiles]; +short tileOver, tempBack, cursorIs; +Boolean originalLeftOpen, originalTopOpen, originalRightOpen, originalBottomOpen; +Boolean originalFloor; + +extern Cursor handCursor, beamCursor; +extern short houseResFork, lastBackground; + + +//============================================================== Functions +//-------------------------------------------------------------- UpdateRoomInfoDialog + +#ifndef COMPILEDEMO +void UpdateRoomInfoDialog (DialogPtr theDialog) +{ + Rect src, dest; + short i; + + DrawDialog(theDialog); + if (tempBack >= kUserBackground) + SetPopUpMenuValue(theDialog, kRoomPopupItem, kOriginalArtworkItem); + else + SetPopUpMenuValue(theDialog, kRoomPopupItem, + (tempBack - kBaseBackgroundID) + 1); + + + + CopyBits(GetPortBitMapForCopyBits(tileSrcMap), + GetPortBitMapForCopyBits(GetDialogPort(theDialog)), + &tileSrcRect, &tileSrc, srcCopy, nil); + /* + CopyBits(&((GrafPtr)tileSrcMap)->portBits, + &(((GrafPtr)theDialog)->portBits), + &tileSrcRect, &tileSrc, srcCopy, nil); + */ + dest = tileDest; + dest.right = dest.left + kMiniTileWide; + for (i = 0; i < kNumTiles; i++) + { + QSetRect(&src, 0, 0, kMiniTileWide, 80); + QOffsetRect(&src, tempTiles[i] * kMiniTileWide, 0); + + CopyBits(GetPortBitMapForCopyBits(tileSrcMap), + GetPortBitMapForCopyBits(GetDialogPort(theDialog)), + &src, &dest, srcCopy, nil); + /* + CopyBits(&((GrafPtr)tileSrcMap)->portBits, + &(((GrafPtr)theDialog)->portBits), + &src, &dest, srcCopy, nil); + */ + QOffsetRect(&dest, kMiniTileWide, 0); + } + + if (GetNumberOfLights(thisRoomNumber) == 0) + SetDialogString(theDialog, kLitUnlitText, PSTR("(Room Is Dark)")); + else + SetDialogString(theDialog, kLitUnlitText, PSTR("(Room Is Lit)")); + + FrameDialogItemC(theDialog, kRoomLocationBox, kRedOrangeColor8); + FrameDialogItem(theDialog, kRoomTilesBox); + FrameDialogItemC(theDialog, kRoomDividerLine, kRedOrangeColor8); + FrameDialogItem(theDialog, kRoomTilesBox2); +} +#endif + +//-------------------------------------------------------------- DragMiniTile + +#ifndef COMPILEDEMO +void DragMiniTile (Point mouseIs, short *newTileOver) +{ + Rect dragRect; + Point mouseWas; + short wasTileOver; + Pattern dummyPattern; + + tileOver = (mouseIs.h - tileSrc.left) / kMiniTileWide; + wasTileOver = -1; + QSetRect(&dragRect, 0, 0, kMiniTileWide, 80); + QOffsetRect(&dragRect, + tileSrc.left + (tileOver * kMiniTileWide), + tileSrc.top); + PenMode(patXor); + PenPat(GetQDGlobalsGray(&dummyPattern)); + FrameRect(&dragRect); + mouseWas = mouseIs; + while (WaitMouseUp()) // loop until mouse button let up + { + GetMouse(&mouseIs); // get mouse coords + if (DeltaPoint(mouseWas, mouseIs) != 0L) // the mouse has moved + { + FrameRect(&dragRect); + QOffsetRect(&dragRect, mouseIs.h - mouseWas.h, 0); + FrameRect(&dragRect); + + if (PtInRect(mouseIs, &tileDest)) // is cursor in the drop rect + { + *newTileOver = (mouseIs.h - tileDest.left) / kMiniTileWide; + if (*newTileOver != wasTileOver) + { + PenNormal(); + PenSize(1, 2); + ForeColor(blueColor); + MoveTo(tileDest.left + (*newTileOver * kMiniTileWide), + tileDest.top - 3); + Line(kMiniTileWide, 0); + MoveTo(tileDest.left + (*newTileOver * kMiniTileWide), + tileDest.bottom + 1); + Line(kMiniTileWide, 0); + + if (wasTileOver != -1) + { + ForeColor(whiteColor); + MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), + tileDest.top - 3); + Line(kMiniTileWide, 0); + MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), + tileDest.bottom + 1); + Line(kMiniTileWide, 0); + } + ForeColor(blackColor); + PenNormal(); + PenMode(patXor); + PenPat(GetQDGlobalsGray(&dummyPattern)); + wasTileOver = *newTileOver; + } + } + else + { + *newTileOver = -1; // we're not in the drop zone + if (wasTileOver != -1) + { + PenNormal(); + PenSize(1, 2); + ForeColor(whiteColor); + MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), + tileDest.top - 3); + Line(kMiniTileWide, 0); + MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), + tileDest.bottom + 1); + Line(kMiniTileWide, 0); + ForeColor(blackColor); + PenNormal(); + PenMode(patXor); + PenPat(GetQDGlobalsGray(&dummyPattern)); + wasTileOver = -1; + } + } + + mouseWas = mouseIs; + } + } + if (wasTileOver != -1) + { + PenNormal(); + PenSize(1, 2); + ForeColor(whiteColor); + MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), tileDest.top - 3); + Line(kMiniTileWide, 0); + MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), tileDest.bottom + 1); + Line(kMiniTileWide, 0); + ForeColor(blackColor); + PenNormal(); + PenMode(patXor); + PenPat(GetQDGlobalsGray(&dummyPattern)); + wasTileOver = -1; + } + FrameRect(&dragRect); + PenNormal(); +} +#endif + +//-------------------------------------------------------------- HiliteTileOver + +#ifndef COMPILEDEMO +void HiliteTileOver (Point mouseIs) +{ + short newTileOver; + + if (PtInRect(mouseIs, &tileSrc)) + { + if (cursorIs != kHandCursor) + { + SetCursor(&handCursor); + cursorIs = kHandCursor; + } + + newTileOver = (mouseIs.h - tileSrc.left) / kMiniTileWide; + if (newTileOver != tileOver) + { + PenSize(1, 2); + ForeColor(redColor); + MoveTo(tileSrc.left + (newTileOver * kMiniTileWide), tileSrc.top - 3); + Line(kMiniTileWide, 0); + MoveTo(tileSrc.left + (newTileOver * kMiniTileWide), tileSrc.bottom + 1); + Line(kMiniTileWide, 0); + + if (tileOver != -1) + { + ForeColor(whiteColor); + MoveTo(tileSrc.left + (tileOver * kMiniTileWide), tileSrc.top - 3); + Line(kMiniTileWide, 0); + MoveTo(tileSrc.left + (tileOver * kMiniTileWide), tileSrc.bottom + 1); + Line(kMiniTileWide, 0); + } + ForeColor(blackColor); + PenNormal(); + + tileOver = newTileOver; + } + } + else + { + if (tileOver != -1) + { + PenSize(1, 2); + ForeColor(whiteColor); + MoveTo(tileSrc.left + (tileOver * kMiniTileWide), tileSrc.top - 3); + Line(kMiniTileWide, 0); + MoveTo(tileSrc.left + (tileOver * kMiniTileWide), tileSrc.bottom + 1); + Line(kMiniTileWide, 0); + ForeColor(blackColor); + PenNormal(); + tileOver = -1; + } + + if (PtInRect(mouseIs, &editTETextBox)) + { + if (cursorIs != kBeamCursor) + { + SetCursor(&beamCursor); + cursorIs = kBeamCursor; + } + } + else + { + if (cursorIs != kArrowCursor) + { + InitCursor(); + cursorIs = kArrowCursor; + } + } + } +} +#endif + +//-------------------------------------------------------------- RoomFilter +#ifndef COMPILEDEMO + +Boolean RoomFilter (DialogPtr dial, EventRecord *event, short *item) +{ + Point mouseIs; + short newTileOver; + + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + case kTabKeyASCII: + SelectDialogItemText(dial, kRoomNameItem, 0, 1024); + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + mouseIs = event->where; + GlobalToLocal(&mouseIs); + if (PtInRect(mouseIs, &tileSrc)) + { + if (StillDown()) + { + DragMiniTile(mouseIs, &newTileOver); + if ((newTileOver >= 0) && (newTileOver < kNumTiles)) + { + tempTiles[newTileOver] = tileOver; + UpdateRoomInfoDialog(dial); + } + } + return(true); + } + else + return(false); + break; + + case mouseUp: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateRoomInfoDialog(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + GetMouse(&mouseIs); + HiliteTileOver(mouseIs); + return(false); + break; + } +} +#endif + +//-------------------------------------------------------------- DoRoomInfo + +void DoRoomInfo (void) +{ +#ifndef COMPILEDEMO + #define kBackgroundsMenuID 140 + DialogPtr roomInfoDialog; + MenuHandle backgroundsMenu; + Str255 floorStr, suiteStr, objectsStr, tempStr; + short item, i, newBack; + char wasState; + Boolean leaving, wasFirstRoom, forceDraw; + ModalFilterUPP roomFilterUPP; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + roomFilterUPP = NewModalFilterUPP(RoomFilter); + + tileOver = -1; + cursorIs = kArrowCursor; + tempBack = thisRoom->background; + backgroundsMenu = GetMenu(kBackgroundsMenuID); +// SetMenuItemTextStyle(backgroundsMenu, kOriginalArtworkItem, italic); + if (HouseHasOriginalPicts()) + EnableMenuItem(backgroundsMenu, kOriginalArtworkItem); + + NumToString(thisRoom->floor, floorStr); + NumToString(thisRoom->suite, suiteStr); + NumToString(thisRoom->numObjects, objectsStr); + ParamText(floorStr, suiteStr, objectsStr, PSTR("")); + + theErr = CreateOffScreenGWorld(&tileSrcMap, &tileSrcRect, kPreferredDepth); + SetGWorld(tileSrcMap, nil); +// CreateOffScreenPixMap(&tileSrcRect, &tileSrcMap); +// SetPort((GrafPtr)tileSrcMap); + if ((tempBack > kStars) && (!PictIDExists(tempBack))) + { + BitchAboutPICTNotFound(); + tempBack = kSimpleRoom; + } + if ((tempBack == 2002) || (tempBack == 2011) || + (tempBack == 2016) || (tempBack == 2017)) + LoadScaledGraphic(tempBack - 800, &tileSrcRect); + else + LoadScaledGraphic(tempBack, &tileSrcRect); + + SetGWorld(wasCPort, wasWorld); + + for (i = 0; i < kNumTiles; i++) + tempTiles[i] = thisRoom->tiles[i]; + +// CenterDialog(kRoomInfoDialogID); + roomInfoDialog = GetNewDialog(kRoomInfoDialogID, nil, kPutInFront); + if (roomInfoDialog == nil) + RedAlert(kErrDialogDidntLoad); + SetPort((GrafPtr)roomInfoDialog); + + // Fix this later. TEMP +// AddMenuToPopUp(roomInfoDialog, kRoomPopupItem, backgroundsMenu); + if (tempBack >= kUserBackground) + SetPopUpMenuValue(roomInfoDialog, kRoomPopupItem, kOriginalArtworkItem); + else + SetPopUpMenuValue(roomInfoDialog, kRoomPopupItem, + (tempBack - kBaseBackgroundID) + 1); + SetDialogString(roomInfoDialog, kRoomNameItem, thisRoom->name); + GetDialogItemRect(roomInfoDialog, kRoomTilesBox, &tileSrc); + GetDialogItemRect(roomInfoDialog, kRoomTilesBox2, &tileDest); + GetDialogItemRect(roomInfoDialog, kRoomNameItem, &editTETextBox); + SelectDialogItemText(roomInfoDialog, kRoomNameItem, 0, 1024); + + ShowWindow(GetDialogWindow(roomInfoDialog)); + DrawDefaultButton(roomInfoDialog); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + wasFirstRoom = ((*thisHouse)->firstRoom == thisRoomNumber); + HSetState((Handle)thisHouse, wasState); + SetDialogItemValue(roomInfoDialog, kRoomFirstCheck, (short)wasFirstRoom); + + if (tempBack >= kUserBackground) + MyEnableControl(roomInfoDialog, kBoundsButton); + else + MyDisableControl(roomInfoDialog, kBoundsButton); + + leaving = false; + + while (!leaving) + { + ModalDialog(roomFilterUPP, &item); + + if (item == kOkayButton) + { + for (i = 0; i < kNumTiles; i++) + thisRoom->tiles[i] = tempTiles[i]; + + GetDialogString(roomInfoDialog, kRoomNameItem, tempStr); + PasStringCopyNum(tempStr, thisRoom->name, 27); + if (wasFirstRoom) + { + HLock((Handle)thisHouse); + (*thisHouse)->firstRoom = thisRoomNumber; + HUnlock((Handle)thisHouse); + } + thisRoom->background = tempBack; + if (tempBack < kUserBackground) + lastBackground = tempBack; + CopyThisRoomToRoom(); + ReflectCurrentRoom(false); + fileDirty = true; + UpdateMenus(false); + leaving = true; + } + else if (item == kCancelButton) + { + leaving = true; + } + else if (item == kRoomFirstCheck) + { + wasFirstRoom = !wasFirstRoom; + SetDialogItemValue(roomInfoDialog, kRoomFirstCheck, (short)wasFirstRoom); + } + else if (item == kRoomPopupItem) + { + GetPopUpMenuValue(roomInfoDialog, kRoomPopupItem, &newBack); + if (newBack == kOriginalArtworkItem) // original art item selected? + { + if (tempBack < kUserBackground) // was previous bg built-in? + { + tempBack = GetFirstPICT(); // then assign 1st PICT + forceDraw = true; + } + else + forceDraw = false; + newBack = ChooseOriginalArt(tempBack); // bring up dialog + if ((tempBack != newBack) || (forceDraw)) + { + tempBack = newBack; + SetPort((GrafPtr)tileSrcMap); + LoadScaledGraphic(tempBack, &tileSrcRect); + InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileSrc); + InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileDest); + } + } + else + { + newBack += (kBaseBackgroundID - 1); // adjust to get real PICT ID + if (newBack != tempBack) // if background has changed + SetInitialTiles(newBack, false); + } + + if (newBack >= kUserBackground) + { + MyEnableControl(roomInfoDialog, kBoundsButton); + if (newBack != tempBack) // if background has changed + SetInitialTiles(newBack, false); + } + else + MyDisableControl(roomInfoDialog, kBoundsButton); + + if (newBack != tempBack) + { + tempBack = newBack; + SetPort((GrafPtr)tileSrcMap); + if ((tempBack == 2002) || (tempBack == 2011) || + (tempBack == 2016) || (tempBack == 2017)) + LoadScaledGraphic(tempBack - 800, &tileSrcRect); + else + LoadScaledGraphic(tempBack, &tileSrcRect); + InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileSrc); + InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileDest); + } + } + else if (item == kBoundsButton) + { + newBack = ChooseOriginalArt(tempBack); + if (tempBack != newBack) + { + tempBack = newBack; + SetPort((GrafPtr)tileSrcMap); + LoadScaledGraphic(tempBack, &tileSrcRect); + InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileSrc); + InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileDest); + } + } + } + + InitCursor(); + DisposeDialog(roomInfoDialog); + DisposeModalFilterUPP(roomFilterUPP); + +// KillOffScreenPixMap(tileSrcMap); + DisposeGWorld(tileSrcMap); + tileSrcMap = nil; +#endif +} + +//-------------------------------------------------------------- UpdateOriginalArt + +#ifndef COMPILEDEMO +void UpdateOriginalArt (DialogPtr theDialog) +{ + Pattern dummyPattern; + + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + + PenSize(2, 1); + if (!originalLeftOpen) + BorderDialogItem(theDialog, 7, 8); + else + { + PenPat(GetQDGlobalsGray(&dummyPattern)); + BorderDialogItem(theDialog, 7, 8); + PenPat(GetQDGlobalsBlack(&dummyPattern)); + } + + PenSize(1, 2); + if (!originalTopOpen) + BorderDialogItem(theDialog, 8, 4); + else + { + PenPat(GetQDGlobalsGray(&dummyPattern)); + BorderDialogItem(theDialog, 8, 4); + PenPat(GetQDGlobalsBlack(&dummyPattern)); + } + + PenSize(2, 1); + if (!originalRightOpen) + BorderDialogItem(theDialog, 9, 1); + else + { + PenPat(GetQDGlobalsGray(&dummyPattern)); + BorderDialogItem(theDialog, 9, 1); + PenPat(GetQDGlobalsBlack(&dummyPattern)); + } + + PenSize(1, 2); + if (!originalBottomOpen) + BorderDialogItem(theDialog, 10, 2); + else + { + PenPat(GetQDGlobalsGray(&dummyPattern)); + BorderDialogItem(theDialog, 10, 2); + PenPat(GetQDGlobalsBlack(&dummyPattern)); + } + + PenSize(1, 1); +} +#endif + +//-------------------------------------------------------------- OriginalArtFilter +#ifndef COMPILEDEMO + +Boolean OriginalArtFilter (DialogPtr dial, EventRecord *event, short *item) +{ + Point mouseIs; + + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + case kTabKeyASCII: + SelectDialogItemText(dial, kPICTIDItem, 0, 1024); + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + mouseIs = event->where; + GlobalToLocal(&mouseIs); + if (PtInRect(mouseIs, &leftBound)) + { + *item = 7; + return(true); + } + else if (PtInRect(mouseIs, &topBound)) + { + *item = 8; + return(true); + } + else if (PtInRect(mouseIs, &rightBound)) + { + *item = 9; + return(true); + } + else if (PtInRect(mouseIs, &bottomBound)) + { + *item = 10; + return(true); + } + else + return(false); + break; + + case mouseUp: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateOriginalArt(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} +#endif + +//-------------------------------------------------------------- ChooseOriginalArt + +#ifndef COMPILEDEMO +short ChooseOriginalArt (short was) +{ + DialogPtr theDialog; + long longID; + short item, newPictID, tempShort, wasPictID; + Boolean leaving; + ModalFilterUPP originalArtFilterUPP; + + originalArtFilterUPP = NewModalFilterUPP(OriginalArtFilter); + + if (was < kUserBackground) + was = kUserBackground; + + InitCursor(); + BringUpDialog(&theDialog, kOriginalArtDialogID); + if (was >= kOriginalArtworkItem) + { + newPictID = was; + wasPictID = was; + } + else + { + newPictID = kUserBackground; + wasPictID = 0; + } + SetDialogNumToStr(theDialog, kPICTIDItem, (long)newPictID); + SelectDialogItemText(theDialog, kPICTIDItem, 0, 16); + + GetDialogItemRect(theDialog, 7, &leftBound); + GetDialogItemRect(theDialog, 8, &topBound); + GetDialogItemRect(theDialog, 9, &rightBound); + GetDialogItemRect(theDialog, 10, &bottomBound); + + tempShort = thisRoom->bounds >> 1; // version 2.0 house + originalLeftOpen = ((tempShort & 1) == 1); + originalTopOpen = ((tempShort & 2) == 2); + originalRightOpen = ((tempShort & 4) == 4); + originalBottomOpen = ((tempShort & 8) == 8); + originalFloor = ((tempShort & 16) == 16); + + SetDialogItemValue(theDialog, kFloorSupportCheck, (short)originalFloor); + + leaving = false; + + while (!leaving) + { + ModalDialog(originalArtFilterUPP, &item); + + if (item == kOkayButton) + { + GetDialogNumFromStr(theDialog, kPICTIDItem, &longID); + if ((longID >= 3000) && (longID < 3800) && (PictIDExists((short)longID))) + { + newPictID = (short)longID; + if (newPictID != wasPictID) + SetInitialTiles(tempBack, false); + tempShort = 0; + if (originalLeftOpen) + tempShort += 1; + if (originalTopOpen) + tempShort += 2; + if (originalRightOpen) + tempShort += 4; + if (originalBottomOpen) + tempShort += 8; + if (originalFloor) + tempShort += 16; + tempShort = tempShort << 1; // shift left 1 bit + tempShort += 1; // flag that says orginal bounds used + thisRoom->bounds = tempShort; + leaving = true; + } + else + { + SysBeep(1); + SetDialogNumToStr(theDialog, kPICTIDItem, (long)newPictID); + } + } + else if (item == kCancelButton) + { + newPictID = was; + leaving = true; + } + else if (item == 7) + { + originalLeftOpen = !originalLeftOpen; + UpdateOriginalArt(theDialog); + } + else if (item == 8) + { + originalTopOpen = !originalTopOpen; + UpdateOriginalArt(theDialog); + } + else if (item == 9) + { + originalRightOpen = !originalRightOpen; + UpdateOriginalArt(theDialog); + } + else if (item == 10) + { + originalBottomOpen = !originalBottomOpen; + UpdateOriginalArt(theDialog); + } + else if (item == kFloorSupportCheck) + { + originalFloor = !originalFloor; + ToggleDialogItemValue(theDialog, kFloorSupportCheck); + } + } + + DisposeDialog(theDialog); + DisposeModalFilterUPP(originalArtFilterUPP); + + return (newPictID); +} +#endif + +//-------------------------------------------------------------- PictIDExists + +Boolean PictIDExists (short theID) +{ + PicHandle thePicture; +// Handle resHandle; +// Str255 resName; +// ResType resType; +// short numPicts, i; +// short resID; + Boolean foundIt; + + foundIt = true; + + thePicture = GetPicture(theID); + if (thePicture == nil) + { + thePicture = (PicHandle)GetResource('Date', theID); + if (thePicture == nil) + { + foundIt = false; + } + else + ReleaseResource((Handle)thePicture); + } + else + ReleaseResource((Handle)thePicture); + +// foundIt = false; +// numPicts = Count1Resources('PICT'); +// for (i = 1; i <= numPicts; i++) +// { +// resHandle = Get1IndResource('PICT', i); +// if (resHandle != nil) +// { +// GetResInfo(resHandle, &resID, &resType, resName); +// ReleaseResource(resHandle); +// if (resID == theID) +// { +// foundIt = true; +// break; +// } +// } +// } + + return (foundIt); +} + +//-------------------------------------------------------------- GetFirstPICT + +short GetFirstPICT (void) +{ + Handle resHandle; + Str255 resName; + ResType resType; + short resID; + + resHandle = Get1IndResource('PICT', 1); + if (resHandle != nil) + { + GetResInfo(resHandle, &resID, &resType, resName); + ReleaseResource(resHandle); + return (resID); + } + else + return (-1); +} + +//-------------------------------------------------------------- BitchAboutPICTNotFound + +#ifndef COMPILEDEMO +void BitchAboutPICTNotFound (void) +{ + short hitWhat; + +// CenterAlert(kNoPICTFoundAlert); + hitWhat = Alert(kNoPICTFoundAlert, nil); +} +#endif + diff --git a/GpApp/RubberBands.cpp b/GpApp/RubberBands.cpp new file mode 100644 index 0000000..43c8f49 --- /dev/null +++ b/GpApp/RubberBands.cpp @@ -0,0 +1,318 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// RubberBands.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "RectUtils.h" + + +#define kRubberBandVelocity 20 +#define kBandFallCount 4 +#define kKillBandMode -1 + + +void CheckBandCollision (short); +void KillBand (short); + + +bandPtr bands; +Rect bandsSrcRect; +Rect bandRects[3]; +GWorldPtr bandsSrcMap; +GWorldPtr bandsMaskMap; +short numBands, bandHitLast; + +extern hotPtr hotSpots; +extern long gameFrame; +extern short nHotSpots, leftThresh, rightThresh; +extern Boolean twoPlayerGame, onePlayerLeft, playerDead; + + +//============================================================== Functions +//-------------------------------------------------------------- CheckBandCollision + +void CheckBandCollision (short who) +{ + short i, action, whoLinked; + Boolean collided, nothingCollided; + + nothingCollided = true; + + if ((leftThresh == kLeftWallLimit) && (bands[who].dest.left < kLeftWallLimit)) + { + if (bands[who].hVel < 0) + bands[who].hVel = -bands[who].hVel; + bands[who].dest.left = kLeftWallLimit; + bands[who].dest.right = bands[who].dest.left + 16; + PlayPrioritySound(kBandReboundSound, kBandReboundPriority); + collided = true; + } + else if ((rightThresh == kRightWallLimit) && (bands[who].dest.right > kRightWallLimit)) + { + if (bands[who].hVel > 0) + bands[who].hVel = -bands[who].hVel; + bands[who].dest.right = kRightWallLimit; + bands[who].dest.left = bands[who].dest.right - 16; + PlayPrioritySound(kBandReboundSound, kBandReboundPriority); + collided = true; + } + + for (i = 0; i < nHotSpots; i++) + { + if (hotSpots[i].isOn) + { + action = hotSpots[i].action; + if ((action == kDissolveIt) || (action == kRewardIt) || + (action == kSwitchIt) || (action == kTriggerIt) || + (action == kBounceIt)) + { + if (bands[who].dest.bottom < hotSpots[i].bounds.top) + collided = false; + else if (bands[who].dest.top > hotSpots[i].bounds.bottom) + collided = false; + else if (bands[who].dest.right < hotSpots[i].bounds.left) + collided = false; + else if (bands[who].dest.left > hotSpots[i].bounds.right) + collided = false; + else + collided = true; + + if (collided) + { + nothingCollided = false; // we have detected a collision + if (bandHitLast != i) // don't count it if same as last frame + { // we don't want rapid on/off toggles + bandHitLast = i; // note who so we don't double-toggle it + if ((action == kDissolveIt) || (action == kBounceIt)) + { + if (bands[who].hVel > 0) + { + if ((bands[who].dest.right - bands[who].hVel) < + hotSpots[i].bounds.left) + { + bands[who].hVel = -bands[who].hVel; + bands[who].dest.right = hotSpots[i].bounds.left; + bands[who].dest.left = bands[who].dest.right - 16; + } + else + bands[who].mode = kKillBandMode; + } + else + { + if ((bands[who].dest.left - bands[who].hVel) > + hotSpots[i].bounds.right) + { + bands[who].hVel = -bands[who].hVel; + bands[who].dest.left = hotSpots[i].bounds.right; + bands[who].dest.right = bands[who].dest.left + 16; + } + else + bands[who].mode = kKillBandMode; + } + PlayPrioritySound(kBandReboundSound, kBandReboundPriority); + break; + } + else if (action == kRewardIt) + { + whoLinked = hotSpots[i].who; + if ((masterObjects[whoLinked].theObject.what == kGreaseRt) || + (masterObjects[whoLinked].theObject.what == kGreaseLf)) + { + if (SetObjectState(thisRoomNumber, + masterObjects[whoLinked].objectNum, 0, whoLinked)) + SpillGrease(masterObjects[whoLinked].dynaNum, + masterObjects[whoLinked].hotNum); + hotSpots[i].isOn = false; + } + } + else if (action == kSwitchIt) + { + HandleSwitches(&hotSpots[i]); + } + else if (action == kTriggerIt) + { + ArmTrigger(&hotSpots[i]); + } + } + } + } + } + } + + if (nothingCollided) // the rubberband has hit nothing + bandHitLast = -1; // so make note of that for the next time + + if (bands[who].hVel != 0) + { + if (bands[who].dest.bottom < theGlider.dest.top) + collided = false; + else if (bands[who].dest.top > theGlider.dest.bottom) + collided = false; + else if (bands[who].dest.right < theGlider.dest.left) + collided = false; + else if (bands[who].dest.left > theGlider.dest.right) + collided = false; + else + collided = true; + + if (collided) + { + if ((!twoPlayerGame) || (!onePlayerLeft) || (playerDead == kPlayer2)) + { + theGlider.hVel += (bands[who].hVel / 2); + bands[who].hVel = 0; + PlayPrioritySound(kHitWallSound, kHitWallPriority); + } + } + + if (twoPlayerGame) + { + if (bands[who].dest.bottom < theGlider2.dest.top) + collided = false; + else if (bands[who].dest.top > theGlider2.dest.bottom) + collided = false; + else if (bands[who].dest.right < theGlider2.dest.left) + collided = false; + else if (bands[who].dest.left > theGlider2.dest.right) + collided = false; + else + collided = true; + + if (collided) + { + if ((!onePlayerLeft) || (playerDead == kPlayer1)) + { + theGlider2.hVel += (bands[who].hVel / 2); + bands[who].hVel = 0; + PlayPrioritySound(kHitWallSound, kHitWallPriority); + } + } + } + } + if ((bands[who].dest.left < kLeftWallLimit) || + (bands[who].dest.right > kRightWallLimit)) + { + bands[who].mode = kKillBandMode; + } + else if (bands[who].dest.bottom > kFloorLimit) + { + bands[who].mode = kKillBandMode; + } +} + +//-------------------------------------------------------------- HandleBands + +void HandleBands (void) +{ + Rect dest; + short i, count; + + if (numBands == 0) + return; + + for (i = 0; i < numBands; i++) + { + bands[i].mode++; + if (bands[i].mode > 2) + bands[i].mode = 0; + + bands[i].count++; + if (bands[i].count >= kBandFallCount) + { + bands[i].vVel++; + bands[i].count = 0; + } + + dest = bands[i].dest; + QOffsetRect(&dest, playOriginH, playOriginV); + AddRectToWorkRects(&dest); + + bands[i].dest.left += bands[i].hVel; + bands[i].dest.right += bands[i].hVel; + bands[i].dest.top += bands[i].vVel; + bands[i].dest.bottom += bands[i].vVel; + + CheckBandCollision(i); + } + + count = 0; + do + { + while (bands[count].mode == kKillBandMode) + { + bands[count].mode = 0; + KillBand(count); + } + count++; + } + while (count < numBands); +} + +//-------------------------------------------------------------- AddBand + +Boolean AddBand (gliderPtr thisGlider, short h, short v, Boolean direction) +{ + if (numBands >= kMaxRubberBands) + return (false); + + bands[numBands].mode = 0; + bands[numBands].count = 0; + if (thisGlider->tipped) + bands[numBands].vVel = -2; + else + bands[numBands].vVel = 0; + bands[numBands].dest.left = h - 8; + bands[numBands].dest.right = h + 8; + bands[numBands].dest.top = v - 3; + bands[numBands].dest.bottom = v + 3; + + if (direction == kFaceLeft) + { + bands[numBands].dest.left -= 32; + bands[numBands].dest.right -= 32; + bands[numBands].hVel = -kRubberBandVelocity; + } + else + { + bands[numBands].dest.left += 32; + bands[numBands].dest.right += 32; + bands[numBands].hVel = kRubberBandVelocity; + } + + thisGlider->hVel -= (bands[numBands].hVel / 2); + numBands++; + + PlayPrioritySound(kFireBandSound, kFireBandPriority); + return (true); +} + +//-------------------------------------------------------------- KillBand + +void KillBand (short which) +{ + short lastBand; + + lastBand = numBands - 1; + if (which != lastBand) + bands[which] = bands[lastBand]; + + numBands--; +} + +//-------------------------------------------------------------- KillAllBands + +void KillAllBands (void) +{ + short i; + + for (i = 0; i < kMaxRubberBands; i++) + { + bands[i].mode = 0; + } + + numBands = 0; +} + diff --git a/GpApp/RubberBands.h b/GpApp/RubberBands.h new file mode 100644 index 0000000..3f1a1e9 --- /dev/null +++ b/GpApp/RubberBands.h @@ -0,0 +1,12 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// RubberBands.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +extern GWorldPtr bandsSrcMap; +extern GWorldPtr bandsMaskMap; diff --git a/GpApp/SavedGames.cpp b/GpApp/SavedGames.cpp new file mode 100644 index 0000000..42d0586 --- /dev/null +++ b/GpApp/SavedGames.cpp @@ -0,0 +1,352 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// SavedGames.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLStringCompare.h" +#include "Externs.h" +#include "House.h" + + +#define kSavedGameVersion 0x0200 + + +void SavedGameMismatchError (StringPtr); + + +gameType smallGame; + +extern FSSpecPtr theHousesSpecs; +extern short numStarsRemaining, thisHouseIndex; +extern Boolean twoPlayerGame; + + +//============================================================== Functions +//-------------------------------------------------------------- SaveGame2 + +void SaveGame2 (void) +{ + // Add NavServices later. +/* + StandardFileReply theReply; + FSSpec tempSpec; + Str255 gameNameStr; + Size byteCount; + OSErr theErr; + houseType *thisHousePtr; + roomType *srcRoom; + savedRoom *destRoom; + gamePtr savedGame; + short r, i, numRooms, gameRefNum; + char wasState; + + FlushEvents(everyEvent, 0); + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + numRooms = thisHousePtr->nRooms; + + HSetState((Handle)thisHouse, wasState); + + byteCount = sizeof(game2Type) + sizeof(savedRoom) * numRooms; + savedGame = (gamePtr)NewPtr(byteCount); + if (savedGame == nil) + { + YellowAlert(kYellowFailedSaveGame, MemError()); + return; + } + + GetFirstWordOfString(thisHouseName, gameNameStr); + if (gameNameStr[0] > 23) + gameNameStr[0] = 23; + PasStringConcat(gameNameStr, "\p Game"); + + StandardPutFile("\pSave Game As:", gameNameStr, &theReply); + if (!theReply.sfGood) + return; + + if (theReply.sfReplacing) + { + theErr = FSMakeFSSpec(theReply.sfFile.vRefNum, theReply.sfFile.parID, + theReply.sfFile.name, &tempSpec); + if (!CheckFileError(theErr, "\pSaved Game")) + return; + + theErr = FSpDelete(&tempSpec); + if (!CheckFileError(theErr, "\pSaved Game")) + return; + } + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + savedGame->house = theHousesSpecs[thisHouseIndex]; + savedGame->version = kSavedGameVersion; + savedGame->wasStarsLeft = numStarsRemaining; + savedGame->timeStamp = thisHousePtr->timeStamp; + savedGame->where.h = theGlider.dest.left; + savedGame->where.v = theGlider.dest.top; + savedGame->score = theScore; + savedGame->unusedLong = 0L; + savedGame->unusedLong2 = 0L; + savedGame->energy = batteryTotal; + savedGame->bands = bandsTotal; + savedGame->roomNumber = thisRoomNumber; + savedGame->gliderState = theGlider.mode; + savedGame->numGliders = mortals; + savedGame->foil = foilTotal; + savedGame->nRooms = numRooms; + savedGame->facing = theGlider.facing; + savedGame->showFoil = showFoil; + + for (r = 0; r < numRooms; r++) + { + destRoom = &(savedGame->savedData[r]); + srcRoom = &(thisHousePtr->rooms[r]); + + destRoom->unusedShort = 0; + destRoom->unusedByte = 0; + destRoom->visited = srcRoom->visited; + for (i = 0; i < kMaxRoomObs; i++) + destRoom->objects[i] = srcRoom->objects[i]; + } + + HSetState((Handle)thisHouse, wasState); + + theErr = FSpCreate(&theReply.sfFile, 'ozm5', 'gliG', theReply.sfScript); + if (CheckFileError(theErr, "\pSaved Game")) + { + theErr = FSpOpenDF(&theReply.sfFile, fsCurPerm, &gameRefNum); + if (CheckFileError(theErr, "\pSaved Game")) + { + theErr = SetFPos(gameRefNum, fsFromStart, 0L); + if (CheckFileError(theErr, "\pSaved Game")) + { + theErr = FSWrite(gameRefNum, &byteCount, (Ptr)savedGame); + if (CheckFileError(theErr, "\pSaved Game")) + { + theErr = SetEOF(gameRefNum, byteCount); + if (CheckFileError(theErr, "\pSaved Game")) + { + } + } + } + theErr = FSClose(gameRefNum); + if (CheckFileError(theErr, "\pSaved Game")) + { + } + } + } + DisposePtr((Ptr)savedGame); + */ +} + +//-------------------------------------------------------------- SavedGameMismatchError + +void SavedGameMismatchError (StringPtr gameName) +{ + #define kSavedGameErrorAlert 1044 + short whoCares; + + InitCursor(); + +// CenterAlert(kSavedGameErrorAlert); + ParamText(gameName, thisHouseName, PSTR(""), PSTR("")); + + whoCares = Alert(kSavedGameErrorAlert, nil); +} + +//-------------------------------------------------------------- OpenSavedGame + +Boolean OpenSavedGame (void) +{ +return false; // TEMP fix this iwth NavServices +/* + StandardFileReply theReply; + SFTypeList theList; + houseType *thisHousePtr; + roomType *destRoom; + savedRoom *srcRoom; + gamePtr savedGame; + long byteCount; + OSErr theErr; + short r, i, gameRefNum; + char wasState; + + theList[0] = 'gliG'; + + StandardGetFile(nil, 1, theList, &theReply); + if (!theReply.sfGood) + return(false); + + theErr = FSpOpenDF(&theReply.sfFile, fsCurPerm, &gameRefNum); + if (!CheckFileError(theErr, "\pSaved Game")) + return(false); + + theErr = GetEOF(gameRefNum, &byteCount); + if (!CheckFileError(theErr, "\pSaved Game")) + { + theErr = FSClose(gameRefNum); + return(false); + } + + savedGame = (gamePtr)NewPtr(byteCount); + if (savedGame == nil) + { + YellowAlert(kYellowFailedSaveGame, MemError()); + theErr = FSClose(gameRefNum); + return(false); + } + + theErr = SetFPos(gameRefNum, fsFromStart, 0L); + if (!CheckFileError(theErr, "\pSaved Game")) + { + DisposePtr((Ptr)savedGame); + theErr = FSClose(gameRefNum); + return(false); + } + + theErr = FSRead(gameRefNum, &byteCount, savedGame); + if (!CheckFileError(theErr, "\pSaved Game")) + { + DisposePtr((Ptr)savedGame); + theErr = FSClose(gameRefNum); + return(false); + } + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + if (!EqualString(savedGame->house.name, thisHouseName, true, true)) + { + SavedGameMismatchError(savedGame->house.name); + HSetState((Handle)thisHouse, wasState); + DisposePtr((Ptr)savedGame); + theErr = FSClose(gameRefNum); + return(false); + } + else if (thisHousePtr->timeStamp != savedGame->timeStamp) + { + YellowAlert(kYellowSavedTimeWrong, 0); + HSetState((Handle)thisHouse, wasState); + DisposePtr((Ptr)savedGame); + theErr = FSClose(gameRefNum); + return(false); + } + else if (savedGame->version != kSavedGameVersion) + { + YellowAlert(kYellowSavedVersWrong, kSavedGameVersion); + HSetState((Handle)thisHouse, wasState); + DisposePtr((Ptr)savedGame); + theErr = FSClose(gameRefNum); + return(false); + } + else if (savedGame->nRooms != thisHousePtr->nRooms) + { + YellowAlert(kYellowSavedRoomsWrong, savedGame->nRooms - thisHousePtr->nRooms); + HSetState((Handle)thisHouse, wasState); + DisposePtr((Ptr)savedGame); + theErr = FSClose(gameRefNum); + return(false); + } + else + { + smallGame.wasStarsLeft = savedGame->wasStarsLeft; + smallGame.where.h = savedGame->where.h; + smallGame.where.v = savedGame->where.v; + smallGame.score = savedGame->score; + smallGame.unusedLong = savedGame->unusedLong; + smallGame.unusedLong2 = savedGame->unusedLong2; + smallGame.energy = savedGame->energy; + smallGame.bands = savedGame->bands; + smallGame.roomNumber = savedGame->roomNumber; + smallGame.gliderState = savedGame->gliderState; + smallGame.numGliders = savedGame->numGliders; + smallGame.foil = savedGame->foil; + smallGame.unusedShort = 0; + smallGame.facing = savedGame->facing; + smallGame.showFoil = savedGame->showFoil; + + for (r = 0; r < savedGame->nRooms; r++) + { + srcRoom = &(savedGame->savedData[r]); + destRoom = &(thisHousePtr->rooms[r]); + destRoom->visited = srcRoom->visited; + for (i = 0; i < kMaxRoomObs; i++) + destRoom->objects[i] = srcRoom->objects[i]; + } + } + HSetState((Handle)thisHouse, wasState); + + DisposePtr((Ptr)savedGame); + + theErr = FSClose(gameRefNum); + if (!CheckFileError(theErr, "\pSaved Game")) + return (false); + + return (true); + */ +} + +//-------------------------------------------------------------- SaveGame + +// This is probably about 3 days away from becoming the "old" functionÉ +// for saving games. + +void SaveGame (Boolean doSave) +{ + houseType *thisHousePtr; + UInt32 stamp; + char wasState; + + if (twoPlayerGame) + return; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + + if (doSave) + { + thisHousePtr->savedGame.version = kSavedGameVersion; + thisHousePtr->savedGame.wasStarsLeft = numStarsRemaining; + GetDateTime(&stamp); + thisHousePtr->savedGame.timeStamp = (long)stamp; + thisHousePtr->savedGame.where.h = theGlider.dest.left; + thisHousePtr->savedGame.where.v = theGlider.dest.top; + thisHousePtr->savedGame.score = theScore; + thisHousePtr->savedGame.unusedLong = 0L; + thisHousePtr->savedGame.unusedLong2 = 0L; + thisHousePtr->savedGame.energy = batteryTotal; + thisHousePtr->savedGame.bands = bandsTotal; + thisHousePtr->savedGame.roomNumber = thisRoomNumber; + thisHousePtr->savedGame.gliderState = theGlider.mode; + thisHousePtr->savedGame.numGliders = mortals; + thisHousePtr->savedGame.foil = foilTotal; + thisHousePtr->savedGame.unusedShort = 0; + thisHousePtr->savedGame.facing = theGlider.facing; + thisHousePtr->savedGame.showFoil = showFoil; + + thisHousePtr->hasGame = true; + } + else + { + thisHousePtr->hasGame = false; + } + + HSetState((Handle)thisHouse, wasState); + + if (doSave) + { + if (!WriteHouse(theMode == kEditMode)) + YellowAlert(kYellowFailedWrite, 0); + } +} + diff --git a/GpApp/Scoreboard.cpp b/GpApp/Scoreboard.cpp new file mode 100644 index 0000000..4bb6418 --- /dev/null +++ b/GpApp/Scoreboard.cpp @@ -0,0 +1,458 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Scoreboard.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLNumberFormatting.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "RectUtils.h" + + +#define kGrayBackgroundColor 251 +#define kGrayBackgroundColor4 10 +#define kFoilBadge 0 +#define kBandsBadge 1 +#define kBatteryBadge 2 +#define kHeliumBadge 3 +#define kScoreRollAmount 13 + + +void RefreshRoomTitle (short); +void RefreshNumGliders (void); +void RefreshPoints (void); + + +Rect boardSrcRect, badgeSrcRect, boardDestRect; +GWorldPtr boardSrcMap, badgeSrcMap; +Rect boardTSrcRect, boardTDestRect; +GWorldPtr boardTSrcMap; +Rect boardGSrcRect, boardGDestRect; +GWorldPtr boardGSrcMap; +Rect boardPSrcRect, boardPDestRect; +Rect boardPQDestRect, boardGQDestRect; +Rect badgesBlankRects[4], badgesBadgesRects[4]; +Rect badgesDestRects[4]; +GWorldPtr boardPSrcMap; +long displayedScore; +short wasScoreboardMode; +Boolean doRollScore; + +extern Rect localRoomsDest[], justRoomsRect; +extern long gameFrame; +extern short numNeighbors, otherPlayerEscaped; +extern Boolean evenFrame, onePlayerLeft; + + +//============================================================== Functions +//-------------------------------------------------------------- RefreshScoreboard + +void RefreshScoreboard (short mode) +{ + doRollScore = true; + + RefreshRoomTitle(mode); + RefreshNumGliders(); + RefreshPoints(); + + CopyBits((BitMap *)*GetGWorldPixMap(boardSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &boardSrcRect, &boardDestRect, srcCopy, 0L); + + QuickBatteryRefresh(false); + QuickBandsRefresh(false); + QuickFoilRefresh(false); +} + +//-------------------------------------------------------------- HandleDynamicScoreboard + + void HandleDynamicScoreboard (void) + { + #define kFoilLow 2 // 25% + #define kBatteryLow 17 // 25% + #define kHeliumLow -38 // 25% + #define kBandsLow 2 // 25% + long whosTurn; + + if (theScore > displayedScore) + { + if (doRollScore) + { + displayedScore += kScoreRollAmount; + if (displayedScore > theScore) + displayedScore = theScore; + } + else + displayedScore = theScore; + + PlayPrioritySound(kScoreTikSound, kScoreTikPriority); + QuickScoreRefresh(); + } + + whosTurn = gameFrame & 0x00000007; + switch (whosTurn) + { + case 0: // show foil + if ((foilTotal > 0) && (foilTotal < kFoilLow)) + QuickFoilRefresh(false); + break; + + case 1: // hide battery + if ((batteryTotal > 0) && (batteryTotal < kBatteryLow)) + QuickBatteryRefresh(true); + else if ((batteryTotal < 0) && (batteryTotal > kHeliumLow)) + QuickBatteryRefresh(true); + break; + + case 2: // show rubber bands + if ((bandsTotal > 0) && (bandsTotal < kBandsLow)) + QuickBandsRefresh(false); + break; + + case 4: // show battery + if ((batteryTotal > 0) && (batteryTotal < kBatteryLow)) + QuickBatteryRefresh(false); + else if ((batteryTotal < 0) && (batteryTotal > kHeliumLow)) + QuickBatteryRefresh(false); + break; + + case 5: // hide foil + if ((foilTotal > 0) && (foilTotal < kFoilLow)) + QuickFoilRefresh(true); + break; + + case 7: // hide rubber bands + if ((bandsTotal > 0) && (bandsTotal < kBandsLow)) + QuickBandsRefresh(true); + break; + } + } + +//-------------------------------------------------------------- RefreshRoomTitle + +void RefreshRoomTitle (short mode) +{ + RGBColor theRGBColor, wasColor; + + SetPort((GrafPtr)boardTSrcMap); + + GetForeColor(&wasColor); + if (thisMac.isDepth == 4) + Index2Color(kGrayBackgroundColor4, &theRGBColor); + else + Index2Color(kGrayBackgroundColor, &theRGBColor); + RGBForeColor(&theRGBColor); + PaintRect(&boardTSrcRect); + RGBForeColor(&wasColor); + + MoveTo(1, 10); + ForeColor(blackColor); + switch (mode) + { + case kEscapedTitleMode: + DrawString(PSTR("Hit Delete key if unable to Follow")); + break; + + case kSavingTitleMode: + DrawString(PSTR("Saving GameÉ")); + break; + + default: + DrawString(thisRoom->name); + break; + } + MoveTo(0, 9); + ForeColor(whiteColor); + switch (mode) + { + case kEscapedTitleMode: + DrawString(PSTR("Hit Delete key if unable to Follow")); + break; + + case kSavingTitleMode: + DrawString(PSTR("Saving GameÉ")); + break; + + default: + DrawString(thisRoom->name); + break; + } + ForeColor(blackColor); + + CopyBits((BitMap *)*GetGWorldPixMap(boardTSrcMap), + (BitMap *)*GetGWorldPixMap(boardSrcMap), + &boardTSrcRect, &boardTDestRect, srcCopy, nil); +} + +//-------------------------------------------------------------- RefreshNumGliders + +void RefreshNumGliders (void) +{ + RGBColor theRGBColor, wasColor; + Str255 nGlidersStr; + long displayMortals; + + SetPort((GrafPtr)boardGSrcMap); + + GetForeColor(&wasColor); + if (thisMac.isDepth == 4) + Index2Color(kGrayBackgroundColor4, &theRGBColor); + else + Index2Color(kGrayBackgroundColor, &theRGBColor); + RGBForeColor(&theRGBColor); + PaintRect(&boardGSrcRect); + RGBForeColor(&wasColor); + + displayMortals = mortals; + if (displayMortals < 0) + displayMortals = 0; + NumToString(displayMortals, nGlidersStr); + + MoveTo(1, 10); + ForeColor(blackColor); + DrawString(nGlidersStr); + + MoveTo(0, 9); + ForeColor(whiteColor); + DrawString(nGlidersStr); + + ForeColor(blackColor); + + CopyBits((BitMap *)*GetGWorldPixMap(boardGSrcMap), + (BitMap *)*GetGWorldPixMap(boardSrcMap), + &boardGSrcRect, &boardGDestRect, srcCopy, nil); +} + +//-------------------------------------------------------------- RefreshPoints + +void RefreshPoints (void) +{ + RGBColor theRGBColor, wasColor; + Str255 scoreStr; + + SetPort((GrafPtr)boardPSrcMap); + + GetForeColor(&wasColor); + if (thisMac.isDepth == 4) + Index2Color(kGrayBackgroundColor4, &theRGBColor); + else + Index2Color(kGrayBackgroundColor, &theRGBColor); + RGBForeColor(&theRGBColor); + PaintRect(&boardPSrcRect); + RGBForeColor(&wasColor); + + NumToString(theScore, scoreStr); + + MoveTo(1, 10); + ForeColor(blackColor); + DrawString(scoreStr); + + MoveTo(0, 9); + ForeColor(whiteColor); + DrawString(scoreStr); + + ForeColor(blackColor); + + CopyBits((BitMap *)*GetGWorldPixMap(boardPSrcMap), + (BitMap *)*GetGWorldPixMap(boardSrcMap), + &boardPSrcRect, &boardPDestRect, srcCopy, nil); + + displayedScore = theScore; +} + +//-------------------------------------------------------------- QuickGlidersRefresh + +void QuickGlidersRefresh (void) +{ + RGBColor theRGBColor, wasColor; + Str255 nGlidersStr; + + SetPort((GrafPtr)boardGSrcMap); + + GetForeColor(&wasColor); + if (thisMac.isDepth == 4) + Index2Color(kGrayBackgroundColor4, &theRGBColor); + else + Index2Color(kGrayBackgroundColor, &theRGBColor); + RGBForeColor(&theRGBColor); + PaintRect(&boardGSrcRect); + RGBForeColor(&wasColor); + + NumToString((long)mortals, nGlidersStr); + + MoveTo(1, 10); + ForeColor(blackColor); + DrawString(nGlidersStr); + + MoveTo(0, 9); + ForeColor(whiteColor); + DrawString(nGlidersStr); + + ForeColor(blackColor); + + CopyBits((BitMap *)*GetGWorldPixMap(boardGSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &boardGSrcRect, &boardGQDestRect, srcCopy, nil); +} + +//-------------------------------------------------------------- QuickScoreRefresh + +void QuickScoreRefresh (void) +{ + RGBColor theRGBColor, wasColor; + Str255 scoreStr; + + SetPort((GrafPtr)boardPSrcMap); + + GetForeColor(&wasColor); + if (thisMac.isDepth == 4) + Index2Color(kGrayBackgroundColor4, &theRGBColor); + else + Index2Color(kGrayBackgroundColor, &theRGBColor); + RGBForeColor(&theRGBColor); + PaintRect(&boardPSrcRect); + RGBForeColor(&wasColor); + + NumToString(displayedScore, scoreStr); + + MoveTo(1, 10); + ForeColor(blackColor); + DrawString(scoreStr); + + MoveTo(0, 9); + ForeColor(whiteColor); + DrawString(scoreStr); + + ForeColor(blackColor); + + CopyBits((BitMap *)*GetGWorldPixMap(boardPSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &boardPSrcRect, &boardPQDestRect, srcCopy, nil); +} + +//-------------------------------------------------------------- QuickBatteryRefresh + +void QuickBatteryRefresh (Boolean flash) +{ + if ((batteryTotal > 0) && (!flash)) + { + CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &badgesBadgesRects[kBatteryBadge], + &badgesDestRects[kBatteryBadge], + srcCopy, nil); + } + else if ((batteryTotal < 0) && (!flash)) + { + CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &badgesBadgesRects[kHeliumBadge], + &badgesDestRects[kHeliumBadge], + srcCopy, nil); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &badgesBlankRects[kBatteryBadge], + &badgesDestRects[kBatteryBadge], + srcCopy, nil); + } +} + +//-------------------------------------------------------------- QuickBandsRefresh + +void QuickBandsRefresh (Boolean flash) +{ + if ((bandsTotal > 0) && (!flash)) + { + CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &badgesBadgesRects[kBandsBadge], + &badgesDestRects[kBandsBadge], + srcCopy, nil); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &badgesBlankRects[kBandsBadge], + &badgesDestRects[kBandsBadge], + srcCopy, nil); + } +} + +//-------------------------------------------------------------- QuickFoilRefresh + +void QuickFoilRefresh (Boolean flash) +{ + if ((foilTotal > 0) && (!flash)) + { + CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &badgesBadgesRects[kFoilBadge], + &badgesDestRects[kFoilBadge], + srcCopy, nil); + } + else + { + CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &badgesBlankRects[kFoilBadge], + &badgesDestRects[kFoilBadge], + srcCopy, nil); + } +} + +//-------------------------------------------------------------- AdjustScoreboardHeight + +void AdjustScoreboardHeight (void) +{ + short offset, newMode; + + if (numNeighbors == 9) + newMode = kScoreboardHigh; + else + newMode = kScoreboardLow; + + if (wasScoreboardMode != newMode) + { + switch (newMode) + { + case kScoreboardHigh: // 9 neighbors + offset = localRoomsDest[kCentralRoom].top; + offset = -offset; + justRoomsRect = workSrcRect; + break; + + case kScoreboardLow: // 1 or 3 neighbors + offset = localRoomsDest[kCentralRoom].top; + justRoomsRect = workSrcRect; + justRoomsRect.top = localRoomsDest[kCentralRoom].top; + justRoomsRect.bottom = localRoomsDest[kCentralRoom].bottom; + break; + } + + QOffsetRect(&boardDestRect, 0, offset); + QOffsetRect(&boardGQDestRect, 0, offset); + QOffsetRect(&boardPQDestRect, 0, offset); + QOffsetRect(&badgesDestRects[kBatteryBadge], 0, offset); + QOffsetRect(&badgesDestRects[kBandsBadge], 0, offset); + QOffsetRect(&badgesDestRects[kFoilBadge], 0, offset); + QOffsetRect(&badgesDestRects[kHeliumBadge], 0, offset); + + wasScoreboardMode = newMode; + } +} + +//-------------------------------------------------------------- BlackenScoreboard + +void BlackenScoreboard (void) +{ + UpdateMenuBarWindow(); +} + diff --git a/GpApp/Scoreboard.h b/GpApp/Scoreboard.h new file mode 100644 index 0000000..23d19ab --- /dev/null +++ b/GpApp/Scoreboard.h @@ -0,0 +1,15 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Scoreboard.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +extern GWorldPtr boardSrcMap; +extern GWorldPtr badgeSrcMap; +extern GWorldPtr boardTSrcMap; +extern GWorldPtr boardGSrcMap; +extern GWorldPtr boardPSrcMap; diff --git a/Sources/Scrap.c b/GpApp/Scrap.c old mode 100755 new mode 100644 similarity index 100% rename from Sources/Scrap.c rename to GpApp/Scrap.c diff --git a/GpApp/SelectHouse.cpp b/GpApp/SelectHouse.cpp new file mode 100644 index 0000000..c3e0a77 --- /dev/null +++ b/GpApp/SelectHouse.cpp @@ -0,0 +1,676 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// SelectHouse.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLAliases.h" +#include "PLResources.h" +#include "PLSound.h" +#include "PLStringCompare.h" +#include "DialogUtils.h" +#include "Externs.h" +#include "Environ.h" +#include "House.h" +#include "RectUtils.h" + + +#define kLoadHouseDialogID 1000 +#define kDispFiles 12 +#define kLoadTitlePictItem 3 +#define kLoadNameFirstItem 5 +#define kLoadNameLastItem 16 +#define kLoadIconFirstItem 17 +#define kLoadIconLastItem 28 +#define kScrollUpItem 29 +#define kScrollDownItem 30 +#define kLoadTitlePict1 1001 +#define kLoadTitlePict8 1002 +#define kDefaultHousePict1 1003 +#define kDefaultHousePict8 1004 +#define kGrayedOutUpArrow 1052 +#define kGrayedOutDownArrow 1053 +#define kMaxExtraHouses 8 + + +void UpdateLoadDialog (DialogPtr); +void PageUpHouses (DialogPtr); +void PageDownHouses (DialogPtr); +Boolean LoadFilter (DialogPtr, EventRecord *, short *); +void SortHouseList (void); +void DoDirSearch (void); + + +Rect loadHouseRects[12]; +FSSpecPtr theHousesSpecs; +FSSpec extraHouseSpecs[kMaxExtraHouses]; +long lastWhenClick; +Point lastWhereClick; +short housesFound, thisHouseIndex, maxFiles, willMaxFiles; +short housePage, demoHouseIndex, numExtraHouses; +char fileFirstChar[12]; + +extern UInt32 doubleTime; + + +//============================================================== Functions +//-------------------------------------------------------------- UpdateLoadWindow + +#ifndef COMPILEDEMO +void UpdateLoadDialog (DialogPtr theDialog) +{ + Rect tempRect, dialogRect, dummyRect; + short houseStart, houseStop, i, wasResFile, isResFile, count; +// char wasState; + WindowRef theWindow; +// RgnHandle theRegion; + + theWindow = GetDialogWindow(theDialog); + GetWindowBounds(theWindow, kWindowContentRgn, &dialogRect); + /* + wasState = HGetState((Handle)(((DialogPeek)theDialog)->window).port.visRgn); + HLock((Handle)(((DialogPeek)theDialog)->window).port.visRgn); + dialogRect = (**((((DialogPeek)theDialog)->window).port.visRgn)).rgnBBox; + HSetState((Handle)(((DialogPeek)theDialog)->window).port.visRgn, wasState); + */ + + DrawDialog(theDialog); + ColorFrameWHRect(8, 39, 413, 184, kRedOrangeColor8); // box around files + + houseStart = housePage; + houseStop = housesFound; + if ((houseStop - houseStart) > kDispFiles) + houseStop = houseStart + kDispFiles; + + wasResFile = CurResFile(); + count = 0; + + for (i = 0; i < 12; i++) + fileFirstChar[i] = 0x7F; + + for (i = houseStart; i < houseStop; i++) + { + SpinCursor(1); + + GetDialogItemRect(theDialog, kLoadIconFirstItem + i - housePage, + &tempRect); + + if (SectRect(&dialogRect, &tempRect, &dummyRect)) + { + isResFile = HOpenResFile(theHousesSpecs[i].vRefNum, + theHousesSpecs[i].parID, theHousesSpecs[i].name, fsRdPerm); + if (isResFile != -1) + { + if (Get1Resource('icl8', -16455) != nil) + { + LargeIconPlot(&tempRect, -16455); + } + else + LoadDialogPICT(theDialog, kLoadIconFirstItem + i - housePage, + kDefaultHousePict8); + CloseResFile(isResFile); + } + else + LoadDialogPICT(theDialog, kLoadIconFirstItem + i - housePage, + kDefaultHousePict8); + } + + fileFirstChar[count] = theHousesSpecs[i].name[1]; + if ((fileFirstChar[count] <= 0x7A) && (fileFirstChar[count] > 0x60)) + fileFirstChar[count] -= 0x20; + count++; + + DrawDialogUserText(theDialog, kLoadNameFirstItem + i - housePage, + theHousesSpecs[i].name, i == (thisHouseIndex + housePage)); + + } + + InitCursor(); + UseResFile(wasResFile); +} +#endif + +//-------------------------------------------------------------- PageUpHouses + +#ifndef COMPILEDEMO +void PageUpHouses (DialogPtr theDial) +{ + Rect tempRect; + + if (housePage < kDispFiles) + { + SysBeep(1); + return; + } + + housePage -= kDispFiles; + thisHouseIndex = kDispFiles - 1; + + ShowDialogItem(theDial, kScrollDownItem); + if (housePage < kDispFiles) + { + GetDialogItemRect(theDial, kScrollUpItem, &tempRect); + HideDialogItem(theDial, kScrollUpItem); + DrawCIcon(kGrayedOutUpArrow, tempRect.left, tempRect.top); + } + + QSetRect(&tempRect, 8, 39, 421, 223); + EraseRect(&tempRect); + InvalWindowRect(GetDialogWindow(theDial), &tempRect); +} +#endif + +//-------------------------------------------------------------- PageDownHouses + +#ifndef COMPILEDEMO +void PageDownHouses (DialogPtr theDial) +{ + Rect tempRect; + + if (housePage >= (housesFound - kDispFiles)) + { + SysBeep(1); + return; + } + + housePage += kDispFiles; + thisHouseIndex = 0; + + ShowDialogItem(theDial, kScrollUpItem); + if (housePage >= (housesFound - kDispFiles)) + { + GetDialogItemRect(theDial, kScrollDownItem, &tempRect); + HideDialogItem(theDial, kScrollDownItem); + DrawCIcon(kGrayedOutDownArrow, tempRect.left, tempRect.top); + } + + QSetRect(&tempRect, 8, 39, 421, 223); + EraseRect(&tempRect); + InvalWindowRect(GetDialogWindow(theDial), &tempRect); +} +#endif + +//-------------------------------------------------------------- LoadFilter +#ifndef COMPILEDEMO + +Boolean LoadFilter (DialogPtr dial, EventRecord *event, short *item) +{ + short screenCount, i, wasIndex; + char theChar; + + switch (event->what) + { + case keyDown: + theChar = (event->message) & charCodeMask; + switch (theChar) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + case kPageUpKeyASCII: + *item = kScrollUpItem; + return (true); + break; + + case kPageDownKeyASCII: + *item = kScrollDownItem; + return (true); + break; + + case kUpArrowKeyASCII: + InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); + thisHouseIndex -= 4; + if (thisHouseIndex < 0) + { + screenCount = housesFound - housePage; + if (screenCount > kDispFiles) + screenCount = kDispFiles; + + thisHouseIndex += 4; + thisHouseIndex = (((screenCount - 1) / 4) * 4) + + (thisHouseIndex % 4); + if (thisHouseIndex >= screenCount) + thisHouseIndex -= 4; + } + InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); + return(true); + break; + + case kDownArrowKeyASCII: + InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); + thisHouseIndex += 4; + screenCount = housesFound - housePage; + if (screenCount > kDispFiles) + screenCount = kDispFiles; + if (thisHouseIndex >= screenCount) + thisHouseIndex %= 4; + InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); + return(true); + break; + + case kLeftArrowKeyASCII: + InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); + thisHouseIndex--; + if (thisHouseIndex < 0) + { + screenCount = housesFound - housePage; + if (screenCount > kDispFiles) + screenCount = kDispFiles; + thisHouseIndex = screenCount - 1; + } + InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); + return(true); + break; + + case kTabKeyASCII: + case kRightArrowKeyASCII: + InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); + thisHouseIndex++; + screenCount = housesFound - housePage; + if (screenCount > kDispFiles) + screenCount = kDispFiles; + if (thisHouseIndex >= screenCount) + thisHouseIndex = 0; + InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); + return(true); + break; + + default: + if (((theChar > 0x40) && (theChar <= 0x5A)) || + ((theChar > 0x60) && (theChar <= 0x7A))) + { + if ((theChar > 0x60) && (theChar <= 0x7A)) + theChar -= 0x20; + wasIndex = thisHouseIndex; + thisHouseIndex = -1; + i = 0; + do + { + if ((fileFirstChar[i] >= theChar) && (fileFirstChar[i] != 0x7F)) + thisHouseIndex = i; + i++; + } + while ((thisHouseIndex == -1) && (i < 12)); + if (thisHouseIndex == -1) + { + screenCount = housesFound - housePage; + if (screenCount > kDispFiles) + screenCount = kDispFiles; + thisHouseIndex = screenCount - 1; + } + if (wasIndex != thisHouseIndex) + { + InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[wasIndex]); + InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); + } + return(true); + } + else + return(false); + } + break; + + case mouseDown: + lastWhenClick = event->when - lastWhenClick; + SubPt(event->where, &lastWhereClick); + return(false); + break; + + case mouseUp: + lastWhenClick = event->when; + lastWhereClick = event->where; + return(false); + break; + + case updateEvt: + BeginUpdate(GetDialogWindow(dial)); + UpdateLoadDialog(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} +#endif + +//-------------------------------------------------------------- DoLoadHouse + +#ifndef COMPILEDEMO +void DoLoadHouse (void) +{ + Rect tempRect; + DialogPtr theDial; + short i, item, wasIndex, screenCount; + Boolean leaving, whoCares; + ModalFilterUPP loadFilterUPP; + + loadFilterUPP = NewModalFilterUPP(LoadFilter); + + BringUpDialog(&theDial, kLoadHouseDialogID); + if (housesFound <= kDispFiles) + { + GetDialogItemRect(theDial, kScrollUpItem, &tempRect); + HideDialogItem(theDial, kScrollUpItem); + DrawCIcon(kGrayedOutUpArrow, tempRect.left, tempRect.top); + + GetDialogItemRect(theDial, kScrollDownItem, &tempRect); + HideDialogItem(theDial, kScrollDownItem); + DrawCIcon(kGrayedOutDownArrow, tempRect.left, tempRect.top); + } + else + { + if (thisHouseIndex < kDispFiles) + { + GetDialogItemRect(theDial, kScrollUpItem, &tempRect); + HideDialogItem(theDial, kScrollUpItem); + DrawCIcon(kGrayedOutUpArrow, tempRect.left, tempRect.top); + } + else if (thisHouseIndex > (housesFound - kDispFiles)) + { + GetDialogItemRect(theDial, kScrollDownItem, &tempRect); + HideDialogItem(theDial, kScrollDownItem); + DrawCIcon(kGrayedOutDownArrow, tempRect.left, tempRect.top); + } + } + wasIndex = thisHouseIndex; + housePage = (thisHouseIndex / kDispFiles) * kDispFiles; + thisHouseIndex -= housePage; + + for (i = 0; i < 12; i++) + { + GetDialogItemRect(theDial, kLoadNameFirstItem + i, + &loadHouseRects[i]); + GetDialogItemRect(theDial, kLoadIconFirstItem + i, + &tempRect); + loadHouseRects[i].top = tempRect.top; + loadHouseRects[i].bottom++; + } + + leaving = false; + + while (!leaving) + { + ModalDialog(loadFilterUPP, &item); + + if (item == kOkayButton) + { + thisHouseIndex += housePage; + if (thisHouseIndex != wasIndex) + { + whoCares = CloseHouse(); + PasStringCopy(theHousesSpecs[thisHouseIndex].name, + thisHouseName); + if (OpenHouse()) + whoCares = ReadHouse(); + } + leaving = true; + } + else if (item == kCancelButton) + { + thisHouseIndex = wasIndex; + leaving = true; + } + else if ((item >= kLoadNameFirstItem) && + (item <= kLoadNameLastItem)) + { + screenCount = housesFound - housePage; + if (screenCount > kDispFiles) + screenCount = kDispFiles; + if ((item - kLoadNameFirstItem != thisHouseIndex) && + (item - kLoadNameFirstItem < screenCount)) + { + InvalWindowRect(GetDialogWindow(theDial), &loadHouseRects[thisHouseIndex]); + thisHouseIndex = item - kLoadNameFirstItem; + InvalWindowRect(GetDialogWindow(theDial), &loadHouseRects[thisHouseIndex]); + } + + if (lastWhereClick.h < 0) + lastWhereClick.h = -lastWhereClick.h; + if (lastWhereClick.v < 0) + lastWhereClick.v = -lastWhereClick.v; + if ((lastWhenClick < doubleTime) && (lastWhereClick.h < 5) && + (lastWhereClick.v < 5)) + { + thisHouseIndex += housePage; + if (thisHouseIndex != wasIndex) + { + MyDisableControl(theDial, kOkayButton); + MyDisableControl(theDial, kCancelButton); + whoCares = CloseHouse(); + PasStringCopy(theHousesSpecs[thisHouseIndex].name, + thisHouseName); + if (OpenHouse()) + whoCares = ReadHouse(); + } + leaving = true; + } + } + else if ((item >= kLoadIconFirstItem) && + (item <= kLoadIconLastItem)) + { + screenCount = housesFound - housePage; + if (screenCount > kDispFiles) + screenCount = kDispFiles; + if ((item - kLoadIconFirstItem != thisHouseIndex) && + (item - kLoadIconFirstItem < screenCount)) + { + InvalWindowRect(GetDialogWindow(theDial), &loadHouseRects[thisHouseIndex]); + thisHouseIndex = item - kLoadIconFirstItem; + InvalWindowRect(GetDialogWindow(theDial), &loadHouseRects[thisHouseIndex]); + } + + if (lastWhereClick.h < 0) + lastWhereClick.h = -lastWhereClick.h; + if (lastWhereClick.v < 0) + lastWhereClick.v = -lastWhereClick.v; + if ((lastWhenClick < doubleTime) && (lastWhereClick.h < 5) && + (lastWhereClick.v < 5)) + { + thisHouseIndex += housePage; + if (thisHouseIndex != wasIndex) + { + MyDisableControl(theDial, kOkayButton); + MyDisableControl(theDial, kCancelButton); + whoCares = CloseHouse(); + PasStringCopy(theHousesSpecs[thisHouseIndex].name, + thisHouseName); + if (OpenHouse()) + whoCares = ReadHouse(); + } + leaving = true; + } + } + else if (item == kScrollUpItem) + { + PageUpHouses(theDial); + } + else if (item == kScrollDownItem) + { + PageDownHouses(theDial); + } + } + + DisposeDialog(theDial); + DisposeModalFilterUPP(loadFilterUPP); +} +#endif + +//-------------------------------------------------------------- SortHouseList + +void SortHouseList (void) +{ + FSSpec tempSpec; + short i, h, whosFirst; + + i = 0; // remove exact duplicate houses + while (i < housesFound) + { + h = i + 1; + while (h < housesFound) + { + if ((EqualString(theHousesSpecs[i].name, theHousesSpecs[h].name, true, true)) && + (theHousesSpecs[i].vRefNum == theHousesSpecs[i].vRefNum) && + (theHousesSpecs[i].parID == theHousesSpecs[i].parID)) + { + theHousesSpecs[h] = theHousesSpecs[housesFound - 1]; + housesFound--; + } + h++; + } + i++; + } + + for (i = 0; i < housesFound - 1; i++) + { + for (h = 0; h < (housesFound - i - 1); h++) + { + whosFirst = WhichStringFirst(theHousesSpecs[h].name, + theHousesSpecs[h + 1].name); + if (whosFirst == 1) + { + tempSpec = theHousesSpecs[h + 1]; + theHousesSpecs[h + 1] = theHousesSpecs[h]; + theHousesSpecs[h] = tempSpec; + } + } + } +} + +//-------------------------------------------------------------- DoDirSearch + +void DoDirSearch (void) +{ + #define kMaxDirectories 32 + CInfoPBRec theBlock; + Str255 nameString; + long theDirs[kMaxDirectories]; + OSErr theErr, notherErr; + short count, i, currentDir, numDirs; + + for (i = 0; i < kMaxDirectories; i++) + theDirs[i] = 0L; + currentDir = 0; + theDirs[currentDir] = thisMac.dirID; + numDirs = 1; + + theBlock.hFileInfo.ioCompletion = nil; + theBlock.hFileInfo.ioVRefNum = thisMac.vRefNum; + theBlock.hFileInfo.ioNamePtr = nameString; + + while ((currentDir < numDirs) && (currentDir < kMaxDirectories)) + { + count = 1; + theErr = noErr; + + while (theErr == noErr) + { + SpinCursor(1); + theBlock.hFileInfo.ioFDirIndex = count; + theBlock.hFileInfo.ioDirID = theDirs[currentDir]; + theErr = PBGetCatInfo(&theBlock, false); + + if (theErr == noErr) + { + if ((theBlock.hFileInfo.ioFlAttrib & 0x10) == 0x00) + { + if ((theBlock.hFileInfo.ioFlFndrInfo.fdType == 'gliH') && + (theBlock.hFileInfo.ioFlFndrInfo.fdCreator == 'ozm5') && + (housesFound < maxFiles)) + { + notherErr = FSMakeFSSpec(thisMac.vRefNum, + theBlock.hFileInfo.ioFlParID, nameString, + &theHousesSpecs[housesFound]); + if (notherErr == noErr) + housesFound++; + } + } + else if ((theBlock.hFileInfo.ioFlAttrib & 0x10) == 0x10) + { + if (numDirs < kMaxDirectories) + { + theDirs[numDirs] = theBlock.hFileInfo.ioDirID; + numDirs++; + } + } + count++; + } + } + currentDir++; + } + + if (housesFound < 1) + { + thisHouseIndex = -1; + YellowAlert(kYellowNoHouses, 0); + } + else + { + SortHouseList(); + thisHouseIndex = 0; + for (i = 0; i < housesFound; i++) + { + if (EqualString(theHousesSpecs[i].name, thisHouseName, false, true)) + { + thisHouseIndex = i; + break; + } + } + PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); + + demoHouseIndex = -1; + for (i = 0; i < housesFound; i++) + { + if (EqualString(theHousesSpecs[i].name, PSTR("Demo House"), false, true)) + { + demoHouseIndex = i; + break; + } + } + } +} + +//-------------------------------------------------------------- BuildHouseList + +void BuildHouseList (void) +{ + short i; + + if (thisMac.hasSystem7) + { + housesFound = 0; // zero the number of houses found + for (i = 0; i < numExtraHouses; i++) // 1st, insert extra houses into list + { + theHousesSpecs[housesFound] = extraHouseSpecs[i]; + housesFound++; + } + DoDirSearch(); // now, search folders for the rest + } +} + +//-------------------------------------------------------------- AddExtraHouse + +void AddExtraHouse (FSSpec *newHouse) +{ + if (numExtraHouses >= kMaxExtraHouses) + return; + + extraHouseSpecs[numExtraHouses] = *newHouse; + numExtraHouses++; +} + diff --git a/GpApp/Settings.cpp b/GpApp/Settings.cpp new file mode 100644 index 0000000..3738e84 --- /dev/null +++ b/GpApp/Settings.cpp @@ -0,0 +1,1482 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Settings.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLSound.h" +#include "PLTextUtils.h" +#include "DialogUtils.h" +#include "Externs.h" +#include "Environ.h" +#include "House.h" + + +#define kMainPrefsDialID 1012 +#define kDisplayPrefsDialID 1017 +#define kSoundPrefsDialID 1018 +#define kControlPrefsDialID 1023 +#define kBrainsPrefsDialID 1024 +#define kDisplayButton 3 +#define kSoundButton 4 +#define kControlsButton 5 +#define kBrainsButton 6 +#define kDisplay1Item 3 +#define kDisplay3Item 4 +#define kDisplay9Item 5 +#define kDoColorFadeItem 9 +#define kCurrentDepth 10 +#define k256Depth 11 +#define k16Depth 12 +#define kDispDefault 15 +#define kUseQDItem 16 +#define kUseScreen2Item 17 +#define kSofterItem 4 +#define kLouderItem 5 +#define kVolNumberItem 7 +#define kIdleMusicItem 8 +#define kPlayMusicItem 9 +#define kSoundDefault 13 +#define kRightControl 5 +#define kLeftControl 6 +#define kBattControl 7 +#define kBandControl 8 +#define kControlDefaults 13 +#define kESCPausesRadio 14 +#define kTABPausesRadio 15 +#define kMaxFilesItem 5 +#define kQuickTransitCheck 7 +#define kDoZoomsCheck 8 +#define kBrainsDefault 9 +#define kDoDemoCheck 10 +#define kDoBackgroundCheck 11 +#define kDoErrorCheck 12 +#define kDoPrettyMapCheck 13 +#define kDoBitchDlgsCheck 14 + + +void SetBrainsToDefaults (DialogPtr); +void UpdateSettingsBrains (DialogPtr); +Boolean BrainsFilter (DialogPtr, EventRecord *, short *); +void DoBrainsPrefs (void); +void SetControlsToDefaults (DialogPtr); +void UpdateControlKeyName (DialogPtr); +void UpdateSettingsControl (DialogPtr); +Boolean ControlFilter (DialogPtr, EventRecord *, short *); +void DoControlPrefs (void); +void SoundDefaults (DialogPtr); +void UpdateSettingsSound (DialogPtr); +void HandleSoundMusicChange (short, Boolean); +Boolean SoundFilter (DialogPtr, EventRecord *, short *); +void DoSoundPrefs (void); +void DisplayDefaults (void); +void FrameDisplayIcon (DialogPtr); +void DisplayUpdate (DialogPtr); +Boolean DisplayFilter (DialogPtr, EventRecord *, short *); +void DoDisplayPrefs (void); +void SetAllDefaults (void); +void FlashSettingsButton (short); +void UpdateSettingsMain (DialogPtr); +Boolean PrefsFilter (DialogPtr, EventRecord *, short *); +void BitchAboutChanges (void); + + +Rect prefButton[4], controlRects[4]; +Str15 leftName, rightName, batteryName, bandName; +Str15 tempLeftStr, tempRightStr, tempBattStr, tempBandStr; +long tempLeftMap, tempRightMap, tempBattMap, tempBandMap; +short whichCtrl, wasDepthPref; +Boolean wasFade, wasIdle, wasPlay, wasTransit, wasZooms, wasBackground; +Boolean wasEscPauseKey, wasDemos, wasScreen2, nextRestartChange, wasErrorCheck; +Boolean wasPrettyMap, wasBitchDialogs; + +extern short numNeighbors, isDepthPref, maxFiles, willMaxFiles; +extern Boolean isDoColorFade, isPlayMusicIdle, isUseSecondScreen; +extern Boolean isHouseChecks, doBitchDialogs; +extern Boolean isEscPauseKey, failedMusic, isSoundOn, doBackground; +extern Boolean isMusicOn, quickerTransitions, doAutoDemo; +extern Boolean changeLockStateOfHouse, saveHouseLocked, doPrettyMap; + + +//============================================================== Functions +//-------------------------------------------------------------- SetBrainsToDefaults + +void SetBrainsToDefaults (DialogPtr theDialog) +{ + SetDialogNumToStr(theDialog, kMaxFilesItem, 24L); +#ifdef powerc + wasTransit = false; +#else + wasTransit = true; +#endif + wasZooms = true; + wasDemos = true; + wasBackground = false; + wasErrorCheck = true; + wasPrettyMap = true; + wasBitchDialogs = true; + SetDialogItemValue(theDialog, kQuickTransitCheck, (short)wasTransit); + SetDialogItemValue(theDialog, kDoZoomsCheck, (short)wasZooms); + SetDialogItemValue(theDialog, kDoDemoCheck, (short)wasDemos); + SetDialogItemValue(theDialog, kDoBackgroundCheck, (short)wasBackground); + SetDialogItemValue(theDialog, kDoErrorCheck, (short)wasErrorCheck); + SetDialogItemValue(theDialog, kDoPrettyMapCheck, (short)wasPrettyMap); + SetDialogItemValue(theDialog, kDoBitchDlgsCheck, (short)wasBitchDialogs); +} + +//-------------------------------------------------------------- UpdateSettingsBrains + +void UpdateSettingsBrains (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + + SetDialogNumToStr(theDialog, kMaxFilesItem, (long)willMaxFiles); + SelectDialogItemText(theDialog, kMaxFilesItem, 0, 1024); + + FrameDialogItemC(theDialog, 3, kRedOrangeColor8); +} + +//-------------------------------------------------------------- BrainsFilter + +Boolean BrainsFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + case kCapAKeyASCII: + case kAKeyASCII: + *item = kDoDemoCheck; + return(true); + break; + + case kCapBKeyASCII: + case kBKeyASCII: + *item = kDoBackgroundCheck; + return(true); + break; + + case kCapDKeyASCII: + case kDKeyASCII: + *item = kBrainsDefault; + FlashDialogButton(dial, kBrainsDefault); + return(true); + break; + + case kCapEKeyASCII: + case kEKeyASCII: + *item = kDoErrorCheck; + return(true); + break; + + case kCapQKeyASCII: + case kQKeyASCII: + *item = kQuickTransitCheck; + return(true); + break; + + case kCapZKeyASCII: + case kZKeyASCII: + *item = kDoZoomsCheck; + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateSettingsBrains(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- DoBrainsPrefs + +void DoBrainsPrefs (void) +{ + DialogPtr prefDlg; + long tempLong; + short itemHit, wasMaxFiles; + Boolean leaving; + ModalFilterUPP brainsFilterUPP; + + brainsFilterUPP = NewModalFilterUPP(BrainsFilter); + + BringUpDialog(&prefDlg, kBrainsPrefsDialID); + leaving = false; + wasMaxFiles = willMaxFiles; + + wasTransit = quickerTransitions; + wasZooms = doZooms; + wasDemos = doAutoDemo; + wasBackground = doBackground; + wasErrorCheck = isHouseChecks; + wasPrettyMap = doPrettyMap; + wasBitchDialogs = doBitchDialogs; + + SetDialogItemValue(prefDlg, kQuickTransitCheck, (short)wasTransit); + SetDialogItemValue(prefDlg, kDoZoomsCheck, (short)wasZooms); + SetDialogItemValue(prefDlg, kDoDemoCheck, (short)wasDemos); + SetDialogItemValue(prefDlg, kDoBackgroundCheck, (short)wasBackground); + SetDialogItemValue(prefDlg, kDoErrorCheck, (short)wasErrorCheck); + SetDialogItemValue(prefDlg, kDoPrettyMapCheck, (short)wasPrettyMap); + SetDialogItemValue(prefDlg, kDoBitchDlgsCheck, (short)wasBitchDialogs); + + while (!leaving) + { + ModalDialog(brainsFilterUPP, &itemHit); + switch (itemHit) + { + case kOkayButton: + GetDialogNumFromStr(prefDlg, kMaxFilesItem, &tempLong); + if (tempLong > 500) + tempLong = 500; + else if (tempLong < 12) + tempLong = 12; + willMaxFiles = static_cast(tempLong); + if (willMaxFiles != wasMaxFiles) + nextRestartChange = true; + quickerTransitions = wasTransit; + doZooms = wasZooms; + doAutoDemo = wasDemos; + doBackground = wasBackground; + isHouseChecks = wasErrorCheck; + doPrettyMap = wasPrettyMap; + doBitchDialogs = wasBitchDialogs; + leaving = true; + break; + + case kCancelButton: + willMaxFiles = wasMaxFiles; + leaving = true; + break; + + case kQuickTransitCheck: + wasTransit = !wasTransit; + SetDialogItemValue(prefDlg, kQuickTransitCheck, (short)wasTransit); + break; + + case kDoZoomsCheck: + wasZooms = !wasZooms; + SetDialogItemValue(prefDlg, kDoZoomsCheck, (short)wasZooms); + break; + + case kDoDemoCheck: + wasDemos = !wasDemos; + SetDialogItemValue(prefDlg, kDoDemoCheck, (short)wasDemos); + break; + + case kDoBackgroundCheck: + wasBackground = !wasBackground; + SetDialogItemValue(prefDlg, kDoBackgroundCheck, (short)wasBackground); + break; + + case kBrainsDefault: + SetBrainsToDefaults(prefDlg); + break; + + case kDoErrorCheck: + wasErrorCheck = !wasErrorCheck; + SetDialogItemValue(prefDlg, kDoErrorCheck, (short)wasErrorCheck); + break; + + case kDoPrettyMapCheck: + wasPrettyMap = !wasPrettyMap; + SetDialogItemValue(prefDlg, kDoPrettyMapCheck, (short)wasPrettyMap); + break; + + case kDoBitchDlgsCheck: + wasBitchDialogs = !wasBitchDialogs; + SetDialogItemValue(prefDlg, kDoBitchDlgsCheck, (short)wasBitchDialogs); + break; + } + } + + DisposeDialog(prefDlg); + DisposeModalFilterUPP(brainsFilterUPP); +} + +//-------------------------------------------------------------- SetControlsToDefaults + +void SetControlsToDefaults (DialogPtr theDialog) +{ + PasStringCopy(PSTR("lf arrow"), tempLeftStr); + PasStringCopy(PSTR("rt arrow"), tempRightStr); + PasStringCopy(PSTR("dn arrow"), tempBattStr); + PasStringCopy(PSTR("up arrow"), tempBandStr); + tempLeftMap = kLeftArrowKeyMap; + tempRightMap = kRightArrowKeyMap; + tempBattMap = kDownArrowKeyMap; + tempBandMap = kUpArrowKeyMap; + wasEscPauseKey = false; + SelectFromRadioGroup(theDialog, kTABPausesRadio, + kESCPausesRadio, kTABPausesRadio); +} + +//-------------------------------------------------------------- UpdateControlKeyName + +void UpdateControlKeyName (DialogPtr theDialog) +{ + DrawDialogUserText(theDialog, kRightControl + 4, tempRightStr, whichCtrl == 0); + DrawDialogUserText(theDialog, kLeftControl + 4, tempLeftStr, whichCtrl == 1); + DrawDialogUserText(theDialog, kBattControl + 4, tempBattStr, whichCtrl == 2); + DrawDialogUserText(theDialog, kBandControl + 4, tempBandStr, whichCtrl == 3); +} + +//-------------------------------------------------------------- UpdateSettingsControl + +void UpdateSettingsControl (DialogPtr theDialog) +{ + short i; + + DrawDialog(theDialog); + + PenSize(2, 2); + ForeColor(whiteColor); + for (i = 0; i < 4; i++) + FrameRect(&controlRects[i]); + ForeColor(redColor); + FrameRect(&controlRects[whichCtrl]); + ForeColor(blackColor); + PenNormal(); + UpdateControlKeyName(theDialog); + FrameDialogItemC(theDialog, 3, kRedOrangeColor8); +} + +//-------------------------------------------------------------- ControlFilter + +Boolean ControlFilter (DialogPtr dial, EventRecord *event, short *item) +{ + long wasKeyMap; + + switch (event->what) + { + case keyDown: + switch (whichCtrl) + { + case 0: + wasKeyMap = (long)GetKeyMapFromMessage(event->message); + if ((wasKeyMap == tempLeftMap) || (wasKeyMap == tempBattMap) || + (wasKeyMap == tempBandMap) || (wasKeyMap == kTabKeyMap) || + (wasKeyMap == kEscKeyMap) || (wasKeyMap == kDeleteKeyMap)) + { + if (wasKeyMap == kEscKeyMap) + { + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + } + else + SysBeep(1); + } + else + { + GetKeyName(event->message, tempRightStr); + tempRightMap = wasKeyMap; + } + break; + + case 1: + wasKeyMap = (long)GetKeyMapFromMessage(event->message); + if ((wasKeyMap == tempRightMap) || (wasKeyMap == tempBattMap) || + (wasKeyMap == tempBandMap) || (wasKeyMap == kTabKeyMap) || + (wasKeyMap == kEscKeyMap) || (wasKeyMap == kDeleteKeyMap)) + { + if (wasKeyMap == kEscKeyMap) + { + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + } + else + SysBeep(1); + } + else + { + GetKeyName(event->message, tempLeftStr); + tempLeftMap = wasKeyMap; + } + break; + + case 2: + wasKeyMap = (long)GetKeyMapFromMessage(event->message); + if ((wasKeyMap == tempRightMap) || (wasKeyMap == tempLeftMap) || + (wasKeyMap == tempBandMap) || (wasKeyMap == kTabKeyMap) || + (wasKeyMap == kEscKeyMap) || (wasKeyMap == kDeleteKeyMap)) + { + if (wasKeyMap == kEscKeyMap) + { + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + } + else + SysBeep(1); + } + else + { + GetKeyName(event->message, tempBattStr); + tempBattMap = wasKeyMap; + } + break; + + case 3: + wasKeyMap = (long)GetKeyMapFromMessage(event->message); + if ((wasKeyMap == tempRightMap) || (wasKeyMap == tempLeftMap) || + (wasKeyMap == tempBattMap) || (wasKeyMap == kTabKeyMap) || + (wasKeyMap == kEscKeyMap) || (wasKeyMap == kDeleteKeyMap)) + { + if (wasKeyMap == kEscKeyMap) + { + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + } + else + SysBeep(1); + } + else + { + GetKeyName(event->message, tempBandStr); + tempBandMap = wasKeyMap; + } + break; + } + UpdateControlKeyName(dial); + return(false); + break; + + case mouseDown: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateSettingsControl(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- DoControlPrefs + +void DoControlPrefs (void) +{ + DialogPtr prefDlg; + short i, itemHit; + Boolean leaving; + ModalFilterUPP controlFilterUPP; + + controlFilterUPP = NewModalFilterUPP(ControlFilter); + +// CenterDialog(kControlPrefsDialID); + prefDlg = GetNewDialog(kControlPrefsDialID, nil, kPutInFront); + if (prefDlg == nil) + RedAlert(kErrDialogDidntLoad); + SetPort((GrafPtr)prefDlg); + for (i = 0; i < 4; i++) + { + GetDialogItemRect(prefDlg, i + kRightControl, &controlRects[i]); + InsetRect(&controlRects[i], -3, -3); + } + whichCtrl = 1; + + PasStringCopy(leftName, tempLeftStr); + PasStringCopy(rightName, tempRightStr); + PasStringCopy(batteryName, tempBattStr); + PasStringCopy(bandName, tempBandStr); + tempLeftMap = theGlider.leftKey; + tempRightMap = theGlider.rightKey; + tempBattMap = theGlider.battKey; + tempBandMap = theGlider.bandKey; + wasEscPauseKey = isEscPauseKey; + + leaving = false; + + ShowWindow(GetDialogWindow(prefDlg)); + if (isEscPauseKey) + SelectFromRadioGroup(prefDlg, kESCPausesRadio, + kESCPausesRadio, kTABPausesRadio); + else + SelectFromRadioGroup(prefDlg, kTABPausesRadio, + kESCPausesRadio, kTABPausesRadio); + + while (!leaving) + { + ModalDialog(controlFilterUPP, &itemHit); + switch (itemHit) + { + case kOkayButton: + PasStringCopy(tempLeftStr, leftName); + PasStringCopy(tempRightStr, rightName); + PasStringCopy(tempBattStr, batteryName); + PasStringCopy(tempBandStr, bandName); + theGlider.leftKey = tempLeftMap; + theGlider.rightKey = tempRightMap; + theGlider.battKey = tempBattMap; + theGlider.bandKey = tempBandMap; + isEscPauseKey = wasEscPauseKey; + leaving = true; + break; + + case kCancelButton: + leaving = true; + break; + + case kRightControl: + case kLeftControl: + case kBattControl: + case kBandControl: + PenSize(2, 2); + ForeColor(whiteColor); + FrameRect(&controlRects[whichCtrl]); + whichCtrl = itemHit - kRightControl; + ForeColor(redColor); + FrameRect(&controlRects[whichCtrl]); + ForeColor(blackColor); + PenNormal(); + UpdateControlKeyName(prefDlg); + break; + + case kESCPausesRadio: + case kTABPausesRadio: + SelectFromRadioGroup(prefDlg, itemHit, kESCPausesRadio, kTABPausesRadio); + wasEscPauseKey = !wasEscPauseKey; + break; + + case kControlDefaults: + SetControlsToDefaults(prefDlg); + UpdateControlKeyName(prefDlg); + break; + } + } + + DisposeDialog(prefDlg); + DisposeModalFilterUPP(controlFilterUPP); +} + +//-------------------------------------------------------------- SoundDefaults + +void SoundDefaults (DialogPtr theDialog) +{ + wasIdle = true; + wasPlay = true; + SetDialogItemValue(theDialog, kIdleMusicItem, (short)wasIdle); + SetDialogItemValue(theDialog, kPlayMusicItem, (short)wasPlay); + UnivSetSoundVolume(3, thisMac.hasSM3); + SetDialogNumToStr(theDialog, kVolNumberItem, 3L); + HandleSoundMusicChange(3, true); +} + +//-------------------------------------------------------------- UpdateSettingsSound + +void UpdateSettingsSound (DialogPtr theDialog) +{ + short howLoudNow; + + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + + UnivGetSoundVolume(&howLoudNow, thisMac.hasSM3); + + if (howLoudNow >= 7) + SetDialogNumToStr(theDialog, kVolNumberItem, 11L); + else + SetDialogNumToStr(theDialog, kVolNumberItem, (long)howLoudNow); + + FrameDialogItemC(theDialog, 11, kRedOrangeColor8); +} + +//-------------------------------------------------------------- HandleSoundMusicChange + +void HandleSoundMusicChange (short newVolume, Boolean sayIt) +{ + OSErr theErr; + + isSoundOn = (newVolume != 0); + + if (wasIdle) + { + if (newVolume == 0) + StopTheMusic(); + else + { + if (!isMusicOn) + { + theErr = StartMusic(); + if (theErr != noErr) + { + YellowAlert(kYellowNoMusic, theErr); + failedMusic = true; + } + } + } + } + + if ((newVolume != 0) && (sayIt)) + PlayPrioritySound(kChord2Sound, kChord2Priority); +} + +//-------------------------------------------------------------- SoundFilter + +Boolean SoundFilter (DialogPtr dial, EventRecord *event, short *item) +{ + short newVolume; + + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + case kUpArrowKeyASCII: + *item = kLouderItem; + return(true); + break; + + case kDownArrowKeyASCII: + *item = kSofterItem; + return(true); + break; + + case k0KeyASCII: + case k1KeyASCII: + case k2KeyASCII: + case k3KeyASCII: + case k4KeyASCII: + case k5KeyASCII: + case k6KeyASCII: + case k7KeyASCII: + newVolume = (((event->message) & charCodeMask) - k0KeyASCII); + if (newVolume == 7L) + SetDialogNumToStr(dial, kVolNumberItem, 11L); + else + SetDialogNumToStr(dial, kVolNumberItem, (long)newVolume); + + UnivSetSoundVolume(newVolume, thisMac.hasSM3); + + HandleSoundMusicChange(newVolume, true); + return(false); + break; + + case kCapDKeyASCII: + case kDKeyASCII: + *item = kSoundDefault; + FlashDialogButton(dial, kSoundDefault); + return(true); + break; + + case kCapGKeyASCII: + case kGKeyASCII: + *item = kPlayMusicItem; + return(true); + break; + + case kCapIKeyASCII: + case kIKeyASCII: + *item = kIdleMusicItem; + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateSettingsSound(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- DoSettingsMain + +void DoSoundPrefs (void) +{ + Rect tempRect; + DialogPtr prefDlg; + short wasLoudness, tempVolume; + OSErr theErr; + short itemHit; + Boolean leaving; + ModalFilterUPP soundFilterUPP; + + soundFilterUPP = NewModalFilterUPP(SoundFilter); + + BringUpDialog(&prefDlg, kSoundPrefsDialID); + + UnivGetSoundVolume(&wasLoudness, thisMac.hasSM3); + + wasIdle = isPlayMusicIdle; + wasPlay = isPlayMusicGame; + SetDialogItemValue(prefDlg, kIdleMusicItem, (short)wasIdle); + SetDialogItemValue(prefDlg, kPlayMusicItem, (short)wasPlay); + leaving = false; + + while (!leaving) + { + ModalDialog(soundFilterUPP, &itemHit); + switch (itemHit) + { + case kOkayButton: + isPlayMusicIdle = wasIdle; + isPlayMusicGame = wasPlay; + leaving = true; + UnivGetSoundVolume(&tempVolume, thisMac.hasSM3); + isSoundOn = (tempVolume != 0); + break; + + case kCancelButton: + UnivSetSoundVolume(wasLoudness, thisMac.hasSM3); + HandleSoundMusicChange(wasLoudness, false); + if (isPlayMusicIdle != wasIdle) + { + if (isPlayMusicIdle) + { + if (wasLoudness != 0) + { + theErr = StartMusic(); + if (theErr != noErr) + { + YellowAlert(kYellowNoMusic, theErr); + failedMusic = true; + } + } + } + else + StopTheMusic(); + } + leaving = true; + break; + + case kSofterItem: + UnivGetSoundVolume(&tempVolume, thisMac.hasSM3); + if (tempVolume > 0) + { + GetDialogItemRect(prefDlg, kSofterItem, &tempRect); + DrawCIcon(1034, tempRect.left, tempRect.top); + tempVolume--; + SetDialogNumToStr(prefDlg, kVolNumberItem, (long)tempVolume); + UnivSetSoundVolume(tempVolume, thisMac.hasSM3); + HandleSoundMusicChange(tempVolume, true); + InvalWindowRect(GetDialogWindow(prefDlg), &tempRect); + DelayTicks(8); + } + break; + + case kLouderItem: + UnivGetSoundVolume(&tempVolume, thisMac.hasSM3); + if (tempVolume < 7) + { + GetDialogItemRect(prefDlg, kLouderItem, &tempRect); + DrawCIcon(1033, tempRect.left, tempRect.top); + tempVolume++; + if (tempVolume == 7) + SetDialogNumToStr(prefDlg, kVolNumberItem, 11L); + else + SetDialogNumToStr(prefDlg, kVolNumberItem, tempVolume); + UnivSetSoundVolume(tempVolume, thisMac.hasSM3); + HandleSoundMusicChange(tempVolume, true); + InvalWindowRect(GetDialogWindow(prefDlg), &tempRect); + DelayTicks(8); + } + break; + + case kIdleMusicItem: + wasIdle = !wasIdle; + SetDialogItemValue(prefDlg, kIdleMusicItem, (short)wasIdle); + if (wasIdle) + { + UnivGetSoundVolume(&tempVolume, thisMac.hasSM3); + if (tempVolume != 0) + { + theErr = StartMusic(); + if (theErr != noErr) + { + YellowAlert(kYellowNoMusic, theErr); + failedMusic = true; + } + } + } + else + StopTheMusic(); + break; + + case kPlayMusicItem: + wasPlay = !wasPlay; + SetDialogItemValue(prefDlg, kPlayMusicItem, (short)wasPlay); + break; + + case kSoundDefault: + SoundDefaults(prefDlg); + break; + } + } + + DisposeDialog(prefDlg); + DisposeModalFilterUPP(soundFilterUPP); +} + +//-------------------------------------------------------------- DisplayDefaults + +void DisplayDefaults (void) +{ + numNeighbors = 9; + wasDepthPref = kSwitchIfNeeded; + wasFade = true; + wasScreen2 = false; +} + +//-------------------------------------------------------------- FrameDisplayIcon + +void FrameDisplayIcon (DialogPtr theDialog) +{ + Rect theRect; + + switch (numNeighbors) + { + case 1: + GetDialogItemRect(theDialog, kDisplay1Item, &theRect); + break; + + case 3: + GetDialogItemRect(theDialog, kDisplay3Item, &theRect); + break; + + default: + GetDialogItemRect(theDialog, kDisplay9Item, &theRect); + break; + } + + theRect.left -= 3; + theRect.top += 0; + theRect.right += 3; + theRect.bottom -= 1; + FrameRect(&theRect); + InsetRect(&theRect, 1, 1); + FrameRect(&theRect); +} + +//-------------------------------------------------------------- DisplayUpdate + +void DisplayUpdate (DialogPtr theDialog) +{ + DrawDialog(theDialog); + DrawDefaultButton(theDialog); + + SetDialogItemValue(theDialog, kDoColorFadeItem, (short)wasFade); + SelectFromRadioGroup(theDialog, kCurrentDepth + wasDepthPref, + kCurrentDepth, k16Depth); +// SetDialogItemValue(theDialog, kUseQDItem, (short)wasQD); + SetDialogItemValue(theDialog, kUseScreen2Item, (short)wasScreen2); + + ForeColor(redColor); + FrameDisplayIcon(theDialog); + ForeColor(blackColor); + FrameDialogItemC(theDialog, 8, kRedOrangeColor8); + FrameDialogItemC(theDialog, 13, kRedOrangeColor8); + FrameDialogItemC(theDialog, 14, kRedOrangeColor8); +} + +//-------------------------------------------------------------- DisplayFilter + +Boolean DisplayFilter (DialogPtr dial, EventRecord *event, short *item) +{ + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kEscapeKeyASCII: + FlashDialogButton(dial, kCancelButton); + *item = kCancelButton; + return(true); + break; + + case kLeftArrowKeyASCII: + switch (numNeighbors) + { + case 1: + *item = kDisplay9Item; + break; + + case 3: + *item = kDisplay1Item; + break; + + case 9: + *item = kDisplay3Item; + break; + } + return(true); + break; + + case kRightArrowKeyASCII: + switch (numNeighbors) + { + case 1: + *item = kDisplay3Item; + break; + + case 3: + *item = kDisplay9Item; + break; + + case 9: + *item = kDisplay1Item; + break; + } + return(true); + break; + + case kUpArrowKeyASCII: + switch (wasDepthPref) + { + case kSwitchIfNeeded: + *item = k16Depth; + break; + + case kSwitchTo256Colors: + *item = kCurrentDepth; + break; + + case kSwitchTo16Grays: + *item = k256Depth; + break; + } + return(true); + break; + + case kDownArrowKeyASCII: + switch (wasDepthPref) + { + case kSwitchIfNeeded: + *item = k256Depth; + break; + + case kSwitchTo256Colors: + *item = k16Depth; + break; + + case kSwitchTo16Grays: + *item = kCurrentDepth; + break; + } + return(true); + break; + + case k1KeyASCII: + *item = kDisplay1Item; + return(true); + break; + + case k3KeyASCII: + *item = kDisplay3Item; + return(true); + break; + + case k9KeyASCII: + *item = kDisplay9Item; + return(true); + break; + + case kCapBKeyASCII: + case kBKeyASCII: + *item = kDoColorFadeItem; + return(true); + break; + + case kCapDKeyASCII: + case kDKeyASCII: + *item = kDispDefault; + FlashDialogButton(dial, kDispDefault); + return(true); + break; + + case kCapRKeyASCII: + case kRKeyASCII: + *item = kUseScreen2Item; + FlashDialogButton(dial, kUseQDItem); + return(true); + break; + + case kCapUKeyASCII: + case kUKeyASCII: + *item = kUseQDItem; + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + return(false); + break; + + case updateEvt: + SetPort((GrafPtr)dial); + BeginUpdate(GetDialogWindow(dial)); + DisplayUpdate(dial); + EndUpdate(GetDialogWindow(dial)); + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- DoDisplayPrefs + +void DoDisplayPrefs (void) +{ + DialogPtr prefDlg; + short itemHit, wasNeighbors; + Boolean leaving; + ModalFilterUPP displayFilterUPP; + + displayFilterUPP = NewModalFilterUPP(DisplayFilter); + + BringUpDialog(&prefDlg, kDisplayPrefsDialID); + if (!thisMac.can8Bit) + { + MyDisableControl(prefDlg, kDoColorFadeItem); + MyDisableControl(prefDlg, k256Depth); + } + if (!thisMac.can4Bit) + MyDisableControl(prefDlg, k16Depth); + if (thisMac.numScreens < 2) + MyDisableControl(prefDlg, kUseScreen2Item); + wasNeighbors = numNeighbors; + wasFade = isDoColorFade; + wasDepthPref = isDepthPref; + wasScreen2 = isUseSecondScreen; + leaving = false; + + while (!leaving) + { + ModalDialog(displayFilterUPP, &itemHit); + switch (itemHit) + { + case kOkayButton: + isDoColorFade = wasFade; + isDepthPref = wasDepthPref; + if (isUseSecondScreen != wasScreen2) + nextRestartChange = true; + isUseSecondScreen = wasScreen2; + leaving = true; + break; + + case kCancelButton: + numNeighbors = wasNeighbors; + leaving = true; + break; + + case kDisplay1Item: + ForeColor(whiteColor); + FrameDisplayIcon(prefDlg); + numNeighbors = 1; + ForeColor(redColor); + FrameDisplayIcon(prefDlg); + ForeColor(blackColor); + break; + + case kDisplay3Item: + if (thisMac.screen.right > 512) + { + ForeColor(whiteColor); + FrameDisplayIcon(prefDlg); + numNeighbors = 3; + ForeColor(redColor); + FrameDisplayIcon(prefDlg); + ForeColor(blackColor); + } + break; + + case kDisplay9Item: + if (thisMac.screen.right > 512) + { + ForeColor(whiteColor); + FrameDisplayIcon(prefDlg); + numNeighbors = 9; + ForeColor(redColor); + FrameDisplayIcon(prefDlg); + ForeColor(blackColor); + } + break; + + case kDoColorFadeItem: + wasFade = !wasFade; + SetDialogItemValue(prefDlg, kDoColorFadeItem, (short)wasFade); + break; + + case kCurrentDepth: + case k256Depth: + case k16Depth: + wasDepthPref = itemHit - kCurrentDepth; + SelectFromRadioGroup(prefDlg, itemHit, kCurrentDepth, k16Depth); + break; + + case kDispDefault: + ForeColor(whiteColor); + FrameDisplayIcon(prefDlg); + ForeColor(blackColor); + DisplayDefaults(); + DisplayUpdate(prefDlg); + break; + + case kUseQDItem: +// wasQD = !wasQD; +// SetDialogItemValue(prefDlg, kUseQDItem, (short)wasQD); + break; + + case kUseScreen2Item: + wasScreen2 = !wasScreen2; + SetDialogItemValue(prefDlg, kUseScreen2Item, (short)wasScreen2); + break; + } + } + + DisposeDialog(prefDlg); + DisposeModalFilterUPP(displayFilterUPP); +} + +//-------------------------------------------------------------- SetAllDefaults + +void SetAllDefaults (void) +{ + OSErr theErr; + // Default brain settings + willMaxFiles = 48; + doZooms = true; + doAutoDemo = true; + doBackground = false; + isHouseChecks = true; + doPrettyMap = true; + doBitchDialogs = true; + // Default control settings + PasStringCopy(PSTR("lf arrow"), leftName); + PasStringCopy(PSTR("rt arrow"), rightName); + PasStringCopy(PSTR("dn arrow"), batteryName); + PasStringCopy(PSTR("up arrow"), bandName); + theGlider.leftKey = kLeftArrowKeyMap; + theGlider.rightKey = kRightArrowKeyMap; + theGlider.battKey = kDownArrowKeyMap; + theGlider.bandKey = kUpArrowKeyMap; + isEscPauseKey = false; + // Default sound settings + isPlayMusicIdle = true; + isPlayMusicGame = true; + UnivSetSoundVolume(3, thisMac.hasSM3); + isSoundOn = true; + if (!isMusicOn) + { + theErr = StartMusic(); + if (theErr != noErr) + { + YellowAlert(kYellowNoMusic, theErr); + failedMusic = true; + } + } + // Default display settings + numNeighbors = 9; + quickerTransitions = false; + isDepthPref = kSwitchIfNeeded; + isDoColorFade = true; +} + +//-------------------------------------------------------------- FlashSettingsButton + +void FlashSettingsButton (short who) +{ + #define kNormalSettingsIcon 1010 + #define kInvertedSettingsIcon 1014 + short theID; + + theID = kInvertedSettingsIcon + who; + DrawCIcon (theID, prefButton[who].left + 4, prefButton[who].top + 4); + DelayTicks(8); + theID = kNormalSettingsIcon + who; + DrawCIcon (theID, prefButton[who].left + 4, prefButton[who].top + 4); +} + +//-------------------------------------------------------------- UpdateSettingsMain + +void UpdateSettingsMain (DialogPtr theDialog) +{ + Str255 theStr; + + DrawDialog(theDialog); + + DrawDefaultButton(theDialog); + + GetIndString(theStr, 129, 1); + DrawDialogUserText(theDialog, 7, theStr, false); + GetIndString(theStr, 129, 2); + DrawDialogUserText(theDialog, 8, theStr, false); + GetIndString(theStr, 129, 3); + DrawDialogUserText(theDialog, 9, theStr, false); + GetIndString(theStr, 129, 4); + DrawDialogUserText(theDialog, 10, theStr, false); + + ColorFrameRect(&prefButton[0], kRedOrangeColor8); + ColorFrameRect(&prefButton[1], kRedOrangeColor8); + ColorFrameRect(&prefButton[2], kRedOrangeColor8); + ColorFrameRect(&prefButton[3], kRedOrangeColor8); +} + +//-------------------------------------------------------------- PrefsFilter + +Boolean PrefsFilter (DialogPtr dial, EventRecord *event, short *item) +{ + Point testPt; + short i; + Boolean foundHit; + + switch (event->what) + { + case keyDown: + switch ((event->message) & charCodeMask) + { + case kReturnKeyASCII: + case kEnterKeyASCII: + FlashDialogButton(dial, kOkayButton); + *item = kOkayButton; + return(true); + break; + + case kCapBKeyASCII: + case kBKeyASCII: + *item = kBrainsButton; + return(true); + break; + + case kCapCKeyASCII: + case kCKeyASCII: + *item = kControlsButton; + return(true); + break; + + case kCapDKeyASCII: + case kDKeyASCII: + *item = kDisplayButton; + return(true); + break; + + case kCapSKeyASCII: + case kSKeyASCII: + *item = kSoundButton; + return(true); + break; + + default: + return(false); + } + break; + + case mouseDown: + testPt = event->where; + GlobalToLocal(&testPt); + foundHit = false; + for (i = 0; i < 4; i++) + { + if (PtInRect(testPt, &prefButton[i])) + { + *item = kDisplayButton + i; + foundHit = true; + } + } + return(foundHit); + break; + + case updateEvt: + if ((WindowPtr)event->message == (WindowPtr)mainWindow) + { + SetPortWindowPort(mainWindow); + BeginUpdate(mainWindow); + UpdateMainWindow(); + EndUpdate(mainWindow); + SetPort((GrafPtr)dial); + } + else if ((WindowPtr)event->message == GetDialogWindow(dial)) + { + SetPortDialogPort(dial); + BeginUpdate(GetDialogWindow(dial)); + UpdateSettingsMain(dial); + EndUpdate(GetDialogWindow(dial)); + } + event->what = nullEvent; + return(false); + break; + + default: + return(false); + break; + } +} + +//-------------------------------------------------------------- DoSettingsMain + +void DoSettingsMain (void) +{ + #define kAllDefaultsButton 11 + DialogPtr prefDlg; + short itemHit; + Boolean leaving; + ModalFilterUPP prefsFilterUPP; + + prefsFilterUPP = NewModalFilterUPP(PrefsFilter); + + BringUpDialog(&prefDlg, kMainPrefsDialID); + + GetDialogItemRect(prefDlg, kDisplayButton, &prefButton[0]); + InsetRect(&prefButton[0], -4, -4); + GetDialogItemRect(prefDlg, 4, &prefButton[1]); + InsetRect(&prefButton[1], -4, -4); + GetDialogItemRect(prefDlg, 5, &prefButton[2]); + InsetRect(&prefButton[2], -4, -4); + GetDialogItemRect(prefDlg, 6, &prefButton[3]); + InsetRect(&prefButton[3], -4, -4); + + leaving = false; + nextRestartChange = false; + + while (!leaving) + { + ModalDialog(prefsFilterUPP, &itemHit); + switch (itemHit) + { + case kOkayButton: + leaving = true; + break; + + case kDisplayButton: + FlashSettingsButton(0); + DoDisplayPrefs(); + SetPort((GrafPtr)prefDlg); + break; + + case kSoundButton: + FlashSettingsButton(1); + DoSoundPrefs(); + SetPort((GrafPtr)prefDlg); + FlushEvents(everyEvent, 0); + break; + + case kControlsButton: + FlashSettingsButton(2); + DoControlPrefs(); + SetPort((GrafPtr)prefDlg); + break; + + case kBrainsButton: + if ((OptionKeyDown()) && (!houseUnlocked)) + { + houseUnlocked = true; + changeLockStateOfHouse = true; + saveHouseLocked = false; + } + FlashSettingsButton(3); + DoBrainsPrefs(); + SetPort((GrafPtr)prefDlg); + break; + + case kAllDefaultsButton: + SetAllDefaults(); + break; + } + } + + DisposeDialog(prefDlg); + DisposeModalFilterUPP(prefsFilterUPP); + + if (nextRestartChange) + BitchAboutChanges(); +} + +//-------------------------------------------------------------- BitchAboutChanges + +void BitchAboutChanges (void) +{ + #define kChangesEffectAlert 1040 + short hitWhat; + +// CenterAlert(kChangesEffectAlert); + hitWhat = Alert(kChangesEffectAlert, nil); +} + diff --git a/GpApp/Sound.cpp b/GpApp/Sound.cpp new file mode 100644 index 0000000..778a62f --- /dev/null +++ b/GpApp/Sound.cpp @@ -0,0 +1,511 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Sound.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLResources.h" +#include "PLSound.h" +#include "Externs.h" + + +#define kBaseBufferSoundID 1000 +#define kMaxSounds 64 +#define kNoSoundPlaying -1 + + +void CallBack0 (SndChannelPtr, SndCommand *); +void CallBack1 (SndChannelPtr, SndCommand *); +void CallBack2 (SndChannelPtr, SndCommand *); +OSErr LoadBufferSounds (void); +void DumpBufferSounds (void); +OSErr OpenSoundChannels (void); +OSErr CloseSoundChannels (void); + + +SndCallBackUPP callBack0UPP, callBack1UPP, callBack2UPP; +SndChannelPtr channel0, channel1, channel2; +Ptr theSoundData[kMaxSounds]; +short numSoundsLoaded, priority0, priority1, priority2; +short soundPlaying0, soundPlaying1, soundPlaying2; +Boolean soundLoaded[kMaxSounds], dontLoadSounds; +Boolean channelOpen, isSoundOn, failedSound; + + +//============================================================== Functions +//-------------------------------------------------------------- PlayPrioritySound + +void PlayPrioritySound (short which, short priority) +{ + short lowestPriority, whosLowest; + + if (failedSound || dontLoadSounds) + return; + + if ((priority == kTriggerPriority) && + ((priority0 == kTriggerPriority) || + ((priority1 == kTriggerPriority)) || + ((priority2 == kTriggerPriority)))) + return; + + whosLowest = 0; + lowestPriority = priority0; + + if (priority1 < lowestPriority) + { + lowestPriority = priority1; + whosLowest = 1; + } + + if (priority2 < lowestPriority) + { + lowestPriority = priority2; + whosLowest = 2; + } + + if (priority >= lowestPriority) + { + switch (whosLowest) + { + case 0: + PlaySound0(which, priority); + break; + + case 1: + PlaySound1(which, priority); + break; + + case 2: + PlaySound2(which, priority); + break; + } + } +} + +//-------------------------------------------------------------- FlushAnyTriggerPlaying + +void FlushAnyTriggerPlaying (void) +{ + SndCommand theCommand; + OSErr theErr; + + if (priority0 == kTriggerPriority) + { + theCommand.cmd = quietCmd; + theCommand.param1 = 0; + theCommand.param2 = 0; + theErr = SndDoImmediate(channel0, &theCommand); + theCommand.cmd = flushCmd; + theCommand.param1 = 0; + theCommand.param2 = 0; + theErr = SndDoImmediate(channel0, &theCommand); + } + + if (priority1 == kTriggerPriority) + { + theCommand.cmd = quietCmd; + theCommand.param1 = 0; + theCommand.param2 = 0; + theErr = SndDoImmediate(channel1, &theCommand); + theCommand.cmd = flushCmd; + theCommand.param1 = 0; + theCommand.param2 = 0; + theErr = SndDoImmediate(channel1, &theCommand); + } + + if (priority2 == kTriggerPriority) + { + theCommand.cmd = quietCmd; + theCommand.param1 = 0; + theCommand.param2 = 0; + theErr = SndDoImmediate(channel2, &theCommand); + theCommand.cmd = flushCmd; + theCommand.param1 = 0; + theCommand.param2 = 0; + theErr = SndDoImmediate(channel2, &theCommand); + } +} + +//-------------------------------------------------------------- PlaySound0 + +void PlaySound0 (short soundID, short priority) +{ + SndCommand theCommand; + OSErr theErr; + + if (failedSound || dontLoadSounds) + return; + + theErr = noErr; + if (isSoundOn) + { + priority0 = priority; + soundPlaying0 = soundID; + + theCommand.cmd = bufferCmd; + theCommand.param1 = 0; + theCommand.param2 = (intptr_t)(theSoundData[soundID]); + theErr = SndDoImmediate(channel0, &theCommand); + + theCommand.cmd = callBackCmd; + theCommand.param1 = 0; + theCommand.param2 = 0; + theErr = SndDoCommand(channel0, &theCommand, true); + } +} + +//-------------------------------------------------------------- PlaySound1 + +void PlaySound1 (short soundID, short priority) +{ + SndCommand theCommand; + OSErr theErr; + + if (failedSound || dontLoadSounds) + return; + + theErr = noErr; + if (isSoundOn) + { + priority1 = priority; + soundPlaying1 = soundID; + + theCommand.cmd = bufferCmd; + theCommand.param1 = 0; + theCommand.param2 = (intptr_t)(theSoundData[soundID]); + theErr = SndDoImmediate(channel1, &theCommand); + + theCommand.cmd = callBackCmd; + theCommand.param1 = 0; + theCommand.param2 = 0; + theErr = SndDoCommand(channel1, &theCommand, true); + } +} + +//-------------------------------------------------------------- PlaySound2 + +void PlaySound2 (short soundID, short priority) +{ + SndCommand theCommand; + OSErr theErr; + + if (failedSound || dontLoadSounds) + return; + + theErr = noErr; + if (isSoundOn) + { + theCommand.cmd = bufferCmd; + theCommand.param1 = 0; + theCommand.param2 = (intptr_t)(theSoundData[soundID]); + theErr = SndDoImmediate(channel2, &theCommand); + + theCommand.cmd = callBackCmd; + theCommand.param1 = 0; + theCommand.param2 = 0; + theErr = SndDoCommand(channel2, &theCommand, true); + + priority2 = priority; + soundPlaying2 = soundID; + } +} + +//-------------------------------------------------------------- CallBack0 + +void CallBack0 (SndChannelPtr theChannel, SndCommand *theCommand) +{ + priority0 = 0; + soundPlaying0 = kNoSoundPlaying; +} + +//-------------------------------------------------------------- CallBack1 + +void CallBack1 (SndChannelPtr theChannel, SndCommand *theCommand) +{ + priority1 = 0; + soundPlaying1 = kNoSoundPlaying; +} + +//-------------------------------------------------------------- CallBack2 + +void CallBack2 (SndChannelPtr theChannel, SndCommand *theCommand) +{ + priority2 = 0; + soundPlaying2 = kNoSoundPlaying; +} + +//-------------------------------------------------------------- LoadTriggerSound + +OSErr LoadTriggerSound (short soundID) +{ + Handle theSound; + long soundDataSize; + OSErr theErr; + + if ((dontLoadSounds) || (theSoundData[kMaxSounds - 1] != nil)) + theErr = -1; + else + { +// FlushAnyTriggerPlaying(); + + theErr = noErr; + + theSound = GetResource('snd ', soundID); + if (theSound == nil) + { + theErr = -1; + } + else + { + soundDataSize = GetHandleSize(theSound) - 20L; + theSoundData[kMaxSounds - 1] = NewPtr(soundDataSize); + HLock(theSound); + if (theSoundData[kMaxSounds - 1] == nil) + { + ReleaseResource(theSound); + theErr = MemError(); + } + else + { + BlockMove((Ptr)((Byte*)(*theSound) + 20L), theSoundData[kMaxSounds - 1], soundDataSize); + ReleaseResource(theSound); + } + } + } + + return (theErr); +} + +//-------------------------------------------------------------- DumpTriggerSound + +void DumpTriggerSound (void) +{ + if (theSoundData[kMaxSounds - 1] != nil) + DisposePtr(theSoundData[kMaxSounds - 1]); + theSoundData[kMaxSounds - 1] = nil; +} + +//-------------------------------------------------------------- LoadBufferSounds + +OSErr LoadBufferSounds (void) +{ + Handle theSound; + long soundDataSize; + OSErr theErr; + short i; + + theErr = noErr; + + for (i = 0; i < kMaxSounds - 1; i++) + { + theSound = GetResource('snd ', i + kBaseBufferSoundID); + if (theSound == nil) + return (MemError()); + + HLock(theSound); + soundDataSize = GetHandleSize(theSound) - 20L; + HUnlock(theSound); + + theSoundData[i] = NewPtr(soundDataSize); + if (theSoundData[i] == nil) + return (MemError()); + + HLock(theSound); + BlockMove((Ptr)((Byte*)(*theSound) + 20L), theSoundData[i], soundDataSize); + ReleaseResource(theSound); + } + + theSoundData[kMaxSounds - 1] = nil; + + return (theErr); +} + +//-------------------------------------------------------------- DumpBufferSounds + +void DumpBufferSounds (void) +{ + short i; + + for (i = 0; i < kMaxSounds; i++) + { + if (theSoundData[i] != nil) + DisposePtr(theSoundData[i]); + theSoundData[i] = nil; + } +} + +//-------------------------------------------------------------- OpenSoundChannels + +OSErr OpenSoundChannels (void) +{ + OSErr theErr; + + callBack0UPP = NewSndCallBackProc(CallBack0); + callBack1UPP = NewSndCallBackProc(CallBack1); + callBack2UPP = NewSndCallBackProc(CallBack2); + + theErr = noErr; + + if (channelOpen) + return (theErr); + + theErr = SndNewChannel(&channel0, + sampledSynth, initNoInterp + initMono, + (SndCallBackUPP)callBack0UPP); + if (theErr == noErr) + channelOpen = true; + else + return (theErr); + + theErr = SndNewChannel(&channel1, + sampledSynth, initNoInterp + initMono, + (SndCallBackUPP)callBack1UPP); + if (theErr == noErr) + channelOpen = true; + else + return (theErr); + + theErr = SndNewChannel(&channel2, + sampledSynth, initNoInterp + initMono, + (SndCallBackUPP)callBack2UPP); + if (theErr == noErr) + channelOpen = true; + + return (theErr); +} + +//-------------------------------------------------------------- CloseSoundChannels + +OSErr CloseSoundChannels (void) +{ + OSErr theErr; + + theErr = noErr; + + if (!channelOpen) + return (theErr); + + if (channel0 != nil) + theErr = SndDisposeChannel(channel0, true); + channel0 = nil; + + if (channel1 != nil) + theErr = SndDisposeChannel(channel1, true); + channel1 = nil; + + if (channel2 != nil) + theErr = SndDisposeChannel(channel2, true); + channel2 = nil; + + if (theErr == noErr) + channelOpen = false; + + DisposeSndCallBackUPP(callBack0UPP); + DisposeSndCallBackUPP(callBack1UPP); + DisposeSndCallBackUPP(callBack2UPP); + + return (theErr); +} + +//-------------------------------------------------------------- InitSound + +void InitSound (void) +{ + OSErr theErr; + + if (dontLoadSounds) + return; + + failedSound = false; + + channel0 = nil; + channel1 = nil; + channel2 = nil; + + priority0 = 0; + priority1 = 0; + priority2 = 0; + soundPlaying0 = kNoSoundPlaying; + soundPlaying1 = kNoSoundPlaying; + soundPlaying2 = kNoSoundPlaying; + + theErr = LoadBufferSounds(); + if (theErr != noErr) + { + YellowAlert(kYellowFailedSound, theErr); + failedSound = true; + } + + if (!failedSound) + { + theErr = OpenSoundChannels(); + if (theErr != noErr) + { + YellowAlert(kYellowFailedSound, theErr); + failedSound = true; + } + } +} + +//-------------------------------------------------------------- KillSound + +void KillSound (void) +{ + OSErr theErr; + + if (dontLoadSounds) + return; + + DumpBufferSounds(); + theErr = CloseSoundChannels(); +} + +//-------------------------------------------------------------- SoundBytesNeeded + +long SoundBytesNeeded (void) +{ + Handle theSound; + long totalBytes; + short i; + + totalBytes = 0L; + SetResLoad(false); + for (i = 0; i < kMaxSounds - 1; i++) + { + theSound = GetResource('snd ', i + kBaseBufferSoundID); + if (theSound == nil) + { + SetResLoad(true); + return ((long)ResError()); + } + totalBytes += GetMaxResourceSize(theSound); +// ReleaseResource(theSound); + } + SetResLoad(true); + return totalBytes; +} + +//-------------------------------------------------------------- TellHerNoSounds + +void TellHerNoSounds (void) +{ + #define kNoMemForSoundsAlert 1039 + short hitWhat; + +// CenterAlert(kNoMemForSoundsAlert); + hitWhat = Alert(kNoMemForSoundsAlert, nil); +} + +//-------------------------------------------------------------- BitchAboutSM3 + +void BitchAboutSM3 (void) +{ + #define kNoSoundManager3Alert 1030 + short hitWhat; + +// CenterAlert(kNoSoundManager3Alert); + hitWhat = Alert(kNoSoundManager3Alert, nil); +} + diff --git a/GpApp/StringUtils.cpp b/GpApp/StringUtils.cpp new file mode 100644 index 0000000..05c0d36 --- /dev/null +++ b/GpApp/StringUtils.cpp @@ -0,0 +1,304 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// StringUtils.c +//---------------------------------------------------------------------------- +//============================================================================ + +#include "PLPasStr.h" +#include "Externs.h" + +#include + + +//============================================================== Functions +//-------------------------------------------------------------- PasStringCopy +// Given a source string and storage for a second, this functionÉ +// copies from one to the other. It assumes Pascal style strings. + +void PasStringCopy (StringPtr p1, StringPtr p2) +{ + register short stringLength; + + stringLength = *p2++ = *p1++; + while (--stringLength >= 0) + *p2++ = *p1++; +} + +//-------------------------------------------------------------- WhichStringFirst + +// This is a sorting function that handles two Pascal strings. ItÉ +// will return a 1 to indicate the 1st string is "greater", a 1 toÉ +// indicate the 2nd was greater and a 0 to indicate that the stringsÉ +// are equal. + +short WhichStringFirst (StringPtr p1, StringPtr p2) +{ + short smallestLength, seek, greater; + char char1, char2; + Boolean foundIt; + + smallestLength = p1[0]; + if (p2[0] < smallestLength) + smallestLength = p2[0]; + + greater = 0; // neither are greater, they are equal + seek = 1; // start at character #1 + foundIt = false; + do + { + char1 = p1[seek]; // make upper case (if applicable) + if ((char1 > 0x60) && (char1 < 0x7B)) + char1 -= 0x20; + char2 = p2[seek]; // make upper case (if applicable) + if ((char2 > 0x60) && (char2 < 0x7B)) + char2 -= 0x20; + + if (char1 > char2) // first string is greater + { + greater = 1; + foundIt = true; + } + else if (char1 < char2) // second string is greater + { + greater = 2; + foundIt = true; + } + seek++; + if (seek > smallestLength) // we've reached the end of the line + { + if (!foundIt) + { + if (p1[0] < p2[0]) // shortest string wins + greater = 1; + else if (p1[0] > p2[0]) + greater = 2; + } + foundIt = true; + } + } + while (!foundIt); + + return (greater); +} + +//-------------------------------------------------------------- PasStringCopyNum + +// This function copies a specified number of characters from oneÉ +// Pascal string to another. + +void PasStringCopyNum (StringPtr p1, StringPtr p2, short charsToCopy) +{ + short i; + + if (charsToCopy > *p1) // if trying to copy more chars than there are + charsToCopy = *p1; // reduce the number of chars to copy to this size + + *p2 = static_cast(charsToCopy); + + *p2++; + *p1++; + + for (i = 0; i < charsToCopy; i++) + *p2++ = *p1++; +} + +//-------------------------------------------------------------- PasStringConcat +// This function concatenates the second Pascal string to the end ofÉ +// the first Pascal string. + +void PasStringConcat (StringPtr p1, const PLPasStr &p2) +{ + short wasLength, addedLength; + + wasLength = *p1; + if (wasLength > 255) + wasLength = 255; + + addedLength = p2.Length(); + if ((wasLength + addedLength) > 255) + addedLength = 255 - wasLength; + + *p1 = wasLength + addedLength; + + p1 += (1 + wasLength); + + memcpy(p1, p2.Chars(), addedLength); +} + +//-------------------------------------------------------------- GetLineOfText + +// This function walks through a source string and looks for anÉ +// entire line of text. A "line" of text is assumed to be boundedÉ +// by carriage returns. The index variable indicates which lineÉ +// is sought. + +void GetLineOfText (StringPtr srcStr, short index, StringPtr textLine) +{ + short i, srcLength, count, start, stop; + Boolean foundIt; + + PasStringCopy(PSTR(""), textLine); + srcLength = srcStr[0]; + + if (index == 0) // walk through to "index" + start = 1; + else + { + start = 0; + count = 0; + i = 0; + foundIt = false; + do + { + i++; + if (srcStr[i] == kReturnKeyASCII) + { + count++; + if (count == index) + { + start = i + 1; + foundIt = true; + } + } + } + while ((i < srcLength) && (!foundIt)); + } + + if (start != 0) + { + i = start; + + foundIt = false; + do + { + if (srcStr[i] == kReturnKeyASCII) + { + stop = i; + foundIt = true; + } + i++; + } + while ((i < srcLength) && (!foundIt)); + + if (!foundIt) + { + if (start > srcLength) + { + start = srcLength; + stop = srcLength - 1; + } + else + stop = i; + } + + count = 0; + + for (i = start; i <= stop; i++) + { + count++; + textLine[count] = srcStr[i]; + } + textLine[0] = static_cast(count); + } +} + +//-------------------------------------------------------------- WrapText + +// Given a string and the maximum number of characters to put onÉ +// one line, this function goes through and inserts carriage returnsÉ +// in order to ensure that no line of text exceeds maxChars. + +void WrapText (StringPtr theText, short maxChars) +{ + short lastChar, count, chars, spaceIs; + Boolean foundEdge, foundSpace; + + lastChar = theText[0]; + count = 0; + + do + { + chars = 0; + foundEdge = false; + foundSpace = false; + do + { + count++; + chars++; + if (theText[count] == kReturnKeyASCII) + foundEdge = true; + else if (theText[count] == kSpaceBarASCII) + { + foundSpace = true; + spaceIs = count; + } + } + while ((count < lastChar) && (chars < maxChars) && (!foundEdge)); + + if ((!foundEdge) && (count < lastChar) && (foundSpace)) + { + theText[spaceIs] = kReturnKeyASCII; + count = spaceIs + 1; + } + } + while (count < lastChar); +} + +//-------------------------------------------------------------- GetFirstWordOfString + +// Walks a string looking for a space (denoting first word of string). + +void GetFirstWordOfString (StringPtr stringIn, StringPtr stringOut) +{ + short isLong, spaceAt, i; + + isLong = stringIn[0]; + spaceAt = isLong; + + for (i = 1; i < isLong; i++) + { + if ((stringIn[i] == ' ') && (spaceAt == isLong)) + spaceAt = i - 1; + } + + if (spaceAt <= 0) + PasStringCopy(PSTR(""), stringOut); + else + PasStringCopyNum(stringIn, stringOut, spaceAt); +} + +//-------------------------------------------------------------- CollapseStringToWidth + +// Given a string and a maximum width (in pixels), this functionÉ +// calculates how wide the text would be drawn with the currentÉ +// font. If the text would exceed our width limit, charactersÉ +// are dropped off the end of the string and "É" appended. + +void CollapseStringToWidth (StringPtr theStr, short wide) +{ + short dotsWide; + Boolean tooWide; + + dotsWide = StringWidth(PSTR("É")); + tooWide = StringWidth(theStr) > wide; + while (tooWide) + { + theStr[0]--; + tooWide = ((StringWidth(theStr) + dotsWide) > wide); + if (!tooWide) + PasStringConcat(theStr, PSTR("É")); + } +} + +//-------------------------------------------------------------- GetLocalizedString + +StringPtr GetLocalizedString (short index, StringPtr theString) +{ + #define kLocalizedStringsID 150 + + GetIndString(theString, kLocalizedStringsID, index); + return (theString); +} + + diff --git a/GpApp/StructuresInit.cpp b/GpApp/StructuresInit.cpp new file mode 100644 index 0000000..9851222 --- /dev/null +++ b/GpApp/StructuresInit.cpp @@ -0,0 +1,726 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// StructuresInit.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLResources.h" +#include "Externs.h" +#include "Objects.h" +#include "Play.h" +#include "Player.h" +#include "RectUtils.h" +#include "RubberBands.h" +#include "Scoreboard.h" +#include "Utilities.h" + + +#define kShadowPictID 3998 +#define kBlowerPictID 4000 +#define kFurniturePictID 4001 +#define kBonusPictID 4002 +#define kSwitchPictID 4003 +#define kLightPictID 4004 +#define kAppliancePictID 4005 +#define kPointsPictID 4006 +#define kRubberBandsPictID 4007 +#define kTransportPictID 4008 +#define kToastPictID 4009 +#define kShreddedPictID 4010 +#define kBalloonPictID 4011 +#define kCopterPictID 4012 +#define kDartPictID 4013 +#define kBallPictID 4014 +#define kDripPictID 4015 +#define kEnemyPictID 4016 +#define kFishPictID 4017 + +#define kBadgePictID 1996 + + +extern Rect glidSrcRect, leftStartGliderSrc, rightStartGliderSrc; +extern Rect gliderSrc[], shadowSrcRect, shadowSrc[]; +extern Rect bandsSrcRect, bandRects[], boardSrcRect, boardDestRect; +extern Rect boardTSrcRect, boardTDestRect, badgeSrcRect; +extern Rect boardGSrcRect, boardGDestRect, boardPSrcRect, boardPDestRect; +extern Rect boardPQDestRect, boardGQDestRect, badgesBlankRects[]; +extern Rect badgesBadgesRects[], badgesDestRects[]; +extern Rect nailSrcRect, sparkleSrc[]; +extern Rect pointsSrc[], breadSrc[]; +extern short wasScoreboardMode; + + +//============================================================== Functions +//-------------------------------------------------------------- InitScoreboardMap +// Any graphics and structures relating to the scoreboard that appearsÉ +// across the top of the game are initialized and loaded up here. + +void InitScoreboardMap (void) +{ + Rect bounds; + PicHandle thePicture; + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + short hOffset; + + GetGWorld(&wasCPort, &wasWorld); + + wasScoreboardMode = kScoreboardHigh; + boardSrcRect = houseRect; + ZeroRectCorner(&boardSrcRect); + boardSrcRect.bottom = kScoreboardTall; + theErr = CreateOffScreenGWorld(&boardSrcMap, &boardSrcRect, kPreferredDepth); + SetGWorld(boardSrcMap, nil); + + if (boardSrcRect.right >= 640) + hOffset = (RectWide(&boardSrcRect) - kMaxViewWidth) / 2; + else + hOffset = -576; + thePicture = GetPicture(kScoreboardPictID); + if (thePicture == nil) + RedAlert(kErrFailedGraphicLoad); + HLock((Handle)thePicture); + bounds = (*thePicture)->picFrame; + HUnlock((Handle)thePicture); + QOffsetRect(&bounds, -bounds.left, -bounds.top); + QOffsetRect(&bounds, hOffset, 0); + DrawPicture(thePicture, &bounds); + ReleaseResource((Handle)thePicture); + + QSetRect(&badgeSrcRect, 0, 0, 32, 66); // 2144 pixels + theErr = CreateOffScreenGWorld(&badgeSrcMap, &badgeSrcRect, kPreferredDepth); + SetGWorld(badgeSrcMap, nil); + LoadGraphic(kBadgePictID); + + boardDestRect = boardSrcRect; + QOffsetRect(&boardDestRect, 0, -kScoreboardTall); + + hOffset = (RectWide(&houseRect) - 640) / 2; + if (hOffset < 0) + hOffset = -128; + + QSetRect(&boardTSrcRect, 0, 0, 256, 12); // room title + theErr = CreateOffScreenGWorld(&boardTSrcMap, &boardTSrcRect, kPreferredDepth); + SetGWorld(boardTSrcMap, nil); + boardTDestRect = boardTSrcRect; + QOffsetRect(&boardTDestRect, 137 + hOffset, 5); + TextFont(applFont); + TextSize(12); + TextFace(bold); + + QSetRect(&boardGSrcRect, 0, 0, 20, 10); // # gliders + theErr = CreateOffScreenGWorld(&boardGSrcMap, &boardGSrcRect, kPreferredDepth); + SetGWorld(boardGSrcMap, nil); + boardGDestRect = boardGSrcRect; + QOffsetRect(&boardGDestRect, 526 + hOffset, 5); + TextFont(applFont); + TextSize(12); + TextFace(bold); + + QSetRect(&boardPSrcRect, 0, 0, 64, 10); // points + theErr = CreateOffScreenGWorld(&boardPSrcMap, &boardPSrcRect, kPreferredDepth); + SetGWorld(boardPSrcMap, nil); + boardPDestRect = boardPSrcRect; + QOffsetRect(&boardPDestRect, 570 + hOffset, 5); // total = 6396 pixels + boardPQDestRect = boardPDestRect; + QOffsetRect(&boardPQDestRect, 0, -kScoreboardTall); + boardGQDestRect = boardGDestRect; + QOffsetRect(&boardGQDestRect, 0, -kScoreboardTall); + TextFont(applFont); + TextSize(12); + TextFace(bold); + + QSetRect(&badgesBlankRects[0], 0, 0, 16, 16); // foil + QOffsetRect(&badgesBlankRects[0], 0, 0); + QSetRect(&badgesBlankRects[1], 0, 0, 16, 16); // rubber bands + QOffsetRect(&badgesBlankRects[1], 0, 16); + QSetRect(&badgesBlankRects[2], 0, 0, 16, 17); // battery + QOffsetRect(&badgesBlankRects[2], 0, 32); + QSetRect(&badgesBlankRects[3], 0, 0, 16, 17); // helium + QOffsetRect(&badgesBlankRects[3], 0, 49); + + QSetRect(&badgesBadgesRects[0], 0, 0, 16, 16); // foil + QOffsetRect(&badgesBadgesRects[0], 16, 0); + QSetRect(&badgesBadgesRects[1], 0, 0, 16, 16); // rubber bands + QOffsetRect(&badgesBadgesRects[1], 16, 16); + QSetRect(&badgesBadgesRects[2], 0, 0, 16, 17); // battery + QOffsetRect(&badgesBadgesRects[2], 16, 32); + QSetRect(&badgesBadgesRects[3], 0, 0, 16, 17); // helium + QOffsetRect(&badgesBadgesRects[3], 16, 49); + + QSetRect(&badgesDestRects[0], 0, 0, 16, 16); // foil + QOffsetRect(&badgesDestRects[0], 432 + hOffset, 2 - kScoreboardTall); + QSetRect(&badgesDestRects[1], 0, 0, 16, 16); // rubber bands + QOffsetRect(&badgesDestRects[1], 449 + hOffset, 2 - kScoreboardTall); + QSetRect(&badgesDestRects[2], 0, 0, 16, 17); // battery + QOffsetRect(&badgesDestRects[2], 467 + hOffset, 1 - kScoreboardTall); + QSetRect(&badgesDestRects[3], 0, 0, 16, 17); // helium + QOffsetRect(&badgesDestRects[3], 467 + hOffset, 1 - kScoreboardTall); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitGliderMap +// Graphics and structures relating to the little paper glider (theÉ +// player) are cretaed, loaded up and initialized here. + +void InitGliderMap (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + short i; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&glidSrcRect, 0, 0, kGliderWide, 668); // 32112 pixels + theErr = CreateOffScreenGWorld(&glidSrcMap, &glidSrcRect, kPreferredDepth); + SetGWorld(glidSrcMap, nil); + LoadGraphic(kGliderPictID); + + theErr = CreateOffScreenGWorld(&glid2SrcMap, &glidSrcRect, kPreferredDepth); + SetGWorld(glid2SrcMap, nil); + LoadGraphic(kGlider2PictID); + + theErr = CreateOffScreenGWorld(&glidMaskMap, &glidSrcRect, 1); + SetGWorld(glidMaskMap, nil); + LoadGraphic(kGliderPictID + 1000); + + for (i = 0; i <= 20; i++) + { + QSetRect(&gliderSrc[i], 0, 0, kGliderWide, kGliderHigh); + QOffsetRect(&gliderSrc[i], 0, kGliderHigh * i); + } + for (i = 21; i <= 28; i++) + { + QSetRect(&gliderSrc[i], 0, 0, kGliderWide, kGliderBurningHigh); + QOffsetRect(&gliderSrc[i], 0, 420 + (kGliderBurningHigh * (i - 21))); + } + + QSetRect(&gliderSrc[29], 0, 0, kGliderWide, kGliderHigh); + QOffsetRect(&gliderSrc[29], 0, 628); + QSetRect(&gliderSrc[30], 0, 0, kGliderWide, kGliderHigh); + QOffsetRect(&gliderSrc[30], 0, 648); + + QSetRect(&shadowSrcRect, 0, 0, kGliderWide, kShadowHigh * kNumShadowSrcRects); + theErr = CreateOffScreenGWorld(&shadowSrcMap, &shadowSrcRect, kPreferredDepth); + SetGWorld(shadowSrcMap, nil); + LoadGraphic(kShadowPictID); + + theErr = CreateOffScreenGWorld(&shadowMaskMap, &shadowSrcRect, 1); + SetGWorld(shadowMaskMap, nil); + LoadGraphic(kShadowPictID + 1000); + + for (i = 0; i < kNumShadowSrcRects; i++) + { + QSetRect(&shadowSrc[i], 0, 0, kGliderWide, kShadowHigh); + QOffsetRect(&shadowSrc[i], 0, kShadowHigh * i); + } + + QSetRect(&bandsSrcRect, 0, 0, 16, 18); // 304 pixels + theErr = CreateOffScreenGWorld(&bandsSrcMap, &bandsSrcRect, kPreferredDepth); + SetGWorld(bandsSrcMap, nil); + LoadGraphic(kRubberBandsPictID); + + theErr = CreateOffScreenGWorld(&bandsMaskMap, &bandsSrcRect, 1); + SetGWorld(bandsMaskMap, nil); + LoadGraphic(kRubberBandsPictID + 1000); + + for (i = 0; i < 3; i++) + { + QSetRect(&bandRects[i], 0, 0, 16, 6); + QOffsetRect(&bandRects[i], 0, 6 * i); + } + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitBlowers +// All blower graphics and structures are loaded up and initialized here. +// Blowers include vents, ducts, candles, fans, etc. + +void InitBlowers (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + short i; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&blowerSrcRect, 0, 0, 48, 402); // 19344 pixels + theErr = CreateOffScreenGWorld(&blowerSrcMap, &blowerSrcRect, kPreferredDepth); + SetGWorld(blowerSrcMap, nil); + LoadGraphic(kBlowerPictID); + + theErr = CreateOffScreenGWorld(&blowerMaskMap, &blowerSrcRect, 1); + SetGWorld(blowerMaskMap, nil); + LoadGraphic(kBlowerPictID + 1000); + + for (i = 0; i < kNumCandleFlames; i++) + { + QSetRect(&flame[i], 0, 0, 16, 15); + QOffsetRect(&flame[i], 32, 179 + (i * 15)); + } + + for (i = 0; i < kNumTikiFlames; i++) + { + QSetRect(&tikiFlame[i], 0, 0, 8, 10); + QOffsetRect(&tikiFlame[i], 40, 69 + (i * 10)); + } + + for (i = 0; i < kNumBBQCoals; i++) + { + QSetRect(&coals[i], 0, 0, 32, 9); + QOffsetRect(&coals[i], 0, 304 + (i * 9)); + } + + QSetRect(&leftStartGliderSrc, 0, 0, 48, 16); + QOffsetRect(&leftStartGliderSrc, 0, 358); + + QSetRect(&rightStartGliderSrc, 0, 0, 48, 16); + QOffsetRect(&rightStartGliderSrc, 0, 374); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitFurniture +// Structures and graphics relating to the furniture is loaded up. +// Furniture includes tables, cabinets, shelves, etc. + +void InitFurniture (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&furnitureSrcRect, 0, 0, 64, 278); // 17856 pixels + theErr = CreateOffScreenGWorld(&furnitureSrcMap, &furnitureSrcRect, kPreferredDepth); + SetGWorld(furnitureSrcMap, nil); + LoadGraphic(kFurniturePictID); + + theErr = CreateOffScreenGWorld(&furnitureMaskMap, &furnitureSrcRect, 1); + SetGWorld(furnitureMaskMap, nil); + LoadGraphic(kFurniturePictID + 1000); + + QSetRect(&tableSrc, 0, 0, 64, 22); + QOffsetRect(&tableSrc, 0, 0); + + QSetRect(&shelfSrc, 0, 0, 16, 21); + QOffsetRect(&shelfSrc, 0, 22); + + QSetRect(&hingeSrc, 0, 0, 4, 16); + QOffsetRect(&hingeSrc, 16, 22); + + QSetRect(&handleSrc, 0, 0, 4, 21); + QOffsetRect(&handleSrc, 20, 22); + + QSetRect(&knobSrc, 0, 0, 8, 8); + QOffsetRect(&knobSrc, 24, 22); + + QSetRect(&leftFootSrc, 0, 0, 16, 16); + QOffsetRect(&leftFootSrc, 32, 22); + + QSetRect(&rightFootSrc, 0, 0, 16, 16); + QOffsetRect(&rightFootSrc, 48, 22); + + QSetRect(&deckSrc, 0, 0, 64, 21); + QOffsetRect(&deckSrc, 0, 162); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitPrizes +// Structures and graphics relating to the prizes (bonuses) are loaded up. +// Prizes includes clocks, rubber bands, extra gliders, etc. + +void InitPrizes (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + short i; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&bonusSrcRect, 0, 0, 88, 378); // 33264 pixels + theErr = CreateOffScreenGWorld(&bonusSrcMap, &bonusSrcRect, kPreferredDepth); + SetGWorld(bonusSrcMap, nil); + LoadGraphic(kBonusPictID); + + theErr = CreateOffScreenGWorld(&bonusMaskMap, &bonusSrcRect, 1); + SetGWorld(bonusMaskMap, nil); + LoadGraphic(kBonusPictID + 1000); + + for (i = 0; i < 11; i++) + { + QSetRect(&digits[i], 0, 0, 4, 6); + QOffsetRect(&digits[i], 28, i * 6); + } + + for (i = 0; i < 3; i++) + { + QSetRect(&pendulumSrc[i], 0, 0, 32, 28); + QOffsetRect(&pendulumSrc[i], 56, 186 + (i * 28)); + } + + QSetRect(&greaseSrcRt[0], 0, 0, 32, 27); + QOffsetRect(&greaseSrcRt[0], 0, 243); + QSetRect(&greaseSrcRt[1], 0, 0, 32, 27); + QOffsetRect(&greaseSrcRt[1], 0, 270); + QSetRect(&greaseSrcRt[2], 0, 0, 32, 27); + QOffsetRect(&greaseSrcRt[2], 0, 297); + QSetRect(&greaseSrcRt[3], 0, 0, 32, 27); + QOffsetRect(&greaseSrcRt[3], 32, 297); + + QSetRect(&greaseSrcLf[0], 0, 0, 32, 27); + QOffsetRect(&greaseSrcLf[0], 0, 324); + QSetRect(&greaseSrcLf[1], 0, 0, 32, 27); + QOffsetRect(&greaseSrcLf[1], 32, 324); + QSetRect(&greaseSrcLf[2], 0, 0, 32, 27); + QOffsetRect(&greaseSrcLf[2], 0, 351); + QSetRect(&greaseSrcLf[3], 0, 0, 32, 27); + QOffsetRect(&greaseSrcLf[3], 32, 351); + + for (i = 0; i < 6; i++) + { + QSetRect(&starSrc[i], 0, 0, 32, 31); + QOffsetRect(&starSrc[i], 48, i * 31); + } + + for (i = 0; i < 3; i++) + { + QSetRect(&sparkleSrc[i + 2], 0, 0, 20, 19); + QOffsetRect(&sparkleSrc[i + 2], 0, 70 + (i * 19)); + } + sparkleSrc[0] = sparkleSrc[4]; + sparkleSrc[1] = sparkleSrc[3]; + + QSetRect(&pointsSrcRect, 0, 0, 24, 120); // 2880 pixels + theErr = CreateOffScreenGWorld(&pointsSrcMap, &pointsSrcRect, kPreferredDepth); + SetGWorld(pointsSrcMap, nil); + LoadGraphic(kPointsPictID); + + theErr = CreateOffScreenGWorld(&pointsMaskMap, &pointsSrcRect, 1); + SetGWorld(pointsMaskMap, nil); + LoadGraphic(kPointsPictID + 1000); + + for (i = 0; i < 15; i++) + { + QSetRect(&pointsSrc[i], 0, 0, 24, 8); + QOffsetRect(&pointsSrc[i], 0, i * 8); + } + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitTransports +// Structures and graphics relating to the transports is loaded up. +// Transports includes transport ducts, mailboxes, etc. + +void InitTransports (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); // GlidePort: this line was missing? + + QSetRect(&transSrcRect, 0, 0, 56, 32); // 1848 pixels + theErr = CreateOffScreenGWorld(&transSrcMap, &transSrcRect, kPreferredDepth); + SetGWorld(transSrcMap, nil); + LoadGraphic(kTransportPictID); + + theErr = CreateOffScreenGWorld(&transMaskMap, &transSrcRect, 1); + SetGWorld(transMaskMap, nil); + LoadGraphic(kTransportPictID + 1000); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitSwitches +// Structures and graphics relating to switches are loaded up. +// Switches includes triggers, light switches, etc. + +void InitSwitches (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&switchSrcRect, 0, 0, 32, 104); // 3360 pixels + theErr = CreateOffScreenGWorld(&switchSrcMap, &switchSrcRect, kPreferredDepth); + SetGWorld(switchSrcMap, nil); + LoadGraphic(kSwitchPictID); + + QSetRect(&lightSwitchSrc[0], 0, 0, 15, 24); + QOffsetRect(&lightSwitchSrc[0], 0, 0); + QSetRect(&lightSwitchSrc[1], 0, 0, 15, 24); + QOffsetRect(&lightSwitchSrc[1], 16, 0); + + QSetRect(&machineSwitchSrc[0], 0, 0, 16, 24); + QOffsetRect(&machineSwitchSrc[0], 0, 24); + QSetRect(&machineSwitchSrc[1], 0, 0, 16, 24); + QOffsetRect(&machineSwitchSrc[1], 16, 24); + + QSetRect(&thermostatSrc[0], 0, 0, 15, 24); + QOffsetRect(&thermostatSrc[0], 0, 48); + QSetRect(&thermostatSrc[1], 0, 0, 15, 24); + QOffsetRect(&thermostatSrc[1], 16, 48); + + QSetRect(&powerSrc[0], 0, 0, 8, 8); + QOffsetRect(&powerSrc[0], 0, 72); + QSetRect(&powerSrc[1], 0, 0, 8, 8); + QOffsetRect(&powerSrc[1], 8, 72); + + QSetRect(&knifeSwitchSrc[0], 0, 0, 16, 24); + QOffsetRect(&knifeSwitchSrc[0], 0, 80); + QSetRect(&knifeSwitchSrc[1], 0, 0, 16, 24); + QOffsetRect(&knifeSwitchSrc[1], 16, 80); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitLights +// Structures and graphics relating to lights are loaded up. +// Lights includes table lamps, flourescent lights, track lights, etc. + +void InitLights (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + short i; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&lightSrcRect, 0, 0, 72, 126); // 9144 pixels + theErr = CreateOffScreenGWorld(&lightSrcMap, &lightSrcRect, kPreferredDepth); + SetGWorld(lightSrcMap, nil); + LoadGraphic(kLightPictID); + + theErr = CreateOffScreenGWorld(&lightMaskMap, &lightSrcRect, 1); + SetGWorld(lightMaskMap, nil); + LoadGraphic(kLightPictID + 1000); + + QSetRect(&flourescentSrc1, 0, 0, 16, 12); + QOffsetRect(&flourescentSrc1, 0, 78); + + QSetRect(&flourescentSrc2, 0, 0, 16, 12); + QOffsetRect(&flourescentSrc2, 0, 90); + + for (i = 0; i < kNumTrackLights; i++) + { + QSetRect(&trackLightSrc[i], 0, 0, 24, 24); + QOffsetRect(&trackLightSrc[i], 24 * i, 102); + } + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitAppliances +// Structures and graphics relating to appliances are loaded up. +// Appliances includes toasters, T.V.s, etc. + +void InitAppliances (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + short i; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&applianceSrcRect, 0, 0, 80, 269); // 21600 pixels + theErr = CreateOffScreenGWorld(&applianceSrcMap, &applianceSrcRect, kPreferredDepth); + SetGWorld(applianceSrcMap, nil); + LoadGraphic(kAppliancePictID); + + theErr = CreateOffScreenGWorld(&applianceMaskMap, &applianceSrcRect, 1); + SetGWorld(applianceMaskMap, nil); + LoadGraphic(kAppliancePictID + 1000); + + QSetRect(&toastSrcRect, 0, 0, 32, 174); // 5600 pixels + theErr = CreateOffScreenGWorld(&toastSrcMap, &toastSrcRect, kPreferredDepth); + SetGWorld(toastSrcMap, nil); + LoadGraphic(kToastPictID); + + theErr = CreateOffScreenGWorld(&toastMaskMap, &toastSrcRect, 1); + SetGWorld(toastMaskMap, nil); + LoadGraphic(kToastPictID + 1000); + + QSetRect(&shredSrcRect, 0, 0, 40, 35); // 1440 pixels + theErr = CreateOffScreenGWorld(&shredSrcMap, &shredSrcRect, kPreferredDepth); + SetGWorld(shredSrcMap, nil); + LoadGraphic(kShreddedPictID); + + theErr = CreateOffScreenGWorld(&shredMaskMap, &shredSrcRect, 1); + SetGWorld(shredMaskMap, nil); + LoadGraphic(kShreddedPictID + 1000); + + QSetRect(&plusScreen1, 0, 0, 32, 22); + QOffsetRect(&plusScreen1, 48, 127); + QSetRect(&plusScreen2, 0, 0, 32, 22); + QOffsetRect(&plusScreen2, 48, 149); + + QSetRect(&tvScreen1, 0, 0, 64, 49); + QOffsetRect(&tvScreen1, 0, 171); + QSetRect(&tvScreen2, 0, 0, 64, 49); + QOffsetRect(&tvScreen2, 0, 220); + + QSetRect(&coffeeLight1, 0, 0, 8, 4); + QOffsetRect(&coffeeLight1, 72, 171); + QSetRect(&coffeeLight2, 0, 0, 8, 4); + QOffsetRect(&coffeeLight2, 72, 175); + + for (i = 0; i < kNumOutletPicts; i++) + { + QSetRect(&outletSrc[i], 0, 0, 16, 24); + QOffsetRect(&outletSrc[i], 64, 22 + (i * 24)); + } + + for (i = 0; i < kNumBreadPicts; i++) + { + QSetRect(&breadSrc[i], 0, 0, 32, 29); + QOffsetRect(&breadSrc[i], 0, i * 29); + } + + QSetRect(&vcrTime1, 0, 0, 16, 4); + QOffsetRect(&vcrTime1, 64, 179); + QSetRect(&vcrTime2, 0, 0, 16, 4); + QOffsetRect(&vcrTime2, 64, 183); + + QSetRect(&stereoLight1, 0, 0, 4, 1); + QOffsetRect(&stereoLight1, 68, 171); + QSetRect(&stereoLight2, 0, 0, 4, 1); + QOffsetRect(&stereoLight2, 68, 172); + + QSetRect(µOn, 0, 0, 16, 35); + QOffsetRect(µOn, 64, 222); + QSetRect(µOff, 0, 0, 16, 35); + QOffsetRect(µOff, 64, 187); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitEnemies +// Structures and graphics relating to enemies are loaded up. +// Enemies includes darts, balloons, fish, etc. + +void InitEnemies (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + short i; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&balloonSrcRect, 0, 0, 24, 30 * kNumBalloonFrames); + theErr = CreateOffScreenGWorld(&balloonSrcMap, &balloonSrcRect, kPreferredDepth); + SetGWorld(balloonSrcMap, nil); + LoadGraphic(kBalloonPictID); + + theErr = CreateOffScreenGWorld(&balloonMaskMap, &balloonSrcRect, 1); + SetGWorld(balloonMaskMap, nil); + LoadGraphic(kBalloonPictID + 1000); + + QSetRect(&copterSrcRect, 0, 0, 32, 30 * kNumCopterFrames); + theErr = CreateOffScreenGWorld(&copterSrcMap, &copterSrcRect, kPreferredDepth); + SetGWorld(copterSrcMap, nil); + LoadGraphic(kCopterPictID); + + theErr = CreateOffScreenGWorld(&copterMaskMap, &copterSrcRect, 1); + SetGWorld(copterMaskMap, nil); + LoadGraphic(kCopterPictID + 1000); + + QSetRect(&dartSrcRect, 0, 0, 64, 19 * kNumDartFrames); + theErr = CreateOffScreenGWorld(&dartSrcMap, &dartSrcRect, kPreferredDepth); + SetGWorld(dartSrcMap, nil); + LoadGraphic(kDartPictID); + + theErr = CreateOffScreenGWorld(&dartMaskMap, &dartSrcRect, 1); + SetGWorld(dartMaskMap, nil); + LoadGraphic(kDartPictID + 1000); + + QSetRect(&ballSrcRect, 0, 0, 32, 32 * kNumBallFrames); + theErr = CreateOffScreenGWorld(&ballSrcMap, &ballSrcRect, kPreferredDepth); + SetGWorld(ballSrcMap, nil); + LoadGraphic(kBallPictID); + + theErr = CreateOffScreenGWorld(&ballMaskMap, &ballSrcRect, 1); + SetGWorld(ballMaskMap, nil); + LoadGraphic(kBallPictID + 1000); + + QSetRect(&dripSrcRect, 0, 0, 16, 12 * kNumDripFrames); + theErr = CreateOffScreenGWorld(&dripSrcMap, &dripSrcRect, kPreferredDepth); + SetGWorld(dripSrcMap, nil); + LoadGraphic(kDripPictID); + + theErr = CreateOffScreenGWorld(&dripMaskMap, &dripSrcRect, 1); + SetGWorld(dripMaskMap, nil); + LoadGraphic(kDripPictID + 1000); + + QSetRect(&enemySrcRect, 0, 0, 36, 33); + theErr = CreateOffScreenGWorld(&enemySrcMap, &enemySrcRect, kPreferredDepth); + SetGWorld(enemySrcMap, nil); + LoadGraphic(kEnemyPictID); + + theErr = CreateOffScreenGWorld(&enemyMaskMap, &enemySrcRect, 1); + SetGWorld(enemyMaskMap, nil); + LoadGraphic(kEnemyPictID + 1000); + + QSetRect(&fishSrcRect, 0, 0, 16, 16 * kNumFishFrames); + theErr = CreateOffScreenGWorld(&fishSrcMap, &fishSrcRect, kPreferredDepth); + SetGWorld(fishSrcMap, nil); + LoadGraphic(kFishPictID); + + theErr = CreateOffScreenGWorld(&fishMaskMap, &fishSrcRect, 1); + SetGWorld(fishMaskMap, nil); + LoadGraphic(kFishPictID + 1000); + + for (i = 0; i < kNumBalloonFrames; i++) + { + QSetRect(&balloonSrc[i], 0, 0, 24, 30); + QOffsetRect(&balloonSrc[i], 0, 30 * i); + } + + for (i = 0; i < kNumCopterFrames; i++) + { + QSetRect(&copterSrc[i], 0, 0, 32, 30); + QOffsetRect(&copterSrc[i], 0, 30 * i); + } + + for (i = 0; i < kNumDartFrames; i++) + { + QSetRect(&dartSrc[i], 0, 0, 64, 19); + QOffsetRect(&dartSrc[i], 0, 19 * i); + } + + for (i = 0; i < kNumBallFrames; i++) + { + QSetRect(&ballSrc[i], 0, 0, 32, 32); + QOffsetRect(&ballSrc[i], 0, 32 * i); + } + + for (i = 0; i < kNumDripFrames; i++) + { + QSetRect(&dripSrc[i], 0, 0, 16, 12); + QOffsetRect(&dripSrc[i], 0, 12 * i); + } + + for (i = 0; i < kNumFishFrames; i++) + { + QSetRect(&fishSrc[i], 0, 0, 16, 16); + QOffsetRect(&fishSrc[i], 0, 16 * i); + } + + SetGWorld(wasCPort, wasWorld); +} + diff --git a/GpApp/StructuresInit2.cpp b/GpApp/StructuresInit2.cpp new file mode 100644 index 0000000..81e9f39 --- /dev/null +++ b/GpApp/StructuresInit2.cpp @@ -0,0 +1,477 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// StructuresInit2.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLResources.h" +#include "Externs.h" +#include "Environ.h" +#include "GameOver.h" +#include "MainWindow.h" +#include "Objects.h" +#include "RectUtils.h" +#include "Room.h" +#include "RoomGraphics.h" +#include "Utilities.h" + + +#define kAngelPictID 1019 +#define kSupportPictID 1999 +#define kClutterPictID 4018 + + +void InitClutter (void); +void InitSupport (void); +void InitAngel (void); + + +extern Rect suppSrcRect, justRoomsRect; +extern Rect tileSrcRect, angelSrcRect; +extern GDHandle thisGDevice; +extern CGrafPtr tileSrcMap; +extern FSSpecPtr theHousesSpecs; +extern hotPtr hotSpots; +extern sparklePtr sparkles; +extern flyingPtPtr flyingPoints; +extern flamePtr flames, tikiFlames, bbqCoals; +extern pendulumPtr pendulums; +extern bandPtr bands; +extern greasePtr grease; +extern starPtr theStars; +extern shredPtr shreds; +extern dynaPtr dinahs; +extern demoPtr demoData; +extern short maxFiles; + + +//============================================================== Functions +//-------------------------------------------------------------- InitClutter +// Structures and graphics relating to clutter are loaded up. +// Clutter includes mirrors, teddy bears, fireplaces, calendars, etc. + +void InitClutter (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&clutterSrcRect, 0, 0, 128, 69); + theErr = CreateOffScreenGWorld(&clutterSrcMap, &clutterSrcRect, kPreferredDepth); + SetGWorld(clutterSrcMap, nil); + LoadGraphic(kClutterPictID); + + theErr = CreateOffScreenGWorld(&clutterMaskMap, &clutterSrcRect, 1); + SetGWorld(clutterMaskMap, nil); + LoadGraphic(kClutterPictID + 1000); + + QSetRect(&flowerSrc[0], 0, 0, 10, 28); + QOffsetRect(&flowerSrc[0], 0, 23); + + QSetRect(&flowerSrc[1], 0, 0, 24, 35); + QOffsetRect(&flowerSrc[1], 10, 16); + + QSetRect(&flowerSrc[2], 0, 0, 34, 35); + QOffsetRect(&flowerSrc[2], 34, 16); + + QSetRect(&flowerSrc[3], 0, 0, 27, 23); + QOffsetRect(&flowerSrc[3], 68, 14); + + QSetRect(&flowerSrc[4], 0, 0, 27, 14); + QOffsetRect(&flowerSrc[4], 68, 37); + + QSetRect(&flowerSrc[5], 0, 0, 32, 51); + QOffsetRect(&flowerSrc[5], 95, 0); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitSupport +// The floor support grphic is loaded up. It is only visible whenÉ +// playing in 9-room mode. It is the horizontal wooden beam thatÉ +// seperates floors from one another. + +void InitSupport (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&suppSrcRect, 0, 0, kRoomWide, kFloorSupportTall); // 44 + theErr = CreateOffScreenGWorld(&suppSrcMap, &suppSrcRect, kPreferredDepth); + SetGWorld(suppSrcMap, nil); + LoadGraphic(kSupportPictID); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- InitAngel +// This loads the graphic of the girl riding the glider. It is seenÉ +// only upon completing a house. She flies across the screen droppingÉ +// stars below. + +void InitAngel (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&angelSrcRect, 0, 0, 96, 44); + theErr = CreateOffScreenGWorld(&angelSrcMap, &angelSrcRect, kPreferredDepth); + SetGWorld(angelSrcMap, nil); + LoadGraphic(kAngelPictID); + + theErr = CreateOffScreenGWorld(&angelMaskMap, &angelSrcRect, 1); + SetGWorld(angelMaskMap, nil); + LoadGraphic(kAngelPictID + 1); + + SetGWorld(wasCPort, wasWorld); +} + +//-------------------------------------------------------------- CreateOffscreens +// All "utility" or "work" offscreen pix/bit maps are created here. +// These would be offscreens that are reused throughout a game - theyÉ +// are not static (mere repositories for graphics). Most are usedÉ +// to facilitate the animation when a game is in progress. + +void CreateOffscreens (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + GetGWorld(&wasCPort, &wasWorld); + + justRoomsRect = houseRect; + ZeroRectCorner(&justRoomsRect); + + workSrcRect = houseRect; // Set up work map + ZeroRectCorner(&workSrcRect); + theErr = CreateOffScreenGWorld(&workSrcMap, &workSrcRect, kPreferredDepth); + + backSrcRect = houseRect; // Set up background map + ZeroRectCorner(&backSrcRect); + theErr = CreateOffScreenGWorld(&backSrcMap, &backSrcRect, kPreferredDepth); + + InitScoreboardMap(); SpinCursor(1); + InitGliderMap(); SpinCursor(1); + InitBlowers(); SpinCursor(1); + InitFurniture(); SpinCursor(1); + InitPrizes(); SpinCursor(1); + InitTransports(); SpinCursor(1); + InitSwitches(); SpinCursor(1); + InitLights(); SpinCursor(1); + InitAppliances(); SpinCursor(1); + InitEnemies(); SpinCursor(1); + InitClutter(); SpinCursor(1); + InitSupport(); SpinCursor(1); + InitAngel(); SpinCursor(1); + + QSetRect(&tileSrcRect, 0, 0, 128, 80); + tileSrcMap = nil; +// ???? +} + +//-------------------------------------------------------------- CreatePointers +// This function allocates other large structures. Pointers to holdÉ +// large arrays, etc. + +void CreatePointers (void) +{ + Handle tempHandle; + + thisRoom = nil; + thisRoom = (roomPtr)NewPtr(sizeof(roomType)); + if (thisRoom == nil) + RedAlert(kErrNoMemory); + + hotSpots = nil; + hotSpots = (hotPtr)NewPtr(sizeof(hotObject) * kMaxHotSpots); + if (hotSpots == nil) + RedAlert(kErrNoMemory); + + sparkles = nil; + sparkles = (sparklePtr)NewPtr(sizeof(sparkleType) * kMaxSparkles); + if (sparkles == nil) + RedAlert(kErrNoMemory); + + flyingPoints = nil; + flyingPoints = (flyingPtPtr)NewPtr(sizeof(flyingPtType) * kMaxFlyingPts); + if (flyingPoints == nil) + RedAlert(kErrNoMemory); + + flames = nil; + flames = (flamePtr)NewPtr(sizeof(flameType) * kMaxCandles); + if (flames == nil) + RedAlert(kErrNoMemory); + + tikiFlames = nil; + tikiFlames = (flamePtr)NewPtr(sizeof(flameType) * kMaxTikis); + if (tikiFlames == nil) + RedAlert(kErrNoMemory); + + bbqCoals = nil; + bbqCoals = (flamePtr)NewPtr(sizeof(flameType) * kMaxCoals); + if (bbqCoals == nil) + RedAlert(kErrNoMemory); + + pendulums = nil; + pendulums = (pendulumPtr)NewPtr(sizeof(pendulumType) * kMaxPendulums); + if (pendulums == nil) + RedAlert(kErrNoMemory); + + // GlidePort: This is broken code, savedMaps is a flat buffer + /* + savedMaps = nil; + savedMaps = (savedPtr)NewPtr(sizeof(savedType) * kMaxSavedMaps); + if (savedMaps == nil) + RedAlert(kErrNoMemory); + + for (i = 0; i < kMaxSavedMaps; i++) + savedMaps[i].map = nil; + */ + + bands = nil; + bands = (bandPtr)NewPtr(sizeof(bandType) * kMaxRubberBands); + if (bands == nil) + RedAlert(kErrNoMemory); + + grease = nil; + grease = (greasePtr)NewPtr(sizeof(greaseType) * kMaxGrease); + if (grease == nil) + RedAlert(kErrNoMemory); + + theStars = nil; + theStars = (starPtr)NewPtr(sizeof(starType) * kMaxStars); + if (theStars == nil) + RedAlert(kErrNoMemory); + + shreds = nil; + shreds = (shredPtr)NewPtr(sizeof(shredType) * kMaxShredded); + if (shreds == nil) + RedAlert(kErrNoMemory); + + dinahs = nil; + dinahs = (dynaPtr)NewPtr(sizeof(dynaType) * kMaxDynamicObs); + if (dinahs == nil) + RedAlert(kErrNoMemory); + + masterObjects = nil; + masterObjects = (objDataPtr)NewPtr(sizeof(objDataType) * kMaxMasterObjects); + if (masterObjects == nil) + RedAlert(kErrNoMemory); + + srcRects = nil; + srcRects = (Rect *)NewPtr(sizeof(Rect) * kNumSrcRects); + if (srcRects == nil) + RedAlert(kErrNoMemory); + + theHousesSpecs = nil; + theHousesSpecs = (FSSpecPtr)NewPtr(sizeof(FSSpec) * maxFiles); + if (theHousesSpecs == nil) + RedAlert(kErrNoMemory); + +#ifdef CREATEDEMODATA + demoData = nil; + demoData = (demoPtr)NewPtr(sizeof(demoType) * 2000); + if (demoData == nil) + RedAlert(kErrNoMemory); +#else + demoData = nil; + demoData = (demoPtr)NewPtr(kDemoLength); + if (demoData == nil) + RedAlert(kErrNoMemory); + tempHandle = GetResource('demo', 128); + if (tempHandle == nil) + RedAlert(kErrNoMemory); + else + { + BlockMove(*tempHandle, demoData, kDemoLength); + ReleaseResource(tempHandle); + } +#endif +} + +//-------------------------------------------------------------- InitSrcRects + +// This is a nasty, ugly function that initializes all global rectanglesÉ +// used in Glider PRO. + +void InitSrcRects (void) +{ + QSetRect(&srcRects[kFloorVent], 0, 0, 48, 11); // Blowers + QOffsetRect(&srcRects[kFloorVent], 0, 0); + QSetRect(&srcRects[kCeilingVent], 0, 0, 48, 11); + QOffsetRect(&srcRects[kCeilingVent], 0, 11); + QSetRect(&srcRects[kFloorBlower], 0, 0, 48, 15); + QOffsetRect(&srcRects[kFloorBlower], 0, 22); + QSetRect(&srcRects[kCeilingBlower], 0, 0, 48, 15); + QOffsetRect(&srcRects[kCeilingBlower], 0, 37); + QSetRect(&srcRects[kSewerGrate], 0, 0, 48, 17); + QOffsetRect(&srcRects[kSewerGrate], 0, 52); + QSetRect(&srcRects[kLeftFan], 0, 0, 40, 55); + QOffsetRect(&srcRects[kLeftFan], 0, 69); + QSetRect(&srcRects[kRightFan], 0, 0, 40, 55); + QOffsetRect(&srcRects[kRightFan], 0, 124); + QSetRect(&srcRects[kTaper], 0, 0, 20, 59); + QOffsetRect(&srcRects[kTaper], 0, 209); + QSetRect(&srcRects[kCandle], 0, 0, 32, 30); + QOffsetRect(&srcRects[kCandle], 0, 179); + QSetRect(&srcRects[kStubby], 0, 0, 20, 36); + QOffsetRect(&srcRects[kStubby], 0, 268); + QSetRect(&srcRects[kTiki], 0, 0, 27, 28); + QOffsetRect(&srcRects[kTiki], 21, 268); + QSetRect(&srcRects[kBBQ], 0, 0, 64, 33); + QSetRect(&srcRects[kInvisBlower], 0, 0, 24, 24); + QSetRect(&srcRects[kGrecoVent], 0, 0, 48, 18); + QOffsetRect(&srcRects[kGrecoVent], 0, 340); + QSetRect(&srcRects[kSewerBlower], 0, 0, 32, 12); + QOffsetRect(&srcRects[kSewerBlower], 0, 390); + QSetRect(&srcRects[kLiftArea], 0, 0, 64, 32); + + QSetRect(&srcRects[kTable], 0, 0, 64, kTableThick); // Furniture + QSetRect(&srcRects[kShelf], 0, 0, 64, kShelfThick); + QSetRect(&srcRects[kCabinet], 0, 0, 64, 64); + QSetRect(&srcRects[kFilingCabinet], 0, 0, 74, 107); + QSetRect(&srcRects[kWasteBasket], 0, 0, 64, 61); + QOffsetRect(&srcRects[kWasteBasket], 0, 43); + QSetRect(&srcRects[kMilkCrate], 0, 0, 64, 58); + QOffsetRect(&srcRects[kMilkCrate], 0, 104); + QSetRect(&srcRects[kCounter], 0, 0, 128, 64); + QSetRect(&srcRects[kDresser], 0, 0, 128, 64); + QSetRect(&srcRects[kDeckTable], 0, 0, 64, kTableThick); + QSetRect(&srcRects[kStool], 0, 0, 48, 38); + QOffsetRect(&srcRects[kStool], 0, 183); + QSetRect(&srcRects[kTrunk], 0, 0, 144, 80); + QSetRect(&srcRects[kInvisObstacle], 0, 0, 64, 64); + QSetRect(&srcRects[kManhole], 0, 0, 123, 22); + QSetRect(&srcRects[kBooks], 0, 0, 64, 51); + QSetRect(&srcRects[kInvisBounce], 0, 0, 64, 64); + + QSetRect(&srcRects[kRedClock], 0, 0, 28, 17); // Prizes + QSetRect(&srcRects[kBlueClock], 0, 0, 28, 25); + QOffsetRect(&srcRects[kBlueClock], 0, 17); + QSetRect(&srcRects[kYellowClock], 0, 0, 28, 28); + QOffsetRect(&srcRects[kYellowClock], 0, 42); + QSetRect(&srcRects[kCuckoo], 0, 0, 40, 80); + QOffsetRect(&srcRects[kCuckoo], 0, 148); + QSetRect(&srcRects[kPaper], 0, 0, 48, 21); + QOffsetRect(&srcRects[kPaper], 0, 127); + QSetRect(&srcRects[kBattery], 0, 0, 16, 25); + QOffsetRect(&srcRects[kBattery], 32, 0); + QSetRect(&srcRects[kBands], 0, 0, 28, 23); + QOffsetRect(&srcRects[kBands], 20, 70); + QSetRect(&srcRects[kGreaseRt], 0, 0, 32, 27); + QOffsetRect(&srcRects[kGreaseRt], 0, 243); + QSetRect(&srcRects[kGreaseLf], 0, 0, 32, 27); + QOffsetRect(&srcRects[kGreaseLf], 0, 324); + QSetRect(&srcRects[kFoil], 0, 0, 55, 15); + QOffsetRect(&srcRects[kFoil], 0, 228); + QSetRect(&srcRects[kInvisBonus], 0, 0, 24, 24); + QSetRect(&srcRects[kStar], 0, 0, 32, 31); + QOffsetRect(&srcRects[kStar], 48, 0); + QSetRect(&srcRects[kSparkle], 0, 0, 20, 19); + QOffsetRect(&srcRects[kSparkle], 0, 70); + QSetRect(&srcRects[kHelium], 0, 0, 56, 16); + QOffsetRect(&srcRects[kHelium], 32, 270); + QSetRect(&srcRects[kSlider], 0, 0, 64, 16); + + QSetRect(&srcRects[kUpStairs], 0, 0, 160, 267); // Transport + QSetRect(&srcRects[kDownStairs], 0, 0, 160, 267); + QSetRect(&srcRects[kMailboxLf], 0, 0, 94, 80); + QSetRect(&srcRects[kMailboxRt], 0, 0, 94, 80); + QSetRect(&srcRects[kFloorTrans], 0, 0, 56, 15); + QOffsetRect(&srcRects[kFloorTrans], 0, 1); + QSetRect(&srcRects[kCeilingTrans], 0, 0, 56, 15); + QOffsetRect(&srcRects[kCeilingTrans], 0, 16); + QSetRect(&srcRects[kDoorInLf], 0, 0, 144, 322); + QSetRect(&srcRects[kDoorInRt], 0, 0, 144, 322); + QSetRect(&srcRects[kDoorExRt], 0, 0, 16, 322); + QSetRect(&srcRects[kDoorExLf], 0, 0, 16, 322); + QSetRect(&srcRects[kWindowInLf], 0, 0, 20, 170); + QSetRect(&srcRects[kWindowInRt], 0, 0, 20, 170); + QSetRect(&srcRects[kWindowExRt], 0, 0, 16, 170); + QSetRect(&srcRects[kWindowExLf], 0, 0, 16, 170); + QSetRect(&srcRects[kInvisTrans], 0, 0, 64, 32); + QSetRect(&srcRects[kDeluxeTrans], 0, 0, 64, 64); + + QSetRect(&srcRects[kLightSwitch], 0, 0, 15, 24); // Switch + QSetRect(&srcRects[kMachineSwitch], 0, 0, 16, 24); + QOffsetRect(&srcRects[kMachineSwitch], 0, 48); + QSetRect(&srcRects[kThermostat], 0, 0, 15, 24); + QOffsetRect(&srcRects[kThermostat], 0, 48); + QSetRect(&srcRects[kPowerSwitch], 0, 0, 8, 8); + QOffsetRect(&srcRects[kPowerSwitch], 0, 72); + QSetRect(&srcRects[kKnifeSwitch], 0, 0, 16, 24); + QOffsetRect(&srcRects[kKnifeSwitch], 0, 80); + QSetRect(&srcRects[kInvisSwitch], 0, 0, 12, 12); + QSetRect(&srcRects[kTrigger], 0, 0, 12, 12); + QSetRect(&srcRects[kLgTrigger], 0, 0, 48, 48); + QSetRect(&srcRects[kSoundTrigger], 0, 0, 32, 32); + + QSetRect(&srcRects[kCeilingLight], 0, 0, 64, 20); // Lights + QOffsetRect(&srcRects[kCeilingLight], 0, 0); + QSetRect(&srcRects[kLightBulb], 0, 0, 16, 28); + QOffsetRect(&srcRects[kLightBulb], 0, 20); + QSetRect(&srcRects[kTableLamp], 0, 0, 48, 70); + QOffsetRect(&srcRects[kTableLamp], 16, 20); + QSetRect(&srcRects[kHipLamp], 0, 0, 72, 276); + QSetRect(&srcRects[kDecoLamp], 0, 0, 64, 212); + QSetRect(&srcRects[kFlourescent], 0, 0, 64, 12); + QSetRect(&srcRects[kTrackLight], 0, 0, 64, 24); + QSetRect(&srcRects[kInvisLight], 0, 0, 16, 16); + + QSetRect(&srcRects[kShredder], 0, 0, 73, 22); // Appliances + QSetRect(&srcRects[kToaster], 0, 0, 48, 27); + QOffsetRect(&srcRects[kToaster], 0, 22); + QSetRect(&srcRects[kMacPlus], 0, 0, 48, 58); + QOffsetRect(&srcRects[kMacPlus], 0, 49); + QSetRect(&srcRects[kGuitar], 0, 0, 64, 172); + QSetRect(&srcRects[kTV], 0, 0, 92, 77); + QSetRect(&srcRects[kCoffee], 0, 0, 43, 64); + QOffsetRect(&srcRects[kCoffee], 0, 107); + QSetRect(&srcRects[kOutlet], 0, 0, 16, 24); + QOffsetRect(&srcRects[kOutlet], 64, 22); + QSetRect(&srcRects[kVCR], 0, 0, 96, 22); + QSetRect(&srcRects[kStereo], 0, 0, 128, 53); + QSetRect(&srcRects[kMicrowave], 0, 0, 92, 59); + QSetRect(&srcRects[kCinderBlock], 0, 0, 40, 62); + QSetRect(&srcRects[kFlowerBox], 0, 0, 80, 32); + QSetRect(&srcRects[kCDs], 0, 0, 16, 30); + QOffsetRect(&srcRects[kCDs], 48, 22); + QSetRect(&srcRects[kCustomPict], 0, 0, 72, 34); + + QSetRect(&srcRects[kBalloon], 0, 0, 24, 30); // Enemies + QSetRect(&srcRects[kCopterLf], 0, 0, 32, 30); + QSetRect(&srcRects[kCopterRt], 0, 0, 32, 30); + QSetRect(&srcRects[kDartLf], 0, 0, 64, 19); + QSetRect(&srcRects[kDartRt], 0, 0, 64, 19); + QSetRect(&srcRects[kBall], 0, 0, 32, 32); + QSetRect(&srcRects[kDrip], 0, 0, 16, 12); + QSetRect(&srcRects[kFish], 0, 0, 36, 33); + QSetRect(&srcRects[kCobweb], 0, 0, 54, 45); + + QSetRect(&srcRects[kOzma], 0, 0, 102, 92); // Clutter + QSetRect(&srcRects[kMirror], 0, 0, 64, 64); + QSetRect(&srcRects[kMousehole], 0, 0, 10, 11); + QSetRect(&srcRects[kFireplace], 0, 0, 180, 142); + QSetRect(&srcRects[kWallWindow], 0, 0, 64, 80); + QSetRect(&srcRects[kBear], 0, 0, 56, 58); + QSetRect(&srcRects[kCalendar], 0, 0, 63, 92); + QSetRect(&srcRects[kVase1], 0, 0, 36, 45); + QSetRect(&srcRects[kVase2], 0, 0, 35, 57); + QSetRect(&srcRects[kBulletin], 0, 0, 80, 58); + QSetRect(&srcRects[kCloud], 0, 0, 128, 30); + QSetRect(&srcRects[kFaucet], 0, 0, 56, 18); + QOffsetRect(&srcRects[kFaucet], 0, 51); + QSetRect(&srcRects[kRug], 0, 0, 144, 18); + QSetRect(&srcRects[kChimes], 0, 0, 28, 74); +} + diff --git a/GpApp/Tools.cpp b/GpApp/Tools.cpp new file mode 100644 index 0000000..9a55cae --- /dev/null +++ b/GpApp/Tools.cpp @@ -0,0 +1,546 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Tools.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLTextUtils.h" +#include "PLControlDefinitions.h" +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "RectUtils.h" +#include "Utilities.h" + + +#define kToolsHigh 4 +#define kToolsWide 4 +#define kTotalTools 16 // kToolsHigh * kToolsWide +#define kPopUpControl 129 +#define kFirstBlower 1 +#define kLastBlower 15 +#define kBlowerBase 1 +#define kFirstFurniture 1 +#define kLastFurniture 15 +#define kFurnitureBase 21 +#define kFirstBonus 1 +#define kLastBonus 15 +#define kBonusBase 41 +#define kFirstTransport 1 +#define kLastTransport 12 +#define kTransportBase 61 +#define kFirstSwitch 1 +#define kLastSwitch 9 +#define kSwitchBase 81 +#define kFirstLight 1 +#define kLastLight 8 +#define kLightBase 101 +#define kFirstAppliance 1 +#define kLastAppliance 14 +#define kApplianceBase 121 +#define kFirstEnemy 1 +#define kLastEnemy 9 +#define kEnemyBase 141 +#define kFirstClutter 1 +#define kLastClutter 15 +#define kClutterBase 161 +#define kToolsPictID 1011 + + +void CreateToolsOffscreen (void); +void KillToolsOffscreen (void); +void FrameSelectedTool (void); +void DrawToolName (void); +void DrawToolTiles (void); +void SwitchToolModes (short); + + +Rect toolsWindowRect, toolSrcRect, toolTextRect; +Rect toolRects[kTotalTools]; +ControlHandle classPopUp; +GWorldPtr toolSrcMap; +WindowPtr toolsWindow; +short isToolsH, isToolsV; +short toolSelected, toolMode; +short firstTool, lastTool, objectBase; +Boolean isToolsOpen; + + +//============================================================== Functions +//-------------------------------------------------------------- CreateToolsOffscreen + +#ifndef COMPILEDEMO +void CreateToolsOffscreen (void) +{ + CGrafPtr wasCPort; + GDHandle wasWorld; + OSErr theErr; + + if (toolSrcMap == nil) + { + GetGWorld(&wasCPort, &wasWorld); + + QSetRect(&toolSrcRect, 0, 0, 360, 216); + theErr = CreateOffScreenGWorld(&toolSrcMap, &toolSrcRect, kPreferredDepth); + SetGWorld(toolSrcMap, nil); + LoadGraphic(kToolsPictID); + + SetGWorld(wasCPort, wasWorld); + } +} +#endif + +//-------------------------------------------------------------- KillToolsOffscreen + +#ifndef COMPILEDEMO +void KillToolsOffscreen (void) +{ + if (toolSrcMap != nil) + { + DisposeGWorld(toolSrcMap); +// KillOffScreenPixMap(toolSrcMap); + toolSrcMap = nil; + } +} +#endif + +//-------------------------------------------------------------- FrameSelectedTool + +#ifndef COMPILEDEMO +void FrameSelectedTool (void) +{ + Rect theRect; + short toolIcon; + + toolIcon = toolSelected; + if ((toolMode == kBlowerMode) && (toolIcon >= 7)) + { + toolIcon--; + } + else if ((toolMode == kTransportMode) && (toolIcon >= 7)) + { + if (toolIcon >= 15) + toolIcon -= 4; + else + toolIcon = ((toolIcon - 7) / 2) + 7; + } + + theRect = toolRects[toolIcon]; + PenSize(2, 2); + ForeColor(redColor); + FrameRect(&theRect); + PenNormal(); + ForeColor(blackColor); +} +#endif + +//-------------------------------------------------------------- DrawToolName + +#ifndef COMPILEDEMO +void DrawToolName (void) +{ + Str255 theString; + + if (toolSelected == 0) + PasStringCopy(PSTR("Selection Tool"), theString); + else + GetIndString(theString, kObjectNameStrings, + toolSelected + ((toolMode - 1) * 0x0010)); + + EraseRect(&toolTextRect); + MoveTo(toolTextRect.left + 3, toolTextRect.bottom - 6); + TextFont(applFont); + TextSize(9); + TextFace(bold); + ColorText(theString, 171L); +} +#endif + +//-------------------------------------------------------------- DrawToolTiles + +#ifndef COMPILEDEMO +void DrawToolTiles (void) +{ + Rect srcRect, destRect; + short i; + + DrawCIcon(2000, toolRects[0].left, toolRects[0].top); // Selection Tool + + for (i = 0; i < 15; i++) // Other tools + { + QSetRect(&srcRect, 0, 0, 24, 24); + QSetRect(&destRect, 0, 0, 24, 24); + + QOffsetRect(&srcRect, i * 24, (toolMode - 1) * 24); + QOffsetRect(&destRect, toolRects[i + 1].left + 2, toolRects[i + 1].top + 2); + + CopyBits((BitMap *)*GetGWorldPixMap(toolSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(toolsWindow)), + &srcRect, &destRect, srcCopy, nil); + } +} +#endif + +//-------------------------------------------------------------- EraseSelectedTool + +void EraseSelectedTool (void) +{ +#ifndef COMPILEDEMO + Rect theRect; + short toolIcon; + + if (toolsWindow == nil) + return; + + SetPort((GrafPtr)toolsWindow); + + toolIcon = toolSelected; + if ((toolMode == kBlowerMode) && (toolIcon >= 7)) + { + toolIcon--; + } + else if ((toolMode == kTransportMode) && (toolIcon >= 7)) + { + if (toolIcon >= 15) + toolIcon -= 4; + else + toolIcon = ((toolIcon - 7) / 2) + 7; + } + + theRect = toolRects[toolIcon]; + PenSize(2, 2); + ForeColor(whiteColor); + FrameRect(&theRect); +#endif +} + +//-------------------------------------------------------------- SelectTool + +void SelectTool (short which) +{ +#ifndef COMPILEDEMO + Rect theRect; + short toolIcon; + + if (toolsWindow == nil) + return; + + SetPort((GrafPtr)toolsWindow); + + toolIcon = which; + if ((toolMode == kBlowerMode) && (toolIcon >= 7)) + { + toolIcon--; + } + else if ((toolMode == kTransportMode) && (toolIcon >= 7)) + { + if (toolIcon >= 15) + toolIcon -= 4; + else + toolIcon = ((toolIcon - 7) / 2) + 7; + } + + theRect = toolRects[toolIcon]; + ForeColor(redColor); + FrameRect(&theRect); + PenNormal(); + ForeColor(blackColor); + + toolSelected = which; + DrawToolName(); +#endif +} + +//-------------------------------------------------------------- UpdateToolsWindow + +void UpdateToolsWindow (void) +{ +#ifndef COMPILEDEMO + if (toolsWindow == nil) + return; + + SetPortWindowPort(toolsWindow); + DrawControls(toolsWindow); + + DkGrayForeColor(); + MoveTo(4, 25); + Line(108, 0); + ForeColor(blackColor); + + DrawToolTiles(); + FrameSelectedTool(); + DrawToolName(); +#endif +} + +//-------------------------------------------------------------- OpenToolsWindow + +void OpenToolsWindow (void) +{ +#ifndef COMPILEDEMO + Rect src, dest; + Point globalMouse; + short h, v; + + if (toolsWindow == nil) + { + QSetRect(&toolsWindowRect, 0, 0, 116, 152); // 143 + QSetRect(&toolTextRect, 0, 0, 116, 12); + InsetRect(&toolTextRect, -1, -1); + QOffsetRect(&toolTextRect, 0, 157 - 15); + if (thisMac.hasColor) + toolsWindow = NewCWindow(nil, &toolsWindowRect, + PSTR("Tools"), false, kWindoidWDEF, kPutInFront, true, 0L); + else + toolsWindow = NewWindow(nil, &toolsWindowRect, + PSTR("Tools"), false, kWindoidWDEF, kPutInFront, true, 0L); + + if (toolsWindow == nil) + RedAlert(kErrNoMemory); + +// if (OptionKeyDown()) +// { +// isToolsH = qd.screenBits.bounds.right - 120; +// isToolsV = 35; +// } + MoveWindow(toolsWindow, isToolsH, isToolsV, true); + globalMouse = MyGetGlobalMouse(); + QSetRect(&src, 0, 0, 1, 1); + QOffsetRect(&src, globalMouse.h, globalMouse.v); + GetWindowRect(toolsWindow, &dest); + BringToFront(toolsWindow); + ShowHide(toolsWindow, true); +// FlagWindowFloating(toolsWindow); TEMP - use flaoting windows + HiliteAllWindows(); + + classPopUp = GetNewControl(kPopUpControl, toolsWindow); + if (classPopUp == nil) + RedAlert(kErrFailedResourceLoad); + + SetControlValue(classPopUp, toolMode); + + for (v = 0; v < kToolsHigh; v++) + for (h = 0; h < kToolsWide; h++) + { + QSetRect(&toolRects[(v * kToolsWide) + h], 2, 29, 30, 57); + QOffsetRect(&toolRects[(v * kToolsWide) + h], h * 28, v * 28); + } + + CreateToolsOffscreen(); + + SwitchToolModes(toolMode); + toolSelected = kSelectTool; + } + + UpdateToolsCheckmark(true); +#endif +} + +//-------------------------------------------------------------- CloseToolsWindow + +void CloseToolsWindow (void) +{ +#ifndef COMPILEDEMO + CloseThisWindow(&toolsWindow); + KillToolsOffscreen(); + UpdateToolsCheckmark(false); +#endif +} + +//-------------------------------------------------------------- ToggleToolsWindow + +void ToggleToolsWindow (void) +{ +#ifndef COMPILEDEMO + if (toolsWindow == nil) + { + OpenToolsWindow(); + isToolsOpen = true; + } + else + { + CloseToolsWindow(); + isToolsOpen = true; + } +#endif +} + +//-------------------------------------------------------------- SwitchToolModes + +#ifndef COMPILEDEMO +void SwitchToolModes (short newMode) +{ + if (toolsWindow == nil) + return; + + SelectTool(kSelectTool); + switch (newMode) + { + case kBlowerMode: + firstTool = kFirstBlower; + lastTool = kLastBlower; + objectBase = kBlowerBase; + break; + + case kFurnitureMode: + firstTool = kFirstFurniture; + lastTool = kLastFurniture; + objectBase = kFurnitureBase; + break; + + case kBonusMode: + firstTool = kFirstBonus; + lastTool = kLastBonus; + objectBase = kBonusBase; + break; + + case kTransportMode: + firstTool = kFirstTransport; + lastTool = kLastTransport; + objectBase = kTransportBase; + break; + + case kSwitchMode: + firstTool = kFirstSwitch; + lastTool = kLastSwitch; + objectBase = kSwitchBase; + break; + + case kLightMode: + firstTool = kFirstLight; + lastTool = kLastLight; + objectBase = kLightBase; + break; + + case kApplianceMode: + firstTool = kFirstAppliance; + lastTool = kLastAppliance; + objectBase = kApplianceBase; + break; + + case kEnemyMode: + firstTool = kFirstEnemy; + lastTool = kLastEnemy; + objectBase = kEnemyBase; + break; + + case kClutterMode: + firstTool = kFirstClutter; + lastTool = kLastClutter; + objectBase = kClutterBase; + break; + } + + toolMode = newMode; + InvalWindowRect(toolsWindow, &toolsWindowRect); +} +#endif + +//-------------------------------------------------------------- HandleToolsClick + +void HandleToolsClick (Point wherePt) +{ +#ifndef COMPILEDEMO + ControlHandle theControl; + short i, part, newMode, toolIcon; + + if (toolsWindow == nil) + return; + + SetPortWindowPort(toolsWindow); + GlobalToLocal(&wherePt); + + part = FindControl(wherePt, toolsWindow, &theControl); + if ((theControl != nil) && (part != 0)) + { + part = TrackControl(theControl, wherePt, (ControlActionUPP)-1L); + if (part != 0) + { + newMode = GetControlValue(theControl); + if (newMode != toolMode) + { + EraseSelectedTool(); + SwitchToolModes(newMode); + } + } + } + else + { + for (i = 0; i < kTotalTools; i++) + if ((PtInRect(wherePt, &toolRects[i])) && (i <= lastTool)) + { + EraseSelectedTool(); + toolIcon = i; + if ((toolMode == kBlowerMode) && (toolIcon >= 7)) + { + toolIcon++; + } + if ((toolMode == kTransportMode) && (toolIcon >= 7)) + { + if (toolIcon >= 11) + toolIcon += 4; + else + toolIcon = ((toolIcon - 7) * 2) + 7; + } + SelectTool(toolIcon); + break; + } + } +#endif +} + +//-------------------------------------------------------------- NextToolMode + +void NextToolMode (void) +{ +#ifndef COMPILEDEMO + if (toolsWindow == nil) + return; + + if ((theMode == kEditMode) && (toolMode < kClutterMode)) + { + EraseSelectedTool(); + toolMode++; + SetControlValue(classPopUp, toolMode); + SwitchToolModes(toolMode); + toolSelected = kSelectTool; + } +#endif +} + +//-------------------------------------------------------------- PrevToolMode + +void PrevToolMode (void) +{ +#ifndef COMPILEDEMO + if (toolsWindow == nil) + return; + + if ((theMode == kEditMode) && (toolMode > kBlowerMode)) + { + EraseSelectedTool(); + toolMode--; + SetControlValue(classPopUp, toolMode); + SwitchToolModes(toolMode); + toolSelected = kSelectTool; + } +#endif +} + +//-------------------------------------------------------------- SetSpecificToolMode + +void SetSpecificToolMode (short modeToSet) +{ +#ifndef COMPILEDEMO + if ((toolsWindow == nil) || (theMode != kEditMode)) + return; + + EraseSelectedTool(); + toolMode = modeToSet; + SetControlValue(classPopUp, toolMode); + SwitchToolModes(toolMode); + toolSelected = kSelectTool; +#endif +} + diff --git a/GpApp/Tools.h b/GpApp/Tools.h new file mode 100644 index 0000000..184c6dc --- /dev/null +++ b/GpApp/Tools.h @@ -0,0 +1,12 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Tools.h +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +extern GWorldPtr toolSrcMap; +extern WindowPtr toolsWindow; diff --git a/GpApp/Transit.cpp b/GpApp/Transit.cpp new file mode 100644 index 0000000..9fd5186 --- /dev/null +++ b/GpApp/Transit.cpp @@ -0,0 +1,558 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Transit.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Environ.h" +#include "RectUtils.h" + + +void HandleRoomVisitation (void); + + +short linkedToWhat; +Boolean takingTheStairs, firstPlayer; + + +extern Rect justRoomsRect, transRect; +extern short transRoom, otherPlayerEscaped; +extern short localNumbers[9]; +extern Boolean topOpen, twoPlayerGame, onePlayerLeft; +extern Boolean playerDead, playerSuicide, tvOn; + + +//============================================================== Functions +//-------------------------------------------------------------- WhatAreWeLinkedTo + +short WhatAreWeLinkedTo (short where, Byte who) +{ + short what, whatType; + char wasState; + + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + what = (*thisHouse)->rooms[where].objects[who].what; + HSetState((Handle)thisHouse, wasState); + + switch (what) + { + case kMailboxLf: + whatType = kLinkedToLeftMailbox; + break; + + case kMailboxRt: + whatType = kLinkedToRightMailbox; + break; + + case kCeilingTrans: + whatType = kLinkedToCeilingDuct; + break; + + default: + whatType = kLinkedToOther; + break; + } + + return (whatType); +} + +//-------------------------------------------------------------- ReadyGliderFromTransit + +void ReadyGliderFromTransit (gliderPtr thisGlider, short toWhat) +{ + Rect tempRect; + + if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) + return; + + FlagGliderNormal(thisGlider); + + switch (toWhat) + { + case kLinkedToOther: + StartGliderTransportingIn(thisGlider); // set glider's mode + tempRect = thisGlider->dest; // position glider + CenterRectInRect(&tempRect, &transRect); + thisGlider->dest.left = tempRect.left; + thisGlider->dest.right = tempRect.right; + thisGlider->dest.top = tempRect.top; + thisGlider->dest.bottom = tempRect.bottom; + thisGlider->destShadow.left = tempRect.left; + thisGlider->destShadow.right = tempRect.right; + thisGlider->whole = thisGlider->dest; + thisGlider->wholeShadow = thisGlider->destShadow; + thisGlider->enteredRect = thisGlider->dest; + break; + + case kLinkedToLeftMailbox: + StartGliderMailingOut(thisGlider); + thisGlider->clip = transRect; // fix clip + thisGlider->clip.right -= 64; + thisGlider->clip.bottom -= 25; + tempRect = thisGlider->dest; + thisGlider->dest.left = thisGlider->clip.right; + thisGlider->dest.right = thisGlider->dest.left; + thisGlider->dest.bottom = thisGlider->clip.bottom - 4; + thisGlider->dest.top = thisGlider->dest.bottom - RectTall(&tempRect); + thisGlider->destShadow.left = thisGlider->dest.left; + thisGlider->destShadow.right = thisGlider->dest.right; + thisGlider->whole = thisGlider->dest; + thisGlider->wholeShadow = thisGlider->destShadow; + break; + + case kLinkedToRightMailbox: + StartGliderMailingOut(thisGlider); + thisGlider->clip = transRect; // fix clip + thisGlider->clip.left += 79; + thisGlider->clip.bottom -= 25; + tempRect = thisGlider->dest; + thisGlider->dest.right = thisGlider->clip.left; + thisGlider->dest.left = thisGlider->dest.right; + thisGlider->dest.bottom = thisGlider->clip.bottom - 4; + thisGlider->dest.top = thisGlider->dest.bottom - RectTall(&tempRect); + thisGlider->destShadow.left = thisGlider->dest.left; + thisGlider->destShadow.right = thisGlider->dest.right; + thisGlider->whole = thisGlider->dest; + thisGlider->wholeShadow = thisGlider->destShadow; + break; + + case kLinkedToCeilingDuct: + StartGliderDuctingIn(thisGlider); + tempRect = thisGlider->dest; // set glider's position + CenterRectInRect(&tempRect, &transRect); + thisGlider->dest.left = tempRect.left; + thisGlider->dest.right = tempRect.right; + thisGlider->dest.top = tempRect.top; + thisGlider->dest.bottom = thisGlider->dest.top; + QOffsetRect(&thisGlider->dest, 0, -RectTall(&tempRect)); + thisGlider->destShadow.left = tempRect.left; + thisGlider->destShadow.right = tempRect.right; + thisGlider->whole = thisGlider->dest; + thisGlider->wholeShadow = thisGlider->destShadow; + break; + + case kLinkedToFloorDuct: + break; + + default: + break; + } + + if ((twoPlayerGame) && (thisGlider->which != firstPlayer)) + TagGliderIdle(thisGlider); +} + +//-------------------------------------------------------------- MoveRoomToRoom + +void MoveRoomToRoom (gliderPtr thisGlider, short where) +{ + Rect enterRect; + + HandleRoomVisitation(); + switch (where) + { + case kToRight: + SetMusicalMode(kProdGameScoreMode); + if (twoPlayerGame) + { + UndoGliderLimbo(&theGlider); + UndoGliderLimbo(&theGlider2); + InsureGliderFacingRight(&theGlider); + InsureGliderFacingRight(&theGlider2); + } + else + InsureGliderFacingRight(thisGlider); + ForceThisRoom(localNumbers[kEastRoom]); + if (twoPlayerGame) + { + OffsetGlider(&theGlider, kToLeft); + OffsetGlider(&theGlider2, kToLeft); + QSetRect(&enterRect, 0, 0, 48, 20); + QOffsetRect(&enterRect, 0, + kGliderStartsDown + (short)thisRoom->leftStart - 2); + theGlider.enteredRect = enterRect; + theGlider2.enteredRect = enterRect; + } + else + { + OffsetGlider(thisGlider, kToLeft); + QSetRect(&enterRect, 0, 0, 48, 20); + QOffsetRect(&enterRect, 0, + kGliderStartsDown + (short)thisRoom->leftStart - 2); + thisGlider->enteredRect = enterRect; + } + break; + + case kToLeft: + SetMusicalMode(kProdGameScoreMode); + if (twoPlayerGame) + { + UndoGliderLimbo(&theGlider); + UndoGliderLimbo(&theGlider2); + InsureGliderFacingLeft(&theGlider); + InsureGliderFacingLeft(&theGlider2); + } + else + InsureGliderFacingLeft(thisGlider); + ForceThisRoom(localNumbers[kWestRoom]); + if (twoPlayerGame) + { + OffsetGlider(&theGlider, kToRight); + OffsetGlider(&theGlider2, kToRight); + QSetRect(&enterRect, 0, 0, 48, 20); + QOffsetRect(&enterRect, kRoomWide - 48, + kGliderStartsDown + (short)thisRoom->rightStart - 2); + theGlider.enteredRect = enterRect; + theGlider2.enteredRect = enterRect; + } + else + { + OffsetGlider(thisGlider, kToRight); + QSetRect(&enterRect, 0, 0, 48, 20); + QOffsetRect(&enterRect, kRoomWide - 48, + kGliderStartsDown + (short)thisRoom->rightStart - 2); + thisGlider->enteredRect = enterRect; + } + break; + + case kAbove: + SetMusicalMode(kKickGameScoreMode); + ForceThisRoom(localNumbers[kNorthRoom]); + if (!takingTheStairs) + { + if (twoPlayerGame) + { + UndoGliderLimbo(&theGlider); + UndoGliderLimbo(&theGlider2); + OffsetGlider(&theGlider, kBelow); + OffsetGlider(&theGlider2, kBelow); + theGlider.enteredRect = theGlider.dest; + theGlider2.enteredRect = theGlider2.dest; + } + else + { + OffsetGlider(thisGlider, kBelow); + thisGlider->enteredRect = thisGlider->dest; + } + } + else + { + if (twoPlayerGame) + { + ReadyGliderForTripUpStairs(&theGlider); + ReadyGliderForTripUpStairs(&theGlider2); + } + else + ReadyGliderForTripUpStairs(thisGlider); + } + break; + + case kBelow: + SetMusicalMode(kKickGameScoreMode); + ForceThisRoom(localNumbers[kSouthRoom]); + if (!takingTheStairs) + { + if (twoPlayerGame) + { + UndoGliderLimbo(&theGlider); + UndoGliderLimbo(&theGlider2); + OffsetGlider(&theGlider, kAbove); + OffsetGlider(&theGlider2, kAbove); + theGlider.enteredRect = theGlider.dest; + theGlider2.enteredRect = theGlider2.dest; + } + else + { + OffsetGlider(thisGlider, kAbove); + thisGlider->enteredRect = thisGlider->dest; + } + } + else + { + if (twoPlayerGame) + { + ReadyGliderForTripDownStairs(&theGlider); + ReadyGliderForTripDownStairs(&theGlider2); + } + else + ReadyGliderForTripDownStairs(thisGlider); + } + break; + + default: + break; + } + + if ((twoPlayerGame) && (!onePlayerLeft)) + { + if (firstPlayer == kPlayer1) + TagGliderIdle(&theGlider2); + else + TagGliderIdle(&theGlider); + } + + ReadyLevel(); + RefreshScoreboard(kNormalTitleMode); + WipeScreenOn(where, &justRoomsRect); + +#ifdef COMPILEQT + RenderFrame(); + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) + { + GoToBeginningOfMovie(theMovie); + StartMovie(theMovie); + } +#endif +} + +//-------------------------------------------------------------- TransportRoomToRoom + +void TransportRoomToRoom (gliderPtr thisGlider) +{ + Boolean sameRoom; + + SetMusicalMode(kKickGameScoreMode); + HandleRoomVisitation(); + + sameRoom = (transRoom == thisRoomNumber); + if (!sameRoom) + ForceThisRoom(transRoom); + if (twoPlayerGame) + { + UndoGliderLimbo(&theGlider); // turn off limbo if needed + UndoGliderLimbo(&theGlider2); // turn off limbo if needed + ReadyGliderFromTransit(&theGlider, linkedToWhat); + ReadyGliderFromTransit(&theGlider2, linkedToWhat); + } + else + ReadyGliderFromTransit(thisGlider, linkedToWhat); + + if (!sameRoom) + ReadyLevel(); + RefreshScoreboard(kNormalTitleMode); + if (!sameRoom) + WipeScreenOn(kAbove, &justRoomsRect); + +#ifdef COMPILEQT + RenderFrame(); + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) + { + GoToBeginningOfMovie(theMovie); + StartMovie(theMovie); + } +#endif +} + +//-------------------------------------------------------------- MoveDuctToDuct + +void MoveDuctToDuct (gliderPtr thisGlider) +{ + Boolean sameRoom; + + SetMusicalMode(kKickGameScoreMode); + HandleRoomVisitation(); + + sameRoom = (transRoom == thisRoomNumber); + if (!sameRoom) + ForceThisRoom(transRoom); + + if (twoPlayerGame) + { + UndoGliderLimbo(&theGlider); // turn off limbo if needed + UndoGliderLimbo(&theGlider2); // turn off limbo if needed + ReadyGliderFromTransit(&theGlider, linkedToWhat); + ReadyGliderFromTransit(&theGlider2, linkedToWhat); + } + else + ReadyGliderFromTransit(thisGlider, linkedToWhat); + + if (!sameRoom) + ReadyLevel(); + RefreshScoreboard(kNormalTitleMode); + if (!sameRoom) + WipeScreenOn(kAbove, &justRoomsRect); + +#ifdef COMPILEQT + RenderFrame(); + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) + { + GoToBeginningOfMovie(theMovie); + StartMovie(theMovie); + } +#endif +} + +//-------------------------------------------------------------- MoveMailToMail + +void MoveMailToMail (gliderPtr thisGlider) +{ + Boolean sameRoom; + + SetMusicalMode(kKickGameScoreMode); + HandleRoomVisitation(); + + sameRoom = (transRoom == thisRoomNumber); + if (!sameRoom) + ForceThisRoom(transRoom); + + if (twoPlayerGame) + { + UndoGliderLimbo(&theGlider); // turn off limbo if needed + UndoGliderLimbo(&theGlider2); // turn off limbo if needed + ReadyGliderFromTransit(&theGlider, linkedToWhat); + ReadyGliderFromTransit(&theGlider2, linkedToWhat); + } + else + ReadyGliderFromTransit(thisGlider, linkedToWhat); + + if (!sameRoom) + ReadyLevel(); + RefreshScoreboard(kNormalTitleMode); + if (!sameRoom) + WipeScreenOn(kAbove, &justRoomsRect); + +#ifdef COMPILEQT + RenderFrame(); + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) + { + GoToBeginningOfMovie(theMovie); + StartMovie(theMovie); + } +#endif +} + +//-------------------------------------------------------------- HandleRoomVisitation + +void HandleRoomVisitation (void) +{ + houseType *thisHousePtr; + char wasState; + + if (!thisRoom->visited) + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + thisHousePtr = *thisHouse; + thisHousePtr->rooms[localNumbers[kCentralRoom]].visited = true; + HSetState((Handle)thisHouse, wasState); + theScore += kRoomVisitScore; + thisRoom->visited = true; + } +} + +//-------------------------------------------------------------- ForceKillGlider + +void ForceKillGlider (void) +{ + if (theGlider.mode == kGliderInLimbo) + { + if (theGlider2.mode != kGliderFadingOut) + { + StartGliderFadingOut(&theGlider2); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + playerSuicide = true; + } + } + else if (theGlider2.mode == kGliderInLimbo) + { + if (theGlider.mode != kGliderFadingOut) + { + StartGliderFadingOut(&theGlider); + PlayPrioritySound(kFadeOutSound, kFadeOutPriority); + playerSuicide = true; + } + } +} + +//-------------------------------------------------------------- FollowTheLeader + +void FollowTheLeader (void) +{ + short wasEscaped; + Boolean oneOrTwo; + + playerSuicide = false; + wasEscaped = otherPlayerEscaped; + otherPlayerEscaped = kNoOneEscaped; + + if (theGlider.mode == kGliderInLimbo) + { + oneOrTwo = true; + theGlider2.dest = theGlider.dest; + theGlider2.destShadow = theGlider.destShadow; + theGlider2.whole = theGlider2.dest; + theGlider2.wholeShadow = theGlider2.destShadow; + } + else if (theGlider2.mode == kGliderInLimbo) + { + oneOrTwo = false; + theGlider.dest = theGlider2.dest; + theGlider.destShadow = theGlider2.destShadow; + theGlider.whole = theGlider.dest; + theGlider.wholeShadow = theGlider.destShadow; + } + + switch (wasEscaped) + { + case kPlayerEscapedUp: + case kPlayerEscapingUpStairs: + case kPlayerEscapedUpStairs: + if (oneOrTwo) + MoveRoomToRoom(&theGlider2, kAbove); + else + MoveRoomToRoom(&theGlider, kAbove); + break; + + case kPlayerEscapedDown: + case kPlayerEscapingDownStairs: + case kPlayerEscapedDownStairs: + if (oneOrTwo) + MoveRoomToRoom(&theGlider2, kBelow); + else + MoveRoomToRoom(&theGlider, kBelow); + break; + + case kPlayerEscapedLeft: + if (oneOrTwo) + MoveRoomToRoom(&theGlider2, kToLeft); + else + MoveRoomToRoom(&theGlider, kToLeft); + break; + + case kPlayerEscapedRight: + if (oneOrTwo) + MoveRoomToRoom(&theGlider2, kToRight); + else + MoveRoomToRoom(&theGlider, kToRight); + break; + + case kPlayerTransportedOut: + if (oneOrTwo) + TransportRoomToRoom(&theGlider2); + else + TransportRoomToRoom(&theGlider); + break; + + case kPlayerMailedOut: + if (oneOrTwo) + MoveMailToMail(&theGlider2); + else + MoveMailToMail(&theGlider); + break; + + case kPlayerDuckedOut: + if (oneOrTwo) + MoveDuctToDuct(&theGlider2); + else + MoveDuctToDuct(&theGlider); + break; + + default: + break; + } +} + diff --git a/GpApp/Transitions.cpp b/GpApp/Transitions.cpp new file mode 100644 index 0000000..927a7e4 --- /dev/null +++ b/GpApp/Transitions.cpp @@ -0,0 +1,145 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Transitions.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Environ.h" +#include "MainWindow.h" +#include "RectUtils.h" + + +//============================================================== Functions +//-------------------------------------------------------------- PourScreenOn + +void PourScreenOn (Rect *theRect) +{ + #define kMaxColumnsWide 96 + #define kChipHigh 20 + #define kChipWide 16 + Rect columnRects[kMaxColumnsWide]; + short columnProgress[kMaxColumnsWide]; + short i, colsComplete, colWide, rowTall; + Boolean working; + + colWide = theRect->right / kChipWide; // determine # of cols + rowTall = (theRect->bottom / kChipHigh) + 1; // determine # of rows + + working = true; + colsComplete = 0; + for (i = 0; i < colWide; i++) + { + columnProgress[i] = 0; + QSetRect(&columnRects[i], 0, 0, kChipWide, kChipHigh); + QOffsetRect(&columnRects[i], (i * kChipWide) + theRect->left, theRect->top); + } + + while (working) + { + do + { + i = RandomInt(colWide); + } + while (columnProgress[i] >= rowTall); + + if (columnRects[i].left < theRect->left) + columnRects[i].left = theRect->left; + if (columnRects[i].top < theRect->top) + columnRects[i].top = theRect->top; + if (columnRects[i].right > theRect->right) + columnRects[i].right = theRect->right; + if (columnRects[i].bottom > theRect->bottom) + columnRects[i].bottom = theRect->bottom; + + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &columnRects[i], &columnRects[i], srcCopy, nil); + + QOffsetRect(&columnRects[i], 0, kChipHigh); + columnProgress[i]++; + if (columnProgress[i] >= rowTall) + { + colsComplete++; + if (colsComplete >= colWide) + working = false; + } + } +} + +//-------------------------------------------------------------- WipeScreenOn + +void WipeScreenOn (short direction, Rect *theRect) +{ + #define kWipeRectThick 4 + Rect wipeRect; + RgnHandle dummyRgn; + short hOffset, vOffset; + short i, count; + + wipeRect = *theRect; + switch (direction) + { + case kAbove: + wipeRect.bottom = wipeRect.top + kWipeRectThick; + hOffset = 0; + vOffset = kWipeRectThick; + count = ((theRect->bottom - theRect->top) / kWipeRectThick) + 1; + break; + + case kToRight: + wipeRect.left = wipeRect.right - kWipeRectThick; + hOffset = -kWipeRectThick; + vOffset = 0; + count = workSrcRect.right / kWipeRectThick; + break; + + case kBelow: + wipeRect.top = wipeRect.bottom - kWipeRectThick; + hOffset = 0; + vOffset = -kWipeRectThick; + count = ((theRect->bottom - theRect->top) / kWipeRectThick) + 1; + break; + + case kToLeft: + wipeRect.right = wipeRect.left + kWipeRectThick; + hOffset = kWipeRectThick; + vOffset = 0; + count = workSrcRect.right / kWipeRectThick; + break; + } + + dummyRgn = NewRgn(); + + for (i = 0; i < count; i++) + { + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &wipeRect, &wipeRect, srcCopy, GetPortVisibleRegion(GetWindowPort(mainWindow), dummyRgn)); + + QOffsetRect(&wipeRect, hOffset, vOffset); + + if (wipeRect.top < theRect->top) + wipeRect.top = theRect->top; + else if (wipeRect.top > theRect->bottom) + wipeRect.top = theRect->bottom; + if (wipeRect.bottom < theRect->top) + wipeRect.bottom = theRect->top; + else if (wipeRect.bottom > theRect->bottom) + wipeRect.bottom = theRect->bottom; + } + + DisposeRgn(dummyRgn); +} + +//-------------------------------------------------------------- DumpScreenOn + +void DumpScreenOn (Rect *theRect) +{ + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + theRect, theRect, srcCopy, nil); +} + diff --git a/GpApp/Triggers.cpp b/GpApp/Triggers.cpp new file mode 100644 index 0000000..77238e2 --- /dev/null +++ b/GpApp/Triggers.cpp @@ -0,0 +1,205 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Triggers.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" + + +#define kMaxTriggers 16 + + +typedef struct +{ + short object, room; + short index, timer; + short what; + Boolean armed; +} trigType, *trigPtr; + + +short FindEmptyTriggerSlot (void); +void FireTrigger (short); + + +trigType triggers[kMaxTriggers]; + + +//============================================================== Functions +//-------------------------------------------------------------- ArmTrigger + +void ArmTrigger (hotPtr who) +{ + short where, whoLinked; + + if (who->stillOver) + return; + + where = FindEmptyTriggerSlot(); + + if (where != -1) + { + whoLinked = who->who; // what is trigger's obj. # + triggers[where].room = masterObjects[whoLinked].roomLink; + triggers[where].object = masterObjects[whoLinked].objectLink; + triggers[where].index = whoLinked; + triggers[where].timer = masterObjects[whoLinked].theObject.data.e.delay * 3; + triggers[where].what = masterObjects[triggers[where].object].theObject.what; + triggers[where].armed = true; + } + + who->stillOver = true; +} + +//-------------------------------------------------------------- FindEmptyTriggerSlot + +short FindEmptyTriggerSlot (void) +{ + short where, i; + + where = -1; + + for (i = 0; i < kMaxTriggers; i++) + { + if (!triggers[i].armed) + { + where = i; + break; + } + } + + return (where); +} + +//-------------------------------------------------------------- HandleTriggers + +void HandleTriggers (void) +{ + short i; + + for (i = 0; i < kMaxTriggers; i++) + { + if (triggers[i].armed) + { + triggers[i].timer--; + if (triggers[i].timer <= 0) + { + triggers[i].timer = 0; + triggers[i].armed = false; + FireTrigger(i); + } + } + } +} + +//-------------------------------------------------------------- FireTrigger + +void FireTrigger (short index) +{ + short triggerIs, triggeredIs; + char wasState; + + triggerIs = triggers[index].index; + + if (masterObjects[triggerIs].localLink != -1) + { + triggeredIs = masterObjects[triggerIs].localLink; + switch (masterObjects[triggeredIs].theObject.what) + { + case kGreaseRt: + case kGreaseLf: + if (SetObjectState(triggers[index].room, triggers[index].object, + kForceOn, triggeredIs)) + { + SpillGrease(masterObjects[triggeredIs].dynaNum, + masterObjects[triggeredIs].hotNum); + } + break; + + case kLightSwitch: + case kMachineSwitch: + case kThermostat: + case kPowerSwitch: + case kKnifeSwitch: + case kInvisSwitch: + TriggerSwitch(masterObjects[triggeredIs].dynaNum); + break; + + case kSoundTrigger: + PlayPrioritySound(kChordSound, kChordPriority); // Change me + break; + + case kToaster: + TriggerToast(masterObjects[triggeredIs].dynaNum); + break; + + case kGuitar: + PlayPrioritySound(kChordSound, kChordPriority); + break; + + case kCoffee: + PlayPrioritySound(kCoffeeSound, kCoffeePriority); + break; + + case kOutlet: + TriggerOutlet(masterObjects[triggeredIs].dynaNum); + break; + + case kBalloon: + TriggerBalloon(masterObjects[triggeredIs].dynaNum); + break; + + case kCopterLf: + case kCopterRt: + TriggerCopter(masterObjects[triggeredIs].dynaNum); + break; + + case kDartLf: + case kDartRt: + TriggerDart(masterObjects[triggeredIs].dynaNum); + break; + + case kDrip: + TriggerDrip(masterObjects[triggeredIs].dynaNum); + break; + + case kFish: + TriggerFish(masterObjects[triggeredIs].dynaNum); + break; + } + } + else + { + wasState = HGetState((Handle)thisHouse); + HLock((Handle)thisHouse); + triggeredIs = masterObjects[triggerIs].localLink; + switch ((*thisHouse)->rooms[triggers[index].room]. + objects[triggers[index].object].what) + { + case kGreaseRt: + case kGreaseLf: + if (SetObjectState(triggers[index].room, triggers[index].object, + kForceOn, triggeredIs)) + { + SpillGrease(masterObjects[triggeredIs].dynaNum, + masterObjects[triggeredIs].hotNum); + } + break; + } + HSetState((Handle)thisHouse, wasState); + } +} + +//-------------------------------------------------------------- ZeroTriggers + +void ZeroTriggers (void) +{ + short i; + + for (i = 0; i < kMaxTriggers; i++) + triggers[i].armed = false; +} + diff --git a/GpApp/Trip.cpp b/GpApp/Trip.cpp new file mode 100644 index 0000000..08134a2 --- /dev/null +++ b/GpApp/Trip.cpp @@ -0,0 +1,245 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// Trip.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "Externs.h" +#include "Environ.h" + + +extern dynaPtr dinahs; +extern hotPtr hotSpots; +extern short numDynamics, tvWithMovieNumber; +extern Boolean tvOn; + + +//============================================================== Functions +//-------------------------------------------------------------- ToggleToaster + +void ToggleToaster (short index) +{ + dinahs[index].active = !dinahs[index].active; +} + +//-------------------------------------------------------------- ToggleMacPlus + +void ToggleMacPlus (short index) +{ + dinahs[index].active = !dinahs[index].active; + if (dinahs[index].active) + dinahs[index].timer = 40; + else + dinahs[index].timer = 10; +} + +//-------------------------------------------------------------- ToggleTV + +void ToggleTV (short index) +{ + dinahs[index].active = !dinahs[index].active; + if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvWithMovieNumber == index)) + { + if (dinahs[index].active) + { + GoToBeginningOfMovie(theMovie); + StartMovie(theMovie); + tvOn = true; + } + else + { + StopMovie(theMovie); + tvOn = false; + } + } + dinahs[index].timer = 4; +} + +//-------------------------------------------------------------- ToggleCoffee + +void ToggleCoffee (short index) +{ + dinahs[index].active = !dinahs[index].active; + dinahs[index].timer = 4; +} + +//-------------------------------------------------------------- ToggleOutlet + +void ToggleOutlet (short index) +{ + dinahs[index].active = !dinahs[index].active; +} + +//-------------------------------------------------------------- ToggleVCR + +void ToggleVCR (short index) +{ + dinahs[index].active = !dinahs[index].active; + dinahs[index].timer = 4; +} + +//-------------------------------------------------------------- ToggleStereo + +void ToggleStereos (short index) +{ + if (dinahs[index].timer == 0) + { + dinahs[index].active = !dinahs[index].active; + dinahs[index].timer = 4; + } +} + +//-------------------------------------------------------------- ToggleMicrowave + +void ToggleMicrowave (short index) +{ + dinahs[index].active = !dinahs[index].active; + dinahs[index].timer = 4; +} + +//-------------------------------------------------------------- ToggleBalloon + +void ToggleBalloon (short index) +{ + dinahs[index].active = !dinahs[index].active; +} + +//-------------------------------------------------------------- ToggleCopter + +void ToggleCopter (short index) +{ + dinahs[index].active = !dinahs[index].active; +} + +//-------------------------------------------------------------- ToggleDart + +void ToggleDart (short index) +{ + dinahs[index].active = !dinahs[index].active; +} + +//-------------------------------------------------------------- ToggleBall + +void ToggleBall (short index) +{ + dinahs[index].active = !dinahs[index].active; +} + +//-------------------------------------------------------------- ToggleDrip + +void ToggleDrip (short index) +{ + dinahs[index].active = !dinahs[index].active; +} + +//-------------------------------------------------------------- ToggleFish + +void ToggleFish (short index) +{ + dinahs[index].active = !dinahs[index].active; +} + +//-------------------------------------------------------------- TriggerSwitch + +void TriggerSwitch (short who) +{ + HandleSwitches(&hotSpots[who]); +} + +//-------------------------------------------------------------- TriggerToast + +void TriggerToast (short who) +{ + if (!dinahs[who].moving) + { + if (dinahs[who].active) + { + dinahs[who].vVel = (short)-dinahs[who].count; + dinahs[who].frame = 0; + dinahs[who].moving = true; + PlayPrioritySound(kToastLaunchSound, kToastLaunchPriority); + } + else + dinahs[who].frame = dinahs[who].timer; + } +} + +//-------------------------------------------------------------- TriggerOutlet + +void TriggerOutlet (short who) +{ + if (dinahs[who].position == 0) + { + if (dinahs[who].active) + { + dinahs[who].position = 1; + dinahs[who].timer = kLengthOfZap; + PlayPrioritySound(kZapSound, kZapPriority); + } + else + dinahs[who].timer = dinahs[who].count; + } +} + +//-------------------------------------------------------------- TriggerDrip + +void TriggerDrip (short who) +{ + if ((!dinahs[who].moving) && (dinahs[who].timer > 7)) + dinahs[who].timer = 7; // kick off drip +} + +//-------------------------------------------------------------- TriggerFish + +void TriggerFish (short who) +{ + if ((dinahs[who].active) && (!dinahs[who].moving)) + { + dinahs[who].whole = dinahs[who].dest; + dinahs[who].moving = true; + dinahs[who].frame = 4; + PlayPrioritySound(kFishOutSound, kFishOutPriority); + } +} + +//-------------------------------------------------------------- TriggerBalloon + +void TriggerBalloon (short who) +{ + if (!dinahs[who].moving) + dinahs[who].timer = kStartSparkle + 1; +} + + +//-------------------------------------------------------------- TriggerCopter + +void TriggerCopter (short who) +{ + if (!dinahs[who].moving) + dinahs[who].timer = kStartSparkle + 1; +} + + +//-------------------------------------------------------------- TriggerDart + +void TriggerDart (short who) +{ + if (!dinahs[who].moving) + dinahs[who].timer = kStartSparkle + 1; +} + +//-------------------------------------------------------------- UpdateOutletsLighting + +void UpdateOutletsLighting (short room, short nLights) +{ + short i; + + for (i = 0; i < numDynamics; i++) + { + if ((dinahs[i].type == kOutlet) && (dinahs[i].room == room)) + dinahs[i].hVel = nLights; + } +} + diff --git a/GpApp/Utilities.cpp b/GpApp/Utilities.cpp new file mode 100644 index 0000000..a05bf67 --- /dev/null +++ b/GpApp/Utilities.cpp @@ -0,0 +1,763 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Utilities.c +//---------------------------------------------------------------------------- +//============================================================================ + +#include "PLQuickdraw.h" +#include "PLPasStr.h" +#include "PLResources.h" +#include "PLSound.h" +#include "Externs.h" +#include "Utilities.h" + + +GDHandle thisGDevice; +UInt32 theSeed; + + +extern Boolean switchedOut; + + +//============================================================== Functions +//-------------------------------------------------------------- MyGetGlobalMouse +// Returns the position of the mouse in global coordinates. + +Point MyGetGlobalMouse (void) +{ + Point localWhere; + + GetMouse(&localWhere); + LocalToGlobal(&localWhere); + return (localWhere); +} + +//-------------------------------------------------------------- ToolBoxInit + +// The standard ToolBox intialization that must happen when any MacÉ +// program first launches. + +void ToolBoxInit (void) +{ + InitCursor(); + switchedOut = false; +} + +//-------------------------------------------------------------- RandomInt +// Returns a random integer (short) within "range". + +short RandomInt (short range) +{ + register long rawResult; + + rawResult = Random(); + if (rawResult < 0L) + rawResult *= -1L; + rawResult = (rawResult * (long)range) / 32768L; + + return ((short)rawResult); +} + +//-------------------------------------------------------------- RandomLong + +// Returns a random long interger within "range". + +long RandomLong (long range) +{ + register long highWord, lowWord; + register long rawResultHi, rawResultLo; + + highWord = (range & 0xFFFF0000) >> 16; + lowWord = range & 0x0000FFFF; + + rawResultHi = Random(); + if (rawResultHi < 0L) + rawResultHi *= -1L; + rawResultHi = (rawResultHi * highWord) / 32768L; + + rawResultLo = Random(); + if (rawResultLo < 0L) + rawResultLo *= -1L; + rawResultLo = (rawResultLo * lowWord) / 32768L; + + rawResultHi = (rawResultHi << 16) + rawResultLo; + + return (rawResultHi); +} + +//-------------------------------------------------------------- InitRandomLongQUS + +// Initializes random seed for quick & dirty long random number function (below). + +void InitRandomLongQUS (void) +{ + GetDateTime(&theSeed); +} + +//-------------------------------------------------------------- RandomLongQUS + +// Very simple (but fast) pseudo-random number generator. + +UInt32 RandomLongQUS (void) +{ + theSeed = theSeed * 1103515245 + 12345; + return (theSeed); +} + +//-------------------------------------------------------------- RedAlert + +// Called when we must quit app. Brings up a dialog informing userÉ +// of the problem and the exits to shell. + +void RedAlert (short errorNumber) +{ + #define rDeathAlertID 170 // alert res. ID for death error + #define rErrTitleID 170 // string ID for death error title + #define rErrMssgID 171 // string ID for death error message + short dummyInt; + Str255 errTitle, errMessage, errNumberString; + + InitCursor(); + + if (errorNumber > 1) // <= 0 is unaccounted for + { + GetIndString(errTitle, rErrTitleID, errorNumber); + GetIndString(errMessage, rErrMssgID, errorNumber); + } + else + { + GetIndString(errTitle, rErrTitleID, 1); + GetIndString(errMessage, rErrMssgID, 1); + } + NumToString((long)errorNumber, errNumberString); + ParamText(errTitle, errMessage, errNumberString, PSTR("")); +// CenterAlert(rDeathAlertID); + + dummyInt = Alert(rDeathAlertID, nil); + ExitToShell(); +} + +//-------------------------------------------------------------- FindOurDevice + +// Finds the main device (monitor with the menu bar on it). + +void FindOurDevice (void) +{ + thisGDevice = GetMainDevice(); + if (thisGDevice == nil) + RedAlert(kErrFailedGetDevice); +} + +//-------------------------------------------------------------- CreateOffScreenBitMap +// Creates an offscreen bit map (b&w - 1 bit depth). + +/* +void CreateOffScreenBitMap (Rect *theRect, GrafPtr *offScreen) +{ + GrafPtr theBWPort; + BitMap theBitMap; + long theRowBytes; + + theBWPort = (GrafPtr)(NewPtr(sizeof(GrafPort))); + OpenPort(theBWPort); + theRowBytes = (long)((theRect->right - theRect->left + 15L) / 16L) * 2L; + theBitMap.rowBytes = (short)theRowBytes; + theBitMap.baseAddr = NewPtr((long)theBitMap.rowBytes * + (theRect->bottom - theRect->top)); + if (theBitMap.baseAddr == nil) + RedAlert(kErrNoMemory); + theBitMap.bounds = *theRect; + if (MemError() != noErr) + RedAlert(kErrNoMemory); + SetPortBits(&theBitMap); + ClipRect(theRect); + RectRgn(theBWPort->visRgn, theRect); + EraseRect(theRect); + *offScreen = theBWPort; +} +*/ +//-------------------------------------------------------------- CreateOffScreenPixMap +// Creates an offscreen pix map using the depth of the current device. +/* +void CreateOffScreenPixMap (Rect *theRect, CGrafPtr *offScreen) +{ + CTabHandle thisColorTable; + GDHandle oldDevice; + CGrafPtr newCGrafPtr; + Ptr theseBits; + long sizeOfOff, offRowBytes; + OSErr theErr; + short thisDepth; + char wasState; + + oldDevice = GetGDevice(); + SetGDevice(thisGDevice); + newCGrafPtr = nil; + newCGrafPtr = (CGrafPtr)NewPtr(sizeof(CGrafPort)); + if (newCGrafPtr != nil) + { + OpenCPort(newCGrafPtr); + thisDepth = (**(*newCGrafPtr).portPixMap).pixelSize; + offRowBytes = ((((long)thisDepth * + (long)(theRect->right - theRect->left)) + 15L) >> 4L) << 1L; + sizeOfOff = (long)(theRect->bottom - theRect->top + 1) * offRowBytes; + // sizeOfOff = (long)(theRect->bottom - theRect->top) * offRowBytes; + OffsetRect(theRect, -theRect->left, -theRect->top); + theseBits = NewPtr(sizeOfOff); + if (theseBits != nil) + { // workaround + (**(*newCGrafPtr).portPixMap).baseAddr = theseBits + offRowBytes; + // (**(*newCGrafPtr).portPixMap).baseAddr = theseBits; + (**(*newCGrafPtr).portPixMap).rowBytes = (short)offRowBytes + 0x8000; + (**(*newCGrafPtr).portPixMap).bounds = *theRect; + wasState = HGetState((Handle)thisGDevice); + HLock((Handle)thisGDevice); + thisColorTable = (**(**thisGDevice).gdPMap).pmTable; + HSetState((Handle)thisGDevice, wasState); + theErr = HandToHand((Handle *)&thisColorTable); + (**(*newCGrafPtr).portPixMap).pmTable = thisColorTable; + ClipRect(theRect); + RectRgn(newCGrafPtr->visRgn, theRect); + ForeColor(blackColor); + BackColor(whiteColor); + EraseRect(theRect); + } + else + { + CloseCPort(newCGrafPtr); + DisposePtr((Ptr)newCGrafPtr); + newCGrafPtr = nil; + RedAlert(kErrNoMemory); + } + } + else + RedAlert(kErrNoMemory); + + *offScreen = newCGrafPtr; + SetGDevice(oldDevice); +} +*/ +//-------------------------------------------------------------------- CreateOffScreenGWorld +// Creates an offscreen GWorldÊusing the depth passed in. + +OSErr CreateOffScreenGWorld (GWorldPtr *theGWorld, Rect *bounds, short depth) +{ + OSErr theErr; + + theErr = NewGWorld(theGWorld, depth, bounds, nil, nil, useTempMem); + + if (theErr) + theErr = NewGWorld(theGWorld, depth, bounds, nil, nil, 0); + + LockPixels(GetGWorldPixMap(*theGWorld)); + + return theErr; +} + + +//-------------------------------------------------------------- KillOffScreenPixMap +// Destroys memory allocated by an offscreen pix map. +/* +void KillOffScreenPixMap (CGrafPtr offScreen) +{ + Ptr theseBits; + + if (offScreen != nil) + { + theseBits = (**(*offScreen).portPixMap).baseAddr; + theseBits -= (**(*offScreen).portPixMap).rowBytes & 0x7FFF; // workaround + DisposePtr(theseBits); + DisposeHandle((Handle)(**(*offScreen).portPixMap).pmTable); + CloseCPort(offScreen); + DisposePtr((Ptr)offScreen); + } +} +*/ +//-------------------------------------------------------------- KillOffScreenBitMap +// Destroys memory allocated by an offscreen bit map. +/* +void KillOffScreenBitMap (GrafPtr offScreen) +{ + if (offScreen != nil) + { + DisposePtr((Ptr)(offScreen->portBits.baseAddr)); + ClosePort(offScreen); + DisposePtr((Ptr)offScreen); + } +} +*/ +//-------------------------------------------------------------- LoadGraphic +// Function loads the specified 'PICT' from disk and draws it toÉ +// the current port (no scaling, clipping, etc, are done). AlwaysÉ +// draws in the upper left corner of current port. + +void LoadGraphic (short resID) +{ + Rect bounds; + PicHandle thePicture; + + thePicture = GetPicture(resID); + if (thePicture == nil) + RedAlert(kErrFailedGraphicLoad); + + HLock((Handle)thePicture); + bounds = (*thePicture)->picFrame; + HUnlock((Handle)thePicture); + OffsetRect(&bounds, -bounds.left, -bounds.top); + DrawPicture(thePicture, &bounds); + + ReleaseResource((Handle)thePicture); +} + +//-------------------------------------------------------------- LoadScaledGraphic +// Loads the specified 'PICT' and draws it mapped to the rectangleÉ +// specified. If this rect isn't the same size of the 'PICT', scalingÉ +// will occur. + +void LoadScaledGraphic (short resID, Rect *theRect) +{ + PicHandle thePicture; + + thePicture = GetPicture(resID); + if (thePicture == nil) + RedAlert(kErrFailedGraphicLoad); + DrawPicture(thePicture, theRect); + ReleaseResource((Handle)thePicture); +} + +//-------------------------------------------------------------- PlotSICN +// Draws a small icon (16 x 16 pixels). +/* +void PlotSICN (Rect *theRect, SICNHand theSICN, long theIndex) +{ + char state; + BitMap srcBits; + + if ((theSICN != nil) && + ((GetHandleSize((Handle)theSICN) / sizeof(SICN)) > theIndex)) + { + state = HGetState((Handle)theSICN); + HLock((Handle)theSICN); + + srcBits.baseAddr = (Ptr)(*theSICN)[theIndex]; + srcBits.rowBytes = 2; + SetRect(&srcBits.bounds, 0, 0, 16, 16); + + CopyBits(&srcBits,&(*qd.thePort).portBits, + &srcBits.bounds, theRect, srcCopy, nil); + + HSetState((Handle) theSICN, state); + } +} +*/ +//-------------------------------------------------------------- LargeIconPlot +// Draws a standard b&w icon (32 x 32) - resource is an 'ICON'. + +void LargeIconPlot (Rect *theRect, short theID) +{ + OSErr theErr; + Handle theSuite; + + theErr = GetIconSuite(&theSuite, theID, svAllLargeData); + if (theErr == noErr) + theErr = PlotIconSuite(theRect, atNone, ttNone, theSuite); +} + +//-------------------------------------------------------------- DrawCIcon + +// Draws a standard color icon (32 x 32) - resource is a 'CICN'. + +void DrawCIcon (short theID, short h, short v) +{ + CIconHandle theIcon; + Rect theRect; + + theIcon = GetCIcon(theID); + if (theIcon != nil) + { + SetRect(&theRect, 0, 0, 32, 32); + OffsetRect(&theRect, h, v); + PlotCIcon(&theRect, theIcon); + DisposeCIcon(theIcon); + } +} + +//-------------------------------------------------------------- LongSquareRoot + +// This is a quick and dirty square root function that returns prettyÉ +// accurate long integer results. It uses no transcendental functions orÉ +// floating point. + +long LongSquareRoot (long theNumber) +{ + long currentAnswer; + long nextTrial; + + if (theNumber <= 1L) + return (theNumber); + + nextTrial = theNumber / 2; + + do + { + currentAnswer = nextTrial; + nextTrial = (nextTrial + theNumber / nextTrial) / 2; + } + while (nextTrial < currentAnswer); + + return(currentAnswer); +} + +//-------------------------------------------------------------- WaitForInputEvent + +// Wait for either a key to be hit or the mouse button to be clicked. +// Also has a "timeout" parameter ("seconds"). + +Boolean WaitForInputEvent (short seconds) +{ + EventRecord theEvent; + KeyMap theKeys; + long timeToBail; + Boolean waiting, didResume; + + timeToBail = TickCount() + 60L * (long)seconds; + FlushEvents(everyEvent, 0); + waiting = true; + didResume = false; + + while (waiting) + { + GetKeys(theKeys); + if ((BitTst(&theKeys, kCommandKeyMap)) || (BitTst(&theKeys, kOptionKeyMap)) || + (BitTst(&theKeys, kShiftKeyMap)) || (BitTst(&theKeys, kControlKeyMap))) + waiting = false; + if (GetNextEvent(everyEvent, &theEvent)) + { + if ((theEvent.what == mouseDown) || (theEvent.what == keyDown)) + waiting = false; + else if ((theEvent.what == osEvt) && (theEvent.message & 0x01000000)) + { + if (theEvent.message & 0x00000001) // resuming + { + didResume = true; + waiting = false; + } + else // suspending + { + InitCursor(); + } + } + } + if ((seconds != -1) && (TickCount() >= timeToBail)) + waiting = false; + } + FlushEvents(everyEvent, 0); + return (didResume); +} + +//-------------------------------------------------------------- WaitCommandQReleased + +// Waits until the Command-Q key combination is released. + +void WaitCommandQReleased (void) +{ + KeyMap theKeys; + Boolean waiting; + + waiting = true; + + while (waiting) + { + GetKeys(theKeys); + if ((!BitTst(&theKeys, kCommandKeyMap)) || (!BitTst(&theKeys, kQKeyMap))) + waiting = false; + } + FlushEvents(everyEvent, 0); +} + +//-------------------------------------------------------------- KeyMapOffsetFromRawKey +// Converts a raw key code to keymap offset (ugly stuff). + +char KeyMapOffsetFromRawKey (char rawKeyCode) +{ + char hiByte, loByte, theOffset; + + hiByte = rawKeyCode & 0xF0; + loByte = rawKeyCode & 0x0F; + + if (loByte <= 0x07) + theOffset = hiByte + (0x07 - loByte); + else + theOffset = hiByte + (0x17 - loByte); + + return (theOffset); +} + +//-------------------------------------------------------------- GetKeyMapFromMessage +// Gets the key map offset from a keyDown event's message field. + +char GetKeyMapFromMessage (intptr_t message) +{ + long theVirtual; + char offset; + + theVirtual = (message & keyCodeMask) >> 8; + offset = KeyMapOffsetFromRawKey((char)theVirtual); + return (offset); +} + +//-------------------------------------------------------------- GetKeyName +// Given a keyDown event (it's message field), this function returnsÉ +// a string with that key's name (so we get "Shift" and "Esc", etc.). + +void GetKeyName (intptr_t message, StringPtr theName) +{ + long theASCII, theVirtual; + + theASCII = message & charCodeMask; + theVirtual = (message & keyCodeMask) >> 8; + + if ((theASCII >= kExclamationASCII) && (theASCII <= kZKeyASCII)) + { + + if ((theVirtual >= 0x0041) && (theVirtual <= 0x005C)) + { + PasStringCopy(PSTR("( )"), theName); + theName[2] = (char)theASCII; + } + else + { + PasStringCopy(PSTR(" key"), theName); + theName[1] = (char)theASCII; + } + } + else + { + switch (theASCII) + { + case kHomeKeyASCII: + PasStringCopy(PSTR("home"), theName); + break; + + case kEnterKeyASCII: + PasStringCopy(PSTR("enter"), theName); + break; + + case kEndKeyASCII: + PasStringCopy(PSTR("end"), theName); + break; + + case kHelpKeyASCII: + PasStringCopy(PSTR("help"), theName); + break; + + case kDeleteKeyASCII: + PasStringCopy(PSTR("delete"), theName); + break; + + case kTabKeyASCII: + PasStringCopy(PSTR("tab"), theName); + break; + + case kPageUpKeyASCII: + PasStringCopy(PSTR("pg up"), theName); + break; + + case kPageDownKeyASCII: + PasStringCopy(PSTR("pg dn"), theName); + break; + + case kReturnKeyASCII: + PasStringCopy(PSTR("return"), theName); + break; + + case kFunctionKeyASCII: + switch (theVirtual) + { + case 0x0060: + PasStringCopy(PSTR("F5"), theName); + break; + case 0x0061: + PasStringCopy(PSTR("F6"), theName); + break; + case 0x0062: + PasStringCopy(PSTR("F7"), theName); + break; + case 0x0063: + PasStringCopy(PSTR("F3"), theName); + break; + case 0x0064: + PasStringCopy(PSTR("F8"), theName); + break; + case 0x0065: + PasStringCopy(PSTR("F9"), theName); + break; + case 0x0067: + PasStringCopy(PSTR("F11"), theName); + break; + case 0x0069: + PasStringCopy(PSTR("F13"), theName); + break; + case 0x006B: + PasStringCopy(PSTR("F14"), theName); + break; + case 0x006D: + PasStringCopy(PSTR("F10"), theName); + break; + case 0x006F: + PasStringCopy(PSTR("F12"), theName); + break; + case 0x0071: + PasStringCopy(PSTR("F15"), theName); + break; + case 0x0076: + PasStringCopy(PSTR("F4"), theName); + break; + case 0x0078: + PasStringCopy(PSTR("F2"), theName); + break; + case 0x007A: + PasStringCopy(PSTR("F1"), theName); + break; + default: + NumToString(theVirtual, theName); + break; + } + break; + + case kClearKeyASCII: + PasStringCopy(PSTR("clear"), theName); + break; + + case kEscapeKeyASCII: + if (theVirtual == 0x0047) + PasStringCopy(PSTR("clear"), theName); + else + PasStringCopy(PSTR("esc"), theName); + break; + + case kLeftArrowKeyASCII: + PasStringCopy(PSTR("lf arrow"), theName); + break; + + case kRightArrowKeyASCII: + PasStringCopy(PSTR("rt arrow"), theName); + break; + + case kUpArrowKeyASCII: + PasStringCopy(PSTR("up arrow"), theName); + break; + + case kDownArrowKeyASCII: + PasStringCopy(PSTR("dn arrow"), theName); + break; + + case kSpaceBarASCII: + PasStringCopy(PSTR("space"), theName); + break; + + case kForwardDeleteASCII: + PasStringCopy(PSTR("frwd del"), theName); + break; + + default: + PasStringCopy(PSTR("????"), theName); + break; + } + } +} + +//-------------------------------------------------------------- OptionKeyDown +// Returns true is the Option key is being held down. + +Boolean OptionKeyDown (void) +{ + KeyMap theKeys; + + GetKeys(theKeys); + if (BitTst(&theKeys, kOptionKeyMap)) + return (true); + else + return (false); +} + +//-------------------------------------------------------------- ExtractCTSeed +// Very esoteric - gets the "color table seed" from a specified graf port. +/* +long ExtractCTSeed (CGrafPtr porter) +{ + long theSeed; + + theSeed = (**((**(porter->portPixMap)).pmTable)).ctSeed; + return(theSeed); +} +*/ +//-------------------------------------------------------------- ForceCTSeed +// Forces the "color table seed" from a specified graf port to aÉ +// specified value. +/* +void ForceCTSeed (CGrafPtr porter, long newSeed) +{ + (**((**(porter->portPixMap)).pmTable)).ctSeed = newSeed; +} +*/ +//-------------------------------------------------------------- DelayTicks +// Lil' function that just sits and waits a specified number ofÉ +// Ticks (1/60 of a second). + +void DelayTicks (long howLong) +{ + UInt32 whoCares; + + Delay(howLong, &whoCares); +} + +//-------------------------------------------------------------- UnivGetSoundVolume +// Returns the speaker volume (as set by the user) in the range ofÉ +// zero to seven (handles Sound Manager 3 case as well). + +void UnivGetSoundVolume (short *volume, Boolean hasSM3) +{ + long longVol; + OSErr theErr; + +// if (hasSM3) +// { + theErr = GetDefaultOutputVolume(&longVol); + *volume = LoWord(longVol) / 0x0024; +// } +// else +// GetSoundVol(volume); + + if (*volume > 7) + *volume = 7; + else if (*volume < 0) + *volume = 0; +} + +//-------------------------------------------------------------- UnivSetSoundVolume +// Sets the speaker volume to a specified value (in the range ofÉ +// zero to seven (handles Sound Manager 3 case as well). + +void UnivSetSoundVolume (short volume, Boolean hasSM3) +{ + long longVol; + OSErr theErr; + + if (volume > 7) + volume = 7; + else if (volume < 0) + volume = 0; + +// if (hasSM3) +// { + longVol = (long)volume * 0x0025; + if (longVol > 0x00000100) + longVol = 0x00000100; + longVol = longVol + (longVol << 16); + theErr = SetDefaultOutputVolume(longVol); +// } +// else +// SetSoundVol(volume); +} + diff --git a/GpApp/Utilities.h b/GpApp/Utilities.h new file mode 100644 index 0000000..d5fca68 --- /dev/null +++ b/GpApp/Utilities.h @@ -0,0 +1,11 @@ +//============================================================================ +//---------------------------------------------------------------------------- +// Utilities.c +//---------------------------------------------------------------------------- +//============================================================================ + + +#include "PLQDOffscreen.h" + + +OSErr CreateOffScreenGWorld (GWorldPtr *theGWorld, Rect *bounds, short depth); diff --git a/Sources/Validate.c b/GpApp/Validate.c old mode 100755 new mode 100644 similarity index 100% rename from Sources/Validate.c rename to GpApp/Validate.c diff --git a/GpApp/WindowUtils.cpp b/GpApp/WindowUtils.cpp new file mode 100644 index 0000000..c9027bd --- /dev/null +++ b/GpApp/WindowUtils.cpp @@ -0,0 +1,172 @@ + +//============================================================================ +//---------------------------------------------------------------------------- +// WindowUtils.c +//---------------------------------------------------------------------------- +//============================================================================ + +#include "PLPasStr.h" +#include "Externs.h" +#include "Environ.h" +#include "RectUtils.h" + + +#define kFloatingKind 2048 +#define kMessageWindowTall 48 + + +WindowPtr mssgWindow; + + +//============================================================== Functions +//-------------------------------------------------------------- GetWindowTopLeft + +// Returns the top left coordinate of the specified window. CorrdinatesÉ +// are (of course) global (local coordinates would always be (0, 0)). + +void GetWindowLeftTop (WindowPtr theWindow, short *left, short *top) +{ + Point thePoint; + Rect bounds; + + *left = 0; + *top = 0; + + if (theWindow != nil) + { + SetPortWindowPort(theWindow); + GetWindowBounds(theWindow, kWindowContentRgn, &bounds); + thePoint.h = bounds.left; + thePoint.v = bounds.top; + LocalToGlobal(&thePoint); + *left = thePoint.h; + *top = thePoint.v; + } +} + +//-------------------------------------------------------------- GetWindowRect + +// Returns bounding rectangle of the specified window in global coords. + +void GetWindowRect (WindowPtr theWindow, Rect *bounds) +{ + if (theWindow != nil) + { + SetPortWindowPort(theWindow); + GetWindowBounds(theWindow, kWindowContentRgn, bounds); + LocalToGlobalRect(bounds); + } +} + +//-------------------------------------------------------------- GetLocalWindowRect +// Returns bounding rectangle of the specified window in local coords. +// (When you just need its width and height.) + +void GetLocalWindowRect (WindowPtr theWindow, Rect *bounds) +{ + if (theWindow != nil) + { + SetPortWindowPort(theWindow); + GetWindowBounds(theWindow, kWindowContentRgn, bounds); + } +} + +//-------------------------------------------------------------- FlagWindowFloating +// Sets the specified window's windowKind field to my own kFloatingKindÉ +// variable. This way I can examine a window later and determine ifÉ +// it's supposed to "float" above all other windows. +/* +void FlagWindowFloating (WindowPtr theWindow) +{ + if (theWindow != nil) + { + ((WindowPeek)theWindow)->windowKind = kFloatingKind; + BringToFront(theWindow); + } +} + +//-------------------------------------------------------------- IsWindowFloating + +// Tests a specific window to see if it is supposed to "float" above allÉ +// other windows. + +Boolean IsWindowFloating (WindowPtr theWindow) +{ + if (theWindow != nil) + { + return (((WindowPeek)theWindow)->windowKind == kFloatingKind); + } + else + return (false); +} +*/ +//-------------------------------------------------------------- OpenMessageWindow +// Brings up a simple message window. Nice sort of utility function. +// Anytime you want a small, quick message to come up, call this. + +void OpenMessageWindow (const PLPasStr &title) +{ + Rect mssgWindowRect; + + SetRect(&mssgWindowRect, 0, 0, 256, kMessageWindowTall); + if (thisMac.hasColor) + mssgWindow = NewCWindow(nil, &mssgWindowRect, + title, false, noGrowDocProc, kPutInFront, false, 0L); + else + mssgWindow = NewWindow(nil, &mssgWindowRect, + title, false, noGrowDocProc, kPutInFront, false, 0L); + + if (mssgWindow != nil) + { + ShowWindow(mssgWindow); + SetPort((GrafPtr)mssgWindow); + ClipRect(&mssgWindowRect); + ForeColor(blackColor); + BackColor(whiteColor); + TextFont(systemFont); + } +} + +//-------------------------------------------------------------- SetMessageWindowMessage + +// For the above message window, this function displays a string of textÉ +// in the center of the window. + +void SetMessageWindowMessage (StringPtr message) +{ + Rect mssgWindowRect; + + if (mssgWindow != nil) + { + SetPort((GrafPtr)mssgWindow); + SetRect(&mssgWindowRect, 0, 0, 256, kMessageWindowTall); + InsetRect(&mssgWindowRect, 16, 16); + EraseRect(&mssgWindowRect); + MoveTo(mssgWindowRect.left, mssgWindowRect.bottom - 6); + DrawString(message); + } +} + +//-------------------------------------------------------------- CloseMessageWindow + +// Closes the previously referred to "message window". + +void CloseMessageWindow (void) +{ + if (mssgWindow != nil) + DisposeWindow(mssgWindow); + mssgWindow = nil; +} + +//-------------------------------------------------------------- CloseThisWindow + +// Given a specific window, this function will close it and set the windowÉ +// pointer to null. + +void CloseThisWindow (WindowPtr *theWindow) +{ + if (*theWindow != nil) + DisposeWindow(*theWindow); + *theWindow = nil; +} + diff --git a/GpApp/x64/Debug/vc141.idb b/GpApp/x64/Debug/vc141.idb new file mode 100644 index 0000000..31c6543 Binary files /dev/null and b/GpApp/x64/Debug/vc141.idb differ diff --git a/GpApp2/ApplicationResources.bin b/GpApp2/ApplicationResources.bin new file mode 100644 index 0000000..271d6a0 Binary files /dev/null and b/GpApp2/ApplicationResources.bin differ diff --git a/CarbonLib b/GpApp2/CarbonLib old mode 100755 new mode 100644 similarity index 100% rename from CarbonLib rename to GpApp2/CarbonLib diff --git a/GPLv2-LICENSE.md b/GpApp2/GPLv2-LICENSE.md similarity index 100% rename from GPLv2-LICENSE.md rename to GpApp2/GPLv2-LICENSE.md diff --git a/GpApp2/Glider PRO.bin b/GpApp2/Glider PRO.bin new file mode 100644 index 0000000..271d6a0 Binary files /dev/null and b/GpApp2/Glider PRO.bin differ diff --git a/Glider PRO.r b/GpApp2/Glider PRO.r similarity index 100% rename from Glider PRO.r rename to GpApp2/Glider PRO.r diff --git a/Houses/Art Museum.binhex b/GpApp2/Houses/Art Museum.binhex similarity index 100% rename from Houses/Art Museum.binhex rename to GpApp2/Houses/Art Museum.binhex diff --git a/Houses/Art Museum.mov b/GpApp2/Houses/Art Museum.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Art Museum.mov rename to GpApp2/Houses/Art Museum.mov diff --git a/Houses/CD Demo House.binhex b/GpApp2/Houses/CD Demo House.binhex similarity index 100% rename from Houses/CD Demo House.binhex rename to GpApp2/Houses/CD Demo House.binhex diff --git a/Houses/CD Demo House.mov b/GpApp2/Houses/CD Demo House.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/CD Demo House.mov rename to GpApp2/Houses/CD Demo House.mov diff --git a/Houses/California or Bust!.binhex b/GpApp2/Houses/California or Bust!.binhex similarity index 100% rename from Houses/California or Bust!.binhex rename to GpApp2/Houses/California or Bust!.binhex diff --git a/Houses/Castle o' the Air.binhex b/GpApp2/Houses/Castle o' the Air.binhex similarity index 100% rename from Houses/Castle o' the Air.binhex rename to GpApp2/Houses/Castle o' the Air.binhex diff --git a/Houses/Castle o' the Air.mov b/GpApp2/Houses/Castle o' the Air.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Castle o' the Air.mov rename to GpApp2/Houses/Castle o' the Air.mov diff --git a/Houses/Davis Station.binhex b/GpApp2/Houses/Davis Station.binhex similarity index 100% rename from Houses/Davis Station.binhex rename to GpApp2/Houses/Davis Station.binhex diff --git a/Houses/Davis Station.mov b/GpApp2/Houses/Davis Station.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Davis Station.mov rename to GpApp2/Houses/Davis Station.mov diff --git a/Houses/Demo House.binhex b/GpApp2/Houses/Demo House.binhex similarity index 100% rename from Houses/Demo House.binhex rename to GpApp2/Houses/Demo House.binhex diff --git a/Houses/Demo House.mov b/GpApp2/Houses/Demo House.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Demo House.mov rename to GpApp2/Houses/Demo House.mov diff --git a/Houses/Empty House.binhex b/GpApp2/Houses/Empty House.binhex similarity index 100% rename from Houses/Empty House.binhex rename to GpApp2/Houses/Empty House.binhex diff --git a/Houses/Fun House.binhex b/GpApp2/Houses/Fun House.binhex similarity index 100% rename from Houses/Fun House.binhex rename to GpApp2/Houses/Fun House.binhex diff --git a/Houses/Grand Prix.binhex b/GpApp2/Houses/Grand Prix.binhex similarity index 100% rename from Houses/Grand Prix.binhex rename to GpApp2/Houses/Grand Prix.binhex diff --git a/Houses/Grand Prix.mov b/GpApp2/Houses/Grand Prix.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Grand Prix.mov rename to GpApp2/Houses/Grand Prix.mov diff --git a/Houses/ImagineHouse PRO II.binhex b/GpApp2/Houses/ImagineHouse PRO II.binhex similarity index 100% rename from Houses/ImagineHouse PRO II.binhex rename to GpApp2/Houses/ImagineHouse PRO II.binhex diff --git a/Houses/ImagineHouse PRO II.mov b/GpApp2/Houses/ImagineHouse PRO II.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/ImagineHouse PRO II.mov rename to GpApp2/Houses/ImagineHouse PRO II.mov diff --git a/Houses/In The Mirror.binhex b/GpApp2/Houses/In The Mirror.binhex similarity index 100% rename from Houses/In The Mirror.binhex rename to GpApp2/Houses/In The Mirror.binhex diff --git a/Houses/Land of Illusion.binhex b/GpApp2/Houses/Land of Illusion.binhex similarity index 100% rename from Houses/Land of Illusion.binhex rename to GpApp2/Houses/Land of Illusion.binhex diff --git a/Houses/Land of Illusion.mov b/GpApp2/Houses/Land of Illusion.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Land of Illusion.mov rename to GpApp2/Houses/Land of Illusion.mov diff --git a/Houses/Leviathan.binhex b/GpApp2/Houses/Leviathan.binhex similarity index 100% rename from Houses/Leviathan.binhex rename to GpApp2/Houses/Leviathan.binhex diff --git a/Houses/Leviathan.mov b/GpApp2/Houses/Leviathan.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Leviathan.mov rename to GpApp2/Houses/Leviathan.mov diff --git a/Houses/Metropolis.binhex b/GpApp2/Houses/Metropolis.binhex similarity index 100% rename from Houses/Metropolis.binhex rename to GpApp2/Houses/Metropolis.binhex diff --git a/Houses/Nemo's Market.binhex b/GpApp2/Houses/Nemo's Market.binhex similarity index 100% rename from Houses/Nemo's Market.binhex rename to GpApp2/Houses/Nemo's Market.binhex diff --git a/Houses/Nemo's Market.mov b/GpApp2/Houses/Nemo's Market.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Nemo's Market.mov rename to GpApp2/Houses/Nemo's Market.mov diff --git a/Houses/Rainbow's End.binhex b/GpApp2/Houses/Rainbow's End.binhex similarity index 100% rename from Houses/Rainbow's End.binhex rename to GpApp2/Houses/Rainbow's End.binhex diff --git a/Houses/Rainbow's End.mov b/GpApp2/Houses/Rainbow's End.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Rainbow's End.mov rename to GpApp2/Houses/Rainbow's End.mov diff --git a/Houses/Sampler.binhex b/GpApp2/Houses/Sampler.binhex similarity index 100% rename from Houses/Sampler.binhex rename to GpApp2/Houses/Sampler.binhex diff --git a/GpApp2/Houses/Slumberland.bin b/GpApp2/Houses/Slumberland.bin new file mode 100644 index 0000000..0de5225 Binary files /dev/null and b/GpApp2/Houses/Slumberland.bin differ diff --git a/Houses/Slumberland.binhex b/GpApp2/Houses/Slumberland.binhex similarity index 100% rename from Houses/Slumberland.binhex rename to GpApp2/Houses/Slumberland.binhex diff --git a/Houses/Slumberland.mov b/GpApp2/Houses/Slumberland.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Slumberland.mov rename to GpApp2/Houses/Slumberland.mov diff --git a/Houses/SpacePods.binhex b/GpApp2/Houses/SpacePods.binhex similarity index 100% rename from Houses/SpacePods.binhex rename to GpApp2/Houses/SpacePods.binhex diff --git a/Houses/SpacePods.mov b/GpApp2/Houses/SpacePods.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/SpacePods.mov rename to GpApp2/Houses/SpacePods.mov diff --git a/Houses/Teddy World.binhex b/GpApp2/Houses/Teddy World.binhex similarity index 100% rename from Houses/Teddy World.binhex rename to GpApp2/Houses/Teddy World.binhex diff --git a/Houses/Teddy World.mov b/GpApp2/Houses/Teddy World.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Teddy World.mov rename to GpApp2/Houses/Teddy World.mov diff --git a/Houses/The Asylum Pro.binhex b/GpApp2/Houses/The Asylum Pro.binhex similarity index 100% rename from Houses/The Asylum Pro.binhex rename to GpApp2/Houses/The Asylum Pro.binhex diff --git a/Houses/Titanic.binhex b/GpApp2/Houses/Titanic.binhex similarity index 100% rename from Houses/Titanic.binhex rename to GpApp2/Houses/Titanic.binhex diff --git a/Houses/Titanic.mov b/GpApp2/Houses/Titanic.mov old mode 100755 new mode 100644 similarity index 100% rename from Houses/Titanic.mov rename to GpApp2/Houses/Titanic.mov diff --git a/README.md b/GpApp2/README.md similarity index 100% rename from README.md rename to GpApp2/README.md diff --git a/GpD3D/EGpDisplayDriverType.h b/GpD3D/EGpDisplayDriverType.h new file mode 100644 index 0000000..e020781 --- /dev/null +++ b/GpD3D/EGpDisplayDriverType.h @@ -0,0 +1,8 @@ +#pragma once + +enum EGpDisplayDriverType +{ + EGpDisplayDriverType_D3D11, + + EGpDisplayDriverType_Count, +}; diff --git a/GpD3D/GpAppEnvironment.cpp b/GpD3D/GpAppEnvironment.cpp new file mode 100644 index 0000000..34310b8 --- /dev/null +++ b/GpD3D/GpAppEnvironment.cpp @@ -0,0 +1,130 @@ +#include "GpAppEnvironment.h" +#include "GpFiberStarter.h" +#include "GpAppInterface.h" +#include "GpPLGlueDisplayDriver.h" +#include "GpFiber.h" +#include "HostSuspendCallArgument.h" + +#include + +GpAppEnvironment::GpAppEnvironment() + : m_applicationState(ApplicationState_NotStarted) + , m_displayDriver(nullptr) + , m_applicationFiber(nullptr) + , m_vosFiber(nullptr) + , m_suspendCallID(PortabilityLayer::HostSuspendCallID_Unknown) + , m_suspendArgs(nullptr) + , m_suspendReturnValue(nullptr) +{ +} + +GpAppEnvironment::~GpAppEnvironment() +{ + assert(m_applicationFiber == nullptr); +} + +void GpAppEnvironment::Init() +{ +} + +void GpAppEnvironment::Tick(GpFiber *vosFiber) +{ + GpAppInterface_Get()->PL_IncrementTickCounter(1); + + m_vosFiber = vosFiber; + + if (m_applicationState == ApplicationState_WaitingForEvents) + m_applicationState = ApplicationState_Running; + + for (;;) + { + switch (m_applicationState) + { + case ApplicationState_NotStarted: + InitializeApplicationState(); + m_applicationFiber = GpFiberStarter::StartFiber(GpAppEnvironment::StaticAppThreadFunc, this, vosFiber); + m_applicationState = ApplicationState_Running; + break; + case ApplicationState_WaitingForEvents: + return; + case ApplicationState_Running: + m_applicationFiber->YieldTo(); + break; + case ApplicationState_SystemCall: + { + PortabilityLayer::HostSuspendCallID callID = m_suspendCallID; + const PortabilityLayer::HostSuspendCallArgument *args = m_suspendArgs; + PortabilityLayer::HostSuspendCallArgument *returnValue = m_suspendReturnValue; + + DispatchSystemCall(callID, args, returnValue); + assert(m_applicationState != ApplicationState_SystemCall); + } + break; + case ApplicationState_TimedSuspend: + if (m_delaySuspendTicks <= 1) + m_applicationState = ApplicationState_Running; + else + { + m_delaySuspendTicks--; + return; + } + break; + default: + assert(false); + break; + }; + } +} + +void GpAppEnvironment::SetDisplayDriver(IGpDisplayDriver *displayDriver) +{ + m_displayDriver = displayDriver; +} + +void GpAppEnvironment::StaticAppThreadFunc(void *context) +{ + static_cast(context)->AppThreadFunc(); +} + +void GpAppEnvironment::AppThreadFunc() +{ + GpAppInterface_Get()->ApplicationMain(); +} + +void GpAppEnvironment::InitializeApplicationState() +{ + GpAppInterface_Get()->PL_HostDisplayDriver_SetInstance(GpPLGlueDisplayDriver::GetInstance()); + GpAppInterface_Get()->PL_InstallHostSuspendHook(GpAppEnvironment::StaticSuspendHookFunc, this); + + SynchronizeState(); +} + +void GpAppEnvironment::SynchronizeState() +{ + GpPLGlueDisplayDriver::GetInstance()->SetGpDisplayDriver(m_displayDriver); +} + +void GpAppEnvironment::StaticSuspendHookFunc(void *context, PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue) +{ + GpAppEnvironment *appEnv = static_cast(context); + + appEnv->m_suspendCallID = callID; + appEnv->m_suspendArgs = args; + appEnv->m_suspendReturnValue = returnValue; + appEnv->m_applicationState = ApplicationState_SystemCall; + + appEnv->m_vosFiber->YieldTo(); +} + +void GpAppEnvironment::DispatchSystemCall(PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue) +{ + switch (callID) + { + case PortabilityLayer::HostSuspendCallID_Delay: + m_applicationState = ApplicationState_TimedSuspend; + m_delaySuspendTicks = args[0].m_uint; + break; + default: + assert(false); + } +} diff --git a/GpD3D/GpAppEnvironment.h b/GpD3D/GpAppEnvironment.h new file mode 100644 index 0000000..443122a --- /dev/null +++ b/GpD3D/GpAppEnvironment.h @@ -0,0 +1,55 @@ +#pragma once + +#include "HostSuspendCallID.h" + +#include + +namespace PortabilityLayer +{ + union HostSuspendCallArgument; +} + +class IGpDisplayDriver; +class GpFiber; + +class GpAppEnvironment +{ +public: + GpAppEnvironment(); + ~GpAppEnvironment(); + + void Init(); + + void Tick(GpFiber *vosFiber); + void SetDisplayDriver(IGpDisplayDriver *displayDriver); + +private: + enum ApplicationState + { + ApplicationState_NotStarted, + ApplicationState_WaitingForEvents, + ApplicationState_Running, + ApplicationState_Terminated, + ApplicationState_SystemCall, + ApplicationState_TimedSuspend, + }; + + static void StaticAppThreadFunc(void *context); + void AppThreadFunc(); + void InitializeApplicationState(); + void SynchronizeState(); + + static void StaticSuspendHookFunc(void *context, PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue); + void DispatchSystemCall(PortabilityLayer::HostSuspendCallID callID, const PortabilityLayer::HostSuspendCallArgument *args, PortabilityLayer::HostSuspendCallArgument *returnValue); + + ApplicationState m_applicationState; + IGpDisplayDriver *m_displayDriver; + GpFiber *m_applicationFiber; + GpFiber *m_vosFiber; + + uint32_t m_delaySuspendTicks; + + PortabilityLayer::HostSuspendCallID m_suspendCallID; + const PortabilityLayer::HostSuspendCallArgument *m_suspendArgs; + PortabilityLayer::HostSuspendCallArgument *m_suspendReturnValue; +}; diff --git a/GpD3D/GpCoreDefs.h b/GpD3D/GpCoreDefs.h new file mode 100644 index 0000000..bfe42cb --- /dev/null +++ b/GpD3D/GpCoreDefs.h @@ -0,0 +1,25 @@ +#pragma once + +#if __cplusplus >= 199711L +#define GP_IS_CPP11 1 +#else +#define GP_IS_CPP11 0 +#endif + +#if GP_IS_CPP11 +#define GP_DELETED = delete +#else +#ifndef nullptr +#define nullptr 0 +#endif + +#ifndef override +#define override +#endif + +#ifndef final +#define final +#endif + +#define GP_DELETED +#endif diff --git a/GpD3D/GpD3D.vcxproj b/GpD3D/GpD3D.vcxproj new file mode 100644 index 0000000..24013d1 --- /dev/null +++ b/GpD3D/GpD3D.vcxproj @@ -0,0 +1,177 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {0E383EF0-CEF7-4733-87C6-5AC9844AA1EF} + GpD3D + 10.0.17763.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level4 + Disabled + true + true + + + shlwapi.lib;%(AdditionalDependencies) + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + shlwapi.lib;%(AdditionalDependencies) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {6233c3f2-5781-488e-b190-4fa8836f5a77} + + + + + + \ No newline at end of file diff --git a/GpD3D/GpD3D.vcxproj.filters b/GpD3D/GpD3D.vcxproj.filters new file mode 100644 index 0000000..54e5914 --- /dev/null +++ b/GpD3D/GpD3D.vcxproj.filters @@ -0,0 +1,129 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/GpD3D/GpDisplayDriverD3D11.cpp b/GpD3D/GpDisplayDriverD3D11.cpp new file mode 100644 index 0000000..53fb13d --- /dev/null +++ b/GpD3D/GpDisplayDriverD3D11.cpp @@ -0,0 +1,290 @@ +#include "GpDisplayDriverD3D11.h" +#include "GpWindows.h" +#include "GpFiber_Win32.h" + +#include +#include + +#include + +#pragma comment (lib, "d3d11.lib") + +void DebugPrintf(const char *fmt, ...) +{ + char buf[256]; + va_list argp; + va_start(argp, fmt); + vsnprintf_s(buf, 255, fmt, argp); + OutputDebugString(buf); + va_end(argp); +} + +LRESULT CALLBACK WinProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + switch (message) + { + case WM_DESTROY: + { + PostQuitMessage(0); + return 0; + } + break; + } + + return DefWindowProc(hWnd, message, wParam, lParam); +} + +void StartD3DForWindow(HWND hWnd, IDXGISwapChain1*& swapChain) +{ + DXGI_SWAP_CHAIN_DESC1 swapChainDesc; + + ZeroMemory(&swapChainDesc, sizeof(swapChainDesc)); + + swapChainDesc.BufferCount = 2; + swapChainDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; + + DXGI_SWAP_CHAIN_FULLSCREEN_DESC swapChainFullscreenDesc; + + ZeroMemory(&swapChainFullscreenDesc, sizeof(swapChainFullscreenDesc)); + + swapChainFullscreenDesc.Windowed = TRUE; + swapChainFullscreenDesc.RefreshRate.Numerator = 60; + swapChainFullscreenDesc.RefreshRate.Denominator = 1; + + UINT flags = 0; + const D3D_FEATURE_LEVEL featureLevels[] = + { + D3D_FEATURE_LEVEL_9_1 + }; + + flags |= D3D11_CREATE_DEVICE_DEBUG; + + ID3D11Device *device = NULL; + ID3D11DeviceContext *context = NULL; + + D3D_FEATURE_LEVEL selectedFeatureLevel; + + HRESULT result = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, NULL, flags, featureLevels, sizeof(featureLevels) / sizeof(featureLevels[0]), + D3D11_SDK_VERSION, &device, &selectedFeatureLevel, &context); + + IDXGIDevice2 *dxgiDevice = nullptr; + result = device->QueryInterface(__uuidof(IDXGIDevice2), reinterpret_cast(&dxgiDevice)); + + IDXGIAdapter *dxgiAdapter = nullptr; + result = dxgiDevice->GetAdapter(&dxgiAdapter); + + IDXGIFactory2 *dxgiFactory = nullptr; + result = dxgiAdapter->GetParent(__uuidof(IDXGIFactory2), reinterpret_cast(&dxgiFactory)); + + result = dxgiFactory->CreateSwapChainForHwnd(device, hWnd, &swapChainDesc, nullptr, nullptr, &swapChain); +} + +bool GpDisplayDriverD3D11::PresentFrameAndSync() +{ + DXGI_PRESENT_PARAMETERS presentParams; + + ZeroMemory(&presentParams, sizeof(presentParams)); + + UINT lastPresentCount = 0; + + if (FAILED(m_SwapChain->GetLastPresentCount(&lastPresentCount))) + return false; + + if (FAILED(m_SwapChain->Present1(1, 0, &presentParams))) + return false; + + //DebugPrintf("r: %i\n", static_cast(r)); + + DXGI_FRAME_STATISTICS stats; + if (FAILED(m_SwapChain->GetFrameStatistics(&stats))) + return false; + + if (stats.SyncQPCTime.QuadPart != 0) + { + if (m_SyncTimeBase.QuadPart == 0) + m_SyncTimeBase = stats.SyncQPCTime; + + LARGE_INTEGER timestamp; + timestamp.QuadPart = stats.SyncQPCTime.QuadPart - m_SyncTimeBase.QuadPart; + + bool compacted = false; + if (m_PresentHistory.Size() > 0) + { + CompactedPresentHistoryItem &lastItem = m_PresentHistory[m_PresentHistory.Size() - 1]; + LONGLONG timeDelta = timestamp.QuadPart - lastItem.m_Timestamp.QuadPart; + + if (timeDelta < 0) + timeDelta = 0; // This should never happen + + if (timeDelta * static_cast(m_Properties.m_FrameTimeLockDenominator) < m_QPFrequency.QuadPart * static_cast(m_Properties.m_FrameTimeLockNumerator)) + { + lastItem.m_NumFrames++; + compacted = true; + } + } + + if (!compacted) + { + if (m_PresentHistory.Size() == m_PresentHistory.CAPACITY) + m_PresentHistory.RemoveFromStart(); + + CompactedPresentHistoryItem *newItem = m_PresentHistory.Append(); + newItem->m_Timestamp = timestamp; + newItem->m_NumFrames = 1; + } + } + + if (m_PresentHistory.Size() >= 2) + { + const size_t presentHistorySizeMinusOne = m_PresentHistory.Size() - 1; + unsigned int numFrames = 0; + for (size_t i = 0; i < presentHistorySizeMinusOne; i++) + numFrames += m_PresentHistory[i].m_NumFrames; + + LONGLONG timeFrame = m_PresentHistory[presentHistorySizeMinusOne].m_Timestamp.QuadPart - m_PresentHistory[0].m_Timestamp.QuadPart; + + unsigned int cancelledFrames = 0; + LONGLONG cancelledTime = 0; + + const int overshootTolerance = 2; + + for (size_t i = 0; i < presentHistorySizeMinusOne; i++) + { + LONGLONG blockTimeframe = m_PresentHistory[i + 1].m_Timestamp.QuadPart - m_PresentHistory[i].m_Timestamp.QuadPart; + unsigned int blockNumFrames = m_PresentHistory[i].m_NumFrames; + + if (blockTimeframe * static_cast(numFrames) >= timeFrame * static_cast(blockNumFrames) * overshootTolerance) + { + cancelledTime += blockTimeframe; + cancelledFrames += blockNumFrames; + } + } + + numFrames -= cancelledFrames; + timeFrame -= cancelledTime; + + // timeFrame / numFrames = Frame timestep + // Unless Frame timestep is within the frame lock range, a.k.a. + // timeFrame / numFrames / qpFreq >= minFrameTimeNum / minFrameTimeDenom + + bool isInFrameTimeLock = false; + if (timeFrame * static_cast(m_Properties.m_FrameTimeLockMinDenominator) >= static_cast(numFrames) * static_cast(m_Properties.m_FrameTimeLockMinNumerator) * m_QPFrequency.QuadPart + && timeFrame * static_cast(m_Properties.m_FrameTimeLockMaxDenominator) <= static_cast(numFrames) * static_cast(m_Properties.m_FrameTimeLockMaxNumerator) * m_QPFrequency.QuadPart) + { + isInFrameTimeLock = true; + } + + LONGLONG frameTimeStep = m_FrameTimeSliceSize; + if (!isInFrameTimeLock) + { + const int MAX_FRAMES_PER_STEP = 4; + + frameTimeStep = timeFrame / numFrames; + if (frameTimeStep > m_FrameTimeSliceSize * MAX_FRAMES_PER_STEP) + frameTimeStep = m_FrameTimeSliceSize * MAX_FRAMES_PER_STEP; + } + + m_FrameTimeAccumulated += frameTimeStep; + while (m_FrameTimeAccumulated >= m_FrameTimeSliceSize) + { + m_Properties.m_TickFunc(m_Properties.m_TickFuncContext, m_vosFiber); + m_FrameTimeAccumulated -= m_FrameTimeSliceSize; + } + } + + return true; +} + +void GpDisplayDriverD3D11::Run() +{ + HWND hWnd; + WNDCLASSEX wc; + + LPVOID fiber = ConvertThreadToFiberEx(this, 0); + if (!fiber) + return; // ??? + + m_vosFiber = new GpFiber_Win32(fiber); + + ZeroMemory(&wc, sizeof(wc)); + + wc.cbSize = sizeof(WNDCLASSEX); + wc.style = CS_HREDRAW | CS_VREDRAW; + wc.lpfnWndProc = WinProc; + wc.hInstance = g_gpWindowsGlobals.m_hInstance; + wc.hCursor = LoadCursor(NULL, IDC_ARROW); + wc.hbrBackground = (HBRUSH)COLOR_WINDOW; + wc.lpszClassName = "GPD3D11WindowClass"; + + RegisterClassEx(&wc); + + LONG windowStyle = WS_OVERLAPPEDWINDOW; + HMENU menus = NULL; + + // TODO: Fix the resolution here + RECT wr = { 0, 0, m_windowWidth, m_windowHeight }; + AdjustWindowRect(&wr, windowStyle, menus != NULL); + + hWnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, g_gpWindowsGlobals.m_hInstance, NULL); + + ShowWindow(hWnd, g_gpWindowsGlobals.m_nCmdShow); + + StartD3DForWindow(hWnd, m_SwapChain); + + LARGE_INTEGER lastTimestamp; + memset(&lastTimestamp, 0, sizeof(lastTimestamp)); + + MSG msg; + for (;;) + { + if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + TranslateMessage(&msg); + + DispatchMessage(&msg); + + if (msg.message == WM_QUIT) + break; + } + else + { + PresentFrameAndSync(); + } + } + + // Exit + ConvertFiberToThread(); +} + +void GpDisplayDriverD3D11::Shutdown() +{ + delete this; +} + +void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int &width, unsigned int &height) +{ + width = m_windowWidth; + height = m_windowHeight; +} + +GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperties &properties) +{ + return new GpDisplayDriverD3D11(properties); +} + +GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties) + : m_Properties(properties) + , m_FrameTimeAccumulated(0) + , m_windowWidth(640) + , m_windowHeight(480) + , m_vosFiber(nullptr) +{ + memset(&m_SyncTimeBase, 0, sizeof(m_SyncTimeBase)); + + QueryPerformanceFrequency(&m_QPFrequency); + + m_FrameTimeSliceSize = m_QPFrequency.QuadPart * static_cast(properties.m_FrameTimeLockNumerator) / static_cast(properties.m_FrameTimeLockDenominator); +} diff --git a/GpD3D/GpDisplayDriverD3D11.h b/GpD3D/GpDisplayDriverD3D11.h new file mode 100644 index 0000000..5e47bc8 --- /dev/null +++ b/GpD3D/GpDisplayDriverD3D11.h @@ -0,0 +1,50 @@ +#pragma once + +#include "GpWindows.h" +#include "GpRingBuffer.h" + +#include "IGpDisplayDriver.h" +#include "GpCoreDefs.h" +#include "GpDisplayDriverProperties.h" + +struct IDXGISwapChain1; + +class GpDisplayDriverD3D11 : public IGpDisplayDriver +{ +public: + void Run() override; + void Shutdown() override; + + void GetDisplayResolution(unsigned int &width, unsigned int &height) override; + + static GpDisplayDriverD3D11 *Create(const GpDisplayDriverProperties &properties); + +private: + GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties); + + bool PresentFrameAndSync(); + + IDXGISwapChain1 *m_SwapChain; + + struct CompactedPresentHistoryItem + { + LARGE_INTEGER m_Timestamp; + unsigned int m_NumFrames; + }; + + GpRingBuffer m_PresentHistory; + GpDisplayDriverProperties m_Properties; + + LARGE_INTEGER m_SyncTimeBase; + LARGE_INTEGER m_QPFrequency; + UINT m_ExpectedSyncDelta; + bool m_IsResettingSwapChain; + + LONGLONG m_FrameTimeAccumulated; + LONGLONG m_FrameTimeSliceSize; + + DWORD m_windowWidth; + DWORD m_windowHeight; + + GpFiber *m_vosFiber; +}; diff --git a/GpD3D/GpDisplayDriverFactory.cpp b/GpD3D/GpDisplayDriverFactory.cpp new file mode 100644 index 0000000..fc79bb1 --- /dev/null +++ b/GpD3D/GpDisplayDriverFactory.cpp @@ -0,0 +1,23 @@ +#include "GpDisplayDriverFactory.h" +#include "GpDisplayDriverProperties.h" + +#include + +IGpDisplayDriver *GpDisplayDriverFactory::CreateDisplayDriver(const GpDisplayDriverProperties &properties) +{ + assert(properties.m_Type < EGpDisplayDriverType_Count); + + if (ms_Registry[properties.m_Type]) + return ms_Registry[properties.m_Type](properties); + else + return nullptr; +} + +void GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType type, FactoryFunc_t func) +{ + assert(type < EGpDisplayDriverType_Count); + + ms_Registry[type] = func; +} + +GpDisplayDriverFactory::FactoryFunc_t GpDisplayDriverFactory::ms_Registry[EGpDisplayDriverType_Count]; diff --git a/GpD3D/GpDisplayDriverFactory.h b/GpD3D/GpDisplayDriverFactory.h new file mode 100644 index 0000000..706375a --- /dev/null +++ b/GpD3D/GpDisplayDriverFactory.h @@ -0,0 +1,18 @@ +#pragma once + +#include "EGpDisplayDriverType.h" + +class IGpDisplayDriver; +struct GpDisplayDriverProperties; + +class GpDisplayDriverFactory +{ +public: + typedef IGpDisplayDriver *(*FactoryFunc_t)(const GpDisplayDriverProperties &properties); + + static IGpDisplayDriver *CreateDisplayDriver(const GpDisplayDriverProperties &properties); + static void RegisterDisplayDriverFactory(EGpDisplayDriverType type, FactoryFunc_t func); + +private: + static FactoryFunc_t ms_Registry[EGpDisplayDriverType_Count]; +}; diff --git a/GpD3D/GpDisplayDriverFactoryD3D11.cpp b/GpD3D/GpDisplayDriverFactoryD3D11.cpp new file mode 100644 index 0000000..33bfea2 --- /dev/null +++ b/GpD3D/GpDisplayDriverFactoryD3D11.cpp @@ -0,0 +1,7 @@ +#include "GpDisplayDriverFactoryD3D11.h" +#include "GpDisplayDriverD3D11.h" + +IGpDisplayDriver *GpDisplayDriverFactoryD3D11::Create(const GpDisplayDriverProperties &properties) +{ + return GpDisplayDriverD3D11::Create(properties); +} diff --git a/GpD3D/GpDisplayDriverFactoryD3D11.h b/GpD3D/GpDisplayDriverFactoryD3D11.h new file mode 100644 index 0000000..b540217 --- /dev/null +++ b/GpD3D/GpDisplayDriverFactoryD3D11.h @@ -0,0 +1,10 @@ +#pragma once + +class IGpDisplayDriver; +struct GpDisplayDriverProperties; + +class GpDisplayDriverFactoryD3D11 +{ +public: + static IGpDisplayDriver *Create(const GpDisplayDriverProperties &properties); +}; diff --git a/GpD3D/GpDisplayDriverProperties.h b/GpD3D/GpDisplayDriverProperties.h new file mode 100644 index 0000000..79ae5bd --- /dev/null +++ b/GpD3D/GpDisplayDriverProperties.h @@ -0,0 +1,26 @@ +#pragma once + +#include "EGpDisplayDriverType.h" + +class IGpDisplayDriver; +class GpFiber; + +struct GpDisplayDriverProperties +{ + typedef void(*TickFunc_t)(void *context, GpFiber *vosFiber); + + EGpDisplayDriverType m_Type; + + unsigned int m_FrameTimeLockNumerator; + unsigned int m_FrameTimeLockDenominator; + + unsigned int m_FrameTimeLockMinNumerator; + unsigned int m_FrameTimeLockMinDenominator; + + unsigned int m_FrameTimeLockMaxNumerator; + unsigned int m_FrameTimeLockMaxDenominator; + + // Tick function and context to call when a frame needs to be served. + TickFunc_t m_TickFunc; + void *m_TickFuncContext; +}; diff --git a/GpD3D/GpEvent.h b/GpD3D/GpEvent.h new file mode 100644 index 0000000..7ccaac1 --- /dev/null +++ b/GpD3D/GpEvent.h @@ -0,0 +1,21 @@ +#pragma once + +#include "GpCoreDefs.h" + +class GpEvent final +{ +public: + void Wait(); + void WaitMSec(unsigned int msec); + void Signal(); + void Reset(); + void Destroy(); + + static GpEvent *Create(bool autoReset, bool startSignalled); + +private: + explicit GpEvent(void *privateData); + ~GpEvent(); + + void *m_PrivateData; +}; diff --git a/GpD3D/GpEvent_Win32.cpp b/GpD3D/GpEvent_Win32.cpp new file mode 100644 index 0000000..6323697 --- /dev/null +++ b/GpD3D/GpEvent_Win32.cpp @@ -0,0 +1,49 @@ +#include "GpEvent.h" +#include "GpWindows.h" + +#include + +GpEvent::~GpEvent() +{ + CloseHandle(static_cast(m_PrivateData)); +} + +void GpEvent::Wait() +{ + WaitForSingleObject(static_cast(m_PrivateData), INFINITE); +} + +void GpEvent::WaitMSec(unsigned int msec) +{ + assert(msec < MAXDWORD); + WaitForSingleObject(static_cast(m_PrivateData), static_cast(msec)); +} + +void GpEvent::Signal() +{ + SetEvent(static_cast(m_PrivateData)); +} + +void GpEvent::Reset() +{ + ResetEvent(static_cast(m_PrivateData)); +} + +void GpEvent::Destroy() +{ + delete this; +} + +GpEvent *GpEvent::Create(bool autoReset, bool startSignalled) +{ + HANDLE handle = CreateEventA(nullptr, autoReset ? FALSE : TRUE, startSignalled ? TRUE : FALSE, nullptr); + if (!handle) + return nullptr; + + return new GpEvent(handle); +} + +GpEvent::GpEvent(void *privateData) + : m_PrivateData(privateData) +{ +} diff --git a/GpD3D/GpFiber.h b/GpD3D/GpFiber.h new file mode 100644 index 0000000..01fbd2c --- /dev/null +++ b/GpD3D/GpFiber.h @@ -0,0 +1,10 @@ +#pragma once + +#include "CoreDefs.h" + +class GpFiber +{ +public: + virtual void YieldTo() = 0; + virtual void Destroy() = 0; +}; diff --git a/GpD3D/GpFiberStarter.h b/GpD3D/GpFiberStarter.h new file mode 100644 index 0000000..24d98a8 --- /dev/null +++ b/GpD3D/GpFiberStarter.h @@ -0,0 +1,11 @@ +#pragma once + +class GpFiber; + +class GpFiberStarter +{ +public: + typedef void(*ThreadFunc_t)(void *context); + + static GpFiber *StartFiber(ThreadFunc_t threadFunc, void *context, GpFiber *creatingFiber); +}; diff --git a/GpD3D/GpFiberStarter_Win32.cpp b/GpD3D/GpFiberStarter_Win32.cpp new file mode 100644 index 0000000..d3d2c78 --- /dev/null +++ b/GpD3D/GpFiberStarter_Win32.cpp @@ -0,0 +1,52 @@ +#include "GpFiberStarter.h" +#include "GpFiber_Win32.h" +#include "GpWindows.h" + +#include + +namespace GpFiberStarter_Win32 +{ + struct FiberStartState + { + GpFiberStarter::ThreadFunc_t m_threadFunc; + GpFiber *m_creatingFiber; + void *m_context; + }; + + static VOID WINAPI FiberStartRoutine(LPVOID lpThreadParameter) + { + const FiberStartState *tss = static_cast(lpThreadParameter); + + GpFiberStarter::ThreadFunc_t threadFunc = tss->m_threadFunc; + GpFiber *creatingFiber = tss->m_creatingFiber; + void *context = tss->m_context; + creatingFiber->YieldTo(); + + threadFunc(context); + + assert(!"Fiber function exited"); + } +} + +GpFiber *GpFiberStarter::StartFiber(ThreadFunc_t threadFunc, void *context, GpFiber *creatingFiber) +{ + ULONG_PTR lowLimit; + ULONG_PTR highLimit; + + GetCurrentThreadStackLimits(&lowLimit, &highLimit); + + ULONG_PTR stackSize = highLimit - lowLimit; + + GpFiberStarter_Win32::FiberStartState startState; + startState.m_context = context; + startState.m_creatingFiber = creatingFiber; + startState.m_threadFunc = threadFunc; + + void *fiber = CreateFiber(static_cast(stackSize), GpFiberStarter_Win32::FiberStartRoutine, &startState); + if (!fiber) + return nullptr; + + SwitchToFiber(fiber); + + return new GpFiber_Win32(fiber); +} diff --git a/GpD3D/GpFiber_Win32.cpp b/GpD3D/GpFiber_Win32.cpp new file mode 100644 index 0000000..ade6202 --- /dev/null +++ b/GpD3D/GpFiber_Win32.cpp @@ -0,0 +1,17 @@ +#include "GpFiber_Win32.h" + +GpFiber_Win32::GpFiber_Win32(LPVOID fiber) + : m_fiber(fiber) +{ +} + +void GpFiber_Win32::YieldTo() +{ + SwitchToFiber(m_fiber); +} + +void GpFiber_Win32::Destroy() +{ + DeleteFiber(m_fiber); + delete this; +} diff --git a/GpD3D/GpFiber_Win32.h b/GpD3D/GpFiber_Win32.h new file mode 100644 index 0000000..9d0ea9b --- /dev/null +++ b/GpD3D/GpFiber_Win32.h @@ -0,0 +1,15 @@ +#pragma once +#include "GpWindows.h" +#include "GpFiber.h" + +class GpFiber_Win32 final : public GpFiber +{ +public: + explicit GpFiber_Win32(LPVOID fiber); + + void YieldTo() override; + void Destroy() override; + +private: + LPVOID m_fiber; +}; diff --git a/GpD3D/GpFileStream_Win32.cpp b/GpD3D/GpFileStream_Win32.cpp new file mode 100644 index 0000000..eeb3ca0 --- /dev/null +++ b/GpD3D/GpFileStream_Win32.cpp @@ -0,0 +1,141 @@ +#include "GpFileStream_Win32.h" + +GpFileStream_Win32::GpFileStream_Win32(HANDLE handle, bool readable, bool writeable, bool seekable) + : m_handle(handle) + , m_readable(readable) + , m_writeable(writeable) + , m_seekable(seekable) +{ +} + +size_t GpFileStream_Win32::Read(void *bytesOut, size_t size) +{ + if (!m_readable) + return 0; + + size_t totalRead = 0; + while (size) + { + const DWORD chunkSizeToRead = (size > MAXDWORD) ? MAXDWORD : size; + DWORD numRead = 0; + + BOOL readSucceeded = ReadFile(m_handle, bytesOut, chunkSizeToRead, &numRead, nullptr); + if (!readSucceeded) + return totalRead; + + totalRead += static_cast(numRead); + size -= static_cast(numRead); + bytesOut = static_cast(static_cast(bytesOut) + numRead); + + if (numRead != chunkSizeToRead) + return totalRead; + } + + return totalRead; +} + +size_t GpFileStream_Win32::Write(const void *bytes, size_t size) +{ + if (!m_writeable) + return 0; + + size_t totalWritten = 0; + while (size) + { + const DWORD chunkSizeToWrite = (size > MAXDWORD) ? MAXDWORD : size; + DWORD numWritten = 0; + + BOOL writeSucceeded = WriteFile(m_handle, bytes, chunkSizeToWrite, &numWritten, nullptr); + if (!writeSucceeded) + return totalWritten; + + totalWritten += static_cast(numWritten); + size -= static_cast(numWritten); + bytes = static_cast(static_cast(bytes) + numWritten); + + if (numWritten != chunkSizeToWrite) + return totalWritten; + } + + return totalWritten; +} + +bool GpFileStream_Win32::IsSeekable() const +{ + return m_seekable; +} + +bool GpFileStream_Win32::IsReadOnly() const +{ + return !m_writeable; +} + +bool GpFileStream_Win32::IsWriteOnly() const +{ + return !m_readable; +} + +bool GpFileStream_Win32::SeekStart(PortabilityLayer::UFilePos_t loc) +{ + LARGE_INTEGER li; + li.QuadPart = static_cast(loc); + return SetFilePointerEx(m_handle, li, nullptr, FILE_BEGIN) != 0; +} + +bool GpFileStream_Win32::SeekCurrent(PortabilityLayer::FilePos_t loc) +{ + LARGE_INTEGER li; + li.QuadPart = static_cast(loc); + return SetFilePointerEx(m_handle, li, nullptr, FILE_CURRENT) != 0; +} + +bool GpFileStream_Win32::SeekEnd(PortabilityLayer::UFilePos_t loc) +{ + LARGE_INTEGER li; + li.QuadPart = static_cast(loc); + return SetFilePointerEx(m_handle, li, nullptr, FILE_END) != 0; +} + +bool GpFileStream_Win32::Truncate(PortabilityLayer::UFilePos_t loc) +{ + if (!m_writeable) + return false; + + PortabilityLayer::UFilePos_t oldPos = Tell(); + if (!SeekStart(loc)) + return false; + + if (!SetEndOfFile(m_handle)) + return false; + + if (!SeekStart(oldPos)) + return false; + + return true; +} + +PortabilityLayer::UFilePos_t GpFileStream_Win32::Size() const +{ + LARGE_INTEGER fsize; + if (!GetFileSizeEx(m_handle, &fsize)) + return 0; + + return static_cast(fsize.QuadPart); +} + +PortabilityLayer::UFilePos_t GpFileStream_Win32::Tell() const +{ + LARGE_INTEGER zero; + zero.QuadPart = 0; + + LARGE_INTEGER fpos; + if (!SetFilePointerEx(m_handle, zero, &fpos, FILE_CURRENT)) + return 0; + + return static_cast(fpos.QuadPart); +} + +void GpFileStream_Win32::Close() +{ + CloseHandle(m_handle); +} diff --git a/GpD3D/GpFileStream_Win32.h b/GpD3D/GpFileStream_Win32.h new file mode 100644 index 0000000..95130b5 --- /dev/null +++ b/GpD3D/GpFileStream_Win32.h @@ -0,0 +1,30 @@ +#pragma once + +#include "GpCoreDefs.h" +#include "GpWindows.h" +#include "IOStream.h" + +class GpFileStream_Win32 final : public PortabilityLayer::IOStream +{ +public: + explicit GpFileStream_Win32(HANDLE handle, bool readable, bool writeable, bool seekable); + + size_t Read(void *bytesOut, size_t size) override; + size_t Write(const void *bytes, size_t size) override; + bool IsSeekable() const override; + bool IsReadOnly() const override; + bool IsWriteOnly() const override; + bool SeekStart(PortabilityLayer::UFilePos_t loc) override; + bool SeekCurrent(PortabilityLayer::FilePos_t loc) override; + bool SeekEnd(PortabilityLayer::UFilePos_t loc) override; + bool Truncate(PortabilityLayer::UFilePos_t loc) override; + PortabilityLayer::UFilePos_t Size() const override; + PortabilityLayer::UFilePos_t Tell() const override; + void Close() override; + +private: + HANDLE m_handle; + bool m_readable; + bool m_writeable; + bool m_seekable; +}; diff --git a/GpD3D/GpFileSystem_Win32.cpp b/GpD3D/GpFileSystem_Win32.cpp new file mode 100644 index 0000000..6959281 --- /dev/null +++ b/GpD3D/GpFileSystem_Win32.cpp @@ -0,0 +1,96 @@ +#include "GpFileSystem_Win32.h" +#include "GpFileStream_Win32.h" +#include "GpWindows.h" +#include "GpMemoryBuffer.h" + +#include +#include +#include + +GpFileSystem_Win32::GpFileSystem_Win32() +{ + PWSTR docsPath; + if (!FAILED(SHGetKnownFolderPath(FOLDERID_Documents, KF_FLAG_DEFAULT, nullptr, &docsPath))) + { + try + { + m_prefsDir = docsPath; + } + catch(...) + { + CoTaskMemFree(docsPath); + throw; + } + + m_prefsDir.append(L"\\GlidePort"); + + CreateDirectoryW(m_prefsDir.c_str(), nullptr); + m_prefsDir.append(L"\\"); + } +} + +bool GpFileSystem_Win32::FileExists(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path) +{ + wchar_t winPath[MAX_PATH + 1]; + + if (!ResolvePath(virtualDirectory, path, winPath)) + return false; + + return PathFileExistsW(winPath) != 0; +} + +PortabilityLayer::IOStream *GpFileSystem_Win32::OpenFile(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, bool writeAccess, bool create) +{ + wchar_t winPath[MAX_PATH + 1]; + + if (!ResolvePath(virtualDirectory, path, winPath)) + return false; + + const DWORD desiredAccess = writeAccess ? (GENERIC_WRITE | GENERIC_READ) : GENERIC_READ; + const DWORD creationDisposition = create ? OPEN_ALWAYS : OPEN_EXISTING; + + HANDLE h = CreateFileW(winPath, desiredAccess, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr); + + return new GpFileStream_Win32(h, true, writeAccess, true); +} + +GpFileSystem_Win32 *GpFileSystem_Win32::GetInstance() +{ + return &ms_instance; +} + +bool GpFileSystem_Win32::ResolvePath(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, wchar_t *outPath) +{ + const wchar_t *baseDir = nullptr; + + switch (virtualDirectory) + { + case PortabilityLayer::EVirtualDirectory_ApplicationData: + baseDir = L"D:\\Source Code\\GlidePort\\Packaged\\"; + break; + case PortabilityLayer::EVirtualDirectory_Prefs: + baseDir = m_prefsDir.c_str(); + break; + default: + return false; + } + + if (baseDir == nullptr) + return false; + + const size_t baseDirLen = wcslen(baseDir); + const size_t pathLen = strlen(path); + + if (baseDirLen >= MAX_PATH || MAX_PATH - baseDirLen < pathLen) + return false; + + memcpy(outPath, baseDir, sizeof(wchar_t) * baseDirLen); + for (size_t i = 0; i < pathLen; i++) + outPath[baseDirLen + i] = static_cast(path[i]); + + outPath[baseDirLen + pathLen] = static_cast(0); + + return true; +} + +GpFileSystem_Win32 GpFileSystem_Win32::ms_instance; diff --git a/GpD3D/GpFileSystem_Win32.h b/GpD3D/GpFileSystem_Win32.h new file mode 100644 index 0000000..1a91e16 --- /dev/null +++ b/GpD3D/GpFileSystem_Win32.h @@ -0,0 +1,25 @@ +#pragma once + +#include "HostFileSystem.h" + +#include "GpCoreDefs.h" + +#include + +class GpFileSystem_Win32 final : public PortabilityLayer::HostFileSystem +{ +public: + GpFileSystem_Win32(); + + bool FileExists(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path) override; + PortabilityLayer::IOStream *OpenFile(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, bool writeAccess, bool create) override; + + static GpFileSystem_Win32 *GetInstance(); + +private: + bool ResolvePath(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, wchar_t *outPath); + + std::wstring m_prefsDir; + + static GpFileSystem_Win32 ms_instance; +}; diff --git a/GpD3D/GpGlobalConfig.cpp b/GpD3D/GpGlobalConfig.cpp new file mode 100644 index 0000000..95b909c --- /dev/null +++ b/GpD3D/GpGlobalConfig.cpp @@ -0,0 +1,3 @@ +#include "GpGlobalConfig.h" + +GpGlobalConfig g_gpGlobalConfig; diff --git a/GpD3D/GpGlobalConfig.h b/GpD3D/GpGlobalConfig.h new file mode 100644 index 0000000..54e8bcb --- /dev/null +++ b/GpD3D/GpGlobalConfig.h @@ -0,0 +1,10 @@ +#pragma once + +#include "EGpDisplayDriverType.h" + +struct GpGlobalConfig +{ + EGpDisplayDriverType m_displayDriverType; +}; + +extern GpGlobalConfig g_gpGlobalConfig; diff --git a/GpD3D/GpMain.cpp b/GpD3D/GpMain.cpp new file mode 100644 index 0000000..25ee433 --- /dev/null +++ b/GpD3D/GpMain.cpp @@ -0,0 +1,48 @@ +#include "GpMain.h" +#include "GpDisplayDriverFactory.h" +#include "GpDisplayDriverProperties.h" +#include "GpGlobalConfig.h" +#include "GpAppEnvironment.h" +#include "IGpDisplayDriver.h" + +#include + +namespace +{ + void TickAppEnvironment(void *context, GpFiber *vosFiber) + { + static_cast(context)->Tick(vosFiber); + } +} + +int GpMain::Run() +{ + GpAppEnvironment *appEnvironment = new GpAppEnvironment(); + + GpDisplayDriverProperties ddProps; + memset(&ddProps, 0, sizeof(ddProps)); + + ddProps.m_FrameTimeLockNumerator = 1; + ddProps.m_FrameTimeLockDenominator = 60; + + // +/- 1% tolerance for frame time variance + ddProps.m_FrameTimeLockMinNumerator = 99; + ddProps.m_FrameTimeLockMinDenominator = 6000; + ddProps.m_FrameTimeLockMaxNumerator = 101; + ddProps.m_FrameTimeLockMaxDenominator = 6000; + + ddProps.m_TickFunc = TickAppEnvironment; + ddProps.m_TickFuncContext = appEnvironment; + ddProps.m_Type = g_gpGlobalConfig.m_displayDriverType; + + IGpDisplayDriver *displayDriver = GpDisplayDriverFactory::CreateDisplayDriver(ddProps); + + appEnvironment->Init(); + + appEnvironment->SetDisplayDriver(displayDriver); + + // Start the display loop + displayDriver->Run(); + + return 0; +} diff --git a/GpD3D/GpMain.h b/GpD3D/GpMain.h new file mode 100644 index 0000000..7d15e06 --- /dev/null +++ b/GpD3D/GpMain.h @@ -0,0 +1,6 @@ +#pragma once + +namespace GpMain +{ + int Run(); +} diff --git a/GpD3D/GpMain_Win32.cpp b/GpD3D/GpMain_Win32.cpp new file mode 100644 index 0000000..f55a8bd --- /dev/null +++ b/GpD3D/GpMain_Win32.cpp @@ -0,0 +1,33 @@ +#include "GpWindows.h" +#include "GpMain.h" +#include "GpDisplayDriverFactory.h" +#include "GpDisplayDriverFactoryD3D11.h" +#include "GpGlobalConfig.h" +#include "GpFileSystem_Win32.h" +#include "GpAppInterface.h" +#include "GpSystemServices_Win32.h" + +#include "HostFileSystem.h" + +#include + +#include + +GPWindowsGlobals g_gpWindowsGlobals; + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) +{ + GpAppInterface_Get()->PL_HostFileSystem_SetInstance(GpFileSystem_Win32::GetInstance()); + GpAppInterface_Get()->PL_HostSystemServices_SetInstance(GpSystemServices_Win32::GetInstance()); + + g_gpWindowsGlobals.m_hInstance = hInstance; + g_gpWindowsGlobals.m_hPrevInstance = hPrevInstance; + g_gpWindowsGlobals.m_cmdLine = lpCmdLine; + g_gpWindowsGlobals.m_nCmdShow = nCmdShow; + + g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_D3D11; + + GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDisplayDriverFactoryD3D11::Create); + + return GpMain::Run(); +} diff --git a/GpD3D/GpMemoryBuffer.cpp b/GpD3D/GpMemoryBuffer.cpp new file mode 100644 index 0000000..74930f7 --- /dev/null +++ b/GpD3D/GpMemoryBuffer.cpp @@ -0,0 +1,49 @@ +#include "GpMemoryBuffer.h" + +#include + +void *GpMemoryBuffer::Contents() +{ + return reinterpret_cast(this) + AlignedSize(); +} + +size_t GpMemoryBuffer::Size() +{ + return m_size; +} + +void GpMemoryBuffer::Destroy() +{ + delete[] reinterpret_cast(this); +} + +GpMemoryBuffer *GpMemoryBuffer::Create(size_t sz) +{ + const size_t allowedSize = SIZE_MAX - AlignedSize(); + if (sz > allowedSize) + return nullptr; + + const size_t bufferSize = GpMemoryBuffer::AlignedSize() + sz; + + uint8_t *buffer = new uint8_t[bufferSize]; + new (buffer) GpMemoryBuffer(sz); + + return reinterpret_cast(buffer); +} + +GpMemoryBuffer::GpMemoryBuffer(size_t sz) + : m_size(sz) +{ +} + +GpMemoryBuffer::~GpMemoryBuffer() +{ +} + +size_t GpMemoryBuffer::AlignedSize() +{ + const size_t paddedSize = (sizeof(GpMemoryBuffer) + PL_SYSTEM_MEMORY_ALIGNMENT - 1); + const size_t sz = paddedSize - paddedSize % PL_SYSTEM_MEMORY_ALIGNMENT; + + return sz; +} diff --git a/GpD3D/GpMemoryBuffer.h b/GpD3D/GpMemoryBuffer.h new file mode 100644 index 0000000..d5ea10d --- /dev/null +++ b/GpD3D/GpMemoryBuffer.h @@ -0,0 +1,21 @@ +#pragma once + +#include "HostMemoryBuffer.h" + +class GpMemoryBuffer final : public PortabilityLayer::HostMemoryBuffer +{ +public: + void *Contents() override; + size_t Size() override; + void Destroy() override; + + static GpMemoryBuffer *Create(size_t sz); + +private: + explicit GpMemoryBuffer(size_t sz); + ~GpMemoryBuffer(); + + static size_t AlignedSize(); + + size_t m_size; +}; diff --git a/GpD3D/GpPLGlueDisplayDriver.cpp b/GpD3D/GpPLGlueDisplayDriver.cpp new file mode 100644 index 0000000..c7ab62d --- /dev/null +++ b/GpD3D/GpPLGlueDisplayDriver.cpp @@ -0,0 +1,28 @@ +#include "GpPLGlueDisplayDriver.h" +#include "IGpDisplayDriver.h" + +GpPLGlueDisplayDriver::GpPLGlueDisplayDriver() + : m_displayDriver(nullptr) +{ +} + +void GpPLGlueDisplayDriver::GetDisplayResolution(unsigned int &width, unsigned int &height) +{ + m_displayDriver->GetDisplayResolution(width, height); +} + +void GpPLGlueDisplayDriver::HideCursor() +{ +} + +GpPLGlueDisplayDriver *GpPLGlueDisplayDriver::GetInstance() +{ + return &ms_instance; +} + +void GpPLGlueDisplayDriver::SetGpDisplayDriver(IGpDisplayDriver *displayDriver) +{ + m_displayDriver = displayDriver; +} + +GpPLGlueDisplayDriver GpPLGlueDisplayDriver::ms_instance; diff --git a/GpD3D/GpPLGlueDisplayDriver.h b/GpD3D/GpPLGlueDisplayDriver.h new file mode 100644 index 0000000..6ded7c4 --- /dev/null +++ b/GpD3D/GpPLGlueDisplayDriver.h @@ -0,0 +1,23 @@ +#pragma once + +#include "HostDisplayDriver.h" + +class IGpDisplayDriver; + +class GpPLGlueDisplayDriver final : public PortabilityLayer::HostDisplayDriver +{ +public: + GpPLGlueDisplayDriver(); + + void GetDisplayResolution(unsigned int &width, unsigned int &height) override; + void HideCursor() override; + + void SetGpDisplayDriver(IGpDisplayDriver *displayDriver); + + static GpPLGlueDisplayDriver *GetInstance(); + +private: + IGpDisplayDriver *m_displayDriver; + + static GpPLGlueDisplayDriver ms_instance; +}; diff --git a/GpD3D/GpRingBuffer.h b/GpD3D/GpRingBuffer.h new file mode 100644 index 0000000..2e8eb4b --- /dev/null +++ b/GpD3D/GpRingBuffer.h @@ -0,0 +1,63 @@ +#pragma once + +#include +#include + +#include "GpCoreDefs.h" + +template +class GpRingBuffer +{ +public: + GpRingBuffer() + : m_Size(0) + , m_Start(0) + { + } + + TItem &operator[](size_t index) + { + assert(index < m_Size); + return m_Items[(m_Start + index) % TCapacity]; + } + + void RemoveFromStart() + { + assert(m_Size >= 1); + m_Start = (m_Start + 1) % TCapacity; + m_Size--; + } + + void RemoveFromEnd() + { + assert(m_Size >= 1); + m_Size--; + } + + void Clear() + { + m_Size = 0; + m_Start = 0; + } + + size_t Size() const + { + return m_Size; + } + + TItem *Append() + { + if (m_Size == TCapacity) + return nullptr; + + m_Size++; + return &m_Items[(m_Start + (m_Size - 1)) % TCapacity]; + } + + static const size_t CAPACITY = TCapacity; + +private: + TItem m_Items[TCapacity]; + size_t m_Size; + size_t m_Start; +}; \ No newline at end of file diff --git a/GpD3D/GpSystemServices_Win32.cpp b/GpD3D/GpSystemServices_Win32.cpp new file mode 100644 index 0000000..42c6328 --- /dev/null +++ b/GpD3D/GpSystemServices_Win32.cpp @@ -0,0 +1,19 @@ +#include "GpSystemServices_Win32.h" + +#include + +GpSystemServices_Win32::GpSystemServices_Win32() +{ +} + +uint32_t GpSystemServices_Win32::GetTime() const +{ + return 0; +} + +GpSystemServices_Win32 *GpSystemServices_Win32::GetInstance() +{ + return &ms_instance; +} + +GpSystemServices_Win32 GpSystemServices_Win32::ms_instance; diff --git a/GpD3D/GpSystemServices_Win32.h b/GpD3D/GpSystemServices_Win32.h new file mode 100644 index 0000000..89b089e --- /dev/null +++ b/GpD3D/GpSystemServices_Win32.h @@ -0,0 +1,19 @@ +#pragma once + +#include "HostSystemServices.h" +#include "GpCoreDefs.h" +#include "GpWindows.h" + + +class GpSystemServices_Win32 final : public PortabilityLayer::HostSystemServices +{ +public: + GpSystemServices_Win32(); + + uint32_t GetTime() const override; + + static GpSystemServices_Win32 *GetInstance(); + +private: + static GpSystemServices_Win32 ms_instance; +}; diff --git a/GpD3D/GpWindows.h b/GpD3D/GpWindows.h new file mode 100644 index 0000000..b1441e7 --- /dev/null +++ b/GpD3D/GpWindows.h @@ -0,0 +1,16 @@ +#pragma once + +#define NOMINMAX +#define WIN32_LEAN_AND_MEAN + +#include + +struct GPWindowsGlobals +{ + HINSTANCE m_hInstance; + HINSTANCE m_hPrevInstance; + LPSTR m_cmdLine; + int m_nCmdShow; +}; + +extern GPWindowsGlobals g_gpWindowsGlobals; diff --git a/GpD3D/IGpDisplayDriver.h b/GpD3D/IGpDisplayDriver.h new file mode 100644 index 0000000..a2231d7 --- /dev/null +++ b/GpD3D/IGpDisplayDriver.h @@ -0,0 +1,13 @@ +#pragma once + +// Display drivers are responsible for timing and calling the game tick function. +class IGpDisplayDriver +{ +public: + virtual ~IGpDisplayDriver() {} + + virtual void Run() = 0; + virtual void Shutdown() = 0; + + virtual void GetDisplayResolution(unsigned int &width, unsigned int &height) = 0; +}; diff --git a/GpD3D/x64/Debug/vc141.idb b/GpD3D/x64/Debug/vc141.idb new file mode 100644 index 0000000..8c4b4fa Binary files /dev/null and b/GpD3D/x64/Debug/vc141.idb differ diff --git a/Headers/About.h b/Headers/About.h deleted file mode 100755 index 1f8c23d..0000000 --- a/Headers/About.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // About.h //---------------------------------------------------------------------------- //============================================================================ void DoAbout (void); \ No newline at end of file diff --git a/Headers/DialogUtils.h b/Headers/DialogUtils.h deleted file mode 100755 index 1a81109..0000000 --- a/Headers/DialogUtils.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // DialogUtils.h //---------------------------------------------------------------------------- //============================================================================ #include void BringUpDialog (DialogPtr *theDialog, short dialogID); //void GetPutDialogCorner (Point *); //void GetGetDialogCorner (Point *); //void CenterDialog (short); void GetDialogRect (Rect *, short); //void TrueCenterDialog (short); //void CenterAlert (short); //void ZoomOutDialogRect (short); //void ZoomOutAlertRect (short); void FlashDialogButton (DialogPtr, short); void DrawDefaultButton (DialogPtr); void GetDialogString (DialogPtr, short, StringPtr); void SetDialogString (DialogPtr, short, StringPtr); short GetDialogStringLen (DialogPtr, short); void GetDialogItemValue (DialogPtr, short, short *); void SetDialogItemValue (DialogPtr, short, short); void ToggleDialogItemValue (DialogPtr, short); void SetDialogNumToStr (DialogPtr, short, long); void GetDialogNumFromStr (DialogPtr, short, long *); void GetDialogItemRect (DialogPtr, short, Rect *); void SetDialogItemRect (DialogPtr, short, Rect *); void OffsetDialogItemRect (DialogPtr, short, short, short); void SelectFromRadioGroup (DialogPtr, short, short, short); //void AddMenuToPopUp (DialogPtr, short, MenuHandle); void GetPopUpMenuValue (DialogPtr, short, short *); void SetPopUpMenuValue (DialogPtr, short, short); void MyEnableControl(DialogPtr, short); void MyDisableControl(DialogPtr, short); void DrawDialogUserText (DialogPtr, short, StringPtr, Boolean); void DrawDialogUserText2 (DialogPtr, short, StringPtr); void LoadDialogPICT (DialogPtr, short, short); void FrameDialogItem (DialogPtr, short); void FrameDialogItemC (DialogPtr, short, long); void FrameOvalDialogItem (DialogPtr, short); void BorderDialogItem (DialogPtr, short, short); void ShadowDialogItem (DialogPtr, short, short); void EraseDialogItem (DialogPtr, short); \ No newline at end of file diff --git a/Headers/Environ.h b/Headers/Environ.h deleted file mode 100755 index 1c972bc..0000000 --- a/Headers/Environ.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Environ.h //---------------------------------------------------------------------------- //============================================================================ #include typedef struct { Rect screen, gray; long dirID; short wasDepth, isDepth; short thisResFile; short numScreens; short vRefNum; Boolean can1Bit; Boolean can4Bit; Boolean can8Bit; Boolean wasColorOrGray; Boolean hasWNE; Boolean hasSystem7; Boolean hasColor; Boolean hasGestalt; Boolean canSwitch; Boolean canColor; Boolean hasSM3; Boolean hasQT; Boolean hasDrag; } macEnviron; extern macEnviron thisMac; \ No newline at end of file diff --git a/Headers/Externs.h b/Headers/Externs.h deleted file mode 100755 index 39b299f..0000000 --- a/Headers/Externs.h +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Externs.h //---------------------------------------------------------------------------- //============================================================================ #pragma once #include #define kPreferredDepth 8 #define kNilPointer 0L #define kPutInFront (WindowPtr)-1L #define kNormalUpdates TRUE #define kOneKilobyte 1024 #define kOkayButton 1 #define kCancelButton 2 #define kControlActive 0 #define kControlInactive 255 #define kAsynch TRUE #define kSynch FALSE #define kHomeKeyASCII 0x01 #define kEnterKeyASCII 0x03 #define kEndKeyASCII 0x04 #define kHelpKeyASCII 0x05 #define kDeleteKeyASCII 0x08 #define kTabKeyASCII 0x09 #define kPageUpKeyASCII 0x0B #define kPageDownKeyASCII 0x0C #define kReturnKeyASCII 0x0D #define kFunctionKeyASCII 0x10 #define kClearKeyASCII 0x1A #define kEscapeKeyASCII 0x1B #define kLeftArrowKeyASCII 0x1C #define kRightArrowKeyASCII 0x1D #define kUpArrowKeyASCII 0x1E #define kDownArrowKeyASCII 0x1F #define kSpaceBarASCII 0x20 #define kExclamationASCII 0x21 #define kPlusKeyASCII 0x2B #define kMinusKeyASCII 0x2D #define k0KeyASCII 0x30 #define k1KeyASCII 0x31 #define k2KeyASCII 0x32 #define k3KeyASCII 0x33 #define k4KeyASCII 0x34 #define k5KeyASCII 0x35 #define k6KeyASCII 0x36 #define k7KeyASCII 0x37 #define k8KeyASCII 0x38 #define k9KeyASCII 0x39 #define kCapAKeyASCII 0x41 #define kCapBKeyASCII 0x42 #define kCapCKeyASCII 0x43 #define kCapDKeyASCII 0x44 #define kCapEKeyASCII 0x45 #define kCapFKeyASCII 0x46 #define kCapGKeyASCII 0x47 #define kCapHKeyASCII 0x48 #define kCapIKeyASCII 0x49 #define kCapJKeyASCII 0x4A #define kCapKKeyASCII 0x4B #define kCapLKeyASCII 0x4C #define kCapMKeyASCII 0x4D #define kCapNKeyASCII 0x4E #define kCapOKeyASCII 0x4F #define kCapPKeyASCII 0x50 #define kCapQKeyASCII 0x51 #define kCapRKeyASCII 0x52 #define kCapSKeyASCII 0x53 #define kCapTKeyASCII 0x54 #define kCapUKeyASCII 0x55 #define kCapVKeyASCII 0x56 #define kCapWKeyASCII 0x57 #define kCapXKeyASCII 0x58 #define kCapYKeyASCII 0x59 #define kCapZKeyASCII 0x5A #define kAKeyASCII 0x61 #define kBKeyASCII 0x62 #define kCKeyASCII 0x63 #define kDKeyASCII 0x64 #define kEKeyASCII 0x65 #define kFKeyASCII 0x66 #define kGKeyASCII 0x67 #define kHKeyASCII 0x68 #define kIKeyASCII 0x69 #define kJKeyASCII 0x6A #define kKKeyASCII 0x6B #define kLKeyASCII 0x6C #define kMKeyASCII 0x6D #define kNKeyASCII 0x6E #define kOKeyASCII 0x6F #define kPKeyASCII 0x70 #define kQKeyASCII 0x71 #define kRKeyASCII 0x72 #define kSKeyASCII 0x73 #define kTKeyASCII 0x74 #define kUKeyASCII 0x75 #define kVKeyASCII 0x76 #define kWKeyASCII 0x77 #define kXKeyASCII 0x78 #define kYKeyASCII 0x79 #define kZKeyASCII 0x7A #define kForwardDeleteASCII 0x7F #define kPlusKeypadMap 66 // key map offset for + on keypad #define kMinusKeypadMap 73 // key map offset for - on keypad #define kTimesKeypadMap 68 // key map offset for * on keypad #define k0KeypadMap 85 // key map offset for 0 on keypad #define k1KeypadMap 84 // key map offset for 1 on keypad #define k2KeypadMap 83 // key map offset for 2 on keypad #define k3KeypadMap 82 // key map offset for 3 on keypad #define k4KeypadMap 81 // key map offset for 4 on keypad #define k5KeypadMap 80 // key map offset for 5 on keypad #define k6KeypadMap 95 // key map offset for 6 on keypad #define k7KeypadMap 94 // key map offset for 7 on keypad #define k8KeypadMap 92 // key map offset for 8 on keypad #define k9KeypadMap 91 // key map offset for 9 on keypad #define kUpArrowKeyMap 121 // key map offset for up arrow #define kDownArrowKeyMap 122 // key map offset for down arrow #define kRightArrowKeyMap 123 // key map offset for right arrow #define kLeftArrowKeyMap 124 // key map offset for left arrow #define kAKeyMap 7 #define kBKeyMap 12 #define kCKeyMap 15 #define kDKeyMap 5 #define kEKeyMap 9 #define kFKeyMap 4 #define kGKeyMap 2 #define kHKeyMap 3 #define kMKeyMap 41 #define kNKeyMap 42 #define kOKeyMap 24 #define kPKeyMap 36 #define kQKeyMap 11 #define kRKeyMap 8 #define kSKeyMap 6 #define kTKeyMap 22 #define kVKeyMap 14 #define kWKeyMap 10 #define kXKeyMap 0 #define kZKeyMap 1 #define kPeriodKeyMap 40 #define kCommandKeyMap 48 #define kEscKeyMap 50 #define kDeleteKeyMap 52 #define kSpaceBarMap 54 #define kTabKeyMap 55 #define kControlKeyMap 60 #define kOptionKeyMap 61 #define kCapsLockKeyMap 62 #define kShiftKeyMap 63 #define kTabRawKey 0x30 // key map offset for Tab key #define kClearRawKey 0x47 // key map offset for Clear key #define kF5RawKey 0x60 // key map offset for F5 #define kF6RawKey 0x61 // key map offset for F6 #define kF7RawKey 0x62 // key map offset for F7 #define kF3RawKey 0x63 // key map offset for F3 #define kF8RawKey 0x64 // key map offset for F8 #define kF9RawKey 0x65 // key map offset for F9 #define kF11RawKey 0x67 // key map offset for F11 #define kF13RawKey 0x69 // key map offset for F13 #define kF14RawKey 0x6B // key map offset for F14 #define kF10RawKey 0x6D // key map offset for F10 #define kF12RawKey 0x6F // key map offset for F12 #define kF15RawKey 0x71 // key map offset for F15 #define kF4RawKey 0x76 // key map offset for F4 #define kF2RawKey 0x78 // key map offset for F2 #define kF1RawKey 0x7A // key map offset for F1 #define kErrUnnaccounted 1 #define kErrNoMemory 2 #define kErrDialogDidntLoad 3 #define kErrFailedResourceLoad 4 #define kErrFailedGraphicLoad 5 #define kErrFailedOurDirect 6 #define kErrFailedValidation 7 #define kErrNeedSystem7 8 #define kErrFailedGetDevice 9 #define kErrFailedMemoryOperation 10 #define kErrFailedCatSearch 11 #define kErrNeedColorQD 12 #define kErrNeed16Or256Colors 13 #define iAbout 1 #define iNewGame 1 #define iTwoPlayer 2 #define iOpenSavedGame 3 #define iLoadHouse 5 #define iQuit 7 #define iEditor 1 #define iHighScores 3 #define iPrefs 4 #define iHelp 5 #define iNewHouse 1 #define iSave 2 #define iHouse 4 #define iRoom 5 #define iObject 6 #define iCut 8 #define iCopy 9 #define iPaste 10 #define iClear 11 #define iDuplicate 12 #define iBringForward 14 #define iSendBack 15 #define iGoToRoom 17 #define iMapWindow 19 #define iObjectWindow 20 #define iCoordinateWindow 21 //-------------------------------------------------------------- Structs /* typedef short SICN[16]; typedef SICN *SICNList; typedef SICNList *SICNHand; */ #pragma options align=mac68k typedef struct { Str32 wasDefaultName; Str15 wasLeftName, wasRightName; Str15 wasBattName, wasBandName; Str15 wasHighName; Str31 wasHighBanner; // long encrypted, fakeLong; long wasLeftMap, wasRightMap; long wasBattMap, wasBandMap; short wasVolume; short prefVersion; short wasMaxFiles; short wasEditH, wasEditV; short wasMapH, wasMapV; short wasMapWide, wasMapHigh; short wasToolsH, wasToolsV; short wasLinkH, wasLinkV; short wasCoordH, wasCoordV; short isMapLeft, isMapTop; short wasNumNeighbors; short wasDepthPref; short wasToolGroup; short smWarnings; short wasFloor, wasSuite; Boolean wasZooms, wasMusicOn; Boolean wasAutoEdit, wasDoColorFade; Boolean wasMapOpen, wasToolsOpen; Boolean wasCoordOpen, wasQuickTrans; Boolean wasIdleMusic, wasGameMusic; Boolean wasEscPauseKey; Boolean wasDoAutoDemo, wasScreen2; Boolean wasDoBackground, wasHouseChecks; Boolean wasPrettyMap, wasBitchDialogs; } prefsInfo; #pragma options align=reset //-------------------------------------------------------------- Prototypes void DoAbout (void); // --- About.c void LoadCursors (void); // --- AnimCursor.c void DisposCursors (void); void IncrementCursor (void); void DecrementCursor (void); void SpinCursor (short); void BackSpinCursor (short); void ColorText (StringPtr, long); // --- ColorUtils.c void ColorRect (Rect *, long); void ColorOval (Rect *, long); void ColorRegion (RgnHandle, long); void ColorLine (short, short, short, short, long); void HiliteRect (Rect *, short, short); void ColorFrameRect (Rect *, long); void ColorFrameWHRect (short, short, short, short, long); void ColorFrameOval (Rect *, long); void LtGrayForeColor (void); void GrayForeColor (void); void DkGrayForeColor (void); void RestoreColorsSlam (void); void MonitorWait (void); // --- DebugUtils.c void DisplayRect (Rect *); void FlashRect (Rect *); void CheckLegitRect(Rect *, Rect *); void DisplayLong (long); void DisplayShort (short); void FlashLong (long); void FlashShort (short); void DoBarGraph (short, short, short, short); short BetaOkay (void); void DebugNum (long); void DisplayCTSeed (CGrafPtr); void FillScreenRed (void); void DumpToResEditFile (Ptr, long); void HandleEvent (void); // --- Event.c void HiliteAllWindows (void); void IgnoreThisClick (void); short WhatsOurDepth (void); // --- Environs.c void SwitchToDepth (short, Boolean); void CheckOurEnvirons (void); //void ReflectSecondMonitorEnvirons (Boolean, Boolean, Boolean); void HandleDepthSwitching (void); void RestoreColorDepth (void); void CheckMemorySize (void); void SetAppMemorySize (long); Boolean CheckFileError (short, StringPtr); // --- File Error.c Boolean SavePrefs (prefsInfo *, short); // --- Prefs.c Boolean LoadPrefs (prefsInfo *, short); void PasStringCopy (StringPtr, StringPtr); // --- StringUtils.c short WhichStringFirst (StringPtr, StringPtr); void PasStringCopyNum (StringPtr, StringPtr, short); void PasStringConcat (StringPtr, StringPtr); void GetLineOfText (StringPtr, short, StringPtr); void WrapText (StringPtr, short); void GetFirstWordOfString (StringPtr, StringPtr); void CollapseStringToWidth (StringPtr, short); void GetChooserName (StringPtr); StringPtr GetLocalizedString (short, StringPtr); Point MyGetGlobalMouse (void); // --- Utilities.c void ToolBoxInit (void); void FindOurDevice (void); short RandomInt (short); long RandomLong (long); void InitRandomLongQUS (void); unsigned long RandomLongQUS (void); //void CenterAlert (short); void RedAlert (short); //void CreateOffScreenBitMap (Rect *, GrafPtr *); //void CreateOffScreenPixMap (Rect *, CGrafPtr *); //void KillOffScreenPixMap (CGrafPtr); //void KillOffScreenBitMap (GrafPtr); void LoadGraphic (short); void LoadScaledGraphic (short, Rect *); //void PlotSICN (Rect *, SICNHand, long); void LargeIconPlot (Rect *, short); void DrawCIcon (short, short, short); char KeyMapOffsetFromRawKey (char); long LongSquareRoot (long); //void HideMenuBarOld (void); //void ShowMenuBarOld (void); Boolean WaitForInputEvent (short); void WaitCommandQReleased (void); char GetKeyMapFromMessage (long); void GetKeyName (long, StringPtr); Boolean OptionKeyDown (void); long ExtractCTSeed (CGrafPtr); //void ForceCTSeed (CGrafPtr, long); void DelayTicks (long); void UnivGetSoundVolume (short *, Boolean); void UnivSetSoundVolume (short, Boolean); Boolean ValidInstallation (Boolean); // --- Validate.c void GetWindowLeftTop (WindowPtr, short *, short *); // --- WindowUtils.c void GetWindowRect (WindowPtr, Rect *); void GetLocalWindowRect (WindowPtr, Rect *); //void FlagWindowFloating (WindowPtr); //Boolean IsWindowFloating (WindowPtr); void OpenMessageWindow (StringPtr); void SetMessageWindowMessage (StringPtr); void CloseMessageWindow (void); void CloseThisWindow (WindowPtr *); #ifdef powerc // extern pascal void SetSoundVol(short level); // for old Sound Manager // extern pascal void GetSoundVol(short *level) // THREEWORDINLINE(0x4218, 0x10B8, 0x0260); #endif #include "GliderDefines.h" #include "GliderStructs.h" #include "GliderVars.h" #include "GliderProtos.h" \ No newline at end of file diff --git a/Headers/GameOver.h b/Headers/GameOver.h deleted file mode 100755 index d90c6f9..0000000 --- a/Headers/GameOver.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // GameOver.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr angelSrcMap; extern GWorldPtr angelMaskMap; \ No newline at end of file diff --git a/Headers/GliderDefines.h b/Headers/GliderDefines.h deleted file mode 100755 index 015e91d..0000000 --- a/Headers/GliderDefines.h +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // GliderDefines.h //---------------------------------------------------------------------------- //============================================================================ //============================================================== Defines //#define CREATEDEMODATA //#define COMPILEDEMO //#define CAREFULDEBUG #define COMPILENOCP #define COMPILEQT #define BUILD_ARCADE_VERSION 1 #define kYellowUnaccounted 1 #define kYellowFailedResOpen 2 #define kYellowFailedResAdd 3 #define kYellowFailedResCreate 4 #define kYellowNoHouses 5 #define kYellowNewerVersion 6 #define kYellowNoBackground 7 #define kYellowIllegalRoomNum 8 #define kYellowNoBoundsRes 9 #define kYellowScrapError 10 #define kYellowNoMemory 11 #define kYellowFailedWrite 12 #define kYellowNoMusic 13 #define kYellowFailedSound 14 #define kYellowAppleEventErr 15 #define kYellowOpenedOldHouse 16 #define kYellowLostAllHouses 17 #define kYellowFailedSaveGame 18 #define kYellowSavedTimeWrong 19 #define kYellowSavedVersWrong 20 #define kYellowSavedRoomsWrong 21 #define kYellowQTMovieNotLoaded 22 #define kYellowNoRooms 23 #define kYellowCantOrderLinks 24 #define kSwitchIfNeeded 0 #define kSwitchTo256Colors 1 #define kSwitchTo16Grays 2 #define kProdGameScoreMode -4 #define kKickGameScoreMode -3 #define kPlayGameScoreMode -2 #define kPlayWholeScoreMode -1 #define kPlayChorus 4 #define kPlayRefrainSparse1 5 #define kPlayRefrainSparse2 6 #define kHitWallSound 0 // ¥¥¥¥¥¥ #define kFadeInSound 1 // ¥¥ #define kFadeOutSound 2 // ¥¥¥¥¥¥ #define kBeepsSound 3 // ¥¥ #define kBuzzerSound 4 // ¥¥¥¥¥¥ #define kDingSound 5 // #define kEnergizeSound 6 // ¥¥¥¥¥¥ #define kFollowSound 7 // ¥¥ ¥¥ #define kMicrowavedSound 8 // ¥¥ ¥¥ #define kSwitchSound 9 // ¥¥ ¥¥ #define kBirdSound 10 // ¥¥¥¥¥¥ #define kCuckooSound 11 // #define kTikSound 12 // ¥¥ ¥¥ #define kTokSound 13 // ¥¥ ¥¥ #define kBlowerOn 14 // ¥¥ ¥¥ #define kBlowerOff 15 // ¥¥ ¥¥ #define kCaughtFireSound 16 // ¥¥¥¥¥¥ #define kScoreTikSound 17 // #define kThrustSound 18 // ¥¥¥ ¥¥ #define kFizzleSound 19 // ¥¥¥¥ ¥¥ #define kFireBandSound 20 // ¥¥ ¥¥ ¥¥ #define kBandReboundSound 21 // ¥¥ ¥¥¥¥ #define kGreaseSpillSound 22 // ¥¥ ¥¥¥ #define kChordSound 23 // #define kVCRSound 24 // ¥¥¥¥¥¥¥ #define kFoilHitSound 25 // ¥¥ ¥¥ #define kShredSound 26 // ¥¥ ¥¥ #define kToastLaunchSound 27 // ¥¥ ¥¥ #define kToastLandSound 28 // ¥¥¥¥¥¥¥ #define kMacOnSound 29 // #define kMacBeepSound 30 // #define kMacOffSound 31 // #define kTVOnSound 32 // #define kTVOffSound 33 // ¥¥¥¥¥¥ #define kCoffeeSound 34 // ¥¥ #define kMysticSound 35 // ¥¥¥¥¥¥ #define kZapSound 36 // ¥¥ #define kPopSound 37 // ¥¥¥¥¥¥ #define kEnemyInSound 38 // #define kEnemyOutSound 39 // ¥¥¥¥¥¥ #define kPaperCrunchSound 40 // ¥¥ ¥¥ #define kBounceSound 41 // ¥¥ ¥¥ #define kDripSound 42 // ¥¥ ¥¥ #define kDropSound 43 // ¥¥¥¥¥¥ #define kFishOutSound 44 // #define kFishInSound 45 // ¥¥ ¥¥ #define kDontExitSound 46 // ¥¥ ¥¥ #define kSizzleSound 47 // ¥¥ ¥¥ #define kPaper1Sound 48 // ¥¥ ¥¥ #define kPaper2Sound 49 // ¥¥¥¥¥¥ #define kPaper3Sound 50 // #define kPaper4Sound 51 // ¥¥¥ ¥¥ #define kTypingSound 52 // ¥¥¥¥ ¥¥ #define kCarriageSound 53 // ¥¥ ¥¥ ¥¥ #define kChord2Sound 54 // ¥¥ ¥¥¥¥ #define kPhoneRingSound 55 // ¥¥ ¥¥¥ #define kChime1Sound 56 // #define kChime2Sound 57 // ¥¥¥¥¥¥¥ #define kWebTwangSound 58 // ¥¥ ¥¥ #define kTransOutSound 59 // ¥¥ ¥¥ #define kTransInSound 60 // ¥¥ ¥¥ #define kBonusSound 61 // ¥¥¥¥¥¥¥ #define kHissSound 62 // #define kTriggerSound 63 #define kHitWallPriority 100 // ¥¥¥¥¥¥ #define kScoreTikPriority 101 // ¥¥ #define kBandReboundPriority 102 // ¥¥¥¥¥¥ #define kDontExitPriority 103 // ¥¥ #define kTikPriority 200 // ¥¥¥¥¥¥ #define kTokPriority 201 // #define kMysticPriority 202 // ¥¥¥¥¥¥ #define kChime1Priority 203 // ¥¥ ¥¥ #define kChime2Priority 204 // ¥¥ ¥¥ #define kThrustPriority 300 // ¥¥ ¥¥ #define kFireBandPriority 301 // ¥¥¥¥¥¥ #define kChordPriority 302 // #define kVCRPriority 303 // ¥¥ ¥¥ #define kToastLaunchPriority 304 // ¥¥ ¥¥ #define kToastLandPriority 305 // ¥¥ ¥¥ #define kCoffeePriority 306 // ¥¥ ¥¥ #define kBouncePriority 307 // ¥¥¥¥¥¥ #define kDripPriority 308 // #define kDropPriority 309 // ¥¥¥ ¥¥ #define kWebTwangPriority 310 // ¥¥¥¥ ¥¥ #define kHissPriority 311 // ¥¥ ¥¥ ¥¥ #define kFoilHitPriority 400 // ¥¥ ¥¥¥¥ #define kMacOnPriority 401 // ¥¥ ¥¥¥ #define kMacOffPriority 402 // #define kMacBeepPriority 403 // ¥¥¥¥¥¥¥ #define kTVOnPriority 404 // ¥¥ ¥¥ #define kTVOffPriority 405 // ¥¥ ¥¥ #define kZapPriority 406 // ¥¥ ¥¥ #define kPopPriority 407 // ¥¥¥¥¥¥¥ #define kEnemyInPriority 408 // #define kEnemyOutPriority 409 // #define kPaperCrunchPriority 410 // #define kFishOutPriority 411 // #define kFishInPriority 412 // #define kSizzlePriority 413 #define kPhoneRingPriority 500 #define kSwitchPriority 700 #define kBlowerOnPriority 701 #define kBlowerOffPriority 702 #define kFizzlePriority 703 #define kBeepsPriority 800 #define kBuzzerPriority 801 #define kDingPriority 802 #define kEnergizePriority 803 #define kBirdPriority 804 #define kCuckooPriority 805 #define kGreaseSpillPriority 806 #define kPapersPriority 807 #define kTypingPriority 808 #define kCarriagePriority 809 #define kChord2Priority 810 #define kMicrowavedPriority 811 #define kBonusPriority 812 #define kFadeInPriority 900 #define kFadeOutPriority 901 #define kCaughtFirePriority 902 #define kShredPriority 903 #define kFollowPriority 904 #define kTransInPriority 905 #define kTransOutPriority 906 #define kTriggerPriority 999 #define kArrowCursor 0 #define kBeamCursor 1 #define kHandCursor 2 #define kAppleMenuID 128 #define kGameMenuID 129 #define kOptionsMenuID 130 #define kHouseMenuID 131 #define kSplashMode 0 #define kEditMode 1 #define kPlayMode 2 #define kIdleSplashMode 0 #define kIdleDemoMode 1 #define kIdleSplashTicks 7200L // 2 minutes #define kIdleLastMode 1 #define kRoomAbove 1 #define kRoomBelow 2 #define kRoomToRight 3 #define kRoomToLeft 4 #define kBumpUp 1 #define kBumpDown 2 #define kBumpRight 3 #define kBumpLeft 4 #define kAbove 1 #define kToRight 2 #define kBelow 3 #define kToLeft 4 #define kBottomCorner 5 #define kTopCorner 6 #define kCentralRoom 0 #define kNorthRoom 1 #define kNorthEastRoom 2 #define kEastRoom 3 #define kSouthEastRoom 4 #define kSouthRoom 5 #define kSouthWestRoom 6 #define kWestRoom 7 #define kNorthWestRoom 8 #define kSimpleRoom 2000 #define kPaneledRoom 2001 #define kBasement 2002 #define kChildsRoom 2003 #define kAsianRoom 2004 #define kUnfinishedRoom 2005 #define kSwingersRoom 2006 #define kBathroom 2007 #define kLibrary 2008 #define kGarden 2009 #define kSkywalk 2010 #define kDirt 2011 #define kMeadow 2012 #define kField 2013 #define kRoof 2014 #define kSky 2015 #define kStratosphere 2016 #define kStars 2017 #define kMapRoomHeight 20 #define kMapRoomWidth 32 #define kMaxScores 10 #define kMaxRoomObs 24 #define kMaxSparkles 3 #define kNumSparkleModes 5 #define kMaxFlyingPts 3 #define kMaxFlyingPointsLoop 24 #define kMaxCandles 20 #define kMaxTikis 8 #define kMaxCoals 8 #define kMaxPendulums 8 #define kMaxHotSpots 56 #define kMaxSavedMaps 24 #define kMaxRubberBands 2 #define kMaxGrease 16 #define kMaxStars 4 #define kMaxShredded 4 #define kMaxDynamicObs 18 #define kMaxMasterObjects 216 // kMaxRoomObs * 9 #define kMaxViewWidth 1536 #define kMaxViewHeight 1026 #define kSelectTool 0 #define kBlowerMode 1 #define kFurnitureMode 2 #define kBonusMode 3 #define kTransportMode 4 #define kSwitchMode 5 #define kLightMode 6 #define kApplianceMode 7 #define kEnemyMode 8 #define kClutterMode 9 #define kIgnoreIt 0 // ¥¥¥¥¥¥ #define kLiftIt 1 // ¥¥ ¥¥ #define kDropIt 2 // ¥¥¥¥¥¥¥¥ #define kPushItLeft 3 // ¥¥ ¥¥ #define kPushItRight 4 // ¥¥ ¥¥ #define kDissolveIt 5 // #define kRewardIt 6 // ¥¥¥¥¥¥ #define kMoveItUp 7 // ¥¥ ¥¥ #define kMoveItDown 8 // ¥¥ #define kSwitchIt 9 // ¥¥ ¥¥ #define kShredIt 10 // ¥¥¥¥¥¥ #define kStrumIt 11 // #define kTriggerIt 12 // ¥¥¥¥¥¥¥¥ #define kBurnIt 13 // ¥¥ #define kSlideIt 14 // ¥¥ #define kTransportIt 15 // ¥¥ #define kIgnoreLeftWall 16 // ¥¥ #define kIgnoreRightWall 17 // #define kMailItLeft 18 // ¥¥¥¥¥¥ #define kMailItRight 19 // ¥¥ #define kDuctItDown 20 // ¥¥ #define kDuctItUp 21 // ¥¥ #define kMicrowaveIt 22 // ¥¥¥¥¥¥ #define kIgnoreGround 23 // #define kBounceIt 24 // #define kChimeIt 25 // ¥¥ #define kWebIt 26 // ¥¥ #define kSoundIt 27 #define kFloorVent 0x01 // Blowers #define kCeilingVent 0x02 #define kFloorBlower 0x03 #define kCeilingBlower 0x04 #define kSewerGrate 0x05 #define kLeftFan 0x06 #define kRightFan 0x07 #define kTaper 0x08 #define kCandle 0x09 #define kStubby 0x0A #define kTiki 0x0B #define kBBQ 0x0C #define kInvisBlower 0x0D #define kGrecoVent 0x0E #define kSewerBlower 0x0F #define kLiftArea 0x10 #define kTable 0x11 // Furniture #define kShelf 0x12 #define kCabinet 0x13 #define kFilingCabinet 0x14 #define kWasteBasket 0x15 #define kMilkCrate 0x16 #define kCounter 0x17 #define kDresser 0x18 #define kDeckTable 0x19 #define kStool 0x1A #define kTrunk 0x1B #define kInvisObstacle 0x1C #define kManhole 0x1D #define kBooks 0x1E #define kInvisBounce 0x1F #define kRedClock 0x21 // Prizes #define kBlueClock 0x22 #define kYellowClock 0x23 #define kCuckoo 0x24 #define kPaper 0x25 #define kBattery 0x26 #define kBands 0x27 #define kGreaseRt 0x28 #define kGreaseLf 0x29 #define kFoil 0x2A #define kInvisBonus 0x2B #define kStar 0x2C #define kSparkle 0x2D #define kHelium 0x2E #define kSlider 0x2F #define kUpStairs 0x31 // Transport #define kDownStairs 0x32 #define kMailboxLf 0x33 #define kMailboxRt 0x34 #define kFloorTrans 0x35 #define kCeilingTrans 0x36 #define kDoorInLf 0x37 #define kDoorInRt 0x38 #define kDoorExRt 0x39 #define kDoorExLf 0x3A #define kWindowInLf 0x3B #define kWindowInRt 0x3C #define kWindowExRt 0x3D #define kWindowExLf 0x3E #define kInvisTrans 0x3F #define kDeluxeTrans 0x40 #define kLightSwitch 0x41 // Switches #define kMachineSwitch 0x42 #define kThermostat 0x43 #define kPowerSwitch 0x44 #define kKnifeSwitch 0x45 #define kInvisSwitch 0x46 #define kTrigger 0x47 #define kLgTrigger 0x48 #define kSoundTrigger 0x49 #define kCeilingLight 0x51 // Lights #define kLightBulb 0x52 #define kTableLamp 0x53 #define kHipLamp 0x54 #define kDecoLamp 0x55 #define kFlourescent 0x56 #define kTrackLight 0x57 #define kInvisLight 0x58 #define kShredder 0x61 // Appliances #define kToaster 0x62 #define kMacPlus 0x63 #define kGuitar 0x64 #define kTV 0x65 #define kCoffee 0x66 #define kOutlet 0x67 #define kVCR 0x68 #define kStereo 0x69 #define kMicrowave 0x6A #define kCinderBlock 0x6B #define kFlowerBox 0x6C #define kCDs 0x6D #define kCustomPict 0x6E #define kBalloon 0x71 // Enemies #define kCopterLf 0x72 #define kCopterRt 0x73 #define kDartLf 0x74 #define kDartRt 0x75 #define kBall 0x76 #define kDrip 0x77 #define kFish 0x78 #define kCobweb 0x79 #define kOzma 0x81 // Clutter #define kMirror 0x82 #define kMousehole 0x83 #define kFireplace 0x84 #define kFlower 0x85 #define kWallWindow 0x86 #define kBear 0x87 #define kCalendar 0x88 #define kVase1 0x89 #define kVase2 0x8A #define kBulletin 0x8B #define kCloud 0x8C #define kFaucet 0x8D #define kRug 0x8E #define kChimes 0x8F #define kNumSrcRects 0x90 #define kTableThick 8 #define kShelfThick 6 #define kToggle 0 #define kForceOn 1 #define kForceOff 2 #define kOneShot 3 #define kNumTrackLights 3 #define kNumOutletPicts 4 #define kNumCandleFlames 5 #define kNumTikiFlames 5 #define kNumBBQCoals 4 #define kNumPendulums 3 #define kNumBreadPicts 6 #define kNumBalloonFrames 8 #define kNumCopterFrames 10 #define kNumDartFrames 4 #define kNumBallFrames 2 #define kNumDripFrames 6 #define kNumFishFrames 8 #define kNumFlowers 6 #define kNumMarqueePats 7 #define kObjectNameStrings 1007 #define kSwitchLinkOnly 3 #define kTriggerLinkOnly 4 #define kTransportLinkOnly 5 #define kFloorVentTop 305 #define kCeilingVentTop 8 #define kFloorBlowerTop 304 #define kCeilingBlowerTop 5 #define kSewerGrateTop 303 #define kCeilingTransTop 6 #define kFloorTransTop 302 #define kStairsTop 28 #define kCounterBottom 304 #define kDresserBottom 293 #define kCeilingLightTop 4 #define kHipLampTop 23 #define kDecoLampTop 91 #define kFlourescentTop 12 #define kTrackLightTop 5 #define kDoorInTop 0 #define kDoorInLfLeft 0 #define kDoorInRtLeft 368 #define kDoorExTop 0 #define kDoorExLfLeft 0 #define kDoorExRtLeft 496 #define kWindowInTop 64 #define kWindowInLfLeft 0 #define kWindowInRtLeft 492 #define kWindowExTop 64 #define kWindowExLfLeft 0 #define kWindowExRtLeft 496 #define kNumTiles 8 #define kTileWide 64 #define kTileHigh 322 #define kRoomWide 512 // kNumTiles * kTileWide #define kFloorSupportTall 44 #define kVertLocalOffset 322 // kTileHigh - 39 (was 283, then 295) #define kCeilingLimit 8 #define kFloorLimit 312 #define kRoofLimit 122 #define kLeftWallLimit 12 #define kNoLeftWallLimit -24 // 0 - (kGliderWide / 2) #define kRightWallLimit 500 #define kNoRightWallLimit 536 // kRoomWide + (kGliderWide / 2) #define kNoCeilingLimit -10 #define kNoFloorLimit 332 #define kScoreboardHigh 0 #define kScoreboardLow 1 #define kScoreboardTall 20 #define kHouseVersion 0x0200 #define kNewHouseVersion 0x0300 #define kBaseBackgroundID 2000 #define kFirstOutdoorBack 2009 #define kNumBackgrounds 18 #define kUserBackground 3000 #define kUserStructureRange 3300 #define kSplash8BitPICT 1000 #define kRoomIsEmpty -1 #define kObjectIsEmpty -1 #define kNoObjectSelected -1 #define kInitialGliderSelected -2 #define kLeftGliderSelected -3 #define kRightGliderSelected -4 #define kWindoidWDEF 2048 #define kWindoidGrowWDEF 2064 #define kTicksPerFrame 2 #define kStarPictID 1995 #define kNumUndergroundFloors 8 #define kRoomVisitScore 100 #define kRedClockPoints 100 #define kBlueClockPoints 300 #define kYellowClockPoints 500 #define kCuckooClockPoints 1000 #define kStarPoints 5000 #define kRedOrangeColor8 23 // actually, 18 #define kMaxNumRoomsH 128 #define kMaxNumRoomsV 64 #define kStartSparkle 4 #define kLengthOfZap 30 #define kGliderWide 48 #define kGliderHigh 20 #define kHalfGliderWide 24 #define kGliderBurningHigh 26 #define kShadowHigh 9 #define kShadowTop 306 #define kFaceRight TRUE #define kFaceLeft FALSE #define kPlayer1 TRUE #define kPlayer2 FALSE #define kNumGliderSrcRects 31 #define kNumShadowSrcRects 2 #define kFirstAboutFaceFrame 18 #define kLastAboutFaceFrame 20 #define kWasBurning 2 #define kLeftFadeOffset 7 #define kLastFadeSequence 16 #define kGliderFoil2PictID 3963 #define kGlider2PictID 3974 #define kGliderFoilPictID 3976 #define kGliderPictID 3999 #define kGliderStartsDown 32 #define kGliderNormal 0 // ¥¥ ¥¥ #define kGliderFadingIn 1 // ¥¥¥ ¥¥¥ #define kGliderFadingOut 2 // ¥¥ ¥¥ ¥¥ #define kGliderGoingUp 3 // ¥¥ ¥¥ #define kGliderComingUp 4 // ¥¥ ¥¥ #define kGliderGoingDown 5 // #define kGliderComingDown 6 // ¥¥¥¥¥¥ #define kGliderFaceLeft 7 // ¥¥ ¥¥ #define kGliderFaceRight 8 // ¥¥ ¥¥ #define kGliderBurning 9 // ¥¥ ¥¥ #define kGliderTransporting 10 // ¥¥¥¥¥¥ #define kGliderDuctingDown 11 // #define kGliderDuctingUp 12 // ¥¥¥¥¥¥¥ #define kGliderDuctingIn 13 // ¥¥ ¥¥ #define kGliderMailInLeft 14 // ¥¥ ¥¥ #define kGliderMailOutLeft 15 // ¥¥ ¥¥ #define kGliderMailInRight 16 // ¥¥¥¥¥¥¥ #define kGliderMailOutRight 17 // #define kGliderGoingFoil 18 // ¥¥¥¥¥¥¥¥ #define kGliderLosingFoil 19 // ¥¥ #define kGliderShredding 20 // ¥¥¥¥ #define kGliderInLimbo 21 // ¥¥ #define kGliderIdle 22 // ¥¥¥¥¥¥¥¥ #define kGliderTransportingIn 23 #define kPlayerIsDeadForever -69 #define kPlayerMailedOut -12 #define kPlayerDuckedOut -11 #define kPlayerTransportedOut -10 #define kPlayerEscapingDownStairs -9 #define kPlayerEscapingUpStairs -8 #define kPlayerEscapedDownStairs -7 #define kPlayerEscapedUpStairs -6 #define kPlayerEscapedDown -5 #define kPlayerEscapedUp -4 #define kPlayerEscapedLeft -3 #define kPlayerEscapedRight -2 #define kNoOneEscaped -1 #define kLinkedToOther 0 #define kLinkedToLeftMailbox 1 #define kLinkedToRightMailbox 2 #define kLinkedToCeilingDuct 3 #define kLinkedToFloorDuct 4 #define kResumeGameMode 0 #define kNewGameMode 1 #define kNormalTitleMode 0 #define kEscapedTitleMode 1 #define kSavingTitleMode 2 #define kScoreboardPictID 1997 #define kDemoLength 6702 \ No newline at end of file diff --git a/Headers/GliderProtos.h b/Headers/GliderProtos.h deleted file mode 100755 index af611a5..0000000 --- a/Headers/GliderProtos.h +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // GliderProtos.h //---------------------------------------------------------------------------- //============================================================================ //-------------------------------------------------------------- Prototypes void SetUpAppleEvents (void); // --- AppleEvents.c void BringUpBanner (void); // --- Banner.c SInt16 CountStarsInHouse (void); void DisplayStarsRemaining (void); void SetCoordinateHVD (SInt16, SInt16, SInt16); // --- Coordinate.c void DeltaCoordinateD (SInt16); void UpdateCoordWindow (void); void OpenCoordWindow (void); void CloseCoordWindow (void); void ToggleCoordinateWindow (void); void NilSavedMaps (void); // --- DynamicMaps.c SInt16 BackUpToSavedMap (Rect *, SInt16, SInt16); SInt16 ReBackUpSavedMap (Rect *, SInt16, SInt16); void RestoreFromSavedMap (SInt16, SInt16, Boolean); void AddSparkle (Rect *); void AddFlyingPoint (Rect *, SInt16, SInt16, SInt16); void ReBackUpFlames (SInt16, SInt16); void AddCandleFlame (SInt16, SInt16, SInt16, SInt16); void ReBackUpTikiFlames (SInt16, SInt16); void AddTikiFlame (SInt16, SInt16, SInt16, SInt16); void ReBackUpBBQCoals (SInt16, SInt16); void AddBBQCoals (SInt16, SInt16, SInt16, SInt16); void ReBackUpPendulum (SInt16, SInt16); void AddPendulum (SInt16, SInt16, SInt16, SInt16); void ReBackUpStar (SInt16, SInt16); void AddStar (SInt16, SInt16, SInt16, SInt16); void StopPendulum (SInt16, SInt16); void StopStar (SInt16, SInt16); void AddAShreddedGlider (Rect *); void RemoveShreds (void); void ZeroFlamesAndTheLike (void); void CheckDynamicCollision (SInt16, gliderPtr, Boolean); // --- Dynamics.c Boolean DidBandHitDynamic (SInt16); void RenderToast (SInt16); void RenderBalloon (SInt16); void RenderCopter (SInt16); void RenderDart (SInt16); void RenderBall (SInt16); void RenderDrip (SInt16); void RenderFish (SInt16); void HandleSparkleObject (SInt16); void HandleToast (SInt16); void HandleMacPlus (SInt16); void HandleTV (SInt16); void HandleCoffee (SInt16); void HandleOutlet (SInt16); void HandleVCR (SInt16); void HandleStereo (SInt16); void HandleMicrowave (SInt16); void HandleBalloon (SInt16); // --- Dynamics2.c void HandleCopter (SInt16); void HandleDart (SInt16); void HandleBall (SInt16); void HandleDrip (SInt16); void HandleFish (SInt16); void HandleDynamics (void); // --- Dynamics3.c void RenderDynamics (void); void ZeroDinahs (void); SInt16 AddDynamicObject (SInt16, Rect *, objectType *, SInt16, SInt16, Boolean); void DoGameOver (void); // --- GameOver.c void FlagGameOver (void); void DoDiedGameOver (void); void HandleGrease (void); // --- Grease.c SInt16 ReBackUpGrease (SInt16, SInt16); SInt16 AddGrease (SInt16, SInt16, SInt16, SInt16, SInt16, Boolean); void SpillGrease (SInt16, SInt16); void RedrawAllGrease (void); void DoHighScores (void); // --- HighScores.c void SortHighScores (void); void ZeroHighScores (void); void ZeroAllButHighestScore (void); Boolean TestHighScore (void); Boolean WriteScoresToDisk (void); Boolean ReadScoresFromDisk (void); Boolean CreateNewHouse (void); // --- House.c Boolean InitializeEmptyHouse (void); SInt16 RealRoomNumberCount (void); SInt16 GetFirstRoomNumber (void); void WhereDoesGliderBegin (Rect *, SInt16); Boolean HouseHasOriginalPicts (void); SInt16 CountHouseLinks (void); void GenerateLinksList (void); void SortRoomsObjects (SInt16); void SortHouseObjects (void); SInt16 CountRoomsVisited (void); void GenerateRetroLinks (void); void DoGoToDialog (void); void ConvertHouseVer1To2 (void); void ShiftWholeHouse (SInt16); void DoHouseInfo (void); // --- HouseInfo.c Boolean OpenHouse (void); // --- HouseIO.c Boolean OpenSpecificHouse (FSSpec *); Boolean SaveHouseAs (void); Boolean ReadHouse (void); Boolean WriteHouse (Boolean); Boolean CloseHouse (void); void OpenHouseResFork (void); void CloseHouseResFork (void); Boolean QuerySaveChanges (void); void YellowAlert (SInt16, SInt16); Boolean KeepObjectLegal (void); // --- HouseLegal.c void CheckHouseForProblems (void); Boolean SectGlider (gliderPtr, Rect *, Boolean); // --- Interactions.c void HandleSwitches (hotPtr); void HandleInteraction (void); void FlagStillOvers (gliderPtr); void InitializeMenus (void); // --- InterfaceInit.c void GetExtraCursors (void); void VariableInit (void); void GetDemoInput (gliderPtr); // --- Input.c void GetInput (gliderPtr); SInt16 MergeFloorSuite (SInt16, SInt16); // --- Link.c void ExtractFloorSuite (SInt16, SInt16 *, SInt16 *); void UpdateLinkControl (void); void UpdateLinkWindow (void); void OpenLinkWindow (void); void CloseLinkWindow (void); void HandleLinkClick (Point); void RedrawSplashScreen (void); // --- MainWindow.c void UpdateMainWindow (void); void UpdateMenuBarWindow (void); void OpenMainWindow (void); void CloseMainWindow (void); void ZoomBetweenWindows (void); void UpdateEditWindowTitle (void); void HandleMainClick (Point, Boolean); //void WashColorIn (void); void CenterMapOnRoom (SInt16, SInt16); // --- Map.c Boolean ThisRoomVisibleOnMap (void); void FindNewActiveRoomRect (void); void FlagMapRoomsForUpdate (void); void UpdateMapWindow (void); void ResizeMapWindow (SInt16, SInt16); void OpenMapWindow (void); void CloseMapWindow (void); void ToggleMapWindow (void); void HandleMapClick (EventRecord *); void MoveRoom (Point); void DoMarquee (void); // --- Marquee.c void StartMarquee (Rect *); void StartMarqueeHandled (Rect *, SInt16, SInt16); void StopMarquee (void); void PauseMarquee (void); void ResumeMarquee (void); void DragOutMarqueeRect (Point, Rect *); void DragMarqueeRect (Point, Rect *, Boolean, Boolean); void DragMarqueeHandle (Point, SInt16 *); void DragMarqueeCorner (Point, SInt16 *, SInt16 *, Boolean); Boolean MarqueeHasHandles (SInt16 *, SInt16 *); Boolean PtInMarqueeHandle (Point); void SetMarqueeGliderRect (SInt16, SInt16); void InitMarquee (void); void UpdateClipboardMenus (void); // --- Menu.c void DoAppleMenu (SInt16); void DoGameMenu (SInt16); void DoOptionsMenu (SInt16); void DoHouseMenu (SInt16); void DoMenuChoice (long); void UpdateMenus (Boolean); void UpdateMapCheckmark (Boolean); void UpdateToolsCheckmark (Boolean); void UpdateCoordinateCheckmark (Boolean); #ifdef COMPILEDEMO void DoNotInDemo (void); #endif void OpenCloseEditWindows (void); void StartGliderFadingIn (gliderPtr); // --- Modes.c void StartGliderTransportingIn (gliderPtr); void StartGliderFadingOut (gliderPtr); void StartGliderGoingUpStairs (gliderPtr); void StartGliderGoingDownStairs (gliderPtr); void StartGliderMailingIn (gliderPtr, Rect *, hotPtr); void StartGliderMailingOut (gliderPtr); void StartGliderDuctingDown (gliderPtr, Rect *, hotPtr); void StartGliderDuctingUp (gliderPtr, Rect *, hotPtr); void StartGliderDuctingIn (gliderPtr); void StartGliderTransporting (gliderPtr, hotPtr); void FlagGliderNormal (gliderPtr); void FlagGliderShredding (gliderPtr, Rect *); void FlagGliderBurning (gliderPtr); void FlagGliderFaceLeft (gliderPtr); void FlagGliderFaceRight (gliderPtr); void FlagGliderInLimbo (gliderPtr, Boolean); void UndoGliderLimbo (gliderPtr); void ToggleGliderFacing (gliderPtr); void InsureGliderFacingRight (gliderPtr); void InsureGliderFacingLeft (gliderPtr); void ReadyGliderForTripUpStairs (gliderPtr); void ReadyGliderForTripDownStairs (gliderPtr); void StartGliderFoilGoing (gliderPtr); void StartGliderFoilLosing (gliderPtr); void TagGliderIdle (gliderPtr); OSErr StartMusic (void); // --- Music.c void StopTheMusic (void); void ToggleMusicWhilePlaying (void); void SetMusicalMode (SInt16); void InitMusic (void); void KillMusic (void); long MusicBytesNeeded (void); void TellHerNoMusic (void); Boolean AddNewObject (Point, SInt16, Boolean); // --- ObjectAdd.c SInt16 FindObjectSlotInRoom (SInt16); Boolean DoesRoomNumHaveObject (SInt16, SInt16); void ShoutNoMoreObjects (void); void DrawSimpleBlowers (SInt16, Rect *); // --- ObjectDraw.c void DrawTiki (Rect *, SInt16); void DrawInvisibleBlower (Rect *); void DrawLiftArea (Rect *); void DrawTable (Rect *, SInt16); void DrawShelf (Rect *); void DrawCabinet (Rect *); void DrawSimpleFurniture (SInt16, Rect *); void DrawCounter (Rect *); void DrawDresser (Rect *); void DrawDeckTable (Rect *, SInt16); void DrawStool (Rect *, SInt16); void DrawInvisObstacle (Rect *); void DrawInvisBounce (Rect *); void DrawRedClock (Rect *); void DrawBlueClock (Rect *); void DrawYellowClock (Rect *); void DrawCuckoo (Rect *); void DrawSimplePrizes (SInt16, Rect *); void DrawGreaseRt (Rect *, SInt16, Boolean); void DrawGreaseLf (Rect *, SInt16, Boolean); void DrawFoil (Rect *); void DrawInvisBonus (Rect *); void DrawSlider (Rect *); void DrawMailboxLeft (Rect *, SInt16); // --- ObjectDraw2.c void DrawMailboxRight (Rect *, SInt16); void DrawSimpleTransport (SInt16, Rect *); void DrawInvisTransport (Rect *); void DrawLightSwitch (Rect *, Boolean); void DrawMachineSwitch (Rect *, Boolean); void DrawThermostat (Rect *, Boolean); void DrawPowerSwitch (Rect *, Boolean); void DrawKnifeSwitch (Rect *, Boolean); void DrawInvisibleSwitch (Rect *); void DrawTrigger (Rect *); void DrawSoundTrigger (Rect *); void DrawSimpleLight (SInt16, Rect *); void DrawFlourescent (Rect *); void DrawSimpleAppliance (SInt16, Rect *); void DrawMacPlus (Rect *, Boolean, Boolean); void DrawTrackLight (Rect *); void DrawInvisLight (Rect *); void DrawTV (Rect *, Boolean, Boolean); void DrawCoffee (Rect *, Boolean, Boolean); void DrawOutlet (Rect *); void DrawVCR (Rect *, Boolean, Boolean); void DrawStereo (Rect *, Boolean, Boolean); void DrawMicrowave (Rect *, Boolean, Boolean); void DrawBalloon (Rect *); void DrawCopter (Rect *); void DrawDart (Rect *, SInt16); void DrawBall (SInt16, Rect *); void DrawFish (SInt16, Rect *); void DrawDrip (Rect *); void DrawMirror (Rect *); void DrawSimpleClutter (SInt16, Rect *); void DrawFlower (Rect *, SInt16); void DrawWallWindow (Rect *); void DrawCalendar (Rect *); void DrawBulletin (Rect *); void DrawPictObject (SInt16, Rect *); void DrawPictWithMaskObject (SInt16, Rect *); void DrawPictSansWhiteObject (SInt16, Rect *); void DrawCustPictSansWhite (SInt16, Rect *); void DrawARoomsObjects (SInt16, Boolean); // --- ObjectDrawAll.c void DoSelectionClick (Point, Boolean); // --- ObjectEdit.c void DoNewObjectClick (Point); void DeleteObject (void); void DuplicateObject (void); void MoveObject (SInt16, Boolean); void DeselectObject (void); Boolean ObjectHasHandle (SInt16 *, SInt16 *); void HandleBlowerGlider (void); void SelectNextObject (void); void SelectPrevObject (void); void GetThisRoomsObjRects (void); void DrawThisRoomsObjects (void); void HiliteAllObjects (void); void GoToObjectInRoom (SInt16, SInt16, SInt16); void GoToObjectInRoomNum (SInt16, SInt16); void DoObjectInfo (void); // --- ObjectInfo.c void GetObjectRect (objectPtr, Rect *); // --- ObjectRects.c SInt16 CreateActiveRects (SInt16); SInt16 VerticalRoomOffset (SInt16); void OffsetRectRoomRelative (Rect *, SInt16); SInt16 GetUpStairsRightEdge (void); SInt16 GetDownStairsLeftEdge (void); SInt16 GetRoomLinked (objectType *); // --- Objects.c Boolean ObjectIsLinkTransport (objectType *); Boolean ObjectIsLinkSwitch (objectType *); void ListAllLocalObjects (void); Boolean SetObjectState (SInt16, SInt16, SInt16, SInt16); Boolean GetObjectState (SInt16, SInt16); void BringSendFrontBack (Boolean); Boolean IsThisValid (SInt16, SInt16); void AddTempManholeRect (Rect *); void NewGame (SInt16); // --- Play.c void DoDemoGame (void); void HideGlider (gliderPtr); void StrikeChime (void); void RestoreEntireGameScreen (void); void HandleGlider (gliderPtr); // --- Player.c void FinishGliderUpStairs (gliderPtr); void FinishGliderDownStairs (gliderPtr); void FinishGliderDuctingIn (gliderPtr); void DeckGliderInFoil (gliderPtr); void RemoveFoilFromGlider (gliderPtr); void OffsetGlider (gliderPtr, SInt16); void OffAMortal (gliderPtr); void AddRectToWorkRects (Rect *); // --- Render.c void AddRectToBackRects (Rect *); void AddRectToWorkRectsWhole (Rect *); void RenderGlider (gliderPtr, Boolean); void CopyRectsQD (void); void DirectWork2Main8 (Rect *); void DirectBack2Work8 (Rect *); void DirectGeneric2Work8 (long, long, Rect *, Rect *); void DirectWork2Main4 (Rect *); void DirectBack2Work4 (Rect *); void DirectGeneric2Work4 (long, long, Rect *, Rect *); void CopyRectsAssm (void); void DirectFillBack8 (Rect *, Byte); void DirectFillWork8 (Rect *, Byte); void DirectFillBack4 (Rect *, Byte); void DirectFillWork4 (Rect *, Byte); void RenderFrame (void); void InitGarbageRects (void); void CopyRectBackToWork (Rect *); void CopyRectWorkToBack (Rect *); void CopyRectWorkToMain (Rect *); void CopyRectMainToWork (Rect *); void CopyRectMainToBack (Rect *); void AddToMirrorRegion (Rect *); void ZeroMirrorRegion (void); void SetInitialTiles (SInt16, Boolean); // --- Room.c Boolean CreateNewRoom (SInt16, SInt16); void DoRoomInfo (void); void ReadyBackground (SInt16, SInt16 *); void ReflectCurrentRoom (Boolean); void CopyRoomToThisRoom (SInt16); void CopyThisRoomToRoom (void); void ForceThisRoom (SInt16); Boolean RoomExists (SInt16, SInt16, SInt16 *); Boolean RoomNumExists (SInt16); void DeleteRoom (Boolean); SInt16 DoesNeighborRoomExist (SInt16); void SelectNeighborRoom (SInt16); SInt16 GetNeighborRoomNumber (SInt16); Boolean GetRoomFloorSuite (SInt16, SInt16 *, SInt16 *); SInt16 GetRoomNumber (SInt16, SInt16); Boolean IsRoomAStructure (SInt16); void DetermineRoomOpenings (void); SInt16 GetOriginalBounding (SInt16); SInt16 GetNumberOfLights (SInt16); Boolean IsShadowVisible (void); Boolean DoesRoomHaveFloor (void); Boolean DoesRoomHaveCeiling (void); void ReadyLevel (void); // --- RoomGraphics.c void DrawLocale (void); void RedrawRoomLighting (void); Boolean PictIDExists (SInt16); // --- RoomInfo.c void HandleBands (void); // --- RubberBands.c Boolean AddBand (gliderPtr, SInt16, SInt16, Boolean); void KillAllBands (void); void SaveGame2 (void); // --- SavedGames.c Boolean OpenSavedGame (void); void SaveGame (Boolean); void RefreshScoreboard (SInt16); // --- Scoreboard.c void HandleDynamicScoreboard (void); void QuickGlidersRefresh (void); void QuickScoreRefresh (void); void QuickBatteryRefresh (Boolean); void QuickBandsRefresh (Boolean); void QuickFoilRefresh (Boolean); void HandleScore (void); void AdjustScoreboardHeight (void); void BlackenScoreboard (void); //void PutRoomScrap (void); // --- Scrap.c //void PutObjectScrap (void); void GetRoomScrap (void); void GetObjectScrap (void); //void SeeIfValidScrapAvailable (Boolean); Boolean HasDragManager (void); //Boolean DragRoom (EventRecord *, Rect *, SInt16); void DoLoadHouse (void); // --- SelectHouse.c void BuildHouseList (void); void AddExtraHouse (FSSpec *); void DoSettingsMain (void); // --- Settings.c void PlayPrioritySound (SInt16, SInt16); // --- Sound.c void FlushAnyTriggerPlaying (void); void PlaySound0 (SInt16, SInt16); void PlaySound1 (SInt16, SInt16); void PlaySound2 (SInt16, SInt16); OSErr LoadTriggerSound (SInt16); void DumpTriggerSound (void); void InitSound (void); void KillSound (void); long SoundBytesNeeded (void); void TellHerNoSounds (void); void BitchAboutSM3 (void); void InitScoreboardMap (void); // --- StructuresInit.c void InitGliderMap (void); void InitBlowers (void); void InitFurniture (void); void InitPrizes (void); void InitTransports (void); void InitSwitches (void); void InitLights (void); void InitAppliances (void); void InitEnemies (void); void CreateOffscreens (void); // --- StructuresInit2.c void CreatePointers (void); void InitSrcRects (void); void UpdateToolsWindow (void); // --- Tools.c void EraseSelectedTool (void); void SelectTool (SInt16); void OpenToolsWindow (void); void CloseToolsWindow (void); void ToggleToolsWindow (void); void HandleToolsClick (Point); void NextToolMode (void); void PrevToolMode (void); void SetSpecificToolMode (SInt16); SInt16 WhatAreWeLinkedTo (SInt16, Byte); // --- Transit.c void ReadyGliderFromTransit (gliderPtr, SInt16); void MoveRoomToRoom (gliderPtr, SInt16); void TransportRoomToRoom (gliderPtr); void MoveDuctToDuct (gliderPtr); void MoveMailToMail (gliderPtr); void ForceKillGlider (void); void FollowTheLeader (void); void PourScreenOn (Rect *); // --- Transitions.c void WipeScreenOn (SInt16, Rect *); void DumpScreenOn (Rect *); //void DissBits (Rect *); //void DissBitsChunky (Rect *); //void FillColorNoise (Rect *); //void FillSnow (Rect *); void ToggleToaster (SInt16); // --- Trip.c void ToggleMacPlus (SInt16); void ToggleTV (SInt16); void ToggleCoffee (SInt16); void ToggleOutlet (SInt16); void ToggleVCR (SInt16); void ToggleStereos (SInt16); void ToggleMicrowave (SInt16); void ToggleBalloon (SInt16); void ToggleCopter (SInt16); void ToggleDart (SInt16); void ToggleBall (SInt16); void ToggleDrip (SInt16); void ToggleFish (SInt16); void TriggerSwitch (SInt16); void TriggerToast (SInt16); void TriggerOutlet (SInt16); void TriggerDrip (SInt16); void TriggerFish (SInt16); void TriggerBalloon (SInt16); void TriggerCopter (SInt16); void TriggerDart (SInt16); void UpdateOutletsLighting (SInt16, SInt16); void ArmTrigger (hotPtr); // --- Triggers.c void HandleTriggers (void); void ZeroTriggers (void); \ No newline at end of file diff --git a/Headers/GliderStructs.h b/Headers/GliderStructs.h deleted file mode 100755 index 1744a30..0000000 --- a/Headers/GliderStructs.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // GliderStructs.h //---------------------------------------------------------------------------- //============================================================================ #include typedef struct { Point topLeft; // 4 short distance; // 2 Boolean initial; // 1 Boolean state; // 1 F. lf. dn. rt. up Byte vector; // 1 | x | x | x | x | 8 | 4 | 2 | 1 | Byte tall; // 1 } blowerType; // total = 10 typedef struct { Rect bounds; // 8 short pict; // 2 } furnitureType; // total = 10 typedef struct { Point topLeft; // 4 short length; // 2 grease spill short points; // 2 invis bonus Boolean state; // 1 Boolean initial; // 1 } bonusType; // total = 10 typedef struct { Point topLeft; // 4 short tall; // 2 invis transport short where; // 2 Byte who; // 1 Byte wide; // 1 } transportType; // total = 10 typedef struct { Point topLeft; // 4 short delay; // 2 short where; // 2 Byte who; // 1 Byte type; // 1 } switchType; // total = 10 typedef struct { Point topLeft; // 4 short length; // 2 Byte byte0; // 1 Byte byte1; // 1 Boolean initial; // 1 Boolean state; // 1 } lightType; // total = 10 typedef struct { Point topLeft; // 4 short height; // 2 toaster, pict ID Byte byte0; // 1 Byte delay; // 1 Boolean initial; // 1 Boolean state; // 1 } applianceType; // total = 10 typedef struct { Point topLeft; // 4 short length; // 2 Byte delay; // 1 Byte byte0; // 1 Boolean initial; // 1 Boolean state; // 1 } enemyType; // total = 10 typedef struct { Rect bounds; // 8 short pict; // 2 } clutterType; // total = 10 typedef struct { short what; // 2 union { blowerType a; furnitureType b; bonusType c; transportType d; switchType e; lightType f; applianceType g; enemyType h; clutterType i; } data; // 10 } objectType, *objectPtr; // total = 12 typedef struct { Str31 banner; // 32 = 32 Str15 names[kMaxScores]; // 16 * 10 = 160 long scores[kMaxScores]; // 4 * 10 = 40 unsigned long timeStamps[kMaxScores]; // 4 * 10 = 40 short levels[kMaxScores]; // 2 * 10 = 20 } scoresType; // total = 292 typedef struct { short version; // 2 short wasStarsLeft; // 2 long timeStamp; // 4 Point where; // 4 long score; // 4 long unusedLong; // 4 long unusedLong2; // 4 short energy; // 2 short bands; // 2 short roomNumber; // 2 short gliderState; // 2 short numGliders; // 2 short foil; // 2 short unusedShort; // 2 Boolean facing; // 1 Boolean showFoil; // 1 } gameType; // total = 40 typedef struct { short unusedShort; // 2 Byte unusedByte; // 1 Boolean visited; // 1 objectType objects[kMaxRoomObs]; // 24 * 12 } savedRoom, *saveRoomPtr; // total = 292 typedef struct { FSSpec house; // 70 short version; // 2 short wasStarsLeft; // 2 long timeStamp; // 4 Point where; // 4 long score; // 4 long unusedLong; // 4 long unusedLong2; // 4 short energy; // 2 short bands; // 2 short roomNumber; // 2 short gliderState; // 2 short numGliders; // 2 short foil; // 2 short nRooms; // 2 Boolean facing; // 1 Boolean showFoil; // 1 savedRoom savedData[]; // 4 } game2Type, *gamePtr; // total = 114 typedef struct { Str27 name; // 28 short bounds; // 2 Byte leftStart; // 1 Byte rightStart; // 1 Byte unusedByte; // 1 Boolean visited; // 1 short background; // 2 short tiles[kNumTiles]; // 2 * 8 short floor, suite; // 2 + 2 short openings; // 2 short numObjects; // 2 objectType objects[kMaxRoomObs]; // 24 * 12 } roomType, *roomPtr; // total = 348 typedef struct { short version; // 2 short unusedShort; // 2 long timeStamp; // 4 long flags; // 4 (bit 0 = wardBit) Point initial; // 4 Str255 banner; // 256 Str255 trailer; // 256 scoresType highScores; // 292 gameType savedGame; // 40 Boolean hasGame; // 1 Boolean unusedBoolean; // 1 short firstRoom; // 2 short nRooms; // 2 roomType rooms[]; // 348 * nRooms } houseType, *housePtr, **houseHand; // total = 866 + typedef struct { Rect src, mask, dest, whole; Rect destShadow, wholeShadow; Rect clip, enteredRect; long leftKey, rightKey; long battKey, bandKey; short hVel, vVel; short wasHVel, wasVVel; short vDesiredVel, hDesiredVel; short mode, frame, wasMode; Boolean facing, tipped; Boolean sliding, ignoreLeft, ignoreRight; Boolean fireHeld, which; Boolean heldLeft, heldRight; Boolean dontDraw, ignoreGround; } gliderType, *gliderPtr; typedef struct { Rect bounds; short action; short who; Boolean isOn, stillOver; Boolean doScrutinize; } hotObject, *hotPtr; typedef struct { Rect dest; GWorldPtr map; short where; short who; } savedType, *savedPtr; typedef struct { Rect bounds; short mode; } sparkleType, *sparklePtr; typedef struct { Rect dest, whole; short start; short stop; short mode; short loops; short hVel, vVel; } flyingPtType, *flyingPtPtr; typedef struct { Rect dest, src; short mode; short who; } flameType, *flamePtr; typedef struct { Rect dest, src; short mode, where; short who, link; Boolean toOrFro, active; } pendulumType, *pendulumPtr; typedef struct { Boolean left; Boolean top; Boolean right; Boolean bottom; } boundsType, *boundsPtr, **boundsHand; typedef struct { Rect dest; short mode, count; short hVel, vVel; } bandType, *bandPtr; typedef struct { short srcRoom, srcObj; short destRoom, destObj; } linksType, *linksPtr; typedef struct { Rect dest; short mapNum, mode; short who, where; short start, stop; short frame, hotNum; Boolean isRight; } greaseType, *greasePtr; typedef struct { Rect dest, src; short mode, who; short link, where; } starType, *starPtr; typedef struct { Rect bounds; short frame; } shredType, *shredPtr; typedef struct { Rect dest; Rect whole; short hVel, vVel; short type, count; short frame, timer; short position, room; Byte byte0, byte1; Boolean moving, active; } dynaType, *dynaPtr; typedef struct { short roomNum; // room # object in (real number) short objectNum; // obj. # in house (real number) short roomLink; // room # object linked to (if any) short objectLink; // obj. # object linked to (if any) short localLink; // index in master list if exists short hotNum; // index into active rects (if any) short dynaNum; // index into dinahs (if any) objectType theObject; // actual object data } objDataType, *objDataPtr; typedef struct { long frame; char key; char padding; } demoType, *demoPtr; typedef struct { short room; short object; } retroLink, *retroLinkPtr; \ No newline at end of file diff --git a/Headers/GliderVars.h b/Headers/GliderVars.h deleted file mode 100755 index 4d4e19a..0000000 --- a/Headers/GliderVars.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // GliderVars.h //---------------------------------------------------------------------------- //============================================================================ #include extern Rect blowerSrcRect; extern Rect flame[], tikiFlame[]; extern Rect coals[]; extern Rect furnitureSrcRect; extern Rect tableSrc, shelfSrc, hingeSrc, handleSrc, knobSrc; extern Rect leftFootSrc, rightFootSrc, deckSrc; extern Rect bonusSrcRect; extern Rect pointsSrcRect; extern Rect starSrc[], sparkleSrc[]; extern Rect digits[], pendulumSrc[], greaseSrcRt[], greaseSrcLf[]; extern Rect transSrcRect; extern Rect switchSrcRect; extern Rect lightSwitchSrc[], machineSwitchSrc[], thermostatSrc[]; extern Rect powerSrc[], knifeSwitchSrc[]; extern Rect lightSrcRect; extern Rect flourescentSrc1, flourescentSrc2; extern Rect trackLightSrc[]; extern Rect applianceSrcRect, toastSrcRect, shredSrcRect; // Appliances extern Rect plusScreen1, plusScreen2, tvScreen1, tvScreen2; extern Rect coffeeLight1, coffeeLight2, vcrTime1, vcrTime2; extern Rect stereoLight1, stereoLight2, microOn, microOff; extern Rect outletSrc[]; extern Rect balloonSrcRect, copterSrcRect, dartSrcRect; // Enemies extern Rect ballSrcRect, dripSrcRect, enemySrcRect; extern Rect fishSrcRect; extern Rect balloonSrc[], copterSrc[], dartSrc[]; extern Rect ballSrc[], dripSrc[], fishSrc[]; extern Rect clutterSrcRect; extern Rect flowerSrc[]; extern Rect *srcRects; extern Movie theMovie; extern Rect movieRect; extern Boolean hasMovie, tvInRoom; extern gliderType theGlider, theGlider2; extern objDataPtr masterObjects; extern Rect workSrcRect; extern Rect backSrcRect; extern Rect mainWindowRect, houseRect; extern houseHand thisHouse; extern roomPtr thisRoom; extern WindowPtr mainWindow, coordWindow; extern long theScore; extern short playOriginH, playOriginV; extern short thisRoomNumber, theMode, batteryTotal, bandsTotal; extern short foilTotal, mortals, numMasterObjects, previousRoom; extern Boolean fileDirty, gameDirty, showFoil, doZooms, isPlayMusicGame; \ No newline at end of file diff --git a/Headers/House.h b/Headers/House.h deleted file mode 100755 index fd64fed..0000000 --- a/Headers/House.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // House.h //---------------------------------------------------------------------------- //============================================================================ #include extern Str32 thisHouseName; extern Boolean houseUnlocked; \ No newline at end of file diff --git a/Headers/MainWindow.h b/Headers/MainWindow.h deleted file mode 100755 index f932866..0000000 --- a/Headers/MainWindow.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // MainWindow.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr workSrcMap; \ No newline at end of file diff --git a/Headers/Map.h b/Headers/Map.h deleted file mode 100755 index 8e4e8bd..0000000 --- a/Headers/Map.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Map.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr nailSrcMap; extern WindowPtr mapWindow; \ No newline at end of file diff --git a/Headers/Marquee.h b/Headers/Marquee.h deleted file mode 100755 index fb21eb2..0000000 --- a/Headers/Marquee.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Marquee.h //---------------------------------------------------------------------------- //============================================================================ #pragma once #include typedef struct { Pattern pats[kNumMarqueePats]; Rect bounds, handle; short index, direction, dist; Boolean active, paused, handled; } marquee; extern marquee theMarquee; \ No newline at end of file diff --git a/Headers/ObjectEdit.h b/Headers/ObjectEdit.h deleted file mode 100755 index dfebe55..0000000 --- a/Headers/ObjectEdit.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // ObjectEdit.h //---------------------------------------------------------------------------- //============================================================================ #pragma once #include extern Rect roomObjectRects[]; extern short objActive; \ No newline at end of file diff --git a/Headers/Objects.h b/Headers/Objects.h deleted file mode 100755 index 083b420..0000000 --- a/Headers/Objects.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Objects.h //---------------------------------------------------------------------------- //============================================================================ extern GWorldPtr blowerSrcMap; extern GWorldPtr blowerMaskMap; extern GWorldPtr furnitureSrcMap; extern GWorldPtr furnitureMaskMap; extern GWorldPtr bonusSrcMap; extern GWorldPtr bonusMaskMap; extern GWorldPtr pointsSrcMap; extern GWorldPtr pointsMaskMap; extern GWorldPtr transSrcMap; extern GWorldPtr transMaskMap; extern GWorldPtr switchSrcMap; extern GWorldPtr lightSrcMap; extern GWorldPtr lightMaskMap; extern GWorldPtr applianceSrcMap; extern GWorldPtr applianceMaskMap; extern GWorldPtr toastSrcMap; extern GWorldPtr toastMaskMap; extern GWorldPtr shredSrcMap; extern GWorldPtr shredMaskMap; extern GWorldPtr balloonSrcMap; extern GWorldPtr balloonMaskMap; extern GWorldPtr copterSrcMap; extern GWorldPtr copterMaskMap; extern GWorldPtr dartSrcMap; extern GWorldPtr dartMaskMap; extern GWorldPtr ballSrcMap; extern GWorldPtr ballMaskMap; extern GWorldPtr dripSrcMap; extern GWorldPtr dripMaskMap; extern GWorldPtr enemySrcMap; extern GWorldPtr enemyMaskMap; extern GWorldPtr fishSrcMap; extern GWorldPtr fishMaskMap; extern GWorldPtr clutterSrcMap; extern GWorldPtr clutterMaskMap; \ No newline at end of file diff --git a/Headers/Play.h b/Headers/Play.h deleted file mode 100755 index b863d2f..0000000 --- a/Headers/Play.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Play.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr glidSrcMap; extern GWorldPtr glid2SrcMap; extern GWorldPtr glidMaskMap; \ No newline at end of file diff --git a/Headers/Player.h b/Headers/Player.h deleted file mode 100755 index a78a38e..0000000 --- a/Headers/Player.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Player.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr shadowSrcMap; extern GWorldPtr shadowMaskMap; \ No newline at end of file diff --git a/Headers/RectUtils.h b/Headers/RectUtils.h deleted file mode 100755 index 7ff4de5..0000000 --- a/Headers/RectUtils.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // RectUtils.h //---------------------------------------------------------------------------- //============================================================================ #pragma once #include void FrameWHRect (short, short, short, short); void NormalizeRect (Rect *); void ZeroRectCorner (Rect *); void CenterRectOnPoint (Rect *, Point); short HalfRectWide (Rect *); short HalfRectTall (Rect *); short RectWide (Rect *); short RectTall (Rect *); void GlobalToLocalRect (Rect *); void LocalToGlobalRect (Rect *); void CenterRectInRect (Rect *, Rect *); void HOffsetRect (Rect *, short); void VOffsetRect (Rect *, short); Boolean IsRectLeftOfRect (Rect *, Rect *); void QOffsetRect (Rect *, short, short); void QSetRect (Rect *, short, short, short, short); Boolean ForceRectInRect (Rect *, Rect *); void QUnionSimilarRect (Rect *, Rect *, Rect *); void FrameRectSansCorners (Rect *); void SetEraseRect (short, short, short, short); \ No newline at end of file diff --git a/Headers/Room.h b/Headers/Room.h deleted file mode 100755 index 434913e..0000000 --- a/Headers/Room.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Room.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr backSrcMap; \ No newline at end of file diff --git a/Headers/RoomGraphics.h b/Headers/RoomGraphics.h deleted file mode 100755 index 5538be1..0000000 --- a/Headers/RoomGraphics.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // RoomGraphics.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr suppSrcMap; \ No newline at end of file diff --git a/Headers/RubberBands.h b/Headers/RubberBands.h deleted file mode 100755 index 566ab20..0000000 --- a/Headers/RubberBands.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // RubberBands.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr bandsSrcMap; extern GWorldPtr bandsMaskMap; \ No newline at end of file diff --git a/Headers/Scoreboard.h b/Headers/Scoreboard.h deleted file mode 100755 index 9d989ea..0000000 --- a/Headers/Scoreboard.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Scoreboard.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr boardSrcMap; extern GWorldPtr badgeSrcMap; extern GWorldPtr boardTSrcMap; extern GWorldPtr boardGSrcMap; extern GWorldPtr boardPSrcMap; \ No newline at end of file diff --git a/Headers/Tools.h b/Headers/Tools.h deleted file mode 100755 index ff80070..0000000 --- a/Headers/Tools.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Tools.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr toolSrcMap; extern WindowPtr toolsWindow; \ No newline at end of file diff --git a/Headers/Utilities.h b/Headers/Utilities.h deleted file mode 100755 index 3f57af2..0000000 --- a/Headers/Utilities.h +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Utilities.c //---------------------------------------------------------------------------- //============================================================================ #include OSErr CreateOffScreenGWorld (GWorldPtr *theGWorld, Rect *bounds, short depth); \ No newline at end of file diff --git a/MiniRez/MiniRez.cpp b/MiniRez/MiniRez.cpp new file mode 100644 index 0000000..2e4cb85 --- /dev/null +++ b/MiniRez/MiniRez.cpp @@ -0,0 +1,528 @@ +#include +#include +#include +#include + +#include "BytePack.h" +#include "CFileStream.h" +#include "IOStream.h" + +#include "MacBinary2.h" +#include "MacFileMem.h" + +// Very simplified resource compiler + +using namespace PortabilityLayer; + +struct SimpleResource +{ + char m_type[4]; + int m_resourceID; + std::string m_name; + std::vector m_resourceData; + size_t m_offsetInResData; + uint8_t m_attributes; +}; + +struct ResCatalogData +{ +}; + +bool IsWhitespace(char c) +{ + return c <= ' '; +} + +void AppendUInt16(std::vector &vec, uint16_t value) +{ + uint8_t encoded[2]; + BytePack::BigUInt16(encoded, value); + vec.push_back(encoded[0]); + vec.push_back(encoded[1]); +} + +void AppendInt16(std::vector &vec, int16_t value) +{ + AppendUInt16(vec, static_cast(value)); +} + +void AppendUInt32(std::vector &vec, uint32_t value) +{ + uint8_t encoded[4]; + BytePack::BigUInt32(encoded, value); + vec.push_back(encoded[0]); + vec.push_back(encoded[1]); + vec.push_back(encoded[2]); + vec.push_back(encoded[3]); +} + +uint32_t TypeToU32(const char *resType) +{ + uint32_t v = 0; + for (int i = 0; i < 4; i++) + v |= static_cast(resType[i]) << (24 - i * 8); + + return v; +} + +bool FindNextNonWhitespace(CFileStream &fs, char &nextChar) +{ + for (;;) + { + char c; + if (!fs.Read(&c, 1)) + return false; + + if (!IsWhitespace(c)) + { + nextChar = c; + return true; + } + } +} + +std::string HandleEscapes(const std::string &str) +{ + const size_t len = str.size(); + + std::string processed; + + for (size_t i = 0; i < len; i++) + { + const char c = str[i]; + + if (c == '\\' && len - i >= 5 && str[i + 1] == '0' && str[i + 2] == 'x') + { + const char highNibbleChar = str[i + 3]; + const char lowNibbleChar = str[i + 4]; + + int highNibble = highNibbleChar - '0'; + int lowNibble = lowNibbleChar - '0'; + + const char reconstructed = (highNibble << 4) | lowNibble; + processed.append(&reconstructed, 1); + + i += 4; + } + else + processed.append(&c, 1); + } + + return processed; +} + +void DefError() +{ + fprintf(stderr, "Malformed def"); + exit(-1); +} + +int main(int argc, const char **argv) +{ + if (argc != 3) + { + fprintf(stderr, "Usage: MiniRez "); + return -1; + } + + FILE *f = nullptr; + if (fopen_s(&f, argv[1], "rb")) + { + fprintf(stderr, "Failed to open input file"); + return -1; + } + + CFileStream fs(f, true, false, true); + + int defsParsed = 0; + + std::vector resources; + + for (;;) + { + printf("%i defs parsed...\n", defsParsed); + defsParsed++; + UFilePos_t defStartOffset = fs.Tell(); + + char nextChar = 0; + if (!FindNextNonWhitespace(fs, nextChar)) + break; + + if (IsWhitespace(nextChar)) + continue; + + if (nextChar == 'd') + { + char nextChars[3]; + if (fs.Read(nextChars, 3) != 3 || nextChars[0] != 'a' || nextChars[1] != 't' || nextChars[2] != 'a') + { + fprintf(stderr, "Unknown token"); + return -1; + } + + if (!FindNextNonWhitespace(fs, nextChar) || nextChar != '\'') + DefError(); + + char resType[5]; + if (!fs.Read(resType, 5) || resType[4] != '\'') + DefError(); + + if (!FindNextNonWhitespace(fs, nextChar) || nextChar != '(') + DefError(); + + int resID = 0; + bool hasProperty = false; + bool isNegative = false; + for (;;) + { + if (!fs.Read(&nextChar, 1)) + DefError(); + + if (nextChar == ')') + break; + else if (nextChar == ',') + { + hasProperty = true; + break; + } + else if (nextChar == '-') + isNegative = true; + else if (nextChar >= '0' && nextChar <= '9') + resID = resID * 10 + (nextChar - '0'); + else + DefError(); + } + + std::string resName; + std::string propName; + std::vector resData; + + if (hasProperty) + { + char singleCharStr[2]; + singleCharStr[1] = '\0'; + + if (!FindNextNonWhitespace(fs, singleCharStr[0])) + DefError(); + + + if (singleCharStr[0] == '\"') + { + hasProperty = false; + + for (;;) + { + if (!fs.Read(singleCharStr, 1)) + DefError(); + + if (singleCharStr[0] == '"') + break; + + resName += singleCharStr; + } + + if (!FindNextNonWhitespace(fs, nextChar)) + DefError(); + + if (nextChar == ')') + { + } + else if (nextChar == ',') + { + hasProperty = true; + if (!FindNextNonWhitespace(fs, singleCharStr[0])) + DefError(); + } + else + DefError(); + } + + if (hasProperty) + { + propName = singleCharStr; + + for (;;) + { + if (!fs.Read(singleCharStr, 1)) + DefError(); + + if (singleCharStr[0] == ')') + break; + + propName += singleCharStr; + } + } + } + + if (!FindNextNonWhitespace(fs, nextChar) || nextChar != '{') + DefError(); + + // Data item parse loop + for (;;) + { + if (!FindNextNonWhitespace(fs, nextChar)) + DefError(); + + if (nextChar == '$') + { + // Res data bytes + uint8_t b = 0; + bool highNibble = true; + + if (!fs.Read(&nextChar, 1) || nextChar != '\"') + DefError(); + + for (;;) + { + if (!fs.Read(&nextChar, 1)) + DefError(); + + uint8_t fragment = 0; + + if (nextChar == '\"') + break; + else if (nextChar >= '0' && nextChar <= '9') + fragment = nextChar - '0'; + else if (nextChar >= 'a' && nextChar <= 'f') + fragment = nextChar - 'a' + 0xa; + else if (nextChar >= 'A' && nextChar <= 'F') + fragment = nextChar - 'A' + 0xa; + else if (nextChar == ' ') + { + continue; + } + else + DefError(); + + if (highNibble) + { + b = fragment << 4; + highNibble = false; + } + else + { + resData.push_back(b | fragment); + highNibble = true; + } + } + + continue; + } + else if (nextChar == '}') + break; + else if (nextChar == '/') + { + if (!fs.Read(&nextChar, 1)) + DefError(); + + if (nextChar == '/') + { + for (;;) + { + if (!fs.Read(&nextChar, 1)) + DefError(); + + if (nextChar == '\r' || nextChar == '\n') + break; + } + } + else if (nextChar == '*') + { + char prevChar = nextChar; + + for (;;) + { + if (!fs.Read(&nextChar, 1)) + DefError(); + + if (nextChar == '/' && prevChar == '*') + break; + + prevChar = nextChar; + } + } + else + DefError(); + } + else + DefError(); + } + + if (!FindNextNonWhitespace(fs, nextChar) || nextChar != ';') + DefError(); + + SimpleResource *res = new SimpleResource(); + res->m_name = HandleEscapes(resName); + res->m_resourceID = resID; + memcpy(res->m_type, resType, 4); + res->m_resourceData.swap(resData); + res->m_attributes = 0; + + if (propName == "purgeable") + res->m_attributes |= (1 << 5); + + + resources.push_back(res); + } + else + { + fprintf(stderr, "Unknown token"); + return -1; + } + } + + std::vector resourceForkData; + + for (size_t i = 0; i < 16; i++) + resourceForkData.push_back(0); + + size_t resForkDataStart = resourceForkData.size(); + + std::vector uniqueResTypes; + std::vector resTypeCounts; + std::vector uniqueResNames; + + printf("Re-emitting defs...\n"); + for (size_t i = 0; i < resources.size(); i++) + { + SimpleResource *res = resources[i]; + + res->m_offsetInResData = resourceForkData.size() - resForkDataStart; + + uint8_t packedLen[4]; + BytePack::BigUInt32(packedLen, static_cast(res->m_resourceData.size())); + + for (int j = 0; j < 4; j++) + resourceForkData.push_back(packedLen[j]); + + for (size_t j = 0; j < res->m_resourceData.size(); j++) + resourceForkData.push_back(res->m_resourceData[j]); + + uint32_t resTypeCode = TypeToU32(res->m_type); + std::vector::iterator uniqueResTypeIndex = std::find(uniqueResTypes.begin(), uniqueResTypes.end(), resTypeCode); + + if (uniqueResTypeIndex == uniqueResTypes.end()) + { + uniqueResTypes.push_back(resTypeCode); + resTypeCounts.push_back(1); + } + else + resTypeCounts[uniqueResTypeIndex - uniqueResTypes.begin()]++; + + if (!res->m_name.empty()) + { + if (std::find(uniqueResNames.begin(), uniqueResNames.end(), res->m_name) == uniqueResNames.end()) + uniqueResNames.push_back(res->m_name); + } + } + + const size_t resDataSize = resourceForkData.size() - resForkDataStart; + const size_t resMapPos = resourceForkData.size(); + + // Reserved space for resource header copy (16), handle to next res map (4), file ref number (2) + for (size_t j = 0; j < 22; j++) + resourceForkData.push_back(0); + + uint16_t resForkAttributes = 0; // We don't use any of these + + const size_t typeListEntrySize = 8; + const size_t refListEntrySize = 12; + + const size_t resourceTypeListStartLoc = 28; + const size_t resourceTypeListSize = 2 + uniqueResTypes.size() * typeListEntrySize; + const size_t resourceRefListStartLoc = resourceTypeListStartLoc + resourceTypeListSize; + const size_t resourceNameListStartLoc = resourceRefListStartLoc + resources.size() * refListEntrySize; + + AppendUInt16(resourceForkData, resForkAttributes); + AppendUInt16(resourceForkData, static_cast(resourceTypeListStartLoc)); + AppendUInt16(resourceForkData, static_cast(resourceNameListStartLoc)); + AppendUInt16(resourceForkData, static_cast(uniqueResTypes.size() - 1)); + + std::vector refListStartForType; + refListStartForType.resize(resTypeCounts.size()); + + refListStartForType[0] = 0; + for (size_t i = 1; i < refListStartForType.size(); i++) + refListStartForType[i] = refListStartForType[i - 1] + resTypeCounts[i - 1]; + + std::vector nameListStarts; + nameListStarts.resize(uniqueResNames.size()); + + nameListStarts[0] = 0; + for (size_t i = 1; i < nameListStarts.size(); i++) + nameListStarts[i] = nameListStarts[i - 1] + uniqueResNames[i - 1].size() + 1; + + // Write resource type list + for (size_t i = 0; i < uniqueResTypes.size(); i++) + { + AppendUInt32(resourceForkData, uniqueResTypes[i]); + AppendUInt16(resourceForkData, resTypeCounts[i] - 1); + AppendUInt16(resourceForkData, static_cast(refListStartForType[i] * refListEntrySize + resourceTypeListSize)); + } + + // Write reference lists + for (size_t ti = 0; ti < uniqueResTypes.size(); ti++) + { + uint32_t resType = uniqueResTypes[ti]; + + for (size_t i = 0; i < resources.size(); i++) + { + const SimpleResource *res = resources[i]; + if (TypeToU32(res->m_type) != resType) + continue; + + AppendInt16(resourceForkData, res->m_resourceID); + if (res->m_name.empty()) + AppendInt16(resourceForkData, -1); + else + { + const std::vector::iterator nameIt = std::find(uniqueResNames.begin(), uniqueResNames.end(), res->m_name); + const size_t nameIndex = nameIt - uniqueResNames.begin(); + + AppendUInt16(resourceForkData, static_cast(nameListStarts[nameIndex])); + } + + resourceForkData.push_back(res->m_attributes); + + const size_t resDataStart = res->m_offsetInResData; + + resourceForkData.push_back((resDataStart >> 16) & 0xff); + resourceForkData.push_back((resDataStart >> 8) & 0xff); + resourceForkData.push_back((resDataStart >> 0) & 0xff); + + for (int j = 0; j < 4; j++) + resourceForkData.push_back(0); // Reserved + } + } + + // Write name lists + for (size_t ni = 0; ni < uniqueResNames.size(); ni++) + { + const std::string &name = uniqueResNames[ni]; + const size_t nameLen = name.size(); + + resourceForkData.push_back(static_cast(nameLen)); + + for (size_t i = 0; i < nameLen; i++) + resourceForkData.push_back(name[i]); + } + + const size_t resMapSize = resourceForkData.size() - resMapPos; + + BytePack::BigUInt32(&resourceForkData[0], static_cast(resForkDataStart)); + BytePack::BigUInt32(&resourceForkData[4], static_cast(resMapPos)); + BytePack::BigUInt32(&resourceForkData[8], static_cast(resDataSize)); + BytePack::BigUInt32(&resourceForkData[12], static_cast(resMapSize)); + + FILE *outF = nullptr; + if (fopen_s(&outF, argv[2], "wb")) + { + fprintf(stderr, "Failed to open output file"); + return -1; + } + + fwrite(&resourceForkData[0], 1, resourceForkData.size(), outF); + fclose(outF); + + return 0; +} diff --git a/MiniRez/MiniRez.vcxproj b/MiniRez/MiniRez.vcxproj new file mode 100644 index 0000000..e835547 --- /dev/null +++ b/MiniRez/MiniRez.vcxproj @@ -0,0 +1,136 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {2FF15659-5C72-48B8-B55B-3C658E4125B5} + MiniRez + 10.0.16299.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + + + + {6ec62b0f-9353-40a4-a510-3788f1368b33} + + + + + + \ No newline at end of file diff --git a/MiniRez/MiniRez.vcxproj.filters b/MiniRez/MiniRez.vcxproj.filters new file mode 100644 index 0000000..2476dcf --- /dev/null +++ b/MiniRez/MiniRez.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/MiniRez/x64/Debug/vc141.idb b/MiniRez/x64/Debug/vc141.idb new file mode 100644 index 0000000..bdae131 Binary files /dev/null and b/MiniRez/x64/Debug/vc141.idb differ diff --git a/PortabilityLayer.props b/PortabilityLayer.props new file mode 100644 index 0000000..1f3de77 --- /dev/null +++ b/PortabilityLayer.props @@ -0,0 +1,12 @@ + + + + + + + + $(SolutionDir)\PortabilityLayer;%(AdditionalIncludeDirectories) + + + + \ No newline at end of file diff --git a/PortabilityLayer/AEHandlerDesc.h b/PortabilityLayer/AEHandlerDesc.h new file mode 100644 index 0000000..d4639fe --- /dev/null +++ b/PortabilityLayer/AEHandlerDesc.h @@ -0,0 +1,20 @@ +#pragma once +#ifndef __PL_AE_HANDLER_DESC_H__ +#define __PL_AE_HANDLER_DESC_H__ + +#include "PLAppleEventsCommonTypes.h" + +#include + +namespace PortabilityLayer +{ + struct AEHandlerDesc + { + AEEventClass m_eventClass; + AEEventID m_eventID; + AEEventHandler m_handler; + uint32_t m_ref; + }; +} + +#endif diff --git a/PortabilityLayer/AEManager.cpp b/PortabilityLayer/AEManager.cpp new file mode 100644 index 0000000..1193083 --- /dev/null +++ b/PortabilityLayer/AEManager.cpp @@ -0,0 +1,73 @@ +#include "AEManager.h" +#include "AEHandlerDesc.h" + +#include + +namespace PortabilityLayer +{ + class AEManagerImpl final : public AEManager + { + public: + AEManagerImpl(); + + void Init() override; + void Shutdown() override; + + void InstallEventHandler(AEEventClass eventClass, AEEventID eventID, AEEventHandler handler, uint32_t ref, bool isSysHandler) override; + void SetInteractAllowed(AEInteractAllowed interactAllowed) override; + + static AEManagerImpl *GetInstance(); + + private: + std::vector m_handlers; + AEInteractAllowed m_interactAllowed; + + static AEManagerImpl ms_instance; + }; + + AEManagerImpl::AEManagerImpl() + : m_interactAllowed(kAEInteractUnknown) + { + } + + void AEManagerImpl::Init() + { + m_interactAllowed = kAEInteractUnknown; + } + + void AEManagerImpl::Shutdown() + { + m_handlers.clear(); + } + + void AEManagerImpl::InstallEventHandler(AEEventClass eventClass, AEEventID eventID, AEEventHandler handler, uint32_t ref, bool isSysHandler) + { + AEHandlerDesc desc; + desc.m_eventClass = eventClass; + desc.m_eventID = eventID; + desc.m_handler = handler; + desc.m_ref = ref; + + m_handlers.push_back(desc); + } + + void AEManagerImpl::SetInteractAllowed(AEInteractAllowed interactAllowed) + { + m_interactAllowed = interactAllowed; + } + + AEManagerImpl *AEManagerImpl::GetInstance() + { + return &ms_instance; + } + + AEManagerImpl AEManagerImpl::ms_instance; + + + AEManager *AEManager::GetInstance() + { + return AEManagerImpl::GetInstance(); + } +} + + diff --git a/PortabilityLayer/AEManager.h b/PortabilityLayer/AEManager.h new file mode 100644 index 0000000..572b75e --- /dev/null +++ b/PortabilityLayer/AEManager.h @@ -0,0 +1,24 @@ +#pragma once +#ifndef __PL_AE_MANAGER_H__ +#define __PL_AE_MANAGER_H__ + +#include "PLAppleEventsCommonTypes.h" + +#include + +namespace PortabilityLayer +{ + class AEManager + { + public: + virtual void Init() = 0; + virtual void Shutdown() = 0; + + virtual void InstallEventHandler(AEEventClass eventClass, AEEventID eventID, AEEventHandler handler, uint32_t ref, bool isSysHandler) = 0; + virtual void SetInteractAllowed(AEInteractAllowed interactAllowed) = 0; + + static AEManager *GetInstance(); + }; +} + +#endif diff --git a/PortabilityLayer/BinHex4.cpp b/PortabilityLayer/BinHex4.cpp new file mode 100644 index 0000000..d07139e --- /dev/null +++ b/PortabilityLayer/BinHex4.cpp @@ -0,0 +1,302 @@ +#include "BinHex4.h" +#include "IOStream.h" + +#include +#include +#include + +// See: https://files.stairways.com/other/binhex-40-specs-info.txt +// Unfortunately, while the spec specifies that decoding is to be done high-to-low, +// it doesn't specify how the encoded 6-bit value is split. + +#include "MacFileInfo.h" +#include "ByteUnpack.h" +#include "XModemCRC.h" +#include "MacFileMem.h" + +namespace +{ + static bool IsEOL(char c) + { + return c == '\r' || c == '\n'; + } + + static bool IsWhitespaceChar(char c) + { + return c == '\r' || c == '\n' || c == ' ' || c == '\t'; + } + + uint16_t BinHexCRCNoPadding(const uint8_t *bytes, size_t size, int initialValue) + { + uint16_t crc = initialValue; + for (size_t b = 0; b < size; b++) + { + uint8_t v = bytes[b]; + + for (int i = 0; i < 8; i++) + { + int temp = (crc & 0x8000); + crc = (crc << 1) | (v >> 7); + + if (temp) + crc = crc ^ 0x1021; + + v = (v << 1) & 0xff; + } + } + + return static_cast(crc); + } + + uint16_t BinHexCRC(const uint8_t *bytes, size_t size) + { + const uint8_t zeroBytes[] = { 0, 0 }; + + uint16_t crc = BinHexCRCNoPadding(bytes, size, 0); + return BinHexCRCNoPadding(zeroBytes, 2, crc); + } +} + +namespace PortabilityLayer +{ + MacFileMem *BinHex4::LoadHQX(IOStream *stream) + { + const uint8_t errCodeChar = 64; + + uint8_t charMap[128]; + for (int i = 0; i < 128; i++) + charMap[i] = errCodeChar; + + const char binHexCharacters[] = "!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr"; + + for (int i = 0; i < 64; i++) + charMap[binHexCharacters[i]] = static_cast(i); + + const char expectedPrefix[] = "(This file must be converted with BinHex"; + const size_t prefixSizeChars = sizeof(expectedPrefix) - 1; + char prefix[prefixSizeChars]; + + if (stream->Read(prefix, prefixSizeChars) != prefixSizeChars) + return nullptr; + + if (memcmp(prefix, expectedPrefix, prefixSizeChars)) + return nullptr; + + // Find end char + for (;;) + { + char nextChar; + if (!stream->Read(&nextChar, 1)) + return nullptr; + + if (IsEOL(nextChar)) + break; + } + + // Find start colon + for (;;) + { + char nextChar; + if (!stream->Read(&nextChar, 1)) + return nullptr; + + if (IsWhitespaceChar(nextChar)) + continue; + else if (nextChar == ':') + break; + else + return nullptr; + } + + std::vector bytesAfter6To8; + + if (stream->IsSeekable()) + { + UFilePos_t filePos = stream->Tell(); + if (stream->SeekEnd(0)) + { + UFilePos_t endPos = stream->Tell(); + if (!stream->SeekStart(filePos)) + return nullptr; + + if (endPos > filePos && (endPos - filePos) < SIZE_MAX / 6) + bytesAfter6To8.reserve(static_cast(endPos - filePos) * 6 / 8); + } + } + + // Undo 8-to-6 coding + const size_t bufferCapacity = 128; + size_t bufferReadPos = 0; + size_t bufferSize = 0; + char buffer[bufferCapacity]; + + bool isEOF = false; + + int decodedByte = 0; + int decodedByteBitPos = 8; + + for (;;) + { + if (bufferReadPos == bufferSize) + { + const size_t numRead = stream->Read(buffer, bufferCapacity); + if (numRead == 0) + return nullptr; // Missing terminator + + bufferSize = numRead; + bufferReadPos = 0; + } + + char nextChar = buffer[bufferReadPos++]; + + if (nextChar == ':') + break; + + if (IsWhitespaceChar(nextChar)) + continue; + + if (nextChar < 0 || nextChar > 127) + return nullptr; + + uint8_t value6Bit = charMap[nextChar]; + if (value6Bit == errCodeChar) + return nullptr; + + switch (decodedByteBitPos) + { + case 8: + decodedByte = value6Bit << 2; + decodedByteBitPos = 2; + break; + case 6: + decodedByte |= value6Bit; + bytesAfter6To8.push_back(decodedByte); + decodedByte = 0; + decodedByteBitPos = 8; + break; + case 4: + decodedByte |= (value6Bit >> 2); + bytesAfter6To8.push_back(decodedByte); + decodedByte = (value6Bit << 6) & 0xff; + decodedByteBitPos = 6; + break; + case 2: + decodedByte |= (value6Bit >> 4); + bytesAfter6To8.push_back(decodedByte); + decodedByte = (value6Bit << 4) & 0xff; + decodedByteBitPos = 4; + break; + default: + return nullptr; + } + } + + const size_t bytesBeforeRLEDec = bytesAfter6To8.size(); + size_t decodedDataSize = 0; + for (size_t i = 0; i < bytesBeforeRLEDec; i++) + { + const uint8_t b = bytesAfter6To8[i]; + if (b == 0x90) + { + if (i == bytesBeforeRLEDec - 1) + return nullptr; + + const uint8_t runLength = bytesAfter6To8[++i]; + + if (runLength == 0) + decodedDataSize++; // 0x90 literal + else + decodedDataSize += runLength - 1; // RLE, runs of length 1 are permitted + } + else + decodedDataSize++; + } + + std::vector decodedBytes; + decodedBytes.reserve(decodedDataSize); + + for (size_t i = 0; i < bytesBeforeRLEDec; i++) + { + const uint8_t b = bytesAfter6To8[i]; + + if (b == 0x90) + { + const uint8_t runLength = bytesAfter6To8[++i]; + + if (runLength == 0) + decodedBytes.push_back(0x90); + else + { + if (decodedBytes.size() == 0) + return nullptr; + + const uint8_t lastByte = *(decodedBytes.end() - 1); + for (size_t r = 1; r < runLength; r++) + decodedBytes.push_back(lastByte); + } + } + else + decodedBytes.push_back(b); + } + + assert(decodedBytes.size() == decodedDataSize); + + if (decodedBytes.size() == 0) + return nullptr; + + const uint8_t nameLength = decodedBytes[0]; + if (decodedBytes.size() < 22 + nameLength || nameLength > 63) + return nullptr; + + // Header format: + // uint8_t nameLength + // char name[nameLength] + // char + // char fileType[4] + // char fileCreator[4] + // word flags + // dword dataLength + // dword resourceLength + // word headerCRC + + const size_t headerStartLoc = 2 + nameLength; + + if (decodedBytes[nameLength + 1] != 0) + return nullptr; + + MacFileInfo mfi; + mfi.m_fileName.Set(nameLength, reinterpret_cast(&decodedBytes[1])); + memcpy(mfi.m_properties.m_fileType, &decodedBytes[headerStartLoc + 0], 4); + memcpy(mfi.m_properties.m_fileCreator, &decodedBytes[headerStartLoc + 4], 4); + mfi.m_properties.m_finderFlags = ByteUnpack::BigUInt16(&decodedBytes[headerStartLoc + 8]); + mfi.m_dataForkSize = ByteUnpack::BigUInt32(&decodedBytes[headerStartLoc + 10]); + mfi.m_resourceForkSize = ByteUnpack::BigUInt32(&decodedBytes[headerStartLoc + 14]); + + const size_t availableDataSize = decodedBytes.size() - 26 - nameLength; // +4 bytes for CRCs + + if (mfi.m_dataForkSize > availableDataSize || availableDataSize - mfi.m_dataForkSize < mfi.m_resourceForkSize) + return nullptr; + + const uint16_t expectedHeaderCRC = ByteUnpack::BigUInt16(&decodedBytes[headerStartLoc + 18]); + const uint16_t actualHeaderCRC = BinHexCRC(&decodedBytes[0], headerStartLoc + 18); + + if (expectedHeaderCRC != actualHeaderCRC) + return nullptr; + + const size_t dataForkStart = headerStartLoc + 20; + const size_t dataForkCRCLoc = dataForkStart + mfi.m_dataForkSize; + const size_t resourceForkStart = dataForkCRCLoc + 2; + const size_t resourceForkCRCLoc = resourceForkStart + mfi.m_resourceForkSize; + + const uint16_t expectedDataCRC = ByteUnpack::BigUInt16(&decodedBytes[dataForkCRCLoc]); + const uint16_t expectedResCRC = ByteUnpack::BigUInt16(&decodedBytes[resourceForkCRCLoc]); + + if (expectedDataCRC != BinHexCRC(&decodedBytes[dataForkStart], mfi.m_dataForkSize)) + return false; + + if (expectedResCRC != BinHexCRC(&decodedBytes[resourceForkStart], mfi.m_resourceForkSize)) + return false; + + return new MacFileMem(&decodedBytes[dataForkStart], &decodedBytes[resourceForkStart], nullptr, mfi); + } +} diff --git a/PortabilityLayer/BinHex4.h b/PortabilityLayer/BinHex4.h new file mode 100644 index 0000000..be30643 --- /dev/null +++ b/PortabilityLayer/BinHex4.h @@ -0,0 +1,17 @@ +#pragma once + +#ifndef __PL_BINHEX4_H__ +#define __PL_BINHEX4_H__ + +namespace PortabilityLayer +{ + class IOStream; + class MacFileMem; + + namespace BinHex4 + { + MacFileMem *LoadHQX(IOStream *stream); + }; +} + +#endif diff --git a/PortabilityLayer/BinarySearch.h b/PortabilityLayer/BinarySearch.h new file mode 100644 index 0000000..ca52557 --- /dev/null +++ b/PortabilityLayer/BinarySearch.h @@ -0,0 +1,36 @@ +#pragma once +#ifndef __PL_BINARY_SEARCH_H__ +#define __PL_BINARY_SEARCH_H__ + +#include + +namespace PortabilityLayer +{ + template + TIterator BinarySearch(const TIterator &startInclusive, const TIterator &endExclusive, const TItem &item, const TPredicate &pred) + { + TIterator searchStartInclusive = startInclusive; + TIterator searchEndExclusive = endExclusive; + + while (searchStartInclusive != searchEndExclusive) + { + const ptrdiff_t delta = searchEndExclusive - searchStartInclusive; + const ptrdiff_t halfDelta = delta / 2; + + const TIterator midPoint = searchStartInclusive + halfDelta; + + const int comparison = pred(item, *midPoint); + + if (comparison < 0) + searchEndExclusive = midPoint; + else if (comparison > 0) + searchStartInclusive = midPoint + 1; + else + return midPoint; + } + + return endExclusive; + } +} + +#endif diff --git a/PortabilityLayer/BytePack.h b/PortabilityLayer/BytePack.h new file mode 100644 index 0000000..ccb1f55 --- /dev/null +++ b/PortabilityLayer/BytePack.h @@ -0,0 +1,76 @@ +#pragma once + +#ifndef __PL_BYTEPACK_H__ +#define __PL_BYTEPACK_H__ + +#include "DataTypes.h" + +namespace PortabilityLayer +{ + namespace BytePack + { + void BigUInt64(uint8_t *bytes, uint64_t value); + void BigUInt32(uint8_t *bytes, uint32_t value); + void BigUInt16(uint8_t *bytes, uint16_t value); + } +} + +namespace PortabilityLayer +{ + namespace BytePack + { + inline void BigUInt64(uint8_t *bytes, uint64_t value) + { + bytes[0] = static_cast((value >> 56) & 0xff); + bytes[1] = static_cast((value >> 48) & 0xff); + bytes[2] = static_cast((value >> 40) & 0xff); + bytes[3] = static_cast((value >> 32) & 0xff); + bytes[4] = static_cast((value >> 24) & 0xff); + bytes[5] = static_cast((value >> 16) & 0xff); + bytes[6] = static_cast((value >> 8) & 0xff); + bytes[7] = static_cast(value & 0xff); + } + + inline void BigUInt32(uint8_t *bytes, uint32_t value) + { + bytes[0] = static_cast((value >> 24) & 0xff); + bytes[1] = static_cast((value >> 16) & 0xff); + bytes[2] = static_cast((value >> 8) & 0xff); + bytes[3] = static_cast(value & 0xff); + } + + inline void BigUInt16(uint8_t *bytes, uint16_t value) + { + bytes[0] = static_cast((value >> 8) & 0xff); + bytes[1] = static_cast(value & 0xff); + } + + inline void BigInt64(uint8_t *bytes, int64_t value) + { + bytes[0] = static_cast((value >> 56) & 0xff); + bytes[1] = static_cast((value >> 48) & 0xff); + bytes[2] = static_cast((value >> 40) & 0xff); + bytes[3] = static_cast((value >> 32) & 0xff); + bytes[4] = static_cast((value >> 24) & 0xff); + bytes[5] = static_cast((value >> 16) & 0xff); + bytes[6] = static_cast((value >> 8) & 0xff); + bytes[7] = static_cast(value & 0xff); + } + + inline void BigInt32(uint8_t *bytes, uint32_t value) + { + bytes[0] = static_cast((value >> 24) & 0xff); + bytes[1] = static_cast((value >> 16) & 0xff); + bytes[2] = static_cast((value >> 8) & 0xff); + bytes[3] = static_cast(value & 0xff); + } + + inline void BigInt16(uint8_t *bytes, uint16_t value) + { + bytes[0] = static_cast((value >> 8) & 0xff); + bytes[1] = static_cast(value & 0xff); + } + } +} + +#endif diff --git a/PortabilityLayer/ByteSwap.cpp b/PortabilityLayer/ByteSwap.cpp new file mode 100644 index 0000000..92836e8 --- /dev/null +++ b/PortabilityLayer/ByteSwap.cpp @@ -0,0 +1,37 @@ +#include "ByteSwap.h" + +namespace PortabilityLayer +{ + namespace ByteSwap + { + void BigInt16(int16_t &v) + { + const uint8_t *asU8 = reinterpret_cast(&v); + const int8_t *asS8 = reinterpret_cast(&v); + + v = static_cast((asS8[0] << 8) | asU8[1]); + } + + void BigInt32(int32_t &v) + { + const uint8_t *asU8 = reinterpret_cast(&v); + const int8_t *asS8 = reinterpret_cast(&v); + + v = static_cast((asS8[0] << 24) | (asU8[1] << 16) | (asU8[2] << 8) | asU8[3]); + } + + void BigUInt16(uint16_t &v) + { + const uint8_t *asU8 = reinterpret_cast(&v); + + v = static_cast((asU8[0] << 8) | asU8[1]); + } + + void BigUInt32(uint32_t &v) + { + const uint8_t *asU8 = reinterpret_cast(&v); + + v = static_cast((asU8[0] << 24) | (asU8[1] << 16) | (asU8[2] << 8) | asU8[3]); + } + } +} diff --git a/PortabilityLayer/ByteSwap.h b/PortabilityLayer/ByteSwap.h new file mode 100644 index 0000000..ca132db --- /dev/null +++ b/PortabilityLayer/ByteSwap.h @@ -0,0 +1,18 @@ +#pragma once +#ifndef __PL_BYTESWAP_H__ +#define __PL_BYTESWAP_H__ + +#include + +namespace PortabilityLayer +{ + namespace ByteSwap + { + void BigInt16(int16_t &v); + void BigInt32(int32_t &v); + void BigUInt16(uint16_t &v); + void BigUInt32(uint32_t &v); + } +} + +#endif diff --git a/PortabilityLayer/ByteUnpack.h b/PortabilityLayer/ByteUnpack.h new file mode 100644 index 0000000..240fa1b --- /dev/null +++ b/PortabilityLayer/ByteUnpack.h @@ -0,0 +1,78 @@ +#pragma once + +#ifndef __PL_BYTEUNPACK_H__ +#define __PL_BYTEUNPACK_H__ + +#include "DataTypes.h" + +namespace PortabilityLayer +{ + namespace ByteUnpack + { + uint64_t BigUInt64(const uint8_t *bytes); + uint32_t BigUInt32(const uint8_t *bytes); + uint16_t BigUInt16(const uint8_t *bytes); + + int64_t BigInt64(const uint8_t *bytes); + int32_t BigInt32(const uint8_t *bytes); + int16_t BigInt16(const uint8_t *bytes); + } +} + +namespace PortabilityLayer +{ + namespace ByteUnpack + { + inline uint64_t BigUInt64(const uint8_t *bytes) + { + return (static_cast(bytes[0]) << 56) + | (static_cast(bytes[1]) << 48) + | (static_cast(bytes[2]) << 32) + | (static_cast(bytes[3]) << 24) + | (static_cast(bytes[4]) << 16) + | (static_cast(bytes[5]) << 8) + | (static_cast(bytes[6])); + } + + inline uint32_t BigUInt32(const uint8_t *bytes) + { + return (static_cast(bytes[0]) << 24) + | (static_cast(bytes[1]) << 16) + | (static_cast(bytes[2]) << 8) + | (static_cast(bytes[3])); + } + + inline uint16_t BigUInt16(const uint8_t *bytes) + { + return (static_cast(bytes[0]) << 8) + | (static_cast(bytes[1])); + } + + inline int64_t BigInt64(const uint8_t *bytes) + { + return (static_cast(bytes[0]) << 56) + | (static_cast(bytes[1]) << 48) + | (static_cast(bytes[2]) << 32) + | (static_cast(bytes[3]) << 24) + | (static_cast(bytes[4]) << 16) + | (static_cast(bytes[5]) << 8) + | (static_cast(bytes[6])); + } + + inline int32_t BigInt32(const uint8_t *bytes) + { + return (static_cast(bytes[0]) << 24) + | (static_cast(bytes[1]) << 16) + | (static_cast(bytes[2]) << 8) + | (static_cast(bytes[3])); + } + + inline int16_t BigInt16(const uint8_t *bytes) + { + return (static_cast(bytes[0]) << 8) + | (static_cast(bytes[1])); + } + } +} + +#endif diff --git a/PortabilityLayer/CFileStream.cpp b/PortabilityLayer/CFileStream.cpp new file mode 100644 index 0000000..700a041 --- /dev/null +++ b/PortabilityLayer/CFileStream.cpp @@ -0,0 +1,110 @@ +#include "CFileStream.h" + +namespace PortabilityLayer +{ + CFileStream::CFileStream(FILE *f) + : m_file(f) + , m_readOnly(false) + , m_writeOnly(false) + , m_seekable(true) + { + } + + CFileStream::CFileStream(FILE *f, bool isReadOnly, bool isWriteOnly, bool isSeekable) + : m_file(f) + , m_readOnly(isReadOnly) + , m_writeOnly(isWriteOnly) + , m_seekable(isSeekable) + { + } + + size_t CFileStream::Read(void *bytesOut, size_t size) + { + if (!m_file || m_writeOnly) + return 0; + + return fread(bytesOut, 1, size, m_file); + } + + size_t CFileStream::Write(const void *bytes, size_t size) + { + if (!m_file || m_readOnly) + return 0; + + return fwrite(bytes, 1, size, m_file); + } + + bool CFileStream::IsSeekable() const + { + return m_seekable; + } + + bool CFileStream::IsReadOnly() const + { + return m_readOnly; + } + + bool CFileStream::IsWriteOnly() const + { + return m_writeOnly; + } + + bool CFileStream::SeekStart(UFilePos_t loc) + { + if (!m_file) + return false; + + return fseek(m_file, static_cast(loc), SEEK_SET) == 0; + } + + bool CFileStream::SeekCurrent(FilePos_t loc) + { + if (!m_file) + return false; + + return fseek(m_file, static_cast(loc), SEEK_CUR) == 0;; + } + + bool CFileStream::SeekEnd(UFilePos_t loc) + { + if (!m_file) + return false; + + return fseek(m_file, static_cast(loc), SEEK_END) == 0; + } + + bool CFileStream::Truncate(UFilePos_t loc) + { + return false; + } + + UFilePos_t CFileStream::Tell() const + { + if (!m_file) + return 0; + + return static_cast(ftell(m_file)); + } + + void CFileStream::Close() + { + if (m_file) + { + fclose(m_file); + m_file = nullptr; + } + } + + UFilePos_t CFileStream::Size() const + { + if (!m_file || !m_seekable) + return 0; + + long oldPos = ftell(m_file); + fseek(m_file, SEEK_END, 0); + const UFilePos_t endPos = static_cast(ftell(m_file)); + fseek(m_file, oldPos, SEEK_SET); + + return endPos; + } +} diff --git a/PortabilityLayer/CFileStream.h b/PortabilityLayer/CFileStream.h new file mode 100644 index 0000000..c411515 --- /dev/null +++ b/PortabilityLayer/CFileStream.h @@ -0,0 +1,42 @@ +#pragma once + +#ifndef __PL_CFILESTREAM_H__ +#define __PL_CFILESTREAM_H__ + +#include + +#include "CoreDefs.h" +#include "IOStream.h" + +namespace PortabilityLayer +{ + class CFileStream final : public IOStream + { + public: + explicit CFileStream(FILE *f); + CFileStream(FILE *f, bool isReadOnly, bool isWriteOnly, bool isSeekable); + + size_t Read(void *bytesOut, size_t size) override; + size_t Write(const void *bytes, size_t size) override; + bool IsSeekable() const override; + bool IsReadOnly() const override; + bool IsWriteOnly() const override; + bool SeekStart(UFilePos_t loc) override; + bool SeekCurrent(FilePos_t loc) override; + bool SeekEnd(UFilePos_t loc) override; + bool Truncate(UFilePos_t loc) override; + UFilePos_t Size() const override; + UFilePos_t Tell() const override; + void Close() override; + + private: + CFileStream(const CFileStream &other) PL_DELETED; + + FILE *m_file; + bool m_readOnly; + bool m_writeOnly; + bool m_seekable; + }; +} + +#endif diff --git a/PortabilityLayer/DataTypes.h b/PortabilityLayer/DataTypes.h new file mode 100644 index 0000000..b5c11fe --- /dev/null +++ b/PortabilityLayer/DataTypes.h @@ -0,0 +1,14 @@ +#pragma once + +#ifndef __PL_DATATYPES_H__ +#define __PL_DATATYPES_H__ + +#include + +namespace PortabilityLayer +{ + typedef int64_t LargestInt_t; + typedef uint64_t LargestUInt_t; +} + +#endif diff --git a/PortabilityLayer/DisplayDeviceManager.cpp b/PortabilityLayer/DisplayDeviceManager.cpp new file mode 100644 index 0000000..a0e0dd5 --- /dev/null +++ b/PortabilityLayer/DisplayDeviceManager.cpp @@ -0,0 +1,75 @@ +#include "DisplayDeviceManager.h" + +#include "PLQuickdraw.h" + +#include "MemoryManager.h" + +namespace PortabilityLayer +{ + class DisplayDeviceManagerImpl final : public DisplayDeviceManager + { + public: + DisplayDeviceManagerImpl(); + + void Init() override; + void Shutdown() override; + + GDevice **GetMainDevice() override; + + + void IncrementTickCount(uint32_t count) override; + uint32_t GetTickCount() override; + + static DisplayDeviceManagerImpl *GetInstance(); + + private: + GDHandle m_mainDevice; + uint32_t m_tickCount; + + static DisplayDeviceManagerImpl ms_instance; + }; + + DisplayDeviceManagerImpl::DisplayDeviceManagerImpl() + : m_mainDevice(nullptr) + , m_tickCount(1) + { + } + + void DisplayDeviceManagerImpl::Init() + { + m_mainDevice = MemoryManager::GetInstance()->NewHandle(); + } + + void DisplayDeviceManagerImpl::Shutdown() + { + MemoryManager::GetInstance()->ReleaseHandle(reinterpret_cast(m_mainDevice)); + } + + GDevice **DisplayDeviceManagerImpl::GetMainDevice() + { + return m_mainDevice; + } + + void DisplayDeviceManagerImpl::IncrementTickCount(uint32_t count) + { + m_tickCount += count; + } + + uint32_t DisplayDeviceManagerImpl::GetTickCount() + { + return m_tickCount; + } + + + DisplayDeviceManagerImpl *DisplayDeviceManagerImpl::GetInstance() + { + return &ms_instance; + } + + DisplayDeviceManagerImpl DisplayDeviceManagerImpl::ms_instance; + + DisplayDeviceManager *DisplayDeviceManager::GetInstance() + { + return DisplayDeviceManagerImpl::GetInstance(); + } +} diff --git a/PortabilityLayer/DisplayDeviceManager.h b/PortabilityLayer/DisplayDeviceManager.h new file mode 100644 index 0000000..6cc5f5a --- /dev/null +++ b/PortabilityLayer/DisplayDeviceManager.h @@ -0,0 +1,25 @@ +#pragma once +#ifndef __PL_DEVICE_MANAGER_H__ +#define __PL_DEVICE_MANAGER_H__ + +#include + +struct GDevice; + +namespace PortabilityLayer +{ + class DisplayDeviceManager + { + public: + virtual void Init() = 0; + virtual void Shutdown() = 0; + + virtual GDevice **GetMainDevice() = 0; + virtual void IncrementTickCount(uint32_t count) = 0; + virtual uint32_t GetTickCount() = 0; + + static DisplayDeviceManager *GetInstance(); + }; +} + +#endif diff --git a/PortabilityLayer/FileManager.cpp b/PortabilityLayer/FileManager.cpp new file mode 100644 index 0000000..bafc946 --- /dev/null +++ b/PortabilityLayer/FileManager.cpp @@ -0,0 +1,207 @@ +#include "FileManager.h" +#include "HostFileSystem.h" +#include "HostMemoryBuffer.h" +#include "MemReaderStream.h" +#include "MacBinary2.h" +#include "MacFileMem.h" +#include "PLPasStr.h" +#include "PLErrorCodes.h" + +#include + +namespace PortabilityLayer +{ + class VirtualFile; + + class FileManagerImpl final : public FileManager + { + public: + bool FileExists(uint32_t dirID, const PLPasStr &filename) override; + + int OpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, short *outRefNum) override; + int OpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, short *outRefNum) override; + + int RawOpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, IOStream **outStream) override; + int RawOpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, IOStream **outStream) override; + + static FileManagerImpl *GetInstance(); + + private: + typedef char ExtendedFileName_t[64 + 4]; + + struct OpenedFile + { + EVirtualDirectory m_dirID; + PascalStr<64> m_fileName; + + IOStream *m_stream; + }; + + int OpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *ext, EFilePermission permission, short *outRefNum); + int RawOpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *ext, EFilePermission permission, bool ignoreMeta, IOStream **outStream); + + static bool ConstructFilename(ExtendedFileName_t& extFN, const PLPasStr &fn, const char *extension); + + std::vector m_refs; + + static FileManagerImpl ms_instance; + }; + + bool FileManagerImpl::FileExists(uint32_t dirID, const PLPasStr &filename) + { + ExtendedFileName_t extFN; + if (!ConstructFilename(extFN, filename, ".gpf")) + return false; + + return HostFileSystem::GetInstance()->FileExists(static_cast(dirID), extFN); + } + + int FileManagerImpl::OpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, short *outRefNum) + { + return OpenFileFork(dirID, filename, ".gpd", permission, outRefNum); + } + + int FileManagerImpl::OpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, short *outRefNum) + { + return OpenFileFork(dirID, filename, ".gpr", permission, outRefNum); + } + + int FileManagerImpl::RawOpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, bool ignoreMeta, IOStream **outStream) + { + return RawOpenFileFork(dirID, filename, ".gpd", permission, ignoreMeta, outStream); + } + + int FileManagerImpl::RawOpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission permission, bool ignoreMeta, IOStream **outStream) + { + return RawOpenFileFork(dirID, filename, ".gpr", permission, ignoreMeta, outStream); + } + + FileManagerImpl *FileManagerImpl::GetInstance() + { + return &ms_instance; + } + + int FileManagerImpl::OpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *extension, EFilePermission permission, short *outRefNum) + { + const size_t numRefs = m_refs.size(); + size_t refIndex = m_refs.size(); + for (size_t i = 0; i < numRefs; i++) + { + if (m_refs[i].m_stream == nullptr) + { + refIndex = i; + break; + } + } + + if (refIndex == 0x7fff) + return tmfoErr; + + IOStream *stream = nullptr; + int openError = RawOpenFileFork(dirID, filename, extension, permission, false, &stream); + if (openError != 0) + return openError; + + if (refIndex == numRefs) + m_refs.push_back(OpenedFile()); + + OpenedFile &of = m_refs[refIndex]; + of.m_stream = stream; + of.m_dirID = static_cast(dirID); + of.m_fileName.Set(filename.Length(), filename.Chars()); + + *outRefNum = static_cast(refIndex + 1); + + return noErr; + } + + int FileManagerImpl::RawOpenFileFork(uint32_t dirID, const PLPasStr &filename, const char *ext, EFilePermission permission, bool ignoreMeta, IOStream **outStream) + { + ExtendedFileName_t gpfExtFN; + ExtendedFileName_t extFN; + + if (filename.Length() > 63) + return bdNamErr; + + if (!ignoreMeta) + { + if (!ConstructFilename(gpfExtFN, filename, ".gpf")) + return bdNamErr; + + if (!HostFileSystem::GetInstance()->FileExists(static_cast(dirID), gpfExtFN)) + return fnfErr; + } + + const bool needToCreate = !(ignoreMeta || HostFileSystem::GetInstance()->FileExists(static_cast(dirID), extFN)); + + if (!ConstructFilename(extFN, filename, ext)) + return bdNamErr; + + IOStream *fstream = nullptr; + switch (permission) + { + case EFilePermission_Any: + fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, true, needToCreate); + if (fstream) + permission = EFilePermission_ReadWrite; + else + { + permission = EFilePermission_Read; + fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, false, needToCreate); + } + break; + case EFilePermission_Read: + fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, false, needToCreate); + break; + case EFilePermission_ReadWrite: + fstream = HostFileSystem::GetInstance()->OpenFile(static_cast(dirID), extFN, true, needToCreate); + break; + } + + if (!fstream) + return permErr; + + *outStream = fstream; + return noErr; + } + + bool FileManagerImpl::ConstructFilename(ExtendedFileName_t& extFN, const PLPasStr &fn, const char *extension) + { + const size_t fnameSize = fn.Length(); + if (fnameSize >= 64) + return false; + + memcpy(extFN, fn.Chars(), fnameSize); + memcpy(extFN + fnameSize, extension, strlen(extension) + 1); + + for (size_t i = 0; i < fnameSize; i++) + { + const char c = extFN[i]; + if (c >= '0' && c <= '9') + continue; + + if (c == '_') + continue; + + if (c == ' ' && i != 0 && i != fnameSize - 1) + continue; + + if (c >= 'a' && c <= 'z') + continue; + + if (c >= 'A' && c <= 'Z') + continue; + + return false; + } + + return true; + } + + FileManagerImpl FileManagerImpl::ms_instance; + + FileManager *FileManager::GetInstance() + { + return FileManagerImpl::GetInstance(); + } +} diff --git a/PortabilityLayer/FileManager.h b/PortabilityLayer/FileManager.h new file mode 100644 index 0000000..7e628f5 --- /dev/null +++ b/PortabilityLayer/FileManager.h @@ -0,0 +1,31 @@ +#pragma once +#ifndef __PL_FILE_MANAGER_H__ +#define __PL_FILE_MANAGER_H__ + +#include "FilePermission.h" +#include "CoreDefs.h" + +#include + +class PLPasStr; + +namespace PortabilityLayer +{ + class IOStream; + + class FileManager + { + public: + virtual bool FileExists(uint32_t dirID, const PLPasStr &filename) = 0; + + virtual int OpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, short *outRefNum) = 0; + virtual int OpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, short *outRefNum) = 0; + + virtual int RawOpenFileDF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, IOStream **outStream) = 0; + virtual int RawOpenFileRF(uint32_t dirID, const PLPasStr &filename, EFilePermission filePermission, bool ignoreMeta, IOStream **outStream) = 0; + + static FileManager *GetInstance(); + }; +} + +#endif diff --git a/PortabilityLayer/FilePermission.h b/PortabilityLayer/FilePermission.h new file mode 100644 index 0000000..f3926f5 --- /dev/null +++ b/PortabilityLayer/FilePermission.h @@ -0,0 +1,15 @@ +#pragma once +#ifndef __PL_FILE_PERMISSION_H__ +#define __PL_FILE_PERMISSION_H__ + +namespace PortabilityLayer +{ + enum EFilePermission + { + EFilePermission_Any, + EFilePermission_Read, + EFilePermission_ReadWrite, + }; +} + +#endif diff --git a/PortabilityLayer/GpAppInterface.h b/PortabilityLayer/GpAppInterface.h new file mode 100644 index 0000000..0d1f844 --- /dev/null +++ b/PortabilityLayer/GpAppInterface.h @@ -0,0 +1,42 @@ +#pragma once +#ifndef __GPAPP_INTERFACE_H__ +#define __GPAPP_INTERFACE_H__ + +#include "HostSuspendHook.h" +#include + +#ifdef GP_APP_DLL + +#ifdef GP_APP_DLL_EXPORT +#define GP_APP_DLL_EXPORT_API extern "C" __declspec(dllexport) +#else +#define GP_APP_DLL_EXPORT_API extern "C" __declspec(dllimport) +#endif + +#else + +#define GP_APP_DLL_EXPORT_API extern "C" + +#endif + +namespace PortabilityLayer +{ + class HostFileSystem; + class HostDisplayDriver; + class HostSystemServices; +} + +class GpAppInterface +{ +public: + virtual int ApplicationMain() = 0; + virtual void PL_IncrementTickCounter(uint32_t count) = 0; + virtual void PL_HostFileSystem_SetInstance(PortabilityLayer::HostFileSystem *instance) = 0; + virtual void PL_HostDisplayDriver_SetInstance(PortabilityLayer::HostDisplayDriver *instance) = 0; + virtual void PL_HostSystemServices_SetInstance(PortabilityLayer::HostSystemServices *instance) = 0; + virtual void PL_InstallHostSuspendHook(PortabilityLayer::HostSuspendHook_t hook, void *context) = 0; +}; + +GP_APP_DLL_EXPORT_API GpAppInterface *GpAppInterface_Get(); + +#endif diff --git a/PortabilityLayer/HostDisplayDriver.cpp b/PortabilityLayer/HostDisplayDriver.cpp new file mode 100644 index 0000000..4dab6c2 --- /dev/null +++ b/PortabilityLayer/HostDisplayDriver.cpp @@ -0,0 +1,16 @@ +#include "HostDisplayDriver.h" + +namespace PortabilityLayer +{ + HostDisplayDriver *HostDisplayDriver::GetInstance() + { + return ms_instance; + } + + void HostDisplayDriver::SetInstance(HostDisplayDriver *instance) + { + ms_instance = instance; + } + + HostDisplayDriver *HostDisplayDriver::ms_instance; +} diff --git a/PortabilityLayer/HostDisplayDriver.h b/PortabilityLayer/HostDisplayDriver.h new file mode 100644 index 0000000..35e1931 --- /dev/null +++ b/PortabilityLayer/HostDisplayDriver.h @@ -0,0 +1,21 @@ +#pragma once +#ifndef __PL_HOST_DISPLAY_DRIVER_H__ +#define __PL_HOST_DISPLAY_DRIVER_H__ + +namespace PortabilityLayer +{ + class HostDisplayDriver + { + public: + virtual void GetDisplayResolution(unsigned int &width, unsigned int &height) = 0; + virtual void HideCursor() = 0; + + static void SetInstance(HostDisplayDriver *instance); + static HostDisplayDriver *GetInstance(); + + private: + static HostDisplayDriver *ms_instance; + }; +} + +#endif diff --git a/PortabilityLayer/HostFileSystem.cpp b/PortabilityLayer/HostFileSystem.cpp new file mode 100644 index 0000000..56832c5 --- /dev/null +++ b/PortabilityLayer/HostFileSystem.cpp @@ -0,0 +1,16 @@ +#include "HostFileSystem.h" + +namespace PortabilityLayer +{ + HostFileSystem *HostFileSystem::GetInstance() + { + return ms_instance; + } + + void HostFileSystem::SetInstance(HostFileSystem *instance) + { + ms_instance = instance; + } + + HostFileSystem *HostFileSystem::ms_instance; +} diff --git a/PortabilityLayer/HostFileSystem.h b/PortabilityLayer/HostFileSystem.h new file mode 100644 index 0000000..443822b --- /dev/null +++ b/PortabilityLayer/HostFileSystem.h @@ -0,0 +1,25 @@ +#pragma once +#ifndef __PL_HOST_FILESYSTEM_H__ +#define __PL_HOST_FILESYSTEM_H__ + +#include "VirtualDirectory.h" + +namespace PortabilityLayer +{ + class IOStream; + + class HostFileSystem + { + public: + virtual bool FileExists(EVirtualDirectory virtualDirectory, const char *path) = 0; + virtual IOStream *OpenFile(EVirtualDirectory virtualDirectory, const char *path, bool writeAccess, bool create) = 0; + + static HostFileSystem *GetInstance(); + static void SetInstance(HostFileSystem *instance); + + private: + static HostFileSystem *ms_instance; + }; +} + +#endif diff --git a/PortabilityLayer/HostMemoryBuffer.h b/PortabilityLayer/HostMemoryBuffer.h new file mode 100644 index 0000000..ca255e8 --- /dev/null +++ b/PortabilityLayer/HostMemoryBuffer.h @@ -0,0 +1,20 @@ +#pragma once +#ifndef __PL_HOST_MEMORYBUFFER_H__ +#define __PL_HOST_MEMORYBUFFER_H__ + +#include + +#include "CoreDefs.h" + +namespace PortabilityLayer +{ + class HostMemoryBuffer + { + public: + virtual void *Contents() = 0; + virtual size_t Size() = 0; + virtual void Destroy() = 0; + }; +} + +#endif diff --git a/PortabilityLayer/HostSuspendCallArgument.h b/PortabilityLayer/HostSuspendCallArgument.h new file mode 100644 index 0000000..5d3b334 --- /dev/null +++ b/PortabilityLayer/HostSuspendCallArgument.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +#include "HostSuspendCallID.h" + +namespace PortabilityLayer +{ + union HostSuspendCallArgument + { + uint32_t m_uint; + int32_t m_int; + size_t m_size; + void *m_pointer; + const void *m_constPointer; + }; +} diff --git a/PortabilityLayer/HostSuspendCallID.h b/PortabilityLayer/HostSuspendCallID.h new file mode 100644 index 0000000..4b3e0d5 --- /dev/null +++ b/PortabilityLayer/HostSuspendCallID.h @@ -0,0 +1,15 @@ +#pragma once +#ifndef __PL_HOST_API_CALL_ID_H__ +#define __PL_HOST_API_CALL_ID_H__ + +namespace PortabilityLayer +{ + enum HostSuspendCallID + { + HostSuspendCallID_Unknown, + + HostSuspendCallID_Delay, + }; +} + +#endif diff --git a/PortabilityLayer/HostSuspendHook.cpp b/PortabilityLayer/HostSuspendHook.cpp new file mode 100644 index 0000000..564cf28 --- /dev/null +++ b/PortabilityLayer/HostSuspendHook.cpp @@ -0,0 +1,22 @@ +#include "HostSuspendHook.h" +#include "HostSuspendCallArgument.h" + +namespace +{ + static PortabilityLayer::HostSuspendHook_t gs_suspendHook; + static void *gs_suspendContext; +} + +namespace PortabilityLayer +{ + void InstallHostSuspendHook(HostSuspendHook_t hook, void *context) + { + gs_suspendHook = hook; + gs_suspendContext = context; + } + + void SuspendApplication(HostSuspendCallID callID, const HostSuspendCallArgument *args, HostSuspendCallArgument *returnValue) + { + gs_suspendHook(gs_suspendContext, callID, args, returnValue); + } +} diff --git a/PortabilityLayer/HostSuspendHook.h b/PortabilityLayer/HostSuspendHook.h new file mode 100644 index 0000000..103e437 --- /dev/null +++ b/PortabilityLayer/HostSuspendHook.h @@ -0,0 +1,17 @@ +#pragma once +#ifndef __PL_HOST_API_HOOK_H__ +#define __PL_HOST_API_HOOK_H__ + +#include "HostSuspendCallID.h" + +namespace PortabilityLayer +{ + union HostSuspendCallArgument; + + typedef void(*HostSuspendHook_t)(void *context, HostSuspendCallID callID, const HostSuspendCallArgument *args, HostSuspendCallArgument *returnValue); + + void InstallHostSuspendHook(HostSuspendHook_t hook, void *context); + void SuspendApplication(HostSuspendCallID callID, const HostSuspendCallArgument *args, HostSuspendCallArgument *returnValue); +} + +#endif diff --git a/PortabilityLayer/HostSystemServices.cpp b/PortabilityLayer/HostSystemServices.cpp new file mode 100644 index 0000000..3d3f72f --- /dev/null +++ b/PortabilityLayer/HostSystemServices.cpp @@ -0,0 +1,16 @@ +#include "HostSystemServices.h" + +namespace PortabilityLayer +{ + void HostSystemServices::SetInstance(HostSystemServices *instance) + { + ms_instance = instance; + } + + HostSystemServices *HostSystemServices::GetInstance() + { + return ms_instance; + } + + HostSystemServices *HostSystemServices::ms_instance; +} diff --git a/PortabilityLayer/HostSystemServices.h b/PortabilityLayer/HostSystemServices.h new file mode 100644 index 0000000..a1287a1 --- /dev/null +++ b/PortabilityLayer/HostSystemServices.h @@ -0,0 +1,22 @@ +#pragma once +#ifndef __PL_HOST_SYSTEM_SERVICES_H__ +#define __PL_HOST_SYSTEM_SERVICES_H__ + +#include + +namespace PortabilityLayer +{ + class HostSystemServices + { + public: + virtual uint32_t GetTime() const = 0; + + static void SetInstance(HostSystemServices *instance); + static HostSystemServices *GetInstance(); + + private: + static HostSystemServices *ms_instance; + }; +} + +#endif diff --git a/PortabilityLayer/IOStream.h b/PortabilityLayer/IOStream.h new file mode 100644 index 0000000..7167373 --- /dev/null +++ b/PortabilityLayer/IOStream.h @@ -0,0 +1,31 @@ +#pragma once + +#ifndef __PL_IOTREAM_H__ +#define __PL_IOTREAM_H__ + +#include "DataTypes.h" + +namespace PortabilityLayer +{ + typedef int64_t FilePos_t; + typedef uint64_t UFilePos_t; + + class IOStream + { + public: + virtual size_t Read(void *bytesOut, size_t size) = 0; + virtual size_t Write(const void *bytes, size_t size) = 0; + virtual bool IsSeekable() const = 0; + virtual bool IsReadOnly() const = 0; + virtual bool IsWriteOnly() const = 0; + virtual bool SeekStart(UFilePos_t loc) = 0; + virtual bool SeekCurrent(FilePos_t loc) = 0; + virtual bool SeekEnd(UFilePos_t loc) = 0; + virtual bool Truncate(UFilePos_t loc) = 0; + virtual UFilePos_t Size() const = 0; + virtual UFilePos_t Tell() const = 0; + virtual void Close() = 0; + }; +} + +#endif diff --git a/PortabilityLayer/MMBlock.cpp b/PortabilityLayer/MMBlock.cpp new file mode 100644 index 0000000..7c34c43 --- /dev/null +++ b/PortabilityLayer/MMBlock.cpp @@ -0,0 +1,12 @@ +#include "MMBlock.h" + +namespace PortabilityLayer +{ + size_t MMBlock::AlignedSize() + { + const size_t paddedSize = sizeof(MMBlock) + PL_SYSTEM_MEMORY_ALIGNMENT - 1; + const size_t paddedSizeTruncated = paddedSize - (paddedSize % PL_SYSTEM_MEMORY_ALIGNMENT); + + return paddedSizeTruncated; + } +} diff --git a/PortabilityLayer/MMBlock.h b/PortabilityLayer/MMBlock.h new file mode 100644 index 0000000..844094a --- /dev/null +++ b/PortabilityLayer/MMBlock.h @@ -0,0 +1,20 @@ +#pragma once +#ifndef __PL_MM_BLOCK_H__ +#define __PL_MM_BLOCK_H__ + +#include + +#include "CoreDefs.h" +#include "SmallestInt.h" + +namespace PortabilityLayer +{ + struct MMBlock + { + SmallestUInt::ValueType_t m_offsetFromAllocLocation; + + static size_t AlignedSize(); + }; +} + +#endif diff --git a/PortabilityLayer/MMHandleBlock.cpp b/PortabilityLayer/MMHandleBlock.cpp new file mode 100644 index 0000000..651ec99 --- /dev/null +++ b/PortabilityLayer/MMHandleBlock.cpp @@ -0,0 +1,17 @@ +#include "MMHandleBlock.h" + +namespace PortabilityLayer +{ + MMHandleBlock::MMHandleBlock(void *contents, size_t size) + : m_contents(contents) + , m_rmSelfRef(nullptr) + , m_size(size) + { + } + + void **MMHandleBlock::AsHandle() + { + return &m_contents; + } + +} diff --git a/PortabilityLayer/MMHandleBlock.h b/PortabilityLayer/MMHandleBlock.h new file mode 100644 index 0000000..bff3801 --- /dev/null +++ b/PortabilityLayer/MMHandleBlock.h @@ -0,0 +1,29 @@ +#pragma once +#ifndef __PL_MM_HANDLE_BLOCK_H__ +#define __PL_MM_HANDLE_BLOCK_H__ + +#include + +#include "CoreDefs.h" + +namespace PortabilityLayer +{ + struct ResourceCompiledRef; + + struct MMHandleBlock + { + explicit MMHandleBlock(void *contents, size_t size); + + void **AsHandle(); + + void *m_contents; // This must be the first field + ResourceCompiledRef *m_rmSelfRef; + + size_t m_size; + + private: + MMHandleBlock() PL_DELETED; + }; +} + +#endif diff --git a/PortabilityLayer/MacBinary2.cpp b/PortabilityLayer/MacBinary2.cpp new file mode 100644 index 0000000..15efa66 --- /dev/null +++ b/PortabilityLayer/MacBinary2.cpp @@ -0,0 +1,185 @@ +#include "MacBinary2.h" + +#include "BytePack.h" +#include "ByteUnpack.h" +#include "DataTypes.h" +#include "IOStream.h" +#include "MacFileMem.h" +#include "XModemCRC.h" + +// See: https://files.stairways.com/other/macbinaryii-standard-info.txt + +namespace +{ + namespace MB2FileOffsets + { + const unsigned int Version = 0; + const unsigned int FileNameLength = 1; + const unsigned int FileName = 2; + const unsigned int FileType = 65; + const unsigned int FileCreator = 69; + const unsigned int FinderFlagsHigh = 73; + const unsigned int YPos = 75; + const unsigned int XPos = 77; + const unsigned int Protected = 81; + const unsigned int DataForkSize = 83; + const unsigned int ResourceForkSize = 87; + const unsigned int CreationDate = 91; + const unsigned int ModifiedDate = 95; + const unsigned int CommentLength = 99; + const unsigned int FinderFlagsLow = 101; + const unsigned int DecompressedSize = 116; + const unsigned int SecondaryHeaderLength = 120; + + const unsigned int WriterVersion = 122; + const unsigned int MinVersion = 123; + const unsigned int Checksum = 124; + const unsigned int ContentStart = 128; + }; +} + +namespace PortabilityLayer +{ + void MacBinary2::WriteBin(const MacFileMem *file, IOStream *stream) + { + const MacFileInfo &fileInfo = file->FileInfo(); + + uint8_t mb2Header[128]; + + memset(mb2Header, 0, sizeof(mb2Header)); + + mb2Header[MB2FileOffsets::Version] = 0; + + size_t fileNameLength = fileInfo.m_fileName.Length(); + if (fileNameLength == 0) + { + mb2Header[MB2FileOffsets::FileNameLength] = 1; + mb2Header[MB2FileOffsets::FileName] = '?'; + } + else + { + if (fileNameLength > 63) + fileNameLength = 63; + + mb2Header[MB2FileOffsets::FileNameLength] = static_cast(fileNameLength); + memcpy(mb2Header + MB2FileOffsets::FileName, &fileInfo.m_fileName[0], fileNameLength); + } + + memcpy(mb2Header + MB2FileOffsets::FileType, fileInfo.m_properties.m_fileType, 4); + memcpy(mb2Header + MB2FileOffsets::FileCreator, fileInfo.m_properties.m_fileCreator, 4); + + mb2Header[MB2FileOffsets::FinderFlagsHigh] = static_cast((fileInfo.m_properties.m_finderFlags >> 8) & 0xff); + + BytePack::BigInt16(mb2Header + MB2FileOffsets::YPos, fileInfo.m_properties.m_yPos); + BytePack::BigInt16(mb2Header + MB2FileOffsets::XPos, fileInfo.m_properties.m_xPos); + mb2Header[MB2FileOffsets::Protected] = fileInfo.m_properties.m_protected; + BytePack::BigUInt32(mb2Header + MB2FileOffsets::DataForkSize, fileInfo.m_dataForkSize); + BytePack::BigUInt32(mb2Header + MB2FileOffsets::ResourceForkSize, fileInfo.m_resourceForkSize); + BytePack::BigUInt32(mb2Header + MB2FileOffsets::CreationDate, fileInfo.m_properties.m_creationDate); + BytePack::BigUInt32(mb2Header + MB2FileOffsets::ModifiedDate, fileInfo.m_properties.m_modifiedDate); + + BytePack::BigUInt16(mb2Header + MB2FileOffsets::CommentLength, fileInfo.m_commentSize); + mb2Header[MB2FileOffsets::FinderFlagsLow] = static_cast(fileInfo.m_properties.m_finderFlags & 0xff); + // DecompressedSize is unused + // SecondaryHeaderLength is zero + + mb2Header[MB2FileOffsets::WriterVersion] = 129; + mb2Header[MB2FileOffsets::MinVersion] = 129; + + BytePack::BigUInt16(mb2Header + MB2FileOffsets::Checksum, XModemCRC(mb2Header, 124, 0)); + + stream->Write(mb2Header, 128); + + uint8_t *padding = mb2Header; + memset(padding, 0, 128); + + const size_t dataForkPadding = 127 - ((fileInfo.m_dataForkSize + 127) % 128); + const size_t resourceForkPadding = 127 - ((fileInfo.m_resourceForkSize + 127) % 128); + + stream->Write(file->DataFork(), fileInfo.m_dataForkSize); + stream->Write(padding, dataForkPadding); + stream->Write(file->ResourceFork(), fileInfo.m_resourceForkSize); + stream->Write(padding, resourceForkPadding); + } + + MacFileMem *MacBinary2::ReadBin(IOStream *stream) + { + MacFileInfo fileInfo; + + uint8_t mb2Header[128]; + + if (stream->Read(mb2Header, 128) != 128) + return nullptr; + + if (mb2Header[MB2FileOffsets::Version] != 0) + return nullptr; + + const uint8_t fileNameLength = mb2Header[MB2FileOffsets::FileNameLength]; + if (fileNameLength < 1 || fileNameLength > 63) + return nullptr; + + fileInfo.m_fileName.Set(fileNameLength, reinterpret_cast(mb2Header + MB2FileOffsets::FileName)); + + memcpy(fileInfo.m_properties.m_fileType, mb2Header + MB2FileOffsets::FileType, 4); + memcpy(fileInfo.m_properties.m_fileCreator, mb2Header + MB2FileOffsets::FileCreator, 4); + + fileInfo.m_properties.m_finderFlags = mb2Header[MB2FileOffsets::FinderFlagsHigh] << 8; + + fileInfo.m_properties.m_yPos = ByteUnpack::BigInt16(mb2Header + MB2FileOffsets::YPos); + fileInfo.m_properties.m_xPos = ByteUnpack::BigInt16(mb2Header + MB2FileOffsets::XPos); + fileInfo.m_properties.m_protected = mb2Header[MB2FileOffsets::Protected]; + fileInfo.m_dataForkSize = ByteUnpack::BigUInt32(mb2Header + MB2FileOffsets::DataForkSize); + fileInfo.m_resourceForkSize = ByteUnpack::BigUInt32(mb2Header + MB2FileOffsets::ResourceForkSize); + fileInfo.m_properties.m_creationDate = ByteUnpack::BigUInt32(mb2Header + MB2FileOffsets::CreationDate); + fileInfo.m_properties.m_modifiedDate = ByteUnpack::BigUInt32(mb2Header + MB2FileOffsets::ModifiedDate); + + fileInfo.m_commentSize = ByteUnpack::BigUInt16(mb2Header + MB2FileOffsets::CommentLength); + fileInfo.m_properties.m_finderFlags |= mb2Header[MB2FileOffsets::FinderFlagsLow]; + + if (ByteUnpack::BigInt16(mb2Header + MB2FileOffsets::SecondaryHeaderLength) != 0) + return nullptr; + + uint16_t crc = ByteUnpack::BigUInt16(mb2Header + MB2FileOffsets::Checksum); + + uint16_t expectedCRC = XModemCRC(mb2Header, 124, 0); + + if (fileInfo.m_dataForkSize > SIZE_MAX) + return nullptr; + + if (fileInfo.m_resourceForkSize > SIZE_MAX) + return nullptr; + + uint8_t *dataBuffer = nullptr; + uint8_t *rsrcBuffer = nullptr; + + if (fileInfo.m_dataForkSize != 0) + dataBuffer = new uint8_t[fileInfo.m_dataForkSize]; + + if (fileInfo.m_resourceForkSize != 0) + rsrcBuffer = new uint8_t[fileInfo.m_resourceForkSize]; + + ScopedArray dataContents = dataBuffer; + ScopedArray rsrcContents = rsrcBuffer; + + uint8_t *padding = mb2Header; + + const size_t dataForkPadding = 127 - ((fileInfo.m_dataForkSize + 127) % 128); + const size_t resourceForkPadding = 127 - ((fileInfo.m_resourceForkSize + 127) % 128); + + if (stream->Read(dataBuffer, fileInfo.m_dataForkSize) != fileInfo.m_dataForkSize) + return nullptr; + + if (stream->Read(padding, dataForkPadding) != dataForkPadding) + return nullptr; + + if (stream->Read(rsrcBuffer, fileInfo.m_resourceForkSize) != fileInfo.m_resourceForkSize) + return nullptr; + + if (stream->Read(padding, resourceForkPadding) != resourceForkPadding) + return nullptr; + + // Ignore comment for now + return new MacFileMem(dataBuffer, rsrcBuffer, nullptr, fileInfo); + } +} + diff --git a/PortabilityLayer/MacBinary2.h b/PortabilityLayer/MacBinary2.h new file mode 100644 index 0000000..0f6b198 --- /dev/null +++ b/PortabilityLayer/MacBinary2.h @@ -0,0 +1,18 @@ +#pragma once + +#ifndef __PL_MACBINARY2_H__ +#define __PL_MACBINARY2_H__ + +namespace PortabilityLayer +{ + class IOStream; + class MacFileMem; + + namespace MacBinary2 + { + void WriteBin(const MacFileMem *file, IOStream *stream); + MacFileMem *ReadBin(IOStream *stream); + }; +} + +#endif diff --git a/PortabilityLayer/MacFileInfo.cpp b/PortabilityLayer/MacFileInfo.cpp new file mode 100644 index 0000000..0fc700a --- /dev/null +++ b/PortabilityLayer/MacFileInfo.cpp @@ -0,0 +1,63 @@ +#include "MacFileInfo.h" +#include "PLBigEndian.h" + +#include + +namespace PortabilityLayer +{ + + static const unsigned int kOffsetFileType = 0; + static const unsigned int kOffsetFileCreator = 4; + static const unsigned int kOffsetXPos = 8; + static const unsigned int kOffsetYPos = 10; + static const unsigned int kOffsetFinderFlags = 12; + static const unsigned int kProtected = 14; + static const unsigned int kCreationDate = 15; + static const unsigned int kModifiedDate = 19; + + static const unsigned int kSize = 23; + + uint8_t m_data[kSize]; + + void MacFilePropertiesSerialized::Deserialize(MacFileProperties &props) const + { + memcpy(props.m_fileType, m_data + kOffsetFileType, 4); + memcpy(props.m_fileCreator, m_data + kOffsetFileCreator, 4); + memcpy(&props.m_xPos, m_data + kOffsetXPos, 2); + memcpy(&props.m_yPos, m_data + kOffsetYPos, 2); + memcpy(&props.m_finderFlags, m_data + kOffsetFinderFlags, 2); + memcpy(&props.m_protected, m_data + kProtected, 1); + memcpy(&props.m_creationDate, m_data + kCreationDate, 4); + memcpy(&props.m_modifiedDate, m_data + kModifiedDate, 4); + + PortabilityLayer::ByteSwap::BigInt16(props.m_xPos); + PortabilityLayer::ByteSwap::BigInt16(props.m_yPos); + PortabilityLayer::ByteSwap::BigUInt16(props.m_finderFlags); + PortabilityLayer::ByteSwap::BigUInt32(props.m_creationDate); + PortabilityLayer::ByteSwap::BigUInt32(props.m_modifiedDate); + } + + void MacFilePropertiesSerialized::Serialize(const MacFileProperties &props) + { + int16_t xPos = props.m_xPos; + int16_t yPos = props.m_yPos; + uint16_t finderFlags = props.m_finderFlags; + uint32_t creationDate = props.m_creationDate; + uint32_t modifiedDate = props.m_modifiedDate; + + PortabilityLayer::ByteSwap::BigInt16(xPos); + PortabilityLayer::ByteSwap::BigInt16(yPos); + PortabilityLayer::ByteSwap::BigUInt16(finderFlags); + PortabilityLayer::ByteSwap::BigUInt32(creationDate); + PortabilityLayer::ByteSwap::BigUInt32(modifiedDate); + + memcpy(m_data + kOffsetFileType, props.m_fileType, 4); + memcpy(m_data + kOffsetFileCreator, props.m_fileCreator, 4); + memcpy(m_data + kOffsetXPos, &xPos, 2); + memcpy(m_data + kOffsetYPos, &yPos, 2); + memcpy(m_data + kOffsetFinderFlags, &finderFlags, 2); + memcpy(m_data + kProtected, &props.m_protected, 1); + memcpy(m_data + kCreationDate, &creationDate, 4); + memcpy(m_data + kModifiedDate, &modifiedDate, 4); + } +} diff --git a/PortabilityLayer/MacFileInfo.h b/PortabilityLayer/MacFileInfo.h new file mode 100644 index 0000000..a4d7557 --- /dev/null +++ b/PortabilityLayer/MacFileInfo.h @@ -0,0 +1,89 @@ +#pragma once + +#include "DataTypes.h" +#include "PascalStr.h" + +namespace PortabilityLayer +{ + enum FinderFileFlags + { + FINDER_FILE_FLAG_LOCKED = (1 << 15), + FINDER_FILE_FLAG_INVISIBLE = (1 << 14), + FINDER_FILE_FLAG_BUNDLE = (1 << 13), + FINDER_FILE_FLAG_SYSTEM = (1 << 12), + FINDER_FILE_FLAG_COPY_PROTECTED = (1 << 11), + FINDER_FILE_FLAG_BUSY = (1 << 10), + FINDER_FILE_FLAG_CHANGED = (1 << 9), + FINDER_FILE_FLAG_INITED = (1 << 8), + }; + + struct MacFileProperties + { + MacFileProperties(); + + char m_fileType[4]; + char m_fileCreator[4]; + int16_t m_xPos; + int16_t m_yPos; + uint16_t m_finderFlags; + uint8_t m_protected; + uint32_t m_creationDate; + uint32_t m_modifiedDate; + + void Serialize(void *buffer); + void Deserialize(const void *buffer); + }; + + struct MacFilePropertiesSerialized + { + static const unsigned int kOffsetFileType = 0; + static const unsigned int kOffsetFileCreator = 4; + static const unsigned int kOffsetXPos = 8; + static const unsigned int kOffsetYPos = 10; + static const unsigned int kOffsetFinderFlags = 12; + static const unsigned int kProtected = 14; + static const unsigned int kCreationDate = 15; + static const unsigned int kModifiedDate = 19; + + static const unsigned int kSize = 23; + + uint8_t m_data[kSize]; + + void Deserialize(MacFileProperties &props) const; + void Serialize(const MacFileProperties &props); + }; + + struct MacFileInfo + { + MacFileInfo(); + + PascalStr<64> m_fileName; + uint16_t m_commentSize; + uint32_t m_dataForkSize; + uint32_t m_resourceForkSize; + + MacFileProperties m_properties; + }; +} + +namespace PortabilityLayer +{ + inline MacFileProperties::MacFileProperties() + : m_xPos(0) + , m_yPos(0) + , m_finderFlags(0) + , m_protected(0) + , m_creationDate(0) + , m_modifiedDate(0) + { + m_fileType[0] = m_fileType[1] = m_fileType[2] = m_fileType[3] = '\0'; + m_fileCreator[0] = m_fileCreator[1] = m_fileCreator[2] = m_fileCreator[3] = '\0'; + } + + inline MacFileInfo::MacFileInfo() + : m_dataForkSize(0) + , m_resourceForkSize(0) + , m_commentSize(0) + { + } +} diff --git a/PortabilityLayer/MacFileMem.cpp b/PortabilityLayer/MacFileMem.cpp new file mode 100644 index 0000000..7784ac6 --- /dev/null +++ b/PortabilityLayer/MacFileMem.cpp @@ -0,0 +1,26 @@ +#include "MacFileMem.h" + +namespace PortabilityLayer +{ + MacFileMem::MacFileMem(const uint8_t *dataFork, const uint8_t *resourceFork, const char* comment, const MacFileInfo &fileInfo) + : m_info(fileInfo) + { + uint8_t *buffer = new uint8_t[fileInfo.m_dataForkSize + fileInfo.m_resourceForkSize + fileInfo.m_commentSize + 1]; + m_data.Set(buffer); + + memcpy(buffer, dataFork, fileInfo.m_dataForkSize); + buffer += fileInfo.m_dataForkSize; + + memcpy(buffer, resourceFork, fileInfo.m_resourceForkSize); + buffer += fileInfo.m_resourceForkSize; + + memcpy(buffer, comment, fileInfo.m_commentSize); + buffer += fileInfo.m_commentSize; + + *buffer = 0; + } + + MacFileMem::~MacFileMem() + { + } +} diff --git a/PortabilityLayer/MacFileMem.h b/PortabilityLayer/MacFileMem.h new file mode 100644 index 0000000..d7f2f3d --- /dev/null +++ b/PortabilityLayer/MacFileMem.h @@ -0,0 +1,52 @@ +#pragma once + +#ifndef __PL_MACFILEMEM_H__ +#define __PL_MACFILEMEM_H__ + +#include "DataTypes.h" +#include "MacFileInfo.h" +#include "ScopedArray.h" + +namespace PortabilityLayer +{ + class MacFileMem + { + public: + MacFileMem(const uint8_t *dataFork, const uint8_t *resourceFork, const char* comment, const MacFileInfo &fileInfo); + ~MacFileMem(); + + const MacFileInfo &FileInfo() const; + const uint8_t *DataFork() const; + const uint8_t *ResourceFork() const; + const char *Comment() const; + + private: + ScopedArray m_data; + MacFileInfo m_info; + }; +} + +namespace PortabilityLayer +{ + inline const MacFileInfo &MacFileMem::FileInfo() const + { + return m_info; + } + + inline const uint8_t *MacFileMem::DataFork() const + { + return m_data; + } + + inline const uint8_t *MacFileMem::ResourceFork() const + { + return m_data + m_info.m_dataForkSize; + } + + inline const char *MacFileMem::Comment() const + { + return reinterpret_cast(m_data + m_info.m_dataForkSize + m_info.m_resourceForkSize); + } +} + +#endif diff --git a/PortabilityLayer/MacFileWriteableMem.h b/PortabilityLayer/MacFileWriteableMem.h new file mode 100644 index 0000000..c5a93e3 --- /dev/null +++ b/PortabilityLayer/MacFileWriteableMem.h @@ -0,0 +1,14 @@ +#pragma once +#ifndef __PL_MAC_FILE_WRITEABLE_MEM_H__ +#define __PL_MAC_FILE_WRITEABLE_MEM_H__ + +namespace PortabilityLayer +{ + class MacFileWriteableMem + { + public: + private: + }; +} + +#endif diff --git a/PortabilityLayer/MacRsrcHeader.h b/PortabilityLayer/MacRsrcHeader.h new file mode 100644 index 0000000..9958721 --- /dev/null +++ b/PortabilityLayer/MacRsrcHeader.h @@ -0,0 +1,21 @@ +#pragma once + +#ifndef __PL_MACRSRCHEADER_H__ +#define __PL_MACRSRCHEADER_H__ + +#include "DataTypes.h" + +namespace PortabilityLayer +{ + struct MacRsrcHeader + { + uint32_t m_resDataOffset; + uint32_t m_resMapOffset; + uint32_t m_resDataSize; + uint32_t m_resMapSize; + + void Load(const void *data); + }; +} + +#endif diff --git a/PortabilityLayer/MacRsrcMap.h b/PortabilityLayer/MacRsrcMap.h new file mode 100644 index 0000000..e7d4eb8 --- /dev/null +++ b/PortabilityLayer/MacRsrcMap.h @@ -0,0 +1,20 @@ +#pragma once + +#ifndef __PL_MACRSRCMAP_H__ +#define __PL_MACRSRCMAP_H__ + +#include "DataTypes.h" + +namespace PortabilityLayer +{ + struct MacRsrcMap + { + uint16_t m_resTypeListOffset; + uint16_t m_resNameListOffset; + uint16_t m_numTypesMinusOne; + + void Load(const void *data); + }; +} + +#endif diff --git a/PortabilityLayer/MemReaderStream.cpp b/PortabilityLayer/MemReaderStream.cpp new file mode 100644 index 0000000..651fb71 --- /dev/null +++ b/PortabilityLayer/MemReaderStream.cpp @@ -0,0 +1,110 @@ +#include "MemReaderStream.h" + +#include + +namespace PortabilityLayer +{ + MemReaderStream::MemReaderStream(const void *memStream, size_t size) + : m_bytes(static_cast(memStream)) + , m_size(size) + , m_loc(0) + { + } + + size_t MemReaderStream::Read(void *bytesOut, size_t size) + { + size_t available = m_size - m_loc; + if (size > available) + size = available; + + memcpy(bytesOut, m_bytes + m_loc, size); + m_loc += size; + + return size; + } + + size_t MemReaderStream::Write(const void *bytes, size_t size) + { + return 0; + } + + bool IsSeekable() + { + return true; + } + + bool MemReaderStream::IsSeekable() const + { + return true; + } + + bool MemReaderStream::IsReadOnly() const + { + return true; + } + + bool MemReaderStream::IsWriteOnly() const + { + return false; + } + + bool MemReaderStream::SeekStart(UFilePos_t loc) + { + if (loc > m_size) + m_loc = m_size; + else + m_loc = static_cast(loc); + + return true; + } + + bool MemReaderStream::SeekCurrent(FilePos_t loc) + { + if (loc < 0) + { + if (static_cast(m_loc) + loc < 0) + m_loc = 0; + else + m_loc = static_cast(static_cast(m_loc) + loc); + } + else + { + const size_t available = m_size - m_loc; + if (static_cast(loc) > available) + m_loc = m_size; + else + m_loc = static_cast(static_cast(m_loc) + loc); + } + + return true; + } + + bool MemReaderStream::SeekEnd(UFilePos_t loc) + { + if (m_size < loc) + m_loc = 0; + else + m_loc = m_size - static_cast(loc); + + return true; + } + + bool MemReaderStream::Truncate(UFilePos_t loc) + { + return false; + } + + UFilePos_t MemReaderStream::Size() const + { + return m_size; + } + + UFilePos_t MemReaderStream::Tell() const + { + return static_cast(m_loc); + } + + void MemReaderStream::Close() + { + } +} diff --git a/PortabilityLayer/MemReaderStream.h b/PortabilityLayer/MemReaderStream.h new file mode 100644 index 0000000..4e61b76 --- /dev/null +++ b/PortabilityLayer/MemReaderStream.h @@ -0,0 +1,37 @@ +#pragma once +#ifndef __PL_MEM_READER_STREAM_H__ +#define __PL_MEM_READER_STREAM_H__ + +#include "CoreDefs.h" +#include "IOStream.h" + +namespace PortabilityLayer +{ + class MemReaderStream final : public IOStream + { + public: + MemReaderStream(const void *memStream, size_t size); + + size_t Read(void *bytesOut, size_t size) override; + size_t Write(const void *bytes, size_t size) override; + bool IsSeekable() const override; + bool IsReadOnly() const override; + bool IsWriteOnly() const override; + bool SeekStart(UFilePos_t loc) override; + bool SeekCurrent(FilePos_t loc) override; + bool SeekEnd(UFilePos_t loc) override; + bool Truncate(UFilePos_t loc) override; + UFilePos_t Size() const override; + UFilePos_t Tell() const override; + void Close() override; + + private: + MemReaderStream() PL_DELETED; + + const uint8_t *m_bytes; + size_t m_size; + size_t m_loc; + }; +} + +#endif diff --git a/PortabilityLayer/MemoryManager.cpp b/PortabilityLayer/MemoryManager.cpp new file mode 100644 index 0000000..8d11e16 --- /dev/null +++ b/PortabilityLayer/MemoryManager.cpp @@ -0,0 +1,106 @@ +#include "MemoryManager.h" +#include "MMBlock.h" +#include "MMHandleBlock.h" +#include "ResourceCompiledRef.h" + +#include +#include + +namespace PortabilityLayer +{ + class MemoryManagerImpl final : public MemoryManager + { + public: + void Init() override; + void Shutdown() override; + + void *Alloc(size_t size) override; + void Release(void *buf) override; + + MMHandleBlock *AllocHandle(size_t size) override; + void ReleaseHandle(MMHandleBlock *hdl) override; + + static MemoryManagerImpl *GetInstance(); + + private: + static MemoryManagerImpl ms_instance; + }; + + void MemoryManagerImpl::Init() + { + } + + void MemoryManagerImpl::Shutdown() + { + } + + void *MemoryManagerImpl::Alloc(size_t size) + { + if (size == 0) + return nullptr; + + const size_t mmBlockSizeWithMaxPadding = MMBlock::AlignedSize() + PL_SYSTEM_MEMORY_ALIGNMENT - 1; + if (SIZE_MAX - size < mmBlockSizeWithMaxPadding) + return nullptr; + + uint8_t *buffer = static_cast(malloc(size + mmBlockSizeWithMaxPadding)); + if (!buffer) + return nullptr; + + const intptr_t offsetFromAlignPoint = reinterpret_cast(buffer) & static_cast(PL_SYSTEM_MEMORY_ALIGNMENT - 1); + intptr_t alignPadding = 0; + if (offsetFromAlignPoint != 0) + alignPadding = static_cast(PL_SYSTEM_MEMORY_ALIGNMENT) - offsetFromAlignPoint; + + MMBlock *mmBlock = reinterpret_cast(buffer + alignPadding); + mmBlock->m_offsetFromAllocLocation = static_cast::ValueType_t>(alignPadding); + + return buffer + alignPadding + MMBlock::AlignedSize(); + } + + void MemoryManagerImpl::Release(void *buf) + { + if (!buf) + return; + + const size_t mmBlockSize = MMBlock::AlignedSize(); + + uint8_t *bytes = static_cast(buf); + const MMBlock *mmBlock = reinterpret_cast(bytes - MMBlock::AlignedSize()); + + free(bytes - MMBlock::AlignedSize() - mmBlock->m_offsetFromAllocLocation); + } + + MMHandleBlock *MemoryManagerImpl::AllocHandle(size_t size) + { + void *contents = Alloc(size); + MMHandleBlock *handleBlock = static_cast(Alloc(sizeof(MMHandleBlock))); + + return new (handleBlock) MMHandleBlock(contents, size); + } + + void MemoryManagerImpl::ReleaseHandle(MMHandleBlock *hdl) + { + if (!hdl) + return; + + if (hdl->m_rmSelfRef != nullptr) + hdl->m_rmSelfRef->m_handle = nullptr; + + hdl->~MMHandleBlock(); + + Release(hdl); + } + + MemoryManagerImpl *MemoryManagerImpl::GetInstance() + { + return &ms_instance; + } + + MemoryManagerImpl MemoryManagerImpl::ms_instance; + + MemoryManager *MemoryManager::GetInstance() + { + return MemoryManagerImpl::GetInstance(); + } +} diff --git a/PortabilityLayer/MemoryManager.h b/PortabilityLayer/MemoryManager.h new file mode 100644 index 0000000..7a9de31 --- /dev/null +++ b/PortabilityLayer/MemoryManager.h @@ -0,0 +1,51 @@ +#pragma once +#ifndef __PL_MEMORY_MANAGER_H__ +#define __PL_MEMORY_MANAGER_H__ + +#include + +namespace PortabilityLayer +{ + struct MMHandleBlock; + + class MemoryManager + { + public: + virtual void Init() = 0; + virtual void Shutdown() = 0; + + virtual void *Alloc(size_t size) = 0; + virtual void Release(void *buf) = 0; + + virtual MMHandleBlock *AllocHandle(size_t size) = 0; + virtual void ReleaseHandle(MMHandleBlock *hdl) = 0; + + template + T **NewHandle(); + + static MemoryManager *GetInstance(); + }; +} + +#include +#include "CoreDefs.h" +#include "MMHandleBlock.h" + +namespace PortabilityLayer +{ + template + T **MemoryManager::NewHandle() + { + MMHandleBlock *hdl = this->AllocHandle(sizeof(T)); + if (!hdl) + return nullptr; + + T **objectHdl = reinterpret_cast(hdl); + T *objectPtr = *objectHdl; + new (objectPtr) T(); + + return objectHdl; + } +} + +#endif diff --git a/PortabilityLayer/PLAliases.cpp b/PortabilityLayer/PLAliases.cpp new file mode 100644 index 0000000..2133817 --- /dev/null +++ b/PortabilityLayer/PLAliases.cpp @@ -0,0 +1,7 @@ +#include "PLAliases.h" + +OSErr ResolveAliasFile(FSSpecPtr fsSpec, Boolean recursive, Boolean *outIsFolder, Boolean *outWasAliased) +{ + PL_NotYetImplemented(); + return noErr; +} diff --git a/PortabilityLayer/PLAliases.h b/PortabilityLayer/PLAliases.h new file mode 100644 index 0000000..ee165cc --- /dev/null +++ b/PortabilityLayer/PLAliases.h @@ -0,0 +1,9 @@ +#pragma once +#ifndef __PL_ALIASES_H__ +#define __PL_ALIASES_H__ + +#include "PLCore.h" + +OSErr ResolveAliasFile(FSSpecPtr fsSpec, Boolean recursive, Boolean *outIsFolder, Boolean *outWasAliased); + +#endif diff --git a/PortabilityLayer/PLAppleEvents.cpp b/PortabilityLayer/PLAppleEvents.cpp new file mode 100644 index 0000000..41d6633 --- /dev/null +++ b/PortabilityLayer/PLAppleEvents.cpp @@ -0,0 +1,49 @@ +#include "PLAppleEvents.h" +#include "AEManager.h" + +OSErr AEGetParamDesc(const AppleEvent *evt, AEKeyword keyword, DescType desiredType, AEDescList *descList) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr AEDisposeDesc(AEDescList *descList) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr AECountItems(AEDescList *descList, long *count) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr AEGetNthPtr(AEDescList *descList, long index, DescType desiredType, AEKeyword *keyword, DescType *type, void *data, Size maxSize, Size *actualSize) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr AEGetAttributePtr(const AppleEvent *evt, AEKeyword keyword, DescType desiredType, DescType *type, void *data, Size maxSize, Size *actualSize) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr AEInstallEventHandler(AEEventClass eventClass, AEEventID eventID, AEEventHandlerUPP handler, UInt32 ref, bool isSysHandler) +{ + PortabilityLayer::AEManager::GetInstance()->InstallEventHandler(eventClass, eventID, handler, ref, isSysHandler); + return noErr; +} + +OSErr AESetInteractionAllowed(AEInteractAllowed level) +{ + PortabilityLayer::AEManager::GetInstance()->SetInteractAllowed(level); + return noErr; +} + +AEEventHandlerUPP NewAEEventHandlerProc(AEEventHandler handler) +{ + return handler; +} diff --git a/PortabilityLayer/PLAppleEvents.h b/PortabilityLayer/PLAppleEvents.h new file mode 100644 index 0000000..7ca1588 --- /dev/null +++ b/PortabilityLayer/PLAppleEvents.h @@ -0,0 +1,32 @@ +#pragma once +#ifndef __PL_APPLEEVENTS_H__ +#define __PL_APPLEEVENTS_H__ + +#include "PLCore.h" +#include "PLAppleEventsCommonTypes.h" + +struct AppleEvent +{ +}; + +struct AEDescList +{ +}; + +struct AEDesc +{ +}; + +typedef AEEventHandler AEEventHandlerUPP; + +OSErr AEGetParamDesc(const AppleEvent *evt, AEKeyword keyword, DescType desiredType, AEDescList *descList); +OSErr AEDisposeDesc(AEDescList *descList); +OSErr AECountItems(AEDescList *descList, long *count); +OSErr AEGetNthPtr(AEDescList *descList, long index, DescType desiredType, AEKeyword *keyword, DescType *type, void *data, Size maxSize, Size *actualSize); +OSErr AEGetAttributePtr(const AppleEvent *evt, AEKeyword keyword, DescType desiredType, DescType *type, void *data, Size maxSize, Size *actualSize); +OSErr AEInstallEventHandler(AEEventClass eventClass, AEEventID eventID, AEEventHandlerUPP handler, UInt32 ref, bool isSysHandler); +OSErr AESetInteractionAllowed(AEInteractAllowed level); + +AEEventHandlerUPP NewAEEventHandlerProc(AEEventHandler handler); + +#endif diff --git a/PortabilityLayer/PLAppleEventsCommonTypes.h b/PortabilityLayer/PLAppleEventsCommonTypes.h new file mode 100644 index 0000000..30b6a38 --- /dev/null +++ b/PortabilityLayer/PLAppleEventsCommonTypes.h @@ -0,0 +1,50 @@ +#pragma once +#ifndef __PL_APPLE_EVENTS_COMMON_TYPES_H__ +#define __PL_APPLE_EVENTS_COMMON_TYPES_H__ + +#include + +struct AppleEvent; + +enum AEError +{ + errAEEventNotHandled = 1, + errAEDescNotFound, + errAEParamMissed, +}; + +enum AEKeyword +{ + keyDirectObject, + keyMissedKeywordAttr, +}; + +enum DescType +{ + typeAEList, + typeFSS, + typeWildCard, +}; + +enum AEEventID +{ + kAEOpenApplication, + kAEOpenDocuments, + kAEPrintDocuments, + kAEQuitApplication +}; + +enum AEEventClass +{ + kCoreEventClass +}; + +enum AEInteractAllowed +{ + kAEInteractUnknown, + kAEInteractWithAll +}; + +typedef int(*AEEventHandler)(const AppleEvent *theAE, AppleEvent *reply, uint32_t ref); + +#endif diff --git a/PortabilityLayer/PLApplication.cpp b/PortabilityLayer/PLApplication.cpp new file mode 100644 index 0000000..44fb61b --- /dev/null +++ b/PortabilityLayer/PLApplication.cpp @@ -0,0 +1,23 @@ +#include "PLApplication.h" +#include "PLCore.h" + +#include +#include + +namespace PortabilityLayer +{ + namespace Utils + { + void MakePStr(unsigned char *dest, size_t sz, const char *src) + { + assert(sz <= 255); + dest[0] = static_cast(sz); + memcpy(dest + 1, src, sz); + } + } +} + +void SysBeep(int duration) +{ + PL_NotYetImplemented(); +} diff --git a/PortabilityLayer/PLApplication.h b/PortabilityLayer/PLApplication.h new file mode 100644 index 0000000..8f6e3bf --- /dev/null +++ b/PortabilityLayer/PLApplication.h @@ -0,0 +1,37 @@ +#pragma once +#ifndef __PL_APPLICATION_H__ +#define __PL_APPLICATION_H__ + +#include "PLCore.h" + +namespace PortabilityLayer +{ + template + class PascalStrLiteral; +} + +namespace PortabilityLayer +{ + namespace Utils + { + void MakePStr(unsigned char *dest, size_t sz, const char *src); + } +} + +void PasStringCopy(const unsigned char *src, unsigned char *dest); + +template +void PasStringCopy(const PortabilityLayer::PascalStrLiteral &src, unsigned char *dest); + +void SysBeep(int duration); + +/////////////////////////////////////////////////////////////////////////////// +#include "PascalStrLiteral.h" + +template +inline void PasStringCopy(const PortabilityLayer::PascalStrLiteral &src, unsigned char *dest) +{ + PortabilityLayer::Utils::MakePStr(dest, TSize - 1, src.GetStr()); +} + +#endif diff --git a/PortabilityLayer/PLBigEndian.h b/PortabilityLayer/PLBigEndian.h new file mode 100644 index 0000000..a70d2bc --- /dev/null +++ b/PortabilityLayer/PLBigEndian.h @@ -0,0 +1,212 @@ +#pragma once +#ifndef __PL_BIG_ENDIAN_H__ +#define __PL_BIG_ENDIAN_H__ + +#include + +template +struct BEInteger +{ +public: + BEInteger(); + BEInteger(const BEInteger &other); + explicit BEInteger(T i); + + operator T() const; + BEInteger &operator=(T value); + + template + BEInteger &operator+=(TOther value); + + template + BEInteger &operator-=(TOther value); + + template + BEInteger &operator*=(TOther value); + + template + BEInteger &operator/=(TOther value); + + template + BEInteger &operator%=(TOther value); + + BEInteger& operator--(); + BEInteger operator--(int); + + BEInteger& operator++(); + BEInteger operator++(int); + +private: + T m_beValue; +}; + +template +struct BEInteger_SwapHelper +{ +}; + +#include "ByteSwap.h" + +template<> +struct BEInteger_SwapHelper +{ + inline static void Swap(int16_t &v) + { + PortabilityLayer::ByteSwap::BigInt16(v); + } +}; + +template<> +struct BEInteger_SwapHelper +{ + inline static void Swap(int32_t &v) + { + PortabilityLayer::ByteSwap::BigInt32(v); + } +}; + +template<> +struct BEInteger_SwapHelper +{ + inline static void Swap(uint16_t &v) + { + PortabilityLayer::ByteSwap::BigUInt16(v); + } +}; + +template<> +struct BEInteger_SwapHelper +{ + inline static void Swap(uint32_t &v) + { + PortabilityLayer::ByteSwap::BigUInt32(v); + } +}; + +// Int16 +template +inline BEInteger::BEInteger() + : m_beValue(0) +{ +} + +template +inline BEInteger::BEInteger(const BEInteger &other) + : m_beValue(other.m_beValue) +{ +} + +template +inline BEInteger::BEInteger(T i) + : m_beValue(i) +{ + BEInteger_SwapHelper::Swap(m_beValue); +} + +template +inline BEInteger::operator T() const +{ + int16_t result = m_beValue; + BEInteger_SwapHelper::Swap(result); + return result; +} + +template +inline BEInteger &BEInteger::operator=(T value) +{ + BEInteger_SwapHelper::Swap(value); + m_beValue = value; + return *this; +} + +template +template +BEInteger &BEInteger::operator+=(TOther value) +{ + BEInteger_SwapHelper::Swap(m_beValue); + m_beValue += value; + BEInteger_SwapHelper::Swap(m_beValue); + return *this; +} + +template +template +BEInteger &BEInteger::operator-=(TOther value) +{ + BEInteger_SwapHelper::Swap(m_beValue); + m_beValue -= value; + BEInteger_SwapHelper::Swap(m_beValue); + return *this; +} + +template +template +BEInteger &BEInteger::operator*=(TOther value) +{ + BEInteger_SwapHelper::Swap(m_beValue); + m_beValue *= value; + BEInteger_SwapHelper::Swap(m_beValue); + return *this; +} + +template +template +BEInteger &BEInteger::operator/=(TOther value) +{ + BEInteger_SwapHelper::Swap(m_beValue); + m_beValue /= value; + BEInteger_SwapHelper::Swap(m_beValue); + return *this; +} + +template +template +BEInteger &BEInteger::operator%=(TOther value) +{ + BEInteger_SwapHelper::Swap(m_beValue); + m_beValue %= value; + BEInteger_SwapHelper::Swap(m_beValue); + return *this; +} + +template +BEInteger& BEInteger::operator--() +{ + BEInteger_SwapHelper::Swap(m_beValue); + m_beValue--; + BEInteger_SwapHelper::Swap(m_beValue); + return *this; +} + +template +BEInteger BEInteger::operator--(int) +{ + BEInteger orig(*this); + --(*this); + return orig; +} + +template +BEInteger& BEInteger::operator++() +{ + BEInteger_SwapHelper::Swap(m_beValue); + m_beValue++; + BEInteger_SwapHelper::Swap(m_beValue); + return *this; +} + +template +BEInteger BEInteger::operator++(int) +{ + BEInteger orig(*this); + ++(*this); + return orig; +} + + +typedef BEInteger BEInt16_t; +typedef BEInteger BEInt32_t; +typedef BEInteger BEUInt16_t; +typedef BEInteger BEUInt32_t; + +#endif diff --git a/PortabilityLayer/PLControlDefinitions.cpp b/PortabilityLayer/PLControlDefinitions.cpp new file mode 100644 index 0000000..c26aef9 --- /dev/null +++ b/PortabilityLayer/PLControlDefinitions.cpp @@ -0,0 +1,72 @@ +#include "PLControlDefinitions.h" + + +int FindControl(Point point, WindowPtr window, ControlHandle *outControl) +{ + PL_NotYetImplemented(); + return 0; +} + +void SetControlValue(ControlHandle control, int value) +{ + PL_NotYetImplemented(); +} + +void SetControlMaximum(ControlHandle control, int value) +{ + PL_NotYetImplemented(); +} + +void MoveControl(ControlHandle control, int x, int y) +{ + PL_NotYetImplemented(); +} + +void SizeControl(ControlHandle control, int width, int height) +{ + PL_NotYetImplemented(); +} + +int GetControlValue(ControlHandle control) +{ + PL_NotYetImplemented(); + return 0; +} + +ControlHandle NewControl(WindowPtr window, const Rect *rect, const PLPasStr &label, Boolean visible, int value, int minValue, int maxValue, int cdef, long userdata) +{ + PL_NotYetImplemented(); + return nullptr; +} + +ControlActionUPP NewControlActionUPP(ControlActionProc proc) +{ + return proc; +} + +void DisposeControlActionUPP(ControlActionUPP upp) +{ +} + +Boolean TrackControl(ControlHandle control, Point point, ControlActionUPP proc) +{ + PL_NotYetImplemented(); + return false; +} + +long GetControlReference(ControlHandle control) +{ + PL_NotYetImplemented(); + return 0; +} + +ControlHandle GetNewControl(int resID, WindowPtr window) +{ + PL_NotYetImplemented(); + return nullptr; +} + +void HiliteControl(ControlHandle control, int unknown) +{ + PL_NotYetImplemented(); +} diff --git a/PortabilityLayer/PLControlDefinitions.h b/PortabilityLayer/PLControlDefinitions.h new file mode 100644 index 0000000..1101733 --- /dev/null +++ b/PortabilityLayer/PLControlDefinitions.h @@ -0,0 +1,49 @@ +#pragma once +#ifndef __PL_CONTROLDEFINITIONS_H__ +#define __PL_CONTROLDEFINITIONS_H__ + +#include "PLCore.h" + +struct Control +{ +}; + +typedef Control *ControlPtr; +typedef ControlPtr *ControlHandle; + +typedef void(*ControlActionProc)(ControlHandle control, short part); +typedef ControlActionProc ControlActionUPP; + +enum BuiltinCDEFs +{ + scrollBarProc = 16, +}; + +enum ControlParts +{ + kControlUpButtonPart = 1, + kControlDownButtonPart, + kControlPageUpPart, + kControlPageDownPart, + kControlIndicatorPart, + kControlButtonPart, +}; + + +int FindControl(Point point, WindowPtr window, ControlHandle *outControl); // Returns part + + +void SetControlValue(ControlHandle control, int value); +void SetControlMaximum(ControlHandle control, int value); +void MoveControl(ControlHandle control, int x, int y); +void SizeControl(ControlHandle control, int width, int height); +int GetControlValue(ControlHandle control); +ControlHandle NewControl(WindowPtr window, const Rect *rect, const PLPasStr &label, Boolean visible, int value, int minValue, int maxValue, int cdef, long userdata); +ControlActionUPP NewControlActionUPP(ControlActionProc proc); +void DisposeControlActionUPP(ControlActionUPP upp); +Boolean TrackControl(ControlHandle control, Point point, ControlActionUPP proc); +long GetControlReference(ControlHandle control); // Returns userdata +ControlHandle GetNewControl(int resID, WindowPtr window); +void HiliteControl(ControlHandle control, int unknown); + +#endif diff --git a/PortabilityLayer/PLCore.cpp b/PortabilityLayer/PLCore.cpp new file mode 100644 index 0000000..702a3fd --- /dev/null +++ b/PortabilityLayer/PLCore.cpp @@ -0,0 +1,614 @@ +#include "PLCore.h" +#include "PLApplication.h" +#include "PLPasStr.h" + +#include "AEManager.h" +#include "DisplayDeviceManager.h" +#include "FileManager.h" +#include "FilePermission.h" +#include "HostSuspendCallArgument.h" +#include "HostSuspendHook.h" +#include "HostDisplayDriver.h" +#include "HostSystemServices.h" +#include "ResourceManager.h" +#include "MemoryManager.h" +#include "MMHandleBlock.h" +#include "ResTypeID.h" +#include "RandomNumberGenerator.h" + +#include + +void InitCursor() +{ +} + +OSErr FSClose(short fsRef) +{ + PL_NotYetImplemented(); + return noErr; +} + +CursHandle GetCursor(int cursorID) +{ + return reinterpret_cast(GetResource('CURS', cursorID)); +} + +CCrsrHandle GetCCursor(int cursorID) +{ + PortabilityLayer::ResourceManager *resManager = PortabilityLayer::ResourceManager::GetInstance(); + PortabilityLayer::MMHandleBlock *ccRes = resManager->GetResource('crsr', cursorID); + + if (!ccRes) + return nullptr; + + PortabilityLayer::MMHandleBlock *copy = PortabilityLayer::MemoryManager::GetInstance()->AllocHandle(ccRes->m_size); + memcpy(copy->m_contents, ccRes->m_contents, ccRes->m_size); + + return reinterpret_cast(copy); +} + +void SetCCursor(CCrsrHandle handle) +{ + PL_NotYetImplemented_Minor(); +} + +void HideCursor() +{ + PortabilityLayer::HostDisplayDriver::GetInstance()->HideCursor(); +} + +void SetCursor(CursPtr cursor) +{ + PL_NotYetImplemented(); +} + +void DisposeCCursor(CCrsrHandle handle) +{ + PL_NotYetImplemented(); +} + +void Delay(int ticks, UInt32 *endTickCount) +{ + if (ticks > 0) + { + PortabilityLayer::HostSuspendCallArgument args[1]; + args[0].m_uint = static_cast(ticks); + + PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_Delay, args, nullptr); + } + + if (endTickCount) + *endTickCount = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetTickCount(); +} + +short Alert(int dialogID, void *unknown) +{ + PL_NotYetImplemented(); + return 0; +} + +Handle GetResource(int32_t resType, int id) +{ + PortabilityLayer::MMHandleBlock *block = PortabilityLayer::ResourceManager::GetInstance()->GetResource(PortabilityLayer::ResTypeID(resType), id); + if (!block) + return nullptr; + + return &block->m_contents; +} + +Handle GetResource(const char(&resTypeLiteral)[5], int id) +{ + PL_NotYetImplemented(); + return nullptr; +} + +short FindWindow(Point point, WindowPtr *window) +{ + PL_NotYetImplemented(); + return 0; +} + +void DragWindow(WindowPtr window, Point start, Rect *bounds) +{ + PL_NotYetImplemented(); +} + +void SendBehind(WindowPtr window, WindowPtr behind) +{ + PL_NotYetImplemented(); +} + +void BringToFront(WindowPtr window) +{ + PL_NotYetImplemented(); +} + +void ShowHide(WindowPtr window, Boolean hide) +{ + PL_NotYetImplemented(); +} + +bool TrackGoAway(WindowPtr window, Point point) +{ + PL_NotYetImplemented(); + return false; +} + +Int32 GrowWindow(WindowPtr window, Point start, Rect *size) +{ + PL_NotYetImplemented(); + return 0; +} + +bool TrackBox(WindowPtr window, Point point, int part) +{ + PL_NotYetImplemented(); + return false; +} + +void ZoomWindow(WindowPtr window, int part, bool bringToFront) +{ + PL_NotYetImplemented(); +} + +void HiliteWindow(WindowPtr window, bool highlighted) +{ + PL_NotYetImplemented(); +} + +void DisposeWindow(WindowPtr window) +{ + PL_NotYetImplemented(); +} + +void GetWindowBounds(WindowPtr window, WindowRegionType windowRegion, Rect *rect) +{ + PL_NotYetImplemented(); +} + +WindowPtr GetNewCWindow(int resID, void *storage, WindowPtr behind) +{ + PL_NotYetImplemented(); + return nullptr; +} + +WindowPtr NewCWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, Boolean hasCloseBox, long userdata) +{ + PL_NotYetImplemented(); + return nullptr; +} + +WindowPtr NewWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, Boolean hasCloseBox, long userdata) +{ + PL_NotYetImplemented(); + return nullptr; +} + +void SizeWindow(WindowPtr window, int width, int height, Boolean addToUpdateRegion) +{ + PL_NotYetImplemented(); +} + +void MoveWindow(WindowPtr window, int x, int y, Boolean moveToFront) +{ + PL_NotYetImplemented(); +} + +void ShowWindow(WindowPtr window) +{ + PL_NotYetImplemented(); +} + +void SetWTitle(WindowPtr window, const PLPasStr &title) +{ + PL_NotYetImplemented(); +} + +bool GetNextEvent(int32_t eventMask, EventRecord *event) +{ + PL_NotYetImplemented(); + return noErr; +} + +long MenuSelect(Point point) +{ + PL_NotYetImplemented(); + return noErr; +} + +long MenuKey(int charCode) +{ + PL_NotYetImplemented(); + return noErr; +} + +long TickCount() +{ + return PortabilityLayer::DisplayDeviceManager::GetInstance()->GetTickCount(); +} + +void GetKeys(KeyMap keyMap) +{ + PL_NotYetImplemented(); +} + +short LoWord(Int32 v) +{ + return ((v ^ 0x8000) & 0xffff) - 0x8000; +} + +short HiWord(Int32 v) +{ + return (((v >> 16) ^ 0x8000) & 0xffff) - 0x8000; +} + +bool BitTst(const KeyMap *keyMap, int bit) +{ + PL_NotYetImplemented(); + return noErr; +} + +void NumToString(long number, unsigned char *str) +{ + PL_NotYetImplemented(); +} + +void ParamText(const PLPasStr &title, const PLPasStr &a, const PLPasStr &b, const PLPasStr &c) +{ + PL_NotYetImplemented(); +} + + +UInt32 FreeMem() +{ + PL_NotYetImplemented_Minor(); + return 256 * 1024 * 1024; +} + +OSErr AEProcessAppleEvent(EventRecord *evt) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr FindFolder(int refNum, int posType, bool createFolder, short *volumeRef, long *dirID) +{ + switch (posType) + { + case kPreferencesFolderType: + *volumeRef = 0; + *dirID = PortabilityLayer::EVirtualDirectory_Prefs; + return noErr; + default: + return genericErr; + } +} + +void GetIndString(unsigned char *str, int stringsID, int fnameIndex) +{ + PL_NotYetImplemented(); +} + +OSErr PBDirCreate(HFileParam *fileParam, bool asynchronous) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr FSMakeFSSpec(int refNum, long dirID, const PLPasStr &fileName, FSSpec *spec) +{ + + if (fileName.Length() >= sizeof(spec->name)) + return genericErr; + + PortabilityLayer::Utils::MakePStr(spec->name, fileName.Length(), fileName.Chars()); + spec->vRefNum = refNum; + spec->parID = dirID; + + if (!PortabilityLayer::FileManager::GetInstance()->FileExists(dirID, fileName)) + return fnfErr; + + return noErr; +} + +OSErr FSpCreate(const FSSpec *spec, UInt32 creator, UInt32 fileType, ScriptCode scriptTag) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr FSpDirCreate(const FSSpec *spec, ScriptCode script, long *outDirID) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr FSpOpenDF(const FSSpec *spec, int permission, short *refNum) +{ + PortabilityLayer::EFilePermission perm = PortabilityLayer::EFilePermission_Any; + switch (permission) + { + case fsRdPerm: + perm = PortabilityLayer::EFilePermission_Read; + break; + case fsWrPerm: + case fsRdWrPerm: + perm = PortabilityLayer::EFilePermission_ReadWrite; + break; + case fsCurPerm: + perm = PortabilityLayer::EFilePermission_Any; + break; + default: + return permErr; + } + + return PortabilityLayer::FileManager::GetInstance()->OpenFileDF(spec->parID, spec->name, perm, refNum); +} + +OSErr FSWrite(short refNum, long *byteCount, const void *data) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr FSRead(short refNum, long *byteCount, void *data) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr FSpDelete(const FSSpec *spec) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr FSpGetFInfo(const FSSpec *spec, FInfo *finfo) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr SetFPos(short refNum, SetFPosWhere where, long offset) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr GetEOF(short refNum, long *byteCount) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr SetEOF(short refNum, long byteCount) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr PBGetCatInfo(CInfoPBPtr paramBlock, Boolean async) +{ + PL_NotYetImplemented(); + return noErr; +} + +short StringWidth(const PLPasStr &str) +{ + PL_NotYetImplemented(); + return 0; +} + +void GetMouse(Point *point) +{ + PL_NotYetImplemented(); +} + +Boolean Button() +{ + PL_NotYetImplemented(); + return false; +} + +Boolean StillDown() +{ + PL_NotYetImplemented(); + return false; +} + +Boolean WaitMouseUp() +{ + PL_NotYetImplemented(); + return false; +} + +void LocalToGlobal(Point *point) +{ + PL_NotYetImplemented(); +} + +void GlobalToLocal(Point *point) +{ + PL_NotYetImplemented(); +} + +short Random() +{ + // Should return with range -32767..32767 + uint32_t bits = PortabilityLayer::RandomNumberGenerator::GetInstance()->GetNextAndAdvance(); + uint16_t rWord = (bits & 0xffff); + if (rWord == 0) + { + rWord = (bits >> 16) & 0xffff; + if (rWord == 0) + return 0; // This should be extremely rare + } + + return static_cast(static_cast(rWord) - 0x8000); +} + +void GetDateTime(UInt32 *dateTime) +{ + PL_NotYetImplemented(); +} + +void GetTime(DateTimeRec *dateTime) +{ + PL_NotYetImplemented(); +} + +UInt32 GetDblTime() +{ + PL_NotYetImplemented_Minor(); + return 30; +} + +void FlushEvents(int mask, int unknown) +{ + PL_NotYetImplemented(); +} + +void ExitToShell() +{ + PL_NotYetImplemented(); +} + +void InvalWindowRect(WindowPtr window, const Rect *rect) +{ + PL_NotYetImplemented(); +} + +Handle NewHandle(Size size) +{ + PortabilityLayer::MMHandleBlock *hBlock = PortabilityLayer::MemoryManager::GetInstance()->AllocHandle(size); + if (!hBlock) + return nullptr; + + return &hBlock->m_contents; +} + +void DisposeHandle(Handle handle) +{ + PL_NotYetImplemented(); +} + +long GetHandleSize(Handle handle) +{ + PL_NotYetImplemented(); + return 0; +} + +void HNoPurge(Handle hdl) +{ +} + +void MoveHHi(Handle hdl) +{ +} + +void HLock(Handle hdl) +{ +} + +void HUnlock(Handle hdl) +{ +} + +OSErr PtrAndHand(const void *data, Handle handle, Size size) +{ + PL_NotYetImplemented(); + return noErr; +} + +void SetHandleSize(Handle hdl, Size newSize) +{ + PL_NotYetImplemented(); +} + +void *NewPtr(Size size) +{ + PL_NotYetImplemented(); + return nullptr; +} + +void *NewPtrClear(Size size) +{ + PL_NotYetImplemented(); + return nullptr; +} + +void DisposePtr(void *ptr) +{ + PL_NotYetImplemented(); +} + +Size MaxMem(Size *growBytes) +{ + PL_NotYetImplemented(); + return 0; +} + +void PurgeSpace(long *totalFree, long *contiguousFree) +{ + PL_NotYetImplemented(); +} + +void HSetState(Handle handle, char state) +{ + PL_NotYetImplemented(); +} + +char HGetState(Handle handle) +{ + PL_NotYetImplemented(); + return 0; +} + +OSErr MemError() +{ + PL_NotYetImplemented(); + return 0; +} + +void BlockMove(const void *src, void *dest, Size size) +{ + PL_NotYetImplemented(); +} + +Boolean WaitNextEvent(int eventMask, EventRecord *eventOut, long sleep, void *unknown) +{ + PL_NotYetImplemented(); + return 0; +} + +void DrawControls(WindowPtr window) +{ + PL_NotYetImplemented(); +} + +void DrawGrowIcon(WindowPtr window) +{ + PL_NotYetImplemented(); +} + +void DebugStr(const PLPasStr &str) +{ + PL_NotYetImplemented(); +} + +void PL_NotYetImplemented() +{ + assert(false); +} + +void PL_NotYetImplemented_Minor() +{ +} + +void PL_Init() +{ + PortabilityLayer::MemoryManager::GetInstance()->Init(); + PortabilityLayer::ResourceManager::GetInstance()->Init(); + PortabilityLayer::DisplayDeviceManager::GetInstance()->Init(); + PortabilityLayer::AEManager::GetInstance()->Init(); +} diff --git a/PortabilityLayer/PLCore.h b/PortabilityLayer/PLCore.h new file mode 100644 index 0000000..d15e086 --- /dev/null +++ b/PortabilityLayer/PLCore.h @@ -0,0 +1,411 @@ +#pragma once +#ifndef __PL_CORE_H__ +#define __PL_CORE_H__ + +#include "DataTypes.h" +#include "PLErrorCodes.h" + +#ifdef _MSC_VER +#pragma warning(error:4311) // Pointer truncation to int +#endif + +namespace PortabilityLayer +{ + struct MMHandleBlock; +} + +typedef uint8_t Boolean; +typedef uint8_t Byte; +typedef uint8_t UInt8; +typedef int16_t SInt16; +typedef int32_t Int32; +typedef uint32_t UInt32; +typedef int OSErr; + +typedef size_t Size; + +typedef unsigned char Str15[16]; +typedef unsigned char Str31[32]; +typedef unsigned char Str63[64]; +typedef unsigned char Str27[28]; +typedef unsigned char Str32[33]; +typedef unsigned char Str255[256]; +typedef unsigned char *StringPtr; + +class PLPasStr; + +#define PL_DEAD(n) ((void)0) + +typedef struct Point +{ + short v; + short h; +} Point; + +// FIXME: Audit +struct Rect +{ + short top; + short left; + short bottom; + short right; +}; + +struct FinderInfoBlock +{ + Int32 fdType; + Int32 fdCreator; +}; + +struct FileInfoBlock +{ + void *ioCompletion; + short ioVRefNum; // Volume ref num + StringPtr ioNamePtr; + int ioFDirIndex; // Index (1-based!) + long ioDirID; // Input: Directory ID Output: File ID + int ioFlAttrib; // File attributes + FinderInfoBlock ioFlFndrInfo; + long ioFlParID; +}; + +struct DirInfoBlock +{ + void *ioCompletion; + short ioVRefNum; + long ioDrDirID; + unsigned char *ioNamePtr; + short ioFDirIndex; + int ioFlAttrib; +}; + +struct CInfoPBRec +{ + FileInfoBlock hFileInfo; + DirInfoBlock dirInfo; +}; + +struct Cursor +{ +}; + +struct CCursor +{ +}; + +struct CGraf +{ +}; + +struct Window +{ +}; + +struct Menu +{ +}; + +struct Region +{ +}; + +struct DateTimeRec +{ + int month; + int hour; + int minute; +}; + +struct VersionRecord +{ + Byte majorVer; + Byte minorVer; + Byte stage; + Byte rcVer; + + short countryCode; + Str255 shortVersion; + Str255 unused; +}; + +struct ColorSpec +{ + uint8_t r, g, b; +}; + +struct FSSpec +{ + Str63 name; + UInt32 parID; // Directory ID + SInt16 vRefNum; // Volume ID +}; + +typedef struct FInfo +{ + UInt32 fdType; +} FInfo; + +struct HFileParam +{ + int ioVRefNum; + long ioDirID; + const unsigned char *ioNamePtr; + void *ioCompletion; +}; + +struct EventRecord +{ + Point where; + uint32_t when; + intptr_t message; + int what; + int modifiers; +}; + +typedef CGraf *CGrafPtr; +typedef CGrafPtr GWorldPtr; +typedef Window *WindowPtr; +typedef Cursor *CursPtr; +typedef CCursor *CCrsrPtr; +typedef FSSpec *FSSpecPtr; +typedef Menu *MenuPtr; +typedef Region *RgnPtr; +typedef CInfoPBRec *CInfoPBPtr; +typedef VersionRecord *VersRecPtr; + +typedef CursPtr *CursHandle; +typedef CCrsrPtr *CCrsrHandle; +typedef MenuPtr *MenuHandle; +typedef RgnPtr *RgnHandle; +typedef VersRecPtr *VersRecHndl; + +typedef void *Ptr; +typedef Ptr *Handle; + +typedef WindowPtr WindowRef; // wtf? + + +typedef unsigned char KeyMap[16]; + + +enum RegionID +{ + inDesk, + inMenuBar, + inSysWindow, + inContent, + inDrag, + inGrow, + inGoAway, + inZoomIn, + inZoomOut, +}; + +enum WindowRegionType +{ + kWindowContentRgn +}; + +enum EventCode +{ + mouseDown, + mouseUp, + keyDown, + autoKey, + updateEvt, + osEvt, + kHighLevelEvent, +}; + +enum ScriptCode +{ + smSystemScript, +}; + +enum FindFolderRefNum +{ + kOnSystemDisk, +}; + +enum FindFolderType +{ + kPreferencesFolderType, +}; + +enum SetFPosWhere +{ + fsFromStart, +}; + +enum BuiltinWDEFs +{ + noGrowDocProc = 4, // Movable, not resizable +}; + +static const int everyEvent = -1; + +static const int iBeamCursor = 1; +static const int watchCursor = 4; + +static const int charCodeMask = 0xff; +static const int keyCodeMask = 0xff00; + +static const int shiftKey = 0x1; +static const int cmdKey = 0x2; // Ctrl +static const int optionKey = 0x4; // Alt + +static const bool kCreateFolder = true; +static const bool kDontCreateFolder = false; + +static const int fsRdPerm = 1; +static const int fsWrPerm = 2; +static const int fsRdWrPerm = (fsRdPerm | fsWrPerm); +static const int fsCurPerm = 4; // Any allowed permission + +static const Boolean TRUE = 1; +static const Boolean FALSE = 0; + +#define nil nullptr + +static const int nullEvent = 0; + +//void FlushEvents(int eventMask, int stopMask); + +OSErr FSClose(short fsRef); + +void InitCursor(); +CursHandle GetCursor(int cursorID); +CCrsrHandle GetCCursor(int cursorID); +void SetCCursor(CCrsrHandle handle); +void HideCursor(); + +void SetCursor(CursPtr cursor); + +void DisposeCCursor(CCrsrHandle handle); + +void Delay(int ticks, UInt32 *endTickCount); +short Alert(int dialogID, void *unknown); + +Handle GetResource(int32_t resType, int id); +Handle GetResource(const char(&resTypeLiteral)[5], int id); + +short FindWindow(Point point, WindowPtr *window); // Translates global coordinates to window coordinates, returns a region ID +void DragWindow(WindowPtr window, Point start, Rect *bounds); // Drags the window (probably not implemented) +void SendBehind(WindowPtr window, WindowPtr behind); +void BringToFront(WindowPtr window); +void ShowHide(WindowPtr window, Boolean hide); +bool TrackGoAway(WindowPtr window, Point point); // Returns true if the close box was actually clicked (?) +Int32 GrowWindow(WindowPtr window, Point start, Rect *size); +bool TrackBox(WindowPtr window, Point point, int part); // Returns true if grow/shrink box was clicked (part corresponds to type) +void ZoomWindow(WindowPtr window, int part, bool bringToFront); +void HiliteWindow(WindowPtr window, bool highlighted); +void DisposeWindow(WindowPtr window); +void GetWindowBounds(WindowPtr window, WindowRegionType windowRegion, Rect *rect); + +WindowPtr GetNewCWindow(int resID, void *storage, WindowPtr behind); +WindowPtr NewCWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, Boolean hasCloseBox, long userdata); +WindowPtr NewWindow(void *storage, const Rect *bounds, const PLPasStr &title, Boolean visible, int wdef, WindowPtr behind, Boolean hasCloseBox, long userdata); +void SizeWindow(WindowPtr window, int width, int height, Boolean addToUpdateRegion); +void MoveWindow(WindowPtr window, int x, int y, Boolean moveToFront); +void ShowWindow(WindowPtr window); +void SetWTitle(WindowPtr window, const PLPasStr &title); + +bool GetNextEvent(int32_t eventMask, EventRecord *event); + +long MenuSelect(Point point); // Breaks into menu select routine (in practice we'll just forward one from the queue?) + +long MenuKey(int charCode); +long TickCount(); +void GetKeys(KeyMap keyMap); + +short LoWord(Int32 v); +short HiWord(Int32 v); +bool BitTst(const KeyMap *keyMap, int bit); + +void NumToString(long number, unsigned char *str); +void ParamText(const PLPasStr &title, const PLPasStr &a, const PLPasStr &b, const PLPasStr &c); + +UInt32 FreeMem(); + +OSErr AEProcessAppleEvent(EventRecord *evt); + +OSErr FindFolder(int refNum, int posType, bool createFolder, short *volumeRef, long *dirID); +void GetIndString(unsigned char *str, int stringsID, int fnameIndex); // Fetches a string resource of some sort +OSErr PBDirCreate(HFileParam *fileParam, bool asynchronous); + +OSErr FSMakeFSSpec(int refNum, long dirID, const PLPasStr &fileName, FSSpec *spec); +OSErr FSpCreate(const FSSpec *spec, UInt32 creator, UInt32 fileType, ScriptCode scriptTag); +OSErr FSpDirCreate(const FSSpec *spec, ScriptCode script, long *outDirID); +OSErr FSpOpenDF(const FSSpec *spec, int permission, short *refNum); +OSErr FSWrite(short refNum, long *byteCount, const void *data); +OSErr FSRead(short refNum, long *byteCount, void *data); +OSErr FSpDelete(const FSSpec *spec); +OSErr FSpGetFInfo(const FSSpec *spec, FInfo *finfo); +OSErr SetFPos(short refNum, SetFPosWhere where, long offset); +OSErr GetEOF(short refNum, long *byteCount); +OSErr SetEOF(short refNum, long byteCount); + +OSErr PBGetCatInfo(CInfoPBPtr paramBlock, Boolean async); + +short StringWidth(const PLPasStr &str); + +void GetMouse(Point *point); +Boolean Button(); // Returns true if there's a mouse down event in the queue +Boolean StillDown(); +Boolean WaitMouseUp(); + +void LocalToGlobal(Point *point); +void GlobalToLocal(Point *point); +short Random(); +void GetDateTime(UInt32 *dateTime); +void GetTime(DateTimeRec *dateTime); +UInt32 GetDblTime(); + +void FlushEvents(int mask, int unknown); +void ExitToShell(); + +void InvalWindowRect(WindowPtr window, const Rect *rect); + +Handle NewHandle(Size size); +void DisposeHandle(Handle handle); +long GetHandleSize(Handle handle); + +void HNoPurge(Handle hdl); // Marks a handle as not purgeable +void MoveHHi(Handle hdl); // Relocates a block to the top of the heap +void HLock(Handle hdl); // Disable relocation +void HUnlock(Handle hdl); // Re-enable relocation + +OSErr PtrAndHand(const void *data, Handle handle, Size size); // Appends data to the end of a handle +void SetHandleSize(Handle hdl, Size newSize); + +void *NewPtr(Size size); +void *NewPtrClear(Size size); +void DisposePtr(void *ptr); + +Size MaxMem(Size *growBytes); +void PurgeSpace(long *totalFree, long *contiguousFree); + +void HSetState(Handle handle, char state); +char HGetState(Handle handle); + +OSErr MemError(); + +void BlockMove(const void *src, void *dest, Size size); + +Boolean WaitNextEvent(int eventMask, EventRecord *eventOut, long sleep, void *unknown); + +void DrawControls(WindowPtr window); +void DrawGrowIcon(WindowPtr window); + +void DebugStr(const PLPasStr &str); + +static const Boolean PL_TRUE = 1; +static const Boolean PL_FALSE = 0; + + +void PL_NotYetImplemented(); +void PL_NotYetImplemented_Minor(); +void PL_Init(); + + +#endif diff --git a/PortabilityLayer/PLDialogs.cpp b/PortabilityLayer/PLDialogs.cpp new file mode 100644 index 0000000..6d2d374 --- /dev/null +++ b/PortabilityLayer/PLDialogs.cpp @@ -0,0 +1,84 @@ +#include "PLDialogs.h" + +void DrawDialog(DialogPtr dialog) +{ + PL_NotYetImplemented(); +} + +WindowPtr GetDialogWindow(DialogPtr dialog) +{ + PL_NotYetImplemented(); + return nullptr; +} + +DialogPtr GetNewDialog(int resID, void *unknown, WindowPtr behind) +{ + PL_NotYetImplemented(); + return nullptr; +} + +CGrafPtr GetDialogPort(DialogPtr dialog) +{ + PL_NotYetImplemented(); + return nullptr; +} + +void GetDialogItem(DialogPtr dialog, int index, short *itemType, Handle *itemHandle, Rect *itemRect) +{ + PL_NotYetImplemented(); +} + +void GetDialogItemText(Handle handle, StringPtr str) +{ + PL_NotYetImplemented(); +} + +void SetDialogItem(DialogPtr dialog, int index, short itemType, Handle itemHandle, const Rect *itemRect) +{ + PL_NotYetImplemented(); +} + +void SetDialogItemText(Handle handle, const PLPasStr &str) +{ + PL_NotYetImplemented(); +} + +void SelectDialogItemText(DialogPtr dialog, int item, int firstSelChar, int lastSelCharExclusive) +{ + PL_NotYetImplemented(); +} + +ModalFilterUPP NewModalFilterUPP(ModalFilterUPP func) +{ + return func; +} + +void ModalDialog(ModalFilterUPP filter, short *item) +{ + PL_NotYetImplemented(); +} + +void DisposeDialog(DialogPtr dialog) +{ + PL_NotYetImplemented(); +} + +void DisposeModalFilterUPP(ModalFilterUPP upp) +{ + PL_NotYetImplemented(); +} + +void ShowDialogItem(DialogPtr dialog, int item) +{ + PL_NotYetImplemented(); +} + +void HideDialogItem(DialogPtr dialog, int item) +{ + PL_NotYetImplemented(); +} + +void TETextBox(const PLPasStr &str, short len, const Rect *rect, TEMode teMode) +{ + PL_NotYetImplemented(); +} diff --git a/PortabilityLayer/PLDialogs.h b/PortabilityLayer/PLDialogs.h new file mode 100644 index 0000000..b4805ad --- /dev/null +++ b/PortabilityLayer/PLDialogs.h @@ -0,0 +1,57 @@ +#pragma once +#ifndef __PL_DIALOGS_H__ +#define __PL_DIALOGS_H__ + +#include "PLCore.h" + +class PLPasStr; + +struct Dialog +{ +}; + +struct DialogTemplate +{ + // FIXME: Audit + Rect boundsRect; +}; + +enum TEMode +{ + teCenter +}; + +typedef Dialog *DialogPtr; + +typedef DialogTemplate *DialogTPtr; +typedef DialogTPtr *DialogTHndl; + + +typedef Boolean(*ModalFilterUPP)(DialogPtr dial, EventRecord *event, short *item); + +void DrawDialog(DialogPtr dialog); +WindowPtr GetDialogWindow(DialogPtr dialog); +DialogPtr GetNewDialog(int resID, void *unknown, WindowPtr behind); +CGrafPtr GetDialogPort(DialogPtr dialog); + +void GetDialogItem(DialogPtr dialog, int index, short *itemType, Handle *itemHandle, Rect *itemRect); +void GetDialogItemText(Handle handle, StringPtr str); + +void SetDialogItem(DialogPtr dialog, int index, short itemType, Handle itemHandle, const Rect *itemRect); +void SetDialogItemText(Handle handle, const PLPasStr &str); + +void SelectDialogItemText(DialogPtr dialog, int item, int firstSelChar, int lastSelCharExclusive); + +ModalFilterUPP NewModalFilterUPP(ModalFilterUPP func); + +void ModalDialog(ModalFilterUPP filter, short *item); + +void DisposeDialog(DialogPtr dialog); +void DisposeModalFilterUPP(ModalFilterUPP upp); + +void ShowDialogItem(DialogPtr dialog, int item); +void HideDialogItem(DialogPtr dialog, int item); + +void TETextBox(const PLPasStr &str, short len, const Rect *rect, TEMode teMode); + +#endif diff --git a/PortabilityLayer/PLErrorCodes.h b/PortabilityLayer/PLErrorCodes.h new file mode 100644 index 0000000..abc5d58 --- /dev/null +++ b/PortabilityLayer/PLErrorCodes.h @@ -0,0 +1,32 @@ +#pragma once +#ifndef __PL_ERROR_CODES_H__ +#define __PL_ERROR_CODES_H__ + +enum ErrorCodes +{ + noErr, + + fnfErr, + eofErr, + userCanceledErr, + dirFulErr, + dskFulErr, + ioErr, + bdNamErr, + fnOpnErr, + mFulErr, + tmfoErr, + wPrErr, + fLckdErr, + vLckdErr, + fBsyErr, + dupFNErr, + opWrErr, + volOffLinErr, + permErr, + wrPermErr, + + genericErr, +}; + +#endif diff --git a/PortabilityLayer/PLFolders.h b/PortabilityLayer/PLFolders.h new file mode 100644 index 0000000..50e9667 --- /dev/null +++ b/PortabilityLayer/PLFolders.h @@ -0,0 +1 @@ +#pragma once diff --git a/PortabilityLayer/PLLowMem.h b/PortabilityLayer/PLLowMem.h new file mode 100644 index 0000000..50e9667 --- /dev/null +++ b/PortabilityLayer/PLLowMem.h @@ -0,0 +1 @@ +#pragma once diff --git a/PortabilityLayer/PLMacTypes.h b/PortabilityLayer/PLMacTypes.h new file mode 100644 index 0000000..50e9667 --- /dev/null +++ b/PortabilityLayer/PLMacTypes.h @@ -0,0 +1 @@ +#pragma once diff --git a/PortabilityLayer/PLMenus.cpp b/PortabilityLayer/PLMenus.cpp new file mode 100644 index 0000000..9a842a3 --- /dev/null +++ b/PortabilityLayer/PLMenus.cpp @@ -0,0 +1,53 @@ +#include "PLMenus.h" + + +MenuHandle GetMenu(int resID) +{ + PL_NotYetImplemented(); + return nullptr; +} + +void AppendResMenu(MenuHandle menu, UInt32 resType) +{ + PL_NotYetImplemented(); +} + +void InsertMenu(MenuHandle menu, int index) +{ + PL_NotYetImplemented(); +} + +void DeleteMenu(int menuID) +{ + PL_NotYetImplemented(); +} + +void DrawMenuBar() +{ + PL_NotYetImplemented(); +} + +void HiliteMenu(int menu) +{ + PL_NotYetImplemented(); +} + +void EnableMenuItem(MenuHandle menu, int index) +{ + PL_NotYetImplemented(); +} + +void DisableMenuItem(MenuHandle menu, int index) +{ + PL_NotYetImplemented(); +} + +void CheckMenuItem(MenuHandle menu, int index, Boolean checked) +{ + PL_NotYetImplemented(); +} + +void SetMenuItemText(MenuHandle menu, int index, const PLPasStr &text) +{ + PL_NotYetImplemented(); +} diff --git a/PortabilityLayer/PLMenus.h b/PortabilityLayer/PLMenus.h new file mode 100644 index 0000000..3a89659 --- /dev/null +++ b/PortabilityLayer/PLMenus.h @@ -0,0 +1,21 @@ +#pragma once +#ifndef __PL_MENUS_H__ +#define __PL_MENUS_H__ + +#include "PLCore.h" + +class PLPasStr; + +MenuHandle GetMenu(int resID); +void AppendResMenu(MenuHandle menu, UInt32 resType); // Appends all menus of a given type +void InsertMenu(MenuHandle menu, int index); +void DeleteMenu(int menuID); // ??? +void DrawMenuBar(); +void HiliteMenu(int menu); + +void EnableMenuItem(MenuHandle menu, int index); +void DisableMenuItem(MenuHandle menu, int index); +void CheckMenuItem(MenuHandle menu, int index, Boolean checked); +void SetMenuItemText(MenuHandle menu, int index, const PLPasStr &text); + +#endif diff --git a/PortabilityLayer/PLMovies.cpp b/PortabilityLayer/PLMovies.cpp new file mode 100644 index 0000000..410532a --- /dev/null +++ b/PortabilityLayer/PLMovies.cpp @@ -0,0 +1,141 @@ +#include "PLMovies.h" + +OSErr EnterMovies() +{ + PL_NotYetImplemented(); + return noErr; +} + +UserData GetMovieUserData(Movie movie) +{ + PL_NotYetImplemented(); + return nullptr; +} + +int CountUserDataType(UserData userData, UInt32 type) +{ + PL_NotYetImplemented(); + return 0; +} + +OSErr RemoveUserData(UserData userData, UInt32 type, int index) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr AddUserData(UserData userData, Handle data, UInt32 type) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr OpenMovieFile(const FSSpec *fsSpec, short *outRefNum, int permissions) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr NewMovieFromFile(Movie *movie, short refNum, const short *optResId, StringPtr resName, int flags, Boolean *unused) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr CloseMovieFile(short refNum) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr GoToBeginningOfMovie(Movie movie) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr LoadMovieIntoRam(Movie movie, TimeValue time, TimeValue duration, int flags) +{ + PL_NotYetImplemented(); + return noErr; +} + +TimeValue GetMovieTime(Movie movie, TimeRecord *outCurrentTime) +{ + PL_NotYetImplemented(); + return 0; +} + +TimeValue GetMovieDuration(Movie movie) +{ + PL_NotYetImplemented(); + return 0; +} + +OSErr PrerollMovie(Movie movie, TimeValue time, UInt32 rate) +{ + PL_NotYetImplemented(); + return noErr; +} + +TimeBase GetMovieTimeBase(Movie movie) +{ + PL_NotYetImplemented(); + return nullptr; +} + +OSErr SetTimeBaseFlags(TimeBase timeBase, int flags) +{ + PL_NotYetImplemented(); + return noErr; +} + +void SetMovieMasterTimeBase(Movie movie, TimeBase timeBase, void *unused) +{ + PL_NotYetImplemented(); +} + +void GetMovieBox(Movie movie, Rect *rect) +{ + PL_NotYetImplemented(); +} + +void StopMovie(Movie movie) +{ + PL_NotYetImplemented(); +} + +void DisposeMovie(Movie movie) +{ + PL_NotYetImplemented(); +} + +void SetMovieGWorld(Movie movie, CGrafPtr graf, void *unknown) +{ + PL_NotYetImplemented(); +} + +void SetMovieActive(Movie movie, Boolean active) +{ + PL_NotYetImplemented(); +} + +void StartMovie(Movie movie) +{ + PL_NotYetImplemented(); +} + +void MoviesTask(Movie movie, int unknown) +{ + PL_NotYetImplemented(); +} + +void SetMovieBox(Movie movie, const Rect *rect) +{ + PL_NotYetImplemented(); +} + +void SetMovieDisplayClipRgn(Movie movie, RgnHandle region) +{ + PL_NotYetImplemented(); +} diff --git a/PortabilityLayer/PLMovies.h b/PortabilityLayer/PLMovies.h new file mode 100644 index 0000000..9b778ff --- /dev/null +++ b/PortabilityLayer/PLMovies.h @@ -0,0 +1,64 @@ +#pragma once +#ifndef __PL_MOVIES_H__ +#define __PL_MOVIES_H__ + +#include "PLApplication.h" + +struct UserDataObject; +struct TimeBaseObject; +struct MovieObject; + +struct UserDataBackingStorage +{ +}; + +typedef int64_t TimeValue; + +struct TimeRecord +{ +}; + +enum MovieFlags +{ + newMovieActive = 1, + flushFromRam = 2, +}; + +enum TimeBaseFlags +{ + loopTimeBase = 1, +}; + +typedef UserDataObject *UserData; +typedef TimeBaseObject *TimeBase; +typedef MovieObject *Movie; + + +OSErr EnterMovies(); + +UserData GetMovieUserData(Movie movie); +int CountUserDataType(UserData userData, UInt32 type); +OSErr RemoveUserData(UserData userData, UInt32 type, int index); // Index is 1-based +OSErr AddUserData(UserData userData, Handle data, UInt32 type); +OSErr OpenMovieFile(const FSSpec *fsSpec, short *outRefNum, int permissions); +OSErr NewMovieFromFile(Movie *movie, short refNum, const short *optResId, StringPtr resName, int flags, Boolean *unused); +OSErr CloseMovieFile(short refNum); +OSErr GoToBeginningOfMovie(Movie movie); +OSErr LoadMovieIntoRam(Movie movie, TimeValue time, TimeValue duration, int flags); +TimeValue GetMovieTime(Movie movie, TimeRecord *outCurrentTime); +TimeValue GetMovieDuration(Movie movie); +OSErr PrerollMovie(Movie movie, TimeValue time, UInt32 rate); +TimeBase GetMovieTimeBase(Movie movie); +OSErr SetTimeBaseFlags(TimeBase timeBase, int flags); +void SetMovieMasterTimeBase(Movie movie, TimeBase timeBase, void *unused); +void GetMovieBox(Movie movie, Rect *rect); +void StopMovie(Movie movie); +void DisposeMovie(Movie movie); +void SetMovieGWorld(Movie movie, CGrafPtr graf, void *unknown); +void SetMovieActive(Movie movie, Boolean active); +void StartMovie(Movie movie); +void MoviesTask(Movie movie, int unknown); +void SetMovieBox(Movie movie, const Rect *rect); +void SetMovieDisplayClipRgn(Movie movie, RgnHandle region); + +#endif diff --git a/PortabilityLayer/PLNavigation.cpp b/PortabilityLayer/PLNavigation.cpp new file mode 100644 index 0000000..0fccea4 --- /dev/null +++ b/PortabilityLayer/PLNavigation.cpp @@ -0,0 +1,13 @@ +#include "PLNavigation.h" + +OSErr NavGetDefaultDialogOptions(NavDialogOptions *options) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr NavPutFile(AEDesc *defaultLocation, NavReplyRecord *reply, NavDialogOptions *dlgOptions, void *unknown, UInt32 fileType, UInt32 fileCreator, void *unknown2) +{ + PL_NotYetImplemented(); + return noErr; +} diff --git a/PortabilityLayer/PLNavigation.h b/PortabilityLayer/PLNavigation.h new file mode 100644 index 0000000..a19305b --- /dev/null +++ b/PortabilityLayer/PLNavigation.h @@ -0,0 +1,27 @@ +#pragma once +#ifndef __PL_NAVIGATION_H__ +#define __PL_NAVIGATION_H__ + +#include "PLCore.h" +#include "PLAppleEvents.h" + +struct AEDesc; + +struct NavReplyRecord +{ + bool validRecord; + bool replacing; + int vRefNum; + long parID; // Directory? + AEDescList selection; + ScriptCode keyScript; // ??? +}; + +struct NavDialogOptions +{ +}; + +OSErr NavGetDefaultDialogOptions(NavDialogOptions *options); +OSErr NavPutFile(AEDesc *defaultLocation, NavReplyRecord *reply, NavDialogOptions *dlgOptions, void *unknown, UInt32 fileType, UInt32 fileCreator, void *unknown2); + +#endif diff --git a/PortabilityLayer/PLNumberFormatting.cpp b/PortabilityLayer/PLNumberFormatting.cpp new file mode 100644 index 0000000..f979f78 --- /dev/null +++ b/PortabilityLayer/PLNumberFormatting.cpp @@ -0,0 +1,52 @@ +#include "PLNumberFormatting.h" +#include "PLPasStr.h" + +void StringToNum(const PLPasStr &str, long *num) +{ + if (str.Length() == 0) + { + num = 0; + return; + } + + const size_t len = str.Length(); + const char *chars = str.Chars(); + const char *charsEnd = chars + len; + + long result = 0; + + if (chars[0] == '-') + { + chars++; + + while (chars != charsEnd) + { + const char c = *chars++; + + if (c < '0' || c > '9') + { + num = 0; + return; + } + + result = result * 10 - (c - '0'); + } + } + else + { + while (chars != charsEnd) + { + const char c = *chars++; + + if (c < '0' || c > '9') + { + num = 0; + return; + } + + result = result * 10 + (c - '0'); + } + } + + *num = result; +} diff --git a/PortabilityLayer/PLNumberFormatting.h b/PortabilityLayer/PLNumberFormatting.h new file mode 100644 index 0000000..61f1602 --- /dev/null +++ b/PortabilityLayer/PLNumberFormatting.h @@ -0,0 +1,9 @@ +#pragma once +#ifndef __PL_NUMBERFORMATTING_H__ +#define __PL_NUMBERFORMATTING_H__ + +class PLPasStr; + +void StringToNum(const PLPasStr &str, long *num); + +#endif diff --git a/PortabilityLayer/PLPalettes.h b/PortabilityLayer/PLPalettes.h new file mode 100644 index 0000000..8f4e86d --- /dev/null +++ b/PortabilityLayer/PLPalettes.h @@ -0,0 +1,5 @@ +#pragma once +#ifndef __PL_PALETTES_H__ +#define __PL_PALETTES_H__ + +#endif diff --git a/PortabilityLayer/PLPasStr.h b/PortabilityLayer/PLPasStr.h new file mode 100644 index 0000000..0edba13 --- /dev/null +++ b/PortabilityLayer/PLPasStr.h @@ -0,0 +1,79 @@ +#pragma once +#ifndef __PL_PASSTR_H__ +#define __PL_PASSTR_H__ + +#include "CoreDefs.h" + +namespace PortabilityLayer +{ + template + class PascalStrLiteral; +} + +class PLPasStr +{ +public: + PLPasStr(); + PLPasStr(const unsigned char *str); + template PLPasStr(const PortabilityLayer::PascalStrLiteral &pstrLiteral); + PLPasStr(const PLPasStr &other); + PLPasStr(unsigned char length, const char *str); + + unsigned char Length() const; + const char *Chars() const; + const unsigned char *UChars() const; + +private: + unsigned char m_length; + const char *m_chars; +}; + +#include "PascalStrLiteral.h" + +inline PLPasStr::PLPasStr() + : m_length(0) + , m_chars(nullptr) +{ +} + +inline PLPasStr::PLPasStr(const unsigned char *str) + : m_length(str[0]) + , m_chars(reinterpret_cast(str) + 1) +{ +} + +template +inline PLPasStr::PLPasStr(const PortabilityLayer::PascalStrLiteral &pstrLiteral) + : m_length(pstrLiteral.kLength) + , m_chars(pstrLiteral.GetStr()) +{ +} + +inline PLPasStr::PLPasStr(const PLPasStr &other) + : m_length(other.m_length) + , m_chars(other.m_chars) +{ +} + +inline PLPasStr::PLPasStr(uint8_t length, const char *str) + : m_length(length) + , m_chars(str) +{ +} + +inline unsigned char PLPasStr::Length() const +{ + return m_length; +} + +inline const char *PLPasStr::Chars() const +{ + return m_chars; +} + +inline const unsigned char *PLPasStr::UChars() const +{ + return reinterpret_cast(m_chars); +} + +#endif diff --git a/PortabilityLayer/PLQDOffscreen.cpp b/PortabilityLayer/PLQDOffscreen.cpp new file mode 100644 index 0000000..d49108c --- /dev/null +++ b/PortabilityLayer/PLQDOffscreen.cpp @@ -0,0 +1,50 @@ +#include "PLQDOffscreen.h" + + +OSErr NewGWorld(GWorldPtr *gworld, int depth, Rect *bounds, CTabHandle colorTable, GDHandle device, int flags) +{ + PL_NotYetImplemented(); + return noErr; +} + +void DisposeGWorld(GWorldPtr gworld) +{ + PL_NotYetImplemented(); +} + +PixMapHandle GetGWorldPixMap(GWorldPtr gworld) +{ + PL_NotYetImplemented(); + return nullptr; +} + +void LockPixels(PixMapHandle pixmap) +{ + PL_NotYetImplemented(); +} + +PicHandle GetPicture(short resID) +{ + PL_NotYetImplemented(); + return nullptr; +} + +void OffsetRect(Rect *rect, int right, int down) +{ + PL_NotYetImplemented(); +} + +void DrawPicture(PicHandle pict, Rect *bounds) +{ + PL_NotYetImplemented(); +} + +void GetGWorld(CGrafPtr *gw, GDHandle *gdHandle) +{ + PL_NotYetImplemented(); +} + +void SetGWorld(CGrafPtr gw, GDHandle gdHandle) +{ + PL_NotYetImplemented(); +} diff --git a/PortabilityLayer/PLQDOffscreen.h b/PortabilityLayer/PLQDOffscreen.h new file mode 100644 index 0000000..55c889d --- /dev/null +++ b/PortabilityLayer/PLQDOffscreen.h @@ -0,0 +1,51 @@ +#pragma once +#ifndef __PL_QDOFFSCREEN_H__ +#define __PL_QDOFFSCREEN_H__ + +#include "PLCore.h" +#include "PLQuickdraw.h" + +struct ColorTable +{ +}; + +struct PixMap +{ +}; + +struct Picture +{ + Rect picFrame; +}; + +typedef ColorTable *CTabPtr; +typedef CTabPtr *CTabHandle; + +typedef PixMap *PixMapPtr; +typedef PixMapPtr *PixMapHandle; + +typedef Picture *PicPtr; +typedef PicPtr *PicHandle; + +enum QDFlags +{ + useTempMem = 1, +}; + +OSErr NewGWorld(GWorldPtr *gworld, int depth, Rect *bounds, CTabHandle colorTable, GDHandle device, int flags); +void DisposeGWorld(GWorldPtr gworld); + +PixMapHandle GetGWorldPixMap(GWorldPtr gworld); +void LockPixels(PixMapHandle pixmap); + +PicHandle GetPicture(short resID); + +void OffsetRect(Rect *rect, int right, int down); + +void DrawPicture(PicHandle pict, Rect *bounds); + +void GetGWorld(CGrafPtr *gw, GDHandle *gdHandle); +void SetGWorld(CGrafPtr gw, GDHandle gdHandle); + + +#endif diff --git a/PortabilityLayer/PLQuickdraw.cpp b/PortabilityLayer/PLQuickdraw.cpp new file mode 100644 index 0000000..49ba898 --- /dev/null +++ b/PortabilityLayer/PLQuickdraw.cpp @@ -0,0 +1,366 @@ +#include "PLQuickdraw.h" +#include "DisplayDeviceManager.h" + +void GetPort(GrafPtr *graf) +{ + PL_NotYetImplemented(); +} + +void SetPort(GrafPtr graf) +{ + PL_NotYetImplemented(); +} + +void BeginUpdate(GrafPtr graf) +{ + PL_NotYetImplemented(); +} + +void EndUpdate(GrafPtr graf) +{ + PL_NotYetImplemented(); +} + +OSErr GetIconSuite(Handle *suite, short resID, IconSuiteFlags flags) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr PlotIconSuite(Rect *rect, IconAlignmentType alignType, IconTransformType transformType, Handle iconSuite) +{ + PL_NotYetImplemented(); + return noErr; +} + +CIconHandle GetCIcon(short resID) +{ + PL_NotYetImplemented(); + return nullptr; +} + +OSErr PlotCIcon(Rect *rect, CIconHandle icon) +{ + PL_NotYetImplemented(); + return noErr; +} + +void DisposeCIcon(CIconHandle icon) +{ + PL_NotYetImplemented(); +} + +void SetRect(Rect *rect, short left, short top, short right, short bottom) +{ + rect->left = left; + rect->top = top; + rect->bottom = bottom; + rect->right = right; +} + +GDHandle GetMainDevice() +{ + return PortabilityLayer::DisplayDeviceManager::GetInstance()->GetMainDevice(); +} + +void SetPortWindowPort(WindowPtr window) +{ + PL_NotYetImplemented(); +} + +void SetPortDialogPort(Dialog *dialog) +{ + PL_NotYetImplemented(); +} + + +void TextSize(int sz) +{ + PL_NotYetImplemented(); +} + +void TextFace(int face) +{ + PL_NotYetImplemented(); +} + +void TextFont(int fontID) +{ + PL_NotYetImplemented(); +} + +int TextWidth(const PLPasStr &str, int firstChar1Based, int length) +{ + PL_NotYetImplemented(); + return 0; +} + +void MoveTo(int x, int y) +{ + PL_NotYetImplemented(); +} + +void LineTo(int x, int y) +{ + PL_NotYetImplemented(); +} + +void SetOrigin(int x, int y) +{ + PL_NotYetImplemented(); +} + +void ForeColor(SystemColorID color) +{ + PL_NotYetImplemented(); +} + +void BackColor(SystemColorID color) +{ + PL_NotYetImplemented(); +} + +void GetForeColor(RGBColor *color) +{ + PL_NotYetImplemented(); +} + +void Index2Color(int index, RGBColor *color) +{ + PL_NotYetImplemented(); +} + +void RGBForeColor(const RGBColor *color) +{ + PL_NotYetImplemented(); +} + +void DrawString(const PLPasStr &str) +{ + PL_NotYetImplemented(); +} + +void PaintRect(const Rect *rect) +{ + PL_NotYetImplemented(); +} + +void PaintOval(const Rect *rect) +{ + PL_NotYetImplemented(); +} + +void PaintRgn(RgnHandle region) +{ + PL_NotYetImplemented(); +} + +void ClipRect(const Rect *rect) +{ + PL_NotYetImplemented(); +} + +void FrameRect(const Rect *rect) +{ + PL_NotYetImplemented(); +} + +void FrameOval(const Rect *rect) +{ + PL_NotYetImplemented(); +} + +void FrameRoundRect(const Rect *rect, int w, int h) +{ + PL_NotYetImplemented(); +} + +void PenMode(int mode) +{ + PL_NotYetImplemented(); +} + +void PenMode(PenModeID penMode) +{ + PL_NotYetImplemented(); +} + +void PenMode(CopyBitsMode copyBitsMode) +{ + PL_NotYetImplemented(); +} + +void PenPat(const Pattern *pattern) +{ + PL_NotYetImplemented(); +} + +void PenSize(int w, int h) +{ + PL_NotYetImplemented(); +} + +void PenNormal() +{ + PL_NotYetImplemented(); +} + +void EraseRect(const Rect *rect) +{ + PL_NotYetImplemented(); +} + +void InvertRect(const Rect *rect) +{ + PL_NotYetImplemented(); +} + +void InsetRect(Rect *rect, int x, int y) +{ + PL_NotYetImplemented(); +} + +void Line(int x, int y) +{ + PL_NotYetImplemented(); +} + +Pattern *GetQDGlobalsGray(Pattern *pattern) +{ + PL_NotYetImplemented(); + return nullptr; +} + +Pattern *GetQDGlobalsBlack(Pattern *pattern) +{ + PL_NotYetImplemented(); + return nullptr; +} + +void GetIndPattern(Pattern *pattern, int patListID, int index) +{ + PL_NotYetImplemented(); +} + + + +void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *destRect, CopyBitsMode copyMode, RgnHandle maskRegion) +{ + PL_NotYetImplemented(); +} + +void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *maskRect, const Rect *destRect) +{ + PL_NotYetImplemented(); +} + + +RgnHandle NewRgn() +{ + PL_NotYetImplemented(); + return nullptr; +} + +void RectRgn(RgnHandle region, const Rect *rect) +{ + PL_NotYetImplemented(); +} + +void UnionRgn(RgnHandle regionA, RgnHandle regionB, RgnHandle regionC) +{ + PL_NotYetImplemented(); +} + +void DisposeRgn(RgnHandle rgn) +{ + PL_NotYetImplemented(); +} + +void OpenRgn() +{ + PL_NotYetImplemented(); +} + +void CloseRgn(RgnHandle rgn) +{ + PL_NotYetImplemented(); +} + +Boolean PtInRgn(Point point, RgnHandle rgn) +{ + PL_NotYetImplemented(); + return false; +} + +void GetClip(RgnHandle rgn) +{ + PL_NotYetImplemented(); +} + +void SetClip(RgnHandle rgn) +{ + PL_NotYetImplemented(); +} + + +BitMap *GetPortBitMapForCopyBits(CGrafPtr grafPtr) +{ + PL_NotYetImplemented(); + return nullptr; +} + +CGrafPtr GetWindowPort(WindowPtr window) +{ + PL_NotYetImplemented(); + return nullptr; +} + +RgnHandle GetPortVisibleRegion(CGrafPtr port, RgnHandle region) +{ + PL_NotYetImplemented(); + return nullptr; +} + + +Int32 DeltaPoint(Point pointA, Point pointB) +{ + PL_NotYetImplemented(); + return 0; +} + + +void SubPt(Point srcPoint, Point *destPoint) +{ + PL_NotYetImplemented(); +} + + +Boolean SectRect(const Rect *rectA, const Rect *rectB, Rect *outIntersection) +{ + PL_NotYetImplemented(); + return false; +} + + +Boolean PtInRect(Point point, const Rect *rect) +{ + PL_NotYetImplemented(); + return false; +} + + +void RestoreDeviceClut(void *unknown) +{ + PL_NotYetImplemented(); +} + +void PaintBehind(void *unknown, RgnHandle region) +{ + PL_NotYetImplemented(); +} + +RgnHandle GetGrayRgn() +{ + PL_NotYetImplemented(); + return nullptr; +} diff --git a/PortabilityLayer/PLQuickdraw.h b/PortabilityLayer/PLQuickdraw.h new file mode 100644 index 0000000..bf26b47 --- /dev/null +++ b/PortabilityLayer/PLQuickdraw.h @@ -0,0 +1,217 @@ +#pragma once +#ifndef __PL_QUICKDRAW_H__ +#define __PL_QUICKDRAW_H__ + +#include "PLCore.h" + +struct Dialog; + +enum IconAlignmentType +{ + atNone +}; + +enum IconTransformType +{ + ttNone +}; + +enum IconSuiteFlags +{ + svAllLargeData = 1, +}; + +enum TextFlags +{ + bold = 1, + italicBit = 2, + ulineBit = 4, + outlineBit = 8, + shadowBit = 16, + condenseBit = 32, + extendBit = 64, +}; + +enum SystemFontID +{ + systemFont = 0, // System font + applFont = 1, // Application font + newYork = 2, + geneva = 3, + monaco = 4, + venice = 5, + london = 6, + athens = 7, + sanFran = 8, + toronto = 9, + cairo = 11, + losAngeles = 12, + times = 20, + helvetica = 21, + courier = 22, + symbol = 23, + mobile = 24, +}; + +// wtf? +enum SystemColorID +{ + whiteColor = 30, + blackColor = 33, + yellowColor = 69, + magentaColor = 137, + redColor = 205, + cyanColor = 273, + greenColor = 341, + blueColor = 409, +}; + +enum CopyBitsMode +{ + srcCopy, + srcOr, + srcXor, + srcBic, + notSrcCopy, + notSrcOr, + notSrcXor, + notSrcBic, + transparent +}; + +enum PenModeID +{ + patCopy = 8, + patOr, + patXor, + patBic, + notPatCopy, + notPatOr, + notPatXor, + notPatBic, +}; + +enum HiliteMode +{ + hilite = 50, +}; + +struct CIcon +{ +}; + +struct GDevice +{ +}; + +struct BitMap +{ +}; + +struct RGBColor +{ + unsigned short red; + unsigned short green; + unsigned short blue; +}; + +typedef GDevice *GDPtr; +typedef GDPtr *GDHandle; + +typedef CIcon *CIconPtr; +typedef CIconPtr *CIconHandle; + +typedef WindowPtr GrafPtr; + +typedef Byte Pattern[8]; + +void GetPort(GrafPtr *graf); +void SetPort(GrafPtr graf); +void SetPortWindowPort(WindowPtr window); +void SetPortDialogPort(Dialog *dialog); + +void BeginUpdate(GrafPtr graf); +void EndUpdate(GrafPtr graf); + +OSErr GetIconSuite(Handle *suite, short resID, IconSuiteFlags flags); +OSErr PlotIconSuite(Rect *rect, IconAlignmentType alignType, IconTransformType transformType, Handle iconSuite); + +CIconHandle GetCIcon(short resID); +OSErr PlotCIcon(Rect *rect, CIconHandle icon); +void DisposeCIcon(CIconHandle icon); + +void SetRect(Rect *rect, short left, short top, short right, short bottom); + +GDHandle GetMainDevice(); + +void TextSize(int sz); +void TextFace(int face); +void TextFont(int fontID); +int TextWidth(const PLPasStr &str, int firstChar1Based, int length); +void MoveTo(int x, int y); +void LineTo(int x, int y); +void SetOrigin(int x, int y); +void ForeColor(SystemColorID color); +void BackColor(SystemColorID color); +void GetForeColor(RGBColor *color); +void Index2Color(int index, RGBColor *color); +void RGBForeColor(const RGBColor *color); +void DrawString(const PLPasStr &str); +void PaintRect(const Rect *rect); +void PaintOval(const Rect *rect); +void PaintRgn(RgnHandle region); + +void ClipRect(const Rect *rect); // Sets the clipping area +void FrameRect(const Rect *rect); +void FrameOval(const Rect *rect); +void FrameRoundRect(const Rect *rect, int w, int h); +void PenMode(int mode); // Can be CopyBitsMode, PenModeID, and possibly add "50" to hilite +void PenPat(const Pattern *pattern); +void PenSize(int w, int h); +void PenNormal(); +void EraseRect(const Rect *rect); +void InvertRect(const Rect *rect); +void InsetRect(Rect *rect, int x, int y); +void Line(int x, int y); // FIXME: Is this relative or absolute? +Pattern *GetQDGlobalsGray(Pattern *pattern); +Pattern *GetQDGlobalsBlack(Pattern *pattern); + +// Finds a pattern from a 'PAT#' resource +// Index is 1-based +void GetIndPattern(Pattern *pattern, int patListID, int index); + + +void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *destRect, CopyBitsMode copyMode, RgnHandle maskRegion); +void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRect, const Rect *maskRect, const Rect *destRect); + +RgnHandle NewRgn(); +void RectRgn(RgnHandle region, const Rect *rect); +void UnionRgn(RgnHandle regionA, RgnHandle regionB, RgnHandle regionC); +void DisposeRgn(RgnHandle rgn); +void OpenRgn(); +void CloseRgn(RgnHandle rgn); +Boolean PtInRgn(Point point, RgnHandle rgn); + +void GetClip(RgnHandle rgn); +void SetClip(RgnHandle rgn); + +BitMap *GetPortBitMapForCopyBits(CGrafPtr grafPtr); +CGrafPtr GetWindowPort(WindowPtr window); +RgnHandle GetPortVisibleRegion(CGrafPtr port, RgnHandle region); + +// Computes A - B and returns it packed? +Int32 DeltaPoint(Point pointA, Point pointB); + +// Subtracts srcPoint from destPoint (reverse of DeltaPoint) +void SubPt(Point srcPoint, Point *destPoint); + +Boolean SectRect(const Rect *rectA, const Rect *rectB, Rect *outIntersection); + +Boolean PtInRect(Point point, const Rect *rect); + +void RestoreDeviceClut(void *unknown); +void PaintBehind(void *unknown, RgnHandle region); + +RgnHandle GetGrayRgn(); // Returns the region not occupied by the menu bar + +#endif diff --git a/PortabilityLayer/PLResourceManager.cpp b/PortabilityLayer/PLResourceManager.cpp new file mode 100644 index 0000000..af3cdc6 --- /dev/null +++ b/PortabilityLayer/PLResourceManager.cpp @@ -0,0 +1,138 @@ +#include "ResourceManager.h" +#include "VirtualDirectory.h" +#include "FileManager.h" +#include "HostFileSystem.h" +#include "HostMemoryBuffer.h" +#include "IOStream.h" +#include "MacBinary2.h" +#include "MacFileMem.h" +#include "MemReaderStream.h" +#include "ResourceFile.h" +#include "PLPasStr.h" +#include "PLErrorCodes.h" + +#include + +namespace PortabilityLayer +{ + class ResourceManagerImpl final : public ResourceManager + { + public: + ResourceManagerImpl(); + + void Init() override; + void Shutdown() override; + + void SetResLoad(bool load) override; + + short OpenResFork(EVirtualDirectory virtualDir, const PLPasStr &filename) override; + MMHandleBlock *GetResource(const ResTypeID &resType, int id) override; + + short GetCurrentResFile() const override; + void SetCurrentResFile(short ref) override; + + static ResourceManagerImpl *GetInstance(); + + private: + std::vector m_resFiles; + short m_currentResFile; + bool m_load; + + static ResourceManagerImpl ms_instance; + }; + + ResourceManagerImpl::ResourceManagerImpl() + : m_currentResFile(0) + , m_load(true) + { + } + + void ResourceManagerImpl::Init() + { + m_currentResFile = OpenResFork(EVirtualDirectory_ApplicationData, PSTR("ApplicationResources")); + } + + void ResourceManagerImpl::Shutdown() + { + for (std::vector::iterator it = m_resFiles.begin(), itEnd = m_resFiles.end(); it != itEnd; ++it) + delete (*it); + + m_resFiles.clear(); + } + + short ResourceManagerImpl::GetCurrentResFile() const + { + return m_currentResFile; + } + + void ResourceManagerImpl::SetCurrentResFile(short ref) + { + m_currentResFile = ref; + } + + ResourceManagerImpl *ResourceManagerImpl::GetInstance() + { + return &ms_instance; + } + + void ResourceManagerImpl::SetResLoad(bool load) + { + m_load = load; + } + + short ResourceManagerImpl::OpenResFork(EVirtualDirectory virtualDir, const PLPasStr &filename) + { + const size_t numSlots = m_resFiles.size(); + size_t resFileIndex = numSlots; + + for (size_t i = 0; i < numSlots; i++) + { + if (m_resFiles[i] == nullptr) + { + resFileIndex = i; + break; + } + } + + if (resFileIndex == 0x7fff) + return 0; + + IOStream *fStream = nullptr; + if (FileManager::GetInstance()->RawOpenFileRF(virtualDir, filename, EFilePermission_Read, true, &fStream) != noErr) + return 0; + + ResourceFile *resFile = new ResourceFile(); + bool loaded = resFile->Load(fStream); + fStream->Close(); + + if (!loaded) + { + delete resFile; + return 0; + } + + if (resFileIndex == numSlots) + m_resFiles.push_back(resFile); + else + m_resFiles[resFileIndex] = resFile; + + return static_cast(resFileIndex + 1); + } + + MMHandleBlock *ResourceManagerImpl::GetResource(const ResTypeID &resType, int id) + { + if (!m_currentResFile) + return nullptr; + + ResourceFile *resFile = m_resFiles[m_currentResFile - 1]; + if (!resFile) + return nullptr; + + return resFile->GetResource(resType, id, m_load); + } + + + ResourceManagerImpl ResourceManagerImpl::ms_instance; + + ResourceManager *ResourceManager::GetInstance() { return ResourceManagerImpl::GetInstance(); } +} diff --git a/PortabilityLayer/PLResources.cpp b/PortabilityLayer/PLResources.cpp new file mode 100644 index 0000000..de4a10a --- /dev/null +++ b/PortabilityLayer/PLResources.cpp @@ -0,0 +1,88 @@ +#include "PLResources.h" + +#include "MMHandleBlock.h" +#include "ResourceManager.h" +#include "ResourceCompiledRef.h" + +void DetachResource(Handle hdl) +{ + PL_NotYetImplemented(); +} + +void ReleaseResource(Handle hdl) +{ + PL_NotYetImplemented(); +} + +short CurResFile() +{ + return PortabilityLayer::ResourceManager::GetInstance()->GetCurrentResFile(); +} + +void UseResFile(short fid) +{ + PL_NotYetImplemented(); +} + +Handle Get1Resource(UInt32 resID, int index) +{ + PL_NotYetImplemented(); + return nullptr; +} + +Handle Get1IndResource(UInt32 resID, int index) +{ + PL_NotYetImplemented(); + return nullptr; +} + +int Count1Resources(UInt32 resType) +{ + PL_NotYetImplemented(); + return 0; +} + +void HCreateResFile(int refNum, long dirID, const PLPasStr &name) +{ + PL_NotYetImplemented(); +} + +OSErr ResError() +{ + PL_NotYetImplemented(); + return noErr; +} + +short FSpOpenResFile(const FSSpec *spec, int permission) +{ + PL_NotYetImplemented(); + return 0; +} + +void CloseResFile(short refNum) +{ + PL_NotYetImplemented(); +} + +void SetResLoad(Boolean load) +{ + PortabilityLayer::ResourceManager::GetInstance()->SetResLoad(load != 0); +} + +long GetMaxResourceSize(Handle res) +{ + const PortabilityLayer::MMHandleBlock *hBlock = reinterpret_cast(res); + const PortabilityLayer::ResourceCompiledRef *resRef = hBlock->m_rmSelfRef; + return resRef->GetSize(); +} + +void GetResInfo(Handle res, short *resID, ResType *resType, Str255 resName) +{ + PL_NotYetImplemented(); +} + +short HOpenResFile(short refNum, long parID, const PLPasStr &name, int permissions) +{ + PL_NotYetImplemented(); + return 0; +} diff --git a/PortabilityLayer/PLResources.h b/PortabilityLayer/PLResources.h new file mode 100644 index 0000000..fa0e591 --- /dev/null +++ b/PortabilityLayer/PLResources.h @@ -0,0 +1,37 @@ +#pragma once +#ifndef __PL_RESOURCES_H__ +#define __PL_RESOURCES_H__ + +#include "PLCore.h" + +struct ResType +{ +}; + +class PLPasStr; + +void DetachResource(Handle hdl); +void ReleaseResource(Handle hdl); + +short CurResFile(); +void UseResFile(short fid); +Handle Get1Resource(UInt32 resID, int index); +Handle Get1IndResource(UInt32 resID, int index); +int Count1Resources(UInt32 resType); + +void HCreateResFile(int refNum, long dirID, const PLPasStr &name); +OSErr ResError(); + +short FSpOpenResFile(const FSSpec *spec, int permission); +void CloseResFile(short refNum); + +void SetResLoad(Boolean load); // Sets whether resources should be loaded when requested + +long GetMaxResourceSize(Handle res); +void GetResInfo(Handle res, short *resID, ResType *resType, Str255 resName); + +// This should return -1 on error? +short HOpenResFile(short refNum, long parID, const PLPasStr &name, int permissions); + + +#endif diff --git a/PortabilityLayer/PLScript.h b/PortabilityLayer/PLScript.h new file mode 100644 index 0000000..50e9667 --- /dev/null +++ b/PortabilityLayer/PLScript.h @@ -0,0 +1 @@ +#pragma once diff --git a/PortabilityLayer/PLSound.cpp b/PortabilityLayer/PLSound.cpp new file mode 100644 index 0000000..49cb59d --- /dev/null +++ b/PortabilityLayer/PLSound.cpp @@ -0,0 +1,53 @@ +#include "PLSound.h" + +OSErr GetDefaultOutputVolume(long *vol) +{ + short leftVol = 0x100; + short rightVol = 0x100; + + PL_NotYetImplemented_Minor(); + + *vol = (leftVol) | (rightVol << 16); + + return noErr; +} + +OSErr SetDefaultOutputVolume(long vol) +{ + return noErr; +} + + +SndCallBackUPP NewSndCallBackProc(SndCallBackProc callback) +{ + return callback; +} + +void DisposeSndCallBackUPP(SndCallBackUPP upp) +{ +} + +OSErr SndNewChannel(SndChannelPtr *outChannel, SndSynthType synthType, int initFlags, SndCallBackUPP callback) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr SndDisposeChannel(SndChannelPtr channel, Boolean flush) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr SndDoCommand(SndChannelPtr channel, const SndCommand *command, Boolean failIfFull) +{ + PL_NotYetImplemented(); + return noErr; +} + +OSErr SndDoImmediate(SndChannelPtr channel, const SndCommand *command) +{ + PL_NotYetImplemented(); + return noErr; +} + diff --git a/PortabilityLayer/PLSound.h b/PortabilityLayer/PLSound.h new file mode 100644 index 0000000..8042d7b --- /dev/null +++ b/PortabilityLayer/PLSound.h @@ -0,0 +1,56 @@ +#pragma once +#ifndef __PL_SOUND_H__ +#define __PL_SOUND_H__ + +#include "PLCore.h" + +enum SndCommandType +{ + nullCmd, + bufferCmd, // Param1: 0 Param2: Offset to sound header + callBackCmd, + flushCmd, + quietCmd +}; + +struct SndChannel +{ +}; + +struct SndCommand +{ + SndCommandType cmd; + intptr_t param1; + intptr_t param2; +}; + +enum SndSynthType +{ + sampledSynth +}; + +enum SndInitFlags +{ + initNoInterp = 1, + initMono = 2, +}; + +typedef SndChannel *SndChannelPtr; + +typedef void(*SndCallBackProc)(SndChannelPtr channel, SndCommand *command); +typedef SndCallBackProc SndCallBackUPP; + +// Vol seems to be a packed stereo DWord + +OSErr GetDefaultOutputVolume(long *vol); +OSErr SetDefaultOutputVolume(long vol); + + +SndCallBackUPP NewSndCallBackProc(SndCallBackProc callback); +void DisposeSndCallBackUPP(SndCallBackUPP upp); +OSErr SndNewChannel(SndChannelPtr *outChannel, SndSynthType synthType, int initFlags, SndCallBackUPP callback); +OSErr SndDisposeChannel(SndChannelPtr channel, Boolean flush); +OSErr SndDoCommand(SndChannelPtr channel, const SndCommand *command, Boolean failIfFull); +OSErr SndDoImmediate(SndChannelPtr channel, const SndCommand *command); + +#endif diff --git a/PortabilityLayer/PLStringCompare.cpp b/PortabilityLayer/PLStringCompare.cpp new file mode 100644 index 0000000..b277464 --- /dev/null +++ b/PortabilityLayer/PLStringCompare.cpp @@ -0,0 +1,7 @@ +#include "PLStringCompare.h" + +Boolean EqualString(const PLPasStr &string1, const PLPasStr &string2, Boolean caseSensitive, Boolean diacriticSensitive) +{ + PL_NotYetImplemented(); + return false; +} \ No newline at end of file diff --git a/PortabilityLayer/PLStringCompare.h b/PortabilityLayer/PLStringCompare.h new file mode 100644 index 0000000..2fd747f --- /dev/null +++ b/PortabilityLayer/PLStringCompare.h @@ -0,0 +1,10 @@ +#pragma once +#ifndef __PL_STRINGCOMPARE_H__ +#define __PL_STRINGCOMPARE_H__ + +#include "PLCore.h" +#include "PLPasStr.h" + +Boolean EqualString(const PLPasStr &string1, const PLPasStr &string2, Boolean caseSensitive, Boolean diacriticSensitive); + +#endif diff --git a/PortabilityLayer/PLTextUtils.h b/PortabilityLayer/PLTextUtils.h new file mode 100644 index 0000000..50e9667 --- /dev/null +++ b/PortabilityLayer/PLTextUtils.h @@ -0,0 +1 @@ +#pragma once diff --git a/PortabilityLayer/PLToolUtils.h b/PortabilityLayer/PLToolUtils.h new file mode 100644 index 0000000..50e9667 --- /dev/null +++ b/PortabilityLayer/PLToolUtils.h @@ -0,0 +1 @@ +#pragma once diff --git a/PortabilityLayer/PascalStr.h b/PortabilityLayer/PascalStr.h new file mode 100644 index 0000000..cc8af89 --- /dev/null +++ b/PortabilityLayer/PascalStr.h @@ -0,0 +1,36 @@ +#pragma once + +#ifndef __PL_PASCALSTR_H__ +#define __PL_PASCALSTR_H__ + +#include "UnsafePascalStr.h" + +namespace PortabilityLayer +{ + template + class PascalStr : public UnsafePascalStr + { + public: + PascalStr(); + PascalStr(size_t size, const char *str); + }; +} + +#include + +namespace PortabilityLayer +{ + template + inline PascalStr::PascalStr() + : UnsafePascalStr(0, nullptr) + { + } + + template + PascalStr::PascalStr(size_t size, const char *str) + : UnsafePascalStr(size, str) + { + } +} + +#endif diff --git a/PortabilityLayer/PascalStrLiteral.h b/PortabilityLayer/PascalStrLiteral.h new file mode 100644 index 0000000..df31267 --- /dev/null +++ b/PortabilityLayer/PascalStrLiteral.h @@ -0,0 +1,40 @@ +#pragma once +#ifndef __PL_PASCAL_STR_LITERAL_H__ +#define __PL_PASCAL_STR_LITERAL_H__ + +#include "DataTypes.h" + +namespace PortabilityLayer +{ + template + class PascalStrLiteral + { + public: + PascalStrLiteral(const char (&literalStr)[TSize]); + const char *GetStr() const; + + static const uint8_t kLength = TSize - 1; + + private: + const char *m_literal; + }; +} + +namespace PortabilityLayer +{ + template + inline PascalStrLiteral::PascalStrLiteral(const char(&literalStr)[TSize]) + : m_literal(literalStr) + { + } + + template + inline const char *PascalStrLiteral::GetStr() const + { + return m_literal; + } +} + +#define PSTR(n) (::PortabilityLayer::PascalStrLiteral(n)) + +#endif diff --git a/PortabilityLayer/PortabilityLayer.vcxproj b/PortabilityLayer/PortabilityLayer.vcxproj new file mode 100644 index 0000000..e4789d0 --- /dev/null +++ b/PortabilityLayer/PortabilityLayer.vcxproj @@ -0,0 +1,238 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {6EC62B0F-9353-40A4-A510-3788F1368B33} + PortabilityLayer + 10.0.16299.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + StaticLibrary + true + v141 + MultiByte + + + StaticLibrary + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/PortabilityLayer/PortabilityLayer.vcxproj.filters b/PortabilityLayer/PortabilityLayer.vcxproj.filters new file mode 100644 index 0000000..d23ec8a --- /dev/null +++ b/PortabilityLayer/PortabilityLayer.vcxproj.filters @@ -0,0 +1,351 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + \ No newline at end of file diff --git a/PortabilityLayer/RCPtr.h b/PortabilityLayer/RCPtr.h new file mode 100644 index 0000000..3a922bd --- /dev/null +++ b/PortabilityLayer/RCPtr.h @@ -0,0 +1,121 @@ +#pragma once + +#include "CoreDefs.h" + +namespace PortabilityLayer +{ + class RefCountedBase; + + template + class RCPtr + { + public: + RCPtr(); + RCPtr(T *other); + RCPtr(const RCPtr &other); +#if IS_CPP11 + RCPtr(RCPtr &&other); +#endif + ~RCPtr(); + + operator T*() const; + T* operator ->() const; + + RCPtr &operator=(T *other); +#if IS_CPP11 + RCPtr &operator=(RCPtr &&other); +#endif + + T *Get() const; + + private: + RefCountedBase *m_target; + }; +} + +#include "RefCounted.h" + +template +inline PortabilityLayer::RCPtr::RCPtr() + : m_target(nullptr) +{ +} + +template +inline PortabilityLayer::RCPtr::RCPtr(const RCPtr &other) + : m_target(other.m_target) +{ + if (m_target) + m_target->IncRef(); +} + +template +inline PortabilityLayer::RCPtr::RCPtr(T *other) + : m_target(other) +{ + if (other) + other->IncRef(); +} + +#if IS_CPP11 +template +inline PortabilityLayer::RCPtr::RCPtr(RCPtr &&other) + : m_target(other.m_target) +{ + other.m_target = nullptr; +} +#endif + +template +inline PortabilityLayer::RCPtr::~RCPtr() +{ + if (m_target) + m_target->DecRef(); +} + +template +inline T *PortabilityLayer::RCPtr::operator T*() const +{ + return m_target; +} + +template +inline T *PortabilityLayer::RCPtr::operator->() const +{ + return m_target; +} + +template +inline PortabilityLayer::RCPtr::RCPtr &PortabilityLayer::RCPtr::operator=(T *other) +{ + RefCountedBase *old = m_target; + + m_target = other; + if (other) + other->IncRef(); + + if (old) + old->DecRef(); + + return *this; +} + +#if IS_CPP11 +template +inline PortabilityLayer::RCPtr& PortabilityLayer::RCPtr::RCPtr &operator=(RCPtr &&other) +{ + RefCountedBase *old = m_target; + RefCountedBase *newRC = other.m_target; + + other.m_target = nullptr; + + m_target = newRC; + if (newRC) + newRC->IncRef(); + + if (old) + old->DecRef(); + + return *this; +} +#endif diff --git a/PortabilityLayer/RandomNumberGenerator.cpp b/PortabilityLayer/RandomNumberGenerator.cpp new file mode 100644 index 0000000..1baf819 --- /dev/null +++ b/PortabilityLayer/RandomNumberGenerator.cpp @@ -0,0 +1,85 @@ +#include "RandomNumberGenerator.h" + +namespace PortabilityLayer +{ + class RandomNumberGeneratorMT19937 final : public RandomNumberGenerator + { + public: + RandomNumberGeneratorMT19937(); + + void Seed(uint32_t seed) override; + uint32_t GetNextAndAdvance() override; + + static RandomNumberGeneratorMT19937 *GetInstance(); + + private: + static const uint32_t kA = 0x9908b0df; + static const int kW = 32; + static const int kN = 624; + static const int kM = 397; + static const int kR = 31; + static const uint32_t kLowMask = (1 << kR) - 1; + static const uint32_t kHighMask = ~kLowMask; + + void Twist(); + + uint32_t m_state[kN]; + int m_index; + + static RandomNumberGeneratorMT19937 ms_instance; + }; + + RandomNumberGeneratorMT19937::RandomNumberGeneratorMT19937() + { + Seed(0x243F6A88); // First 8 hex digits of pi + } + + void RandomNumberGeneratorMT19937::Seed(uint32_t seed) + { + m_index = kN; + + m_state[0] = seed; + for (unsigned int i = 1; i < kN; i++) + { + const uint32_t prev = m_state[i - 1]; + m_state[i] = static_cast((static_cast(1812433253) * static_cast(prev ^ (prev >> 30)) + i) & 0xffffffff); + } + } + + uint32_t RandomNumberGeneratorMT19937::GetNextAndAdvance() + { + if (m_index == kN) + Twist(); + + uint32_t x = m_state[m_index++]; + x ^= (x >> 11); + x ^= (x >> 7) & 0x9d2c5680; + x ^= (x << 15) & 0xefc60000; + return x ^ (x >> 18); + } + + void RandomNumberGeneratorMT19937::Twist() + { + for (unsigned int i = 0; i < kN; i++) + { + uint32_t x = (m_state[i] & kHighMask) + (m_state[(i + 1) % kN] & kLowMask); + uint32_t xA = x >> 1; + if ((x & 1) == 1) + xA ^= kA; + m_state[i] = m_state[(i + kM) % kN] ^ kA; + } + m_index = 0; + } + + RandomNumberGeneratorMT19937 *RandomNumberGeneratorMT19937::GetInstance() + { + return &ms_instance; + } + + RandomNumberGeneratorMT19937 RandomNumberGeneratorMT19937::ms_instance; + + RandomNumberGenerator* RandomNumberGenerator::GetInstance() + { + return RandomNumberGeneratorMT19937::GetInstance(); + } +} diff --git a/PortabilityLayer/RandomNumberGenerator.h b/PortabilityLayer/RandomNumberGenerator.h new file mode 100644 index 0000000..36cacfb --- /dev/null +++ b/PortabilityLayer/RandomNumberGenerator.h @@ -0,0 +1,19 @@ +#pragma once +#ifndef __PL_RANDOM_NUMBER_GENERATOR_H__ +#define __PL_RANDOM_NUMBER_GENERATOR_H__ + +#include + +namespace PortabilityLayer +{ + class RandomNumberGenerator + { + public: + virtual void Seed(uint32_t seed) = 0; + virtual uint32_t GetNextAndAdvance() = 0; + + static RandomNumberGenerator *GetInstance(); + }; +} + +#endif diff --git a/PortabilityLayer/RefCounted.h b/PortabilityLayer/RefCounted.h new file mode 100644 index 0000000..acfc6bc --- /dev/null +++ b/PortabilityLayer/RefCounted.h @@ -0,0 +1,38 @@ +#pragma once + +namespace PortabilityLayer +{ + class RefCountedBase + { + public: + RefCountedBase(); + virtual ~RefCountedBase(); + virtual void Release() = 0; + + void IncRef(); + void DecRef(); + + private: + unsigned int m_refCount; + }; +} + +inline PortabilityLayer::RefCountedBase::RefCountedBase() + : m_refCount(0) +{ +} + +inline PortabilityLayer::RefCountedBase::~RefCountedBase() +{ +} + +inline void PortabilityLayer::RefCountedBase::IncRef() +{ + m_refCount++; +} + +inline void PortabilityLayer::RefCountedBase::DecRef() +{ + if (--m_refCount == 0) + this->Release(); +} diff --git a/PortabilityLayer/ResTypeID.h b/PortabilityLayer/ResTypeID.h new file mode 100644 index 0000000..36a1492 --- /dev/null +++ b/PortabilityLayer/ResTypeID.h @@ -0,0 +1,68 @@ +#pragma once +#ifndef __PL_RES_TYPE_ID_H__ +#define __PL_RES_TYPE_ID_H__ + +#include + +namespace PortabilityLayer +{ + class ResTypeID + { + public: + ResTypeID(); + ResTypeID(int32_t i); + ResTypeID(const ResTypeID &other); + explicit ResTypeID(const char *chars); + + ResTypeID &operator=(const ResTypeID &other); + bool operator==(const ResTypeID &other) const; + bool operator!=(const ResTypeID &other) const; + + private: + char m_id[4]; + }; +} + +#include "ResTypeIDCodec.h" +#include + +namespace PortabilityLayer +{ + inline ResTypeID::ResTypeID() + { + m_id[0] = m_id[1] = m_id[2] = m_id[3] = 0; + } + + inline ResTypeID::ResTypeID(int32_t i) + { + ResTypeIDCodec::Encode(i, m_id); + } + + inline ResTypeID::ResTypeID(const ResTypeID &other) + { + memcpy(m_id, other.m_id, 4); + } + + inline ResTypeID::ResTypeID(const char *chars) + { + memcpy(m_id, chars, 4); + } + + inline ResTypeID &ResTypeID::operator=(const ResTypeID &other) + { + memcpy(m_id, other.m_id, 4); + return *this; + } + + inline bool ResTypeID::operator==(const ResTypeID &other) const + { + return memcmp(m_id, other.m_id, 4) == 0; + } + + inline bool ResTypeID::operator!=(const ResTypeID &other) const + { + return memcmp(m_id, other.m_id, 4) != 0; + } +} + +#endif diff --git a/PortabilityLayer/ResTypeIDCodec.h b/PortabilityLayer/ResTypeIDCodec.h new file mode 100644 index 0000000..4cda1c3 --- /dev/null +++ b/PortabilityLayer/ResTypeIDCodec.h @@ -0,0 +1,70 @@ +#pragma once +#ifndef __PL_RES_TYPE_ID_CODEC_H__ +#define __PL_RES_TYPE_ID_CODEC_H__ + +#include + +namespace PortabilityLayer +{ + template + class ResTypeIDCodecResolver + { + }; + + template<> + class ResTypeIDCodecResolver<0x64636261> + { + public: + static void Encode(int32_t id, char *chars); + static int32_t Decode(char *chars); + }; + + template<> + class ResTypeIDCodecResolver<0x61626364> + { + public: + static void Encode(int32_t id, char *chars); + static int32_t Decode(char *chars); + }; + + typedef ResTypeIDCodecResolver<'abcd'> ResTypeIDCodec; +} + +namespace PortabilityLayer +{ + inline void ResTypeIDCodecResolver<0x64636261>::Encode(int32_t id, char *chars) + { + chars[0] = static_cast((id >> 0) & 0xff); + chars[1] = static_cast((id >> 8) & 0xff); + chars[2] = static_cast((id >> 16) & 0xff); + chars[3] = static_cast((id >> 24) & 0xff); + } + + inline int32_t ResTypeIDCodecResolver<0x64636261>::Decode(char *chars) + { + return static_cast( + ((chars[0] & 0xff) << 0) + | ((chars[1] & 0xff) << 8) + | ((chars[2] & 0xff) << 16) + | ((chars[3] & 0xff) << 24)); + } + + inline void ResTypeIDCodecResolver<0x61626364>::Encode(int32_t id, char *chars) + { + chars[0] = static_cast((id >> 24) & 0xff); + chars[1] = static_cast((id >> 16) & 0xff); + chars[2] = static_cast((id >> 8) & 0xff); + chars[3] = static_cast((id >> 0) & 0xff); + } + + inline int32_t ResTypeIDCodecResolver<0x61626364>::Decode(char *chars) + { + return static_cast( + ((chars[0] & 0xff) << 24) + | ((chars[1] & 0xff) << 16) + | ((chars[2] & 0xff) << 8) + | ((chars[3] & 0xff) << 0)); + } +} + +#endif diff --git a/PortabilityLayer/ResourceCompiledRef.cpp b/PortabilityLayer/ResourceCompiledRef.cpp new file mode 100644 index 0000000..ea3be2a --- /dev/null +++ b/PortabilityLayer/ResourceCompiledRef.cpp @@ -0,0 +1,17 @@ +#include "ResourceCompiledRef.h" +#include "ByteSwap.h" + +#include + +namespace PortabilityLayer +{ + uint32_t ResourceCompiledRef::GetSize() const + { + uint32_t resSize; + memcpy(&resSize, m_resData - 4, 4); + + ByteSwap::BigUInt32(resSize); + + return resSize; + } +} \ No newline at end of file diff --git a/PortabilityLayer/ResourceCompiledRef.h b/PortabilityLayer/ResourceCompiledRef.h new file mode 100644 index 0000000..37ad954 --- /dev/null +++ b/PortabilityLayer/ResourceCompiledRef.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +namespace PortabilityLayer +{ + struct MMHandleBlock; + + struct ResourceCompiledRef + { + const uint8_t *m_resData; + MMHandleBlock *m_handle; + int16_t m_resID; + int16_t m_resNameOffset; + uint8_t m_attributes; + + uint32_t GetSize() const; + }; +} diff --git a/PortabilityLayer/ResourceFile.cpp b/PortabilityLayer/ResourceFile.cpp new file mode 100644 index 0000000..0df4ed7 --- /dev/null +++ b/PortabilityLayer/ResourceFile.cpp @@ -0,0 +1,375 @@ +#include "ResourceFile.h" +#include "BinarySearch.h" +#include "ByteSwap.h" +#include "MacFileMem.h" +#include "MemoryManager.h" +#include "MemReaderStream.h" +#include "ResourceCompiledRef.h" + +#include + +namespace PortabilityLayer +{ + ResourceFile::ResourceFile() + : m_resDataBlob(nullptr) + , m_resDataBlobSize(0) + , m_resNameBlob(nullptr) + , m_resNameBlobSize(0) + , m_compiledRefBlob(nullptr) + , m_numResources(0) + , m_compiledTypeListBlob(nullptr) + , m_numResourceTypes(0) + { + } + + ResourceFile::~ResourceFile() + { + if (m_resNameBlob) + delete[] m_resNameBlob; + + if (m_resDataBlob) + delete[] m_resDataBlob; + + if (m_compiledRefBlob) + delete[] m_compiledRefBlob; + + if (m_compiledTypeListBlob) + delete[] m_compiledTypeListBlob; + } + + bool ResourceFile::Load(IOStream *stream) + { + struct ResourceHeader + { + uint32_t m_resDataOffset; + uint32_t m_resMapOffset; + uint32_t m_resDataSize; + uint32_t m_resMapSize; + }; + + const UFilePos_t streamSize = stream->Size(); + if (streamSize > UINT32_MAX) + return false; + + uint32_t resForkSize = static_cast(streamSize); + + ResourceHeader resourceHeader; + + if (stream->Read(&resourceHeader, sizeof(ResourceHeader)) != sizeof(ResourceHeader)) + return false; + + ByteSwap::BigUInt32(resourceHeader.m_resDataOffset); + ByteSwap::BigUInt32(resourceHeader.m_resMapOffset); + ByteSwap::BigUInt32(resourceHeader.m_resDataSize); + ByteSwap::BigUInt32(resourceHeader.m_resMapSize); + + if (resourceHeader.m_resDataOffset > resForkSize) + return false; + + if (resourceHeader.m_resMapOffset > resForkSize) + return false; + + if (resForkSize - resourceHeader.m_resDataOffset < resourceHeader.m_resDataSize) + return false; + + if (resForkSize - resourceHeader.m_resMapOffset < resourceHeader.m_resMapSize) + return false; + + if (!stream->SeekStart(resourceHeader.m_resDataOffset)) + return false; + + m_resDataBlob = new uint8_t[resourceHeader.m_resDataSize]; + m_resDataBlobSize = resourceHeader.m_resDataSize; + + if (stream->Read(m_resDataBlob, resourceHeader.m_resDataSize) != resourceHeader.m_resDataSize) + return false; + + // The format of this is slightly different from the documented format: + // The type list offset is the offset of the type COUNT, which takes up 2 bytes. + // Usually the offset is 28, even though the size of the resource map including the + // count would appear to be 30. + + struct ResourceMap + { + uint8_t m_reserved[16 + 4 + 2]; + uint16_t m_attributes; + uint16_t m_typeListOffset; + uint16_t m_nameListOffset; + }; + + struct ResourceTypeListEntry + { + ResTypeID m_resType; + uint16_t m_numResourcesMinusOne; + uint16_t m_refListOffset; + }; + + struct ResourceRefListEntry + { + int16_t m_resID; + int16_t m_resourceNameOffset; + uint8_t m_attributes; + uint8_t m_packedResDataOffset[3]; + uint32_t m_reserved; + }; + + if (!stream->SeekStart(resourceHeader.m_resMapOffset)) + return false; + + ResourceMap resourceMap; + if (stream->Read(&resourceMap, sizeof(ResourceMap)) != sizeof(ResourceMap)) + return false; + + ByteSwap::BigUInt16(resourceMap.m_attributes); + ByteSwap::BigUInt16(resourceMap.m_typeListOffset); + ByteSwap::BigUInt16(resourceMap.m_nameListOffset); + + const size_t sizeFromStartOfResMap = resForkSize - resourceHeader.m_resMapOffset; + if (resourceMap.m_typeListOffset > sizeFromStartOfResMap) + return false; + + if (resourceMap.m_nameListOffset > sizeFromStartOfResMap) + return false; + + const size_t typeListOffset = resourceHeader.m_resMapOffset + resourceMap.m_typeListOffset; + const size_t sizeFromStartOfTypeList = resForkSize - typeListOffset; + + // First pass: Count the number of references we need + if (!stream->SeekStart(typeListOffset)) + return false; + + uint16_t numTypesMinusOne; + if (stream->Read(&numTypesMinusOne, 2) != 2) + return false; + ByteSwap::BigUInt16(numTypesMinusOne); + + m_numResourceTypes = numTypesMinusOne + 1; + + if (sizeFromStartOfTypeList < 2 || (sizeFromStartOfTypeList - 2) / 8 < m_numResourceTypes) + return false; + + uint32_t numResourcesTotal = 0; + + for (uint32_t i = 0; i < m_numResourceTypes; i++) + { + ResourceTypeListEntry tlEntry; + if (stream->Read(&tlEntry, sizeof(ResourceTypeListEntry)) != sizeof(ResourceTypeListEntry)) + return false; + + ByteSwap::BigUInt16(tlEntry.m_numResourcesMinusOne); + + const uint32_t numResourcesOfThisType = tlEntry.m_numResourcesMinusOne + 1; + + if (UINT32_MAX - numResourcesTotal < numResourcesOfThisType) + return false; + + numResourcesTotal += numResourcesOfThisType; + } + + m_compiledRefBlob = new ResourceCompiledRef[numResourcesTotal]; + m_numResources = numResourcesTotal; + + // Second pass: Compile references + ResourceCompiledRef *refToCompile = m_compiledRefBlob; + + m_compiledTypeListBlob = new CompiledTypeList[m_numResourceTypes]; + + for (uint32_t i = 0; i < m_numResourceTypes; i++) + { + if (!stream->SeekStart(typeListOffset + 2 + i * 8)) + return false; + + ResourceTypeListEntry tlEntry; + if (stream->Read(&tlEntry, sizeof(ResourceTypeListEntry)) != sizeof(ResourceTypeListEntry)) + return false; + + ByteSwap::BigUInt16(tlEntry.m_numResourcesMinusOne); + ByteSwap::BigUInt16(tlEntry.m_refListOffset); + + CompiledTypeList &ctl = m_compiledTypeListBlob[i]; + ctl.m_resType = tlEntry.m_resType; + ctl.m_firstRef = refToCompile; + ctl.m_numRefs = tlEntry.m_numResourcesMinusOne + 1; + + if (sizeFromStartOfTypeList < tlEntry.m_refListOffset) + return false; + + // Start reading the ref list + if (!stream->SeekStart(typeListOffset + tlEntry.m_refListOffset)) + return false; + + const uint32_t numResourcesOfThisType = tlEntry.m_numResourcesMinusOne + 1; + + ResourceCompiledRef *firstRefOfThisType = refToCompile; + + for (uint32_t i = 0; i < numResourcesOfThisType; i++) + { + ResourceRefListEntry refListEntry; + if (stream->Read(&refListEntry, sizeof(ResourceRefListEntry)) != sizeof(ResourceRefListEntry)) + return false; + + ByteSwap::BigInt16(refListEntry.m_resID); + ByteSwap::BigInt16(refListEntry.m_resourceNameOffset); + + const uint8_t *packedOffset = refListEntry.m_packedResDataOffset; + + const size_t dataSizeOffset = (packedOffset[0] << 16) + (packedOffset[1] << 8) + packedOffset[2]; + + if (dataSizeOffset > resourceHeader.m_resDataSize) + return false; + + // Needs to be at least size 4 to decode the resource size + if (resourceHeader.m_resDataSize - dataSizeOffset < 4) + return false; + + const size_t dataOffset = dataSizeOffset + 4; + + refToCompile->m_attributes = refListEntry.m_attributes; + refToCompile->m_resData = m_resDataBlob + dataOffset; + refToCompile->m_resID = refListEntry.m_resID; + refToCompile->m_resNameOffset = refListEntry.m_resourceNameOffset; + refToCompile->m_handle = nullptr; + + uint32_t resSize; + memcpy(&resSize, m_resDataBlob + dataSizeOffset, 4); + + ByteSwap::BigUInt32(resSize); + + if (resSize > resourceHeader.m_resDataSize) + return false; + + if (resourceHeader.m_resDataSize - resSize < dataOffset) + return false; + + refToCompile++; + } + + std::sort(firstRefOfThisType, refToCompile, CompiledRefSortPredicate); + + for (uint32_t i = 1; i < numResourcesOfThisType; i++) + { + if (firstRefOfThisType[i - 1].m_resID == firstRefOfThisType[i].m_resID) + return false; + } + } + + if (m_numResources > 0) + { + bool anyNamed = false; + + size_t lastNameStart = 0; + for (size_t i = 0; i < m_numResources; i++) + { + const ResourceCompiledRef &ref = m_compiledRefBlob[i]; + if (ref.m_resNameOffset < 0) + { + if (ref.m_resNameOffset != -1) + return false; // Non-compliant + } + else + { + anyNamed = true; + + const size_t candidateOffset = static_cast(ref.m_resNameOffset); + if (candidateOffset > lastNameStart) + lastNameStart = candidateOffset; + } + } + + if (anyNamed) + { + const size_t nameListCapacity = sizeFromStartOfResMap - resourceMap.m_nameListOffset; + if (lastNameStart >= nameListCapacity) + return false; + + m_resNameBlobSize = lastNameStart + 1 + 256; + m_resNameBlob = new uint8_t[m_resNameBlobSize]; + memset(m_resNameBlob, 0, m_resNameBlobSize); + + if (!stream->SeekStart(resourceHeader.m_resMapOffset + resourceMap.m_nameListOffset)) + return false; + + if (stream->Read(m_resNameBlob, lastNameStart + 1) != lastNameStart + 1) + return false; + + // Figure out the length of the final string + const size_t lastStringLength = m_resNameBlob[lastNameStart]; + if (lastStringLength > 0) + { + if (stream->Read(m_resNameBlob + lastNameStart + 1, lastStringLength) != lastStringLength) + return false; + } + } + } + + std::sort(m_compiledTypeListBlob, m_compiledTypeListBlob + m_numResourceTypes, CompiledTypeListSortPredicate); + + for (uint32_t i = 1; i < m_numResourceTypes; i++) + { + if (m_compiledTypeListBlob[i - 1].m_resType == m_compiledTypeListBlob[i].m_resType) + return false; + } + + return true; + } + + bool ResourceFile::CompiledRefSortPredicate(const ResourceCompiledRef &a, const ResourceCompiledRef &b) + { + return a.m_resID < b.m_resID; + } + + bool ResourceFile::CompiledTypeListSortPredicate(const CompiledTypeList &a, const CompiledTypeList &b) + { + return memcmp(&a.m_resType, &b.m_resType, sizeof(ResTypeID)) < 0; + } + + int ResourceFile::CompiledRefSearchPredicate(int resID, const ResourceCompiledRef &ref) + { + return resID - ref.m_resID; + } + + int ResourceFile::CompiledTypeListSearchPredicate(const ResTypeID &resTypeID, const CompiledTypeList &typeList) + { + return memcmp(&resTypeID, &typeList.m_resType, 4); + } + + MMHandleBlock *ResourceFile::GetResource(const ResTypeID &resType, int id, bool load) + { + const CompiledTypeList *tlStart = m_compiledTypeListBlob; + const CompiledTypeList *tlEnd = tlStart + m_numResourceTypes; + + const CompiledTypeList *tl = BinarySearch(tlStart, tlEnd, resType, CompiledTypeListSearchPredicate); + if (tl == tlEnd) + return nullptr; + + ResourceCompiledRef *refStart = tl->m_firstRef; + ResourceCompiledRef *refEnd = refStart + tl->m_numRefs; + ResourceCompiledRef *ref = BinarySearch(refStart, refEnd, id, CompiledRefSearchPredicate); + + if (ref == refEnd) + return nullptr; + + MMHandleBlock *handle = nullptr; + if (ref->m_handle != nullptr) + handle = ref->m_handle; + else + { + handle = MemoryManager::GetInstance()->AllocHandle(0); + handle->m_rmSelfRef = ref; + ref->m_handle = handle; + } + + if (handle->m_contents == nullptr && load) + { + const uint32_t resSize = ref->GetSize(); + if (resSize > 0) + { + void *contents = MemoryManager::GetInstance()->Alloc(resSize); + handle->m_contents = contents; + memcpy(handle->m_contents, ref->m_resData, resSize); + } + } + + return handle; + } +} diff --git a/PortabilityLayer/ResourceFile.h b/PortabilityLayer/ResourceFile.h new file mode 100644 index 0000000..198f870 --- /dev/null +++ b/PortabilityLayer/ResourceFile.h @@ -0,0 +1,54 @@ +#pragma once +#ifndef __PL_RESOURCE_FILE_H__ +#define __PL_RESOURCE_FILE_H__ + +#include "ResTypeID.h" +#include + +namespace PortabilityLayer +{ + class IOStream; + class MacFileMem; + struct MMHandleBlock; + struct ResourceCompiledRef; + class ResTypeID; + + class ResourceFile + { + public: + ResourceFile(); + ~ResourceFile(); + + bool Load(IOStream *stream); + + MMHandleBlock *GetResource(const ResTypeID &resType, int id, bool load); + + private: + struct CompiledTypeList + { + ResTypeID m_resType; + ResourceCompiledRef *m_firstRef; + size_t m_numRefs; + }; + + uint8_t *m_resDataBlob; + size_t m_resDataBlobSize; + + uint8_t *m_resNameBlob; + size_t m_resNameBlobSize; + + ResourceCompiledRef *m_compiledRefBlob; + size_t m_numResources; + + CompiledTypeList *m_compiledTypeListBlob; + size_t m_numResourceTypes; + + static bool CompiledRefSortPredicate(const ResourceCompiledRef &a, const ResourceCompiledRef &b); + static bool CompiledTypeListSortPredicate(const CompiledTypeList &a, const CompiledTypeList &b); + + static int CompiledRefSearchPredicate(int resID, const ResourceCompiledRef &ref); + static int CompiledTypeListSearchPredicate(const ResTypeID &resTypeID, const CompiledTypeList &typeList); + }; +} + +#endif diff --git a/PortabilityLayer/ResourceManager.h b/PortabilityLayer/ResourceManager.h new file mode 100644 index 0000000..76899cd --- /dev/null +++ b/PortabilityLayer/ResourceManager.h @@ -0,0 +1,28 @@ +#pragma once + +#include "VirtualDirectory.h" + +class PLPasStr; + +namespace PortabilityLayer +{ + struct MMHandleBlock; + class ResTypeID; + + class ResourceManager + { + public: + virtual void Init() = 0; + virtual void Shutdown() = 0; + + virtual void SetResLoad(bool load) = 0; + + virtual short OpenResFork(EVirtualDirectory virtualDir, const PLPasStr &filename) = 0; + virtual MMHandleBlock *GetResource(const ResTypeID &resType, int id) = 0; + + virtual short GetCurrentResFile() const = 0; + virtual void SetCurrentResFile(short ref) = 0; + + static ResourceManager *GetInstance(); + }; +} diff --git a/PortabilityLayer/ScopedArray.h b/PortabilityLayer/ScopedArray.h new file mode 100644 index 0000000..3dfc9da --- /dev/null +++ b/PortabilityLayer/ScopedArray.h @@ -0,0 +1,83 @@ +#pragma once + +#ifndef __PL_SCOPEDARRAY_H__ +#define __PL_SCOPEDARRAY_H__ + +#include "CoreDefs.h" + +namespace PortabilityLayer +{ + template + class ScopedArray + { + public: + ScopedArray(); + ScopedArray(T *ref); + ~ScopedArray(); + + void Swap(ScopedArray &other); + + operator T*(); + operator const T*() const; + + void Set(T *ref); + + private: + ScopedArray(const ScopedArray &other) PL_DELETED; + void operator=(const ScopedArray &other) PL_DELETED; + T *m_ref; + }; +} + +namespace PortabilityLayer +{ + template + inline ScopedArray::ScopedArray() + : m_ref(nullptr) + { + } + + template + inline ScopedArray::ScopedArray(T *ref) + : m_ref(ref) + { + } + + template + inline ScopedArray::~ScopedArray() + { + if (m_ref) + delete[] m_ref; + } + + template + inline void ScopedArray::Swap(ScopedArray &other) + { + T *temp = m_ref; + m_ref = other.m_ref; + other.m_ref = temp; + } + + template + inline ScopedArray::operator T*() + { + return m_ref; + } + + template + inline ScopedArray::operator const T*() const + { + return m_ref; + } + + template + inline void ScopedArray::Set(T *ref) + { + if (m_ref && m_ref != ref) + delete m_ref; + + m_ref = ref; + } +} + +#endif diff --git a/PortabilityLayer/ScopedPtr.h b/PortabilityLayer/ScopedPtr.h new file mode 100644 index 0000000..934ef10 --- /dev/null +++ b/PortabilityLayer/ScopedPtr.h @@ -0,0 +1,97 @@ +#pragma once + +#ifndef __PL_SCOPEDPTR_H__ +#define __PL_SCOPEDPTR_H__ + +#include "CoreDefs.h" + +namespace PortabilityLayer +{ + template + class ScopedPtr + { + public: + ScopedPtr(); + ScopedPtr(T *ref); + ~ScopedPtr(); + + void Swap(ScopedPtr &other); + + operator T*(); + operator const T*() const; + T *operator->(); + const T *operator->() const; + + void Set(T *ref); + + private: + ScopedPtr(const ScopedPtr &other) PL_DELETED; + void operator=(const ScopedPtr &other) PL_DELETED; + T *m_ref; + }; +} + +namespace PortabilityLayer +{ + template + inline ScopedPtr::ScopedPtr() + : m_ref(nullptr) + { + } + + template + inline ScopedPtr::ScopedPtr(T *ref) + : m_ref(ref) + { + } + + template + inline ScopedPtr::~ScopedPtr() + { + if (m_ref) + delete m_ref; + } + + template + inline void ScopedPtr::Swap(ScopedPtr &other) + { + T *temp = m_ref; + m_ref = other.m_ref; + other.m_ref = temp; + } + + template + inline ScopedPtr::operator T*() + { + return m_ref; + } + + template + inline ScopedPtr::operator const T*() const + { + return m_ref; + } + + template + inline T *ScopedPtr::operator->() + { + return m_ref; + } + + template + inline const T *ScopedPtr::operator->() const + { + return m_ref; + } + + template + inline void ScopedPtr::Set(T *ref) + { + if (m_ref && m_ref != ref) + delete m_ref; + + m_ref = ref; + } +} + +#endif diff --git a/PortabilityLayer/SmallestInt.h b/PortabilityLayer/SmallestInt.h new file mode 100644 index 0000000..3bee75e --- /dev/null +++ b/PortabilityLayer/SmallestInt.h @@ -0,0 +1,100 @@ +#pragma once + +#ifndef __PL_SMALLESTINT_H__ +#define __PL_SMALLESTINT_H__ + +#include "DataTypes.h" + +namespace PortabilityLayer +{ + namespace Internal_SmallestInt + { + template + class SmallestIntSignedResolver + { + }; + + template + class SmallestIntUnsignedResolver + { + }; + + template<> + class SmallestIntSignedResolver<1, 1, 1, 1> + { + public: + typedef int8_t ValueType_t; + }; + + template<> + class SmallestIntSignedResolver<0, 1, 1, 1> + { + public: + typedef int16_t ValueType_t; + }; + + template<> + class SmallestIntSignedResolver<0, 0, 1, 1> + { + public: + typedef int32_t ValueType_t; + }; + + template<> + class SmallestIntSignedResolver<0, 0, 0, 1> + { + public: + typedef int64_t ValueType_t; + }; + + template<> + class SmallestIntUnsignedResolver<1, 1, 1, 1> + { + public: + typedef uint8_t ValueType_t; + }; + + template<> + class SmallestIntUnsignedResolver<0, 1, 1, 1> + { + public: + typedef uint16_t ValueType_t; + }; + + template<> + class SmallestIntUnsignedResolver<0, 0, 1, 1> + { + public: + typedef uint32_t ValueType_t; + }; + + template<> + class SmallestIntUnsignedResolver<0, 0, 0, 1> + { + public: + typedef uint64_t ValueType_t; + }; + } + + template + struct SmallestInt + { + typedef typename Internal_SmallestInt::SmallestIntSignedResolver< + TValue >= -128 && TValue <= 127, + TValue >= -32768 && TValue <= 32767, + TValue >= -2147483648LL && TValue <= 2147483647LL, + 1>::ValueType_t ValueType_t; + }; + + template + struct SmallestUInt + { + typedef typename Internal_SmallestInt::SmallestIntUnsignedResolver< + TValue <= 256, + TValue <= 65536, + TValue <= 4294967295, + 1>::ValueType_t ValueType_t; + }; +} + +#endif diff --git a/PortabilityLayer/UnsafePascalStr.h b/PortabilityLayer/UnsafePascalStr.h new file mode 100644 index 0000000..bcdab92 --- /dev/null +++ b/PortabilityLayer/UnsafePascalStr.h @@ -0,0 +1,90 @@ +#pragma once + +#ifndef __PL_UNSAFEPASCALSTR_H__ +#define __PL_UNSAFEPASCALSTR_H__ + +#include "DataTypes.h" +#include "SmallestInt.h" + +namespace PortabilityLayer +{ + template + class UnsafePascalStr + { + public: + UnsafePascalStr(); + UnsafePascalStr(size_t size, const char *str); + + char &operator[](size_t index); + const char &operator[](size_t index) const; + void Set(size_t size, const char *str); + void SetLength(size_t size); + size_t Length() const; + + private: + char m_chars[TSize + (TCStr ? 1 : 0)]; + typename SmallestUInt::ValueType_t m_size; + }; +} + +#include +#include + +namespace PortabilityLayer +{ + template + inline UnsafePascalStr::UnsafePascalStr(size_t size, const char *str) + : m_size(static_cast::ValueType_t>(size)) + { + assert(size <= TSize); + + if (size) + memcpy(m_chars, str, size); + + if (TCStr) + m_chars[size] = '\0'; + } + + template + inline char &UnsafePascalStr::operator[](size_t index) + { + assert(index < m_size); + return m_chars[index]; + } + + template + inline const char &UnsafePascalStr::operator[](size_t index) const + { + assert(index < m_size); + return m_chars[index]; + } + + template + inline void UnsafePascalStr::Set(size_t size, const char *str) + { + assert(size <= TSize); + + memcpy(m_chars, str, size); + m_size = static_cast::ValueType_t>(size); + + if (TCStr) + m_chars[size] = '\0'; + } + + template + inline void UnsafePascalStr::SetLength(size_t size) + { + assert(size <= TSize); + + if (TCStr) + m_chars[size] = '\0'; + } + + template + inline size_t UnsafePascalStr::Length() const + { + return m_size; + } +} + +#endif diff --git a/PortabilityLayer/VirtualDirectory.h b/PortabilityLayer/VirtualDirectory.h new file mode 100644 index 0000000..ec7f156 --- /dev/null +++ b/PortabilityLayer/VirtualDirectory.h @@ -0,0 +1,15 @@ +#pragma once +#ifndef __PL_VIRTUALDIRECTORY_H__ +#define __PL_VIRTUALDIRECTORY_H__ + +namespace PortabilityLayer +{ + enum EVirtualDirectory + { + EVirtualDirectory_ApplicationData = 1, + EVirtualDirectory_GameData, + EVirtualDirectory_Prefs, + }; +} + +#endif diff --git a/PortabilityLayer/XModemCRC.cpp b/PortabilityLayer/XModemCRC.cpp new file mode 100644 index 0000000..8c66e20 --- /dev/null +++ b/PortabilityLayer/XModemCRC.cpp @@ -0,0 +1,54 @@ +#include "XModemCRC.h" + +namespace +{ + static const uint16_t gs_crcTable[256] = + { + 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7, + 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef, + 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6, + 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de, + 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485, + 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d, + 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4, + 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc, + 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823, + 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b, + 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12, + 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a, + 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41, + 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49, + 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70, + 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78, + 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f, + 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067, + 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e, + 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256, + 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d, + 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405, + 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c, + 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634, + 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab, + 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3, + 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a, + 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92, + 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9, + 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1, + 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8, + 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0, + }; +} + +uint16_t PortabilityLayer::XModemCRC(const void *bytes, size_t size, uint16_t initialValue) +{ + const uint8_t *bytesU8 = static_cast(bytes); + int crc = initialValue; + + for (size_t i = 0; i < size; i++) + { + crc ^= (bytesU8[i] << 8); + crc = static_cast(((crc << 8) ^ gs_crcTable[crc >> 8]) & 0xffff); + } + + return static_cast(crc); +} diff --git a/PortabilityLayer/XModemCRC.h b/PortabilityLayer/XModemCRC.h new file mode 100644 index 0000000..e34708c --- /dev/null +++ b/PortabilityLayer/XModemCRC.h @@ -0,0 +1,13 @@ +#pragma once + +#ifndef __PL_XMODEMCRC_H__ +#define __PL_XMODEMCRC_H__ + +#include "DataTypes.h" + +namespace PortabilityLayer +{ + uint16_t XModemCRC(const void *bytes, size_t size, uint16_t initialValue); +} + +#endif diff --git a/PortabilityLayer/x64/Debug/PortabilityLayer.idb b/PortabilityLayer/x64/Debug/PortabilityLayer.idb new file mode 100644 index 0000000..30308f0 Binary files /dev/null and b/PortabilityLayer/x64/Debug/PortabilityLayer.idb differ diff --git a/Sources/About.c b/Sources/About.c deleted file mode 100755 index 37ea79e..0000000 --- a/Sources/About.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // About.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include "About.h" #include "DialogUtils.h" #include "Environ.h" #include "Externs.h" static void HiLiteOkayButton (void); static void UnHiLiteOkayButton (void); static void UpdateMainPict (DialogPtr); static pascal Boolean AboutFilter (DialogPtr, EventRecord *theEvent, short *hit); static RgnHandle okayButtRgn; static Rect okayButtonBounds, mainPICTBounds; static Boolean okayButtIsHiLit, clickedDownInOkay; //============================================================== Functions //-------------------------------------------------------------- DoAbout // Brings up the About dialog box. void DoAbout (void) { #define kAboutDialogID 150 // res ID of About dialog #define kTextItemVers 2 // item number of version text #define kPictItemMain 4 // item number of main PICT DialogPtr aboutDialog; Str255 longVersion; StringPtr messagePtr; VersRecHndl version; Handle itemHandle; short itemType, hit, wasResFile; ModalFilterUPP aboutFilterUPP; aboutFilterUPP = NewModalFilterUPP(AboutFilter); wasResFile = CurResFile(); UseResFile(thisMac.thisResFile); aboutDialog = GetNewDialog(kAboutDialogID, nil, (WindowRef)-1L); // if (aboutDialog == nil) // RedAlert(kErrDialogDidntLoad); version = (VersRecHndl)GetResource('vers', 1); if (version != nil) { messagePtr = (StringPtr)(((UInt32)&(**version).shortVersion[1]) + ((**version).shortVersion[0])); BlockMove((Ptr)messagePtr, &longVersion, ((UInt8)*messagePtr) + 1); SetDialogString(aboutDialog, kTextItemVers, longVersion); } GetDialogItem(aboutDialog, kOkayButton, &itemType, &itemHandle, &okayButtonBounds); okayButtRgn = NewRgn(); // Create diagonal button region OpenRgn(); MoveTo(okayButtonBounds.left + 1, okayButtonBounds.top + 45); Line(44, -44); // These lines define the region Line(16, 16); Line(-44, 44); Line(-16, -16); CloseRgn(okayButtRgn); okayButtIsHiLit = false; // Initially, button is not hilit clickedDownInOkay = false; // Initially, didn't click in okay button GetDialogItem(aboutDialog, kPictItemMain, &itemType, &itemHandle, &mainPICTBounds); do // Loop until user wants to exit { ModalDialog(aboutFilterUPP, &hit); } while ((hit != kOkayButton) && (okayButtRgn != nil)); if (okayButtRgn != nil) DisposeRgn(okayButtRgn); // Clean up! DisposeDialog(aboutDialog); DisposeModalFilterUPP(aboutFilterUPP); UseResFile(wasResFile); } //============================================================== Static Functions //-------------------------------------------------------------- HiLiteOkayButton // Draws my pseudo-button to appear as though it is clicked on. static void HiLiteOkayButton (void) { #define kOkayButtPICTHiLit 151 // res ID of unhilit button PICT PicHandle thePict; if (!okayButtIsHiLit) { thePict = GetPicture(kOkayButtPICTHiLit); if (thePict != nil) { DrawPicture(thePict, &okayButtonBounds); ReleaseResource((Handle)thePict); okayButtIsHiLit = true; } } } //-------------------------------------------------------------- UnHiLiteOkayButton // Draws my pseudo-button normal (not clicked on). static void UnHiLiteOkayButton (void) { #define kOkayButtPICTNotHiLit 150 // res ID of hilit button PICT PicHandle thePict; if (okayButtIsHiLit) { thePict = GetPicture(kOkayButtPICTNotHiLit); if (thePict != nil) { DrawPicture(thePict, &okayButtonBounds); ReleaseResource((Handle)thePict); okayButtIsHiLit = false; } } } //-------------------------------------------------------------- UpdateMainPict // Redraws the main graphic in the dialog (in response to an update event). static void UpdateMainPict (DialogPtr theDial) { Str255 theStr, theStr2; long totalSize, contigSize; DrawDialog(theDial); PasStringCopy("\pMemory: ", theStr); // display free memory PurgeSpace(&totalSize, &contigSize); totalSize /= 1024; NumToString(totalSize, theStr2); PasStringConcat(theStr, theStr2); PasStringConcat(theStr, "\pK"); DrawDialogUserText2(theDial, 7, theStr); PasStringCopy("\pScreen: ", theStr); // display screen size/depth NumToString((long)(thisMac.screen.right - thisMac.screen.left), theStr2); PasStringConcat(theStr, theStr2); PasStringConcat(theStr, "\px"); NumToString((long)(thisMac.screen.bottom - thisMac.screen.top), theStr2); PasStringConcat(theStr, theStr2); PasStringConcat(theStr, "\px"); NumToString((long)thisMac.isDepth, theStr2); PasStringConcat(theStr, theStr2); DrawDialogUserText2(theDial, 8, theStr); } //-------------------------------------------------------------- AboutFilter // Dialog filter for the About dialog. static pascal Boolean AboutFilter (DialogPtr theDial, EventRecord *theEvent, short *hit) { Point mousePt; UInt32 dummyLong; Boolean handledIt; if (Button() && clickedDownInOkay) { GetMouse(&mousePt); if(PtInRgn(mousePt, okayButtRgn)) HiLiteOkayButton(); else UnHiLiteOkayButton(); } switch (theEvent->what) { case keyDown: switch ((theEvent->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: HiLiteOkayButton(); Delay(8, &dummyLong); UnHiLiteOkayButton(); *hit = kOkayButton; handledIt = true; break; default: handledIt = false; } break; case mouseDown: mousePt = theEvent->where; GlobalToLocal(&mousePt); if(PtInRgn(mousePt, okayButtRgn)) { clickedDownInOkay = true; handledIt = false; } else handledIt = false; break; case mouseUp: mousePt = theEvent->where; GlobalToLocal(&mousePt); if(PtInRgn(mousePt, okayButtRgn) && clickedDownInOkay) { UnHiLiteOkayButton(); *hit = kOkayButton; handledIt = true; } else { clickedDownInOkay = false; handledIt = false; } break; case updateEvt: if ((WindowPtr)theEvent->message == mainWindow) { SetPort((GrafPtr)mainWindow); BeginUpdate((WindowPtr)theEvent->message); UpdateMainWindow(); EndUpdate((WindowPtr)theEvent->message); SetPortDialogPort(theDial); handledIt = true; } else if ((WindowPtr)theEvent->message == (WindowPtr)theDial) { SetPortDialogPort(theDial); BeginUpdate((WindowPtr)theEvent->message); UpdateMainPict(theDial); EndUpdate((WindowPtr)theEvent->message); handledIt = false; } break; default: handledIt = false; break; } return (handledIt); } \ No newline at end of file diff --git a/Sources/AnimCursor.c b/Sources/AnimCursor.c deleted file mode 100755 index 102d1b8..0000000 --- a/Sources/AnimCursor.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // AnimCursor.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "Environ.h" #define rAcurID 128 #define rHandCursorID 1000 typedef struct { short n; short index; union { Handle cursorHdl; short resID; } frame[1]; } acurRec, *acurPtr, **acurHandle; Boolean GetMonoCursors (acurHandle); Boolean GetColorCursors (acurHandle); void InitAnimatedCursor (acurHandle); acurHandle animCursorH = nil; Boolean useColorCursor = false; //============================================================== Functions //-------------------------------------------------------------- GetMonoCursors // Loads b&w cursors (for animated beach ball). Boolean GetMonoCursors (acurHandle ballCursH) { short i, j; CursHandle cursHdl; if (ballCursH) // Were we passed a legit acur handle? { j = (*ballCursH)->n; // Get number of 'frames' in the acur for (i = 0; i < j; i++) // Start walking the frames { cursHdl = GetCursor((*ballCursH)->frame[i].resID); if (cursHdl == nil) // Did the cursor load? It didn't?... { // Well then, toss what we got. for (j = 0; j < i; j++) DisposeHandle((*ballCursH)->frame[j].cursorHdl); return(false); // And report this to mother. } // However!... else // If cursor loaded ok... { // Detach it from the resource map... DetachResource((Handle)cursHdl); // And assign to our struct (*ballCursH)->frame[i].cursorHdl = (Handle)cursHdl; } } } return(true); } //-------------------------------------------------------------- GetColorCursors // Loads color cursors (for animated beach ball). Boolean GetColorCursors (acurHandle ballCursH) { short i, j; CCrsrHandle cursHdl; Boolean result = true; if (ballCursH) { j = (*ballCursH)->n; // Get the number of cursors HideCursor(); // Hide the cursor for (i = 0; i < j; i++) // Walk through the acur resource { cursHdl = GetCCursor((*ballCursH)->frame[i].resID); // Get the cursor if (cursHdl == nil) // Make sure a real cursor was returned { // If not, trash all cursors loaded for (j = 0; j < i; j++) DisposeCCursor((CCrsrHandle)(*ballCursH)->frame[j].cursorHdl); result = false; // Tell calling proc we failed break; // And break out of the loop } else // But, if the cursor loaded ok { // add it to our list or cursor handles (*ballCursH)->frame[i].cursorHdl = (Handle)cursHdl; SetCCursor((CCrsrHandle)(*ballCursH)->frame[i].cursorHdl); } } InitCursor(); // Show the cursor again (as arrow) } return(result); // Return to calling proc w/ results } //-------------------------------------------------------------- InitAnimatedCursor // Loads and sets up animated beach ball cursor structures. void InitAnimatedCursor (acurHandle ballCursH) { Boolean useColor; useColor = thisMac.hasColor; if (ballCursH == nil) ballCursH = (void *)GetResource('acur', 128); if (ballCursH && ballCursH != animCursorH) { HNoPurge((Handle)ballCursH); MoveHHi((Handle)ballCursH); HLock((Handle)ballCursH); if (useColor) useColor = GetColorCursors(ballCursH); if (!useColor && !GetMonoCursors(ballCursH)) RedAlert(kErrFailedResourceLoad); DisposCursors(); animCursorH = ballCursH; useColorCursor = useColor; (*ballCursH)->index = 0; } else RedAlert(kErrFailedResourceLoad); } //-------------------------------------------------------------- LoadCursors // Just calls the above function. Other code could be added here thoughÉ // to add additional cursors. void LoadCursors (void) { InitAnimatedCursor((acurHandle)GetResource('acur', rAcurID)); } //-------------------------------------------------------------- DisposCursors // Disposes of all memory allocated by anaimated beach ball cursors. void DisposCursors (void) { register short i, j; if (animCursorH != nil) { j = (*animCursorH)->n; if (useColorCursor) { for (i = 0; i < j; i++) { if ((*animCursorH)->frame[i].cursorHdl != nil) DisposeCCursor((CCrsrHandle)(*animCursorH)->frame[i].cursorHdl); } } else { for (i = 0; i < j; i++) { if ((*animCursorH)->frame[i].cursorHdl != nil) DisposeHandle((Handle)(*animCursorH)->frame[i].cursorHdl); } } ReleaseResource((Handle)animCursorH); animCursorH = nil; } } //-------------------------------------------------------------- IncrementCursor // Advances the beach ball cursor one frame. void IncrementCursor (void) { if (animCursorH == 0) InitAnimatedCursor(nil); if (animCursorH) { (*animCursorH)->index++; (*animCursorH)->index %= (*animCursorH)->n; if (useColorCursor) { SetCCursor((CCrsrHandle)(*animCursorH)-> frame[(*animCursorH)->index].cursorHdl); } else { SetCursor((CursPtr)*(*animCursorH)-> frame[(*animCursorH)->index].cursorHdl); } } else SetCursor((CursPtr)*GetCursor(watchCursor)); } //-------------------------------------------------------------- DecrementCursor // Reverses the beach ball cursor one frame. void DecrementCursor (void) { if (animCursorH == 0) InitAnimatedCursor(nil); if (animCursorH) { (*animCursorH)->index--; if (((*animCursorH)->index) < 0) (*animCursorH)->index = ((*animCursorH)->n) - 1; if (useColorCursor) { SetCCursor((CCrsrHandle)(*animCursorH)-> frame[(*animCursorH)->index].cursorHdl); } else { SetCursor((CursPtr)*(*animCursorH)-> frame[(*animCursorH)->index].cursorHdl); } } else SetCursor((CursPtr)*GetCursor(watchCursor)); } //-------------------------------------------------------------- SpinCursor // Advances the beach ball cursor the number of frames specified. void SpinCursor (short incrementIndex) { UInt32 dummyLong; short i; for (i = 0; i < incrementIndex; i++) { IncrementCursor(); Delay(1, &dummyLong); } } //-------------------------------------------------------------- BackSpinCursor // Reverses the beach ball cursor the number of frames specified. void BackSpinCursor (short decrementIndex) { UInt32 dummyLong; short i; for (i = 0; i < decrementIndex; i++) { DecrementCursor(); Delay(1, &dummyLong); } } \ No newline at end of file diff --git a/Sources/AppleEvents.c b/Sources/AppleEvents.c deleted file mode 100755 index 44d3ec9..0000000 --- a/Sources/AppleEvents.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // AppleEvents.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include #include "House.h" #define kNoPrintingAlert 1031 pascal OSErr DoOpenAppAE (const AppleEvent *, AppleEvent *, UInt32); pascal OSErr DoOpenDocAE (const AppleEvent *, AppleEvent *, UInt32); pascal OSErr DoPrintDocAE (const AppleEvent *, AppleEvent *, UInt32); pascal OSErr DoQuitAE (const AppleEvent *, AppleEvent *, UInt32); pascal OSErr MyGotRequiredParams (const AppleEvent *); AEEventHandlerUPP openAppAEUPP, openDocAEUPP, printDocAEUPP, quitAEUPP; extern FSSpecPtr theHousesSpecs; extern long incrementModeTime; extern short thisHouseIndex, splashOriginH, splashOriginV; extern Boolean quitting; //============================================================== Functions //-------------------------------------------------------------- DoOpenAppAE // Handles an "Open Application" Apple Event. pascal OSErr DoOpenAppAE (const AppleEvent *theAE, AppleEvent *reply, UInt32 ref) { #pragma unused (reply, ref) OSErr theErr; theErr = MyGotRequiredParams(theAE); return (theErr); } //-------------------------------------------------------------- DoOpenDocAE // Handles an "Open Document" Apple Event. pascal OSErr DoOpenDocAE (const AppleEvent *theAE, AppleEvent *reply, UInt32 ref) { #pragma unused (reply, ref) FSSpec oneFSS; FInfo finderInfo; AEDescList docList; long itemsInList; Size actualSize; AEKeyword keywd; DescType returnedType; OSErr theErr, whoCares; short i; theErr = AEGetParamDesc(theAE, keyDirectObject, typeAEList, &docList); if (theErr != noErr) { YellowAlert(kYellowAppleEventErr, theErr); return (theErr); } theErr = MyGotRequiredParams(theAE); if (theErr != noErr) { whoCares = AEDisposeDesc(&docList); return (theErr); } theErr = AECountItems(&docList, &itemsInList); if (theErr != noErr) { whoCares = AEDisposeDesc(&docList); return (theErr); } #ifndef COMPILEDEMO for (i = 1; i <= itemsInList; i++) { theErr = AEGetNthPtr(&docList, i, typeFSS, &keywd, &returnedType, &oneFSS, sizeof(oneFSS), &actualSize); if (theErr == noErr) { theErr = FSpGetFInfo(&oneFSS, &finderInfo); if ((theErr == noErr) && (finderInfo.fdType == 'gliH')) AddExtraHouse(&oneFSS); } } if (itemsInList > 0) { theErr = AEGetNthPtr(&docList, 1, typeFSS, &keywd, &returnedType, &oneFSS, sizeof(oneFSS), &actualSize); if (theErr == noErr) { theErr = FSpGetFInfo(&oneFSS, &finderInfo); if ((theErr == noErr) && (finderInfo.fdType == 'gliH')) { whoCares = CloseHouse(); PasStringCopy(oneFSS.name, thisHouseName); BuildHouseList(); if (OpenHouse()) whoCares = ReadHouse(); PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); OpenCloseEditWindows(); incrementModeTime = TickCount() + kIdleSplashTicks; if ((theMode == kSplashMode) || (theMode == kPlayMode)) { Rect updateRect; SetRect(&updateRect, splashOriginH + 474, splashOriginV + 304, splashOriginH + 474 + 166, splashOriginV + 304 + 12); InvalWindowRect(mainWindow, &updateRect); } } } InitCursor(); } #endif whoCares = AEDisposeDesc(&docList); return theErr; } //-------------------------------------------------------------- DoPrintDocAE // Handles a "Print Document" Apple Event. pascal OSErr DoPrintDocAE (const AppleEvent *theAE, AppleEvent *reply, UInt32 ref) { #pragma unused (theAE, reply, ref) short hitWhat; // CenterAlert(kNoPrintingAlert); hitWhat = Alert(kNoPrintingAlert, nil); return errAEEventNotHandled; } //-------------------------------------------------------------- DoQuitAE // Handles a "Quit Application" Apple Event. pascal OSErr DoQuitAE (const AppleEvent *theAE, AppleEvent *reply, UInt32 ref) { #pragma unused (reply, ref) OSErr isHuman; isHuman = MyGotRequiredParams(theAE); if (isHuman == noErr) quitting = true; return isHuman; } //-------------------------------------------------------------- MyGotRequiredParams // Have no clue! :) pascal OSErr MyGotRequiredParams (const AppleEvent *theAE) { DescType returnedType; Size actualSize; return (AEGetAttributePtr(theAE, keyMissedKeywordAttr, typeWildCard, &returnedType, 0L, 0, &actualSize) == errAEDescNotFound) ? noErr : errAEParamMissed; } //-------------------------------------------------------------- SetUpAppleEvents // Initializes all handlers, etc. for dealing with Apple Events. void SetUpAppleEvents (void) { OSErr theErr; openAppAEUPP = NewAEEventHandlerProc(DoOpenAppAE); openDocAEUPP = NewAEEventHandlerProc(DoOpenDocAE); printDocAEUPP = NewAEEventHandlerProc(DoPrintDocAE); quitAEUPP = NewAEEventHandlerProc(DoQuitAE); theErr = AEInstallEventHandler(kCoreEventClass, // install oapp kAEOpenApplication, openAppAEUPP, 0, false); if (theErr != noErr) YellowAlert(kYellowAppleEventErr, theErr); theErr = AEInstallEventHandler(kCoreEventClass, // install odoc kAEOpenDocuments, openDocAEUPP, 0, false); if (theErr != noErr) YellowAlert(kYellowAppleEventErr, theErr); theErr = AEInstallEventHandler(kCoreEventClass, // install pdoc kAEPrintDocuments, printDocAEUPP, 0, false); if (theErr != noErr) YellowAlert(kYellowAppleEventErr, theErr); theErr = AEInstallEventHandler(kCoreEventClass, // install quit kAEQuitApplication, quitAEUPP, 0, false); if (theErr != noErr) YellowAlert(kYellowAppleEventErr, theErr); theErr = AESetInteractionAllowed(kAEInteractWithAll); if (theErr != noErr) YellowAlert(kYellowAppleEventErr, theErr); } \ No newline at end of file diff --git a/Sources/Banner.c b/Sources/Banner.c deleted file mode 100755 index 730dd35..0000000 --- a/Sources/Banner.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Banner.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "Environ.h" #include "MainWindow.h" #include "RectUtils.h" #include "Room.h" #include "Utilities.h" #define kBannerPageTopPICT 1993 #define kBannerPageBottomPICT 1992 #define kBannerPageBottomMask 1991 #define kStarsRemainingPICT 1017 #define kStarRemainingPICT 1018 void DrawBanner (Point *); void DrawBannerMessage (Point); short numStarsRemaining; Boolean bannerStarCountOn; extern Rect justRoomsRect; extern Boolean quickerTransitions, demoGoing, isUseSecondScreen; //============================================================== Functions //-------------------------------------------------------------- DrawBanner // Displays opening banner (when a new game is begun). The banner looksÉ // like a sheet of notebook paper. The text printed on it is specifiedÉ // by the author of the house. void DrawBanner (Point *topLeft) { CGrafPtr wasCPort; GDHandle wasWorld; Rect wholePage, partPage, mapBounds; GWorldPtr tempMap; GWorldPtr tempMask; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&wholePage, 0, 0, 330, 220); mapBounds = thisMac.screen; ZeroRectCorner(&mapBounds); CenterRectInRect(&wholePage, &mapBounds); topLeft->h = wholePage.left; topLeft->v = wholePage.top; partPage = wholePage; partPage.bottom = partPage.top + 190; SetGWorld(workSrcMap, nil); LoadScaledGraphic(kBannerPageTopPICT, &partPage); partPage = wholePage; partPage.top = partPage.bottom - 30; mapBounds = partPage; ZeroRectCorner(&mapBounds); theErr = CreateOffScreenGWorld(&tempMap, &mapBounds, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(kBannerPageBottomPICT); theErr = CreateOffScreenGWorld(&tempMask, &mapBounds, 1); SetGWorld(tempMask, nil); LoadGraphic(kBannerPageBottomMask); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(tempMask), (BitMap *)*GetGWorldPixMap(workSrcMap), &mapBounds, &mapBounds, &partPage); SetPort((GrafPtr)workSrcMap); SetGWorld(wasCPort, wasWorld); DisposeGWorld(tempMap); DisposeGWorld(tempMask); } //-------------------------------------------------------------- CountStarsInHouse // Goes through the current house and counts the total number of stars within. short CountStarsInHouse (void) { short i, h, numRooms, numStars; char wasState; numStars = 0; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; for (i = 0; i < numRooms; i++) { if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) for (h = 0; h < kMaxRoomObs; h++) { if ((*thisHouse)->rooms[i].objects[h].what == kStar) numStars++; } } HSetState((Handle)thisHouse, wasState); return (numStars); } //-------------------------------------------------------------- DrawBannerMessage // This function prints the author's message acorss the notebook paper banner. void DrawBannerMessage (Point topLeft) { Str255 bannerStr, subStr; short count; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); PasStringCopy((*thisHouse)->banner, bannerStr); HSetState((Handle)thisHouse, wasState); TextFont(applFont); TextFace(bold); TextSize(12); ForeColor(blackColor); count = 0; do { GetLineOfText(bannerStr, count, subStr); MoveTo(topLeft.h + 16, topLeft.v + 32 + (count * 20)); DrawString(subStr); count++; } while (subStr[0] > 0); if (bannerStarCountOn) { if (numStarsRemaining != 1) GetLocalizedString(1, bannerStr); else GetLocalizedString(2, bannerStr); NumToString((long)numStarsRemaining, subStr); PasStringConcat(bannerStr, subStr); if (numStarsRemaining != 1) GetLocalizedString(3, subStr); else GetLocalizedString(4, subStr); PasStringConcat(bannerStr, subStr); ForeColor(redColor); MoveTo(topLeft.h + 16, topLeft.v + 164); DrawString(bannerStr); MoveTo(topLeft.h + 16, topLeft.v + 180); GetLocalizedString(5, subStr); DrawString(subStr); } ForeColor(blackColor); } //-------------------------------------------------------------- BringUpBanner // Handles bringing up displaying and disposing of the banner. void BringUpBanner (void) { Rect wholePage; Point topLeft; DrawBanner(&topLeft); DrawBannerMessage(topLeft); // if (quickerTransitions) // DissBitsChunky(&justRoomsRect); // was workSrcRect // else // DissBits(&justRoomsRect); QSetRect(&wholePage, 0, 0, 330, 220); QOffsetRect(&wholePage, topLeft.h, topLeft.v); CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &wholePage, &wholePage, srcCopy, nil); if (demoGoing) WaitForInputEvent(4); else WaitForInputEvent(15); // if (quickerTransitions) // DissBitsChunky(&justRoomsRect); // else // DissBits(&justRoomsRect); } //-------------------------------------------------------------- DisplayStarsRemaining // This brings up a small message indicating the number of stars remainingÉ // in a house. It comes up when the player gets a star (the game is pausedÉ // and the user informed as to how many remain). void DisplayStarsRemaining (void) { Rect src, bounds; Str255 theStr; SetPortWindowPort(mainWindow); QSetRect(&bounds, 0, 0, 256, 64); CenterRectInRect(&bounds, &thisMac.screen); QOffsetRect(&bounds, -thisMac.screen.left, -thisMac.screen.top); src = bounds; InsetRect(&src, 64, 32); TextFont(applFont); TextFace(bold); TextSize(12); NumToString((long)numStarsRemaining, theStr); QOffsetRect(&bounds, 0, -20); if (numStarsRemaining < 2) LoadScaledGraphic(kStarRemainingPICT, &bounds); else { LoadScaledGraphic(kStarsRemainingPICT, &bounds); MoveTo(bounds.left + 102 - (StringWidth(theStr) / 2), bounds.top + 23); ColorText(theStr, 4L); } DelayTicks(60); if (WaitForInputEvent(30)) RestoreEntireGameScreen(); CopyRectWorkToMain(&bounds); } \ No newline at end of file diff --git a/Sources/ColorUtils.c b/Sources/ColorUtils.c deleted file mode 100755 index 3b81c06..0000000 --- a/Sources/ColorUtils.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // ColorUtils.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include //============================================================== Functions //-------------------------------------------------------------- ColorText // Given a string and a color index (index into the current palette),É // this function draws text in that color. It assumes the current port,É // the current font, the current pen location, etc. void ColorText (StringPtr theStr, long color) { RGBColor theRGBColor, wasColor; GetForeColor(&wasColor); Index2Color(color, &theRGBColor); RGBForeColor(&theRGBColor); DrawString(theStr); RGBForeColor(&wasColor); } //-------------------------------------------------------------- ColorRect // Given a rectangle and color index, this function draws a solidÉ // rectangle in that color. Current port, pen mode, etc. assumed. void ColorRect (Rect *theRect, long color) { RGBColor theRGBColor, wasColor; GetForeColor(&wasColor); Index2Color(color, &theRGBColor); RGBForeColor(&theRGBColor); PaintRect(theRect); RGBForeColor(&wasColor); } //-------------------------------------------------------------- ColorOval // Given a rectangle and color index, this function draws a solidÉ // oval in that color. Current port, pen mode, etc. assumed. void ColorOval (Rect *theRect, long color) { RGBColor theRGBColor, wasColor; GetForeColor(&wasColor); Index2Color(color, &theRGBColor); RGBForeColor(&theRGBColor); PaintOval(theRect); RGBForeColor(&wasColor); } //-------------------------------------------------------------- ColorRegion // Given a region and color index, this function draws a solidÉ // region in that color. Current port, pen mode, etc. assumed. void ColorRegion (RgnHandle theRgn, long color) { RGBColor theRGBColor, wasColor; GetForeColor(&wasColor); Index2Color(color, &theRGBColor); RGBForeColor(&theRGBColor); PaintRgn(theRgn); RGBForeColor(&wasColor); } //-------------------------------------------------------------- ColorLine // Given a the end points for a line and color index, this functionÉ // draws a line in that color. Current port, pen mode, etc. assumed. void ColorLine (short h0, short v0, short h1, short v1, long color) { RGBColor theRGBColor, wasColor; GetForeColor(&wasColor); Index2Color(color, &theRGBColor); RGBForeColor(&theRGBColor); MoveTo(h0, v0); LineTo(h1, v1); RGBForeColor(&wasColor); } //-------------------------------------------------------------- HiliteRect // Given a rect and two hilite colors, this function frames the top andÉ // left edges of the rect with color 1 and frames the bottom and rightÉ // sides with color 2. A rect can be made to appear "hi-lit" or "3D"É // in this way. void HiliteRect (Rect *theRect, short color1, short color2) { ColorLine(theRect->left, theRect->top, theRect->right - 2, theRect->top, color1); ColorLine(theRect->left, theRect->top, theRect->left, theRect->bottom - 2, color1); ColorLine(theRect->right - 1, theRect->top, theRect->right - 1, theRect->bottom - 2, color2); ColorLine(theRect->left + 1, theRect->bottom - 1, theRect->right - 1, theRect->bottom - 1, color2); } //-------------------------------------------------------------- ColorFrameRect // Given a rectangle and color index, this function frames aÉ // rectangle in that color. Current port, pen mode, etc. assumed. void ColorFrameRect (Rect *theRect, long color) { RGBColor theRGBColor, wasColor; GetForeColor(&wasColor); Index2Color(color, &theRGBColor); RGBForeColor(&theRGBColor); FrameRect(theRect); RGBForeColor(&wasColor); } //-------------------------------------------------------------- ColorFrameWHRect // Given a the top-left corner of a rectangle, its width and height,É // and a color index, this function frames a rectangle in that color. // Current port, pen mode, etc. assumed. void ColorFrameWHRect (short left, short top, short wide, short high, long color) { Rect theRect; theRect.left = left; theRect.top = top; theRect.right = left + wide; theRect.bottom = top + high; ColorFrameRect(&theRect, color); } //-------------------------------------------------------------- ColorFrameOval // Given a rectangle and color index, this function frames anÉ // oval in that color. Current port, pen mode, etc. assumed. void ColorFrameOval (Rect *theRect, long color) { RGBColor theRGBColor, wasColor; GetForeColor(&wasColor); Index2Color(color, &theRGBColor); RGBForeColor(&theRGBColor); FrameOval(theRect); RGBForeColor(&wasColor); } //-------------------------------------------------------------- LtGrayForeColor // This function finds the closest match to a "light gray" in theÉ // current palette and sets the pen color to that. void LtGrayForeColor (void) { RGBColor color; color.red = (unsigned short) 0xBFFF; color.green = (unsigned short) 0xBFFF; color.blue = (unsigned short) 0xBFFF; RGBForeColor(&color); } //-------------------------------------------------------------- GrayForeColor // This function finds the closest match to a "medium gray" in theÉ // current palette and sets the pen color to that. void GrayForeColor (void) { RGBColor color; color.red = (unsigned short) 0x7FFF; color.green = (unsigned short) 0x7FFF; color.blue = (unsigned short) 0x7FFF; RGBForeColor(&color); } //-------------------------------------------------------------- DkGrayForeColor // This function finds the closest match to a "dark gray" in theÉ // current palette and sets the pen color to that. void DkGrayForeColor (void) { RGBColor color; color.red = (unsigned short) 0x3FFF; color.green = (unsigned short) 0x3FFF; color.blue = (unsigned short) 0x3FFF; RGBForeColor(&color); } //-------------------------------------------------------------- RestoreColorsSlam // This function forces the Macintosh to rebuild the palette. It isÉ // called to restore a sense or normality after some serious mungingÉ // with the palette. void RestoreColorsSlam (void) { RestoreDeviceClut(nil); PaintBehind(nil, GetGrayRgn()); DrawMenuBar(); } \ No newline at end of file diff --git a/Sources/Coordinates.c b/Sources/Coordinates.c deleted file mode 100755 index 6831426..0000000 --- a/Sources/Coordinates.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Coordinates.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "Environ.h" #include "Marquee.h" #include "ObjectEdit.h" #include "RectUtils.h" Rect coordWindowRect; WindowPtr coordWindow; short isCoordH, isCoordV; short coordH, coordV, coordD; Boolean isCoordOpen; //============================================================== Functions //-------------------------------------------------------------- SetCoordinateHVD // Given a horizontal, vertical and distance value, this functionÉ // displays these values in the Coordinates window. void SetCoordinateHVD (short h, short v, short d) { #ifndef COMPILEDEMO if (h != -2) coordH = h; if (v != -2) coordV = v; if (d != -2) coordD = d; UpdateCoordWindow(); #endif } //-------------------------------------------------------------- DeltaCoordinateD // When the user is dragging a handle (such as the height of a blower)É // this function can be called and passed the amount by which the userÉ // has changed the height (delta). This function then displays it inÉ // the Coordinate window. void DeltaCoordinateD (short d) { #ifndef COMPILEDEMO coordD = d; UpdateCoordWindow(); #endif } //-------------------------------------------------------------- UpdateCoordWindow // Completely redraws and updates the Coordinate window. void UpdateCoordWindow (void) { #ifndef COMPILEDEMO Str255 tempStr, numStr; GrafPtr wasPort; if (coordWindow == nil) return; GetPort(&wasPort); SetPort((GrafPtr)coordWindow); EraseRect(&coordWindowRect); PasStringCopy("\ph: ", tempStr); if (coordH != -1) { NumToString((long)coordH, numStr); PasStringConcat(tempStr, numStr); } else PasStringConcat(tempStr, "\p-"); MoveTo(5, 12); DrawString(tempStr); PasStringCopy("\pv: ", tempStr); if (coordV != -1) { NumToString((long)coordV, numStr); PasStringConcat(tempStr, numStr); } else PasStringConcat(tempStr, "\p-"); MoveTo(4, 22); DrawString(tempStr); ForeColor(blueColor); PasStringCopy("\pd: ", tempStr); if (coordD != -1) { NumToString((long)coordD, numStr); PasStringConcat(tempStr, numStr); } else PasStringConcat(tempStr, "\p-"); MoveTo(5, 32); DrawString(tempStr); ForeColor(blackColor); SetPort((GrafPtr)wasPort); #endif } //-------------------------------------------------------------- OpenCoordWindow // Brings up the Coordinate window. void OpenCoordWindow (void) { #ifndef COMPILEDEMO Rect src, dest; Point globalMouse; short direction, dist; if (coordWindow == nil) { QSetRect(&coordWindowRect, 0, 0, 50, 38); if (thisMac.hasColor) coordWindow = NewCWindow(nil, &coordWindowRect, "\pTools", false, kWindoidWDEF, kPutInFront, true, 0L); else coordWindow = NewWindow(nil, &coordWindowRect, "\pTools", false, kWindoidWDEF, kPutInFront, true, 0L); if (coordWindow == nil) RedAlert(kErrNoMemory); // if (OptionKeyDown()) // { // isCoordH = qd.screenBits.bounds.right - 55; // isCoordV = 204; // } MoveWindow(coordWindow, isCoordH, isCoordV, true); globalMouse = MyGetGlobalMouse(); QSetRect(&src, 0, 0, 1, 1); QOffsetRect(&src, globalMouse.h, globalMouse.v); GetWindowRect(coordWindow, &dest); BringToFront(coordWindow); ShowHide(coordWindow, true); // FlagWindowFloating(coordWindow); TEMP - use flaoting windows HiliteAllWindows(); coordH = -1; coordV = -1; coordD = -1; TextFace(applFont); TextSize(9); if (objActive != kNoObjectSelected) { if (ObjectHasHandle(&direction, &dist)) coordD = dist; SetCoordinateHVD(theMarquee.bounds.left, theMarquee.bounds.top, coordD); } } UpdateCoordinateCheckmark(true); #endif } //-------------------------------------------------------------- CloseCoordWindow // Closes and disposes of the Coordinate window. void CloseCoordWindow (void) { CloseThisWindow(&coordWindow); UpdateCoordinateCheckmark(false); } //-------------------------------------------------------------- ToggleCoordinateWindow // Toggles the Coordinate windows state between open and closed. void ToggleCoordinateWindow (void) { #ifndef COMPILEDEMO if (coordWindow == nil) { OpenCoordWindow(); isCoordOpen = true; } else { CloseCoordWindow(); isCoordOpen = false; } #endif } \ No newline at end of file diff --git a/Sources/DialogUtils.c b/Sources/DialogUtils.c deleted file mode 100755 index eae9cf3..0000000 --- a/Sources/DialogUtils.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // DialogUtils.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include "DialogUtils.h" #include "Externs.h" #define kActive 0 #define kInactive 255 //============================================================== Functions //-------------------------------------------------------------- BringUpDialog // Given a dialog pointer and a resource ID, this function brings it upÉ // centered, visible, and with the default button outlined. void BringUpDialog (DialogPtr *theDialog, short dialogID) { // CenterDialog(dialogID); *theDialog = GetNewDialog(dialogID, nil, kPutInFront); if (*theDialog == nil) RedAlert(kErrDialogDidntLoad); SetPort((GrafPtr)*theDialog); ShowWindow(GetDialogWindow(*theDialog)); DrawDefaultButton(*theDialog); } //-------------------------------------------------------------- GetPutDialogCorner // Determines the upper left corner coordinates needed to properly centerÉ // the standard Mac PutFile dialog (when you save files). /* void GetPutDialogCorner (Point *theCorner) { DialogTHndl dlogHandle; Rect theScreen, dlogBounds; Byte wasState; theCorner->h = 64; theCorner->v = 64; theScreen = qd.screenBits.bounds; theScreen.top += LMGetMBarHeight(); OffsetRect(&theScreen, -theScreen.left, -theScreen.top); dlogHandle = (DialogTHndl)GetResource('DLOG', sfPutDialogID); if (dlogHandle != nil) { wasState = HGetState((Handle)dlogHandle); HLock((Handle)dlogHandle); dlogBounds = (**dlogHandle).boundsRect; OffsetRect(&dlogBounds, -dlogBounds.left, -dlogBounds.top); theCorner->h = (theScreen.right - dlogBounds.right) / 2; theCorner->v = (theScreen.bottom - dlogBounds.bottom) / 3; HSetState((Handle)dlogHandle, wasState); } theCorner->v += LMGetMBarHeight(); } */ //-------------------------------------------------------------- GetPutDialogCorner // Determines the upper left corner coordinates needed to properly centerÉ // the standard Mac GetFile dialog (when you open files). /* void GetGetDialogCorner (Point *theCorner) { DialogTHndl dlogHandle; Rect theScreen, dlogBounds; Byte wasState; theCorner->h = 64; theCorner->v = 64; theScreen = qd.screenBits.bounds; theScreen.top += LMGetMBarHeight(); OffsetRect(&theScreen, -theScreen.left, -theScreen.top); dlogHandle = (DialogTHndl)GetResource('DLOG', sfGetDialogID); if (dlogHandle != nil) { wasState = HGetState((Handle)dlogHandle); HLock((Handle)dlogHandle); dlogBounds = (**dlogHandle).boundsRect; OffsetRect(&dlogBounds, -dlogBounds.left, -dlogBounds.top); theCorner->h = (theScreen.right - dlogBounds.right) / 2; theCorner->v = (theScreen.bottom - dlogBounds.bottom) / 3; HSetState((Handle)dlogHandle, wasState); } theCorner->v += LMGetMBarHeight(); } */ //-------------------------------------------------------------- CenterDialog // Given a resource ID for a dialog, this function properly centers it. /* void CenterDialog (SInt16 dialogID) { DialogTHndl dlogHandle; Rect theScreen, dlogBounds; SInt16 hPos, vPos; Byte wasState; theScreen = qd.screenBits.bounds; theScreen.top += LMGetMBarHeight(); dlogHandle = (DialogTHndl)GetResource('DLOG', dialogID); if (dlogHandle != nil) { wasState = HGetState((Handle)dlogHandle); HLock((Handle)dlogHandle); dlogBounds = (**dlogHandle).boundsRect; OffsetRect(&dlogBounds, -dlogBounds.left, -dlogBounds.top); hPos = ((theScreen.right - theScreen.left) - dlogBounds.right) / 2; vPos = ((theScreen.bottom - theScreen.top) - dlogBounds.bottom) / 3; OffsetRect(&dlogBounds, hPos, vPos + LMGetMBarHeight()); (**dlogHandle).boundsRect = dlogBounds; HSetState((Handle)dlogHandle, wasState); } } */ //-------------------------------------------------------------- GetDialogRect // Determines the bounding rectangle for a given dialog. void GetDialogRect (Rect *bounds, short dialogID) { DialogTHndl dlogHandle; Byte wasState; dlogHandle = (DialogTHndl)GetResource('DLOG', dialogID); if (dlogHandle != nil) { wasState = HGetState((Handle)dlogHandle); HLock((Handle)dlogHandle); *bounds = (**dlogHandle).boundsRect; HSetState((Handle)dlogHandle, wasState); } } //-------------------------------------------------------------- TrueCenterDialog // Places a dialog DEAD CENTER (as opposed to 1/3 of the way down asÉ // is common for Mac dialog centering). /* void TrueCenterDialog (short dialogID) { DialogTHndl dlogHandle; Rect theScreen, dlogBounds; short hPos, vPos; Byte wasState; theScreen = qd.screenBits.bounds; theScreen.top += LMGetMBarHeight(); dlogHandle = (DialogTHndl)GetResource('DLOG', dialogID); if (dlogHandle != nil) { wasState = HGetState((Handle)dlogHandle); HLock((Handle)dlogHandle); dlogBounds = (**dlogHandle).boundsRect; OffsetRect(&dlogBounds, theScreen.left - dlogBounds.left, theScreen.top - dlogBounds.top); hPos = ((theScreen.right - theScreen.left) - (dlogBounds.right - dlogBounds.left)) / 2; vPos = ((theScreen.bottom - theScreen.top) - (dlogBounds.bottom - dlogBounds.top)) / 2; OffsetRect(&dlogBounds, hPos, vPos + LMGetMBarHeight()); (**dlogHandle).boundsRect = dlogBounds; HSetState((Handle)dlogHandle, wasState); } } */ //-------------------------------------------------------------- CenterAlert // Given an alert ID, this function properly centers it on the main monitor. /* void CenterAlert (short alertID) { AlertTHndl alertHandle; Rect theScreen, alertRect; short horiOff, vertOff; Byte wasState; theScreen = qd.screenBits.bounds; theScreen.top += LMGetMBarHeight(); alertHandle = (AlertTHndl)GetResource('ALRT', alertID); if (alertHandle != nil) { wasState = HGetState((Handle)alertHandle); HLock((Handle)alertHandle); alertRect = (**alertHandle).boundsRect; OffsetRect(&alertRect, -alertRect.left, -alertRect.top); horiOff = ((theScreen.right - theScreen.left) - alertRect.right) / 2; vertOff = ((theScreen.bottom - theScreen.top) - alertRect.bottom) / 3; OffsetRect(&alertRect, horiOff, vertOff + LMGetMBarHeight()); (**alertHandle).boundsRect = alertRect; HSetState((Handle)alertHandle, wasState); } } */ //-------------------------------------------------------------- ZoomOutDialogRect // Given a dialog, this function does the "zoom" animation to make theÉ // the dialog appear to expand from nothingness or zoom in at you. /* void ZoomOutDialogRect (short dialogID) { #define kSteps 16 #define kZoomDelay 1 DialogTHndl dlogHandle; GrafPtr wasPort, tempPort; Rect dlogBounds, zoomRect; UInt32 dummyLong; Byte wasState; short wideStep, highStep, i; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); dlogHandle = (DialogTHndl)GetResource('DLOG', dialogID); if (dlogHandle != nil) { wasState = HGetState((Handle)dlogHandle); HLock((Handle)dlogHandle); dlogBounds = (**dlogHandle).boundsRect; HSetState((Handle)dlogHandle, wasState); } wideStep = ((dlogBounds.right - dlogBounds.left) / 2) / kSteps; highStep = ((dlogBounds.bottom - dlogBounds.top) / 2) / kSteps; SetRect(&zoomRect, dlogBounds.left + (wideStep * kSteps), dlogBounds.top + (highStep * kSteps), dlogBounds.right - (wideStep * kSteps), dlogBounds.bottom - (highStep * kSteps)); GlobalToLocalRect(&zoomRect); PenPat(GetQDGlobalsGray(&dummyPattern)); PenMode(patXor); for (i = 0; i < kSteps; i++) { FrameRect(&zoomRect); Delay(kZoomDelay, &dummyLong); FrameRect(&zoomRect); InsetRect(&zoomRect, -wideStep, -highStep); } ClosePort(tempPort); SetPort((GrafPtr)wasPort); } */ //-------------------------------------------------------------- ZoomOutAlertRect // Like the above funciton but zooms out alerts instead of dialogs. /* void ZoomOutAlertRect (short alertID) { #define kSteps 16 #define kZoomDelay 1 AlertTHndl alertHandle; GrafPtr wasPort, tempPort; Rect alertBounds, zoomRect; UInt32 dummyLong; Byte wasState; short wideStep, highStep, i; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); alertHandle = (AlertTHndl)GetResource('ALRT', alertID); if (alertHandle != nil) { wasState = HGetState((Handle)alertHandle); HLock((Handle)alertHandle); alertBounds = (**alertHandle).boundsRect; HSetState((Handle)alertHandle, wasState); } wideStep = ((alertBounds.right - alertBounds.left) / 2) / kSteps; highStep = ((alertBounds.bottom - alertBounds.top) / 2) / kSteps; SetRect(&zoomRect, alertBounds.left + (wideStep * kSteps), alertBounds.top + (highStep * kSteps), alertBounds.right - (wideStep * kSteps), alertBounds.bottom - (highStep * kSteps)); GlobalToLocalRect(&zoomRect); PenPat(GetQDGlobalsGray(&dummyPattern)); PenMode(patXor); for (i = 0; i < kSteps; i++) { FrameRect(&zoomRect); Delay(kZoomDelay, &dummyLong); FrameRect(&zoomRect); InsetRect(&zoomRect, -wideStep, -highStep); } ClosePort(tempPort); SetPort((GrafPtr)wasPort); } */ //-------------------------------------------------------------- FlashDialogButton // Flashes the default dialog button (item = 1) so as to make it appearÉ // as though the user clicked on it. void FlashDialogButton (DialogPtr theDialog, short itemNumber) { Rect itemRect; Handle itemHandle; UInt32 dummyLong; short itemType; GetDialogItem(theDialog, itemNumber, &itemType, &itemHandle, &itemRect); HiliteControl((ControlHandle)itemHandle, kControlButtonPart); Delay(8, &dummyLong); HiliteControl((ControlHandle)itemHandle, 0); } //-------------------------------------------------------------- DrawDefaultButton // Draws a fat outline around the default item (item = 1). This is theÉ // item that is selected if the user hits the Return key. void DrawDefaultButton (DialogPtr theDialog) { Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, 1, &itemType, &itemHandle, &itemRect); InsetRect(&itemRect, -4, -4); PenSize(3, 3); FrameRoundRect(&itemRect, 16, 16); PenNormal(); } //-------------------------------------------------------------- GetDialogString // Returns a string from a specific dialog item. void GetDialogString (DialogPtr theDialog, short item, StringPtr theString) { Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); GetDialogItemText(itemHandle, theString); } //-------------------------------------------------------------- SetDialogString // Sets a specific string to a specific dialog item. void SetDialogString (DialogPtr theDialog, short item, StringPtr theString) { Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); SetDialogItemText(itemHandle, theString); } //-------------------------------------------------------------- GetDialogStringLen // Returns the length of a dialog item string (text). short GetDialogStringLen (DialogPtr theDialog, short item) { Rect itemRect; Str255 theString; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); GetDialogItemText(itemHandle, theString); return (theString[0]); } //-------------------------------------------------------------- GetDialogItemValue // Returns the value or "state" of a dialog item. For checkboxes andÉ // radio buttons, this may be a 1 or 0. void GetDialogItemValue (DialogPtr theDialog, short item, short *theState) { Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); *theState = GetControlValue((ControlHandle)itemHandle); } //-------------------------------------------------------------- SetDialogItemValue // Sets a specific dialogf items value or state (can set or clearÉ // checkboxes, radio buttons, etc.). void SetDialogItemValue (DialogPtr theDialog, short item, short theState) { Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); SetControlValue((ControlHandle)itemHandle, theState); } //-------------------------------------------------------------- ToggleDialogItemValue // If item is a checkbox or radio button, its state is toggled. void ToggleDialogItemValue (DialogPtr theDialog, short item) { Rect itemRect; Handle itemHandle; short itemType, theState; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); theState = GetControlValue((ControlHandle)itemHandle); if (theState == 0) theState = 1; else theState = 0; SetControlValue((ControlHandle)itemHandle, theState); } //-------------------------------------------------------------- SetDialogNumToStr // Function accepts an integer, converts it to a string and sets aÉ // dialog items text to this string. void SetDialogNumToStr (DialogPtr theDialog, short item, long theNumber) { Str255 theString; Rect itemRect; Handle itemHandle; short itemType; NumToString(theNumber, theString); GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); SetDialogItemText(itemHandle, theString); } //-------------------------------------------------------------- GetDialogNumFromStr // Function extracts the text from a dialog item and converts it to anÉ // integer for returning. void GetDialogNumFromStr (DialogPtr theDialog, short item, long *theNumber) { Str255 theString; Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); GetDialogItemText(itemHandle, theString); StringToNum(theString, theNumber); } //-------------------------------------------------------------- GetDialogItemRect // Returns the bounding rectangle of the specified dialog item. void GetDialogItemRect (DialogPtr theDialog, short item, Rect *theRect) { Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, theRect); } //-------------------------------------------------------------- SetDialogItemRect // Sets the bounding rectangle of the specified dialog item. Used toÉ // resize or move a control. void SetDialogItemRect (DialogPtr theDialog, short item, Rect *theRect) { Rect oldRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &oldRect); OffsetRect(&oldRect, theRect->left - oldRect.left, theRect->top - oldRect.top); SetDialogItem(theDialog, item, itemType, itemHandle, &oldRect); } //-------------------------------------------------------------- OffsetDialogItemRect // Moves a dialog item by h and v. void OffsetDialogItemRect (DialogPtr theDialog, short item, short h, short v) { Rect oldRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &oldRect); OffsetRect(&oldRect, h, v); SetDialogItem(theDialog, item, itemType, itemHandle, &oldRect); } //-------------------------------------------------------------- SelectFromRadioGroup // Assuming a series of consecutively numbered radio buttons, this functionÉ // clears the whole range of them but sets the one specified (as thoughÉ // the radio buttons are linked and only one can be set at a time). void SelectFromRadioGroup (DialogPtr dial, short which, short first, short last) { Rect iRect; Handle iHandle; short iType, i; for (i = first; i <= last; i++) { GetDialogItem(dial, i, &iType, &iHandle, &iRect); SetControlValue((ControlHandle)iHandle, (short)false); } GetDialogItem(dial, which, &iType, &iHandle, &iRect); SetControlValue((ControlHandle)iHandle, (short)true); } //-------------------------------------------------------------- AddMenuToPopUp // Assigns a menu handle to a pop-up dialog item - thus, giving thatÉ // pop-up item something to pop up. /* void AddMenuToPopUp (DialogPtr theDialog, short whichItem, MenuHandle theMenu) { Rect iRect; Handle iHandle; short iType; GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); (**(ControlHandle)iHandle).contrlRfCon = (long)theMenu; } */ //-------------------------------------------------------------- GetPopUpMenuValu // Returns which item is currently selected in a pop-up menu. void GetPopUpMenuValue (DialogPtr theDialog, short whichItem, short *value) { Rect iRect; Handle iHandle; short iType; GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); *value = GetControlValue((ControlHandle)iHandle); } //-------------------------------------------------------------- SetPopUpMenuValue // Forces a specific item to be set (as though selected) in a pop-up menu. void SetPopUpMenuValue (DialogPtr theDialog, short whichItem, short value) { Rect iRect; Handle iHandle; short iType; GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); SetControlValue((ControlHandle)iHandle, value); } //-------------------------------------------------------------- MyEnableControl // "Un-grays" or enables a dialog item (usually a button). void MyEnableControl (DialogPtr theDialog, short whichItem) { Rect iRect; Handle iHandle; short iType; GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); HiliteControl((ControlHandle)iHandle, kActive); } //-------------------------------------------------------------- MyDisableControl // "Grays out" or disables a dialog item (usually a button). void MyDisableControl (DialogPtr theDialog, short whichItem) { Rect iRect; Handle iHandle; short iType; GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); HiliteControl((ControlHandle)iHandle, kInactive); } //-------------------------------------------------------------- DrawDialogUserText // Given a string of text and an item, this function draws the stringÉ // within the bounding rect of the item. Dialog item assumed to beÉ // a "user item" (invisible item with only bounds). void DrawDialogUserText (DialogPtr dial, short item, StringPtr text, Boolean invert) { Rect iRect; Handle iHandle; Str255 newString, stringCopy; short iType, textLong, i, inset; TextFont(applFont); TextSize(9); PasStringCopy(text, stringCopy); GetDialogItem(dial, item, &iType, &iHandle, &iRect); if ((StringWidth(stringCopy) + 2) > (iRect.right - iRect.left)) CollapseStringToWidth(stringCopy, iRect.right - iRect.left - 2); textLong = stringCopy[0]; for (i = 0; i < textLong; i++) newString[i] = stringCopy[i + 1]; OffsetRect(&iRect, 0, 1); EraseRect(&iRect); OffsetRect(&iRect, 0, -1); inset = ((iRect.right - iRect.left) - (StringWidth(stringCopy) + 2)) / 2; iRect.left += inset; iRect.right -= inset; TETextBox(newString, textLong, &iRect, teCenter); if (invert) { OffsetRect(&iRect, 0, 1); InvertRect(&iRect); } } //-------------------------------------------------------------- DrawDialogUserText // Similar to the above function but doesn't call TETextBox(). Instead,É // it truncates the string (and appends "É") to the end in order thatÉ // the string fits within the dialog item's bounds. void DrawDialogUserText2 (DialogPtr dial, short item, StringPtr text) { Rect iRect; Handle iHandle; Str255 stringCopy; short iType; TextFont(applFont); TextSize(9); PasStringCopy(text, stringCopy); GetDialogItem(dial, item, &iType, &iHandle, &iRect); if ((StringWidth(stringCopy) + 2) > (iRect.right - iRect.left)) CollapseStringToWidth(stringCopy, iRect.right - iRect.left - 2); MoveTo(iRect.left, iRect.bottom); DrawString(stringCopy); } //-------------------------------------------------------------- LoadDialogPICT // Draws a 'PICT' specified by ID within the bounds of the specifiedÉ // dialog item. void LoadDialogPICT (DialogPtr theDialog, short item, short theID) { Rect iRect; Handle iHandle; PicHandle thePict; short iType; GetDialogItem(theDialog, item, &iType, &iHandle, &iRect); thePict = GetPicture(theID); if (thePict) DrawPicture(thePict, &iRect); } //-------------------------------------------------------------- FrameDialogItem // Given a dialog item, this function draws a box around it. void FrameDialogItem (DialogPtr theDialog, short item) { Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); FrameRect(&itemRect); } //-------------------------------------------------------------- FrameDialogItemC // Given a dialog item, this function draws a color (specified) box around it. void FrameDialogItemC (DialogPtr theDialog, short item, long color) { RGBColor theRGBColor, wasColor; Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); GetForeColor(&wasColor); Index2Color(color, &theRGBColor); RGBForeColor(&theRGBColor); FrameRect(&itemRect); RGBForeColor(&wasColor); } //-------------------------------------------------------------- FrameOvalDialogItem // Given a dialog item, this function draws an oval around it. void FrameOvalDialogItem (DialogPtr theDialog, short item) { Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); FrameOval(&itemRect); } //-------------------------------------------------------------- BorderDialogItem // Given a dialog item, this function draws any combination of 4 sidesÉ // of a box around it. Which sides get drawn is encoded in "sides". void BorderDialogItem (DialogPtr theDialog, short item, short sides) { Rect itemRect; Handle itemHandle; short itemType; // 1 = left // 2 = top // 4 = bottom // 8 = right ... so 6 = top & bottom, 15 = all 4 sides GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); if (sides >= 8) // 8 = right { MoveTo(itemRect.right, itemRect.top); LineTo(itemRect.right, itemRect.bottom); sides -= 8; } if (sides >= 4) // 4 = bottom { MoveTo(itemRect.left, itemRect.bottom); LineTo(itemRect.right, itemRect.bottom); sides -= 4; } if (sides >= 2) // 2 = top { MoveTo(itemRect.left, itemRect.top - 1); LineTo(itemRect.right, itemRect.top - 1); sides -= 2; } if (sides >= 1) // 1 = left { MoveTo(itemRect.left - 1, itemRect.top); LineTo(itemRect.left - 1, itemRect.bottom); } } //-------------------------------------------------------------- ShadowDialogItem // Draws a drop shadow to the right and below a specified dialog item. void ShadowDialogItem (DialogPtr theDialog, short item, short thickness) { Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); PenSize(thickness, thickness); MoveTo(itemRect.left + thickness, itemRect.bottom); Line(itemRect.right - itemRect.left - thickness, 0); MoveTo(itemRect.right, itemRect.top + thickness); Line(0, itemRect.bottom - itemRect.top - thickness); PenNormal(); } //-------------------------------------------------------------- EraseDialogItem // Erases (but doesn't physically remove) a dialog item. void EraseDialogItem (DialogPtr theDialog, short item) { Rect itemRect; Handle itemHandle; short itemType; GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); EraseRect(&itemRect); } \ No newline at end of file diff --git a/Sources/DynamicMaps.c b/Sources/DynamicMaps.c deleted file mode 100755 index 390cf49..0000000 --- a/Sources/DynamicMaps.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // DynamicMaps.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" #include "MainWindow.h" #include "Objects.h" #include "RectUtils.h" #include "Room.h" #include "Utilities.h" void BackUpFlames (Rect *, short); void BackUpTikiFlames (Rect *, short); void BackUpBBQCoals (Rect *, short); void BackUpPendulum (Rect *, short); void BackUpStar (Rect *, short); sparklePtr sparkles; flyingPtPtr flyingPoints; flamePtr flames, tikiFlames, bbqCoals; pendulumPtr pendulums; starPtr theStars; shredPtr shreds; Rect pointsSrc[15]; short numSparkles, numFlyingPts, numChimes; short numFlames, numSavedMaps, numTikiFlames, numCoals; short numPendulums, clockFrame, numStars, numShredded; extern savedType savedMaps[]; extern Rect flame[], tikiFlame[], coals[], pendulumSrc[]; extern Rect starSrc[]; extern short numGrease, numDynamics; //============================================================== Functions //-------------------------------------------------------------- NilSavedMaps // Deletes array of "dyanmics" offscreen pixmaps. void NilSavedMaps (void) { short i; for (i = 0; i < kMaxSavedMaps; i++) { if (savedMaps[i].map != nil) { DisposeGWorld(savedMaps[i].map); // KillOffScreenPixMap(savedMaps[i].map); savedMaps[i].map = nil; } savedMaps[i].where = -1; savedMaps[i].who = -1; } numSavedMaps = 0; } //-------------------------------------------------------------- BackUpToSavedMap // Saves a copy of the room behind an object to an array of pixmaps. // Then when the object in question is drawn, there is a copy of theÉ // room that it obscured so that, should the player get the object,É // it can be made to "disappear". short BackUpToSavedMap (Rect *theRect, short where, short who) { Rect mapRect; OSErr theErr; if (numSavedMaps >= kMaxSavedMaps) return(-1); mapRect = *theRect; ZeroRectCorner(&mapRect); savedMaps[numSavedMaps].dest = *theRect; // CreateOffScreenPixMap(&mapRect, &savedMaps[numSavedMaps].map); theErr = CreateOffScreenGWorld(&savedMaps[numSavedMaps].map, &mapRect, kPreferredDepth); CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), GetPortBitMapForCopyBits(savedMaps[numSavedMaps].map), theRect, &mapRect, srcCopy, nil); savedMaps[numSavedMaps].where = where; savedMaps[numSavedMaps].who = who; numSavedMaps++; return (numSavedMaps - 1); // return array index } //-------------------------------------------------------------- ReBackUpSavedMap // This function is similar to the above, but assumes there is alreadyÉ // a slot in the pixmap array for the object. It re-copies the backgroundÉ // and is needed when the lights in the room go on or off. short ReBackUpSavedMap (Rect *theRect, short where, short who) { Rect mapRect; short i, foundIndex; foundIndex = -1; for (i = 0; i < numSavedMaps; i++) { if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) { foundIndex = i; mapRect = *theRect; ZeroRectCorner(&mapRect); CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), GetPortBitMapForCopyBits(savedMaps[foundIndex].map), theRect, &mapRect, srcCopy, nil); return (foundIndex); } } return (foundIndex); } //-------------------------------------------------------------- RestoreFromSavedMap // This copies the saved background swatch to the screen - effectivelyÉ // covering up or "erasing" the object. void RestoreFromSavedMap (short where, short who, Boolean doSparkle) { Rect mapRect, bounds; short i; for (i = 0; i < numSavedMaps; i++) { if ((savedMaps[i].where == where) && (savedMaps[i].who == who) && (savedMaps[i].map != nil)) { mapRect = savedMaps[i].dest; ZeroRectCorner(&mapRect); CopyBits(GetPortBitMapForCopyBits(savedMaps[i].map), (BitMap *)*GetGWorldPixMap(backSrcMap), &mapRect, &savedMaps[i].dest, srcCopy, nil); CopyBits(GetPortBitMapForCopyBits(savedMaps[i].map), (BitMap *)*GetGWorldPixMap(workSrcMap), &mapRect, &savedMaps[i].dest, srcCopy, nil); AddRectToWorkRects(&savedMaps[i].dest); if (doSparkle) { bounds = savedMaps[i].dest; QOffsetRect(&bounds, -playOriginH, -playOriginV); AddSparkle(&bounds); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } break; } } } //-------------------------------------------------------------- AddSparkle // This adds a "sparkle" object to the fixed array of sparkles. void AddSparkle (Rect *theRect) { Rect centeredRect; short i; if (numSparkles < kMaxSparkles) { theRect->left += playOriginH; theRect->right += playOriginH; theRect->top += playOriginV; theRect->bottom += playOriginV; centeredRect = sparkleSrc[0]; CenterRectInRect(¢eredRect, theRect); for (i = 0; i < kMaxSparkles; i++) if (sparkles[i].mode == -1) { sparkles[i].bounds = centeredRect; sparkles[i].mode = 0; numSparkles++; break; } } } //-------------------------------------------------------------- AddFlyingPoint // This adds a "flying point" object to the array of flying points. void AddFlyingPoint (Rect *theRect, short points, short hVel, short vVel) { Rect centeredRect; short i; if (numFlyingPts < kMaxFlyingPts) { theRect->left += playOriginH; theRect->right += playOriginH; theRect->top += playOriginV; theRect->bottom += playOriginV; centeredRect = pointsSrc[0]; CenterRectInRect(¢eredRect, theRect); for (i = 0; i < kMaxFlyingPts; i++) if (flyingPoints[i].mode == -1) { flyingPoints[i].dest = centeredRect; flyingPoints[i].whole = centeredRect; flyingPoints[i].loops = 0; flyingPoints[i].hVel = hVel; flyingPoints[i].vVel = vVel; switch (points) { case 100: flyingPoints[i].start = 12; flyingPoints[i].stop = 14; break; case 250: flyingPoints[i].start = 9; flyingPoints[i].stop = 11; break; case 300: flyingPoints[i].start = 6; flyingPoints[i].stop = 8; break; case 500: flyingPoints[i].start = 3; flyingPoints[i].stop = 5; break; default: flyingPoints[i].start = 0; flyingPoints[i].stop = 2; break; } flyingPoints[i].mode = flyingPoints[i].start; numFlyingPts++; break; } } } //-------------------------------------------------------------- BackUpFlames // This makes copies of the area of the room behind a flame. The flameÉ // graphic can be "copy masked" to this pixmap then and then simpleÉ // CopyBits() calls will properly draw the flame on screen with theÉ // proper background. void BackUpFlames (Rect *src, short index) { Rect dest; short i; QSetRect(&dest, 0, 0, 16, 15); for (i = 0; i < kNumCandleFlames; i++) { // Copy background to map. CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), GetPortBitMapForCopyBits(savedMaps[index].map), src, &dest, srcCopy, nil); // Copy flame to map. CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), (BitMap *)*GetGWorldPixMap(blowerMaskMap), GetPortBitMapForCopyBits(savedMaps[index].map), &flame[i], &flame[i], &dest); QOffsetRect(&dest, 0, 15); } } //-------------------------------------------------------------- ReBackUpFlames // Like the above function but this is called when the lighting changesÉ // in a room (lights go on or off). void ReBackUpFlames (short where, short who) { short i, f; for (i = 0; i < numSavedMaps; i++) { if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) { for (f = 0; f < numFlames; f++) { if (flames[f].who == i) { BackUpFlames(&flames[f].dest, i); return; } } } } } //-------------------------------------------------------------- AddCandleFlame // This adds a candle flame to tha array of flames. void AddCandleFlame (short where, short who, short h, short v) { Rect src, bounds; short savedNum; if ((numFlames >= kMaxCandles) || (h < 16) || (v < 15)) return; QSetRect(&src, 0, 0, 16, 15); QOffsetRect(&src, h - 8, v - 15); if ((thisMac.isDepth == 4) && ((src.left % 2) == 1)) { QOffsetRect(&src, -1, 0); if (src.left < 0) QOffsetRect(&src, 2, 0); } QSetRect(&bounds, 0, 0, 16, 15 * kNumCandleFlames); savedNum = BackUpToSavedMap(&bounds, where, who); if (savedNum != -1) { BackUpFlames(&src, savedNum); flames[numFlames].dest = src; flames[numFlames].mode = RandomInt(kNumCandleFlames); QSetRect(&flames[numFlames].src, 0, 0, 16, 15); QOffsetRect(&flames[numFlames].src, 0, flames[numFlames].mode * 15); flames[numFlames].who = savedNum; numFlames++; } } //-------------------------------------------------------------- BackUpTikiFlames // This is like the function BackUpFlames() but customized for Tiki torches. void BackUpTikiFlames (Rect *src, short index) { Rect dest; short i; QSetRect(&dest, 0, 0, 8, 10); for (i = 0; i < kNumTikiFlames; i++) { // copy background to map CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), GetPortBitMapForCopyBits(savedMaps[index].map), src, &dest, srcCopy, nil); // copy flame to map CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), (BitMap *)*GetGWorldPixMap(blowerMaskMap), GetPortBitMapForCopyBits(savedMaps[index].map), &tikiFlame[i], &tikiFlame[i], &dest); QOffsetRect(&dest, 0, 10); } } //-------------------------------------------------------------- ReBackUpTikiFlames // This is like the function ReBackUpFlames() but customized for Tiki torches. void ReBackUpTikiFlames (short where, short who) { short i, f; for (i = 0; i < numSavedMaps; i++) { if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) { for (f = 0; f < numTikiFlames; f++) { if (tikiFlames[f].who == i) { BackUpTikiFlames(&tikiFlames[f].dest, i); return; } } } } } //-------------------------------------------------------------- AddTikiFlame // This adds a tiki flame to the array of tiki flames. void AddTikiFlame (short where, short who, short h, short v) { Rect src, bounds; short savedNum; if ((numTikiFlames >= kMaxTikis) || (h < 8) || (v < 10)) return; QSetRect(&src, 0, 0, 8, 10); if ((thisMac.isDepth == 4) && ((h % 2) == 1)) { h--; if (h < 0) h += 2; } QOffsetRect(&src, h, v); QSetRect(&bounds, 0, 0, 8, 10 * kNumTikiFlames); savedNum = BackUpToSavedMap(&bounds, where, who); if (savedNum != -1) { BackUpTikiFlames(&src, savedNum); tikiFlames[numTikiFlames].dest = src; tikiFlames[numTikiFlames].mode = RandomInt(kNumTikiFlames); QSetRect(&tikiFlames[numTikiFlames].src, 0, 0, 8, 10); QOffsetRect(&tikiFlames[numTikiFlames].src, 0, tikiFlames[numTikiFlames].mode * 10); tikiFlames[numTikiFlames].who = savedNum; numTikiFlames++; } } //-------------------------------------------------------------- BackUpBBQCoals // Another one - but for BBQ coals. void BackUpBBQCoals (Rect *src, short index) { Rect dest; short i; QSetRect(&dest, 0, 0, 32, 9); for (i = 0; i < kNumBBQCoals; i++) { // copy background to map CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), GetPortBitMapForCopyBits(savedMaps[index].map), src, &dest, srcCopy, nil); // copy flame to map CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), (BitMap *)*GetGWorldPixMap(blowerMaskMap), GetPortBitMapForCopyBits(savedMaps[index].map), &coals[i], &coals[i], &dest); QOffsetRect(&dest, 0, 9); } } //-------------------------------------------------------------- ReBackUpBBQCoals // Sense a pattern here? void ReBackUpBBQCoals (short where, short who) { short i, f; for (i = 0; i < numSavedMaps; i++) { if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) { for (f = 0; f < numCoals; f++) { if (bbqCoals[f].who == i) { BackUpBBQCoals(&bbqCoals[f].dest, i); return; } } } } } //-------------------------------------------------------------- AddBBQCoals // Adds BBQ coals to the array of BBQ coals. void AddBBQCoals (short where, short who, short h, short v) { Rect src, bounds; short savedNum; if ((numCoals >= kMaxCoals) || (h < 32) || (v < 9)) return; QSetRect(&src, 0, 0, 32, 9); if ((thisMac.isDepth == 4) && ((h % 2) == 1)) { h--; if (h < 0) h += 2; } QOffsetRect(&src, h, v); QSetRect(&bounds, 0, 0, 32, 9 * kNumBBQCoals); savedNum = BackUpToSavedMap(&bounds, where, who); if (savedNum != -1) { BackUpBBQCoals(&src, savedNum); bbqCoals[numCoals].dest = src; bbqCoals[numCoals].mode = RandomInt(kNumBBQCoals); QSetRect(&bbqCoals[numCoals].src, 0, 0, 32, 9); QOffsetRect(&bbqCoals[numCoals].src, 0, bbqCoals[numCoals].mode * 9); bbqCoals[numCoals].who = savedNum; numCoals++; } } //-------------------------------------------------------------- BackUpPendulum // Just like many of the previous functions, but for the pendulum on theÉ // cuckoo clock. void BackUpPendulum (Rect *src, short index) { Rect dest; short i; QSetRect(&dest, 0, 0, 32, 28); for (i = 0; i < kNumPendulums; i++) { CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), GetPortBitMapForCopyBits(savedMaps[index].map), src, &dest, srcCopy, nil); CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), GetPortBitMapForCopyBits(savedMaps[index].map), &pendulumSrc[i], &pendulumSrc[i], &dest); QOffsetRect(&dest, 0, 28); } } //-------------------------------------------------------------- ReBackUpPendulum // Backs up the pendulums in the event of lights going on or off. void ReBackUpPendulum (short where, short who) { short i, f; for (i = 0; i < numSavedMaps; i++) { if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) { for (f = 0; f < numPendulums; f++) { if (pendulums[f].who == i) { BackUpPendulum(&pendulums[f].dest, i); return; } } } } } //-------------------------------------------------------------- AddPendulum // Adds a pendulum to the array of pendulums. void AddPendulum (short where, short who, short h, short v) { Rect src, bounds; short savedNum; if ((numPendulums >= kMaxPendulums) || (h < 32) || (v < 28)) return; clockFrame = 10; QSetRect(&bounds, 0, 0, 32, 28 * kNumPendulums); savedNum = BackUpToSavedMap(&bounds, where, who); if (savedNum != -1) { QSetRect(&src, 0, 0, 32, 28); if ((thisMac.isDepth == 4) && ((h % 2) == 1)) { h--; if (h < 0) h += 2; } QOffsetRect(&src, h, v); BackUpPendulum (&src, savedNum); pendulums[numPendulums].dest = src; pendulums[numPendulums].mode = 1; if (RandomInt(2) == 0) pendulums[numPendulums].toOrFro = true; else pendulums[numPendulums].toOrFro = false; pendulums[numPendulums].active = true; QSetRect(&pendulums[numPendulums].src, 0, 0, 32, 28); QOffsetRect(&pendulums[numPendulums].src, 0, 28); pendulums[numPendulums].who = savedNum; pendulums[numPendulums].where = where; pendulums[numPendulums].link = who; numPendulums++; } } //-------------------------------------------------------------- BackUpStar // Makes a copy of background beneath a star. void BackUpStar (Rect *src, short index) { Rect dest; short i; QSetRect(&dest, 0, 0, 32, 31); for (i = 0; i < 6; i++) { CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), GetPortBitMapForCopyBits(savedMaps[index].map), src, &dest, srcCopy, nil); // copy flame to map CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), GetPortBitMapForCopyBits(savedMaps[index].map), &starSrc[i], &starSrc[i], &dest); QOffsetRect(&dest, 0, 31); } } //-------------------------------------------------------------- ReBackUpStar // Re-backs up the stars - in the event of lighting switch. void ReBackUpStar (short where, short who) { short i, f; for (i = 0; i < numSavedMaps; i++) { if ((savedMaps[i].where == where) && (savedMaps[i].who == who)) { for (f = 0; f < numStars; f++) { if (theStars[f].who == i) { BackUpStar(&theStars[f].dest, i); return; } } } } } //-------------------------------------------------------------- AddStar // Adds a star to the star array. void AddStar (short where, short who, short h, short v) { Rect src, bounds; short savedNum; if (numStars >= kMaxStars) return; QSetRect(&src, 0, 0, 32, 31); if ((thisMac.isDepth == 4) && ((h % 2) == 1)) { h--; if (h < 0) h += 2; } QOffsetRect(&src, h, v); QSetRect(&bounds, 0, 0, 32, 31 * 6); savedNum = BackUpToSavedMap(&bounds, where, who); if (savedNum != -1) { BackUpStar(&src, savedNum); theStars[numStars].dest = src; theStars[numStars].mode = RandomInt(6); QSetRect(&theStars[numStars].src, 0, 0, 32, 31); QOffsetRect(&theStars[numStars].src, 0, theStars[numStars].mode * 31); theStars[numStars].who = savedNum; theStars[numStars].link = who; theStars[numStars].where = where; numStars++; } } //-------------------------------------------------------------- StopPendulum // Will set a flag to kill a pendulum. void StopPendulum (short where, short who) { short i; for (i = 0; i < numPendulums; i++) { if ((pendulums[i].link == who) && (pendulums[i].where == where)) pendulums[i].active = false; } } //-------------------------------------------------------------- StopStar // Will set a flag to kill a star. void StopStar (short where, short who) { short i; for (i = 0; i < numStars; i++) { if ((theStars[i].link == who) && (theStars[i].where == where)) theStars[i].mode = -1; } } //-------------------------------------------------------------- AddAShreddedGlider // Adds a shredded glider. void AddAShreddedGlider (Rect *bounds) { if (numShredded > kMaxShredded) return; shreds[numShredded].bounds.left = bounds->left + 4; shreds[numShredded].bounds.right = shreds[numShredded].bounds.left + 40; shreds[numShredded].bounds.top = bounds->top + 14; shreds[numShredded].bounds.bottom = shreds[numShredded].bounds.top; shreds[numShredded].frame = 0; numShredded++; } //-------------------------------------------------------------- RemoveShreds // Remves the shredded glider. void RemoveShreds (void) { short largest, who, i; largest = 0; who = -1; for (i = 0; i < numShredded; i++) { if (shreds[i].frame > largest) { largest = shreds[i].frame; who = i; } } if (who != -1) { if (who == (numShredded - 1)) { numShredded--; shreds[who].frame = 0; } else { numShredded--; shreds[who].bounds = shreds[numShredded].bounds; shreds[who].frame = shreds[numShredded].frame; shreds[numShredded].frame = 0; } } } //-------------------------------------------------------------- ZeroFlamesAndTheLike // Zeroes all counters that indicate the number of flames, pendulums, etc thereÉ // are in a room. Called before a room is drawn. As the room is drawn, theÉ // above functions are called and the counters incremented as objects of theÉ // specified types are drawn. void ZeroFlamesAndTheLike (void) { numFlames = 0; numTikiFlames = 0; numCoals = 0; numPendulums = 0; numGrease = 0; numStars = 0; numShredded = 0; numChimes = 0; } \ No newline at end of file diff --git a/Sources/Dynamics.c b/Sources/Dynamics.c deleted file mode 100755 index 37ed103..0000000 --- a/Sources/Dynamics.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Dynamics.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" #include "MainWindow.h" #include "Objects.h" #include "RectUtils.h" #include "Room.h" #define kShoveVelocity 8 Rect breadSrc[kNumBreadPicts]; extern dynaPtr dinahs; extern bandPtr bands; extern short numBands, tvWithMovieNumber; extern Boolean evenFrame, twoPlayerGame, onePlayerLeft, playerDead; //============================================================== Functions //-------------------------------------------------------------- CheckDynamicCollision // Checks for a collision betwen the glider and one of the dynamic objects. // For example, did the glider hit a flying piece of toast? void CheckDynamicCollision (short who, gliderPtr thisGlider, Boolean doOffset) { Rect dinahRect; dinahRect = dinahs[who].dest; if (doOffset) QOffsetRect(&dinahRect, -playOriginH, -playOriginV); if (SectGlider(thisGlider, &dinahRect, true)) { if ((thisGlider->mode == kGliderNormal) || (thisGlider->mode == kGliderFaceLeft) || (thisGlider->mode == kGliderFaceRight) || (thisGlider->mode == kGliderBurning) || (thisGlider->mode == kGliderGoingFoil) || (thisGlider->mode == kGliderLosingFoil)) { if ((foilTotal > 0) || (thisGlider->mode == kGliderLosingFoil)) { if (IsRectLeftOfRect(&dinahRect, &thisGlider->dest)) thisGlider->hDesiredVel = kShoveVelocity; else thisGlider->hDesiredVel = -kShoveVelocity; if (dinahs[who].vVel < 0) thisGlider->vDesiredVel = dinahs[who].vVel; PlayPrioritySound(kFoilHitSound, kFoilHitPriority); if ((evenFrame) && (foilTotal > 0)) { foilTotal--; if (foilTotal <= 0) StartGliderFoilLosing(thisGlider); } } else { StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } } } //-------------------------------------------------------------- DidBandHitDynamic // Checks to see if a rubber band struck a dynamic. Boolean DidBandHitDynamic (short who) { Rect dinahRect; short i; Boolean collided; dinahRect = dinahs[who].dest; for (i = 0; i < numBands; i++) { if (bands[i].dest.bottom < dinahRect.top) collided = false; else if (bands[i].dest.top > dinahRect.bottom) collided = false; else if (bands[i].dest.right < dinahRect.left) collided = false; else if (bands[i].dest.left > dinahRect.right) collided = false; else collided = true; if (collided) break; } return (collided); } //-------------------------------------------------------------- RenderToast // The following handful of functions handle drawing specific "dynamic" objecsts. void RenderToast (short who) { Rect src, dest; short vClip; if (dinahs[who].moving) { dest = dinahs[who].dest; QOffsetRect(&dest, playOriginH, playOriginV); src = breadSrc[dinahs[who].frame]; vClip = dinahs[who].dest.bottom - dinahs[who].hVel; if (vClip > 0) { src.bottom -= vClip; dest.bottom -= vClip; } CopyMask((BitMap *)*GetGWorldPixMap(toastSrcMap), (BitMap *)*GetGWorldPixMap(toastMaskMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &src, &src, &dest); AddRectToBackRects(&dest); dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); } } //-------------------------------------------------------------- RenderBalloon void RenderBalloon (short who) { Rect src, dest; if (dinahs[who].moving) { dest = dinahs[who].dest; QOffsetRect(&dest, playOriginH, playOriginV); src = balloonSrc[dinahs[who].frame]; CopyMask((BitMap *)*GetGWorldPixMap(balloonSrcMap), (BitMap *)*GetGWorldPixMap(balloonMaskMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &src, &src, &dest); AddRectToBackRects(&dest); dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); } } //-------------------------------------------------------------- RenderCopter void RenderCopter (short who) { Rect src, dest; if (dinahs[who].moving) { dest = dinahs[who].dest; QOffsetRect(&dest, playOriginH, playOriginV); src = copterSrc[dinahs[who].frame]; CopyMask((BitMap *)*GetGWorldPixMap(copterSrcMap), (BitMap *)*GetGWorldPixMap(copterMaskMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &src, &src, &dest); AddRectToBackRects(&dest); dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); } } //-------------------------------------------------------------- RenderDart void RenderDart (short who) { Rect src, dest; if (dinahs[who].moving) { dest = dinahs[who].dest; QOffsetRect(&dest, playOriginH, playOriginV); src = dartSrc[dinahs[who].frame]; CopyMask((BitMap *)*GetGWorldPixMap(dartSrcMap), (BitMap *)*GetGWorldPixMap(dartMaskMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &src, &src, &dest); AddRectToBackRects(&dest); dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); } } //-------------------------------------------------------------- RenderBall void RenderBall (short who) { Rect src, dest; dest = dinahs[who].dest; QOffsetRect(&dest, playOriginH, playOriginV); src = ballSrc[dinahs[who].frame]; CopyMask((BitMap *)*GetGWorldPixMap(ballSrcMap), (BitMap *)*GetGWorldPixMap(ballMaskMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &src, &src, &dest); AddRectToBackRects(&dest); dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); } //-------------------------------------------------------------- RenderDrip void RenderDrip (short who) { Rect src, dest; dest = dinahs[who].dest; QOffsetRect(&dest, playOriginH, playOriginV); src = dripSrc[dinahs[who].frame]; CopyMask((BitMap *)*GetGWorldPixMap(dripSrcMap), (BitMap *)*GetGWorldPixMap(dripMaskMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &src, &src, &dest); AddRectToBackRects(&dest); dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); } //-------------------------------------------------------------- RenderFish void RenderFish (short who) { Rect src, dest; dest = dinahs[who].dest; QOffsetRect(&dest, playOriginH, playOriginV); src = fishSrc[dinahs[who].frame]; if (dinahs[who].moving) { CopyMask((BitMap *)*GetGWorldPixMap(fishSrcMap), (BitMap *)*GetGWorldPixMap(fishMaskMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &src, &src, &dest); AddRectToBackRects(&dest); dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); } else { CopyBits((BitMap *)*GetGWorldPixMap(fishSrcMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &src, &dest, srcCopy, nil); AddRectToBackRects(&dest); dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); } } //-------------------------------------------------------------- HandleSparkleObject // The following handful of functions are called each game frame and handleÉ // the movement and state of the various types of dynamic objects. void HandleSparkleObject (short who) { Rect tempRect; if (dinahs[who].active) // is it on? { if (dinahs[who].frame <= 0) // is it idle? { // it is idle dinahs[who].timer--; if (dinahs[who].timer <= 0) { dinahs[who].timer = RandomInt(240) + 60;// reset timer dinahs[who].frame = kNumSparkleModes; // time to sparkle tempRect = dinahs[who].dest; AddSparkle(&tempRect); PlayPrioritySound(kMysticSound, kMysticPriority); } } else // it's sparkling dinahs[who].frame--; } else { } } //-------------------------------------------------------------- HandleToast void HandleToast (short who) { Rect dest; if (dinahs[who].moving) { if (evenFrame) { dinahs[who].frame++; if (dinahs[who].frame >= kNumBreadPicts) dinahs[who].frame = 0; } if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == theGlider.which) CheckDynamicCollision(who, &theGlider2, false); else CheckDynamicCollision(who, &theGlider, false); } else { CheckDynamicCollision(who, &theGlider, false); CheckDynamicCollision(who, &theGlider2, false); } } else CheckDynamicCollision(who, &theGlider, false); VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); dinahs[who].whole = dinahs[who].dest; if (dinahs[who].vVel > 0) dinahs[who].whole.top -= dinahs[who].vVel; else dinahs[who].whole.bottom -= dinahs[who].vVel; dinahs[who].vVel++; // falls if (dinahs[who].vVel > dinahs[who].count) { dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); dinahs[who].moving = false; dinahs[who].frame = dinahs[who].timer; PlayPrioritySound(kToastLandSound, kToastLandPriority); } } else { if (dinahs[who].active) dinahs[who].frame--; if (dinahs[who].frame <= 0) { if (dinahs[who].active) { dinahs[who].vVel = (short)-dinahs[who].count; dinahs[who].frame = 0; dinahs[who].moving = true; PlayPrioritySound(kToastLaunchSound, kToastLaunchPriority); } else dinahs[who].frame = dinahs[who].timer; } } } //-------------------------------------------------------------- HandleMacPlus void HandleMacPlus (short who) { if (dinahs[who].timer > 0) { dinahs[who].timer--; if (dinahs[who].active) { if (dinahs[who].timer == 0) AddRectToWorkRects(&dinahs[who].dest); else if (dinahs[who].timer == 1) { PlayPrioritySound(kMacBeepSound, kMacBeepPriority); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &plusScreen2, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } else if (dinahs[who].timer == 30) PlayPrioritySound(kMacOnSound, kMacOnPriority); } else { if (dinahs[who].timer == 0) AddRectToWorkRects(&dinahs[who].dest); else if (dinahs[who].timer == 1) { PlayPrioritySound(kMacOffSound, kMacOffPriority); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &plusScreen1, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } } } } //-------------------------------------------------------------- HandleTV void HandleTV (short who) { if (dinahs[who].timer > 0) { dinahs[who].timer--; if (dinahs[who].active) { if (dinahs[who].timer == 0) { if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (who == tvWithMovieNumber)) { } else { AddRectToWorkRects(&dinahs[who].dest); } } else if (dinahs[who].timer == 1) { PlayPrioritySound(kTVOnSound, kTVOnPriority); if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (who == tvWithMovieNumber)) { } else { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &tvScreen2, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } } } else { if (dinahs[who].timer == 0) AddRectToWorkRects(&dinahs[who].dest); else if (dinahs[who].timer == 1) { PlayPrioritySound(kTVOffSound, kTVOffPriority); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &tvScreen1, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } } } } //-------------------------------------------------------------- HandleCoffee void HandleCoffee (short who) { if (dinahs[who].timer > 0) { dinahs[who].timer--; if (dinahs[who].active) { if (dinahs[who].timer == 0) { AddRectToWorkRects(&dinahs[who].dest); dinahs[who].timer = 200 + RandomInt(200); } else if (dinahs[who].timer == 1) { PlayPrioritySound(kMacOnSound, kMacOnPriority); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &coffeeLight2, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } else if (dinahs[who].timer == 100) { PlayPrioritySound(kCoffeeSound, kCoffeePriority); dinahs[who].timer = 200 + RandomInt(200); } } else { if (dinahs[who].timer == 0) AddRectToWorkRects(&dinahs[who].dest); else if (dinahs[who].timer == 1) { PlayPrioritySound(kMacOffSound, kMacOffPriority); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &coffeeLight1, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } } } } //-------------------------------------------------------------- HandleOutlet void HandleOutlet (short who) { if (dinahs[who].position != 0) { dinahs[who].timer--; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == theGlider.which) CheckDynamicCollision(who, &theGlider2, false); else CheckDynamicCollision(who, &theGlider, false); } else { CheckDynamicCollision(who, &theGlider, true); CheckDynamicCollision(who, &theGlider2, true); } } else CheckDynamicCollision(who, &theGlider, true); if (dinahs[who].timer <= 0) { dinahs[who].frame = 0; dinahs[who].position = 0; dinahs[who].timer = dinahs[who].count; } else { if ((dinahs[who].timer % 5) == 0) PlayPrioritySound(kZapSound, kZapPriority); dinahs[who].frame++; if (dinahs[who].frame >= kNumOutletPicts) dinahs[who].frame = 1; } if ((dinahs[who].position != 0) || (dinahs[who].hVel > 0)) { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &outletSrc[dinahs[who].frame], &dinahs[who].dest, srcCopy, nil); } else { // SetPort((GrafPtr)workSrcMap); PaintRect(&dinahs[who].dest); } AddRectToWorkRects(&dinahs[who].dest); } else { if (dinahs[who].active) dinahs[who].timer--; if (dinahs[who].timer <= 0) { if (dinahs[who].active) { dinahs[who].position = 1; dinahs[who].timer = kLengthOfZap; PlayPrioritySound(kZapSound, kZapPriority); } else dinahs[who].timer = dinahs[who].count; } } } //-------------------------------------------------------------- HandleVCR void HandleVCR (short who) { if (dinahs[who].timer > 0) { dinahs[who].timer--; if (dinahs[who].active) { if (dinahs[who].timer == 0) { AddRectToWorkRects(&dinahs[who].dest); dinahs[who].timer = 115; } else if (dinahs[who].timer == 5) PlayPrioritySound(kMacOnSound, kMacOnPriority); else if (dinahs[who].timer == 1) { PlayPrioritySound(kVCRSound, kVCRPriority); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &vcrTime2, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } else if (dinahs[who].timer == 100) { AddRectToWorkRects(&dinahs[who].dest); dinahs[who].timer = 115; dinahs[who].frame = 1 - dinahs[who].frame; } else if (dinahs[who].timer == 101) { if (dinahs[who].frame == 0) { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &vcrTime2, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } else { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &vcrTime1, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } } } else { if (dinahs[who].timer == 0) AddRectToWorkRects(&dinahs[who].dest); else if (dinahs[who].timer == 1) { PlayPrioritySound(kMacOffSound, kMacOffPriority); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &vcrTime1, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } } } } //-------------------------------------------------------------- HandleStereo void HandleStereo (short who) { if (dinahs[who].timer > 0) { dinahs[who].timer--; if (dinahs[who].active) { if (dinahs[who].timer == 0) { AddRectToWorkRects(&dinahs[who].dest); ToggleMusicWhilePlaying(); } else if (dinahs[who].timer == 1) { PlayPrioritySound(kMacOnSound, kMacOnPriority); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &stereoLight2, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } } else { if (dinahs[who].timer == 0) { AddRectToWorkRects(&dinahs[who].dest); ToggleMusicWhilePlaying(); } else if (dinahs[who].timer == 1) { PlayPrioritySound(kMacOffSound, kMacOffPriority); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &stereoLight1, &dinahs[who].dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } } } } //-------------------------------------------------------------- HandleMicrowave void HandleMicrowave (short who) { Rect dest; if (dinahs[who].timer > 0) { dinahs[who].timer--; if (dinahs[who].active) { if (dinahs[who].timer == 0) AddRectToWorkRects(&dinahs[who].dest); else if (dinahs[who].timer == 1) { PlayPrioritySound(kMacOnSound, kMacOnPriority); dest = dinahs[who].dest; dest.right = dest.left + 16; CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOn, &dest, srcCopy, nil); QOffsetRect(&dest, 16, 0); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOn, &dest, srcCopy, nil); QOffsetRect(&dest, 16, 0); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOn, &dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } } else { if (dinahs[who].timer == 0) AddRectToWorkRects(&dinahs[who].dest); else if (dinahs[who].timer == 1) { PlayPrioritySound(kMacOffSound, kMacOffPriority); dest = dinahs[who].dest; dest.right = dest.left + 16; CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOff, &dest, srcCopy, nil); QOffsetRect(&dest, 16, 0); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOff, &dest, srcCopy, nil); QOffsetRect(&dest, 16, 0); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOff, &dest, srcCopy, nil); AddRectToBackRects(&dinahs[who].dest); } } } } \ No newline at end of file diff --git a/Sources/Dynamics2.c b/Sources/Dynamics2.c deleted file mode 100755 index 0300e7d..0000000 --- a/Sources/Dynamics2.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Dynamics2.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "RectUtils.h" #define kBalloonStop 8 #define kBalloonStart 310 #define kCopterStart 8 #define kCopterStop 310 #define kDartVelocity 6 #define kDartStop 310 #define kEnemyDropSpeed 8 extern dynaPtr dinahs; extern short numBands; extern Boolean evenFrame, twoPlayerGame, onePlayerLeft, playerDead; //============================================================== Functions //-------------------------------------------------------------- HandleBalloon void HandleBalloon (short who) { Rect dest; if (dinahs[who].moving) { if (dinahs[who].vVel < 0) { if (evenFrame) { dinahs[who].frame++; if (dinahs[who].frame >= 6) dinahs[who].frame = 0; } if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == theGlider.which) CheckDynamicCollision(who, &theGlider2, false); else CheckDynamicCollision(who, &theGlider, false); } else { CheckDynamicCollision(who, &theGlider, false); CheckDynamicCollision(who, &theGlider2, false); } } else CheckDynamicCollision(who, &theGlider, false); if ((numBands > 0) && (DidBandHitDynamic(who))) { dinahs[who].frame = 6; dinahs[who].vVel = kEnemyDropSpeed; PlayPrioritySound(kPopSound, kPopPriority); } else { VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); dinahs[who].whole = dinahs[who].dest; dinahs[who].whole.bottom -= dinahs[who].vVel; } } else { if (evenFrame) { dinahs[who].frame++; if (dinahs[who].frame >= 8) dinahs[who].frame = 6; } VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); dinahs[who].whole = dinahs[who].dest; dinahs[who].whole.top -= dinahs[who].vVel; } if ((dinahs[who].dest.top <= kBalloonStop) || (dinahs[who].dest.bottom >= kBalloonStart)) { dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); dest = dinahs[who].dest; AddSparkle(&dest); PlayPrioritySound(kEnemyOutSound, kEnemyOutPriority); dinahs[who].moving = false; dinahs[who].vVel = -2; dinahs[who].timer = dinahs[who].count; dinahs[who].dest.bottom = kBalloonStart; dinahs[who].dest.top = dinahs[who].dest.bottom - RectTall(&balloonSrc[0]); dinahs[who].whole = dinahs[who].dest; } } else // balloon is idle, waiting to appear { if (dinahs[who].active) { dinahs[who].timer--; if (dinahs[who].timer <= 0) { dinahs[who].moving = true; if (dinahs[who].count < kStartSparkle) { dest = dinahs[who].dest; AddSparkle(&dest); PlayPrioritySound(kEnemyInSound, kEnemyInPriority); } } else if (dinahs[who].timer == kStartSparkle) { dest = dinahs[who].dest; AddSparkle(&dest); PlayPrioritySound(kEnemyInSound, kEnemyInPriority); } } } } //-------------------------------------------------------------- HandleCopter void HandleCopter (short who) { Rect dest; if (dinahs[who].moving) // is 'copter about? { if (dinahs[who].hVel != 0) // 'copter was not shot { dinahs[who].frame++; if (dinahs[who].frame >= 8) dinahs[who].frame = 0; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == theGlider.which) CheckDynamicCollision(who, &theGlider2, false); else CheckDynamicCollision(who, &theGlider, false); } else { CheckDynamicCollision(who, &theGlider, false); CheckDynamicCollision(who, &theGlider2, false); } } else CheckDynamicCollision(who, &theGlider, false); if ((numBands > 0) && (DidBandHitDynamic(who))) { dinahs[who].frame = 8; dinahs[who].hVel = 0; dinahs[who].vVel = kEnemyDropSpeed; PlayPrioritySound(kPaperCrunchSound, kPaperCrunchPriority); } else { HOffsetRect(&dinahs[who].dest, dinahs[who].hVel); VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); dinahs[who].whole = dinahs[who].dest; dinahs[who].whole.top -= dinahs[who].vVel; if (dinahs[who].hVel < 0) dinahs[who].whole.right -= dinahs[who].hVel; else dinahs[who].whole.left -= dinahs[who].hVel; } } else // 'copter was shot { dinahs[who].frame++; if (dinahs[who].frame >= 10) dinahs[who].frame = 8; VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); dinahs[who].whole = dinahs[who].dest; dinahs[who].whole.top -= dinahs[who].vVel; } if ((dinahs[who].dest.top <= kCopterStart) || (dinahs[who].dest.bottom >= kCopterStop)) { dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); dest = dinahs[who].dest; AddSparkle(&dest); PlayPrioritySound(kEnemyOutSound, kEnemyOutPriority); dinahs[who].moving = false; dinahs[who].vVel = 2; if (dinahs[who].type == kCopterLf) dinahs[who].hVel = -1; else dinahs[who].hVel = 1; dinahs[who].timer = dinahs[who].count; dinahs[who].dest.top = kCopterStart; dinahs[who].dest.bottom = dinahs[who].dest.top + RectTall(&copterSrc[0]); dinahs[who].dest.left = dinahs[who].position; dinahs[who].dest.right = dinahs[who].dest.left + 32; dinahs[who].whole = dinahs[who].dest; } } else { if (dinahs[who].active) { dinahs[who].timer--; if (dinahs[who].timer <= 0) { dinahs[who].moving = true; if (dinahs[who].count < kStartSparkle) { dest = dinahs[who].dest; AddSparkle(&dest); PlayPrioritySound(kEnemyInSound, kEnemyInPriority); } } else if (dinahs[who].timer == kStartSparkle) { dest = dinahs[who].dest; AddSparkle(&dest); PlayPrioritySound(kEnemyInSound, kEnemyInPriority); } } } } //-------------------------------------------------------------- HandleDart void HandleDart (short who) { Rect dest; if (dinahs[who].moving) // Dart has appeared { if (dinahs[who].hVel != 0) // meaning it isn't falling { if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == theGlider.which) CheckDynamicCollision(who, &theGlider2, false); else CheckDynamicCollision(who, &theGlider, false); } else { CheckDynamicCollision(who, &theGlider, false); CheckDynamicCollision(who, &theGlider2, false); } } else CheckDynamicCollision(who, &theGlider, false); if ((numBands > 0) && (DidBandHitDynamic(who))) { if (dinahs[who].type == kDartLf) dinahs[who].frame = 1; else dinahs[who].frame = 3; dinahs[who].hVel = 0; dinahs[who].vVel = kEnemyDropSpeed; PlayPrioritySound(kPaperCrunchSound, kPaperCrunchPriority); } else { HOffsetRect(&dinahs[who].dest, dinahs[who].hVel); VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); dinahs[who].whole = dinahs[who].dest; dinahs[who].whole.top -= dinahs[who].vVel; if (dinahs[who].hVel < 0) dinahs[who].whole.right -= dinahs[who].hVel; else dinahs[who].whole.left -= dinahs[who].hVel; } } else // dart is falling straight down { VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); dinahs[who].whole = dinahs[who].dest; dinahs[who].whole.top -= dinahs[who].vVel; } if ((dinahs[who].dest.left <= 0) || (dinahs[who].dest.right >= kRoomWide) || (dinahs[who].dest.bottom >= kDartStop)) { dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); dest = dinahs[who].dest; AddSparkle(&dest); PlayPrioritySound(kEnemyOutSound, kEnemyOutPriority); dinahs[who].moving = false; dinahs[who].vVel = 2; if (dinahs[who].type == kDartLf) { dinahs[who].frame = 0; dinahs[who].hVel = -kDartVelocity; dinahs[who].dest.right = kRoomWide; dinahs[who].dest.left = dinahs[who].dest.right - RectWide(&dartSrc[0]); } else { dinahs[who].frame = 2; dinahs[who].hVel = kDartVelocity; dinahs[who].dest.left = 0; dinahs[who].dest.right = dinahs[who].dest.left + RectWide(&dartSrc[0]); } dinahs[who].timer = dinahs[who].count; dinahs[who].dest.top = dinahs[who].position; dinahs[who].dest.bottom = dinahs[who].dest.top + RectTall(&dartSrc[0]); dinahs[who].whole = dinahs[who].dest; } } else { if (dinahs[who].active) { dinahs[who].timer--; if (dinahs[who].timer <= 0) { dinahs[who].moving = true; if (dinahs[who].count < kStartSparkle) { dest = dinahs[who].dest; AddSparkle(&dest); PlayPrioritySound(kEnemyInSound, kEnemyInPriority); } } else if (dinahs[who].timer == kStartSparkle) { dest = dinahs[who].dest; AddSparkle(&dest); PlayPrioritySound(kEnemyInSound, kEnemyInPriority); } } } } //-------------------------------------------------------------- HandleBall void HandleBall (short who) { if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == theGlider.which) CheckDynamicCollision(who, &theGlider2, false); else CheckDynamicCollision(who, &theGlider, false); } else { CheckDynamicCollision(who, &theGlider, false); CheckDynamicCollision(who, &theGlider2, false); } } else CheckDynamicCollision(who, &theGlider, false); if (dinahs[who].moving) // is ball bouncing? { VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); if (dinahs[who].dest.bottom >= dinahs[who].position) // bounce! { dinahs[who].whole = dinahs[who].dest; dinahs[who].whole.top -= dinahs[who].vVel; dinahs[who].whole.bottom = dinahs[who].position; dinahs[who].dest.bottom = dinahs[who].position; dinahs[who].dest.top = dinahs[who].dest.bottom - 32; if (dinahs[who].active) dinahs[who].vVel = dinahs[who].count; else { dinahs[who].vVel = -((dinahs[who].vVel * 3) / 4); if (dinahs[who].vVel == 0) dinahs[who].moving = false; // stop bounce } if (dinahs[who].whole.bottom < dinahs[who].dest.bottom) dinahs[who].whole.bottom = dinahs[who].dest.bottom; PlayPrioritySound(kBounceSound, kBouncePriority); if (dinahs[who].moving) dinahs[who].frame = 1; } else { dinahs[who].whole = dinahs[who].dest; if (dinahs[who].vVel > 0) dinahs[who].whole.top -= dinahs[who].vVel; else dinahs[who].whole.bottom -= dinahs[who].vVel; if (evenFrame) dinahs[who].vVel++; dinahs[who].frame = 0; } } else { if (dinahs[who].active) { dinahs[who].vVel = dinahs[who].count; dinahs[who].moving = true; evenFrame = true; } } } //-------------------------------------------------------------- HandleDrip void HandleDrip (short who) { Rect dest; if (dinahs[who].moving) { if (evenFrame) dinahs[who].frame = 9 - dinahs[who].frame; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == theGlider.which) CheckDynamicCollision(who, &theGlider2, false); else CheckDynamicCollision(who, &theGlider, false); } else { CheckDynamicCollision(who, &theGlider, false); CheckDynamicCollision(who, &theGlider2, false); } } else CheckDynamicCollision(who, &theGlider, false); VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); if (dinahs[who].dest.bottom >= dinahs[who].position) { dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); dinahs[who].dest.top = dinahs[who].hVel; dinahs[who].dest.bottom = dinahs[who].dest.top + 12; PlayPrioritySound(kDropSound, kDropPriority); dinahs[who].vVel = 0; dinahs[who].timer = dinahs[who].count; dinahs[who].frame = 3; dinahs[who].moving = false; } else { dinahs[who].whole = dinahs[who].dest; dinahs[who].whole.top -= dinahs[who].vVel; if (evenFrame) dinahs[who].vVel++; } } else { if (dinahs[who].active) { dinahs[who].timer--; if (dinahs[who].timer == 6) dinahs[who].frame = 0; else if (dinahs[who].timer == 4) dinahs[who].frame = 1; else if (dinahs[who].timer == 2) dinahs[who].frame = 2; else if (dinahs[who].timer <= 0) { VOffsetRect(&dinahs[who].dest, 3); dinahs[who].whole = dinahs[who].dest; dinahs[who].moving = true; dinahs[who].frame = 4; PlayPrioritySound(kDripSound, kDripPriority); } } } } //-------------------------------------------------------------- HandleFish void HandleFish (short who) { Rect dest; if (dinahs[who].moving) // fish leaping { if ((dinahs[who].vVel >= 0) && (dinahs[who].frame < 7)) dinahs[who].frame++; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == theGlider.which) CheckDynamicCollision(who, &theGlider2, false); else CheckDynamicCollision(who, &theGlider, false); } else { CheckDynamicCollision(who, &theGlider, false); CheckDynamicCollision(who, &theGlider2, false); } } else CheckDynamicCollision(who, &theGlider, false); VOffsetRect(&dinahs[who].dest, dinahs[who].vVel); if (dinahs[who].dest.bottom >= dinahs[who].position) // splash down { dest = dinahs[who].whole; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); dinahs[who].dest.bottom = dinahs[who].position; dinahs[who].dest.top = dinahs[who].dest.bottom - 16; dinahs[who].whole = dinahs[who].dest; dinahs[who].whole.top -= 2; PlayPrioritySound(kDropSound, kDropPriority); dinahs[who].vVel = dinahs[who].count; dinahs[who].timer = dinahs[who].hVel; dinahs[who].frame = 0; dinahs[who].moving = false; PlayPrioritySound(kFishInSound, kFishInPriority); } else { dinahs[who].whole = dinahs[who].dest; if (dinahs[who].vVel > 0) dinahs[who].whole.top -= dinahs[who].vVel; else dinahs[who].whole.bottom -= dinahs[who].vVel; if (evenFrame) dinahs[who].vVel++; } } else // fish idle { dinahs[who].whole = dinahs[who].dest; if ((dinahs[who].timer & 0x0003) == 0x0003) { dinahs[who].frame++; if (dinahs[who].frame > 3) dinahs[who].frame = 0; if ((dinahs[who].frame == 1) || (dinahs[who].frame == 2)) { dinahs[who].dest.top++; dinahs[who].dest.bottom++; dinahs[who].whole.bottom++; } else { dinahs[who].dest.top--; dinahs[who].dest.bottom--; dinahs[who].whole.top--; } } if (dinahs[who].active) { dinahs[who].timer--; if (dinahs[who].timer <= 0) // fish leaps { dinahs[who].whole = dinahs[who].dest; dinahs[who].moving = true; dinahs[who].frame = 4; PlayPrioritySound(kFishOutSound, kFishOutPriority); } } } } \ No newline at end of file diff --git a/Sources/Dynamics3.c b/Sources/Dynamics3.c deleted file mode 100755 index 10c50d0..0000000 --- a/Sources/Dynamics3.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Dynamics3.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "RectUtils.h" #define kBalloonStart 310 #define kCopterStart 8 #define kDartVelocity 6 dynaPtr dinahs; short numDynamics; extern Rect breadSrc[]; extern short numLights; extern Boolean evenFrame; //============================================================== Functions //-------------------------------------------------------------- HandleDynamics // This is the master function that calls all the specific handlers above. void HandleDynamics (void) { short i; for (i = 0; i < numDynamics; i++) { switch (dinahs[i].type) { case kSparkle: HandleSparkleObject(i); break; case kToaster: HandleToast(i); break; case kMacPlus: HandleMacPlus(i); break; case kTV: HandleTV(i); break; case kCoffee: HandleCoffee(i); break; case kOutlet: HandleOutlet(i); break; case kVCR: HandleVCR(i); break; case kStereo: HandleStereo(i); break; case kMicrowave: HandleMicrowave(i); break; case kBalloon: HandleBalloon(i); break; case kCopterLf: case kCopterRt: HandleCopter(i); break; case kDartLf: case kDartRt: HandleDart(i); break; case kBall: HandleBall(i); break; case kDrip: HandleDrip(i); break; case kFish: HandleFish(i); break; default: break; } } } //-------------------------------------------------------------- HandleDynamics // This is the master function that calls all the various rendering handlersÉ // above. void RenderDynamics (void) { short i; for (i = 0; i < numDynamics; i++) { switch (dinahs[i].type) { case kToaster: RenderToast(i); break; case kBalloon: RenderBalloon(i); break; case kCopterLf: case kCopterRt: RenderCopter(i); break; case kDartLf: case kDartRt: RenderDart(i); break; case kBall: RenderBall(i); break; case kDrip: RenderDrip(i); break; case kFish: RenderFish(i); break; default: break; } } } //-------------------------------------------------------------- ZeroDinahs // This clears all dynamics - zeros them all out. Used to initialize them. void ZeroDinahs (void) { short i; for (i = 0; i < kMaxDynamicObs; i++) { dinahs[i].type = kObjectIsEmpty; QSetRect(&dinahs[i].dest, 0, 0, 0, 0); QSetRect(&dinahs[i].whole, 0, 0, 0, 0); dinahs[i].hVel = 0; dinahs[i].vVel = 0; dinahs[i].count = 0; dinahs[i].frame = 0; dinahs[i].timer = 0; dinahs[i].position = 0; dinahs[i].room = 0; dinahs[i].byte0 = 0; dinahs[i].active = false; } numDynamics = 0; } //-------------------------------------------------------------- AddDynamicObject // When a room is being drawn, various dynamic objects are pointed here. // This function sets up the structures to handle them. short AddDynamicObject (short what, Rect *where, objectType *who, short room, short index, Boolean isOn) { short position, velocity; Boolean lilFrame; if (numDynamics >= kMaxDynamicObs) return (-1); dinahs[numDynamics].type = what; switch (what) { case kSparkle: dinahs[numDynamics].dest = sparkleSrc[0]; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left, where->top); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = 0; dinahs[numDynamics].vVel = 0; dinahs[numDynamics].count = 0; dinahs[numDynamics].frame = 0; dinahs[numDynamics].timer = RandomInt(60) + 15; dinahs[numDynamics].position = 0; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; case kToaster: dinahs[numDynamics].dest = breadSrc[0]; CenterRectInRect(&dinahs[numDynamics].dest, where); VOffsetRect(&dinahs[numDynamics].dest, where->top - dinahs[numDynamics].dest.top); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = where->top + 2; // hVel used as clip position = who->data.g.height; // reverse engineer init. vel. velocity = 0; do { velocity++; position -= velocity; } while (position > 0); dinahs[numDynamics].vVel = -velocity; dinahs[numDynamics].count = velocity; // count = initial velocity dinahs[numDynamics].frame = (short)who->data.g.delay * 3; dinahs[numDynamics].timer = dinahs[numDynamics].frame; dinahs[numDynamics].position = 0; // launch/idle state dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; case kMacPlus: dinahs[numDynamics].dest = plusScreen1; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left + playOriginH + 10, where->top + playOriginV + 7); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = 0; dinahs[numDynamics].vVel = 0; dinahs[numDynamics].count = 0; dinahs[numDynamics].frame = 0; dinahs[numDynamics].timer = 0; dinahs[numDynamics].position = 0; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; case kTV: dinahs[numDynamics].dest = tvScreen1; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left + playOriginH + 17, where->top + playOriginV + 10); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = 0; dinahs[numDynamics].vVel = 0; dinahs[numDynamics].count = 0; dinahs[numDynamics].frame = 0; dinahs[numDynamics].timer = 0; dinahs[numDynamics].position = 0; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; case kCoffee: dinahs[numDynamics].dest = coffeeLight1; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left + playOriginH + 32, where->top + playOriginV + 57); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = 0; dinahs[numDynamics].vVel = 0; dinahs[numDynamics].count = 0; dinahs[numDynamics].frame = 0; if (isOn) dinahs[numDynamics].timer = 200; else dinahs[numDynamics].timer = 0; dinahs[numDynamics].position = 0; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; case kOutlet: dinahs[numDynamics].dest = outletSrc[0]; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left + playOriginH, where->top + playOriginV); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = numLights; dinahs[numDynamics].vVel = 0; dinahs[numDynamics].count = ((short)who->data.g.delay * 6) / kTicksPerFrame; dinahs[numDynamics].frame = 0; dinahs[numDynamics].timer = dinahs[numDynamics].count; dinahs[numDynamics].position = 0; // launch/idle state dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; case kVCR: dinahs[numDynamics].dest = vcrTime1; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left + playOriginH + 64, where->top + playOriginV + 6); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = 0; dinahs[numDynamics].vVel = 0; dinahs[numDynamics].count = 0; dinahs[numDynamics].frame = 0; if (isOn) dinahs[numDynamics].timer = 115; else dinahs[numDynamics].timer = 0; dinahs[numDynamics].position = 0; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; case kStereo: dinahs[numDynamics].dest = stereoLight1; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left + playOriginH + 56, where->top + playOriginV + 20); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = 0; dinahs[numDynamics].vVel = 0; dinahs[numDynamics].count = 0; dinahs[numDynamics].frame = 0; dinahs[numDynamics].timer = 0; dinahs[numDynamics].position = 0; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; case kMicrowave: dinahs[numDynamics].dest = microOn; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left + playOriginH + 14, where->top + playOriginV + 13); dinahs[numDynamics].dest.right = dinahs[numDynamics].dest.left + 48; dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = 0; dinahs[numDynamics].vVel = 0; dinahs[numDynamics].count = 0; dinahs[numDynamics].frame = 0; dinahs[numDynamics].timer = 0; dinahs[numDynamics].position = 0; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; case kBalloon: dinahs[numDynamics].dest = balloonSrc[0]; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left, 0); dinahs[numDynamics].dest.bottom = kBalloonStart; dinahs[numDynamics].dest.top = dinahs[numDynamics].dest.bottom - RectTall(&balloonSrc[0]); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = 0; dinahs[numDynamics].vVel = -2; dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; dinahs[numDynamics].frame = 0; dinahs[numDynamics].timer = dinahs[numDynamics].count; dinahs[numDynamics].position = 0; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; // initially idle break; case kCopterLf: case kCopterRt: dinahs[numDynamics].dest = copterSrc[0]; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left, 0); dinahs[numDynamics].dest.top = kCopterStart; dinahs[numDynamics].dest.bottom = dinahs[numDynamics].dest.top + RectTall(&copterSrc[0]); dinahs[numDynamics].whole = dinahs[numDynamics].dest; if (what == kCopterLf) dinahs[numDynamics].hVel = -1; else dinahs[numDynamics].hVel = 1; dinahs[numDynamics].vVel = 2; dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; dinahs[numDynamics].frame = 0; dinahs[numDynamics].timer = dinahs[numDynamics].count; dinahs[numDynamics].position = dinahs[numDynamics].dest.left; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; // initially idle break; case kDartLf: case kDartRt: dinahs[numDynamics].dest = dartSrc[0]; ZeroRectCorner(&dinahs[numDynamics].dest); if (what == kDartLf) { QOffsetRect(&dinahs[numDynamics].dest, kRoomWide - RectWide(&dartSrc[0]), where->top); dinahs[numDynamics].hVel = -kDartVelocity; dinahs[numDynamics].frame = 0; } else { QOffsetRect(&dinahs[numDynamics].dest, 0, where->top); dinahs[numDynamics].hVel = kDartVelocity; dinahs[numDynamics].frame = 2; } dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].vVel = 2; dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; dinahs[numDynamics].timer = dinahs[numDynamics].count; dinahs[numDynamics].position = dinahs[numDynamics].dest.top; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; // initially idle break; case kBall: dinahs[numDynamics].dest = ballSrc[0]; ZeroRectCorner(&dinahs[numDynamics].dest); QOffsetRect(&dinahs[numDynamics].dest, where->left, where->top); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = 0; position = who->data.h.length; // reverse engineer init. vel. velocity = 0; evenFrame = true; lilFrame = true; do { if (lilFrame) velocity++; lilFrame = !lilFrame; position -= velocity; } while (position > 0); dinahs[numDynamics].vVel = -velocity; dinahs[numDynamics].moving = false; dinahs[numDynamics].count = -velocity; // count = initial velocity dinahs[numDynamics].frame = 0; dinahs[numDynamics].timer = 0; dinahs[numDynamics].position = dinahs[numDynamics].dest.bottom; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].active = isOn; break; case kDrip: dinahs[numDynamics].dest = dripSrc[0]; CenterRectInRect(&dinahs[numDynamics].dest, where); VOffsetRect(&dinahs[numDynamics].dest, where->top - dinahs[numDynamics].dest.top); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = dinahs[numDynamics].dest.top; // remember dinahs[numDynamics].vVel = 0; dinahs[numDynamics].count = ((short)who->data.h.delay * 6) / kTicksPerFrame; dinahs[numDynamics].frame = 3; dinahs[numDynamics].timer = dinahs[numDynamics].count; dinahs[numDynamics].position = dinahs[numDynamics].dest.top + who->data.h.length; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; case kFish: dinahs[numDynamics].dest = fishSrc[0]; QOffsetRect(&dinahs[numDynamics].dest, where->left + 10, where->top + 8); dinahs[numDynamics].whole = dinahs[numDynamics].dest; dinahs[numDynamics].hVel = ((short)who->data.h.delay * 6) / kTicksPerFrame; position = who->data.g.height; // reverse engineer init. vel. velocity = 0; evenFrame = true; lilFrame = true; do { if (lilFrame) velocity++; lilFrame = !lilFrame; position -= velocity; } while (position > 0); dinahs[numDynamics].vVel = -velocity; dinahs[numDynamics].count = -velocity; // count = initial velocity dinahs[numDynamics].frame = 0; dinahs[numDynamics].timer = dinahs[numDynamics].hVel; dinahs[numDynamics].position = dinahs[numDynamics].dest.bottom; dinahs[numDynamics].room = room; dinahs[numDynamics].byte0 = (Byte)index; dinahs[numDynamics].byte1 = 0; dinahs[numDynamics].moving = false; dinahs[numDynamics].active = isOn; break; default: return (-1); break; } numDynamics++; return (numDynamics - 1); } \ No newline at end of file diff --git a/Sources/Environ.c b/Sources/Environ.c deleted file mode 100755 index a1143ba..0000000 --- a/Sources/Environ.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Environ.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include #include "Externs.h" #include "Environ.h" #include #define kSwitchDepthAlert 130 #define kSetMemoryAlert 180 #define kLowMemoryAlert 181 #define kWNETrap 0x60 #define kSetDepthTrap 0xA2 #define kUnimpTrap 0x9F #define kGestaltTrap 0xAD #define kDisplay9Inch 1 #define kDisplay12Inch 2 #define kDisplay13Inch 3 typedef struct { short flags; long mem1; long mem2; } sizeType; //short GetThisVolumeRefNum (void); //long GetThisCurrentDirectoryID (void); //Boolean TrapExists (short); //Boolean DoWeHaveGestalt (void); //Boolean DoWeHaveWNE (void); //Boolean DoWeHaveColor (void); //Boolean DoWeHaveSystem602 (void); //Boolean DoWeHaveSystem605 (void); //Boolean DoWeHaveSystem7 (void); //Boolean DoWeHaveSoundManager3 (void); Boolean DoWeHaveQuickTime (void); Boolean DoWeHaveDragManager (void); Boolean CanWeDisplay8Bit (GDHandle); //Boolean CanWeDisplay4Bit (GDHandle); //Boolean CanWeDisplay1Bit (GDHandle); short HowManyUsableScreens (Boolean, Boolean, Boolean); void GetDeviceRect (Rect *); Boolean AreWeColorOrGrayscale (void); void SwitchDepthOrAbort (void); macEnviron thisMac; extern GDHandle thisGDevice; extern short isDepthPref; extern Boolean dontLoadMusic, dontLoadSounds; //============================================================== Functions //-------------------------------------------------------------- GetThisVolumeRefNum // Get a hard reference number for the current drive volume this app is on. /* short GetThisVolumeRefNum (void) { OSErr theErr; short vRef; theErr = GetVol(nil, &vRef); return (vRef); } */ //-------------------------------------------------------------- GetThisCurrentDirectoryID // Get a hard ID number for the current directory volume this app is in. /* long GetThisCurrentDirectoryID (void) { long dirID; dirID = LMGetCurDirStore(); return (dirID); } */ //-------------------------------------------------------------- TrapExists // Returns whether or not a ToolBox trap exists for the users ROMs/System. /* Boolean TrapExists (short trapNumber) { return ((NGetTrapAddress(trapNumber, ToolTrap) != NGetTrapAddress(kUnimpTrap, ToolTrap))); } */ //-------------------------------------------------------------- DoWeHaveGestalt // Specifically tests for the availablity of the Gestalt() trap. /* Boolean DoWeHaveGestalt (void) { return (TrapExists(kGestaltTrap)); } */ //-------------------------------------------------------------- DoWeHaveWNE // Specifically tests for the availablity of the WaitNextEvent() trap. /* Boolean DoWeHaveWNE (void) { return (TrapExists(kWNETrap)); } */ //-------------------------------------------------------------- DoWeHaveColor // Determines if ROMs support Color QuickDraw (monitor not neccessarily color). /* Boolean DoWeHaveColor (void) { SysEnvRec thisWorld; SysEnvirons(2, &thisWorld); return (thisWorld.hasColorQD); } */ //-------------------------------------------------------------- DoWeHaveSystem602 // Determines if the System version is at least 6.0.2 or more recent. /* Boolean DoWeHaveSystem602 (void) { SysEnvRec thisWorld; Boolean haveIt; SysEnvirons(2, &thisWorld); if (thisWorld.systemVersion >= 0x0602) haveIt = true; else haveIt = false; return (haveIt); } */ //-------------------------------------------------------------- DoWeHaveSystem605 // Determines if the System version is at least 6.0.5 or more recent. /* Boolean DoWeHaveSystem605 (void) { SysEnvRec thisWorld; Boolean haveIt; SysEnvirons(2, &thisWorld); if (thisWorld.systemVersion >= 0x0605) haveIt = true; else haveIt = false; return (haveIt); } / //-------------------------------------------------------------- DoWeHaveSystem7 // Determines if the System version is at least 7.0.0 or more recent. Boolean DoWeHaveSystem7 (void) { SysEnvRec thisWorld; Boolean haveIt; SysEnvirons(2, &thisWorld); if (thisWorld.systemVersion >= 0x0700) haveIt = true; else haveIt = false; return (haveIt); } //-------------------------------------------------------------- DoWeHaveSoundManager3 // Determines if the Sound Manager version is at least 3.0.0 or more recent. /* Boolean DoWeHaveSoundManager3 (void) { // NumVersion version; Boolean hasIt; hasIt = true; version = SndSoundManagerVersion(); hasIt = (version.majorRev >= 3); return hasIt; } */ //-------------------------------------------------------------- DoWeHaveQuickTime Boolean DoWeHaveQuickTime (void) { long theResponse; OSErr theErr; Boolean haveIt; theErr = Gestalt(gestaltQuickTime, &theResponse); if (theErr == noErr) haveIt = true; else haveIt = false; return (haveIt); } //-------------------------------------------------------------- DoWeHaveDragManager Boolean DoWeHaveDragManager (void) { long theResponse; OSErr theErr; Boolean haveIt; theErr = Gestalt(gestaltDragMgrAttr, &theResponse); if ((theErr == noErr) && ((theResponse & (1L << gestaltDragMgrPresent)) != 0)) haveIt = true; else haveIt = false; return (haveIt); } //-------------------------------------------------------------- WhatsOurDepth // Determines the pixel bit depth for current device (monitor). short WhatsOurDepth (void) { short thisDepth; char wasState; if (thisMac.hasColor) { if (thisGDevice != nil) { wasState = HGetState((Handle)thisGDevice); HLock((Handle)thisGDevice); thisDepth = (**(**thisGDevice).gdPMap).pixelSize; HSetState((Handle)thisGDevice, wasState); } else RedAlert(kErrUnnaccounted); } else thisDepth = 1; return (thisDepth); } //-------------------------------------------------------------- CanWeDisplay8Bit // Determines if device (monitor) capable of supporting 8 bit (256 colors/grays). Boolean CanWeDisplay8Bit (GDHandle theDevice) { short canDepth; Boolean canDo; canDo = false; canDepth = HasDepth(theDevice, 8, 1, 0); if (canDepth != 0) canDo = true; return (canDo); } //-------------------------------------------------------------- CanWeDisplay4Bit // Determines if device (monitor) capable of supporting 4 bit (16 colors/grays). /* Boolean CanWeDisplay4Bit (GDHandle theDevice) { short canDepth; Boolean canDo; canDo = false; canDepth = HasDepth(theDevice, 4, 1, 0); if (canDepth != 0) canDo = true; return (canDo); } */ //-------------------------------------------------------------- CanWeDisplay1Bit // Determines if device (monitor) capable of supporting 1 bit (black & white). /* Boolean CanWeDisplay1Bit (GDHandle theDevice) { short canDepth; Boolean canDo; canDo = false; canDepth = HasDepth(theDevice, 1, 1, 0); if (canDepth != 0) canDo = true; return (canDo); } */ //-------------------------------------------------------------- HowManyUsableScreens // Counts the number of monitors that meet the depth criteria passed in. short HowManyUsableScreens (Boolean use1Bit, Boolean use4Bit, Boolean use8Bit) { GDHandle tempGDevice; short count; count = 0; tempGDevice = GetDeviceList(); while (tempGDevice != nil) { if (TestDeviceAttribute(tempGDevice, screenDevice)) { // if ((use1Bit && CanWeDisplay1Bit(tempGDevice)) || // (use4Bit && CanWeDisplay4Bit(tempGDevice)) || // (use8Bit && CanWeDisplay8Bit(tempGDevice))) count = count + 1; } tempGDevice = GetNextDevice(tempGDevice); } return (count); } //-------------------------------------------------------------- GetDeviceRect // Returns the bounding rectangle for the current device (monitor). void GetDeviceRect (Rect *theRect) { char wasState; wasState = HGetState((Handle)thisGDevice); HLock((Handle)thisGDevice); *theRect = (*thisGDevice)->gdRect; HSetState((Handle)thisGDevice, wasState); } //-------------------------------------------------------------- AreWeColorOrGrayscale // Determines if the current device (monitor) is in colors or grayscale. Boolean AreWeColorOrGrayscale (void) { char wasState; Boolean colorOrGray; wasState = HGetState((Handle)thisGDevice); HLock((Handle)thisGDevice); colorOrGray = (**thisGDevice).gdFlags & 0x0001; HSetState((Handle)thisGDevice, wasState); if (thisMac.hasColor) { wasState = HGetState((Handle)thisGDevice); HLock((Handle)thisGDevice); colorOrGray = (**thisGDevice).gdFlags & 0x0001; HSetState((Handle)thisGDevice, wasState); return (colorOrGray); } else return (false); } //-------------------------------------------------------------- SwitchToDepth // Switches the current device (monitor) to a specific bit depth. void SwitchToDepth (short newDepth, Boolean doColor) { OSErr theErr; short colorFlag; char tagByte; if (doColor) colorFlag = 1; else colorFlag = 0; if (thisGDevice != nil) { tagByte = HGetState((Handle)thisGDevice); HLock((Handle)thisGDevice); theErr = SetDepth(thisGDevice, newDepth, 1, colorFlag); HSetState((Handle)thisGDevice, tagByte); if (theErr != noErr) RedAlert(kErrUnnaccounted); else thisMac.isDepth = newDepth; } else RedAlert(kErrUnnaccounted); } //-------------------------------------------------------------- SwitchDepthOrAbort // Brings up a dialog allowing user to select bit depth or exit to shell. void SwitchDepthOrAbort (void) { short usersDecision; if (thisMac.canSwitch) { InitCursor(); // CenterAlert(kSwitchDepthAlert); usersDecision = Alert(kSwitchDepthAlert, nil); switch (usersDecision) { case 1: SwitchToDepth(8, true); break; case 2: SwitchToDepth(4, false); break; case 3: ExitToShell(); break; } } else RedAlert(kErrUnnaccounted); } //-------------------------------------------------------------- CheckOurEnvirons // Calls all the above functions in order to fill out a sort of "spec sheet"É // for the current Mac. void CheckOurEnvirons (void) { RgnHandle grayRegion; char wasState; thisMac.thisResFile = CurResFile(); thisMac.vRefNum = 0; // TEMP thisMac.dirID = 0; // TEMP thisMac.hasGestalt = true; // TEMP thisMac.hasWNE = true; // TEMP thisMac.hasColor = true; // TEMP thisMac.canSwitch = true; // TEMP thisMac.hasSystem7 = true; // TEMP thisMac.hasSM3 = true; // TEMP thisMac.hasQT = DoWeHaveQuickTime(); thisMac.hasDrag = DoWeHaveDragManager(); FindOurDevice(); wasState = HGetState((Handle)thisGDevice); HLock((Handle)thisGDevice); thisMac.can1Bit = true; thisMac.can4Bit = true; thisMac.can8Bit = true; HSetState((Handle)thisGDevice, wasState); thisMac.numScreens = HowManyUsableScreens(false, true, true); GetDeviceRect(&thisMac.screen); thisMac.wasDepth = WhatsOurDepth(); thisMac.wasColorOrGray = AreWeColorOrGrayscale(); grayRegion = GetGrayRgn(); (void) GetRegionBounds(grayRegion, &(thisMac.gray)); } //-------------------------------------------------------------- ReflectMonitor2Environs // Tests second monitor (if available) for specific bit depth capabilities. /* void ReflectSecondMonitorEnvirons (Boolean use1Bit, Boolean use4Bit, Boolean use8Bit) { GDHandle tempGDevice; tempGDevice = GetDeviceList(); while (tempGDevice != nil) { if (TestDeviceAttribute(tempGDevice, screenDevice)) if ((use1Bit && CanWeDisplay1Bit(tempGDevice)) || (use4Bit && CanWeDisplay4Bit(tempGDevice)) || (use8Bit && CanWeDisplay8Bit(tempGDevice))) if (!TestDeviceAttribute(tempGDevice, mainScreen)) { thisGDevice = tempGDevice; thisMac.can1Bit = CanWeDisplay1Bit(thisGDevice); thisMac.can4Bit = CanWeDisplay4Bit(thisGDevice); thisMac.can8Bit = CanWeDisplay8Bit(thisGDevice); thisMac.wasDepth = WhatsOurDepth(); thisMac.wasColorOrGray = AreWeColorOrGrayscale(); GetDeviceRect(&thisMac.screen); break; } tempGDevice = GetNextDevice(tempGDevice); } } */ //-------------------------------------------------------------- HandleDepthSwitching // Handles setting up a monitor's depth to play on. void HandleDepthSwitching (void) { if (thisMac.hasColor) { switch (isDepthPref) { case kSwitchIfNeeded: if ((thisMac.wasDepth != 8) && ((thisMac.wasDepth != 4) || (thisMac.wasColorOrGray))) SwitchDepthOrAbort(); break; case kSwitchTo256Colors: if (thisMac.wasDepth != 8) { if (thisMac.can8Bit) SwitchToDepth(8, true); else SwitchDepthOrAbort(); } break; case kSwitchTo16Grays: if ((thisMac.wasDepth != 4) || (thisMac.wasColorOrGray)) { if (thisMac.can4Bit) SwitchToDepth(4, false); else SwitchDepthOrAbort(); } break; default: break; } } thisMac.isDepth = WhatsOurDepth(); } //-------------------------------------------------------------- RestoreColorDepth // Restores a monitor to its previous depth when we quit (if we changed it). void RestoreColorDepth (void) { if ((thisMac.hasColor) && ((thisMac.wasDepth != thisMac.isDepth) || (thisMac.wasColorOrGray != AreWeColorOrGrayscale()))) SwitchToDepth(thisMac.wasDepth, true); } //-------------------------------------------------------------- CheckMemorySize // Tests for a specific amount of memory available. If the required memoryÉ // is not available, attempts to turn off various game features (music, etc.)É // in order to accomodate the constrained memory available. void CheckMemorySize (void) { #define kBaseBytesNeeded 614400L // 600K Base memory #define kPaddingBytes 204800L // 200K Padding long bytesNeeded, bytesAvail; long soundBytes, musicBytes; short hitWhat; Str255 sizeStr; dontLoadMusic = false; dontLoadSounds = false; bytesNeeded = kBaseBytesNeeded; // base memory soundBytes = SoundBytesNeeded(); // sound memory if (soundBytes <= 0L) RedAlert(kErrNoMemory); else bytesNeeded += soundBytes; musicBytes = MusicBytesNeeded(); // music memory if (musicBytes <= 0L) RedAlert(kErrNoMemory); else bytesNeeded += musicBytes; bytesNeeded += 4L * (long)thisMac.screen.bottom; // main screen bytesNeeded += (((long)houseRect.right - (long)houseRect.left) * ((long)houseRect.bottom + 1 - (long)houseRect.top) * (long)thisMac.isDepth) / 8L; // work map bytesNeeded += 4L * (long)houseRect.bottom; bytesNeeded += (((long)houseRect.right - (long)houseRect.left) * ((long)houseRect.bottom + 1 - (long)houseRect.top) * (long)thisMac.isDepth) / 8L; // back map bytesNeeded += 4L * houseRect.bottom; bytesNeeded += (((long)houseRect.right - (long)houseRect.left) * 21 * (long)thisMac.isDepth) / 8L; // scoreboard map bytesNeeded += (6396L * (long)thisMac.isDepth) / 8L; // more scoreboard bytesNeeded += (32112L * (long)thisMac.isDepth) / 8L; // glider map bytesNeeded += (32112L * (long)thisMac.isDepth) / 8L; // glider2 map bytesNeeded += 32064L / 8L; // glider mask bytesNeeded += (912L * (long)thisMac.isDepth) / 8L; // glider shadow bytesNeeded += 864L / 8L; // shadow mask bytesNeeded += (304L * (long)thisMac.isDepth) / 8L; // rubber bands bytesNeeded += 288L / 8L; // bands mask bytesNeeded += (19344L * (long)thisMac.isDepth) / 8L; // blower map bytesNeeded += 19344L / 8L; // blower mask bytesNeeded += (17856L * (long)thisMac.isDepth) / 8L; // furniture map bytesNeeded += 17792L / 8L; // furniture mask bytesNeeded += (33264L * (long)thisMac.isDepth) / 8L; // prizes map bytesNeeded += 33176L / 8L; // prizes mask bytesNeeded += (2904L * (long)thisMac.isDepth) / 8L; // points map bytesNeeded += 2880L / 8L; // points mask bytesNeeded += (1848L * (long)thisMac.isDepth) / 8L; // transport map bytesNeeded += 1792L / 8L; // transport mask bytesNeeded += (3360L * (long)thisMac.isDepth) / 8L; // switches map bytesNeeded += (9144L * (long)thisMac.isDepth) / 8L; // lights map bytesNeeded += 9072L / 8L; // lights mask bytesNeeded += (21600L * (long)thisMac.isDepth) / 8L; // appliances map bytesNeeded += 21520L / 8L; // appliances mask bytesNeeded += (5600L * (long)thisMac.isDepth) / 8L; // toast map bytesNeeded += 5568L / 8L; // toast mask bytesNeeded += (1440L * (long)thisMac.isDepth) / 8L; // shredded map bytesNeeded += 1400L / 8L; // shredded mask bytesNeeded += (5784L * (long)thisMac.isDepth) / 8L; // balloon map bytesNeeded += 5760L / 8L; // balloon mask bytesNeeded += (9632L * (long)thisMac.isDepth) / 8L; // copter map bytesNeeded += 9600L / 8L; // copter mask bytesNeeded += (4928L * (long)thisMac.isDepth) / 8L; // dart map bytesNeeded += 4864L / 8L; // dart mask bytesNeeded += (2080L * (long)thisMac.isDepth) / 8L; // ball map bytesNeeded += 2048L / 8L; // ball mask bytesNeeded += (1168L * (long)thisMac.isDepth) / 8L; // drip map bytesNeeded += 1152L / 8L; // drip mask bytesNeeded += (1224L * (long)thisMac.isDepth) / 8L; // enemy map bytesNeeded += 1188L / 8L; // enemy mask bytesNeeded += (2064L * (long)thisMac.isDepth) / 8L; // fish map bytesNeeded += 2048L / 8L; // fish mask bytesNeeded += (8960L * (long)thisMac.isDepth) / 8L; // clutter map bytesNeeded += 8832L / 8L; // clutter mask bytesNeeded += (23040L * (long)thisMac.isDepth) / 8L; // support map bytesNeeded += (4320L * (long)thisMac.isDepth) / 8L; // angel map bytesNeeded += 4224L / 8L; // angel mask bytesNeeded += sizeof(roomType); bytesNeeded += sizeof(hotObject) * kMaxHotSpots; bytesNeeded += sizeof(sparkleType) * kMaxSparkles; bytesNeeded += sizeof(flyingPtType) * kMaxFlyingPts; bytesNeeded += sizeof(flameType) * kMaxCandles; bytesNeeded += sizeof(flameType) * kMaxTikis; bytesNeeded += sizeof(flameType) * kMaxCoals; bytesNeeded += sizeof(pendulumType) * kMaxPendulums; bytesNeeded += sizeof(savedType) * kMaxSavedMaps; bytesNeeded += sizeof(bandType) * kMaxRubberBands; bytesNeeded += sizeof(greaseType) * kMaxGrease; bytesNeeded += sizeof(starType) * kMaxStars; bytesNeeded += sizeof(shredType) * kMaxShredded; bytesNeeded += sizeof(dynaType) * kMaxDynamicObs; bytesNeeded += sizeof(objDataType) * kMaxMasterObjects; bytesNeeded += kDemoLength; SpinCursor(1); bytesAvail = FreeMem(); SpinCursor(1); if (bytesAvail < bytesNeeded) { InitCursor(); if (bytesAvail >= (bytesNeeded - musicBytes)) { // if we don't load the music we can run TellHerNoMusic(); dontLoadMusic = true; return; } else if (bytesAvail >= (bytesNeeded - (musicBytes + soundBytes))) { // if we don't load the music AND sounds, we can run TellHerNoSounds(); dontLoadMusic = true; dontLoadSounds = true; return; } #ifdef COMPILEDEMO // CenterAlert(kLowMemoryAlert); NumToString((bytesNeeded + kPaddingBytes) / 1024L, sizeStr); ParamText(sizeStr, "\p", "\p", "\p"); hitWhat = Alert(kLowMemoryAlert, nil); #else // CenterAlert(kSetMemoryAlert); NumToString((bytesNeeded + kPaddingBytes) / 1024L, sizeStr); ParamText(sizeStr, "\p", "\p", "\p"); hitWhat = Alert(kSetMemoryAlert, nil); // SetAppMemorySize(bytesNeeded + kPaddingBytes); #endif ExitToShell(); } } //-------------------------------------------------------------- SetAppMemorySize // Physically changes the 'SIZE' resource of the app so that when launched again,É // the Finder will give us enough memory to fully run the game (God, we hope!). void SetAppMemorySize (long newSize) { Handle tempResource; short oldResFile; short i; oldResFile = CurResFile(); UseResFile(thisMac.thisResFile); for (i = 0; i < 2; i++) { tempResource = Get1Resource('SIZE', i); if (tempResource != nil) { RemoveResource(tempResource); if (ResError() != noErr) DisposeHandle(tempResource); } } tempResource = Get1Resource('SIZE', -1); if (tempResource != nil) { HLock(tempResource); ((sizeType*)(*tempResource))->mem1 = newSize; ((sizeType*)(*tempResource))->mem2 = newSize; ChangedResource(tempResource); WriteResource(tempResource); ReleaseResource(tempResource); } UpdateResFile(thisMac.thisResFile); FlushVol(nil, 0); UseResFile(oldResFile); } \ No newline at end of file diff --git a/Sources/Events.c b/Sources/Events.c deleted file mode 100755 index cf449dc..0000000 --- a/Sources/Events.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Events.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Externs.h" #include "Environ.h" #include "House.h" #include "ObjectEdit.h" short BitchAboutColorDepth (void); void HandleMouseEvent (EventRecord *); void HandleKeyEvent (EventRecord *); void HandleUpdateEvent (EventRecord *); void HandleOSEvent (EventRecord *); void HandleHighLevelEvent (EventRecord *); void HandleIdleTask (void); void IncrementMode (void); long lastUp, incrementModeTime; UInt32 doubleTime; Point lastWhere; short idleMode; Boolean doAutoDemo, switchedOut; extern WindowPtr mapWindow, toolsWindow, linkWindow; extern WindowPtr menuWindow; extern short isEditH, isEditV, isMapH, isMapV, isToolsH, isToolsV; extern short isLinkH, isLinkV, isCoordH, isCoordV; extern Boolean quitting, isMusicOn, failedMusic; extern Boolean autoRoomEdit, newRoomNow, isPlayMusicIdle; //============================================================== Functions //-------------------------------------------------------------- BitchAboutColorDepth // Display a dialog that alerts the user that they have switched the bitÉ // depth of the monitor under our noses. They must return it to previous. short BitchAboutColorDepth (void) { #define kColorSwitchedAlert 1042 short sheSaid; // CenterAlert(kColorSwitchedAlert); sheSaid = Alert(kColorSwitchedAlert, nil); return (sheSaid); } //-------------------------------------------------------------- HandleMouseEvent // Handle a mouse click event. void HandleMouseEvent (EventRecord *theEvent) { WindowPtr whichWindow; long menuChoice, newSize; short thePart, hDelta, vDelta; Boolean isDoubleClick; thePart = FindWindow(theEvent->where, &whichWindow); switch (thePart) { case inSysWindow: // SystemClick(theEvent, whichWindow); break; case inMenuBar: menuChoice = MenuSelect(theEvent->where); DoMenuChoice(menuChoice); break; case inDrag: DragWindow(whichWindow, theEvent->where, &thisMac.screen); if (whichWindow == mainWindow) { SendBehind(mainWindow, (WindowPtr)0L); GetWindowLeftTop(whichWindow, &isEditH, &isEditV); } else if (whichWindow == mapWindow) GetWindowLeftTop(whichWindow, &isMapH, &isMapV); else if (whichWindow == toolsWindow) GetWindowLeftTop(whichWindow, &isToolsH, &isToolsV); else if (whichWindow == linkWindow) GetWindowLeftTop(whichWindow, &isLinkH, &isLinkV); else if (whichWindow == coordWindow) GetWindowLeftTop(whichWindow, &isCoordH, &isCoordV); HiliteAllWindows(); break; case inGoAway: if (TrackGoAway(whichWindow,theEvent->where)) { if (whichWindow == mapWindow) ToggleMapWindow(); else if (whichWindow == toolsWindow) ToggleToolsWindow(); else if (whichWindow == linkWindow) CloseLinkWindow(); else if (whichWindow == coordWindow) ToggleCoordinateWindow(); } break; case inGrow: if (whichWindow == mapWindow) { newSize = GrowWindow(mapWindow, theEvent->where, &thisMac.gray); ResizeMapWindow(LoWord(newSize), HiWord(newSize)); } break; case inZoomIn: case inZoomOut: if (TrackBox(whichWindow, theEvent->where, thePart)) ZoomWindow(whichWindow, thePart, true); break; case inContent: if (whichWindow == mainWindow) { hDelta = theEvent->where.h - lastWhere.h; if (hDelta < 0) hDelta = -hDelta; vDelta = theEvent->where.v - lastWhere.v; if (vDelta < 0) vDelta = -vDelta; if (((theEvent->when - lastUp) < doubleTime) && (hDelta < 5) && (vDelta < 5)) isDoubleClick = true; else { isDoubleClick = false; lastUp = theEvent->when; lastWhere = theEvent->where; } HandleMainClick(theEvent->where, isDoubleClick); } else if (whichWindow == mapWindow) HandleMapClick(theEvent); else if (whichWindow == toolsWindow) HandleToolsClick(theEvent->where); else if (whichWindow == linkWindow) HandleLinkClick(theEvent->where); break; default: break; } } //-------------------------------------------------------------- HandleKeyEvent // Handle a key-down event. void HandleKeyEvent (EventRecord *theEvent) { char theChar; Boolean shiftDown, commandDown, optionDown; theChar = theEvent->message & charCodeMask; shiftDown = ((theEvent->modifiers & shiftKey) != 0); commandDown = ((theEvent->modifiers & cmdKey) != 0); optionDown = ((theEvent->modifiers & optionKey) != 0); if ((commandDown) && (!optionDown)) DoMenuChoice(MenuKey(theChar)); else { switch (theChar) { case kHelpKeyASCII: break; case kPageUpKeyASCII: if (houseUnlocked) PrevToolMode(); break; case kPageDownKeyASCII: if (houseUnlocked) NextToolMode(); break; #if BUILD_ARCADE_VERSION case kLeftArrowKeyASCII: DoOptionsMenu(iHighScores); break; case kRightArrowKeyASCII: DoOptionsMenu(iHelp); break; case kUpArrowKeyASCII: DoGameMenu(iNewGame); break; case kDownArrowKeyASCII: DoGameMenu(iNewGame); break; #else case kLeftArrowKeyASCII: if (houseUnlocked) { if (objActive == kNoObjectSelected) SelectNeighborRoom(kRoomToLeft); else MoveObject(kBumpLeft, shiftDown); } break; case kRightArrowKeyASCII: if (houseUnlocked) { if (objActive == kNoObjectSelected) SelectNeighborRoom(kRoomToRight); else MoveObject(kBumpRight, shiftDown); } break; case kUpArrowKeyASCII: if (houseUnlocked) { if (objActive == kNoObjectSelected) SelectNeighborRoom(kRoomAbove); else MoveObject(kBumpUp, shiftDown); } break; case kDownArrowKeyASCII: if (houseUnlocked) { if (objActive == kNoObjectSelected) SelectNeighborRoom(kRoomBelow); else MoveObject(kBumpDown, shiftDown); } break; #endif case kDeleteKeyASCII: if (houseUnlocked) { if (objActive == kNoObjectSelected) DeleteRoom(true); else DeleteObject(); } break; case kTabKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) { if (shiftDown) SelectPrevObject(); else SelectNextObject(); } break; case kEscapeKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) DeselectObject(); break; case kAKeyASCII: case kCapAKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) SetSpecificToolMode(kApplianceMode); break; case kBKeyASCII: case kCapBKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) SetSpecificToolMode(kBlowerMode); break; case kCKeyASCII: case kCapCKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) SetSpecificToolMode(kClutterMode); break; case kEKeyASCII: case kCapEKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) SetSpecificToolMode(kEnemyMode); break; case kFKeyASCII: case kCapFKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) SetSpecificToolMode(kFurnitureMode); break; case kLKeyASCII: case kCapLKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) SetSpecificToolMode(kLightMode); break; case kPKeyASCII: case kCapPKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) SetSpecificToolMode(kBonusMode); break; case kSKeyASCII: case kCapSKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) SetSpecificToolMode(kSwitchMode); break; case kTKeyASCII: case kCapTKeyASCII: if ((theMode == kEditMode) && (houseUnlocked)) SetSpecificToolMode(kTransportMode); break; default: break; } } } //-------------------------------------------------------------- HandleUpdateEvent // Handle an update event. void HandleUpdateEvent (EventRecord *theEvent) { if ((WindowPtr)theEvent->message == mainWindow) { SetPort((GrafPtr)mainWindow); BeginUpdate(mainWindow); UpdateMainWindow(); EndUpdate(mainWindow); } else if ((WindowPtr)theEvent->message == mapWindow) { SetPort((GrafPtr)mapWindow); BeginUpdate(mapWindow); UpdateMapWindow(); EndUpdate(mapWindow); } else if ((WindowPtr)theEvent->message == toolsWindow) { SetPort((GrafPtr)toolsWindow); BeginUpdate(toolsWindow); UpdateToolsWindow(); EndUpdate(toolsWindow); } else if ((WindowPtr)theEvent->message == linkWindow) { SetPort((GrafPtr)linkWindow); BeginUpdate(linkWindow); UpdateLinkWindow(); EndUpdate(linkWindow); } else if ((WindowPtr)theEvent->message == coordWindow) { SetPort((GrafPtr)coordWindow); BeginUpdate(coordWindow); UpdateCoordWindow(); EndUpdate(coordWindow); } else if ((WindowPtr)theEvent->message == menuWindow) { SetPort((GrafPtr)menuWindow); BeginUpdate(menuWindow); UpdateMenuBarWindow(); EndUpdate(menuWindow); } } //-------------------------------------------------------------- HandleOSEvent // Handle an OS Event (MultiFinder - user has switched in or out of app). void HandleOSEvent (EventRecord *theEvent) { OSErr theErr; short buttonHit; if (theEvent->message & 0x01000000) // suspend or resume event { if (theEvent->message & 0x00000001) // resume event { if (WhatsOurDepth() != thisMac.isDepth) { buttonHit = BitchAboutColorDepth(); if (buttonHit == 1) // player wants to Quit { #ifndef COMPILEDEMO if (QuerySaveChanges()) quitting = true; #else quitting = true; #endif } else { SwitchToDepth(thisMac.isDepth, thisMac.wasColorOrGray); } } switchedOut = false; InitCursor(); if ((isPlayMusicIdle) && (theMode != kEditMode)) { theErr = StartMusic(); if (theErr != noErr) { YellowAlert(kYellowNoMusic, theErr); failedMusic = true; } } incrementModeTime = TickCount() + kIdleSplashTicks; #ifndef COMPILEDEMO // if (theMode == kEditMode) // SeeIfValidScrapAvailable(true); #endif } else // suspend event { switchedOut = true; InitCursor(); if ((isMusicOn) && (theMode != kEditMode)) StopTheMusic(); } } } //-------------------------------------------------------------- HandleHighLevelEvent // Handle an AppleEvent (Open Document, Quit Application, etc.). void HandleHighLevelEvent (EventRecord *theEvent) { OSErr theErr; theErr = AEProcessAppleEvent(theEvent); if ((theErr != noErr) && (theErr != errAEEventNotHandled)) YellowAlert(kYellowAppleEventErr, theErr); } //-------------------------------------------------------------- HandleIdleTask // Handle some processing during event lulls. void HandleIdleTask (void) { if (theMode == kEditMode) { SetPort((GrafPtr)mainWindow); DoMarquee(); if ((autoRoomEdit) && (newRoomNow)) { if (theMode == kEditMode) DoRoomInfo(); newRoomNow = false; } } } //-------------------------------------------------------------- HandleEvent // "Master" function that tests for events and calls the above functions toÉ // handle each event type. Not called during and actual game. void HandleEvent (void) { KeyMap eventKeys; EventRecord theEvent; long sleep = 2; Boolean itHappened; GetKeys(eventKeys); if ((BitTst(&eventKeys, kCommandKeyMap)) && (BitTst(&eventKeys, kOptionKeyMap))) { HiliteAllObjects(); } else if ((BitTst(&eventKeys, kOptionKeyMap)) && (theMode == kEditMode) && (houseUnlocked)) { EraseSelectedTool(); SelectTool(kSelectTool); } if (thisMac.hasWNE) itHappened = WaitNextEvent(everyEvent, &theEvent, sleep, nil); else { // SystemTask(); itHappened = GetNextEvent(everyEvent, &theEvent); } if (itHappened) { switch (theEvent.what) { case mouseDown: HandleMouseEvent(&theEvent); break; case keyDown: case autoKey: HandleKeyEvent(&theEvent); break; case updateEvt: HandleUpdateEvent(&theEvent); break; case osEvt: HandleOSEvent(&theEvent); break; case kHighLevelEvent: HandleHighLevelEvent(&theEvent); break; } } else HandleIdleTask(); if ((theMode == kSplashMode) && doAutoDemo && !switchedOut) { if (TickCount() >= incrementModeTime) DoDemoGame(); } } //-------------------------------------------------------------- HiliteAllWindows // Ugly kludge in order to keep "floating windows" (palettes) on top ofÉ // the main window. void HiliteAllWindows (void) { if (mainWindow != nil) HiliteWindow(mainWindow, true); if (mapWindow != nil) HiliteWindow(mapWindow, true); if (toolsWindow != nil) HiliteWindow(toolsWindow, true); if (coordWindow != nil) HiliteWindow(coordWindow, true); if (linkWindow != nil) HiliteWindow(linkWindow, true); } //-------------------------------------------------------------- IgnoreThisClick // Another inelegant kludge designed to temporarily prevent an unwantedÉ // double-click to be registered. void IgnoreThisClick (void) { lastUp -= doubleTime; lastWhere.h = -100; lastWhere.v = -100; } \ No newline at end of file diff --git a/Sources/FileError.c b/Sources/FileError.c deleted file mode 100755 index bb68187..0000000 --- a/Sources/FileError.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // FileError.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Externs.h" #define rFileErrorAlert 140 #define rFileErrorStrings 140 //============================================================== Functions //-------------------------------------------------------------- CheckFileError // Given a result code (returned from a previous file operation) thisÉ // function cheks to see if the result code is an error and, if it isÉ // a common error for which I have a string message, I bring up anÉ // alert with the error message. If it is an unusual error, I stillÉ // bring up an alert but with "Miscellaneous file error" and theÉ // error ID. Boolean CheckFileError (short resultCode, StringPtr fileName) { short dummyInt, stringIndex; Str255 errMessage, errNumString; if (resultCode == noErr) // No problems? Then cruise return(true); switch (resultCode) { case dirFulErr: stringIndex = 2; break; case dskFulErr: stringIndex = 3; break; case ioErr: stringIndex = 4; break; case bdNamErr: stringIndex = 5; break; case fnOpnErr: stringIndex = 6; break; case mFulErr: stringIndex = 7; break; case tmfoErr: stringIndex = 8; break; case wPrErr: stringIndex = 9; break; case fLckdErr: stringIndex = 10; break; case vLckdErr: stringIndex = 11; break; case fBsyErr: stringIndex = 12; break; case dupFNErr: stringIndex = 13; break; case opWrErr: stringIndex = 14; break; case volOffLinErr: stringIndex = 15; break; case permErr: stringIndex = 16; break; case wrPermErr: stringIndex = 17; break; default: stringIndex = 1; break; } InitCursor(); GetIndString(errMessage, rFileErrorStrings, stringIndex); NumToString((long)resultCode, errNumString); ParamText(errMessage, errNumString, fileName, "\p"); // CenterAlert(rFileErrorAlert); dummyInt = Alert(rFileErrorAlert, 0L); return(false); } \ No newline at end of file diff --git a/Sources/GameOver.c b/Sources/GameOver.c deleted file mode 100755 index 706c884..0000000 --- a/Sources/GameOver.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // GameOver.c //---------------------------------------------------------------------------- //============================================================================ #include #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(); } \ No newline at end of file diff --git a/Sources/Grease.c b/Sources/Grease.c deleted file mode 100755 index a734cca..0000000 --- a/Sources/Grease.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Grease.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" #include "MainWindow.h" #include "Objects.h" #include "RectUtils.h" #include "Room.h" #define kGreaseIdle 0 #define kGreaseFalling 1 #define kGreaseSpreading 2 #define kGreaseSpiltIdle 3 void BackupGrease (Rect *, short, Boolean); greasePtr grease; short numGrease; extern hotPtr hotSpots; extern savedType savedMaps[]; extern Point shieldPt; extern Rect greaseSrcRt[], greaseSrcLf[], shieldRect; //============================================================== Functions //-------------------------------------------------------------- HandleGrease // Goes through all grease objects currently on screen and handlesÉ // them. If they're upright, nothing happens, but if they're inÉ // the course of falling or spilling, this function will handleÉ // advancing the spill, etc. void HandleGrease (void) { Rect src; short i; if (numGrease == 0) return; for (i = 0; i < numGrease; i++) { if (grease[i].mode == kGreaseFalling) { grease[i].frame++; if (grease[i].frame >= 3) // grease completely tipped { grease[i].frame = 3; grease[i].mode = kGreaseSpreading; hotSpots[grease[i].hotNum].action = kSlideIt; hotSpots[grease[i].hotNum].isOn = true; if (grease[i].isRight) QSetRect(&src, 0, -2, 2, 0); else QSetRect(&src, -2, -2, 0, 0); QOffsetRect(&src, -playOriginH, -playOriginV); QOffsetRect(&src, grease[i].start, grease[i].dest.bottom); hotSpots[grease[i].hotNum].bounds = src; } QSetRect(&src, 0, 0, 32, 27); QOffsetRect(&src, 0, grease[i].frame * 27); CopyBits((BitMap *)*GetGWorldPixMap(savedMaps[grease[i].mapNum].map), (BitMap *)*GetGWorldPixMap(workSrcMap), &src, &grease[i].dest, srcCopy, nil); CopyBits((BitMap *)*GetGWorldPixMap(savedMaps[grease[i].mapNum].map), (BitMap *)*GetGWorldPixMap(backSrcMap), &src, &grease[i].dest, srcCopy, nil); AddRectToWorkRects(&grease[i].dest); if (grease[i].isRight) QOffsetRect(&grease[i].dest, 2, 0); else QOffsetRect(&grease[i].dest, -2, 0); } else if (grease[i].mode == kGreaseSpreading) { if (grease[i].isRight) { QSetRect(&src, 0, -2, 2, 0); QOffsetRect(&src, grease[i].start, grease[i].dest.bottom); grease[i].start += 2; hotSpots[grease[i].hotNum].bounds.right += 2; } else { QSetRect(&src, -2, -2, 0, 0); QOffsetRect(&src, grease[i].start, grease[i].dest.bottom); grease[i].start -= 2; hotSpots[grease[i].hotNum].bounds.left -= 2; } { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); PaintRect(&src); SetGWorld(workSrcMap, nil); PaintRect(&src); AddRectToWorkRects(&src); SetGWorld(wasCPort, wasWorld); } if (grease[i].isRight) { if (grease[i].start >= grease[i].stop) grease[i].mode = kGreaseSpiltIdle; } else { if (grease[i].start <= grease[i].stop) grease[i].mode = kGreaseSpiltIdle; } } } } //-------------------------------------------------------------- BackupGrease // This makes copies of the region of the screen the grease is aboutÉ // to be drawn to. It is called in the "set up" when a player hasÉ // just entered a new room. The "grease jar falling over" animationÉ // is set up here. void BackupGrease (Rect *src, short index, Boolean isRight) { Rect dest; short i; QSetRect(&dest, 0, 0, 32, 27); for (i = 0; i < 4; i++) { CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), (BitMap *)*GetGWorldPixMap(savedMaps[index].map), src, &dest, srcCopy, nil); if (isRight) { CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(savedMaps[index].map), &greaseSrcRt[i], &greaseSrcRt[i], &dest); QOffsetRect(src, 2, 0); } else { CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(savedMaps[index].map), &greaseSrcLf[i], &greaseSrcLf[i], &dest); QOffsetRect(src, -2, 0); } QOffsetRect(&dest, 0, 27); } } //-------------------------------------------------------------- ReBackUpGrease // Just like th eabove function but it is called while the player isÉ // active in a room and has changed the lighting situation (like turnedÉ // off or on the lights). It assumes certain data strucutures areÉ // already declared from an earlier call to the above funciton. short ReBackUpGrease (short where, short who) { Rect src; short i; for (i = 0; i < numGrease; i++) { if ((grease[i].where == where) && (grease[i].who == who)) { if ((grease[i].mode == kGreaseIdle) || (grease[i].mode == kGreaseFalling)) { src = grease[i].dest; BackupGrease(&src, grease[i].mapNum, grease[i].isRight); } return (i); } } return (-1); } //-------------------------------------------------------------- AddGrease // Called when a new room is being set up during a game. This addsÉ // another jar of grease to the queue of jars to be handled. short AddGrease (short where, short who, short h, short v, short distance, Boolean isRight) { Rect src, bounds; short savedNum; if (numGrease >= kMaxGrease) return (-1); QSetRect(&src, 0, 0, 32, 27); QOffsetRect(&src, h, v); QSetRect(&bounds, 0, 0, 32, 27 * 4); savedNum = BackUpToSavedMap(&bounds, where, who); if (savedNum != -1) { BackupGrease (&src, savedNum, isRight); if (isRight) QOffsetRect(&src, -8, 0); else QOffsetRect(&src, 8, 0); grease[numGrease].who = who; grease[numGrease].where = where; grease[numGrease].dest = src; grease[numGrease].mapNum = savedNum; grease[numGrease].mode = kGreaseIdle; grease[numGrease].frame = -1; if (isRight) { grease[numGrease].isRight = true; grease[numGrease].start = src.right + 4; grease[numGrease].stop = src.right + distance; } else { grease[numGrease].isRight = false; grease[numGrease].start = src.left - 4; grease[numGrease].stop = src.left - distance; } numGrease++; return (numGrease - 1); } else return (-1); } //-------------------------------------------------------------- SpillGrease // A player has knocked a jar of grease over - this function flags that. void SpillGrease (short who, short index) { if (grease[who].mode == kGreaseIdle) { grease[who].mode = kGreaseFalling; grease[who].hotNum = index; PlayPrioritySound(kGreaseSpillSound, kGreaseSpillPriority); } } //-------------------------------------------------------------- RedrawAllGrease // Called to redraw all the black lines of spilt grease. void RedrawAllGrease (void) { CGrafPtr wasCPort; GDHandle wasWorld; Rect src; short i; if (numGrease == 0) return; for (i = 0; i < numGrease; i++) { src = hotSpots[grease[i].hotNum].bounds; if ((grease[i].where == thisRoomNumber) && ((src.bottom - src.top) == 2) && (grease[i].mode != kGreaseIdle)) { QOffsetRect(&src, playOriginH, playOriginV); GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); PaintRect(&src); SetGWorld(workSrcMap, nil); PaintRect(&src); AddRectToWorkRects(&src); SetGWorld(wasCPort, wasWorld); } } } \ No newline at end of file diff --git a/Sources/HighScores.c b/Sources/HighScores.c deleted file mode 100755 index 27cdab0..0000000 --- a/Sources/HighScores.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // HighScores.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include #include #include "DialogUtils.h" #include "Externs.h" #include "Environ.h" #include "House.h" #include "MainWindow.h" #include "RectUtils.h" #include "Utilities.h" #define kHighScoresPictID 1994 #define kHighScoresMaskID 1998 #define kHighNameDialogID 1020 #define kHighBannerDialogID 1021 #define kHighNameItem 2 #define kNameNCharsItem 5 #define kHighBannerItem 2 #define kBannerScoreNCharsItem 5 void DrawHighScores (void); void UpdateNameDialog (DialogPtr); pascal Boolean NameFilter (DialogPtr, EventRecord *, short *); void GetHighScoreName (short); void UpdateBannerDialog (DialogPtr); pascal Boolean BannerFilter (DialogPtr, EventRecord *, short *); void GetHighScoreBanner (void); Boolean CreateScoresFolder (long *); Boolean FindHighScoresFolder (short *, long *); Boolean OpenHighScoresFile (FSSpec *, short *); Str31 highBanner; Str15 highName; short lastHighScore; Boolean keyStroke; extern short splashOriginH, splashOriginV; extern Boolean quickerTransitions, resumedSavedGame; //============================================================== Functions //-------------------------------------------------------------- DoHighScores // Handles fading in and cleaning up the high scores screen. void DoHighScores (void) { Rect tempRect; SpinCursor(3); SetPort((GrafPtr)workSrcMap); PaintRect(&workSrcRect); QSetRect(&tempRect, 0, 0, 640, 480); QOffsetRect(&tempRect, splashOriginH, splashOriginV); LoadScaledGraphic(kStarPictID, &tempRect); // if (quickerTransitions) // DissBitsChunky(&workSrcRect); // else // DissBits(&workSrcRect); SpinCursor(3); SetPort((GrafPtr)workSrcMap); DrawHighScores(); SpinCursor(3); // if (quickerTransitions) // DissBitsChunky(&workSrcRect); // else // DissBits(&workSrcRect); InitCursor(); DelayTicks(60); WaitForInputEvent(30); RedrawSplashScreen(); } //-------------------------------------------------------------- DrawHighScores // Draws the actual scores on the screen. #define kScoreSpacing 18 #define kScoreWide 352 #define kKimsLifted 4 void DrawHighScores (void) { GWorldPtr tempMap, tempMask; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; houseType *thisHousePtr; Rect tempRect, tempRect2; Str255 tempStr; short scoreLeft, bannerWidth, i, dropIt; char wasState; scoreLeft = ((thisMac.screen.right - thisMac.screen.left) - kScoreWide) / 2; dropIt = 129 + splashOriginV; GetGWorld(&wasCPort, &wasWorld); QSetRect(&tempRect, 0, 0, 332, 30); theErr = CreateOffScreenGWorld(&tempMap, &tempRect, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(kHighScoresPictID); theErr = CreateOffScreenGWorld(&tempMask, &tempRect, 1); SetGWorld(tempMask, nil); LoadGraphic(kHighScoresMaskID); tempRect2 = tempRect; QOffsetRect(&tempRect2, scoreLeft + (kScoreWide - 332) / 2, dropIt - 60); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(tempMask), (BitMap *)*GetGWorldPixMap(workSrcMap), &tempRect, &tempRect, &tempRect2); DisposeGWorld(tempMap); DisposeGWorld(tempMask); SetGWorld(wasCPort, wasWorld); TextFont(applFont); TextFace(bold); TextSize(14); PasStringCopy("\p¥ ", tempStr); PasStringConcat(tempStr, thisHouseName); PasStringConcat(tempStr, "\p ¥"); MoveTo(scoreLeft + ((kScoreWide - StringWidth(tempStr)) / 2) - 1, dropIt - 66); ForeColor(blackColor); DrawString(tempStr); MoveTo(scoreLeft + ((kScoreWide - StringWidth(tempStr)) / 2), dropIt - 65); ForeColor(cyanColor); DrawString(tempStr); ForeColor(blackColor); TextFont(applFont); TextFace(bold); TextSize(12); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; // message for score #1 PasStringCopy(thisHousePtr->highScores.banner, tempStr); bannerWidth = StringWidth(tempStr); ForeColor(blackColor); MoveTo(scoreLeft + (kScoreWide - bannerWidth) / 2, dropIt - kKimsLifted); DrawString(tempStr); ForeColor(yellowColor); MoveTo(scoreLeft + (kScoreWide - bannerWidth) / 2, dropIt - kKimsLifted - 1); DrawString(tempStr); QSetRect(&tempRect, 0, 0, bannerWidth + 8, kScoreSpacing); QOffsetRect(&tempRect, scoreLeft - 3 + (kScoreWide - bannerWidth) / 2, dropIt + 5 - kScoreSpacing - kKimsLifted); ForeColor(blackColor); FrameRect(&tempRect); QOffsetRect(&tempRect, -1, -1); ForeColor(yellowColor); FrameRect(&tempRect); for (i = 0; i < kMaxScores; i++) { if (thisHousePtr->highScores.scores[i] > 0L) { SpinCursor(1); NumToString((long)i + 1L, tempStr); // draw placing number ForeColor(blackColor); if (i == 0) MoveTo(scoreLeft + 1, dropIt - kScoreSpacing - kKimsLifted); else MoveTo(scoreLeft + 1, dropIt + (i * kScoreSpacing)); DrawString(tempStr); if (i == lastHighScore) ForeColor(whiteColor); else ForeColor(cyanColor); if (i == 0) MoveTo(scoreLeft + 0, dropIt - 1 - kScoreSpacing - kKimsLifted); else MoveTo(scoreLeft + 0, dropIt - 1 + (i * kScoreSpacing)); DrawString(tempStr); // draw high score name PasStringCopy(thisHousePtr->highScores.names[i], tempStr); ForeColor(blackColor); if (i == 0) MoveTo(scoreLeft + 31, dropIt - kScoreSpacing - kKimsLifted); else MoveTo(scoreLeft + 31, dropIt + (i * kScoreSpacing)); DrawString(tempStr); if (i == lastHighScore) ForeColor(whiteColor); else ForeColor(yellowColor); if (i == 0) MoveTo(scoreLeft + 30, dropIt - 1 - kScoreSpacing - kKimsLifted); else MoveTo(scoreLeft + 30, dropIt - 1 + (i * kScoreSpacing)); DrawString(tempStr); // draw level number NumToString(thisHousePtr->highScores.levels[i], tempStr); ForeColor(blackColor); if (i == 0) MoveTo(scoreLeft + 161, dropIt - kScoreSpacing - kKimsLifted); else MoveTo(scoreLeft + 161, dropIt + (i * kScoreSpacing)); DrawString(tempStr); if (i == lastHighScore) ForeColor(whiteColor); else ForeColor(yellowColor); if (i == 0) MoveTo(scoreLeft + 160, dropIt - 1 - kScoreSpacing - kKimsLifted); else MoveTo(scoreLeft + 160, dropIt - 1 + (i * kScoreSpacing)); DrawString(tempStr); // draw word "rooms" if (thisHousePtr->highScores.levels[i] == 1) GetLocalizedString(6, tempStr); else GetLocalizedString(7, tempStr); ForeColor(blackColor); if (i == 0) MoveTo(scoreLeft + 193, dropIt - kScoreSpacing - kKimsLifted); else MoveTo(scoreLeft + 193, dropIt + (i * kScoreSpacing)); DrawString(tempStr); ForeColor(cyanColor); if (i == 0) MoveTo(scoreLeft + 192, dropIt - 1 - kScoreSpacing - kKimsLifted); else MoveTo(scoreLeft + 192, dropIt - 1 + (i * kScoreSpacing)); DrawString(tempStr); // draw high score points NumToString(thisHousePtr->highScores.scores[i], tempStr); ForeColor(blackColor); if (i == 0) MoveTo(scoreLeft + 291, dropIt - kScoreSpacing - kKimsLifted); else MoveTo(scoreLeft + 291, dropIt + (i * kScoreSpacing)); DrawString(tempStr); if (i == lastHighScore) ForeColor(whiteColor); else ForeColor(yellowColor); if (i == 0) MoveTo(scoreLeft + 290, dropIt - 1 - kScoreSpacing - kKimsLifted); else MoveTo(scoreLeft + 290, dropIt - 1 + (i * kScoreSpacing)); DrawString(tempStr); } } ForeColor(blueColor); TextFont(applFont); TextFace(bold); TextSize(9); MoveTo(scoreLeft + 80, dropIt - 1 + (10 * kScoreSpacing)); GetLocalizedString(8, tempStr); DrawString(tempStr); ForeColor(blackColor); HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- SortHighScores // This does a simple sort of the high scores. void SortHighScores (void) { scoresType tempScores; houseType *thisHousePtr; long greatest; short i, h, which; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; for (h = 0; h < kMaxScores; h++) { greatest = -1L; which = -1; for (i = 0; i < kMaxScores; i++) { if (thisHousePtr->highScores.scores[i] > greatest) { greatest = thisHousePtr->highScores.scores[i]; which = i; } } if (which != -1) { PasStringCopy(thisHousePtr->highScores.names[which], tempScores.names[h]); tempScores.scores[h] = thisHousePtr->highScores.scores[which]; tempScores.timeStamps[h] = thisHousePtr->highScores.timeStamps[which]; tempScores.levels[h] = thisHousePtr->highScores.levels[which]; thisHousePtr->highScores.scores[which] = -1L; } } PasStringCopy(thisHousePtr->highScores.banner, tempScores.banner); thisHousePtr->highScores = tempScores; HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- ZeroHighScores // This funciton goes through and resets or "zeros" all high scores. void ZeroHighScores (void) { houseType *thisHousePtr; short i; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; PasStringCopy(thisHouseName, thisHousePtr->highScores.banner); for (i = 0; i < kMaxScores; i++) { PasStringCopy("\p--------------", thisHousePtr->highScores.names[i]); thisHousePtr->highScores.scores[i] = 0L; thisHousePtr->highScores.timeStamps[i] = 0L; thisHousePtr->highScores.levels[i] = 0; } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- ZeroAllButHighestScore // Like the above, but this function preserves the highest score. void ZeroAllButHighestScore (void) { houseType *thisHousePtr; short i; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; for (i = 1; i < kMaxScores; i++) { PasStringCopy("\p--------------", thisHousePtr->highScores.names[i]); thisHousePtr->highScores.scores[i] = 0L; thisHousePtr->highScores.timeStamps[i] = 0L; thisHousePtr->highScores.levels[i] = 0; } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- TestHighScore // This function is called after a game ends in order to test theÉ // current high score against the high score list. It returns trueÉ // if the player is on the high score list now. Boolean TestHighScore (void) { houseType *thisHousePtr; short placing, i; char wasState; if (resumedSavedGame) return (false); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; lastHighScore = -1; placing = -1; for (i = 0; i < kMaxScores; i++) { if (theScore > thisHousePtr->highScores.scores[i]) { placing = i; lastHighScore = i; break; } } if (placing != -1) { FlushEvents(everyEvent, 0); GetHighScoreName(placing + 1); PasStringCopy(highName, thisHousePtr->highScores.names[kMaxScores - 1]); if (placing == 0) { GetHighScoreBanner(); PasStringCopy(highBanner, thisHousePtr->highScores.banner); } thisHousePtr->highScores.scores[kMaxScores - 1] = theScore; GetDateTime(&thisHousePtr->highScores.timeStamps[kMaxScores - 1]); thisHousePtr->highScores.levels[kMaxScores - 1] = CountRoomsVisited(); SortHighScores(); gameDirty = true; } HSetState((Handle)thisHouse, wasState); if (placing != -1) { DoHighScores(); return (true); } else return (false); } //-------------------------------------------------------------- UpdateNameDialog // Redraws the "Enter High Score Name" dialog. void UpdateNameDialog (DialogPtr theDialog) { short nChars; DrawDialog(theDialog); DrawDefaultButton(theDialog); nChars = GetDialogStringLen(theDialog, kHighNameItem); SetDialogNumToStr(theDialog, kNameNCharsItem, (long)nChars); } //-------------------------------------------------------------- NameFilter // Dialog filter for the "Enter High Score Name" dialog. pascal Boolean NameFilter (DialogPtr dial, EventRecord *event, short *item) { short nChars; if (keyStroke) { nChars = GetDialogStringLen(dial, kHighNameItem); SetDialogNumToStr(dial, kNameNCharsItem, (long)nChars); keyStroke = false; } switch (event->what) { case keyDown: keyStroke = true; switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: PlayPrioritySound(kCarriageSound, kCarriagePriority); FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kTabKeyASCII: SelectDialogItemText(dial, kHighNameItem, 0, 1024); return(false); break; default: PlayPrioritySound(kTypingSound, kTypingPriority); return(false); } break; case updateEvt: BeginUpdate(GetDialogWindow(dial)); UpdateNameDialog(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- GetHighScoreName // Brings up a dialog to get player's name (due to a high score). void GetHighScoreName (short place) { DialogPtr theDial; Str255 scoreStr, placeStr, tempStr; short item; Boolean leaving; ModalFilterUPP nameFilterUPP; nameFilterUPP = NewModalFilterUPP(NameFilter); InitCursor(); NumToString(theScore, scoreStr); NumToString((long)place, placeStr); ParamText(scoreStr, placeStr, thisHouseName, "\p"); PlayPrioritySound(kEnergizeSound, kEnergizePriority); BringUpDialog(&theDial, kHighNameDialogID); FlushEvents(everyEvent, 0); SetDialogString(theDial, kHighNameItem, highName); SelectDialogItemText(theDial, kHighNameItem, 0, 1024); leaving = false; while (!leaving) { ModalDialog(nameFilterUPP, &item); if (item == kOkayButton) { GetDialogString(theDial, kHighNameItem, tempStr); PasStringCopyNum(tempStr, highName, 15); leaving = true; } } DisposeDialog(theDial); DisposeModalFilterUPP(nameFilterUPP); } //-------------------------------------------------------------- UpdateBannerDialog // Redraws the "Enter Message" dialog. void UpdateBannerDialog (DialogPtr theDialog) { short nChars; DrawDialog(theDialog); DrawDefaultButton(theDialog); nChars = GetDialogStringLen(theDialog, kHighBannerItem); SetDialogNumToStr(theDialog, kBannerScoreNCharsItem, (long)nChars); } //-------------------------------------------------------------- BannerFilter // Dialog filter for the "Enter Message" dialog. pascal Boolean BannerFilter (DialogPtr dial, EventRecord *event, short *item) { short nChars; if (keyStroke) { nChars = GetDialogStringLen(dial, kHighBannerItem); SetDialogNumToStr(dial, kBannerScoreNCharsItem, (long)nChars); keyStroke = false; } switch (event->what) { case keyDown: keyStroke = true; switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: PlayPrioritySound(kCarriageSound, kCarriagePriority); FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kTabKeyASCII: SelectDialogItemText(dial, kHighBannerItem, 0, 1024); return(false); break; default: PlayPrioritySound(kTypingSound, kTypingPriority); return(false); } break; case updateEvt: BeginUpdate(GetDialogWindow(dial)); UpdateBannerDialog(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- GetHighScoreBanner // A player who gets the #1 slot gets to enter a short message (thatÉ // appears across the top of the high scores list). This dialogÉ // gets that message. void GetHighScoreBanner (void) { DialogPtr theDial; Str255 tempStr; short item; Boolean leaving; ModalFilterUPP bannerFilterUPP; bannerFilterUPP = NewModalFilterUPP(BannerFilter); PlayPrioritySound(kEnergizeSound, kEnergizePriority); BringUpDialog(&theDial, kHighBannerDialogID); SetDialogString(theDial, kHighBannerItem, highBanner); SelectDialogItemText(theDial, kHighBannerItem, 0, 1024); leaving = false; while (!leaving) { ModalDialog(bannerFilterUPP, &item); if (item == kOkayButton) { GetDialogString(theDial, kHighBannerItem, tempStr); PasStringCopyNum(tempStr, highBanner, 31); leaving = true; } } DisposeDialog(theDial); DisposeModalFilterUPP(bannerFilterUPP); } //-------------------------------------------------------------- CreateScoresFolder Boolean CreateScoresFolder (long *scoresDirID) { FSSpec scoresSpec; long prefsDirID; OSErr theErr; short volRefNum; theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, &volRefNum, &prefsDirID); if (!CheckFileError(theErr, "\pPrefs Folder")) return (false); theErr = FSMakeFSSpec(volRefNum, prefsDirID, "\pG-PRO Scores Ä", &scoresSpec); theErr = FSpDirCreate(&scoresSpec, smSystemScript, scoresDirID); if (!CheckFileError(theErr, "\pHigh Scores Folder")) return (false); return (true); } //-------------------------------------------------------------- FindHighScoresFolder Boolean FindHighScoresFolder (short *volRefNum, long *scoresDirID) { CInfoPBRec theBlock; Str255 nameString; long prefsDirID; OSErr theErr; short count; Boolean foundIt; theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, volRefNum, &prefsDirID); if (!CheckFileError(theErr, "\pPrefs Folder")) return (false); PasStringCopy("\pG-PRO Scores Ä", nameString); count = 1; foundIt = false; theBlock.dirInfo.ioCompletion = nil; theBlock.dirInfo.ioVRefNum = *volRefNum; theBlock.dirInfo.ioNamePtr = nameString; while ((theErr == noErr) && (!foundIt)) { theBlock.dirInfo.ioFDirIndex = count; theBlock.dirInfo.ioDrDirID = prefsDirID; theErr = PBGetCatInfo(&theBlock, false); if (theErr == noErr) { if ((theBlock.dirInfo.ioFlAttrib & 0x10) == 0x10) { if (EqualString(theBlock.dirInfo.ioNamePtr, "\pG-PRO Scores Ä", true, true)) { foundIt = true; *scoresDirID = theBlock.dirInfo.ioDrDirID; } } count++; } } if (theErr == fnfErr) { if (CreateScoresFolder(scoresDirID)) return (true); else return (false); } else return (true); } //-------------------------------------------------------------- OpenHighScoresFile Boolean OpenHighScoresFile (FSSpec *scoreSpec, short *scoresRefNum) { OSErr theErr; theErr = FSpOpenDF(scoreSpec, fsCurPerm, scoresRefNum); if (theErr == fnfErr) { theErr = FSpCreate(scoreSpec, 'ozm5', 'gliS', smSystemScript); if (!CheckFileError(theErr, "\pNew High Scores File")) return (false); theErr = FSpOpenDF(scoreSpec, fsCurPerm, scoresRefNum); if (!CheckFileError(theErr, "\pHigh Score")) return (false); } else if (!CheckFileError(theErr, "\pHigh Score")) return (false); return (true); } //-------------------------------------------------------------- WriteScoresToDisk Boolean WriteScoresToDisk (void) { scoresType *theScores; FSSpec scoreSpec; long dirID, byteCount; OSErr theErr; short volRefNum, scoresRefNum; char wasState; if (!FindHighScoresFolder(&volRefNum, &dirID)) { SysBeep(1); return (false); } theErr = FSMakeFSSpec(volRefNum, dirID, thisHouseName, &scoreSpec); if (!OpenHighScoresFile(&scoreSpec, &scoresRefNum)) { SysBeep(1); return (false); } theErr = SetFPos(scoresRefNum, fsFromStart, 0L); if (!CheckFileError(theErr, "\pHigh Scores File")) { theErr = FSClose(scoresRefNum); return(false); } byteCount = sizeof(scoresType); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); theScores = &((*thisHouse)->highScores); theErr = FSWrite(scoresRefNum, &byteCount, (Ptr)theScores); if (!CheckFileError(theErr, "\pHigh Scores File")) { HSetState((Handle)thisHouse, wasState); theErr = FSClose(scoresRefNum); return(false); } HSetState((Handle)thisHouse, wasState); theErr = SetEOF(scoresRefNum, byteCount); if (!CheckFileError(theErr, "\pHigh Scores File")) { theErr = FSClose(scoresRefNum); return(false); } theErr = FSClose(scoresRefNum); if (!CheckFileError(theErr, "\pHigh Scores File")) return(false); return (true); } //-------------------------------------------------------------- ReadScoresFromDisk Boolean ReadScoresFromDisk (void) { scoresType *theScores; FSSpec scoreSpec; long dirID, byteCount; OSErr theErr; short volRefNum, scoresRefNum; char wasState; if (!FindHighScoresFolder(&volRefNum, &dirID)) { SysBeep(1); return (false); } theErr = FSMakeFSSpec(volRefNum, dirID, thisHouseName, &scoreSpec); if (!OpenHighScoresFile(&scoreSpec, &scoresRefNum)) { SysBeep(1); return (false); } theErr = GetEOF(scoresRefNum, &byteCount); if (!CheckFileError(theErr, "\pHigh Scores File")) { theErr = FSClose(scoresRefNum); return (false); } theErr = SetFPos(scoresRefNum, fsFromStart, 0L); if (!CheckFileError(theErr, "\pHigh Scores File")) { theErr = FSClose(scoresRefNum); return (false); } wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); theScores = &((*thisHouse)->highScores); theErr = FSRead(scoresRefNum, &byteCount, theScores); if (!CheckFileError(theErr, "\pHigh Scores File")) { HSetState((Handle)thisHouse, wasState); theErr = FSClose(scoresRefNum); return (false); } HSetState((Handle)thisHouse, wasState); theErr = FSClose(scoresRefNum); if (!CheckFileError(theErr, "\pHigh Scores File")) return(false); return (true); } \ No newline at end of file diff --git a/Sources/House.c b/Sources/House.c deleted file mode 100755 index cfd8641..0000000 --- a/Sources/House.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // House.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include #include "DialogUtils.h" #include "Externs.h" #include "House.h" #include "RectUtils.h" #define kGoToDialogID 1043 void UpdateGoToDialog (DialogPtr); pascal Boolean GoToFilter (DialogPtr, EventRecord *, short *); houseHand thisHouse; linksPtr linksList; Str32 thisHouseName; short srcLocations[kMaxRoomObs]; short destLocations[kMaxRoomObs]; short wasFloor, wasSuite; retroLink retroLinkList[kMaxRoomObs]; Boolean houseUnlocked; extern gameType smallGame; extern short numberRooms, mapLeftRoom, mapTopRoom, numStarsRemaining; extern Boolean houseOpen, noRoomAtAll; extern Boolean twoPlayerGame, wardBitSet, phoneBitSet; //============================================================== Functions //-------------------------------------------------------------- CreateNewHouse // Called to create a new house file. #ifndef COMPILEDEMO Boolean CreateNewHouse (void) { AEKeyword theKeyword; DescType actualType; Size actualSize; NavReplyRecord theReply; NavDialogOptions dialogOptions; FSSpec tempSpec; FSSpec theSpec; OSErr theErr; theErr = NavGetDefaultDialogOptions(&dialogOptions); theErr = NavPutFile(nil, &theReply, &dialogOptions, nil, 'gliH', 'ozm5', nil); if (theErr == userCanceledErr) return false; if (!theReply.validRecord) return (false); theErr = AEGetNthPtr(&(theReply.selection), 1, typeFSS, &theKeyword, &actualType, &theSpec, sizeof(FSSpec), &actualSize); if (theReply.replacing) { theErr = FSMakeFSSpec(theSpec.vRefNum, theSpec.parID, theSpec.name, &tempSpec); if (!CheckFileError(theErr, theSpec.name)) return (false); theErr = FSpDelete(&tempSpec); if (!CheckFileError(theErr, theSpec.name)) return (false); } if (houseOpen) { if (!CloseHouse()) return (false); } theErr = FSpCreate(&theSpec, 'ozm5', 'gliH', theReply.keyScript); if (!CheckFileError(theErr, "\pNew House")) return (false); HCreateResFile(theSpec.vRefNum, theSpec.parID, theSpec.name); if (ResError() != noErr) YellowAlert(kYellowFailedResCreate, ResError()); PasStringCopy(theSpec.name, thisHouseName); AddExtraHouse(&theSpec); BuildHouseList(); InitCursor(); if (!OpenHouse()) return (false); return (true); } #endif //-------------------------------------------------------------- InitializeEmptyHouse // Initializes all the structures for an empty (new) house. #ifndef COMPILEDEMO Boolean InitializeEmptyHouse (void) { houseType *thisHousePtr; Str255 tempStr; if (thisHouse != nil) DisposeHandle((Handle)thisHouse); thisHouse = (houseHand)NewHandle(sizeof(houseType)); if (thisHouse == nil) { YellowAlert(kYellowUnaccounted, 1); return (false); } HLock((Handle)thisHouse); thisHousePtr = *thisHouse; thisHousePtr->version = kHouseVersion; thisHousePtr->firstRoom = -1; thisHousePtr->timeStamp = 0L; thisHousePtr->flags = 0L; thisHousePtr->initial.h = 32; thisHousePtr->initial.v = 32; ZeroHighScores(); GetLocalizedString(11, tempStr); PasStringCopy(tempStr, thisHousePtr->banner); GetLocalizedString(12, tempStr); PasStringCopy(tempStr, thisHousePtr->trailer); thisHousePtr->hasGame = false; thisHousePtr->nRooms = 0; wardBitSet = false; phoneBitSet = false; HUnlock((Handle)thisHouse); numberRooms = 0; mapLeftRoom = 60; mapTopRoom = 50; thisRoomNumber = kRoomIsEmpty; previousRoom = -1; houseUnlocked = true; OpenMapWindow(); UpdateMapWindow(); noRoomAtAll = true; fileDirty = true; UpdateMenus(false); ReflectCurrentRoom(true); return (true); } #endif //-------------------------------------------------------------- RealRoomNumberCount // Returns the real number of rooms in a house (some rooms may stillÉ // be place-holders - they were deleted earlier and are flagged asÉ // deleted but still occupy space in the file). short RealRoomNumberCount (void) { short realRoomCount, i; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); realRoomCount = (*thisHouse)->nRooms; if (realRoomCount != 0) { for (i = 0; i < (*thisHouse)->nRooms; i++) { if ((*thisHouse)->rooms[i].suite == kRoomIsEmpty) realRoomCount--; } } HSetState((Handle)thisHouse, wasState); return (realRoomCount); } //-------------------------------------------------------------- GetFirstRoomNumber // Returns the room number (indicee into house file) of the room whereÉ // the player is to begin. short GetFirstRoomNumber (void) { short firstRoom; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); if ((*thisHouse)->nRooms <= 0) { firstRoom = -1; noRoomAtAll = true; } else { firstRoom = (*thisHouse)->firstRoom; if ((firstRoom >= (*thisHouse)->nRooms) || (firstRoom < 0)) firstRoom = 0; } HSetState((Handle)thisHouse, wasState); return (firstRoom); } //-------------------------------------------------------------- WhereDoesGliderBegin // Returns a rectangle indicating where in the first room the player'sÉ // glider is to appear. void WhereDoesGliderBegin (Rect *theRect, short mode) { Point initialPt; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); if (mode == kResumeGameMode) initialPt = smallGame.where; else if (mode == kNewGameMode) initialPt = (*thisHouse)->initial; HSetState((Handle)thisHouse, wasState); QSetRect(theRect, 0, 0, kGliderWide, kGliderHigh); QOffsetRect(theRect, initialPt.h, initialPt.v); } //-------------------------------------------------------------- HouseHasOriginalPicts // Returns true is the current house has custom artwork imbedded. Boolean HouseHasOriginalPicts (void) { short nPicts; nPicts = Count1Resources('PICT'); return (nPicts > 0); } //-------------------------------------------------------------- CountHouseLinks // Counts up the number of linked objects in a house. short CountHouseLinks (void) { houseType *thisHousePtr; short numRooms, numLinks; short r, i, what; char wasState; numLinks = 0; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; numRooms = thisHousePtr->nRooms; for (r = 0; r < numRooms; r++) { for (i = 0; i < kMaxRoomObs; i++) { what = thisHousePtr->rooms[r].objects[i].what; switch (what) { case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: if (thisHousePtr->rooms[r].objects[i].data.e.where != -1) numLinks++; break; case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kInvisTrans: case kDeluxeTrans: if (thisHousePtr->rooms[r].objects[i].data.d.where != -1) numLinks++; break; } } } HSetState((Handle)thisHouse, wasState); return (numLinks); } //-------------------------------------------------------------- GenerateLinksList // Generates a list of all objects that have links and what roomsÉ // and objects they are linked to. It is called in order to preserveÉ // the links if the objects or rooms in a house are to be shuffledÉ // around. #ifndef COMPILEDEMO void GenerateLinksList (void) { houseType *thisHousePtr; objectType thisObject; short numLinks, numRooms, r, i, what; short floor, suite, roomLinked, objectLinked; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; numRooms = thisHousePtr->nRooms; numLinks = 0; for (r = 0; r < numRooms; r++) { for (i = 0; i < kMaxRoomObs; i++) { what = thisHousePtr->rooms[r].objects[i].what; switch (what) { case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: thisObject = thisHousePtr->rooms[r].objects[i]; if (thisObject.data.e.where != -1) { ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); roomLinked = GetRoomNumber(floor, suite); objectLinked = (short)thisObject.data.e.who; linksList[numLinks].srcRoom = r; linksList[numLinks].srcObj = i; linksList[numLinks].destRoom = roomLinked; linksList[numLinks].destObj = objectLinked; numLinks++; } break; case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kInvisTrans: case kDeluxeTrans: thisObject = thisHousePtr->rooms[r].objects[i]; if (thisObject.data.d.where != -1) { ExtractFloorSuite(thisObject.data.d.where, &floor, &suite); roomLinked = GetRoomNumber(floor, suite); objectLinked = (short)thisObject.data.d.who; linksList[numLinks].srcRoom = r; linksList[numLinks].srcObj = i; linksList[numLinks].destRoom = roomLinked; linksList[numLinks].destObj = objectLinked; numLinks++; } break; } } } HSetState((Handle)thisHouse, wasState); } #endif //-------------------------------------------------------------- SortRoomObjects // I'm a little fuzzy on what this does. #ifndef COMPILEDEMO void SortRoomsObjects (short which) { short probe, probe2, room, obj; Boolean busy, looking; busy = true; probe = 0; do { if ((*thisHouse)->rooms[which].objects[probe].what == kObjectIsEmpty) { looking = true; probe2 = probe + 1; // begin by looking at the next object do { if ((*thisHouse)->rooms[which].objects[probe2].what != kObjectIsEmpty) { (*thisHouse)->rooms[which].objects[probe] = (*thisHouse)->rooms[which].objects[probe2]; (*thisHouse)->rooms[which].objects[probe2].what = kObjectIsEmpty; if (srcLocations[probe2] != -1) linksList[srcLocations[probe2]].srcObj = probe; if (destLocations[probe2] != -1) { linksList[destLocations[probe2]].destObj = probe; room = linksList[destLocations[probe2]].srcRoom; obj = linksList[destLocations[probe2]].srcObj; (*thisHouse)->rooms[room].objects[obj].data.e.who = probe; } fileDirty = true; looking = false; } probe2++; if ((probe2 >= kMaxRoomObs) && (looking)) { looking = false; busy = false; } } while (looking); } probe++; if (probe >= (kMaxRoomObs - 1)) busy = false; } while (busy); } #endif //-------------------------------------------------------------- SortHouseObjects // I'm a little fuzzy on what this does exactly either. #ifndef COMPILEDEMO void SortHouseObjects (void) { houseType *thisHousePtr; short numLinks, numRooms, r, i, l; char wasState; SpinCursor(3); CopyThisRoomToRoom(); numLinks = CountHouseLinks(); if (numLinks == 0) return; linksList = nil; linksList = (linksPtr)NewPtr(sizeof(linksType) * numLinks); if (linksList == nil) RedAlert(kErrNoMemory); GenerateLinksList(); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; numRooms = thisHousePtr->nRooms; for (r = 0; r < numRooms; r++) { for (i = 0; i < kMaxRoomObs; i++) // initialize arrays { srcLocations[i] = -1; destLocations[i] = -1; } for (i = 0; i < kMaxRoomObs; i++) // walk object list { for (l = 0; l < numLinks; l++) // walk link list { if ((linksList[l].srcRoom == r) && (linksList[l].srcObj == i)) srcLocations[i] = l; if ((linksList[l].destRoom == r) && (linksList[l].destObj == i)) destLocations[i] = l; } } SortRoomsObjects(r); if ((r & 0x0007) == 0x0007) IncrementCursor(); } SpinCursor(3); HSetState((Handle)thisHouse, wasState); if (linksList != nil) DisposePtr((Ptr)linksList); ForceThisRoom(thisRoomNumber); } #endif //-------------------------------------------------------------- CountRoomsVisited // Goes through and counts the number of rooms a player has been to inÉ // the current game. short CountRoomsVisited (void) { houseType *thisHousePtr; short numRooms, r, count; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; numRooms = thisHousePtr->nRooms; count = 0; for (r = 0; r < numRooms; r++) { if (thisHousePtr->rooms[r].visited) count++; } HSetState((Handle)thisHouse, wasState); return (count); } //-------------------------------------------------------------- GenerateRetroLinks // Walk entire house looking for objects which are linked to objectsÉ // in the current room. void GenerateRetroLinks (void) { houseType *thisHousePtr; objectType thisObject; short i, r, numRooms, floor, suite; short what, roomLinked, objectLinked; char wasState; for (i = 0; i < kMaxRoomObs; i++) // Initialize array. retroLinkList[i].room = -1; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; numRooms = thisHousePtr->nRooms; for (r = 0; r < numRooms; r++) { for (i = 0; i < kMaxRoomObs; i++) { what = thisHousePtr->rooms[r].objects[i].what; switch (what) { case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: thisObject = thisHousePtr->rooms[r].objects[i]; if (thisObject.data.e.where != -1) { ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); roomLinked = GetRoomNumber(floor, suite); if (roomLinked == thisRoomNumber) { objectLinked = (short)thisObject.data.e.who; if (retroLinkList[objectLinked].room == -1) { retroLinkList[objectLinked].room = r; retroLinkList[objectLinked].object = i; } } } break; case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kInvisTrans: case kDeluxeTrans: thisObject = thisHousePtr->rooms[r].objects[i]; if (thisObject.data.d.where != -1) { ExtractFloorSuite(thisObject.data.d.where, &floor, &suite); roomLinked = GetRoomNumber(floor, suite); if (roomLinked == thisRoomNumber) { objectLinked = (short)thisObject.data.d.who; if (retroLinkList[objectLinked].room == -1) { retroLinkList[objectLinked].room = r; retroLinkList[objectLinked].object = i; } } } break; } } } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- UpdateGoToDialog // Redraws the "Go To Room..." dialog. void UpdateGoToDialog (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 10, kRedOrangeColor8); } //-------------------------------------------------------------- GoToFilter // Dialog filter for the "Go To Room..." dialog. pascal Boolean GoToFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; default: return(false); } break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateGoToDialog(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- DoGoToDialog // "Go To Room..." dialog. void DoGoToDialog (void) { #define kGoToFirstButt 2 #define kGoToPrevButt 3 #define kGoToFSButt 4 #define kFloorEditText 5 #define kSuiteEditText 6 DialogPtr theDialog; long tempLong; short item, roomToGoTo; Boolean leaving, canceled; ModalFilterUPP goToFilterUPP; goToFilterUPP = NewModalFilterUPP(GoToFilter); BringUpDialog(&theDialog, kGoToDialogID); if (GetFirstRoomNumber() == thisRoomNumber) MyDisableControl(theDialog, kGoToFirstButt); if ((!RoomNumExists(previousRoom)) || (previousRoom == thisRoomNumber)) MyDisableControl(theDialog, kGoToPrevButt); SetDialogNumToStr(theDialog, kFloorEditText, (long)wasFloor); SetDialogNumToStr(theDialog, kSuiteEditText, (long)wasSuite); SelectDialogItemText(theDialog, kFloorEditText, 0, 1024); leaving = false; canceled = false; while (!leaving) { ModalDialog(goToFilterUPP, &item); if (item == kOkayButton) { roomToGoTo = -1; canceled = true; leaving = true; } else if (item == kGoToFirstButt) { roomToGoTo = GetFirstRoomNumber(); leaving = true; } else if (item == kGoToPrevButt) { roomToGoTo = previousRoom; leaving = true; } else if (item == kGoToFSButt) { GetDialogNumFromStr(theDialog, kFloorEditText, &tempLong); wasFloor = (short)tempLong; GetDialogNumFromStr(theDialog, kSuiteEditText, &tempLong); wasSuite = (short)tempLong; roomToGoTo = GetRoomNumber(wasFloor, wasSuite); leaving = true; } } DisposeDialog(theDialog); DisposeModalFilterUPP(goToFilterUPP); if (!canceled) { if (RoomNumExists(roomToGoTo)) { DeselectObject(); CopyRoomToThisRoom(roomToGoTo); ReflectCurrentRoom(false); } else SysBeep(1); } } //-------------------------------------------------------------- ConvertHouseVer1To2 // This function goes through an old version 1 house and converts itÉ // to version 2. void ConvertHouseVer1To2 (void) { Str255 roomStr, message; short wasRoom, floor, suite; short i, h, numRooms; char wasState; CopyThisRoomToRoom(); wasRoom = thisRoomNumber; GetLocalizedString(13, message); OpenMessageWindow(message); SpinCursor(3); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; for (i = 0; i < numRooms; i++) { if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) { NumToString((long)i, roomStr); GetLocalizedString(14, message); PasStringConcat(message, roomStr); SetMessageWindowMessage(message); SpinCursor(1); ForceThisRoom(i); for (h = 0; h < kMaxRoomObs; h++) { switch (thisRoom->objects[h].what) { case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kInvisTrans: case kDeluxeTrans: if (thisRoom->objects[h].data.d.where != -1) { ExtractFloorSuite(thisRoom->objects[h].data.d.where, &floor, &suite); floor += kNumUndergroundFloors; thisRoom->objects[h].data.d.where = MergeFloorSuite(floor, suite); } break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: if (thisRoom->objects[h].data.e.where != -1) { ExtractFloorSuite(thisRoom->objects[h].data.e.where, &floor, &suite); floor += kNumUndergroundFloors; thisRoom->objects[h].data.e.where = MergeFloorSuite(floor, suite); } break; } } CopyThisRoomToRoom(); } } (*thisHouse)->version = kHouseVersion; HSetState((Handle)thisHouse, wasState); InitCursor(); CloseMessageWindow(); ForceThisRoom(wasRoom); } //-------------------------------------------------------------- ShiftWholeHouse void ShiftWholeHouse (short howFar) { #pragma unused (howFar) short wasRoom; short i, h, numRooms; char wasState; OpenMessageWindow("\pShifting Whole HouseÉ"); SpinCursor(3); CopyThisRoomToRoom(); wasRoom = thisRoomNumber; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; for (i = 0; i < numRooms; i++) { if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) { SpinCursor(1); ForceThisRoom(i); for (h = 0; h < kMaxRoomObs; h++) { } CopyThisRoomToRoom(); } } HSetState((Handle)thisHouse, wasState); ForceThisRoom(wasRoom); InitCursor(); CloseMessageWindow(); } \ No newline at end of file diff --git a/Sources/HouseIO.c b/Sources/HouseIO.c deleted file mode 100755 index 46517c2..0000000 --- a/Sources/HouseIO.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // HouseIO.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include #include #include "Externs.h" #include "Environ.h" #include "House.h" #include "ObjectEdit.h" #define kSaveChangesAlert 1002 #define kSaveChanges 1 #define kDiscardChanges 2 void LoopMovie (void); void OpenHouseMovie (void); void CloseHouseMovie (void); Boolean IsFileReadOnly (FSSpec *); Movie theMovie; Rect movieRect; short houseRefNum, houseResFork, wasHouseVersion; Boolean houseOpen, fileDirty, gameDirty; Boolean changeLockStateOfHouse, saveHouseLocked, houseIsReadOnly; Boolean hasMovie, tvInRoom; extern FSSpecPtr theHousesSpecs; extern short thisHouseIndex, tvWithMovieNumber; extern short numberRooms, housesFound; extern Boolean noRoomAtAll, quitting, wardBitSet; extern Boolean phoneBitSet, bannerStarCountOn; //============================================================== Functions //-------------------------------------------------------------- LoopMovie void LoopMovie (void) { Handle theLoop; UserData theUserData; short theCount; theLoop = NewHandle(sizeof(long)); (** (long **) theLoop) = 0; theUserData = GetMovieUserData(theMovie); theCount = CountUserDataType(theUserData, 'LOOP'); while (theCount--) { RemoveUserData(theUserData, 'LOOP', 1); } AddUserData(theUserData, theLoop, 'LOOP'); } //-------------------------------------------------------------- OpenHouseMovie void OpenHouseMovie (void) { #ifdef COMPILEQT TimeBase theTime; FSSpec theSpec; FInfo finderInfo; Handle spaceSaver; OSErr theErr; short movieRefNum; Boolean dataRefWasChanged; if (thisMac.hasQT) { theSpec = theHousesSpecs[thisHouseIndex]; PasStringConcat(theSpec.name, "\p.mov"); theErr = FSpGetFInfo(&theSpec, &finderInfo); if (theErr != noErr) return; theErr = OpenMovieFile(&theSpec, &movieRefNum, fsCurPerm); if (theErr != noErr) { YellowAlert(kYellowQTMovieNotLoaded, theErr); return; } theErr = NewMovieFromFile(&theMovie, movieRefNum, nil, theSpec.name, newMovieActive, &dataRefWasChanged); if (theErr != noErr) { YellowAlert(kYellowQTMovieNotLoaded, theErr); theErr = CloseMovieFile(movieRefNum); return; } theErr = CloseMovieFile(movieRefNum); spaceSaver = NewHandle(307200L); if (spaceSaver == nil) { YellowAlert(kYellowQTMovieNotLoaded, 749); CloseHouseMovie(); return; } GoToBeginningOfMovie(theMovie); theErr = LoadMovieIntoRam(theMovie, GetMovieTime(theMovie, 0L), GetMovieDuration(theMovie), 0); if (theErr != noErr) { YellowAlert(kYellowQTMovieNotLoaded, theErr); DisposeHandle(spaceSaver); CloseHouseMovie(); return; } DisposeHandle(spaceSaver); theErr = PrerollMovie(theMovie, 0, 0x000F0000); if (theErr != noErr) { YellowAlert(kYellowQTMovieNotLoaded, theErr); CloseHouseMovie(); return; } theTime = GetMovieTimeBase(theMovie); SetTimeBaseFlags(theTime, loopTimeBase); SetMovieMasterTimeBase(theMovie, theTime, nil); LoopMovie(); GetMovieBox(theMovie, &movieRect); hasMovie = true; } #endif } //-------------------------------------------------------------- CloseHouseMovie void CloseHouseMovie (void) { #ifdef COMPILEQT OSErr theErr; if ((thisMac.hasQT) && (hasMovie)) { theErr = LoadMovieIntoRam(theMovie, GetMovieTime(theMovie, 0L), GetMovieDuration(theMovie), flushFromRam); DisposeMovie(theMovie); } #endif hasMovie = false; } //-------------------------------------------------------------- OpenHouse // Opens a house (whatever current selection is). Returns true if all went well. Boolean OpenHouse (void) { OSErr theErr; Boolean targetIsFolder, wasAliased; if (houseOpen) { if (!CloseHouse()) return(false); } if ((housesFound < 1) || (thisHouseIndex == -1)) return(false); theErr = ResolveAliasFile(&theHousesSpecs[thisHouseIndex], true, &targetIsFolder, &wasAliased); if (!CheckFileError(theErr, thisHouseName)) return (false); #ifdef COMPILEDEMO if (!EqualString(theHousesSpecs[thisHouseIndex].name, "\pDemo House", false, true)) return (false); #endif houseIsReadOnly = IsFileReadOnly(&theHousesSpecs[thisHouseIndex]); theErr = FSpOpenDF(&theHousesSpecs[thisHouseIndex], fsCurPerm, &houseRefNum); if (!CheckFileError(theErr, thisHouseName)) return (false); houseOpen = true; OpenHouseResFork(); hasMovie = false; tvInRoom = false; tvWithMovieNumber = -1; OpenHouseMovie(); return (true); } //-------------------------------------------------------------- OpenSpecificHouse // Opens the specific house passed in. #ifndef COMPILEDEMO Boolean OpenSpecificHouse (FSSpec *specs) { short i; Boolean itOpened; if ((housesFound < 1) || (thisHouseIndex == -1)) return (false); itOpened = true; for (i = 0; i < housesFound; i++) { if ((theHousesSpecs[i].vRefNum == specs->vRefNum) && (theHousesSpecs[i].parID == specs->parID) && (EqualString(theHousesSpecs[i].name, specs->name, false, true))) { thisHouseIndex = i; PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); if (OpenHouse()) itOpened = ReadHouse(); else itOpened = false; break; } } return (itOpened); } #endif //-------------------------------------------------------------- SaveHouseAs #ifndef COMPILEDEMO Boolean SaveHouseAs (void) { // TEMP - fix this later -- use NavServices (see House.c) /* StandardFileReply theReply; FSSpec oldHouse; OSErr theErr; Boolean noProblems; Str255 tempStr; noProblems = true; GetLocalizedString(15, tempStr); StandardPutFile(tempStr, thisHouseName, &theReply); if (theReply.sfGood) { oldHouse = theHousesSpecs[thisHouseIndex]; CloseHouseResFork(); // close this house file theErr = FSClose(houseRefNum); if (theErr != noErr) { CheckFileError(theErr, "\pPreferences"); return(false); } // create new house file theErr = FSpCreate(&theReply.sfFile, 'ozm5', 'gliH', theReply.sfScript); if (!CheckFileError(theErr, theReply.sfFile.name)) return (false); HCreateResFile(theReply.sfFile.vRefNum, theReply.sfFile.parID, theReply.sfFile.name); if (ResError() != noErr) YellowAlert(kYellowFailedResCreate, ResError()); PasStringCopy(theReply.sfFile.name, thisHouseName); // open new house data fork theErr = FSpOpenDF(&theReply.sfFile, fsRdWrPerm, &houseRefNum); if (!CheckFileError(theErr, thisHouseName)) return (false); houseOpen = true; noProblems = WriteHouse(false); // write out house data if (!noProblems) return(false); BuildHouseList(); if (OpenSpecificHouse(&theReply.sfFile)) // open new house again { } else { if (OpenSpecificHouse(&oldHouse)) { YellowAlert(kYellowOpenedOldHouse, 0); } else { YellowAlert(kYellowLostAllHouses, 0); noProblems = false; } } } return (noProblems); */ return false; } #endif //-------------------------------------------------------------- ReadHouse // With a house open, this function reads in the actual bits of dataÉ // into memory. Boolean ReadHouse (void) { long byteCount; OSErr theErr; short whichRoom; if (!houseOpen) { YellowAlert(kYellowUnaccounted, 2); return (false); } if (gameDirty || fileDirty) { if (houseIsReadOnly) { if (!WriteScoresToDisk()) { YellowAlert(kYellowFailedWrite, 0); return(false); } } else if (!WriteHouse(false)) return(false); } theErr = GetEOF(houseRefNum, &byteCount); if (theErr != noErr) { CheckFileError(theErr, thisHouseName); return(false); } #ifdef COMPILEDEMO if (byteCount != 16526L) return (false); #endif if (thisHouse != nil) DisposeHandle((Handle)thisHouse); thisHouse = (houseHand)NewHandle(byteCount); if (thisHouse == nil) { YellowAlert(kYellowNoMemory, 10); return(false); } MoveHHi((Handle)thisHouse); theErr = SetFPos(houseRefNum, fsFromStart, 0L); if (theErr != noErr) { CheckFileError(theErr, thisHouseName); return(false); } HLock((Handle)thisHouse); theErr = FSRead(houseRefNum, &byteCount, *thisHouse); if (theErr != noErr) { CheckFileError(theErr, thisHouseName); HUnlock((Handle)thisHouse); return(false); } numberRooms = (*thisHouse)->nRooms; #ifdef COMPILEDEMO if (numberRooms != 45) return (false); #endif if ((numberRooms < 1) || (byteCount == 0L)) { numberRooms = 0; noRoomAtAll = true; YellowAlert(kYellowNoRooms, 0); HUnlock((Handle)thisHouse); return(false); } wasHouseVersion = (*thisHouse)->version; if (wasHouseVersion >= kNewHouseVersion) { YellowAlert(kYellowNewerVersion, 0); HUnlock((Handle)thisHouse); return(false); } houseUnlocked = (((*thisHouse)->timeStamp & 0x00000001) == 0); #ifdef COMPILEDEMO if (houseUnlocked) return (false); #endif changeLockStateOfHouse = false; saveHouseLocked = false; whichRoom = (*thisHouse)->firstRoom; #ifdef COMPILEDEMO if (whichRoom != 0) return (false); #endif wardBitSet = (((*thisHouse)->flags & 0x00000001) == 0x00000001); phoneBitSet = (((*thisHouse)->flags & 0x00000002) == 0x00000002); bannerStarCountOn = (((*thisHouse)->flags & 0x00000004) == 0x00000000); HUnlock((Handle)thisHouse); noRoomAtAll = (RealRoomNumberCount() == 0); thisRoomNumber = -1; previousRoom = -1; if (!noRoomAtAll) CopyRoomToThisRoom(whichRoom); if (houseIsReadOnly) { houseUnlocked = false; if (ReadScoresFromDisk()) { } } objActive = kNoObjectSelected; ReflectCurrentRoom(true); gameDirty = false; fileDirty = false; UpdateMenus(false); return (true); } //-------------------------------------------------------------- WriteHouse // This function writes out the house data to disk. Boolean WriteHouse (Boolean checkIt) { UInt32 timeStamp; long byteCount; OSErr theErr; if (!houseOpen) { YellowAlert(kYellowUnaccounted, 4); return (false); } theErr = SetFPos(houseRefNum, fsFromStart, 0L); if (theErr != noErr) { CheckFileError(theErr, thisHouseName); return(false); } CopyThisRoomToRoom(); if (checkIt) CheckHouseForProblems(); HLock((Handle)thisHouse); byteCount = GetHandleSize((Handle)thisHouse); if (fileDirty) { GetDateTime(&timeStamp); timeStamp &= 0x7FFFFFFF; if (changeLockStateOfHouse) houseUnlocked = !saveHouseLocked; if (houseUnlocked) // house unlocked timeStamp &= 0x7FFFFFFE; else timeStamp |= 0x00000001; (*thisHouse)->timeStamp = (long)timeStamp; (*thisHouse)->version = wasHouseVersion; } theErr = FSWrite(houseRefNum, &byteCount, *thisHouse); if (theErr != noErr) { CheckFileError(theErr, thisHouseName); HUnlock((Handle)thisHouse); return(false); } theErr = SetEOF(houseRefNum, byteCount); if (theErr != noErr) { CheckFileError(theErr, thisHouseName); HUnlock((Handle)thisHouse); return(false); } HUnlock((Handle)thisHouse); if (changeLockStateOfHouse) { changeLockStateOfHouse = false; ReflectCurrentRoom(true); } gameDirty = false; fileDirty = false; UpdateMenus(false); return (true); } //-------------------------------------------------------------- CloseHouse // This function closes the current house that is open. Boolean CloseHouse (void) { OSErr theErr; if (!houseOpen) return (true); if (gameDirty) { if (houseIsReadOnly) { if (!WriteScoresToDisk()) YellowAlert(kYellowFailedWrite, 0); } else if (!WriteHouse(theMode == kEditMode)) YellowAlert(kYellowFailedWrite, 0); } else if (fileDirty) { #ifndef COMPILEDEMO if (!QuerySaveChanges()) // false signifies user canceled return(false); #endif } CloseHouseResFork(); CloseHouseMovie(); theErr = FSClose(houseRefNum); if (theErr != noErr) { CheckFileError(theErr, thisHouseName); return(false); } houseOpen = false; return (true); } //-------------------------------------------------------------- OpenHouseResFork // Opens the resource fork of the current house that is open. void OpenHouseResFork (void) { if (houseResFork == -1) { houseResFork = FSpOpenResFile(&theHousesSpecs[thisHouseIndex], fsCurPerm); if (houseResFork == -1) YellowAlert(kYellowFailedResOpen, ResError()); else UseResFile(houseResFork); } } //-------------------------------------------------------------- CloseHouseResFork // Closes the resource fork of the current house that is open. void CloseHouseResFork (void) { if (houseResFork != -1) { CloseResFile(houseResFork); houseResFork = -1; } } //-------------------------------------------------------------- QuerySaveChanges // If changes were made, this function will present the user with aÉ // dialog asking them if they would like to save the changes. #ifndef COMPILEDEMO Boolean QuerySaveChanges (void) { short hitWhat; Boolean whoCares; if (!fileDirty) return(true); InitCursor(); // CenterAlert(kSaveChangesAlert); ParamText(thisHouseName, "\p", "\p", "\p"); hitWhat = Alert(kSaveChangesAlert, nil); if (hitWhat == kSaveChanges) { if (wasHouseVersion < kHouseVersion) ConvertHouseVer1To2(); wasHouseVersion = kHouseVersion; if (WriteHouse(true)) return (true); else return (false); } else if (hitWhat == kDiscardChanges) { fileDirty = false; if (!quitting) { whoCares = CloseHouse(); if (OpenHouse()) whoCares = ReadHouse(); } UpdateMenus(false); return (true); } else return (false); } #endif //-------------------------------------------------------------- YellowAlert // This is a dialog used to present an error code and explanationÉ // to the user when a non-lethal error has occurred. Ideally, ofÉ // course, this never is called. void YellowAlert (short whichAlert, short identifier) { #define kYellowAlert 1006 Str255 errStr, errNumStr; short whoCares; InitCursor(); GetIndString(errStr, kYellowAlert, whichAlert); NumToString((long)identifier, errNumStr); // CenterAlert(kYellowAlert); ParamText(errStr, errNumStr, "\p", "\p"); whoCares = Alert(kYellowAlert, nil); } //-------------------------------------------------------------- IsFileReadOnly Boolean IsFileReadOnly (FSSpec *theSpec) { #pragma unused (theSpec) return false; /* Str255 tempStr; ParamBlockRec theBlock; HParamBlockRec hBlock; VolumeParam *volPtr; OSErr theErr; volPtr = (VolumeParam *)&theBlock; volPtr->ioCompletion = nil; volPtr->ioVolIndex = 0; volPtr->ioNamePtr = tempStr; volPtr->ioVRefNum = theSpec->vRefNum; theErr = PBGetVInfo(&theBlock, false); if (CheckFileError(theErr, "\pRead/Write")) { if (((volPtr->ioVAtrb & 0x0080) == 0x0080) || ((volPtr->ioVAtrb & 0x8000) == 0x8000)) return (true); // soft/hard locked bits else { hBlock.fileParam.ioCompletion = nil; hBlock.fileParam.ioVRefNum = theSpec->vRefNum; hBlock.fileParam.ioFVersNum = 0; hBlock.fileParam.ioFDirIndex = 0; hBlock.fileParam.ioNamePtr = theSpec->name; hBlock.fileParam.ioDirID = theSpec->parID; theErr = PBHGetFInfo(&hBlock, false); if (CheckFileError(theErr, "\pRead/Write")) { if ((hBlock.fileParam.ioFlAttrib & 0x0001) == 0x0001) return (true); else return (false); } else return (false); } } else return (false); */ } \ No newline at end of file diff --git a/Sources/HouseInfo.c b/Sources/HouseInfo.c deleted file mode 100755 index da7bb14..0000000 --- a/Sources/HouseInfo.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // HouseInfo.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "DialogUtils.h" #define kHouseInfoDialogID 1001 #define kBannerTextItem 4 #define kLockHouseButton 6 #define kClearScoresButton 9 #define kTrailerTextItem 11 #define kNoPhoneCheck 14 #define kBannerNCharsItem 15 #define kTrailerNCharsItem 16 #define kHouseSizeItem 18 #define kLockHouseAlert 1029 #define kZeroScoresAlert 1032 long CountTotalHousePoints (void); void UpdateHouseInfoDialog (DialogPtr); pascal Boolean HouseFilter (DialogPtr, EventRecord *, short *); Boolean WarnLockingHouse (void); void HowToZeroScores (void); Str255 banner, trailer; Rect houseEditText1, houseEditText2; short houseCursorIs; Boolean keyHit, tempPhoneBit; extern Cursor beamCursor; extern Boolean noRoomAtAll, changeLockStateOfHouse, saveHouseLocked; extern Boolean phoneBitSet; #ifndef COMPILEDEMO //============================================================== Functions //-------------------------------------------------------------- CountTotalHousePoints // The following functions all handle the "House Info" dialog in the editor. long CountTotalHousePoints (void) { long pointTotal; short numRooms, h, i; char wasState; pointTotal = (long)RealRoomNumberCount() * (long)kRoomVisitScore; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; for (i = 0; i < numRooms; i++) { if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) { for (h = 0; h < kMaxRoomObs; h++) { switch ((*thisHouse)->rooms[i].objects[h].what) { case kRedClock: pointTotal += kRedClockPoints; break; case kBlueClock: pointTotal += kBlueClockPoints; break; case kYellowClock: pointTotal += kYellowClockPoints; break; case kCuckoo: pointTotal += kCuckooClockPoints; break; case kStar: pointTotal += kStarPoints; break; case kInvisBonus: pointTotal += (*thisHouse)->rooms[i].objects[h].data.c.points; break; default: break; } } } } HSetState((Handle)thisHouse, wasState); return (pointTotal); } //-------------------------------------------------------------- UpdateHouseInfoDialog void UpdateHouseInfoDialog (DialogPtr theDialog) { short nChars; DrawDialog(theDialog); nChars = GetDialogStringLen(theDialog, kBannerTextItem); SetDialogNumToStr(theDialog, kBannerNCharsItem, (long)nChars); nChars = GetDialogStringLen(theDialog, kTrailerTextItem); SetDialogNumToStr(theDialog, kTrailerNCharsItem, (long)nChars); SetDialogNumToStr(theDialog, kHouseSizeItem, CountTotalHousePoints()); FrameDialogItemC(theDialog, 10, kRedOrangeColor8); SetDialogItemValue(theDialog, kNoPhoneCheck, (short)tempPhoneBit); } //-------------------------------------------------------------- HouseFilter pascal Boolean HouseFilter (DialogPtr dial, EventRecord *event, short *item) { Point mouseIs; short nChars; if (keyHit) { nChars = GetDialogStringLen(dial, kBannerTextItem); SetDialogNumToStr(dial, kBannerNCharsItem, (long)nChars); nChars = GetDialogStringLen(dial, kTrailerTextItem); SetDialogNumToStr(dial, kTrailerNCharsItem, (long)nChars); keyHit = false; } switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; default: keyHit = true; return(false); } break; case mouseDown: return(false); break; case mouseUp: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateHouseInfoDialog(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: mouseIs = event->where; GlobalToLocal(&mouseIs); if ((PtInRect(mouseIs, &houseEditText1)) || (PtInRect(mouseIs, &houseEditText2))) { if (houseCursorIs != kBeamCursor) { SetCursor(&beamCursor); houseCursorIs = kBeamCursor; } } else { if (houseCursorIs != kArrowCursor) { InitCursor(); houseCursorIs = kArrowCursor; } } return(false); break; } } //-------------------------------------------------------------- DoHouseInfo void DoHouseInfo (void) { DialogPtr houseInfoDialog; Str255 versStr, loVers, nRoomsStr; long h, v; short item, numRooms, version; char wasState; Boolean leaving; ModalFilterUPP houseFilterUPP; houseFilterUPP = NewModalFilterUPP(HouseFilter); tempPhoneBit = phoneBitSet; wasState = HGetState((Handle)thisHouse); numRooms = RealRoomNumberCount(); HLock((Handle)thisHouse); PasStringCopy((*thisHouse)->banner, banner); PasStringCopy((*thisHouse)->trailer, trailer); version = (*thisHouse)->version; if (!noRoomAtAll) { h = (long)(*thisHouse)->rooms[(*thisHouse)->firstRoom].suite; v = (long)(*thisHouse)->rooms[(*thisHouse)->firstRoom].floor; } HSetState((Handle)thisHouse, wasState); NumToString((long)version >> 8, versStr); // Convert version to two stringsÉ NumToString((long)version % 0x0100, loVers); // the 1's and 1/10th's part. NumToString((long)numRooms, nRoomsStr); // Number of rooms -> string. ParamText(versStr, loVers, nRoomsStr, "\p"); // CenterDialog(kHouseInfoDialogID); houseInfoDialog = GetNewDialog(kHouseInfoDialogID, nil, kPutInFront); if (houseInfoDialog == nil) RedAlert(kErrDialogDidntLoad); SetPort((GrafPtr)houseInfoDialog); ShowWindow(GetDialogWindow(houseInfoDialog)); SetDialogString(houseInfoDialog, kBannerTextItem, banner); SetDialogString(houseInfoDialog, kTrailerTextItem, trailer); SelectDialogItemText(houseInfoDialog, kBannerTextItem, 0, 1024); GetDialogItemRect(houseInfoDialog, kBannerTextItem, &houseEditText1); GetDialogItemRect(houseInfoDialog, kTrailerTextItem, &houseEditText2); houseCursorIs = kArrowCursor; leaving = false; while (!leaving) { ModalDialog(houseFilterUPP, &item); if (item == kOkayButton) { GetDialogString(houseInfoDialog, kBannerTextItem, banner); GetDialogString(houseInfoDialog, kTrailerTextItem, trailer); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); PasStringCopyNum(banner, (*thisHouse)->banner, 255); PasStringCopyNum(trailer, (*thisHouse)->trailer, 255); if (tempPhoneBit != phoneBitSet) { phoneBitSet = tempPhoneBit; if (phoneBitSet) (*thisHouse)->flags = (*thisHouse)->flags | 0x00000002; else (*thisHouse)->flags = (*thisHouse)->flags & 0xFFFFDFFD; } HSetState((Handle)thisHouse, wasState); fileDirty = true; UpdateMenus(false); leaving = true; } else if (item == kCancelButton) leaving = true; else if (item == kLockHouseButton) { if (WarnLockingHouse()) { changeLockStateOfHouse = true; saveHouseLocked = true; fileDirty = true; UpdateMenus(false); } } else if (item == kClearScoresButton) HowToZeroScores(); else if (item == kNoPhoneCheck) { tempPhoneBit = !tempPhoneBit; SetDialogItemValue(houseInfoDialog, kNoPhoneCheck, (short)tempPhoneBit); } } InitCursor(); DisposeDialog(houseInfoDialog); DisposeModalFilterUPP(houseFilterUPP); } //-------------------------------------------------------------- WarnLockingHouse Boolean WarnLockingHouse (void) { short hitWhat; // CenterAlert(kLockHouseAlert); hitWhat = Alert(kLockHouseAlert, nil); return (hitWhat == 1); } //-------------------------------------------------------------- HowToZeroScores void HowToZeroScores (void) { short hitWhat; // CenterAlert(kZeroScoresAlert); hitWhat = Alert(kZeroScoresAlert, nil); switch (hitWhat) { case 2: // zero all ZeroHighScores(); fileDirty = true; UpdateMenus(false); break; case 3: // zero all but highest ZeroAllButHighestScore(); fileDirty = true; UpdateMenus(false); break; } } #endif \ No newline at end of file diff --git a/Sources/HouseLegal.c b/Sources/HouseLegal.c deleted file mode 100755 index 2e50a8d..0000000 --- a/Sources/HouseLegal.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // HouseLegal.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Externs.h" #include "ObjectEdit.h" #include "RectUtils.h" void WrapBannerAndTrailer (void); void ValidateNumberOfRooms (void); void CheckDuplicateFloorSuite (void); void CompressHouse (void); void LopOffExtraRooms (void); void ValidateRoomNumbers (void); void CountUntitledRooms (void); void CheckRoomNameLength (void); void MakeSureNumObjectsJives (void); void KeepAllObjectsLegal (void); void CheckForStaircasePairs (void); short houseErrors, wasRoom; Boolean isHouseChecks; extern short numberRooms; //============================================================== Functions //-------------------------------------------------------------- KeepObjectLegal // Does a test of the current object active for any illegal boundsÉ // or values. It corrects the erros and returns true if any changesÉ // were made. Boolean KeepObjectLegal (void) { objectType *theObject; Rect bounds, roomRect; short direction, dist; char wasState; Boolean unchanged; unchanged = true; #ifndef COMPILEDEMO theObject = &thisRoom->objects[objActive]; if (objActive == kInitialGliderSelected) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); if ((*thisHouse)->initial.h < 0) (*thisHouse)->initial.h = 0; if ((*thisHouse)->initial.v < 0) (*thisHouse)->initial.v = 0; if ((*thisHouse)->initial.h > (kRoomWide - kGliderWide)) (*thisHouse)->initial.h = kRoomWide - kGliderWide; if ((*thisHouse)->initial.v > (kTileHigh - kGliderHigh)) (*thisHouse)->initial.v = kTileHigh - kGliderHigh; HSetState((Handle)thisHouse, wasState); return (true); } QSetRect(&roomRect, 0, 0, kRoomWide, kTileHigh); switch (theObject->what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kLeftFan: case kRightFan: case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kInvisBlower: case kGrecoVent: case kSewerBlower: case kLiftArea: GetObjectRect(&thisRoom->objects[objActive], &bounds); if (ForceRectInRect(&bounds, &roomRect)) { theObject->data.a.topLeft.h = bounds.left; theObject->data.a.topLeft.v = bounds.top; unchanged = false; if (theObject->what == kLiftArea) { theObject->data.a.distance = RectWide(&bounds); theObject->data.a.tall = RectTall(&bounds) / 2; } } if ((theObject->what == kStubby) && (theObject->data.a.topLeft.h % 2 == 0)) { theObject->data.a.topLeft.h--; unchanged = false; } if (((theObject->what == kTaper) || (theObject->what == kCandle) || (theObject->what == kTiki) || (theObject->what == kBBQ)) && (theObject->data.a.topLeft.h % 2 != 0)) { theObject->data.a.topLeft.h--; unchanged = false; } if ((theObject->what == kFloorVent) && (theObject->data.a.topLeft.v != kFloorVentTop)) { theObject->data.a.topLeft.v = kFloorVentTop; theObject->data.a.distance += 2; } if ((theObject->what == kFloorBlower) && (theObject->data.a.topLeft.v != kFloorBlowerTop)) { theObject->data.a.topLeft.v = kFloorBlowerTop; theObject->data.a.distance += 2; } if ((theObject->what == kSewerGrate) && (theObject->data.a.topLeft.v != kSewerGrateTop)) { theObject->data.a.topLeft.v = kSewerGrateTop; theObject->data.a.distance += 2; } if ((theObject->what == kFloorTrans) && (theObject->data.a.topLeft.v != kFloorTransTop)) { theObject->data.a.topLeft.v = kFloorTransTop; theObject->data.a.distance += 2; } if (ObjectHasHandle(&direction, &dist)) { switch (direction) { case kAbove: dist = bounds.top - dist; if ((theObject->what == kFloorVent) || (theObject->what == kFloorBlower) || (theObject->what == kTaper) || (theObject->what == kCandle) || (theObject->what == kStubby)) { if (dist < 36) { theObject->data.a.distance += dist - 36; unchanged = false; } } else { if (dist < 0) { theObject->data.a.distance += dist; unchanged = false; } } break; case kToRight: dist = bounds.right + dist; if (dist > kRoomWide) { theObject->data.a.distance += (kRoomWide - dist); unchanged = false; } break; case kBelow: dist = bounds.bottom + dist; if (dist > kTileHigh) { theObject->data.a.distance += (kTileHigh - dist); unchanged = false; } break; case kToLeft: dist = bounds.left - dist; if (dist < 0) { theObject->data.a.distance += dist; unchanged = false; } break; } } break; case kTable: case kShelf: case kCabinet: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kCounter: case kDresser: case kDeckTable: case kStool: case kTrunk: case kInvisObstacle: case kManhole: case kBooks: case kInvisBounce: GetObjectRect(&thisRoom->objects[objActive], &bounds); if (ForceRectInRect(&bounds, &roomRect)) { theObject->data.b.bounds = bounds; unchanged = false; } if ((theObject->what == kManhole) && (((bounds.left - 3) % 64) != 0)) { theObject->data.b.bounds.left = (((bounds.left + 29) / 64) * 64) + 3; theObject->data.b.bounds.right = theObject->data.b.bounds.left + RectWide(&srcRects[kManhole]); unchanged = false; } break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kGreaseRt: case kGreaseLf: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: case kSlider: GetObjectRect(&thisRoom->objects[objActive], &bounds); if (ForceRectInRect(&bounds, &roomRect)) { theObject->data.c.topLeft.h = bounds.left; theObject->data.c.topLeft.v = bounds.top; unchanged = false; } if ((theObject->what == kGreaseRt) && (bounds.right + theObject->data.c.length > kRoomWide)) { theObject->data.c.length = kRoomWide - bounds.right; unchanged = false; } else if ((theObject->what == kGreaseLf) && (bounds.left - theObject->data.c.length < 0)) { theObject->data.c.length = bounds.left; unchanged = false; } else if ((theObject->what == kSlider) && (bounds.left + theObject->data.c.length > kRoomWide)) { theObject->data.c.length = kRoomWide - bounds.left; unchanged = false; } if (theObject->data.c.topLeft.h % 2 != 0) { theObject->data.c.topLeft.h--; unchanged = false; } if ((theObject->what != kStar) && (theObject->data.c.length % 2 != 0)) { theObject->data.c.length--; unchanged = false; } break; case kUpStairs: case kDownStairs: case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kDoorInLf: case kDoorInRt: case kDoorExRt: case kDoorExLf: case kWindowInLf: case kWindowInRt: case kWindowExRt: case kWindowExLf: case kInvisTrans: case kDeluxeTrans: GetObjectRect(&thisRoom->objects[objActive], &bounds); if (ForceRectInRect(&bounds, &roomRect)) { theObject->data.d.topLeft.h = bounds.left; theObject->data.d.topLeft.v = bounds.top; unchanged = false; if (theObject->what == kDeluxeTrans) { theObject->data.d.tall = ((RectWide(&bounds) / 4) << 8) + (RectTall(&bounds) / 4); } } if ((theObject->what == kDoorInLf) || (theObject->what == kDoorInRt)) { if (theObject->data.d.topLeft.h + HalfRectWide(&srcRects[kDoorInLf]) > (kRoomWide / 2)) { theObject->data.d.topLeft.h = kDoorInRtLeft; theObject->what = kDoorInRt; } else { theObject->data.d.topLeft.h = kDoorInLfLeft; theObject->what = kDoorInLf; } } if ((theObject->what == kDoorExRt) || (theObject->what == kDoorExLf)) { if (theObject->data.d.topLeft.h + HalfRectWide(&srcRects[kDoorExRt]) > (kRoomWide / 2)) { theObject->data.d.topLeft.h = kDoorExRtLeft; theObject->what = kDoorExRt; } else { theObject->data.d.topLeft.h = kDoorExLfLeft; theObject->what = kDoorExLf; } } if ((theObject->what == kWindowInLf) || (theObject->what == kWindowInRt)) { if (theObject->data.d.topLeft.h + HalfRectWide(&srcRects[kWindowInLf]) > (kRoomWide / 2)) { theObject->data.d.topLeft.h = kWindowInRtLeft; theObject->what = kWindowInRt; } else { theObject->data.d.topLeft.h = kWindowInLfLeft; theObject->what = kWindowInLf; } } if ((theObject->what == kWindowExRt) || (theObject->what == kWindowExLf)) { if (theObject->data.d.topLeft.h + HalfRectWide(&srcRects[kWindowExRt]) > (kRoomWide / 2)) { theObject->data.d.topLeft.h = kWindowExRtLeft; theObject->what = kWindowExRt; } else { theObject->data.d.topLeft.h = kWindowExLfLeft; theObject->what = kWindowExLf; } } if ((theObject->what == kInvisTrans) && ((theObject->data.d.topLeft.v + theObject->data.d.tall) > kTileHigh)) { theObject->data.d.tall = kTileHigh - theObject->data.d.topLeft.v; unchanged = false; } if ((theObject->what == kInvisTrans) && (theObject->data.d.wide < 0)) { theObject->data.d.wide = 0; unchanged = false; } break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: GetObjectRect(&thisRoom->objects[objActive], &bounds); if (ForceRectInRect(&bounds, &roomRect)) { theObject->data.e.topLeft.h = bounds.left; theObject->data.e.topLeft.v = bounds.top; unchanged = false; } if (theObject->data.e.topLeft.h % 2 != 0) { theObject->data.e.topLeft.h--; unchanged = false; } break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: GetObjectRect(&thisRoom->objects[objActive], &bounds); if (ForceRectInRect(&bounds, &roomRect)) { if ((theObject->what == kFlourescent) || (theObject->what == kTrackLight)) { if (theObject->data.f.topLeft.h < bounds.left) theObject->data.f.topLeft.h = bounds.left; if (theObject->data.f.topLeft.v < bounds.top) theObject->data.f.topLeft.v = bounds.top; if ((theObject->data.f.topLeft.h + theObject->data.f.length) > bounds.right) theObject->data.f.length = bounds.right - theObject->data.f.topLeft.h; } else { theObject->data.f.topLeft.h = bounds.left; theObject->data.f.topLeft.v = bounds.top; } unchanged = false; } if (((theObject->what == kFlourescent) || (theObject->what == kTrackLight)) && ((bounds.right > kRoomWide) || (bounds.left < 0))) { if (theObject->data.f.topLeft.h < 0) { theObject->data.f.topLeft.h = 0; unchanged = false; } if (bounds.left < 0) { bounds.left = 0; unchanged = false; } if (theObject->data.f.topLeft.h > kRoomWide) { theObject->data.f.topLeft.h = kRoomWide; unchanged = false; } if (bounds.right > kRoomWide) { bounds.right = kRoomWide; unchanged = false; } theObject->data.f.length = kRoomWide - bounds.left; } break; case kShredder: case kToaster: case kMacPlus: case kGuitar: case kTV: case kCoffee: case kOutlet: case kVCR: case kStereo: case kMicrowave: case kCinderBlock: case kFlowerBox: case kCDs: case kCustomPict: GetObjectRect(&thisRoom->objects[objActive], &bounds); if (ForceRectInRect(&bounds, &roomRect)) { theObject->data.g.topLeft.h = bounds.left; theObject->data.g.topLeft.v = bounds.top; unchanged = false; } if ((theObject->what == kToaster) && (bounds.top - theObject->data.g.height < 0)) { theObject->data.g.height = bounds.top; unchanged = false; } if ((theObject->what == kTV) && (theObject->data.g.topLeft.h % 2 == 0)) { theObject->data.g.topLeft.h--; unchanged = false; } if (((theObject->what == kToaster) || (theObject->what == kMacPlus) || (theObject->what == kCoffee) || (theObject->what == kOutlet) || (theObject->what == kVCR) || (theObject->what == kStereo) || (theObject->what == kMicrowave)) && (theObject->data.g.topLeft.h % 2 != 0)) { theObject->data.g.topLeft.h--; unchanged = false; } break; case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kBall: case kDrip: case kFish: case kCobweb: GetObjectRect(&thisRoom->objects[objActive], &bounds); if (ForceRectInRect(&bounds, &roomRect)) { theObject->data.h.topLeft.h = bounds.left; theObject->data.h.topLeft.v = bounds.top; unchanged = false; } if (((theObject->what == kBall) || (theObject->what == kFish)) && (bounds.top - theObject->data.h.length < 0)) { theObject->data.h.length = bounds.top; unchanged = false; } if ((theObject->what == kDrip) && (bounds.bottom + theObject->data.h.length > kTileHigh)) { theObject->data.h.length = kTileHigh - bounds.bottom; unchanged = false; } if (((theObject->what == kBalloon) || (theObject->what == kCopterLf) || (theObject->what == kCopterRt) || (theObject->what == kBall) || (theObject->what == kDrip) || (theObject->what == kFish)) && (theObject->data.h.topLeft.h % 2 != 0)) { theObject->data.h.topLeft.h--; unchanged = false; } break; case kOzma: case kMirror: case kMousehole: case kFireplace: case kFlower: case kWallWindow: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: GetObjectRect(&thisRoom->objects[objActive], &bounds); if (ForceRectInRect(&bounds, &roomRect)) { theObject->data.i.bounds = bounds; unchanged = false; } if (theObject->what == kMirror) { if (theObject->data.i.bounds.left % 2 != 0) { theObject->data.i.bounds.left--; unchanged = false; } if (theObject->data.i.bounds.right % 2 != 0) { theObject->data.i.bounds.right--; unchanged = false; } } break; } #endif return (unchanged); } //-------------------------------------------------------------- WrapBannerAndTrailer // Tries to wrap around the text of the banner and trailer messages. #ifndef COMPILEDEMO void WrapBannerAndTrailer (void) { char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); WrapText((*thisHouse)->banner, 40); WrapText((*thisHouse)->trailer, 64); HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- ValidateNumberOfRooms // Makes sure the number of room count and actual number of rooms match. void ValidateNumberOfRooms (void) { long countedRooms, reportsRooms; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); reportsRooms = (long)(*thisHouse)->nRooms; countedRooms = (GetHandleSize((Handle)thisHouse) - sizeof(houseType)) / sizeof(roomType); if (reportsRooms != countedRooms) { (*thisHouse)->nRooms = (short)countedRooms; numberRooms = (*thisHouse)->nRooms; houseErrors++; } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- CheckDuplicateFloorSuite // Error check, looks for rooms with the same floor suite (stacked). void CheckDuplicateFloorSuite (void) { #define kRoomsTimesSuites 8192 short i, numRooms, bitPlace; char *pidgeonHoles; char wasState; pidgeonHoles = (char *)NewPtrClear(sizeof(char) * kRoomsTimesSuites); if (pidgeonHoles == nil) return; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; for (i = 0; i < numRooms; i++) { if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) { bitPlace = (((*thisHouse)->rooms[i].floor + 7) * 128) + (*thisHouse)->rooms[i].suite; if ((bitPlace < 0) || (bitPlace >= 8192)) DebugStr("\pBlew array"); if (pidgeonHoles[bitPlace] != 0) { houseErrors++; (*thisHouse)->rooms[i].suite = kRoomIsEmpty; } else pidgeonHoles[bitPlace]++; } } HSetState((Handle)thisHouse, wasState); DisposePtr((Ptr)pidgeonHoles); } //-------------------------------------------------------------- CompressHouse // Removes place-holder (deleted) rooms from the middle of the file. void CompressHouse (void) { short wasFirstRoom, roomNumber, probe; char wasState; Boolean compressing, probing; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); wasFirstRoom = (*thisHouse)->firstRoom; compressing = true; roomNumber = (*thisHouse)->nRooms - 1; // start with last room do { if ((*thisHouse)->rooms[roomNumber].suite != kRoomIsEmpty) { // if not an empty roomÉ probe = 0; // start looking for empty slot probing = true; do { // test room at probe to see if empty if ((*thisHouse)->rooms[probe].suite == kRoomIsEmpty) { // if it is, copy room there (*thisHouse)->rooms[probe] = (*thisHouse)->rooms[roomNumber]; (*thisHouse)->rooms[roomNumber].suite = kRoomIsEmpty; if (roomNumber == wasFirstRoom) (*thisHouse)->firstRoom = probe; if (roomNumber == wasRoom) wasRoom = probe; probing = false; } probe++; // bump probe up to next room if ((probing) && (probe >= roomNumber)) { // we reached the current room probing = false; // we can look no further compressing = false; // so we can compress no more } } while (probing); } roomNumber--; // go on to room preceding if (roomNumber <= 0) // stop if we reach the first room compressing = false; } while (compressing); HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- LopOffExtraRooms // Deletes all empty rooms hanging off the end of the house file. void LopOffExtraRooms (void) { long newSize; short r, count; char wasState; Str255 message; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); count = 0; r = (*thisHouse)->nRooms; // begin at last room do { r--; // look for trailing empties if ((*thisHouse)->rooms[r].suite == kRoomIsEmpty) count++; else r = 0; } while (r > 0); if (count > 0) // if there were trailing emptiesÉ { r = (*thisHouse)->nRooms - count; newSize = sizeof(houseType) + (sizeof(roomType) * (long)r); HUnlock((Handle)thisHouse); // resize house handle (shrink) SetHandleSize((Handle)thisHouse, newSize); if (MemError() != noErr) // problem? { ForeColor(redColor); GetLocalizedString(16, message); SetMessageWindowMessage(message); } HLock((Handle)thisHouse); // reflect new room count (*thisHouse)->nRooms -= count; numberRooms = (*thisHouse)->nRooms; } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- ValidateRoomNumbers // Error check - ensures that the floor and suite numbers are within legal ranges. void ValidateRoomNumbers (void) { short i, numRooms; char wasState; Str255 message; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; if (numRooms < 0) { (*thisHouse)->nRooms = 0; numRooms = 0; } for (i = 0; i < numRooms; i++) { if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) { if (((*thisHouse)->rooms[i].floor > 56) || ((*thisHouse)->rooms[i].floor < -7)) { (*thisHouse)->rooms[i].suite = kRoomIsEmpty; ForeColor(redColor); GetLocalizedString(17, message); SetMessageWindowMessage(message); houseErrors++; ForeColor(blackColor); } if (((*thisHouse)->rooms[i].suite >= 128) || ((*thisHouse)->rooms[i].suite < 0)) { (*thisHouse)->rooms[i].suite = kRoomIsEmpty; ForeColor(redColor); GetLocalizedString(18, message); SetMessageWindowMessage(message); houseErrors++; ForeColor(blackColor); } } } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- CountUntitledRooms // Returns the number of rooms left "Untitled". void CountUntitledRooms (void) { short i, numRooms; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; for (i = 0; i < numRooms; i++) { if (((*thisHouse)->rooms[i].suite != kRoomIsEmpty) && (EqualString((*thisHouse)->rooms[i].name, "\pUntitled Room", false, true))) houseErrors++; } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- CheckRoomNameLength // Error check - ensures the length of the room name is legal. void CheckRoomNameLength (void) { short i, numRooms; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; for (i = 0; i < numRooms; i++) { (*thisHouse)->rooms[i].unusedByte = 0; if (((*thisHouse)->rooms[i].suite != kRoomIsEmpty) && ((*thisHouse)->rooms[i].name[0] > 27)) { (*thisHouse)->rooms[i].name[0] = 27; houseErrors++; } } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- MakeSureNumObjectsJives // Error check - ensures the actual count of objects equals number of objects. void MakeSureNumObjectsJives (void) { short i, h, numRooms, count; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; for (i = 0; i < numRooms; i++) { if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) { count = 0; for (h = 0; h < kMaxRoomObs; h++) { if ((*thisHouse)->rooms[i].objects[h].what != kObjectIsEmpty) count++; } if (count != (*thisHouse)->rooms[i].numObjects) { houseErrors++; (*thisHouse)->rooms[i].numObjects = count; } } } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- KeepAllObjectsLegal // Repeatedly calls KeepObjectLegal() on ALL objects in a house. Wow! void KeepAllObjectsLegal (void) { short i, h, numRooms; char wasState; Str255 message; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; for (i = 0; i < numRooms; i++) { if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) { ForceThisRoom(i); for (h = 0; h < kMaxRoomObs; h++) { objActive = h; if (thisRoom->objects[objActive].what != kObjectIsEmpty) { if (!KeepObjectLegal()) { ForeColor(redColor); GetLocalizedString(19, message); SetMessageWindowMessage(message); houseErrors++; ForeColor(blackColor); DelayTicks(60); } } } CopyThisRoomToRoom(); } } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- CheckForStaircasePairs // Ensures that for every up-stair there is a down-stair. void CheckForStaircasePairs (void) { short i, h, g, numRooms, neighbor; char wasState; Boolean hasStairs; Str255 message; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); numRooms = (*thisHouse)->nRooms; for (i = 0; i < numRooms; i++) { if ((*thisHouse)->rooms[i].suite != kRoomIsEmpty) { for (h = 0; h < kMaxRoomObs; h++) { if ((*thisHouse)->rooms[i].objects[h].what == kUpStairs) { thisRoomNumber = i; neighbor = GetNeighborRoomNumber(kNorthRoom); if (neighbor == kRoomIsEmpty) { ForeColor(redColor); GetLocalizedString(20, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); } else { hasStairs = false; for (g = 0; g < kMaxRoomObs; g++) { if ((*thisHouse)->rooms[neighbor].objects[g].what == kDownStairs) hasStairs = true; } if (!hasStairs) { ForeColor(redColor); GetLocalizedString(21, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); } } } else if ((*thisHouse)->rooms[i].objects[h].what == kDownStairs) { thisRoomNumber = i; neighbor = GetNeighborRoomNumber(kSouthRoom); if (neighbor == kRoomIsEmpty) { ForeColor(redColor); GetLocalizedString(22, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); } else { hasStairs = false; for (g = 0; g < kMaxRoomObs; g++) { if ((*thisHouse)->rooms[neighbor].objects[g].what == kUpStairs) hasStairs = true; } if (!hasStairs) { ForeColor(redColor); GetLocalizedString(23, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); } } } } } } HSetState((Handle)thisHouse, wasState); } #endif //-------------------------------------------------------------- CheckHouseForProblems // Calls all the above functions and reports (and corrects) errors. void CheckHouseForProblems (void) { #ifndef COMPILEDEMO Str255 message, message2; short wasActive; houseErrors = 0; CopyThisRoomToRoom(); wasRoom = thisRoomNumber; wasActive = objActive; GetLocalizedString(24, message); OpenMessageWindow(message); SpinCursor(3); GetLocalizedString(25, message); SetMessageWindowMessage(message); WrapBannerAndTrailer(); if (isHouseChecks) { SpinCursor(3); GetLocalizedString(26, message); SetMessageWindowMessage(message); ValidateNumberOfRooms(); if (houseErrors != 0) { GetLocalizedString(27, message); SetMessageWindowMessage(message); DelayTicks(60); houseErrors = 0; } } if (isHouseChecks) { SpinCursor(3); houseErrors = 0; CheckDuplicateFloorSuite(); if (houseErrors != 0) { NumToString((long)houseErrors, message); GetLocalizedString(28, message2); PasStringConcat(message, message2); ForeColor(redColor); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(45); } } SpinCursor(3); CompressHouse(); SpinCursor(3); LopOffExtraRooms(); if (isHouseChecks) { SpinCursor(3); ValidateRoomNumbers(); if (houseErrors != 0) { NumToString((long)houseErrors, message); GetLocalizedString(29, message2); PasStringConcat(message, message2); ForeColor(redColor); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); } } if (isHouseChecks) { SpinCursor(3); houseErrors = 0; CountUntitledRooms(); if (houseErrors != 0) { NumToString((long)houseErrors, message); GetLocalizedString(30, message2); PasStringConcat(message, message2); ForeColor(blueColor); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(45); } } if (isHouseChecks) { SpinCursor(3); houseErrors = 0; CheckRoomNameLength(); if (houseErrors != 0) { NumToString((long)houseErrors, message); GetLocalizedString(31, message2); PasStringConcat(message, message2); ForeColor(blueColor); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(45); } } if (isHouseChecks) { SpinCursor(3); houseErrors = 0; MakeSureNumObjectsJives(); if (houseErrors != 0) { NumToString((long)houseErrors, message); GetLocalizedString(32, message2); PasStringConcat(message, message2); ForeColor(redColor); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); } } if (isHouseChecks) { SpinCursor(3); houseErrors = 0; GetLocalizedString(33, message); SetMessageWindowMessage(message); KeepAllObjectsLegal(); if (houseErrors != 0) { NumToString((long)houseErrors, message); GetLocalizedString(34, message2); PasStringConcat(message, message2); ForeColor(redColor); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); } } if (isHouseChecks) { SpinCursor(3); houseErrors = 0; CheckForStaircasePairs(); } if (isHouseChecks) { SpinCursor(3); if (CountStarsInHouse() < 1) { ForeColor(redColor); GetLocalizedString(35, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); } } InitCursor(); CloseMessageWindow(); ForceThisRoom(wasRoom); objActive = wasActive; #endif } \ No newline at end of file diff --git a/Sources/Input.c b/Sources/Input.c deleted file mode 100755 index 5637c2b..0000000 --- a/Sources/Input.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Input.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "MainWindow.h" #include "RectUtils.h" #define kNormalThrust 5 #define kHyperThrust 8 #define kHeliumLift 4 #define kEscPausePictID 1015 #define kTabPausePictID 1016 #define kSavingGameDial 1042 void LogDemoKey (char); void DoCommandKey (void); void DoPause (void); void DoBatteryEngaged (gliderPtr); void DoHeliumEngaged (gliderPtr); Boolean QuerySaveGame (void); demoPtr demoData; KeyMap theKeys; DialogPtr saveDial; short demoIndex, batteryFrame; Boolean isEscPauseKey, paused, batteryWasEngaged; extern long gameFrame; extern short otherPlayerEscaped; extern Boolean quitting, playing, onePlayerLeft, twoPlayerGame, demoGoing; //============================================================== Functions //-------------------------------------------------------------- LogDemoKey void LogDemoKey (char keyIs) { demoData[demoIndex].frame = gameFrame; demoData[demoIndex].key = keyIs; demoIndex++; } //-------------------------------------------------------------- DoCommandKey void DoCommandKey (void) { if (BitTst(&theKeys, kQKeyMap)) { playing = false; paused = false; if ((!twoPlayerGame) && (!demoGoing)) { if (QuerySaveGame()) SaveGame2(); // New save game. } } else if ((BitTst(&theKeys, kSKeyMap)) && (!twoPlayerGame)) { RefreshScoreboard(kSavingTitleMode); SaveGame2(); // New save game. HideCursor(); CopyRectWorkToMain(&workSrcRect); RefreshScoreboard(kNormalTitleMode); } } //-------------------------------------------------------------- DoPause void DoPause (void) { Rect bounds; SetPort((GrafPtr)mainWindow); QSetRect(&bounds, 0, 0, 214, 54); CenterRectInRect(&bounds, &houseRect); if (isEscPauseKey) LoadScaledGraphic(kEscPausePictID, &bounds); else LoadScaledGraphic(kTabPausePictID, &bounds); do { GetKeys(theKeys); } while ((isEscPauseKey && BitTst(&theKeys, kEscKeyMap)) || (!isEscPauseKey && BitTst(&theKeys, kTabKeyMap))); paused = true; while (paused) { GetKeys(theKeys); if ((isEscPauseKey && BitTst(&theKeys, kEscKeyMap)) || (!isEscPauseKey && BitTst(&theKeys, kTabKeyMap))) paused = false; else if (BitTst(&theKeys, kCommandKeyMap)) DoCommandKey(); } CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &bounds, &bounds, srcCopy, nil); do { GetKeys(theKeys); } while ((isEscPauseKey && BitTst(&theKeys, kEscKeyMap)) || (!isEscPauseKey && BitTst(&theKeys, kTabKeyMap))); } //-------------------------------------------------------------- DoBatteryEngaged void DoBatteryEngaged (gliderPtr thisGlider) { if (thisGlider->facing == kFaceLeft) { if (thisGlider->tipped) thisGlider->hVel += kHyperThrust; else thisGlider->hVel -= kHyperThrust; } else { if (thisGlider->tipped) thisGlider->hVel -= kHyperThrust; else thisGlider->hVel += kHyperThrust; } batteryTotal--; if (batteryTotal == 0) { QuickBatteryRefresh(false); PlayPrioritySound(kFizzleSound, kFizzlePriority); } else { if (!batteryWasEngaged) batteryFrame = 0; if (batteryFrame == 0) PlayPrioritySound(kThrustSound, kThrustPriority); batteryFrame++; if (batteryFrame >= 4) batteryFrame = 0; batteryWasEngaged = true; } } //-------------------------------------------------------------- DoHeliumEngaged void DoHeliumEngaged (gliderPtr thisGlider) { thisGlider->vDesiredVel = -kHeliumLift; batteryTotal++; if (batteryTotal == 0) { QuickBatteryRefresh(false); PlayPrioritySound(kFizzleSound, kFizzlePriority); batteryWasEngaged = false; } else { if (!batteryWasEngaged) batteryFrame = 0; if (batteryFrame == 0) PlayPrioritySound(kHissSound, kHissPriority); batteryFrame++; if (batteryFrame >= 4) batteryFrame = 0; batteryWasEngaged = true; } } //-------------------------------------------------------------- GetDemoInput void GetDemoInput (gliderPtr thisGlider) { if (thisGlider->which == kPlayer1) { GetKeys(theKeys); #if BUILD_ARCADE_VERSION if ((BitTst(&theKeys, thisGlider->leftKey)) || (BitTst(&theKeys, thisGlider->rightKey)) || (BitTst(&theKeys, thisGlider->battKey)) || (BitTst(&theKeys, thisGlider->bandKey))) { playing = false; paused = false; } #else if (BitTst(&theKeys, kCommandKeyMap)) DoCommandKey(); #endif } if (thisGlider->mode == kGliderBurning) { if (thisGlider->facing == kFaceLeft) thisGlider->hDesiredVel -= kNormalThrust; else thisGlider->hDesiredVel += kNormalThrust; } else { thisGlider->heldLeft = false; thisGlider->heldRight = false; thisGlider->tipped = false; if (gameFrame == (long)demoData[demoIndex].frame) { switch (demoData[demoIndex].key) { case 0: // left key thisGlider->hDesiredVel += kNormalThrust; thisGlider->tipped = (thisGlider->facing == kFaceLeft); thisGlider->heldRight = true; thisGlider->fireHeld = false; break; case 1: // right key thisGlider->hDesiredVel -= kNormalThrust; thisGlider->tipped = (thisGlider->facing == kFaceRight); thisGlider->heldLeft = true; thisGlider->fireHeld = false; break; case 2: // battery key if (batteryTotal > 0) DoBatteryEngaged(thisGlider); else DoHeliumEngaged(thisGlider); thisGlider->fireHeld = false; break; case 3: // rubber band key if (!thisGlider->fireHeld) { if (AddBand(thisGlider, thisGlider->dest.left + 24, thisGlider->dest.top + 10, thisGlider->facing)) { bandsTotal--; if (bandsTotal <= 0) QuickBandsRefresh(false); thisGlider->fireHeld = true; } } break; } demoIndex++; } else thisGlider->fireHeld = false; if ((isEscPauseKey && BitTst(&theKeys, kEscKeyMap)) || (!isEscPauseKey && BitTst(&theKeys, kTabKeyMap))) { DoPause(); } } } //-------------------------------------------------------------- GetInput void GetInput (gliderPtr thisGlider) { if (thisGlider->which == kPlayer1) { GetKeys(theKeys); if (BitTst(&theKeys, kCommandKeyMap)) DoCommandKey(); } if (thisGlider->mode == kGliderBurning) { if (thisGlider->facing == kFaceLeft) thisGlider->hDesiredVel -= kNormalThrust; else thisGlider->hDesiredVel += kNormalThrust; } else { thisGlider->heldLeft = false; thisGlider->heldRight = false; if (BitTst(&theKeys, thisGlider->rightKey)) // right key { #ifdef CREATEDEMODATA LogDemoKey(0); #endif if (BitTst(&theKeys, thisGlider->leftKey)) { ToggleGliderFacing(thisGlider); thisGlider->heldLeft = true; } else { thisGlider->hDesiredVel += kNormalThrust; thisGlider->tipped = (thisGlider->facing == kFaceLeft); thisGlider->heldRight = true; } } else if (BitTst(&theKeys, thisGlider->leftKey)) // left key { #ifdef CREATEDEMODATA LogDemoKey(1); #endif thisGlider->hDesiredVel -= kNormalThrust; thisGlider->tipped = (thisGlider->facing == kFaceRight); thisGlider->heldLeft = true; } else thisGlider->tipped = false; if ((BitTst(&theKeys, thisGlider->battKey)) && (batteryTotal != 0) && (thisGlider->mode == kGliderNormal)) { #ifdef CREATEDEMODATA LogDemoKey(2); #endif if (batteryTotal > 0) DoBatteryEngaged(thisGlider); else DoHeliumEngaged(thisGlider); } else batteryWasEngaged = false; if ((BitTst(&theKeys, thisGlider->bandKey)) && (bandsTotal > 0) && (thisGlider->mode == kGliderNormal)) { #ifdef CREATEDEMODATA LogDemoKey(3); #endif if (!thisGlider->fireHeld) { if (AddBand(thisGlider, thisGlider->dest.left + 24, thisGlider->dest.top + 10, thisGlider->facing)) { bandsTotal--; if (bandsTotal <= 0) QuickBandsRefresh(false); thisGlider->fireHeld = true; } } } else thisGlider->fireHeld = false; if ((otherPlayerEscaped != kNoOneEscaped) && (BitTst(&theKeys, kDeleteKeyMap)) && (thisGlider->which) && (!onePlayerLeft)) { ForceKillGlider(); } if ((isEscPauseKey && BitTst(&theKeys, kEscKeyMap)) || (!isEscPauseKey && BitTst(&theKeys, kTabKeyMap))) { DoPause(); } } } //-------------------------------------------------------------- QuerySaveGame Boolean QuerySaveGame (void) { #define kSaveGameAlert 1041 #define kYesSaveGameButton 1 short hitWhat; InitCursor(); FlushEvents(everyEvent, 0); // CenterAlert(kSaveGameAlert); hitWhat = Alert(kSaveGameAlert, nil); if (hitWhat == kYesSaveGameButton) return (true); else return (false); } \ No newline at end of file diff --git a/Sources/Interactions.c b/Sources/Interactions.c deleted file mode 100755 index a8f1a65..0000000 --- a/Sources/Interactions.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Interactions.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "RectUtils.h" #define kFloorVentLift -6 #define kCeilingVentDrop 8 #define kFanStrength 12 #define kBatterySupply 50 // about 2 rooms worth of thrust #define kHeliumSupply 150 #define kBandsSupply 8 #define kFoilSupply 8 Boolean GliderHitTop (gliderPtr, Rect *); Boolean GliderInRect (gliderPtr, Rect *); void BounceGlider (gliderPtr, Rect *); void CheckEscapeUpTwo (gliderPtr); void CheckEscapeUp (gliderPtr); void CheckEscapeDownTwo (gliderPtr); void CheckEscapeDown (gliderPtr); void CheckRoofCollision (gliderPtr); void CheckEscapeLeftTwo (gliderPtr); void CheckEscapeLeft (gliderPtr); void CheckEscapeRightTwo (gliderPtr); void CheckEscapeRight (gliderPtr); void CheckGliderInRoom (gliderPtr); void HandleRewards (gliderPtr, hotPtr); void HandleMicrowaveAction (hotPtr, gliderPtr); void HandleHotSpotCollision (gliderPtr, hotPtr, short); void CheckForHotSpots (void); void WebGlider (gliderPtr, Rect *); short otherPlayerEscaped, activeRectEscaped; extern hotPtr hotSpots; extern short nHotSpots, leftThresh, rightThresh, thisTiles[]; extern short localNumbers[], thisBackground, numStarsRemaining; extern Boolean leftOpen, rightOpen, topOpen, bottomOpen, evenFrame; extern Boolean twoPlayerGame, newState, onePlayerLeft, playerDead; //============================================================== Functions //-------------------------------------------------------------- GliderHitSides Boolean GliderHitTop (gliderPtr thisGlider, Rect *theRect) { Rect glideBounds; short offset; Boolean hitTop; glideBounds.left = thisGlider->dest.left + 5; glideBounds.top = thisGlider->dest.top + 5; glideBounds.right = thisGlider->dest.right - 5; glideBounds.bottom = thisGlider->dest.bottom - 5; glideBounds.left -= thisGlider->wasHVel; glideBounds.right -= thisGlider->wasHVel; if (theRect->bottom < glideBounds.top) hitTop = false; else if (theRect->top > glideBounds.bottom) hitTop = false; else if (theRect->right < glideBounds.left) hitTop = false; else if (theRect->left > glideBounds.right) hitTop = false; else hitTop = true; if (!hitTop) { PlayPrioritySound(kFoilHitSound, kFoilHitPriority); foilTotal--; if (foilTotal <= 0) StartGliderFoilLosing(thisGlider); glideBounds.left += thisGlider->wasHVel; glideBounds.right += thisGlider->wasHVel; if (thisGlider->hVel > 0) offset = 2 + glideBounds.right - theRect->left; else offset = 2 + glideBounds.left - theRect->right; thisGlider->hVel = -thisGlider->hVel - offset; } return (hitTop); } //-------------------------------------------------------------- SectGlider Boolean SectGlider (gliderPtr thisGlider, Rect *theRect, Boolean scrutinize) { Rect glideBounds; Boolean itHit; glideBounds = thisGlider->dest; if (thisGlider->mode == kGliderBurning) glideBounds.top += 6; if (scrutinize) { glideBounds.left += 5; glideBounds.top += 5; glideBounds.right -= 5; glideBounds.bottom -= 5; } if (theRect->bottom < glideBounds.top) itHit = false; else if (theRect->top > glideBounds.bottom) itHit = false; else if (theRect->right < glideBounds.left) itHit = false; else if (theRect->left > glideBounds.right) itHit = false; else itHit = true; return (itHit); } //-------------------------------------------------------------- GliderInRect Boolean GliderInRect (gliderPtr thisGlider, Rect *theRect) { Rect glideBounds; glideBounds = thisGlider->dest; if (glideBounds.top < theRect->top) return (false); else if (glideBounds.bottom > theRect->bottom) return (false); else if (glideBounds.left < theRect->left) return (false); else if (glideBounds.right > theRect->right) return (false); else return (true); } //-------------------------------------------------------------- BounceGlider void BounceGlider (gliderPtr thisGlider, Rect *theRect) { Rect glideBounds; glideBounds = thisGlider->dest; if ((theRect->right - glideBounds.left) < (glideBounds.right - theRect->left)) thisGlider->hVel = theRect->right - glideBounds.left; else thisGlider->hVel = theRect->left - glideBounds.right; if (foilTotal > 0) PlayPrioritySound(kFoilHitSound, kFoilHitPriority); else PlayPrioritySound(kHitWallSound, kHitWallPriority); } //-------------------------------------------------------------- CheckEscapeUpTwo void CheckEscapeUpTwo (gliderPtr thisGlider) { short offset, leftTile, rightTile; if (topOpen) { if (thisGlider->dest.top < kNoCeilingLimit) { if (otherPlayerEscaped == kNoOneEscaped) { otherPlayerEscaped = kPlayerEscapedUp; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } else if (otherPlayerEscaped == kPlayerEscapedUp) { otherPlayerEscaped = kNoOneEscaped; MoveRoomToRoom(thisGlider, kAbove); } else { PlayPrioritySound(kDontExitSound, kDontExitPriority); offset = kNoCeilingLimit - thisGlider->dest.top; thisGlider->vVel = -thisGlider->vVel + offset; } } } else if (thisBackground == kDirt) { leftTile = thisGlider->dest.left >> 6; // Ö 64 rightTile = thisGlider->dest.right >> 6; // Ö 64 if ((leftTile >= 0) && (leftTile < 8) && (rightTile >= 0) && (rightTile < 8)) { if (((thisTiles[leftTile] == 5) || (thisTiles[leftTile] == 6)) && ((thisTiles[rightTile] == 5) || (thisTiles[rightTile] == 6))) { if (thisGlider->dest.top < kNoCeilingLimit) { if (otherPlayerEscaped == kNoOneEscaped) { otherPlayerEscaped = kPlayerEscapedUp; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } else if (otherPlayerEscaped == kPlayerEscapedUp) { otherPlayerEscaped = kNoOneEscaped; MoveRoomToRoom(thisGlider, kAbove); } else { PlayPrioritySound(kDontExitSound, kDontExitPriority); offset = kNoCeilingLimit - thisGlider->dest.top; thisGlider->vVel = -thisGlider->vVel + offset; } } } else thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; } else thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; } else thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; } //-------------------------------------------------------------- CheckEscapeUp void CheckEscapeUp (gliderPtr thisGlider) { short leftTile, rightTile; if (topOpen) { if (thisGlider->dest.top < kNoCeilingLimit) { MoveRoomToRoom(thisGlider, kAbove); } } else if (thisBackground == kDirt) { leftTile = thisGlider->dest.left >> 6; // Ö 64 rightTile = thisGlider->dest.right >> 6; // Ö 64 if ((leftTile >= 0) && (leftTile < 8) && (rightTile >= 0) && (rightTile < 8)) { if (((thisTiles[leftTile] == 5) || (thisTiles[leftTile] == 6)) && ((thisTiles[rightTile] == 5) || (thisTiles[rightTile] == 6))) { if (thisGlider->dest.top < kNoCeilingLimit) MoveRoomToRoom(thisGlider, kAbove); } else thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; } else thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; } else thisGlider->vVel = kCeilingLimit - thisGlider->dest.top; } //-------------------------------------------------------------- CheckEscapeDownTwo void CheckEscapeDownTwo (gliderPtr thisGlider) { short offset, leftTile, rightTile; if (bottomOpen) { if (thisGlider->dest.bottom > kNoFloorLimit) { if (otherPlayerEscaped == kNoOneEscaped) { otherPlayerEscaped = kPlayerEscapedDown; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } else if (otherPlayerEscaped == kPlayerEscapedDown) { otherPlayerEscaped = kNoOneEscaped; MoveRoomToRoom(thisGlider, kBelow); } else { PlayPrioritySound(kDontExitSound, kDontExitPriority); offset = kNoFloorLimit - thisGlider->dest.bottom; thisGlider->vVel = -thisGlider->vVel + offset; } } } else if (thisBackground == kDirt) { leftTile = thisGlider->dest.left >> 6; // Ö 64 rightTile = thisGlider->dest.right >> 6; // Ö 64 if ((leftTile >= 0) && (leftTile < 8) && (rightTile >= 0) && (rightTile < 8)) { if (((thisTiles[leftTile] == 2) || (thisTiles[leftTile] == 3)) && ((thisTiles[rightTile] == 2) || (thisTiles[rightTile] == 3))) { if (thisGlider->dest.bottom > kNoFloorLimit) { if (otherPlayerEscaped == kNoOneEscaped) { otherPlayerEscaped = kPlayerEscapedDown; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } else if (otherPlayerEscaped == kPlayerEscapedDown) { otherPlayerEscaped = kNoOneEscaped; MoveRoomToRoom(thisGlider, kBelow); } else { PlayPrioritySound(kDontExitSound, kDontExitPriority); offset = kNoFloorLimit - thisGlider->dest.bottom; thisGlider->vVel = -thisGlider->vVel + offset; } } } else { if (thisGlider->ignoreGround) { if (thisGlider->dest.bottom > kNoFloorLimit) MoveRoomToRoom(thisGlider, kBelow); } else { thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } } } else { if (thisGlider->ignoreGround) { if (thisGlider->dest.bottom > kNoFloorLimit) MoveRoomToRoom(thisGlider, kBelow); } else { thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } } //-------------------------------------------------------------- CheckEscapeDown void CheckEscapeDown (gliderPtr thisGlider) { short leftTile, rightTile; if (bottomOpen) { if (thisGlider->dest.bottom > kNoFloorLimit) { MoveRoomToRoom(thisGlider, kBelow); } } else if (thisBackground == kDirt) { leftTile = thisGlider->dest.left >> 6; // Ö 64 rightTile = thisGlider->dest.right >> 6; // Ö 64 if ((leftTile >= 0) && (leftTile < 8) && (rightTile >= 0) && (rightTile < 8)) { if (((thisTiles[leftTile] == 2) || (thisTiles[leftTile] == 3)) && ((thisTiles[rightTile] == 2) || (thisTiles[rightTile] == 3))) { if (thisGlider->dest.bottom > kNoFloorLimit) MoveRoomToRoom(thisGlider, kBelow); } else { if (thisGlider->ignoreGround) { if (thisGlider->dest.bottom > kNoFloorLimit) MoveRoomToRoom(thisGlider, kBelow); } else { thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } } else { if (thisGlider->ignoreGround) { if (thisGlider->dest.bottom > kNoFloorLimit) MoveRoomToRoom(thisGlider, kBelow); } else { thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } } else { if (thisGlider->ignoreGround) { if (thisGlider->dest.bottom > kNoFloorLimit) MoveRoomToRoom(thisGlider, kBelow); } else { thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } } //-------------------------------------------------------------- CheckRoofCollision void CheckRoofCollision (gliderPtr thisGlider) { short offset, tileOver; offset = (thisGlider->dest.left + kHalfGliderWide) >> 6; // Ö 64 if ((offset >= 0) && (offset <= 7) && (!thisGlider->sliding)) { tileOver = thisTiles[offset]; if (tileOver == 1) { if (((thisGlider->dest.left + kHalfGliderWide) - (offset << 6)) > (250 - thisGlider->dest.bottom)) { thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } else if (tileOver == 2) { if (((thisGlider->dest.left + kHalfGliderWide) - (offset << 6)) > (186 - thisGlider->dest.bottom)) { thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } else if (tileOver == 5) { if ((64 - ((thisGlider->dest.left + kHalfGliderWide) - (offset << 6))) > (186 - thisGlider->dest.bottom)) { thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } else if (tileOver == 6) { if ((64 - ((thisGlider->dest.left + kHalfGliderWide) - (offset << 6))) > (250 - thisGlider->dest.bottom)) { thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } else { thisGlider->vVel = kFloorLimit - thisGlider->dest.bottom; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } } //-------------------------------------------------------------- CheckEscapeLeftTwo void CheckEscapeLeftTwo (gliderPtr thisGlider) { short offset; if (leftThresh == kLeftWallLimit) { if (thisGlider->ignoreLeft) { if (thisGlider->dest.left < kNoLeftWallLimit) { if (otherPlayerEscaped == kNoOneEscaped) { otherPlayerEscaped = kPlayerEscapedLeft; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } else if (otherPlayerEscaped == kPlayerEscapedLeft) { otherPlayerEscaped = kNoOneEscaped; MoveRoomToRoom(thisGlider, kToLeft); } else { PlayPrioritySound(kDontExitSound, kDontExitPriority); offset = kNoLeftWallLimit - thisGlider->dest.left; thisGlider->hVel = -thisGlider->hVel + offset; } } } else { if (foilTotal > 0) PlayPrioritySound(kFoilHitSound, kFoilHitPriority); else PlayPrioritySound(kHitWallSound, kHitWallPriority); offset = kLeftWallLimit - thisGlider->dest.left; thisGlider->hVel = -thisGlider->hVel + offset; } } else { if (otherPlayerEscaped == kNoOneEscaped) { otherPlayerEscaped = kPlayerEscapedLeft; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } else if (otherPlayerEscaped == kPlayerEscapedLeft) { otherPlayerEscaped = kNoOneEscaped; MoveRoomToRoom(thisGlider, kToLeft); } else { PlayPrioritySound(kDontExitSound, kDontExitPriority); offset = kNoLeftWallLimit - thisGlider->dest.left; thisGlider->hVel = -thisGlider->hVel + offset; } } } //-------------------------------------------------------------- CheckEscapeLeft void CheckEscapeLeft (gliderPtr thisGlider) { short offset; if (leftThresh == kLeftWallLimit) { if (thisGlider->ignoreLeft) { if (thisGlider->dest.left < kNoLeftWallLimit) MoveRoomToRoom(thisGlider, kToLeft); } else { if (foilTotal > 0) PlayPrioritySound(kFoilHitSound, kFoilHitPriority); else PlayPrioritySound(kHitWallSound, kHitWallPriority); offset = kLeftWallLimit - thisGlider->dest.left; thisGlider->hVel = -thisGlider->hVel + offset; } } else MoveRoomToRoom(thisGlider, kToLeft); } //-------------------------------------------------------------- CheckEscapeRightTwo void CheckEscapeRightTwo (gliderPtr thisGlider) { short offset; if (rightThresh == kRightWallLimit) { if (thisGlider->ignoreRight) { if (thisGlider->dest.right > kNoRightWallLimit) { if (otherPlayerEscaped == kNoOneEscaped) { otherPlayerEscaped = kPlayerEscapedRight; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } else if (otherPlayerEscaped == kPlayerEscapedRight) { otherPlayerEscaped = kNoOneEscaped; MoveRoomToRoom(thisGlider, kToRight); } else { PlayPrioritySound(kDontExitSound, kDontExitPriority); offset = kNoRightWallLimit - thisGlider->dest.right; thisGlider->hVel = -thisGlider->hVel + offset; } } } else { if (foilTotal > 0) PlayPrioritySound(kFoilHitSound, kFoilHitPriority); else PlayPrioritySound(kHitWallSound, kHitWallPriority); offset = kRightWallLimit - thisGlider->dest.right; thisGlider->hVel = -thisGlider->hVel + offset; } } else { if (otherPlayerEscaped == kNoOneEscaped) { otherPlayerEscaped = kPlayerEscapedRight; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } else if (otherPlayerEscaped == kPlayerEscapedRight) { otherPlayerEscaped = kNoOneEscaped; MoveRoomToRoom(thisGlider, kToRight); } else { PlayPrioritySound(kDontExitSound, kDontExitPriority); offset = kNoRightWallLimit - thisGlider->dest.right; thisGlider->hVel = -thisGlider->hVel + offset; } } } //-------------------------------------------------------------- CheckEscapeRight void CheckEscapeRight (gliderPtr thisGlider) { short offset; if (rightThresh == kRightWallLimit) { if (thisGlider->ignoreRight) { if (thisGlider->dest.right > kNoRightWallLimit) MoveRoomToRoom(thisGlider, kToRight); } else { if (foilTotal > 0) PlayPrioritySound(kFoilHitSound, kFoilHitPriority); else PlayPrioritySound(kHitWallSound, kHitWallPriority); offset = kRightWallLimit - thisGlider->dest.right; thisGlider->hVel = -thisGlider->hVel + offset; } } else MoveRoomToRoom(thisGlider, kToRight); } //-------------------------------------------------------------- CheckGliderInRoom void CheckGliderInRoom (gliderPtr thisGlider) { if ((thisGlider->mode == kGliderNormal) || (thisGlider->mode == kGliderFaceLeft) || (thisGlider->mode == kGliderFaceRight) || (thisGlider->mode == kGliderBurning)) { if (thisGlider->dest.top < kCeilingLimit) { if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if ((twoPlayerGame) && (!onePlayerLeft)) CheckEscapeUpTwo(thisGlider); else CheckEscapeUp(thisGlider); } else if (thisGlider->dest.bottom > kFloorLimit) { if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if ((twoPlayerGame) && (!onePlayerLeft)) CheckEscapeDownTwo(thisGlider); else CheckEscapeDown(thisGlider); } else if ((thisBackground == kRoof) && (thisGlider->dest.bottom > kRoofLimit)) CheckRoofCollision(thisGlider); if (thisGlider->dest.left < leftThresh) { if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if((twoPlayerGame) && (!onePlayerLeft)) CheckEscapeLeftTwo(thisGlider); else CheckEscapeLeft(thisGlider); } else if (thisGlider->dest.right > rightThresh) { if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if ((twoPlayerGame) && (!onePlayerLeft)) CheckEscapeRightTwo(thisGlider); else CheckEscapeRight(thisGlider); } } } //-------------------------------------------------------------- HandleRewards void HandleRewards (gliderPtr thisGlider, hotPtr who) { Rect bounds; short whoLinked, points; whoLinked = who->who; bounds = who->bounds; switch (masterObjects[whoLinked].theObject.what) { case kRedClock: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kBeepsSound, kBeepsPriority); RestoreFromSavedMap(thisRoomNumber, masterObjects[whoLinked].objectNum, false); AddFlyingPoint(&bounds, 100, thisGlider->hVel / 2, thisGlider->vVel / 2); thisGlider->hVel /= 4; thisGlider->vVel /= 4; theScore += kRedClockPoints; RedrawAllGrease(); } who->isOn = false; break; case kBlueClock: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kBuzzerSound, kBuzzerPriority); RestoreFromSavedMap(thisRoomNumber, masterObjects[whoLinked].objectNum, false); AddFlyingPoint(&bounds, 300, thisGlider->hVel / 2, thisGlider->vVel / 2); thisGlider->hVel /= 4; thisGlider->vVel /= 4; theScore += kBlueClockPoints; RedrawAllGrease(); } who->isOn = false; break; case kYellowClock: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kDingSound, kDingPriority); RestoreFromSavedMap(thisRoomNumber, masterObjects[whoLinked].objectNum, false); AddFlyingPoint(&bounds, 500, thisGlider->hVel / 2, thisGlider->vVel / 2); thisGlider->hVel /= 4; thisGlider->vVel /= 4; theScore += kYellowClockPoints; RedrawAllGrease(); } who->isOn = false; break; case kCuckoo: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kCuckooSound, kCuckooPriority); RestoreFromSavedMap(thisRoomNumber, masterObjects[whoLinked].objectNum, false); StopPendulum(thisRoomNumber, masterObjects[whoLinked].objectNum); AddFlyingPoint(&bounds, 1000, thisGlider->hVel / 2, thisGlider->vVel / 2); thisGlider->hVel /= 4; thisGlider->vVel /= 4; theScore += kCuckooClockPoints; RedrawAllGrease(); } who->isOn = false; break; case kPaper: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kEnergizeSound, kEnergizePriority); RestoreFromSavedMap(thisRoomNumber, masterObjects[whoLinked].objectNum, false); AddSparkle(&bounds); thisGlider->hVel /= 2; thisGlider->vVel /= 2; mortals++; if ((twoPlayerGame) && (!onePlayerLeft)) mortals++; QuickGlidersRefresh(); RedrawAllGrease(); } who->isOn = false; break; case kBattery: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kEnergizeSound, kEnergizePriority); RestoreFromSavedMap(thisRoomNumber, masterObjects[whoLinked].objectNum, false); AddSparkle(&bounds); thisGlider->hVel /= 2; thisGlider->vVel /= 2; if (batteryTotal > 0) // positive number means battery power batteryTotal += kBatterySupply; else // negative number means helium gas batteryTotal = kBatterySupply; if ((twoPlayerGame) && (!onePlayerLeft)) batteryTotal += kBatterySupply; QuickBatteryRefresh(false); RedrawAllGrease(); } who->isOn = false; break; case kBands: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kEnergizeSound, kEnergizePriority); RestoreFromSavedMap(thisRoomNumber, masterObjects[whoLinked].objectNum, false); AddSparkle(&bounds); thisGlider->hVel /= 2; thisGlider->vVel /= 2; bandsTotal += kBandsSupply; if ((twoPlayerGame) && (!onePlayerLeft)) bandsTotal += kBandsSupply; QuickBandsRefresh(false); RedrawAllGrease(); } who->isOn = false; break; case kGreaseRt: case kGreaseLf: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) SpillGrease(masterObjects[whoLinked].dynaNum, masterObjects[whoLinked].hotNum); who->isOn = false; break; case kFoil: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kEnergizeSound, kEnergizePriority); RestoreFromSavedMap(thisRoomNumber, masterObjects[whoLinked].objectNum, false); AddSparkle(&bounds); thisGlider->hVel /= 2; thisGlider->vVel /= 2; foilTotal += kFoilSupply; if ((twoPlayerGame) && (!onePlayerLeft)) foilTotal += kFoilSupply; StartGliderFoilGoing(thisGlider); RedrawAllGrease(); } who->isOn = false; break; case kInvisBonus: points = masterObjects[whoLinked].theObject.data.c.points; if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kBonusSound, kBonusPriority); AddFlyingPoint(&bounds, points, thisGlider->hVel / 2, thisGlider->vVel / 2); thisGlider->hVel /= 4; thisGlider->vVel /= 4; theScore += points; } who->isOn = false; break; case kStar: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kEnergizeSound, kEnergizePriority); RestoreFromSavedMap(thisRoomNumber, masterObjects[whoLinked].objectNum, false); AddSparkle(&bounds); StopStar(thisRoomNumber, masterObjects[whoLinked].objectNum); numStarsRemaining--; if (numStarsRemaining <= 0) FlagGameOver(); else DisplayStarsRemaining(); RedrawAllGrease(); theScore += kStarPoints; } who->isOn = false; break; case kSparkle: break; case kHelium: if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) { PlayPrioritySound(kEnergizeSound, kEnergizePriority); RestoreFromSavedMap(thisRoomNumber, masterObjects[whoLinked].objectNum, false); AddSparkle(&bounds); thisGlider->hVel /= 2; thisGlider->vVel /= 2; if (batteryTotal < 0) // if negative, it is already helium gas batteryTotal -= kHeliumSupply; else // if positive, it is battery power batteryTotal = -kHeliumSupply; if ((twoPlayerGame) && (!onePlayerLeft)) batteryTotal -= kHeliumSupply; QuickBatteryRefresh(false); RedrawAllGrease(); } who->isOn = false; break; case kSlider: break; } } //-------------------------------------------------------------- HandleSwitches void HandleSwitches (hotPtr who) { Rect newRect, bounds; short whoLinked, roomLinked, objectLinked, linkIndex; if (who->stillOver) return; whoLinked = who->who; // what is switch's obj. # roomLinked = masterObjects[whoLinked].roomLink; objectLinked = masterObjects[whoLinked].objectLink; linkIndex = masterObjects[whoLinked].localLink; // change state of linked obj. if (SetObjectState(roomLinked, objectLinked, masterObjects[whoLinked].theObject.data.e.type, linkIndex)) { newRect = who->bounds; QOffsetRect(&newRect, playOriginH, playOriginV); switch (masterObjects[whoLinked].theObject.what) { case kLightSwitch: PlayPrioritySound(kSwitchSound, kSwitchPriority); DrawLightSwitch(&newRect, newState); break; case kMachineSwitch: PlayPrioritySound(kSwitchSound, kSwitchPriority); DrawMachineSwitch(&newRect, newState); break; case kThermostat: PlayPrioritySound(kSwitchSound, kSwitchPriority); DrawThermostat(&newRect, newState); break; case kPowerSwitch: PlayPrioritySound(kSwitchSound, kSwitchPriority); DrawPowerSwitch(&newRect, newState); break; case kKnifeSwitch: PlayPrioritySound(kSwitchSound, kSwitchPriority); DrawKnifeSwitch(&newRect, newState); break; case kInvisSwitch: break; } CopyRectBackToWork(&newRect); AddRectToWorkRects(&newRect); if (linkIndex != -1) { switch (masterObjects[linkIndex].theObject.what) { case kRedClock: case kBlueClock: case kYellowClock: case kPaper: case kBattery: case kBands: case kFoil: case kStar: case kHelium: RestoreFromSavedMap(roomLinked, objectLinked, true); AddSparkle(&bounds); break; case kCuckoo: RestoreFromSavedMap(roomLinked, objectLinked, true); StopPendulum(roomLinked, objectLinked); break; case kGreaseRt: case kGreaseLf: SpillGrease(masterObjects[linkIndex].dynaNum, masterObjects[linkIndex].hotNum); break; case kInvisBonus: case kSlider: break; case kDeluxeTrans: break; case kSoundTrigger: PlayPrioritySound(kTriggerSound, kTriggerPriority); break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: RedrawRoomLighting(); break; case kShredder: break; case kToaster: ToggleToaster(masterObjects[linkIndex].dynaNum); break; case kMacPlus: ToggleMacPlus(masterObjects[linkIndex].dynaNum); break; case kGuitar: PlayPrioritySound(kChordSound, kChordPriority); break; case kTV: ToggleTV(masterObjects[linkIndex].dynaNum); break; case kCoffee: ToggleCoffee(masterObjects[linkIndex].dynaNum); break; case kOutlet: ToggleOutlet(masterObjects[linkIndex].dynaNum); break; case kVCR: ToggleVCR(masterObjects[linkIndex].dynaNum); break; case kStereo: ToggleStereos(masterObjects[linkIndex].dynaNum); break; case kMicrowave: ToggleMicrowave(masterObjects[linkIndex].dynaNum); break; case kBalloon: ToggleBalloon(masterObjects[linkIndex].dynaNum); break; case kCopterLf: case kCopterRt: ToggleCopter(masterObjects[linkIndex].dynaNum); break; case kDartLf: case kDartRt: ToggleDart(masterObjects[linkIndex].dynaNum); break; case kBall: ToggleBall(masterObjects[linkIndex].dynaNum); break; case kDrip: ToggleDrip(masterObjects[linkIndex].dynaNum); break; case kFish: ToggleFish(masterObjects[linkIndex].dynaNum); break; } } } who->stillOver = true; } //-------------------------------------------------------------- HandleMicrowaveAction void HandleMicrowaveAction (hotPtr who, gliderPtr thisGlider) { short whoLinked, kills; Boolean killed; if (who->stillOver) return; killed = false; whoLinked = who->who; // what is microwave's obj. # if (masterObjects[whoLinked].theObject.data.g.state) { kills = (short)masterObjects[whoLinked].theObject.data.g.byte0; if (((kills & 0x0001) == 0x0001) && (bandsTotal > 0)) { bandsTotal = 0; killed = true; QuickBandsRefresh(false); } if (((kills & 0x0002) == 0x0002) && (batteryTotal != 0)) { batteryTotal = 0; killed = true; QuickBatteryRefresh(false); } if (((kills & 0x0004) == 0x0004) && (foilTotal > 0)) { foilTotal = 0; killed = true; StartGliderFoilLosing(thisGlider); } } if (killed) PlayPrioritySound(kMicrowavedSound, kMicrowavedPriority); } //-------------------------------------------------------------- HandleHotSpotCollision void HandleHotSpotCollision (gliderPtr thisGlider, hotPtr who, short index) { switch (who->action) { case kLiftIt: thisGlider->vDesiredVel = kFloorVentLift; break; case kDropIt: thisGlider->vDesiredVel = kCeilingVentDrop; break; case kPushItLeft: thisGlider->hDesiredVel += -kFanStrength; break; case kPushItRight: thisGlider->hDesiredVel += kFanStrength; break; case kDissolveIt: if (thisGlider->mode != kGliderFadingOut) { if ((foilTotal > 0) || (thisGlider->mode == kGliderLosingFoil)) { if (GliderHitTop(thisGlider, &(who->bounds))) { StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else { if (foilTotal > 0) { foilTotal--; if (foilTotal <= 0) StartGliderFoilLosing(thisGlider); } } } else { StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } break; case kRewardIt: HandleRewards(thisGlider, who); break; case kMoveItUp: if (!thisGlider->heldRight && GliderInRect(thisGlider, &who->bounds)) { if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if ((twoPlayerGame) && (!onePlayerLeft)) { if (otherPlayerEscaped == kNoOneEscaped) { if ((thisGlider->mode != kGliderGoingUp) && (thisGlider->mode != kGliderInLimbo)) { otherPlayerEscaped = kPlayerEscapingUpStairs; RefreshScoreboard(kEscapedTitleMode); StartGliderGoingUpStairs(thisGlider); } } else if (otherPlayerEscaped == kPlayerEscapedUpStairs) { if ((thisGlider->mode != kGliderGoingUp) && (thisGlider->mode != kGliderInLimbo)) { StartGliderGoingUpStairs(thisGlider); } } } else StartGliderGoingUpStairs(thisGlider); } break; case kMoveItDown: if (!thisGlider->heldLeft && GliderInRect(thisGlider, &who->bounds)) { if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if ((twoPlayerGame) && (!onePlayerLeft)) { if (otherPlayerEscaped == kNoOneEscaped) { if ((thisGlider->mode != kGliderGoingDown) && (thisGlider->mode != kGliderInLimbo)) { otherPlayerEscaped = kPlayerEscapingDownStairs; RefreshScoreboard(kEscapedTitleMode); StartGliderGoingDownStairs(thisGlider); } } else if (otherPlayerEscaped == kPlayerEscapedDownStairs) { if ((thisGlider->mode != kGliderGoingDown) && (thisGlider->mode != kGliderInLimbo)) { StartGliderGoingDownStairs(thisGlider); } } } else StartGliderGoingDownStairs(thisGlider); } break; case kSwitchIt: HandleSwitches(who); break; case kShredIt: if ((thisGlider->mode != kGliderShredding) && (GliderInRect(thisGlider, &who->bounds))) { if ((foilTotal > 0) || (thisGlider->mode == kGliderLosingFoil)) { PlayPrioritySound(kFoilHitSound, kFoilHitPriority); if (foilTotal > 0) { foilTotal--; if (foilTotal <= 0) StartGliderFoilLosing(thisGlider); } } else FlagGliderShredding(thisGlider, &who->bounds); } break; case kStrumIt: if (!who->stillOver) { PlayPrioritySound(kChordSound, kChordPriority); who->stillOver = true; } break; case kTriggerIt: case kLgTrigger: ArmTrigger(who); break; case kBurnIt: if ((thisGlider->mode != kGliderBurning) && (thisGlider->mode != kGliderFadingOut)) { if ((foilTotal > 0) || (thisGlider->mode == kGliderLosingFoil)) { thisGlider->vDesiredVel = kFloorVentLift; if (foilTotal > 0) { PlayPrioritySound(kSizzleSound, kSizzlePriority); foilTotal--; if (foilTotal <= 0) StartGliderFoilLosing(thisGlider); } } else FlagGliderBurning(thisGlider); } break; case kSlideIt: thisGlider->sliding = true; thisGlider->vVel = who->bounds.top - thisGlider->dest.bottom; break; case kTransportIt: if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if ((GliderInRect(thisGlider, &who->bounds)) && (thisGlider->mode != kGliderTransporting) && (thisGlider->mode != kGliderFadingOut)) { if ((twoPlayerGame) && (!onePlayerLeft)) { if (otherPlayerEscaped == kNoOneEscaped) { if (thisGlider->mode != kGliderInLimbo) { activeRectEscaped = index; StartGliderTransporting(thisGlider, who); } } else if (otherPlayerEscaped == kPlayerTransportedOut) { if ((thisGlider->mode != kGliderInLimbo) && (activeRectEscaped == index)) { StartGliderTransporting(thisGlider, who); } } } else StartGliderTransporting(thisGlider, who); } break; case kIgnoreLeftWall: thisGlider->ignoreLeft = true; break; case kIgnoreRightWall: thisGlider->ignoreRight = true; break; case kMailItLeft: // mailbox open to right if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if ((GliderInRect(thisGlider, &who->bounds)) && (thisGlider->mode != kGliderMailOutRight) && (thisGlider->mode != kGliderMailInLeft) && (thisGlider->mode != kGliderFadingOut) && (((thisGlider->facing == kFaceRight) && (!thisGlider->tipped)) || ((thisGlider->facing == kFaceLeft) && (thisGlider->tipped)))) { if ((twoPlayerGame) && (!onePlayerLeft)) // two gliders to handle { if (otherPlayerEscaped == kNoOneEscaped) // other glider in room { if (thisGlider->mode != kGliderInLimbo) // this glider is active { activeRectEscaped = index; StartGliderMailingIn(thisGlider, &who->bounds, who); thisGlider->mode = kGliderMailInLeft; } } else if (otherPlayerEscaped == kPlayerMailedOut) { // other glider left here if ((thisGlider->mode != kGliderInLimbo) && (activeRectEscaped == index)) { // []_ <--G StartGliderMailingIn(thisGlider, &who->bounds, who); thisGlider->mode = kGliderMailInLeft; } } } else // only 1 glider in game { StartGliderMailingIn(thisGlider, &who->bounds, who); thisGlider->mode = kGliderMailInLeft; } } break; case kMailItRight: // mailbox open to left if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if ((GliderInRect(thisGlider, &who->bounds)) && (thisGlider->mode != kGliderMailOutLeft) && (thisGlider->mode != kGliderMailInRight) && (thisGlider->mode != kGliderFadingOut) && (((thisGlider->facing == kFaceRight) && (thisGlider->tipped)) || ((thisGlider->facing == kFaceLeft) && (!thisGlider->tipped)))) { if ((twoPlayerGame) && (!onePlayerLeft)) { if (otherPlayerEscaped == kNoOneEscaped) { if (thisGlider->mode != kGliderInLimbo) { activeRectEscaped = index; StartGliderMailingIn(thisGlider, &who->bounds, who); thisGlider->mode = kGliderMailInRight; } } else if (otherPlayerEscaped == kPlayerMailedOut) { if ((thisGlider->mode != kGliderInLimbo) && (activeRectEscaped == index)) { StartGliderMailingIn(thisGlider, &who->bounds, who); thisGlider->mode = kGliderMailInRight; } } } else { StartGliderMailingIn(thisGlider, &who->bounds, who); thisGlider->mode = kGliderMailInRight; } } break; case kDuctItDown: if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if ((GliderInRect(thisGlider, &who->bounds)) && (thisGlider->mode != kGliderDuctingDown) && (thisGlider->mode != kGliderFadingOut)) { if ((twoPlayerGame) && (!onePlayerLeft)) { if (otherPlayerEscaped == kNoOneEscaped) { if (thisGlider->mode != kGliderInLimbo) { activeRectEscaped = index; StartGliderDuctingDown(thisGlider, &who->bounds, who); } } else if (otherPlayerEscaped == kPlayerDuckedOut) { if ((thisGlider->mode != kGliderInLimbo) && (activeRectEscaped == index)) StartGliderDuctingDown(thisGlider, &who->bounds, who); } } else StartGliderDuctingDown(thisGlider, &who->bounds, who); } break; case kDuctItUp: if (thisGlider->mode == kGliderBurning) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } else if ((GliderInRect(thisGlider, &who->bounds)) && (thisGlider->mode != kGliderDuctingUp) && (thisGlider->mode != kGliderDuctingIn) && (thisGlider->mode != kGliderFadingOut) && (!who->stillOver)) { if ((twoPlayerGame) && (!onePlayerLeft)) { if (otherPlayerEscaped == kNoOneEscaped) { if (thisGlider->mode != kGliderInLimbo) { activeRectEscaped = index; StartGliderDuctingUp(thisGlider, &who->bounds, who); } } else if (otherPlayerEscaped == kPlayerDuckedOut) { if ((thisGlider->mode != kGliderInLimbo) && (activeRectEscaped == index)) StartGliderDuctingUp(thisGlider, &who->bounds, who); } } else { StartGliderDuctingUp(thisGlider, &who->bounds, who); who->stillOver = true; } } break; case kMicrowaveIt: if (GliderInRect(thisGlider, &who->bounds)) HandleMicrowaveAction(who, thisGlider); break; case kIgnoreGround: thisGlider->ignoreGround = true; break; case kBounceIt: BounceGlider(thisGlider, &who->bounds); break; case kChimeIt: if (!who->stillOver) { StrikeChime(); who->stillOver = true; } break; case kWebIt: if ((GliderInRect(thisGlider, &who->bounds)) && (thisGlider->mode != kGliderBurning)) WebGlider(thisGlider, &who->bounds); else if ((thisGlider->mode == kGliderBurning) && (GliderInRect(thisGlider, &who->bounds))) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } break; case kSoundIt: if (!who->stillOver) { PlayPrioritySound(kTriggerSound, kTriggerPriority); who->stillOver = true; } break; } } //-------------------------------------------------------------- CheckForHotSpots void CheckForHotSpots (void) { short i; Boolean hitObject; for (i = 0; i < nHotSpots; i++) { if (hotSpots[i].isOn) { if (twoPlayerGame) { hitObject = false; if (SectGlider(&theGlider, &hotSpots[i].bounds, hotSpots[i].doScrutinize)) { if (onePlayerLeft) { if (playerDead == kPlayer2) { HandleHotSpotCollision(&theGlider, &hotSpots[i], i); hitObject = true; } } else { HandleHotSpotCollision(&theGlider, &hotSpots[i], i); hitObject = true; } } if (SectGlider(&theGlider2, &hotSpots[i].bounds, hotSpots[i].doScrutinize)) { if (onePlayerLeft) { if (playerDead == kPlayer1) { HandleHotSpotCollision(&theGlider2, &hotSpots[i], i); hitObject = true; } } else { HandleHotSpotCollision(&theGlider2, &hotSpots[i], i); hitObject = true; } } if (!hitObject) hotSpots[i].stillOver = false; } else { if (SectGlider(&theGlider, &hotSpots[i].bounds, hotSpots[i].doScrutinize)) HandleHotSpotCollision(&theGlider, &hotSpots[i], i); else hotSpots[i].stillOver = false; } } } } //-------------------------------------------------------------- HandleInteraction void HandleInteraction (void) { CheckForHotSpots(); if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == kPlayer1) CheckGliderInRoom(&theGlider2); else CheckGliderInRoom(&theGlider); } else { CheckGliderInRoom(&theGlider); CheckGliderInRoom(&theGlider2); } } else CheckGliderInRoom(&theGlider); } //-------------------------------------------------------------- FlagStillOvers void FlagStillOvers (gliderPtr thisGlider) { short i; for (i = 0; i < nHotSpots; i++) { if (hotSpots[i].isOn) { if (SectGlider(thisGlider, &hotSpots[i].bounds, hotSpots[i].doScrutinize)) hotSpots[i].stillOver = true; else hotSpots[i].stillOver = false; } else hotSpots[i].stillOver = false; } } //-------------------------------------------------------------- WebGlider void WebGlider (gliderPtr thisGlider, Rect *webBounds) { #define kKillWebbedGlider 150 short hDist, vDist; if ((thisGlider->mode == kGliderBurning) && (GliderInRect(thisGlider, webBounds))) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); return; } hDist = ((webBounds->right - thisGlider->dest.right) + (webBounds->left - thisGlider->dest.left)) >> 3; vDist = ((webBounds->bottom - thisGlider->dest.bottom) + (webBounds->top - thisGlider->dest.top)) >> 3; if (thisGlider->hDesiredVel != 0) { if (evenFrame) { thisGlider->hVel = hDist; thisGlider->vVel = vDist; PlayPrioritySound(kWebTwangSound, kWebTwangPriority); } } else { thisGlider->hDesiredVel = 0; thisGlider->vDesiredVel = 0; } thisGlider->wasMode++; if (thisGlider->wasMode >= kKillWebbedGlider) { thisGlider->wasMode = 0; StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } } \ No newline at end of file diff --git a/Sources/InterfaceInit.c b/Sources/InterfaceInit.c deleted file mode 100755 index 13bd6bf..0000000 --- a/Sources/InterfaceInit.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // InterfaceInit.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" #include "Map.h" #include "RectUtils.h" #include "Tools.h" #define kHandCursorID 128 #define kVertCursorID 129 #define kHoriCursorID 130 #define kDiagCursorID 131 extern RgnHandle mirrorRgn; extern WindowPtr mapWindow, toolsWindow, linkWindow; extern WindowPtr menuWindow; extern Rect shieldRect, boardSrcRect, localRoomsDest[]; extern CursHandle handCursorH, beamCursorH, vertCursorH, horiCursorH; extern CursHandle diagCursorH; extern Cursor handCursor, beamCursor, vertCursor, horiCursor; extern Cursor diagCursor; extern MenuHandle appleMenu, gameMenu, optionsMenu, houseMenu; extern Point shieldPt; extern long incrementModeTime; extern UInt32 doubleTime; extern short fadeInSequence[], idleMode; extern short toolSelected, lastBackground, wasFlower, numExtraHouses; extern short houseResFork, lastHighScore, maxFiles, willMaxFiles; extern Boolean quitting, playing, fadeGraysOut; extern Boolean houseOpen, newRoomNow, evenFrame, menusUp, demoGoing; extern Boolean twoPlayerGame, paused, hasMirror, splashDrawn; //============================================================== Functions //-------------------------------------------------------------- InitializeMenus // The menus are loaded from disk and the menu bar set up and drawn. void InitializeMenus (void) { appleMenu = GetMenu(kAppleMenuID); if (appleMenu == nil) RedAlert(kErrFailedResourceLoad); AppendResMenu(appleMenu, 'DRVR'); InsertMenu(appleMenu, 0); gameMenu = GetMenu(kGameMenuID); if (gameMenu == nil) RedAlert(kErrFailedResourceLoad); InsertMenu(gameMenu, 0); optionsMenu = GetMenu(kOptionsMenuID); if (optionsMenu == nil) RedAlert(kErrFailedResourceLoad); InsertMenu(optionsMenu, 0); menusUp = true; DrawMenuBar(); houseMenu = GetMenu(kHouseMenuID); if (houseMenu == nil) RedAlert(kErrFailedResourceLoad); UpdateMenus(false); } //-------------------------------------------------------------- GetExtraCursors // Extra cursors (custom cursors) like the "hand" and various roomÉ // editing cursors are loaded up. void GetExtraCursors (void) { handCursorH = GetCursor(kHandCursorID); if (handCursorH == nil) RedAlert(kErrFailedResourceLoad); HLock((Handle)handCursorH); handCursor = **handCursorH; beamCursorH = GetCursor(iBeamCursor); if (beamCursorH == nil) RedAlert(kErrFailedResourceLoad); HLock((Handle)beamCursorH); beamCursor = **beamCursorH; vertCursorH = GetCursor(kVertCursorID); if (vertCursorH == nil) RedAlert(kErrFailedResourceLoad); HLock((Handle)vertCursorH); vertCursor = **vertCursorH; horiCursorH = GetCursor(kHoriCursorID); if (horiCursorH == nil) RedAlert(kErrFailedResourceLoad); HLock((Handle)horiCursorH); horiCursor = **horiCursorH; diagCursorH = GetCursor(kDiagCursorID); if (diagCursorH == nil) RedAlert(kErrFailedResourceLoad); HLock((Handle)diagCursorH); diagCursor = **diagCursorH; } //-------------------------------------------------------------- VariableInit // All the simple interface variables are intialized here - Booleans,É // shorts, a few Rects, etc. void VariableInit (void) { short i; shieldPt.h = 0; shieldPt.v = 0; shieldRect = thisMac.screen; menusUp = false; quitting = false; houseOpen = false; newRoomNow = false; playing = false; evenFrame = false; if (thisMac.isDepth == 8) fadeGraysOut = true; else fadeGraysOut = false; twoPlayerGame = false; paused = false; hasMirror = false; demoGoing = false; // scrapIsARoom = true; splashDrawn = false; #ifndef COMPILEDEMO // SeeIfValidScrapAvailable(false); #endif theGlider.which = kPlayer1; theGlider2.leftKey = kControlKeyMap; theGlider2.rightKey = kCommandKeyMap; theGlider2.battKey = kOptionKeyMap; theGlider2.bandKey = kShiftKeyMap; theGlider2.which = kPlayer2; theMode = kSplashMode; thisRoomNumber = 0; previousRoom = -1; toolSelected = kSelectTool; houseResFork = -1; lastBackground = kBaseBackgroundID; wasFlower = RandomInt(kNumFlowers); lastHighScore = -1; idleMode = kIdleSplashMode; incrementModeTime = TickCount() + kIdleSplashTicks; willMaxFiles = maxFiles; numExtraHouses = 0; fadeInSequence[0] = 4; // 4 fadeInSequence[1] = 5; fadeInSequence[2] = 6; fadeInSequence[3] = 7; fadeInSequence[4] = 5; // 5 fadeInSequence[5] = 6; fadeInSequence[6] = 7; fadeInSequence[7] = 8; fadeInSequence[8] = 6; // 6 fadeInSequence[9] = 7; fadeInSequence[10] = 8; fadeInSequence[11] = 9; fadeInSequence[12] = 7; // 7 fadeInSequence[13] = 8; fadeInSequence[14] = 9; fadeInSequence[15] = 10; doubleTime = GetDblTime(); mirrorRgn = nil; mainWindow = nil; mapWindow = nil; toolsWindow = nil; linkWindow = nil; coordWindow = nil; toolSrcMap = nil; nailSrcMap = nil; menuWindow = nil; houseRect = thisMac.screen; houseRect.bottom -= kScoreboardTall; if (houseRect.right > kMaxViewWidth) houseRect.right = kMaxViewWidth; if (houseRect.bottom > kMaxViewHeight) houseRect.bottom = kMaxViewHeight; playOriginH = (RectWide(&thisMac.screen) - kRoomWide) / 2; playOriginV = (RectTall(&thisMac.screen) - kTileHigh) / 2; for (i = 0; i < 9; i++) { QSetRect(&localRoomsDest[i], 0, 0, kRoomWide, kTileHigh); QOffsetRect(&localRoomsDest[i], playOriginH, playOriginV); } QOffsetRect(&localRoomsDest[kNorthRoom], 0, -kVertLocalOffset); QOffsetRect(&localRoomsDest[kNorthEastRoom], kRoomWide, -kVertLocalOffset); QOffsetRect(&localRoomsDest[kEastRoom], kRoomWide, 0); QOffsetRect(&localRoomsDest[kSouthEastRoom], kRoomWide, kVertLocalOffset); QOffsetRect(&localRoomsDest[kSouthRoom], 0, kVertLocalOffset); QOffsetRect(&localRoomsDest[kSouthWestRoom], -kRoomWide, kVertLocalOffset); QOffsetRect(&localRoomsDest[kWestRoom], -kRoomWide, 0); QOffsetRect(&localRoomsDest[kNorthWestRoom], -kRoomWide, -kVertLocalOffset); } \ No newline at end of file diff --git a/Sources/Link.c b/Sources/Link.c deleted file mode 100755 index de0d209..0000000 --- a/Sources/Link.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Link.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" #include "ObjectEdit.h" #include "RectUtils.h" #define kLinkControlID 130 #define kUnlinkControlID 131 void DoLink (void); void DoUnlink (void); Rect linkWindowRect; ControlHandle linkControl, unlinkControl; WindowPtr linkWindow; short isLinkH, isLinkV, linkRoom, linkType; Byte linkObject; Boolean isLinkOpen, linkerIsSwitch; //============================================================== Functions //-------------------------------------------------------------- MergeFloorSuite short MergeFloorSuite (short floor, short suite) { return ((suite * 100) + floor); } //-------------------------------------------------------------- ExtractFloorSuite void ExtractFloorSuite (short combo, short *floor, short *suite) { if ((*thisHouse)->version < 0x0200) // old floor/suite combo { *floor = (combo / 100) - kNumUndergroundFloors; *suite = combo % 100; } else { *suite = combo / 100; *floor = (combo % 100) - kNumUndergroundFloors; } } //-------------------------------------------------------------- UpdateLinkControl void UpdateLinkControl (void) { #ifndef COMPILEDEMO if (linkWindow == nil) return; switch (linkType) { case kSwitchLinkOnly: if (objActive == kNoObjectSelected) HiliteControl(linkControl, kControlInactive); else switch (thisRoom->objects[objActive].what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kLeftFan: case kRightFan: case kInvisBlower: case kGrecoVent: case kSewerBlower: case kLiftArea: case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kFoil: case kInvisBonus: case kHelium: case kDeluxeTrans: case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: case kShredder: case kToaster: case kMacPlus: case kTV: case kCoffee: case kOutlet: case kVCR: case kStereo: case kMicrowave: case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kBall: case kDrip: case kFish: HiliteControl(linkControl, kControlActive); break; default: HiliteControl(linkControl, kControlInactive); break; } break; case kTriggerLinkOnly: if (objActive == kNoObjectSelected) HiliteControl(linkControl, kControlInactive); else switch (thisRoom->objects[objActive].what) { case kGreaseRt: case kGreaseLf: case kToaster: case kGuitar: case kCoffee: case kOutlet: case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kDrip: case kFish: HiliteControl(linkControl, kControlActive); break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: if (linkRoom == thisRoomNumber) HiliteControl(linkControl, kControlActive); break; default: HiliteControl(linkControl, kControlInactive); break; } break; case kTransportLinkOnly: if (objActive == kNoObjectSelected) HiliteControl(linkControl, kControlInactive); else switch (thisRoom->objects[objActive].what) { case kMailboxLf: case kMailboxRt: case kCeilingTrans: case kInvisTrans: case kDeluxeTrans: case kInvisLight: case kOzma: case kMirror: case kFireplace: case kWallWindow: case kCalendar: case kBulletin: case kCloud: HiliteControl(linkControl, kControlActive); break; default: HiliteControl(linkControl, kControlInactive); break; } break; } #endif } //-------------------------------------------------------------- UpdateLinkWindow void UpdateLinkWindow (void) { #ifndef COMPILEDEMO if (linkWindow == nil) return; SetPortWindowPort(linkWindow); DrawControls(linkWindow); UpdateLinkControl(); #endif } //-------------------------------------------------------------- OpenLinkWindow void OpenLinkWindow (void) { #ifndef COMPILEDEMO Rect src, dest; Point globalMouse; if (linkWindow == nil) { QSetRect(&linkWindowRect, 0, 0, 129, 30); if (thisMac.hasColor) linkWindow = NewCWindow(nil, &linkWindowRect, "\pLink", false, kWindoidWDEF, kPutInFront, true, 0L); else linkWindow = NewWindow(nil, &linkWindowRect, "\pLink", false, kWindoidWDEF, kPutInFront, true, 0L); MoveWindow(linkWindow, isLinkH, isLinkV, true); globalMouse = MyGetGlobalMouse(); QSetRect(&src, 0, 0, 1, 1); QOffsetRect(&src, globalMouse.h, globalMouse.v); GetWindowRect(linkWindow, &dest); BringToFront(linkWindow); ShowHide(linkWindow, true); // FlagWindowFloating(linkWindow); TEMP - use flaoting windows HiliteAllWindows(); linkControl = GetNewControl(kLinkControlID, linkWindow); if (linkControl == nil) RedAlert(kErrFailedResourceLoad); unlinkControl = GetNewControl(kUnlinkControlID, linkWindow); if (unlinkControl == nil) RedAlert(kErrFailedResourceLoad); linkRoom = -1; linkObject = 255; isLinkOpen = true; } #endif } //-------------------------------------------------------------- CloseLinkWindow void CloseLinkWindow (void) { #ifndef COMPILEDEMO if (linkWindow != nil) DisposeWindow(linkWindow); linkWindow = nil; isLinkOpen = false; #endif } //-------------------------------------------------------------- DoLink #ifndef COMPILEDEMO void DoLink (void) { short floor, suite; char wasState; if (GetRoomFloorSuite(thisRoomNumber, &floor, &suite)) { floor += kNumUndergroundFloors; if (thisRoomNumber == linkRoom) { if (linkerIsSwitch) { thisRoom->objects[linkObject].data.e.where = MergeFloorSuite(floor, suite); thisRoom->objects[linkObject].data.e.who = objActive; } else { thisRoom->objects[linkObject].data.d.where = MergeFloorSuite(floor, suite); thisRoom->objects[linkObject].data.d.who = objActive; } } else { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); if (linkerIsSwitch) { (*thisHouse)->rooms[linkRoom].objects[linkObject].data.e.where = MergeFloorSuite(floor, suite); (*thisHouse)->rooms[linkRoom].objects[linkObject].data.e.who = objActive; } else // linker is transport { (*thisHouse)->rooms[linkRoom].objects[linkObject].data.d.where = MergeFloorSuite(floor, suite); (*thisHouse)->rooms[linkRoom].objects[linkObject].data.d.who = objActive; } HSetState((Handle)thisHouse, wasState); } fileDirty = true; UpdateMenus(false); CloseLinkWindow(); } } #endif //-------------------------------------------------------------- DoUnlink #ifndef COMPILEDEMO void DoUnlink (void) { char wasState; if (thisRoomNumber == linkRoom) { if (linkerIsSwitch) { thisRoom->objects[linkObject].data.e.where = -1; thisRoom->objects[linkObject].data.e.who = 255; } else { thisRoom->objects[linkObject].data.d.where = -1; thisRoom->objects[linkObject].data.d.who = 255; } } else { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); if (linkerIsSwitch) { (*thisHouse)->rooms[linkRoom].objects[linkObject].data.e.where = -1; (*thisHouse)->rooms[linkRoom].objects[linkObject].data.e.who = 255; } else { (*thisHouse)->rooms[linkRoom].objects[linkObject].data.d.where = -1; (*thisHouse)->rooms[linkRoom].objects[linkObject].data.d.who = 255; } HSetState((Handle)thisHouse, wasState); } fileDirty = true; UpdateMenus(false); CloseLinkWindow(); } #endif //-------------------------------------------------------------- HandleLinkClick void HandleLinkClick (Point wherePt) { #ifndef COMPILEDEMO ControlHandle theControl; short part; if (linkWindow == nil) return; SetPortWindowPort(linkWindow); GlobalToLocal(&wherePt); part = FindControl(wherePt, linkWindow, &theControl); if ((theControl != nil) && (part != 0)) { part = TrackControl(theControl, wherePt, nil); if (part != 0) { if (theControl == linkControl) DoLink(); else if (theControl == unlinkControl) DoUnlink(); if (thisRoomNumber == linkRoom) CopyThisRoomToRoom(); GenerateRetroLinks(); } } #endif } \ No newline at end of file diff --git a/Sources/Main.c b/Sources/Main.c deleted file mode 100755 index c41f189..0000000 --- a/Sources/Main.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Glider PRO 1.0.4 // by john calhoun //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Externs.h" #include "Environ.h" #include "House.h" #define kPrefsVersion 0x0034 void ReadInPrefs (void); void WriteOutPrefs (void); void main (void); short isVolume, wasVolume; short isDepthPref, dataResFile, numSMWarnings; Boolean quitting, doZooms, quickerTransitions, isUseSecondScreen; extern Str31 highBanner; extern Str15 leftName, rightName, batteryName, bandName; extern Str15 highName; //extern long encryptedNumber; extern short maxFiles, numNeighbors, houseRefNum, willMaxFiles; extern short isEditH, isEditV, isMapH, isMapV; extern short isToolsH, isToolsV, isCoordH, isCoordV; extern short isLinkH, isLinkV, toolMode, mapLeftRoom, mapTopRoom; extern short mapRoomsWide, mapRoomsHigh, wasFloor, wasSuite; extern Boolean isMusicOn, isSoundOn, isPlayMusicIdle, isHouseChecks; extern Boolean houseOpen, isDoColorFade, isEscPauseKey; extern Boolean autoRoomEdit, doAutoDemo, doBackground; extern Boolean isMapOpen, isToolsOpen, isCoordOpen; extern Boolean doPrettyMap, doBitchDialogs; //extern Boolean didValidation; //============================================================== Functions //-------------------------------------------------------------- ReadInPrefs // Called only once when game launches - reads in the preferences savedÉ // from the last time Glider PRO was launched. If no prefs are found,É // it assigns default settings. void ReadInPrefs (void) { prefsInfo thePrefs; if (LoadPrefs(&thePrefs, kPrefsVersion)) { #ifdef COMPILEDEMO PasStringCopy("\pDemo House", thisHouseName); #else PasStringCopy(thePrefs.wasDefaultName, thisHouseName); #endif PasStringCopy(thePrefs.wasLeftName, leftName); PasStringCopy(thePrefs.wasRightName, rightName); PasStringCopy(thePrefs.wasBattName, batteryName); PasStringCopy(thePrefs.wasBandName, bandName); PasStringCopy(thePrefs.wasHighName, highName); PasStringCopy(thePrefs.wasHighBanner, highBanner); theGlider.leftKey = thePrefs.wasLeftMap; theGlider.rightKey = thePrefs.wasRightMap; theGlider.battKey = thePrefs.wasBattMap; theGlider.bandKey = thePrefs.wasBandMap; #ifndef COMPILEDEMO #ifndef COMPILENOCP encryptedNumber = thePrefs.encrypted; #endif // COMPILENOCP #endif // COMPILEDEMO isVolume = thePrefs.wasVolume; isDepthPref = thePrefs.wasDepthPref; isMusicOn = thePrefs.wasMusicOn; doZooms = thePrefs.wasZooms; quickerTransitions = thePrefs.wasQuickTrans; isDoColorFade = thePrefs.wasDoColorFade; isPlayMusicIdle = thePrefs.wasIdleMusic; isPlayMusicGame = thePrefs.wasGameMusic; isHouseChecks = thePrefs.wasHouseChecks; maxFiles = thePrefs.wasMaxFiles; if ((maxFiles < 12) || (maxFiles > 500)) maxFiles = 12; isEditH = thePrefs.wasEditH; isEditV = thePrefs.wasEditV; isMapH = thePrefs.wasMapH; isMapV = thePrefs.wasMapV; mapRoomsWide = thePrefs.wasMapWide; mapRoomsHigh = thePrefs.wasMapHigh; isToolsH = thePrefs.wasToolsH; isToolsV = thePrefs.wasToolsV; isLinkH = thePrefs.wasLinkH; isLinkV = thePrefs.wasLinkV; isCoordH = thePrefs.wasCoordH; isCoordV = thePrefs.wasCoordV; mapLeftRoom = thePrefs.isMapLeft; mapTopRoom = thePrefs.isMapTop; wasFloor = thePrefs.wasFloor; wasSuite = thePrefs.wasSuite; numSMWarnings = thePrefs.smWarnings; autoRoomEdit = thePrefs.wasAutoEdit; isMapOpen = thePrefs.wasMapOpen; isToolsOpen = thePrefs.wasToolsOpen; isCoordOpen = thePrefs.wasCoordOpen; numNeighbors = thePrefs.wasNumNeighbors; toolMode = thePrefs.wasToolGroup; doAutoDemo = thePrefs.wasDoAutoDemo; isEscPauseKey = thePrefs.wasEscPauseKey; isUseSecondScreen = thePrefs.wasScreen2; if (thisMac.numScreens < 2) isUseSecondScreen = false; doBackground = thePrefs.wasDoBackground; doPrettyMap = thePrefs.wasPrettyMap; doBitchDialogs = thePrefs.wasBitchDialogs; } else { #ifdef COMPILEDEMO PasStringCopy("\pDemo House", thisHouseName); #else PasStringCopy("\pSlumberland", thisHouseName); #endif PasStringCopy("\plf arrow", leftName); PasStringCopy("\prt arrow", rightName); PasStringCopy("\pdn arrow", batteryName); PasStringCopy("\pup arrow", bandName); PasStringCopy("\pYour Name", highName); PasStringCopy("\pYour Message Here", highBanner); theGlider.leftKey = kLeftArrowKeyMap; theGlider.rightKey = kRightArrowKeyMap; theGlider.battKey = kDownArrowKeyMap; theGlider.bandKey = kUpArrowKeyMap; UnivGetSoundVolume(&isVolume, thisMac.hasSM3); if (isVolume < 1) isVolume = 1; else if (isVolume > 3) isVolume = 3; isDepthPref = kSwitchIfNeeded; isSoundOn = true; isMusicOn = true; isPlayMusicIdle = true; isPlayMusicGame = true; isHouseChecks = true; doZooms = true; quickerTransitions = false; numNeighbors = 9; isDoColorFade = true; maxFiles = 48; willMaxFiles = 48; isEditH = 3; isEditV = 41; isMapH = 3; // isMapV = qd.screenBits.bounds.bottom - 100; isMapV = 100; mapRoomsWide = 15; mapRoomsHigh = 4; // isToolsH = qd.screenBits.bounds.right - 120; isToolsH = 100; isToolsV = 35; isLinkH = 50; isLinkV = 80; // isCoordH = qd.screenBits.bounds.right - 55; isCoordH = 50; isCoordV = 204; mapLeftRoom = 60; mapTopRoom = 50; wasFloor = 0; wasSuite = 0; numSMWarnings = 0; autoRoomEdit = true; isMapOpen = true; isToolsOpen = true; isCoordOpen = false; toolMode = kBlowerMode; doAutoDemo = true; isEscPauseKey = false; isUseSecondScreen = false; doBackground = false; doPrettyMap = false; doBitchDialogs = true; } if ((numNeighbors > 1) && (thisMac.screen.right <= 512)) numNeighbors = 1; UnivGetSoundVolume(&wasVolume, thisMac.hasSM3); UnivSetSoundVolume(isVolume, thisMac.hasSM3); if (isVolume == 0) isSoundOn = false; else isSoundOn = true; } //-------------------------------------------------------------- WriteOutPrefs // Called just before Glider PRO quits. This function writes outÉ // the user preferences to disk. void WriteOutPrefs (void) { prefsInfo thePrefs; UnivGetSoundVolume(&isVolume, thisMac.hasSM3); #ifdef COMPILEDEMO PasStringCopy("\pDemo House", thePrefs.wasDefaultName); #else PasStringCopy(thisHouseName, thePrefs.wasDefaultName); #endif PasStringCopy(leftName, thePrefs.wasLeftName); PasStringCopy(rightName, thePrefs.wasRightName); PasStringCopy(batteryName, thePrefs.wasBattName); PasStringCopy(bandName, thePrefs.wasBandName); PasStringCopy(highName, thePrefs.wasHighName); PasStringCopy(highBanner, thePrefs.wasHighBanner); thePrefs.wasLeftMap = theGlider.leftKey; thePrefs.wasRightMap = theGlider.rightKey; thePrefs.wasBattMap = theGlider.battKey; thePrefs.wasBandMap = theGlider.bandKey; #ifndef COMPILEDEMO #ifndef COMPILENOCP thePrefs.encrypted = encryptedNumber; thePrefs.fakeLong = Random(); #endif // COMPILENOCP #endif // COMPILEDEMO thePrefs.wasVolume = isVolume; thePrefs.wasDepthPref = isDepthPref; thePrefs.wasMusicOn = isMusicOn; thePrefs.wasZooms = doZooms; thePrefs.wasQuickTrans = quickerTransitions; thePrefs.wasDoColorFade = isDoColorFade; thePrefs.wasIdleMusic = isPlayMusicIdle; thePrefs.wasGameMusic = isPlayMusicGame; thePrefs.wasHouseChecks = isHouseChecks; thePrefs.wasMaxFiles = willMaxFiles; thePrefs.wasEditH = isEditH; thePrefs.wasEditV = isEditV; thePrefs.wasMapH = isMapH; thePrefs.wasMapV = isMapV; thePrefs.wasMapWide = mapRoomsWide; thePrefs.wasMapHigh = mapRoomsHigh; thePrefs.wasToolsH = isToolsH; thePrefs.wasToolsV = isToolsV; thePrefs.isMapLeft = mapLeftRoom; thePrefs.isMapTop = mapTopRoom; thePrefs.wasFloor = wasFloor; thePrefs.wasSuite = wasSuite; thePrefs.wasLinkH = isLinkH; thePrefs.wasLinkV = isLinkV; thePrefs.wasCoordH = isCoordH; thePrefs.wasCoordV = isCoordV; thePrefs.smWarnings = numSMWarnings; thePrefs.wasAutoEdit = autoRoomEdit; thePrefs.wasMapOpen = isMapOpen; thePrefs.wasToolsOpen = isToolsOpen; thePrefs.wasCoordOpen = isCoordOpen; thePrefs.wasNumNeighbors = numNeighbors; thePrefs.wasToolGroup = toolMode; thePrefs.wasDoAutoDemo = doAutoDemo; thePrefs.wasEscPauseKey = isEscPauseKey; thePrefs.wasScreen2 = isUseSecondScreen; thePrefs.wasDoBackground = doBackground; thePrefs.wasPrettyMap = doPrettyMap; thePrefs.wasBitchDialogs = doBitchDialogs; if (!SavePrefs(&thePrefs, kPrefsVersion)) SysBeep(1); UnivSetSoundVolume(wasVolume, thisMac.hasSM3); } //-------------------------------------------------------------- main // Here is main(). The first function called when Glider PRO comes up. void main (void) { // long wasSeed; long theErr; OSErr fileErr; Boolean whoCares, copyGood; ToolBoxInit(); CheckOurEnvirons(); if (!thisMac.hasColor) RedAlert(kErrNeedColorQD); if (!thisMac.hasSystem7) RedAlert(kErrNeedSystem7); if (thisMac.numScreens == 0) RedAlert(kErrNeed16Or256Colors); // dataResFile = OpenResFile("\pMermaid"); SetUpAppleEvents(); LoadCursors(); ReadInPrefs(); #if defined COMPILEDEMO copyGood = true; #elif defined COMPILENOCP // didValidation = false; copyGood = true; #else didValidation = false; copyGood = ValidInstallation(true); if (!copyGood) encryptedNumber = 0L; else if (didValidation) WriteOutPrefs(); SpinCursor(3); #endif // if ((thisMac.numScreens > 1) && (isUseSecondScreen)) // ReflectSecondMonitorEnvirons(false, true, true); HandleDepthSwitching(); VariableInit(); SpinCursor(2); CheckMemorySize(); GetExtraCursors(); SpinCursor(2); InitMarquee(); CreatePointers(); SpinCursor(2); InitSrcRects(); CreateOffscreens(); SpinCursor(2); OpenMainWindow(); if (thisMac.hasQT) { theErr = EnterMovies(); if (theErr != noErr) thisMac.hasQT = false; } InitSound(); SpinCursor(2); InitMusic(); SpinCursor(2); BuildHouseList(); if (OpenHouse()) whoCares = ReadHouse(); PlayPrioritySound(kBirdSound, kBirdPriority); DelayTicks(6); InitializeMenus(); InitCursor(); #if BUILD_ARCADE_VERSION // HideMenuBarOld(); #endif // if ((isDoColorFade) && (thisMac.isDepth == 8)) // { // wasSeed = ExtractCTSeed((CGrafPtr)mainWindow); // WashColorIn(); // ForceCTSeed((CGrafPtr)mainWindow, wasSeed); // } // if ((!thisMac.hasSM3) && (numSMWarnings < 3)) // { // numSMWarnings++; // BitchAboutSM3(); // } while (!quitting) // this is the main loop HandleEvent(); /* #if BUILD_ARCADE_VERSION ShowMenuBarOld(); #endif */ KillMusic(); KillSound(); if (houseOpen) { if (!CloseHouse()) { CloseHouseResFork(); fileErr = FSClose(houseRefNum); houseOpen = false; } } WriteOutPrefs(); RestoreColorDepth(); FlushEvents(everyEvent, 0); // theErr = LoadScrap(); } \ No newline at end of file diff --git a/Sources/MainWindow.c b/Sources/MainWindow.c deleted file mode 100755 index 8f2829f..0000000 --- a/Sources/MainWindow.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // MainWindow.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Externs.h" #include "Environ.h" #include "House.h" #include "RectUtils.h" #define kMainWindowID 128 #define kEditWindowID 129 #define kMenuWindowID 130 void DrawOnSplash (void); void SetPaletteToGrays (void); void HardDrawMainWindow (void); void RestoreColorsSlam (void); CTabHandle theCTab; PixMapHandle thePMap; ColorSpec * wasColors; ColorSpec * newColors; CursHandle handCursorH, beamCursorH, vertCursorH, horiCursorH; CursHandle diagCursorH; Cursor handCursor, beamCursor, vertCursor, horiCursor; Cursor diagCursor; Rect workSrcRect; GWorldPtr workSrcMap; Rect mainWindowRect; WindowPtr mainWindow, menuWindow; short isEditH, isEditV; short playOriginH, playOriginV; short splashOriginH, splashOriginV; short theMode; Boolean fadeGraysOut, isDoColorFade, splashDrawn; extern GDHandle thisGDevice; extern short toolSelected; extern Boolean noRoomAtAll, isUseSecondScreen; extern Boolean quickerTransitions, houseIsReadOnly; //============================================================== Functions //-------------------------------------------------------------- DrawOnSplash // Draws additional text on top of splash screen. void DrawOnSplash (void) { Str255 houseLoadedStr; PasStringCopy("\pHouse: ", houseLoadedStr); PasStringConcat(houseLoadedStr, thisHouseName); if ((thisMac.hasQT) && (hasMovie)) PasStringConcat(houseLoadedStr, "\p (QT)"); TextSize(9); TextFace(1); TextFont(applFont); MoveTo(splashOriginH + 436, splashOriginV + 314); if (thisMac.isDepth == 4) { ForeColor(whiteColor); DrawString(houseLoadedStr); ForeColor(blackColor); } else { if (houseIsReadOnly) ColorText(houseLoadedStr, 5L); else ColorText(houseLoadedStr, 28L); } #if defined(powerc) || defined(__powerc) TextSize(12); TextFace(0); TextFont(systemFont); ForeColor(blackColor); MoveTo(splashOriginH + 5, splashOriginV + 457); DrawString("\pPowerPC Native!"); ForeColor(whiteColor); MoveTo(splashOriginH + 4, splashOriginV + 456); DrawString("\pPowerPC Native!"); ForeColor(blackColor); #endif } //-------------------------------------------------------------- RedrawSplashScreen void RedrawSplashScreen (void) { Rect tempRect; SetPort((GrafPtr)workSrcMap); PaintRect(&workSrcRect); QSetRect(&tempRect, 0, 0, 640, 460); QOffsetRect(&tempRect, splashOriginH, splashOriginV); LoadScaledGraphic(kSplash8BitPICT, &tempRect); DrawOnSplash(); SetPortWindowPort(mainWindow); // if (quickerTransitions) // DissBitsChunky(&workSrcRect); // else // DissBits(&workSrcRect); CopyRectMainToWork(&workSrcRect); } //-------------------------------------------------------------- UpdateMainWindow // Redraws the main window (depends on mode were in - splash, editing, playing). void UpdateMainWindow (void) { Rect tempRect; RgnHandle dummyRgn; dummyRgn = NewRgn(); SetPortWindowPort(mainWindow); if (theMode == kEditMode) { PauseMarquee(); CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &mainWindowRect, &mainWindowRect, srcCopy, GetPortVisibleRegion(GetWindowPort(mainWindow), dummyRgn)); ResumeMarquee(); } else if ((theMode == kSplashMode) || (theMode == kPlayMode)) { SetPort((GrafPtr)workSrcMap); PaintRect(&workSrcRect); QSetRect(&tempRect, 0, 0, 640, 460); QOffsetRect(&tempRect, splashOriginH, splashOriginV); LoadScaledGraphic(kSplash8BitPICT, &tempRect); CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &workSrcRect, &mainWindowRect, srcCopy, GetPortVisibleRegion(GetWindowPort(mainWindow), dummyRgn)); SetPortWindowPort(mainWindow); DrawOnSplash(); } DisposeRgn(dummyRgn); splashDrawn = true; } //-------------------------------------------------------------- UpdateMenuBarWindow // Ugly kludge to cover over the menu bar when playing game on 2nd monitor. void UpdateMenuBarWindow (void) { Rect bounds; if (menuWindow == nil) return; GetLocalWindowRect(menuWindow, &bounds); PaintRect(&bounds); } //-------------------------------------------------------------- OpenMainWindow // Opens up the main window (how it does this depends on mode were in). void OpenMainWindow (void) { // long wasSeed; short whichRoom; if (mainWindow != nil) { YellowAlert(kYellowUnaccounted, 6); return; } if (theMode == kEditMode) { if (menuWindow != nil) DisposeWindow(menuWindow); menuWindow = nil; QSetRect(&mainWindowRect, 0, 0, 512, 322); mainWindow = GetNewCWindow(kEditWindowID, nil, kPutInFront); SizeWindow(mainWindow, mainWindowRect.right, mainWindowRect.bottom, false); if (OptionKeyDown()) { isEditH = 3; isEditV = 41; } MoveWindow(mainWindow, isEditH, isEditV, true); ShowWindow(mainWindow); SetPortWindowPort(mainWindow); ClipRect(&mainWindowRect); ForeColor(blackColor); BackColor(whiteColor); whichRoom = GetFirstRoomNumber(); CopyRoomToThisRoom(whichRoom); ReflectCurrentRoom(false); } else { if (menuWindow == nil) { menuWindow = GetNewCWindow(kMenuWindowID, nil, kPutInFront); SizeWindow(menuWindow, RectWide(&thisMac.screen), 20, false); MoveWindow(menuWindow, thisMac.screen.left, thisMac.screen.top, true); ShowWindow(menuWindow); } mainWindowRect = thisMac.screen; ZeroRectCorner(&mainWindowRect); mainWindowRect.bottom -= 20; // thisMac.menuHigh mainWindow = GetNewCWindow(kMainWindowID, nil, kPutInFront); SizeWindow(mainWindow, mainWindowRect.right - mainWindowRect.left, mainWindowRect.bottom - mainWindowRect.top, false); MoveWindow(mainWindow, thisMac.screen.left, thisMac.screen.top + 20, true); // thisMac.menuHigh ShowWindow(mainWindow); SetPortWindowPort(mainWindow); ClipRect(&mainWindowRect); // CopyRgn(mainWindow->clipRgn, mainWindow->visRgn); ForeColor(blackColor); BackColor(whiteColor); PaintRect(&mainWindowRect); splashOriginH = ((thisMac.screen.right - thisMac.screen.left) - 640) / 2; if (splashOriginH < 0) splashOriginH = 0; splashOriginV = ((thisMac.screen.bottom - thisMac.screen.top) - 480) / 2; if (splashOriginV < 0) splashOriginV = 0; SetPort((GrafPtr)workSrcMap); PaintRect(&workSrcRect); LoadGraphic(kSplash8BitPICT); // if ((fadeGraysOut) && (isDoColorFade)) // { // wasSeed = ExtractCTSeed((CGrafPtr)mainWindow); // SetPortWindowPort(mainWindow); // SetPaletteToGrays(); // HardDrawMainWindow(); // fadeGraysOut = false; // ForceCTSeed((CGrafPtr)mainWindow, wasSeed); // } SetPortWindowPort(mainWindow); } } //-------------------------------------------------------------- CloseMainWindow // Closes the main window. void CloseMainWindow (void) { if (mainWindow != nil) DisposeWindow(mainWindow); mainWindow = nil; } //-------------------------------------------------------------- ZoomBetweenWindows // Zooms from one window size to another. Just for effect. /* #ifndef COMPILEDEMO void ZoomBetweenWindows (void) { Rect aRect; short h, v; if (theMode == kEditMode) { QSetRect(&aRect, 0, 0, 512, 342); QOffsetRect(&aRect, isEditH, isEditV); ZoomRectToRect(&(thisMac.screen), &aRect); } else { aRect = mainWindow->portRect; GetWindowLeftTop(mainWindow, &h, &v); QOffsetRect(&aRect, h, v); ZoomRectToRect(&aRect, &(thisMac.screen)); } } #endif */ //-------------------------------------------------------------- UpdateEditWindowTitle // Handles changing the title across the top of the main window. OnlyÉ // relevant when editing a house (room title displayed in window title). #ifndef COMPILEDEMO void UpdateEditWindowTitle (void) { Str255 newTitle, tempStr; if (mainWindow == nil) return; PasStringCopy(thisHouseName, newTitle); PasStringConcat(newTitle, "\p - "); if (noRoomAtAll) PasStringConcat(newTitle, "\pNo rooms"); else if (houseUnlocked) { PasStringConcat(newTitle, thisRoom->name); PasStringConcat(newTitle, "\p ("); NumToString((long)thisRoom->floor, tempStr); PasStringConcat(newTitle, tempStr); PasStringConcat(newTitle, "\p, "); NumToString((long)thisRoom->suite, tempStr); PasStringConcat(newTitle, tempStr); PasStringConcat(newTitle, "\p)"); } else PasStringConcat(newTitle, "\pHouse Locked"); SetWTitle(mainWindow, newTitle); } #endif //-------------------------------------------------------------- HandleMainClick // Handle a mouse click in the main window (relevant only when editing). void HandleMainClick (Point wherePt, Boolean isDoubleClick) { KeyMap theseKeys; if ((theMode != kEditMode) || (mainWindow == nil) || (!houseUnlocked)) return; SetPortWindowPort(mainWindow); GlobalToLocal(&wherePt); if (toolSelected == kSelectTool) DoSelectionClick(wherePt, isDoubleClick); else DoNewObjectClick(wherePt); GetKeys(theseKeys); if (!BitTst(&theseKeys, kShiftKeyMap)) { EraseSelectedTool(); SelectTool(kSelectTool); } } //-------------------------------------------------------------- ShowMenuBarOld // Displays the menu bar (after having been hidden). /* void ShowMenuBarOld (void) { Rect theRect; GrafPtr wasPort, tempPort; RgnHandle worldRgn, menuBarRgn; if (LMGetMBarHeight() == 0) { GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); SetPort((GrafPtr)tempPort); LMSetMBarHeight(thisMac.menuHigh); theRect = (**GetGrayRgn()).rgnBBox; UnionRect(&theRect, &qd.screenBits.bounds, &theRect); worldRgn = NewRgn(); OpenRgn(); FrameRoundRect(&theRect, 16, 16); CloseRgn(worldRgn); theRect = qd.screenBits.bounds; theRect.bottom = theRect.top + thisMac.menuHigh; menuBarRgn = NewRgn(); RectRgn(menuBarRgn, &theRect); SectRgn(worldRgn, menuBarRgn, menuBarRgn); // /------------------\ DisposeRgn(worldRgn); // |__________________| UnionRgn(tempPort->visRgn, menuBarRgn, tempPort->visRgn); DiffRgn(tempPort->visRgn, menuBarRgn, tempPort->visRgn); DisposeRgn(menuBarRgn); ClosePort(tempPort); SetPort((GrafPtr)wasPort); DrawMenuBar(); } } */ //-------------------------------------------------------------- HideMenuBarOld // Hides the menu bar - completely erasing it from the screen. /* void HideMenuBarOld (void) { Rect theRect; RgnHandle worldRgn, menuBarRgn; GrafPtr wasPort, tempPort; if (LMGetMBarHeight() != 0) { GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); SetPort((GrafPtr)tempPort); LMSetMBarHeight(0); theRect = (**GetGrayRgn()).rgnBBox; UnionRect(&theRect, &qd.screenBits.bounds, &theRect); worldRgn = NewRgn(); OpenRgn(); FrameRoundRect(&theRect, 16, 16); CloseRgn(worldRgn); theRect = qd.screenBits.bounds; theRect.bottom = theRect.top + thisMac.menuHigh; menuBarRgn = NewRgn(); RectRgn(menuBarRgn, &theRect); SectRgn(worldRgn, menuBarRgn, menuBarRgn); // /------------------\ DisposeRgn(worldRgn); // |__________________| UnionRgn(tempPort->visRgn, menuBarRgn, tempPort->visRgn); DisposeRgn(menuBarRgn); PaintRect(&theRect); ClosePort(tempPort); SetPort((GrafPtr)wasPort); } } */ //-------------------------------------------------------------- SetPaletteToGrays // Sets up a gray palette corresponding in luminance to the standard colorÉ // palette. This is to facilitate the gray->color fade when the game comes up. /* void SetPaletteToGrays (void) { GDHandle theDevice; long longGray; short i; char wasState; wasState = HGetState((Handle)thisGDevice); HLock((Handle)thisGDevice); thePMap = (*thisGDevice)->gdPMap; HSetState((Handle)thisGDevice, wasState); theCTab = (*thePMap)->pmTable; wasColors = nil; wasColors = (ColorSpec*)NewPtr(sizeof(ColorSpec) * 256); if (wasColors == nil) RedAlert(kErrNoMemory); newColors = nil; newColors = (ColorSpec*)NewPtr(sizeof(ColorSpec) * 256); if (newColors == nil) RedAlert(kErrNoMemory); for (i = 0; i < 256; i++) { wasColors[i] = (*theCTab)->ctTable[i]; newColors[i] = (*theCTab)->ctTable[i]; if (i != 5) { longGray = ((long)newColors[i].rgb.red * 3L) / 10L + ((long)newColors[i].rgb.green * 6L) / 10L + ((long)newColors[i].rgb.blue * 1L) / 10L; newColors[i].rgb.red = (unsigned short)longGray; newColors[i].rgb.green = (unsigned short)longGray; newColors[i].rgb.blue = (unsigned short)longGray; } } theDevice = GetGDevice(); SetGDevice(thisGDevice); SetEntries(0, 255, newColors); SetGDevice(theDevice); } */ //-------------------------------------------------------------- HardDrawMainWindow // Ignores the ToolBox - this function draws direct to screen in order toÉ // circumvent the Toolbox's attempt to color-match to the current palette. /* void HardDrawMainWindow (void) { PixMapHandle pixMapH; Point offsetPt; long srcRowBytes, destRowBytes; long src; long dest; short i, w; SInt8 mode; char wasState; wasState = HGetState((Handle)thisGDevice); HLock((Handle)thisGDevice); pixMapH = (**thisGDevice).gdPMap; HSetState((Handle)thisGDevice, wasState); srcRowBytes = (long)((*(workSrcMap->portPixMap))->rowBytes & 0x7FFF); destRowBytes = (**pixMapH).rowBytes & 0x7FFF; src = (long)((*(workSrcMap->portPixMap))->baseAddr); dest = (long)((**pixMapH).baseAddr) + splashOriginH + ((splashOriginV + thisMac.menuHigh) * destRowBytes); offsetPt.h = 0; offsetPt.v = 0; ShieldCursor(&mainWindowRect, offsetPt); mode = true32b; SwapMMUMode(&mode); for (i = 0; i < 460; i++) { for (w = 0; w < 160; w++) { *(long *)dest = *(long *)src; dest += 4L; src += 4L; } src -= 640; dest -= 640; src += srcRowBytes; dest += destRowBytes; } SwapMMUMode(&mode); ShowCursor(); } */ //-------------------------------------------------------------- WashColorIn // Slowly walks the palette from its gray luminance state to the full colorÉ // palette. In this way, color appears to slowly wash in. /* void WashColorIn (void) { #define kGray2ColorSteps 180 GDHandle theDevice; long longDelta; short i, c; theDevice = GetGDevice(); SetGDevice(thisGDevice); for (i = 0; i < kGray2ColorSteps; i++) { for (c = 0; c < 256; c++) { if (c != 5) { longDelta = (((long)wasColors[c].rgb.red - (long)newColors[c].rgb.red) / (long)(kGray2ColorSteps - i)) + (long)newColors[c].rgb.red; newColors[c].rgb.red = (unsigned short)longDelta; longDelta = (((long)wasColors[c].rgb.green - (long)newColors[c].rgb.green) / (long)(kGray2ColorSteps - i)) + (long)newColors[c].rgb.green; newColors[c].rgb.green = (unsigned short)longDelta; longDelta = (((long)wasColors[c].rgb.blue - (long)newColors[c].rgb.blue) / (long)(kGray2ColorSteps - i)) + (long)newColors[c].rgb.blue; newColors[c].rgb.blue = (unsigned short)longDelta; } } SetEntries(0, 255, newColors); if (Button()) break; } SetEntries(0, 255, wasColors); SetGDevice(theDevice); RestoreColorsSlam(); if (wasColors != nil) DisposePtr((Ptr)wasColors); if (newColors != nil) DisposePtr((Ptr)newColors); } */ \ No newline at end of file diff --git a/Sources/Map.c b/Sources/Map.c deleted file mode 100755 index bb302ac..0000000 --- a/Sources/Map.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Map.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Externs.h" #include "Environ.h" #include "House.h" #include "RectUtils.h" #include "Utilities.h" #define kMapRoomsHigh 9 // was 7 #define kMapRoomsWide 9 // was 7 #define kMapScrollBarWidth 16 #define kHScrollRef 5L #define kVScrollRef 27L #define kMapGroundValue 56 #define kNewRoomAlert 1004 #define kYesDoNewRoom 1 #define kThumbnailPictID 1010 void LoadGraphicPlus (short, Rect *); void RedrawMapContents (void); pascal void LiveHScrollAction (ControlHandle, short); pascal void LiveVScrollAction (ControlHandle, short); Boolean QueryNewRoom (void); void CreateNailOffscreen (void); void KillNailOffscreen (void); Rect nailSrcRect, activeRoomRect, wasActiveRoomRect; Rect mapHScrollRect, mapVScrollRect, mapCenterRect; Rect mapWindowRect; GWorldPtr nailSrcMap; WindowPtr mapWindow; ControlHandle mapHScroll, mapVScroll; short isMapH, isMapV, mapRoomsHigh, mapRoomsWide; short mapLeftRoom, mapTopRoom; Boolean isMapOpen, doPrettyMap; extern Boolean doBitchDialogs; //============================================================== Functions //-------------------------------------------------------------- ThisRoomVisibleOnMap #ifndef COMPILEDEMO Boolean ThisRoomVisibleOnMap (void) { short h, v; h = thisRoom->suite; v = kMapGroundValue - thisRoom->floor; if ((h < mapLeftRoom) || (v < mapTopRoom) || (h >= (mapLeftRoom + mapRoomsWide)) || (v >= (mapTopRoom + mapRoomsHigh))) return (false); else return (true); } #endif //-------------------------------------------------------------- CenterMapOnRoom #ifndef COMPILEDEMO void CenterMapOnRoom (short h, short v) { if (mapWindow == nil) return; mapLeftRoom = h - (mapRoomsWide / 2); mapTopRoom = (kMapGroundValue - v) - (mapRoomsHigh / 2); if (mapLeftRoom < 0) mapLeftRoom = 0; else if (mapLeftRoom > (kMaxNumRoomsH - mapRoomsWide)) mapLeftRoom = kMaxNumRoomsH - mapRoomsWide; if (mapTopRoom < 0) mapTopRoom = 0; else if (mapTopRoom > (kMaxNumRoomsV - mapRoomsHigh)) mapTopRoom = kMaxNumRoomsV - mapRoomsHigh; if (mapWindow != nil) { SetControlValue(mapHScroll, mapLeftRoom); SetControlValue(mapVScroll, mapTopRoom); } } #endif //-------------------------------------------------------------- FlagMapRoomsForUpdate #ifndef COMPILEDEMO void FlagMapRoomsForUpdate (void) { if (mapWindow == nil) return; // SetPortWindowPort(mapWindow); InvalWindowRect(mapWindow, &wasActiveRoomRect); InvalWindowRect(mapWindow, &activeRoomRect); } #endif //-------------------------------------------------------------- FindNewActiveRoomRect #ifndef COMPILEDEMO void FindNewActiveRoomRect (void) { Rect aRoom; short h, i; short floor, suite, whoCares; char wasState; Boolean activeRoomVisible; if (mapWindow == nil) return; activeRoomVisible = false; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); for (i = 0; i < mapRoomsHigh; i++) { for (h = 0; h < mapRoomsWide; h++) { QSetRect(&aRoom, 0, 0, kMapRoomWidth, kMapRoomHeight); QOffsetRect(&aRoom, kMapRoomWidth * h, kMapRoomHeight * i); suite = h + mapLeftRoom; floor = kMapGroundValue - (i + mapTopRoom); if ((RoomExists(suite, floor, &whoCares)) && (houseUnlocked)) { if (whoCares == thisRoomNumber) { wasActiveRoomRect = activeRoomRect; activeRoomRect = aRoom; activeRoomVisible = true; } } } } HSetState((Handle)thisHouse, wasState); if (activeRoomVisible) { activeRoomRect.right++; activeRoomRect.bottom++; InsetRect(&activeRoomRect, -1, -1); } } #endif //-------------------------------------------------------------- LoadGraphicPlus void LoadGraphicPlus (short resID, Rect *theRect) { PicHandle thePicture; thePicture = GetPicture(resID); if (thePicture == nil) { thePicture = (PicHandle)GetResource('Date', resID); if (thePicture == nil) { return; } } DrawPicture(thePicture, theRect); ReleaseResource((Handle)thePicture); } //-------------------------------------------------------------- RedrawMapContents #ifndef COMPILEDEMO void RedrawMapContents (void) { Rect newClip, aRoom, src; RgnHandle wasClip; short h, i, groundLevel; short floor, suite, whoCares, type; char wasState; Boolean activeRoomVisible; if (mapWindow == nil) return; activeRoomVisible = false; groundLevel = kMapGroundValue - mapTopRoom; newClip.left = mapWindowRect.left; newClip.top = mapWindowRect.top; newClip.right = mapWindowRect.right + 2 - kMapScrollBarWidth; newClip.bottom = mapWindowRect.bottom + 2 - kMapScrollBarWidth; SetPort((GrafPtr)mapWindow); wasClip = NewRgn(); if (wasClip != nil) { GetClip(wasClip); ClipRect(&newClip); } wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); for (i = 0; i < mapRoomsHigh; i++) { for (h = 0; h < mapRoomsWide; h++) { QSetRect(&aRoom, 0, 0, kMapRoomWidth, kMapRoomHeight); QOffsetRect(&aRoom, kMapRoomWidth * h, kMapRoomHeight * i); suite = h + mapLeftRoom; floor = kMapGroundValue - (i + mapTopRoom); if ((RoomExists(suite, floor, &whoCares)) && (houseUnlocked)) { PenNormal(); type = (*thisHouse)->rooms[whoCares].background - kBaseBackgroundID; if (type > kNumBackgrounds) { if (!doPrettyMap) type = kNumBackgrounds; // Draw "?" thumbnail. } ForeColor(blackColor); if (type > kNumBackgrounds) // Do a "pretty" thumbnail. { LoadGraphicPlus(type + kBaseBackgroundID, &aRoom); } else { QSetRect(&src, 0, 0, kMapRoomWidth, kMapRoomHeight); QOffsetRect(&src, 0, type * kMapRoomHeight); CopyBits((BitMap *)*GetGWorldPixMap(nailSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mapWindow)), &src, &aRoom, srcCopy, nil); } if (whoCares == thisRoomNumber) { activeRoomRect = aRoom; activeRoomVisible = true; } } else { Pattern dummyPat; PenPat(GetQDGlobalsGray(&dummyPat)); if (i >= groundLevel) ForeColor(greenColor); else ForeColor(blueColor); PaintRect(&aRoom); } } } HSetState((Handle)thisHouse, wasState); ForeColor(blackColor); PenNormal(); for (i = 1; i < mapRoomsWide; i++) { MoveTo(i * kMapRoomWidth, 0); Line(0, mapRoomsHigh * kMapRoomHeight); } for (i = 1; i < mapRoomsHigh; i++) { MoveTo(0, i * kMapRoomHeight); Line(mapRoomsWide * kMapRoomWidth, 0); } if (activeRoomVisible) { ForeColor(redColor); activeRoomRect.right++; activeRoomRect.bottom++; FrameRect(&activeRoomRect); InsetRect(&activeRoomRect, 1, 1); FrameRect(&activeRoomRect); ForeColor(blackColor); InsetRect(&activeRoomRect, -1, -1); } if (wasClip != nil) { SetClip(wasClip); DisposeRgn(wasClip); } } #endif //-------------------------------------------------------------- UpdateMapWindow void UpdateMapWindow (void) { #ifndef COMPILEDEMO if (mapWindow == nil) return; SetControlValue(mapHScroll, mapLeftRoom); SetControlValue(mapVScroll, mapTopRoom); SetPortWindowPort(mapWindow); DrawControls(mapWindow); DrawGrowIcon(mapWindow); RedrawMapContents(); #endif } //-------------------------------------------------------------- ResizeMapWindow void ResizeMapWindow (short newH, short newV) { #ifndef COMPILEDEMO if ((newH == 0) && (newV == 0)) return; SetPortWindowPort(mapWindow); mapRoomsWide = newH / kMapRoomWidth; if (mapRoomsWide < 3) mapRoomsWide = 3; mapRoomsHigh = newV / kMapRoomHeight; if (mapRoomsHigh < 3) mapRoomsHigh = 3; QSetRect(&mapWindowRect, 0, 0, mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth - 2, mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth - 2); EraseRect(&mapWindowRect); SizeWindow(mapWindow, mapWindowRect.right, mapWindowRect.bottom, true); SetControlMaximum(mapHScroll, kMaxNumRoomsH - mapRoomsWide); MoveControl(mapHScroll, 0, mapWindowRect.bottom - kMapScrollBarWidth + 2); SizeControl(mapHScroll, mapWindowRect.right - kMapScrollBarWidth + 3, kMapScrollBarWidth); mapLeftRoom = GetControlValue(mapHScroll); SetControlMaximum(mapVScroll, kMaxNumRoomsV - mapRoomsHigh); MoveControl(mapVScroll, mapWindowRect.right - kMapScrollBarWidth + 2, 0); SizeControl(mapVScroll, kMapScrollBarWidth, mapWindowRect.bottom - kMapScrollBarWidth + 3); mapTopRoom = GetControlValue(mapVScroll); InvalWindowRect(mapWindow, &mapWindowRect); #endif } //-------------------------------------------------------------- OpenMapWindow void OpenMapWindow (void) { #ifndef COMPILEDEMO Rect src, dest; Point globalMouse; if (mapWindow == nil) { CreateNailOffscreen(); QSetRect(&mapWindowRect, 0, 0, mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth - 2, mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth - 2); mapWindow = NewCWindow(nil, &mapWindowRect, "\pMap", false, kWindoidGrowWDEF, kPutInFront, true, 0L); if (mapWindow == nil) RedAlert(kErrNoMemory); // if (OptionKeyDown()) // { // isMapH = 3; // isMapV = qd.screenBits.bounds.bottom - 100; // } MoveWindow(mapWindow, isMapH, isMapV, true); globalMouse = MyGetGlobalMouse(); QSetRect(&wasActiveRoomRect, 0, 0, 1, 1); QSetRect(&activeRoomRect, 0, 0, 1, 1); QSetRect(&src, 0, 0, 1, 1); QOffsetRect(&src, globalMouse.h, globalMouse.v); GetWindowRect(mapWindow, &dest); BringToFront(mapWindow); ShowHide(mapWindow, true); // FlagWindowFloating(mapWindow); TEMP - use flaoting windows HiliteAllWindows(); SetPort((GrafPtr)mapWindow); SetOrigin(1, 1); QSetRect(&mapHScrollRect, -1, mapRoomsHigh * kMapRoomHeight, mapRoomsWide * kMapRoomWidth + 1, mapRoomsHigh * kMapRoomHeight + kMapScrollBarWidth); QSetRect(&mapVScrollRect, mapRoomsWide * kMapRoomWidth, -1, mapRoomsWide * kMapRoomWidth + kMapScrollBarWidth, mapRoomsHigh * kMapRoomHeight + 1); mapHScroll = NewControl(mapWindow, &mapHScrollRect, "\p", true, mapLeftRoom, 0, kMaxNumRoomsH - mapRoomsWide, scrollBarProc, kHScrollRef); if (mapHScroll == nil) RedAlert(kErrNoMemory); mapVScroll = NewControl(mapWindow, &mapVScrollRect, "\p", true, mapTopRoom, 0, kMaxNumRoomsV - mapRoomsHigh, scrollBarProc, kVScrollRef); if (mapVScroll == nil) RedAlert(kErrNoMemory); QSetRect(&mapCenterRect, -16, -16, 0, 0); QOffsetRect(&mapCenterRect, mapWindowRect.right + 2, mapWindowRect.bottom + 2); CenterMapOnRoom(thisRoom->suite, thisRoom->floor); } UpdateMapCheckmark(true); #endif } //-------------------------------------------------------------- CloseMapWindow void CloseMapWindow (void) { #ifndef COMPILEDEMO CloseThisWindow(&mapWindow); UpdateMapCheckmark(false); #endif } //-------------------------------------------------------------- ToggleMapWindow void ToggleMapWindow (void) { #ifndef COMPILEDEMO if (mapWindow == nil) { OpenMapWindow(); isMapOpen = true; } else { CloseMapWindow(); isMapOpen = false; } #endif } //-------------------------------------------------------------- LiveHScrollAction #ifndef COMPILEDEMO pascal void LiveHScrollAction (ControlHandle theControl, short thePart) { short wasValue, newValue; switch (thePart) { case kControlUpButtonPart: wasValue = GetControlValue(theControl); SetControlValue(theControl, wasValue - 1); if (GetControlValue(theControl) != wasValue) { mapLeftRoom = GetControlValue(theControl); RedrawMapContents(); } break; case kControlDownButtonPart: wasValue = GetControlValue(theControl); SetControlValue(theControl, wasValue + 1); if (GetControlValue(theControl) != wasValue) { mapLeftRoom = GetControlValue(theControl); RedrawMapContents(); } break; case kControlPageUpPart: wasValue = GetControlValue(theControl); newValue = wasValue - (mapRoomsWide / 2); SetControlValue(theControl, newValue); if (GetControlValue(theControl) != wasValue) { mapLeftRoom = GetControlValue(theControl); RedrawMapContents(); } break; case kControlPageDownPart: wasValue = GetControlValue(theControl); newValue = wasValue + (mapRoomsWide / 2); SetControlValue(theControl, newValue); if (GetControlValue(theControl) != wasValue) { mapLeftRoom = GetControlValue(theControl); RedrawMapContents(); } break; case kControlIndicatorPart: break; } } #endif //-------------------------------------------------------------- LiveVScrollAction #ifndef COMPILEDEMO pascal void LiveVScrollAction (ControlHandle theControl, short thePart) { short wasValue, newValue; switch (thePart) { case kControlUpButtonPart: wasValue = GetControlValue(theControl); SetControlValue(theControl, wasValue - 1); if (GetControlValue(theControl) != wasValue) { mapTopRoom = GetControlValue(theControl); RedrawMapContents(); } break; case kControlDownButtonPart: wasValue = GetControlValue(theControl); SetControlValue(theControl, wasValue + 1); if (GetControlValue(theControl) != wasValue) { mapTopRoom = GetControlValue(theControl); RedrawMapContents(); } break; case kControlPageUpPart: wasValue = GetControlValue(theControl); newValue = wasValue - (mapRoomsHigh / 2); SetControlValue(theControl, newValue); if (GetControlValue(theControl) != wasValue) { mapTopRoom = GetControlValue(theControl); RedrawMapContents(); } break; case kControlPageDownPart: wasValue = GetControlValue(theControl); newValue = wasValue + (mapRoomsHigh / 2); SetControlValue(theControl, newValue); if (GetControlValue(theControl) != wasValue) { mapTopRoom = GetControlValue(theControl); RedrawMapContents(); } break; case kControlIndicatorPart: break; } } #endif //-------------------------------------------------------------- HandleMapClick void HandleMapClick (EventRecord *theEvent) { #ifndef COMPILEDEMO Rect aRoom; ControlHandle whichControl; Point wherePt, globalWhere; long controlRef; short whichPart, localH, localV; short roomH, roomV, itsNumber; ControlActionUPP scrollHActionUPP, scrollVActionUPP; wherePt = theEvent->where; scrollHActionUPP = NewControlActionUPP(LiveHScrollAction); scrollVActionUPP = NewControlActionUPP(LiveVScrollAction); if (mapWindow == nil) return; SetPortWindowPort(mapWindow); globalWhere = wherePt; GlobalToLocal(&wherePt); wherePt.h -= 1; wherePt.v -= 1; whichPart = FindControl(wherePt, mapWindow, &whichControl); if (whichPart == 0) // User clicked in map content area. { localH = wherePt.h / kMapRoomWidth; localV = wherePt.v / kMapRoomHeight; if ((localH >= mapRoomsWide) || (localV >= mapRoomsHigh)) return; roomH = localH + mapLeftRoom; roomV = kMapGroundValue - (localV + mapTopRoom); if (RoomExists(roomH, roomV, &itsNumber)) { CopyRoomToThisRoom(itsNumber); DeselectObject(); ReflectCurrentRoom(false); if (thisMac.hasDrag) { SetPortWindowPort(mainWindow); QSetRect(&aRoom, 0, 0, kMapRoomWidth, kMapRoomHeight); CenterRectOnPoint(&aRoom, globalWhere); // if (DragRoom(theEvent, &aRoom, itsNumber)) // { // TEMP disabled. // } } } else { if (doBitchDialogs) { if (QueryNewRoom()) { if (!CreateNewRoom(roomH, roomV)) { YellowAlert(kYellowUnaccounted, 11); return; } else { DeselectObject(); ReflectCurrentRoom(false); } } else return; } else { if (!CreateNewRoom(roomH, roomV)) { YellowAlert(kYellowUnaccounted, 11); return; } else { DeselectObject(); ReflectCurrentRoom(false); } } } } else { controlRef = GetControlReference(whichControl); if (controlRef == kHScrollRef) { switch (whichPart) { case kControlUpButtonPart: case kControlDownButtonPart: case kControlPageUpPart: case kControlPageDownPart: if (TrackControl(whichControl, wherePt, scrollHActionUPP)) { } break; case kControlIndicatorPart: if (TrackControl(whichControl, wherePt, nil)) { mapLeftRoom = GetControlValue(whichControl); RedrawMapContents(); } break; } } else if (controlRef == kVScrollRef) { switch (whichPart) { case kControlUpButtonPart: case kControlDownButtonPart: case kControlPageUpPart: case kControlPageDownPart: if (TrackControl(whichControl, wherePt, scrollVActionUPP)) { } break; case kControlIndicatorPart: if (TrackControl(whichControl, wherePt, nil)) { mapTopRoom = GetControlValue(whichControl); RedrawMapContents(); } break; } } } DisposeControlActionUPP(scrollHActionUPP); DisposeControlActionUPP(scrollVActionUPP); #endif } //-------------------------------------------------------------- QueryNewRoom #ifndef COMPILEDEMO Boolean QueryNewRoom (void) { short hitWhat; // CenterAlert(kNewRoomAlert); hitWhat = Alert(kNewRoomAlert, nil); if (hitWhat == kYesDoNewRoom) return (true); else return (false); } #endif //-------------------------------------------------------------- CreateNailOffscreen #ifndef COMPILEDEMO void CreateNailOffscreen (void) { CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; if (nailSrcMap == nil) { GetGWorld(&wasCPort, &wasWorld); QSetRect(&nailSrcRect, 0, 0, kMapRoomWidth, kMapRoomHeight * (kNumBackgrounds + 1)); theErr = CreateOffScreenGWorld(&nailSrcMap, &nailSrcRect, kPreferredDepth); SetGWorld(nailSrcMap, nil); LoadGraphic(kThumbnailPictID); SetGWorld(wasCPort, wasWorld); } } #endif //-------------------------------------------------------------- KillNailOffscreen #ifndef COMPILEDEMO void KillNailOffscreen (void) { if (nailSrcMap != nil) { // KillOffScreenPixMap(nailSrcMap); DisposeGWorld(nailSrcMap); nailSrcMap = nil; } } #endif //-------------------------------------------------------------- MoveRoom void MoveRoom (Point wherePt) { short localH, localV; short roomH, roomV, itsNumber; localH = wherePt.h / kMapRoomWidth; localV = wherePt.v / kMapRoomHeight; if ((localH >= mapRoomsWide) || (localV >= mapRoomsHigh)) return; roomH = localH + mapLeftRoom; roomV = kMapGroundValue - (localV + mapTopRoom); if (RoomExists(roomH, roomV, &itsNumber)) { } else { thisRoom->floor = roomV; thisRoom->suite = roomH; fileDirty = true; UpdateMenus(false); RedrawMapContents(); } } \ No newline at end of file diff --git a/Sources/Marquee.c b/Sources/Marquee.c deleted file mode 100755 index 53a9712..0000000 --- a/Sources/Marquee.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Marquee.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Marquee.h" #include "Objects.h" #include "ObjectEdit.h" #include "RectUtils.h" #define kMarqueePatListID 128 #define kHandleSideLong 9 void DrawGliderMarquee (void); void DrawMarquee (void); marquee theMarquee; Rect marqueeGliderRect; Boolean gliderMarqueeUp; extern Cursor handCursor, vertCursor, horiCursor, diagCursor; extern Rect leftStartGliderSrc; //============================================================== Functions //-------------------------------------------------------------- DoMarquee void DoMarquee (void) { if ((!theMarquee.active) || (theMarquee.paused)) return; SetPortWindowPort(mainWindow); PenMode(patXor); PenPat(&theMarquee.pats[theMarquee.index]); DrawMarquee(); theMarquee.index++; if (theMarquee.index >= kNumMarqueePats) theMarquee.index = 0; PenPat(&theMarquee.pats[theMarquee.index]); DrawMarquee(); PenNormal(); } //-------------------------------------------------------------- StartMarquee void StartMarquee (Rect *theRect) { if (theMarquee.active) StopMarquee(); if (objActive == kNoObjectSelected) return; SetPortWindowPort(mainWindow); theMarquee.bounds = *theRect; theMarquee.active = true; theMarquee.paused = false; theMarquee.handled = false; PenMode(patXor); PenPat(&theMarquee.pats[theMarquee.index]); DrawMarquee(); PenNormal(); SetCoordinateHVD(theMarquee.bounds.left, theMarquee.bounds.top, -1); } //-------------------------------------------------------------- StartMarqueeHandled void StartMarqueeHandled (Rect *theRect, short direction, short dist) { if (theMarquee.active) StopMarquee(); if (objActive == kNoObjectSelected) return; SetPortWindowPort(mainWindow); theMarquee.bounds = *theRect; theMarquee.active = true; theMarquee.paused = false; theMarquee.handled = true; QSetRect(&theMarquee.handle, 0, 0, kHandleSideLong, kHandleSideLong); QOffsetRect(&theMarquee.handle, kHandleSideLong / -2, kHandleSideLong / -2); switch (direction) { case kAbove: QOffsetRect(&theMarquee.handle, theMarquee.bounds.left, theMarquee.bounds.top); QOffsetRect(&theMarquee.handle, HalfRectWide(&theMarquee.bounds), -dist); break; case kToRight: QOffsetRect(&theMarquee.handle, theMarquee.bounds.right, theMarquee.bounds.top); QOffsetRect(&theMarquee.handle, dist, HalfRectTall(&theMarquee.bounds)); break; case kBelow: QOffsetRect(&theMarquee.handle, theMarquee.bounds.left, theMarquee.bounds.bottom); QOffsetRect(&theMarquee.handle, HalfRectWide(&theMarquee.bounds), dist); break; case kToLeft: QOffsetRect(&theMarquee.handle, theMarquee.bounds.left, theMarquee.bounds.top); QOffsetRect(&theMarquee.handle, -dist, HalfRectTall(&theMarquee.bounds)); break; case kBottomCorner: QOffsetRect(&theMarquee.handle, theMarquee.bounds.right, theMarquee.bounds.bottom); break; case kTopCorner: QOffsetRect(&theMarquee.handle, theMarquee.bounds.right, theMarquee.bounds.top); break; } theMarquee.direction = direction; theMarquee.dist = dist; PenMode(patXor); PenPat(&theMarquee.pats[theMarquee.index]); DrawMarquee(); PenNormal(); SetCoordinateHVD(theMarquee.bounds.left, theMarquee.bounds.top, dist); } //-------------------------------------------------------------- StopMarquee void StopMarquee (void) { if (gliderMarqueeUp) { DrawGliderMarquee(); gliderMarqueeUp = false; } if (!theMarquee.active) return; SetPortWindowPort(mainWindow); PenMode(patXor); PenPat(&theMarquee.pats[theMarquee.index]); DrawMarquee(); PenNormal(); theMarquee.active = false; SetCoordinateHVD(-1, -1, -1); } //-------------------------------------------------------------- PauseMarquee void PauseMarquee (void) { if (!theMarquee.active) return; theMarquee.paused = true; StopMarquee(); } //-------------------------------------------------------------- ResumeMarquee void ResumeMarquee (void) { if (!theMarquee.paused) return; if (theMarquee.handled) { StartMarqueeHandled(&theMarquee.bounds, theMarquee.direction, theMarquee.dist); HandleBlowerGlider(); } else StartMarquee(&theMarquee.bounds); } //-------------------------------------------------------------- DragOutMarqueeRect void DragOutMarqueeRect (Point start, Rect *theRect) { Point wasPt, newPt; SetPortWindowPort(mainWindow); InitCursor(); QSetRect(theRect, start.h, start.v, start.h, start.v); PenMode(patXor); PenPat(&theMarquee.pats[theMarquee.index]); FrameRect(theRect); wasPt = start; while (WaitMouseUp()) { GetMouse(&newPt); if (DeltaPoint(wasPt, newPt)) { FrameRect(theRect); QSetRect(theRect, start.h, start.v, newPt.h, newPt.v); NormalizeRect(theRect); FrameRect(theRect); wasPt = newPt; } } FrameRect(theRect); PenNormal(); } //-------------------------------------------------------------- DragMarqueeRect void DragMarqueeRect (Point start, Rect *theRect, Boolean lockH, Boolean lockV) { Point wasPt, newPt; short deltaH, deltaV; SetCursor(&handCursor); StopMarquee(); PenMode(patXor); PenPat(&theMarquee.pats[theMarquee.index]); theMarquee.bounds = *theRect; FrameRect(&theMarquee.bounds); wasPt = start; while (WaitMouseUp()) { GetMouse(&newPt); if (DeltaPoint(wasPt, newPt)) { if (lockV) deltaH = 0; else deltaH = newPt.h - wasPt.h; if (lockH) deltaV = 0; else deltaV = newPt.v - wasPt.v; FrameRect(&theMarquee.bounds); QOffsetRect(&theMarquee.bounds, deltaH, deltaV); FrameRect(&theMarquee.bounds); wasPt = newPt; SetCoordinateHVD(theMarquee.bounds.left, theMarquee.bounds.top, -2); } } FrameRect(&theMarquee.bounds); *theRect = theMarquee.bounds; PenNormal(); InitCursor(); } //-------------------------------------------------------------- DragMarqueeHandle void DragMarqueeHandle (Point start, short *dragged) { Point wasPt, newPt; short deltaH, deltaV; if ((theMarquee.direction == kAbove) || (theMarquee.direction == kBelow)) SetCursor(&vertCursor); else SetCursor(&horiCursor); StopMarquee(); PenMode(patXor); PenPat(&theMarquee.pats[theMarquee.index]); FrameRect(&theMarquee.bounds); PaintRect(&theMarquee.handle); wasPt = start; while (WaitMouseUp()) { GetMouse(&newPt); if (DeltaPoint(wasPt, newPt)) { switch (theMarquee.direction) { case kAbove: deltaH = 0; deltaV = newPt.v - wasPt.v; *dragged -= deltaV; if (*dragged <= 0) { deltaV += *dragged; *dragged = 0; } DeltaCoordinateD(*dragged); break; case kToRight: deltaH = newPt.h - wasPt.h; deltaV = 0; *dragged += deltaH; if (*dragged <= 0) { deltaH -= *dragged; *dragged = 0; } DeltaCoordinateD(*dragged); break; case kBelow: deltaH = 0; deltaV = newPt.v - wasPt.v; *dragged += deltaV; if (*dragged <= 0) { deltaV -= *dragged; *dragged = 0; } DeltaCoordinateD(*dragged); break; case kToLeft: deltaH = newPt.h - wasPt.h; deltaV = 0; *dragged -= deltaH; if (*dragged <= 0) { deltaH += *dragged; *dragged = 0; } DeltaCoordinateD(*dragged); break; } PaintRect(&theMarquee.handle); QOffsetRect(&theMarquee.handle, deltaH, deltaV); PaintRect(&theMarquee.handle); wasPt = newPt; } } FrameRect(&theMarquee.bounds); PaintRect(&theMarquee.handle); PenNormal(); InitCursor(); } //-------------------------------------------------------------- DragMarqueeCorner void DragMarqueeCorner (Point start, short *hDragged, short *vDragged, Boolean isTop) { Point wasPt, newPt; short deltaH, deltaV; SetCursor(&diagCursor); StopMarquee(); PenMode(patXor); PenPat(&theMarquee.pats[theMarquee.index]); FrameRect(&theMarquee.bounds); PaintRect(&theMarquee.handle); wasPt = start; while (WaitMouseUp()) { GetMouse(&newPt); if (DeltaPoint(wasPt, newPt)) { deltaH = newPt.h - wasPt.h; if (isTop) deltaV = wasPt.v - newPt.v; else deltaV = newPt.v - wasPt.v; *hDragged += deltaH; if (*hDragged <= 0) { deltaH -= *hDragged; *hDragged = 0; } *vDragged += deltaV; if (*vDragged <= 0) { deltaV -= *vDragged; *vDragged = 0; } FrameRect(&theMarquee.bounds); PaintRect(&theMarquee.handle); if (isTop) { QOffsetRect(&theMarquee.handle, deltaH, -deltaV); theMarquee.bounds.right += deltaH; theMarquee.bounds.top -= deltaV; } else { QOffsetRect(&theMarquee.handle, deltaH, deltaV); theMarquee.bounds.right += deltaH; theMarquee.bounds.bottom += deltaV; } FrameRect(&theMarquee.bounds); PaintRect(&theMarquee.handle); wasPt = newPt; } } FrameRect(&theMarquee.bounds); PaintRect(&theMarquee.handle); PenNormal(); InitCursor(); } //-------------------------------------------------------------- MarqueeHasHandles Boolean MarqueeHasHandles (short *direction, short *dist) { if (theMarquee.handled) { *direction = theMarquee.direction; *dist = theMarquee.dist; return (true); } else { *direction = 0; *dist = 0; return (false); } } //-------------------------------------------------------------- PtInMarqueeHandle Boolean PtInMarqueeHandle (Point where) { return (PtInRect(where, &theMarquee.handle)); } //-------------------------------------------------------------- DrawGliderMarquee void DrawGliderMarquee (void) { CopyBits((BitMap *)*GetGWorldPixMap(blowerMaskMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &leftStartGliderSrc, &marqueeGliderRect, srcXor, nil); } //-------------------------------------------------------------- SetMarqueeGliderCenter void SetMarqueeGliderRect (short h, short v) { marqueeGliderRect = leftStartGliderSrc; ZeroRectCorner(&marqueeGliderRect); QOffsetRect(&marqueeGliderRect, h - kHalfGliderWide, v - kGliderHigh); DrawGliderMarquee(); gliderMarqueeUp = true; } //-------------------------------------------------------------- DrawMarquee void DrawMarquee (void) { FrameRect(&theMarquee.bounds); if (theMarquee.handled) { PaintRect(&theMarquee.handle); switch (theMarquee.direction) { case kAbove: MoveTo(theMarquee.handle.left + (kHandleSideLong / 2), theMarquee.handle.bottom); LineTo(theMarquee.handle.left + (kHandleSideLong / 2), theMarquee.bounds.top - 1); break; case kToRight: MoveTo(theMarquee.handle.left, theMarquee.handle.top + (kHandleSideLong / 2)); LineTo(theMarquee.bounds.right, theMarquee.handle.top + (kHandleSideLong / 2)); break; case kBelow: MoveTo(theMarquee.handle.left + (kHandleSideLong / 2), theMarquee.handle.top - 1); LineTo(theMarquee.handle.left + (kHandleSideLong / 2), theMarquee.bounds.bottom); break; case kToLeft: MoveTo(theMarquee.handle.right, theMarquee.handle.top + (kHandleSideLong / 2)); LineTo(theMarquee.bounds.left, theMarquee.handle.top + (kHandleSideLong / 2)); break; } } if (gliderMarqueeUp) DrawGliderMarquee(); } //-------------------------------------------------------------- InitMarquee void InitMarquee (void) { short i; for (i = 0; i < kNumMarqueePats; i++) GetIndPattern(&theMarquee.pats[i], kMarqueePatListID, i + 1); theMarquee.index = 0; theMarquee.active = false; theMarquee.paused = false; theMarquee.handled = false; gliderMarqueeUp = false; } \ No newline at end of file diff --git a/Sources/Menu.c b/Sources/Menu.c deleted file mode 100755 index 5b77619..0000000 --- a/Sources/Menu.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Menu.c //---------------------------------------------------------------------------- //============================================================================ //#include #include #include #include "DialogUtils.h" #include "Externs.h" #include "House.h" #include "ObjectEdit.h" #define kSheWantsNewGame 1 #define kSheWantsResumeGame 2 void UpdateMenusEditMode (void); void UpdateMenusNonEditMode (void); void UpdateMenusHouseOpen (void); void UpdateMenusHouseClosed (void); void UpdateResumeDialog (DialogPtr); pascal Boolean ResumeFilter (DialogPtr, EventRecord *, short *); short QueryResumeGame (void); void HeyYourPissingAHighScore (void); MenuHandle appleMenu, gameMenu, optionsMenu, houseMenu; Boolean menusUp, resumedSavedGame; extern long incrementModeTime; extern short demoHouseIndex, wasHouseVersion; extern short splashOriginH, splashOriginV, numberRooms; extern Boolean quitting, noRoomAtAll, twoPlayerGame; extern Boolean isMapOpen, isToolsOpen, isPlayMusicIdle; extern Boolean isCoordOpen, failedMusic, splashDrawn; extern Boolean houseOpen; //============================================================== Functions //-------------------------------------------------------------- UpdateMenusEditMode // Sets the menus to reflect that user is in edit mode. void UpdateMenusEditMode (void) { DisableMenuItem(gameMenu, iNewGame); DisableMenuItem(gameMenu, iTwoPlayer); DisableMenuItem(gameMenu, iOpenSavedGame); DisableMenuItem(optionsMenu, iHighScores); DisableMenuItem(optionsMenu, iHelp); CheckMenuItem(optionsMenu, iEditor, true); } //-------------------------------------------------------------- UpdateMenusNonEditMode // Sets the menus to reflect that user is NOT in edit mode. void UpdateMenusNonEditMode (void) { if ((noRoomAtAll) || (!houseOpen) || (numberRooms <= 0)) { DisableMenuItem(gameMenu, iNewGame); DisableMenuItem(gameMenu, iTwoPlayer); DisableMenuItem(gameMenu, iOpenSavedGame); if (houseOpen) { EnableMenuItem(gameMenu, iLoadHouse); EnableMenuItem(optionsMenu, iHighScores); } else { DisableMenuItem(gameMenu, iLoadHouse); DisableMenuItem(optionsMenu, iHighScores); } } else { EnableMenuItem(gameMenu, iNewGame); EnableMenuItem(gameMenu, iTwoPlayer); EnableMenuItem(gameMenu, iOpenSavedGame); EnableMenuItem(gameMenu, iLoadHouse); EnableMenuItem(optionsMenu, iHighScores); } if (demoHouseIndex == -1) DisableMenuItem(optionsMenu, iHelp); else EnableMenuItem(optionsMenu, iHelp); CheckMenuItem(optionsMenu, iEditor, false); } //-------------------------------------------------------------- UpdateMenusHouseOpen // Sets the menus to reflect that a house is currently open. void UpdateMenusHouseOpen (void) { EnableMenuItem(gameMenu, iLoadHouse); if ((fileDirty) && (houseUnlocked)) EnableMenuItem(houseMenu, iSave); else DisableMenuItem(houseMenu, iSave); if (houseUnlocked) { // EnableMenuItem(houseMenu, iSaveAs); EnableMenuItem(houseMenu, iHouse); } else { // DisableMenuItem(houseMenu, iSaveAs); DisableMenuItem(houseMenu, iHouse); } if ((noRoomAtAll) || (!houseUnlocked)) DisableMenuItem(houseMenu, iRoom); else EnableMenuItem(houseMenu, iRoom); if ((objActive == kNoObjectSelected) || (!houseUnlocked)) { DisableMenuItem(houseMenu, iObject); DisableMenuItem(houseMenu, iBringForward); DisableMenuItem(houseMenu, iSendBack); } else { EnableMenuItem(houseMenu, iObject); if ((objActive == kInitialGliderSelected) || (objActive == kLeftGliderSelected) || (objActive == kRightGliderSelected)) { DisableMenuItem(houseMenu, iBringForward); DisableMenuItem(houseMenu, iSendBack); } else { EnableMenuItem(houseMenu, iBringForward); EnableMenuItem(houseMenu, iSendBack); } } } //-------------------------------------------------------------- UpdateMenusHouseClosed // Sets the menus to reflect that a house is NOT currently open. void UpdateMenusHouseClosed (void) { DisableMenuItem(gameMenu, iLoadHouse); DisableMenuItem(houseMenu, iSave); // DisableMenuItem(houseMenu, iSaveAs); DisableMenuItem(houseMenu, iHouse); DisableMenuItem(houseMenu, iRoom); DisableMenuItem(houseMenu, iObject); DisableMenuItem(houseMenu, iCut); DisableMenuItem(houseMenu, iCopy); DisableMenuItem(houseMenu, iPaste); DisableMenuItem(houseMenu, iClear); DisableMenuItem(houseMenu, iDuplicate); } //-------------------------------------------------------------- UpdateClipboardMenus // Set the Cut/Copy/Paste menus to reflect if we have data in theÉ // Mac's "clipboard" or not. void UpdateClipboardMenus (void) { Str255 title; if (!houseOpen) return; if (houseUnlocked) { if (objActive > kNoObjectSelected) { GetLocalizedString(36, title); SetMenuItemText(houseMenu, iCut, title); GetLocalizedString(37, title); SetMenuItemText(houseMenu, iCopy, title); GetLocalizedString(38, title); SetMenuItemText(houseMenu, iClear, title); EnableMenuItem(houseMenu, iDuplicate); } else { GetLocalizedString(39, title); SetMenuItemText(houseMenu, iCut, title); GetLocalizedString(40, title); SetMenuItemText(houseMenu, iCopy, title); GetLocalizedString(41, title); SetMenuItemText(houseMenu, iClear, title); DisableMenuItem(houseMenu, iDuplicate); } EnableMenuItem(houseMenu, iCut); EnableMenuItem(houseMenu, iCopy); // if (hasScrap) // { // EnableMenuItem(houseMenu, iPaste); // if (scrapIsARoom) // { // GetLocalizedString(42, title); // SetMenuItemText(houseMenu, iPaste, title); // } // else // { // GetLocalizedString(43, title); // SetMenuItemText(houseMenu, iPaste, title); // } // } // else { DisableMenuItem(houseMenu, iPaste); GetLocalizedString(44, title); SetMenuItemText(houseMenu, iPaste, title); } EnableMenuItem(houseMenu, iClear); EnableMenuItem(houseMenu, iGoToRoom); EnableMenuItem(houseMenu, iMapWindow); EnableMenuItem(houseMenu, iObjectWindow); EnableMenuItem(houseMenu, iCoordinateWindow); } else { DisableMenuItem(houseMenu, iCut); DisableMenuItem(houseMenu, iCopy); DisableMenuItem(houseMenu, iPaste); DisableMenuItem(houseMenu, iClear); DisableMenuItem(houseMenu, iDuplicate); DisableMenuItem(houseMenu, iGoToRoom); DisableMenuItem(houseMenu, iMapWindow); DisableMenuItem(houseMenu, iObjectWindow); DisableMenuItem(houseMenu, iCoordinateWindow); } } //-------------------------------------------------------------- UpdateMenus // Called whenever a significant change to the environment has takenÉ // place and some of the menu states may have changes (for example,É // a menui was grayed out before becuase it wasn't an option - nowÉ // perhaps the situation has changed and we want the menu to be "usable"). void UpdateMenus (Boolean newMode) { if (!menusUp) return; if (newMode) { if (theMode == kEditMode) InsertMenu(houseMenu, 0); else DeleteMenu(kHouseMenuID); } if (theMode == kEditMode) { UpdateMenusEditMode(); if (houseOpen) { UpdateMenusHouseOpen(); UpdateClipboardMenus(); } else UpdateMenusHouseClosed(); UpdateLinkControl(); } else UpdateMenusNonEditMode(); DrawMenuBar(); } //-------------------------------------------------------------- DoAppleMenu // Handle the Apple menu (About box and desk accessories). void DoAppleMenu (short theItem) { // Str255 daName; // GrafPtr wasPort; // short daNumber; switch (theItem) { case iAbout: DoAbout(); break; default: // GetMenuItemText(appleMenu, theItem, daName); // GetPort(&wasPort); // daNumber = OpenDeskAccesory(daName); // SetPort((GrafPtr)wasPort); break; } } //-------------------------------------------------------------- DoGameMenu // Handle the user selecting an item from the Game menu. void DoGameMenu (short theItem) { switch (theItem) { case iNewGame: twoPlayerGame = false; resumedSavedGame = false; NewGame(kNewGameMode); break; case iTwoPlayer: twoPlayerGame = true; resumedSavedGame = false; NewGame(kNewGameMode); break; case iOpenSavedGame: resumedSavedGame = true; HeyYourPissingAHighScore(); if (OpenSavedGame()) { twoPlayerGame = false; NewGame(kResumeGameMode); } break; case iLoadHouse: #ifdef COMPILEDEMO DoNotInDemo(); #else if (splashDrawn) { DoLoadHouse(); OpenCloseEditWindows(); UpdateMenus(false); incrementModeTime = TickCount() + kIdleSplashTicks; if ((theMode == kSplashMode) || (theMode == kPlayMode)) { Rect updateRect; SetRect(&updateRect, splashOriginH + 474, splashOriginV + 304, splashOriginH + 474 + 166, splashOriginV + 304 + 12); InvalWindowRect(mainWindow, &updateRect); } } #endif break; case iQuit: #ifndef COMPILEDEMO quitting = true; if (!QuerySaveChanges()) quitting = false; #else quitting = true; #endif break; default: break; } } //-------------------------------------------------------------- DoOptionsMenu // Handle the user selecting an item from the Options menu. void DoOptionsMenu (short theItem) { #ifndef COMPILEDEMO OSErr theErr; #endif switch (theItem) { case iEditor: #ifdef COMPILEDEMO DoNotInDemo(); #else if (theMode == kEditMode) // switching to splash mode { if (fileDirty) SortHouseObjects(); if (!QuerySaveChanges()) break; theMode = kSplashMode; CloseMapWindow(); CloseToolsWindow(); CloseCoordWindow(); CloseLinkWindow(); DeselectObject(); StopMarquee(); if (isPlayMusicIdle) { theErr = StartMusic(); if (theErr != noErr) { YellowAlert(kYellowNoMusic, theErr); failedMusic = true; } } CloseMainWindow(); OpenMainWindow(); incrementModeTime = TickCount() + kIdleSplashTicks; } else if (theMode == kSplashMode) // switching to edit mode { theMode = kEditMode; StopTheMusic(); CloseMainWindow(); OpenMainWindow(); OpenCloseEditWindows(); } InitCursor(); UpdateMenus(true); #endif break; case iHighScores: DoHighScores(); incrementModeTime = TickCount() + kIdleSplashTicks; break; case iPrefs: DoSettingsMain(); incrementModeTime = TickCount() + kIdleSplashTicks; break; case iHelp: DoDemoGame(); break; } } //-------------------------------------------------------------- DoHouseMenu // Handle the user selecting an item from the House menu (only in Edit mode). void DoHouseMenu (short theItem) { #ifndef COMPILEDEMO short direction, dist; Boolean whoCares; switch (theItem) { case iNewHouse: if (CreateNewHouse()) { whoCares = InitializeEmptyHouse(); OpenCloseEditWindows(); } break; case iSave: DeselectObject(); if (fileDirty) SortHouseObjects(); if ((fileDirty) && (houseUnlocked)) { // SaveGame(false); if (wasHouseVersion < kHouseVersion) ConvertHouseVer1To2(); wasHouseVersion = kHouseVersion; whoCares = WriteHouse(true); ForceThisRoom(thisRoomNumber); ReadyBackground(thisRoom->background, thisRoom->tiles); GetThisRoomsObjRects(); DrawThisRoomsObjects(); } break; // case iSaveAs: // whoCares = SaveHouseAs(); // break; case iHouse: if (houseUnlocked) DoHouseInfo(); break; case iRoom: if (houseUnlocked) DoRoomInfo(); break; case iObject: if (houseUnlocked) { DoObjectInfo(); if (ObjectHasHandle(&direction, &dist)) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else StartMarquee(&roomObjectRects[objActive]); } break; case iCut: if (houseUnlocked) { if (objActive > kNoObjectSelected) { // PutObjectScrap(); DeleteObject(); } else { // PutRoomScrap(); DeleteRoom(false); } UpdateClipboardMenus(); } break; case iCopy: if (houseUnlocked) { // if (objActive > kNoObjectSelected) // PutObjectScrap(); // else // PutRoomScrap(); UpdateClipboardMenus(); } break; case iPaste: if (houseUnlocked) { /* if (scrapIsARoom) GetRoomScrap(); else GetObjectScrap(); UpdateClipboardMenus(); */ } break; case iClear: if (houseUnlocked) { if (objActive > kNoObjectSelected) DeleteObject(); else DeleteRoom(false); UpdateClipboardMenus(); } break; case iDuplicate: if (houseUnlocked) DuplicateObject(); break; case iBringForward: if (houseUnlocked) BringSendFrontBack(true); break; case iSendBack: if (houseUnlocked) BringSendFrontBack(false); break; case iGoToRoom: if (houseUnlocked) DoGoToDialog(); break; case iMapWindow: if (houseUnlocked) ToggleMapWindow(); break; case iObjectWindow: if (houseUnlocked) ToggleToolsWindow(); break; case iCoordinateWindow: if (houseUnlocked) ToggleCoordinateWindow(); break; } #endif } //-------------------------------------------------------------- DoMenuChoice // Users has selected a menu item - determin which menu was selectedÉ // and call the appropriate function above. void DoMenuChoice (long menuChoice) { short theMenu, theItem; if (menuChoice == 0) return; theMenu = HiWord(menuChoice); theItem = LoWord(menuChoice); switch (theMenu) { case kAppleMenuID: DoAppleMenu(theItem); break; case kGameMenuID: DoGameMenu(theItem); break; case kOptionsMenuID: DoOptionsMenu(theItem); break; case kHouseMenuID: DoHouseMenu(theItem); break; } HiliteMenu(0); } //-------------------------------------------------------------- UpdateMapCheckmark // Checks or unchecks the Map Window item (to indicate if open or not). void UpdateMapCheckmark (Boolean checkIt) { if (!menusUp) return; CheckMenuItem(houseMenu, iMapWindow, checkIt); } //-------------------------------------------------------------- UpdateToolsCheckmark // Checks or unchecks the Tools Window item (to indicate if open or not). void UpdateToolsCheckmark (Boolean checkIt) { if (!menusUp) return; CheckMenuItem(houseMenu, iObjectWindow, checkIt); } //-------------------------------------------------------------- UpdateCoordinateCheckmark // Checks or unchecks the Coordinates Window item (to indicate if open or not). void UpdateCoordinateCheckmark (Boolean checkIt) { if (!menusUp) return; CheckMenuItem(houseMenu, iCoordinateWindow, checkIt); } //-------------------------------------------------------------- UpdateResumeDialog // Update function for Resume dialog (below). void UpdateResumeDialog (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); } //-------------------------------------------------------------- ResumeFilter // Dialog filter for the Resume dialog (below). pascal Boolean ResumeFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; default: return(false); } break; case updateEvt: if ((WindowPtr)event->message == GetDialogWindow(dial)) { SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateResumeDialog(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; } return(false); break; default: return(false); break; } } //-------------------------------------------------------------- QueryResumeGame // Dialog that asks user whether they want to resume a saved game orÉ // begin a new one. It displays a little info on the state of theirÉ // saved game (number of glider left, points, etc.). short QueryResumeGame (void) { #define kResumeGameDial 1025 DialogPtr theDial; houseType *thisHousePtr; Str255 scoreStr, glidStr; long hadPoints; short hitWhat, hadGliders; char wasState; Boolean leaving; ModalFilterUPP resumeFilterUPP; resumeFilterUPP = NewModalFilterUPP(ResumeFilter); wasState = HGetState((Handle)thisHouse); // get score & num. gliders HLock((Handle)thisHouse); thisHousePtr = *thisHouse; hadPoints = thisHousePtr->savedGame.score; hadGliders = thisHousePtr->savedGame.numGliders; HSetState((Handle)thisHouse, wasState); NumToString(hadPoints, scoreStr); // param text strings NumToString((long)hadGliders, glidStr); if (hadGliders == 1) ParamText(glidStr, "\p", scoreStr, "\p"); else ParamText(glidStr, "\ps", scoreStr, "\p"); // CenterDialog(kResumeGameDial); theDial = GetNewDialog(kResumeGameDial, nil, kPutInFront); if (theDial == nil) RedAlert(kErrDialogDidntLoad); SetPort((GrafPtr)theDial); ShowWindow(GetDialogWindow(theDial)); DrawDefaultButton(theDial); leaving = false; while (!leaving) { ModalDialog(resumeFilterUPP, &hitWhat); if ((hitWhat == kSheWantsNewGame) || (hitWhat == kSheWantsResumeGame)) { leaving = true; } } DisposeDialog(theDial); DisposeModalFilterUPP(resumeFilterUPP); return (hitWhat); } //-------------------------------------------------------------- DoNotInDemo // Only compiled for "demo version" of Glider PRO. It brings up aÉ // dialog that says, essentially, "x" feature is not implemented inÉ // the demo version. #ifdef COMPILEDEMO void DoNotInDemo (void) { #define kNotInDemoAlert 1037 short whoCares; // CenterAlert(kNotInDemoAlert); whoCares = Alert(kNotInDemoAlert, nil); } #endif //-------------------------------------------------------------- HeyYourPissingAHighScore void HeyYourPissingAHighScore (void) { #define kNoHighScoreAlert 1046 short whoCares; // CenterAlert(kNoHighScoreAlert); whoCares = Alert(kNoHighScoreAlert, nil); } //-------------------------------------------------------------- OpenCloseEditWindows // Function goes through and either closes or opens all the variousÉ // editing windows (in response to switching in or out of editor). void OpenCloseEditWindows (void) { if (theMode == kEditMode) { if (houseUnlocked) { if (isMapOpen) OpenMapWindow(); if (isToolsOpen) OpenToolsWindow(); if (isCoordOpen) OpenCoordWindow(); } else { CloseMapWindow(); CloseToolsWindow(); CloseCoordWindow(); } } } \ No newline at end of file diff --git a/Sources/Modes.c b/Sources/Modes.c deleted file mode 100755 index df9a0e8..0000000 --- a/Sources/Modes.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Modes.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "RectUtils.h" short saidFollow; extern Rect gliderSrc[]; extern Rect transRect; extern short fadeInSequence[], linkedToWhat; extern short rightClip, leftClip, transRoom; extern Boolean hasMirror, shadowVisible, firstPlayer, twoPlayerGame; extern Boolean onePlayerLeft, playerDead; //============================================================== Functions //-------------------------------------------------------------- StartGliderFadingIn void StartGliderFadingIn (gliderPtr thisGlider) { if (foilTotal <= 0) showFoil = false; thisGlider->mode = kGliderFadingIn; thisGlider->whole = thisGlider->dest; thisGlider->frame = 0; thisGlider->dontDraw = false; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; } } //-------------------------------------------------------------- StartGliderTransportingIn void StartGliderTransportingIn (gliderPtr thisGlider) { if (foilTotal <= 0) showFoil = false; thisGlider->mode = kGliderTransportingIn; thisGlider->whole = thisGlider->dest; thisGlider->frame = 0; thisGlider->dontDraw = false; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; } } //-------------------------------------------------------------- StartGliderFadingOut void StartGliderFadingOut (gliderPtr thisGlider) { Rect tempBounds; if (thisGlider->mode == kGliderFadingOut) return; if (thisGlider->mode == kGliderGoingFoil) DeckGliderInFoil(thisGlider); else if (thisGlider->mode == kGliderLosingFoil) RemoveFoilFromGlider(thisGlider); if (RectTall(&thisGlider->dest) > kGliderHigh) { tempBounds = thisGlider->dest; QOffsetRect(&tempBounds, playOriginH, playOriginV); AddRectToWorkRects(&tempBounds); if (hasMirror) { tempBounds = thisGlider->dest; QOffsetRect(&tempBounds, playOriginH - 20, playOriginV - 16); AddRectToWorkRects(&tempBounds); } thisGlider->dest.right = thisGlider->dest.left + kGliderWide; thisGlider->dest.top = thisGlider->dest.bottom - kGliderHigh; } thisGlider->mode = kGliderFadingOut; thisGlider->whole = thisGlider->dest; thisGlider->frame = kLastFadeSequence - 1; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; } } //-------------------------------------------------------------- StartGliderGoingUpStairs void StartGliderGoingUpStairs (gliderPtr thisGlider) { if (thisGlider->mode == kGliderGoingFoil) DeckGliderInFoil(thisGlider); else if (thisGlider->mode == kGliderLosingFoil) RemoveFoilFromGlider(thisGlider); if (thisGlider->mode == kGliderBurning) thisGlider->frame = kWasBurning; else thisGlider->frame = 0; thisGlider->mode = kGliderGoingUp; } //-------------------------------------------------------------- StartGliderGoingDownStairs void StartGliderGoingDownStairs (gliderPtr thisGlider) { if (thisGlider->mode == kGliderGoingFoil) DeckGliderInFoil(thisGlider); else if (thisGlider->mode == kGliderLosingFoil) RemoveFoilFromGlider(thisGlider); if (thisGlider->mode == kGliderBurning) thisGlider->frame = kWasBurning; else thisGlider->frame = 0; thisGlider->mode = kGliderGoingDown; rightClip = GetUpStairsRightEdge(); } //-------------------------------------------------------------- StartGliderMailingIn void StartGliderMailingIn (gliderPtr thisGlider, Rect *bounds, hotPtr who) { short topSought, whoLinked; Byte objLinked; char wasState; PlayPrioritySound(kTransOutSound, kTransOutPriority); whoLinked = who->who; transRoom = masterObjects[whoLinked].roomLink; objLinked = masterObjects[whoLinked].objectLink; linkedToWhat = WhatAreWeLinkedTo(transRoom, objLinked); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); GetObjectRect(&(*thisHouse)->rooms[transRoom].objects[objLinked], &transRect); HSetState((Handle)thisHouse, wasState); thisGlider->frame = 0; thisGlider->clip = *bounds; topSought = bounds->bottom - RectTall(&thisGlider->dest); thisGlider->clip.top = topSought; } //-------------------------------------------------------------- StartGliderMailingOut void StartGliderMailingOut (gliderPtr thisGlider) { if (thisGlider->mode == kGliderGoingFoil) DeckGliderInFoil(thisGlider); else if (thisGlider->mode == kGliderLosingFoil) RemoveFoilFromGlider(thisGlider); if (linkedToWhat == kLinkedToLeftMailbox) { thisGlider->facing = kFaceLeft; thisGlider->mode = kGliderMailOutLeft; thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } else { thisGlider->facing = kFaceRight; thisGlider->mode = kGliderMailOutRight; thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; } thisGlider->hVel = 0; thisGlider->vVel = 0; thisGlider->hDesiredVel = 0; thisGlider->vDesiredVel = 0; thisGlider->tipped = false; thisGlider->dontDraw = false; } //-------------------------------------------------------------- StartGliderDuctingDown void StartGliderDuctingDown (gliderPtr thisGlider, Rect *bounds, hotPtr who) { short leftSought, whoLinked; Byte objLinked; char wasState; PlayPrioritySound(kTransOutSound, kTransOutPriority); if (thisGlider->mode == kGliderGoingFoil) DeckGliderInFoil(thisGlider); else if (thisGlider->mode == kGliderLosingFoil) RemoveFoilFromGlider(thisGlider); whoLinked = who->who; transRoom = masterObjects[whoLinked].roomLink; objLinked = masterObjects[whoLinked].objectLink; linkedToWhat = WhatAreWeLinkedTo(transRoom, objLinked); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); GetObjectRect(&(*thisHouse)->rooms[transRoom].objects[objLinked], &transRect); HSetState((Handle)thisHouse, wasState); thisGlider->frame = 0; thisGlider->clip = *bounds; leftSought = bounds->left + ((RectWide(bounds) - kGliderWide) / 2); thisGlider->clip.left = leftSought; thisGlider->mode = kGliderDuctingDown; } //-------------------------------------------------------------- StartGliderDuctingUp void StartGliderDuctingUp (gliderPtr thisGlider, Rect *bounds, hotPtr who) { short leftSought, whoLinked; Byte objLinked; char wasState; PlayPrioritySound(kTransOutSound, kTransOutPriority); if (thisGlider->mode == kGliderGoingFoil) DeckGliderInFoil(thisGlider); else if (thisGlider->mode == kGliderLosingFoil) RemoveFoilFromGlider(thisGlider); whoLinked = who->who; transRoom = masterObjects[whoLinked].roomLink; objLinked = masterObjects[whoLinked].objectLink; linkedToWhat = WhatAreWeLinkedTo(transRoom, objLinked); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); GetObjectRect(&(*thisHouse)->rooms[transRoom].objects[objLinked], &transRect); HSetState((Handle)thisHouse, wasState); thisGlider->frame = 0; thisGlider->clip = *bounds; leftSought = bounds->left + ((RectWide(bounds) - kGliderWide) / 2); thisGlider->clip.left = leftSought; thisGlider->mode = kGliderDuctingUp; } //-------------------------------------------------------------- StartGliderDuctingIn void StartGliderDuctingIn (gliderPtr thisGlider) { thisGlider->mode = kGliderDuctingIn; thisGlider->whole = thisGlider->dest; thisGlider->dontDraw = false; } //-------------------------------------------------------------- StartGliderTransporting void StartGliderTransporting (gliderPtr thisGlider, hotPtr who) { short whoLinked; Byte objLinked; char wasState; PlayPrioritySound(kTransOutSound, kTransOutPriority); if (thisGlider->mode == kGliderGoingFoil) DeckGliderInFoil(thisGlider); else if (thisGlider->mode == kGliderLosingFoil) RemoveFoilFromGlider(thisGlider); whoLinked = who->who; transRoom = masterObjects[whoLinked].roomLink; objLinked = masterObjects[whoLinked].objectLink; linkedToWhat = WhatAreWeLinkedTo(transRoom, objLinked); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); GetObjectRect(&(*thisHouse)->rooms[transRoom].objects[objLinked], &transRect); HSetState((Handle)thisHouse, wasState); thisGlider->dest.right = thisGlider->dest.left + kGliderWide; thisGlider->dest.bottom = thisGlider->dest.top + kGliderHigh; thisGlider->destShadow.right = thisGlider->destShadow.left + kGliderWide; thisGlider->destShadow.bottom = thisGlider->destShadow.top + kShadowHigh; thisGlider->mode = kGliderTransporting; thisGlider->whole = thisGlider->dest; thisGlider->frame = kLastFadeSequence - 1; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; } } //-------------------------------------------------------------- FlagGliderNormal void FlagGliderNormal (gliderPtr thisGlider) { thisGlider->dest.right = thisGlider->dest.left + kGliderWide; thisGlider->dest.bottom = thisGlider->dest.top + kGliderHigh; thisGlider->destShadow.right = thisGlider->destShadow.left + kGliderWide; thisGlider->destShadow.bottom = thisGlider->destShadow.top + kShadowHigh; thisGlider->mode = kGliderNormal; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } else { thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; } thisGlider->hVel = 0; thisGlider->vVel = 0; thisGlider->hDesiredVel = 0; thisGlider->vDesiredVel = 0; thisGlider->tipped = false; thisGlider->ignoreLeft = false; thisGlider->ignoreRight = false; thisGlider->ignoreGround = false; thisGlider->dontDraw = false; thisGlider->frame = 0; shadowVisible = IsShadowVisible(); } //-------------------------------------------------------------- FlagGliderShredding void FlagGliderShredding (gliderPtr thisGlider, Rect *bounds) { PlayPrioritySound(kCaughtFireSound, kCaughtFirePriority); thisGlider->dest.left = bounds->left + 36; thisGlider->dest.right = thisGlider->dest.left + kGliderWide; thisGlider->dest.bottom = thisGlider->dest.top + kGliderHigh; if (thisGlider->dest.left > thisGlider->whole.left) { thisGlider->whole.right = thisGlider->dest.right; thisGlider->wholeShadow.right = thisGlider->dest.right; } else { thisGlider->whole.left = thisGlider->dest.left; thisGlider->wholeShadow.left = thisGlider->dest.left; } thisGlider->destShadow.left = thisGlider->dest.left; thisGlider->destShadow.right = thisGlider->destShadow.left + kGliderWide; thisGlider->destShadow.bottom = thisGlider->destShadow.top + kShadowHigh; thisGlider->mode = kGliderShredding; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } else { thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; } thisGlider->hVel = 0; thisGlider->vVel = 0; thisGlider->hDesiredVel = 0; thisGlider->vDesiredVel = 0; thisGlider->frame = bounds->bottom - 3; thisGlider->tipped = false; } //-------------------------------------------------------------- FlagGliderBurning void FlagGliderBurning (gliderPtr thisGlider) { #define kFramesToBurn 60 PlayPrioritySound(kCaughtFireSound, kCaughtFirePriority); thisGlider->dest.right = thisGlider->dest.left + kGliderWide; thisGlider->dest.top = thisGlider->dest.bottom - kGliderBurningHigh; thisGlider->destShadow.right = thisGlider->destShadow.left + kGliderWide; thisGlider->destShadow.bottom = thisGlider->destShadow.top + kShadowHigh; thisGlider->mode = kGliderBurning; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[25]; thisGlider->mask = gliderSrc[25]; } else { thisGlider->src = gliderSrc[21]; thisGlider->mask = gliderSrc[21]; } thisGlider->hVel = 0; thisGlider->vVel = 0; thisGlider->hDesiredVel = 0; thisGlider->vDesiredVel = 0; thisGlider->frame = 0; thisGlider->wasMode = kFramesToBurn; // used to count down burning thisGlider->tipped = false; } //-------------------------------------------------------------- FlagGliderFaceLeft void FlagGliderFaceLeft (gliderPtr thisGlider) { thisGlider->mode = kGliderFaceLeft; thisGlider->frame = kLastAboutFaceFrame; thisGlider->src = gliderSrc[kLastAboutFaceFrame]; thisGlider->mask = gliderSrc[kLastAboutFaceFrame]; } //-------------------------------------------------------------- FlagGliderFaceRight void FlagGliderFaceRight (gliderPtr thisGlider) { thisGlider->mode = kGliderFaceRight; thisGlider->frame = kFirstAboutFaceFrame; thisGlider->src = gliderSrc[kFirstAboutFaceFrame]; thisGlider->mask = gliderSrc[kFirstAboutFaceFrame]; } //-------------------------------------------------------------- FlagGliderInLimbo void FlagGliderInLimbo (gliderPtr thisGlider, Boolean sayIt) { thisGlider->wasMode = thisGlider->mode; thisGlider->mode = kGliderInLimbo; if ((sayIt) && (saidFollow < 3)) { PlayPrioritySound(kFollowSound, kFollowPriority); saidFollow++; } firstPlayer = thisGlider->which; } //-------------------------------------------------------------- UndoGliderLimbo void UndoGliderLimbo (gliderPtr thisGlider) { if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) return; if (thisGlider->mode == kGliderInLimbo) thisGlider->mode = thisGlider->wasMode; thisGlider->dontDraw = false; } //-------------------------------------------------------------- ToggleGliderFacing void ToggleGliderFacing (gliderPtr thisGlider) { if (thisGlider->mode != kGliderNormal) return; if (thisGlider->facing == kFaceLeft) FlagGliderFaceRight(thisGlider); else FlagGliderFaceLeft(thisGlider); } //-------------------------------------------------------------- InsureGliderFacingRight void InsureGliderFacingRight (gliderPtr thisGlider) { if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) return; if ((thisGlider->facing == kFaceLeft) && (thisGlider->mode != kGliderBurning)) FlagGliderFaceRight(thisGlider); } //-------------------------------------------------------------- InsureGliderFacingLeft void InsureGliderFacingLeft (gliderPtr thisGlider) { if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) return; if ((thisGlider->facing == kFaceRight) && (thisGlider->mode != kGliderBurning)) FlagGliderFaceLeft(thisGlider); } //-------------------------------------------------------------- ReadyGliderForTripUpStairs void ReadyGliderForTripUpStairs (gliderPtr thisGlider) { #define kVGliderAppearsComingUp 100 if ((twoPlayerGame) && (thisGlider->which == playerDead) && (onePlayerLeft)) return; thisGlider->facing = kFaceLeft; thisGlider->mode = kGliderComingUp; thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; thisGlider->hVel = 0; thisGlider->vVel = 0; thisGlider->hDesiredVel = 0; thisGlider->vDesiredVel = 0; thisGlider->tipped = false; rightClip = GetUpStairsRightEdge(); thisGlider->dest = thisGlider->src; ZeroRectCorner(&thisGlider->dest); QOffsetRect(&thisGlider->dest, rightClip, kVGliderAppearsComingUp); thisGlider->whole = thisGlider->dest; thisGlider->destShadow.left = thisGlider->dest.left; thisGlider->destShadow.right = thisGlider->dest.right; thisGlider->wholeShadow = thisGlider->destShadow; FinishGliderUpStairs(thisGlider); } //-------------------------------------------------------------- ReadyGliderForTripDownStairs void ReadyGliderForTripDownStairs (gliderPtr thisGlider) { #define kVGliderAppearsComingDown 100 if ((twoPlayerGame) && (thisGlider->which == playerDead) && (onePlayerLeft)) return; thisGlider->facing = kFaceRight; thisGlider->mode = kGliderComingDown; thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; thisGlider->hVel = 0; thisGlider->vVel = 0; thisGlider->hDesiredVel = 0; thisGlider->vDesiredVel = 0; thisGlider->tipped = false; leftClip = GetDownStairsLeftEdge(); thisGlider->dest = thisGlider->src; ZeroRectCorner(&thisGlider->dest); QOffsetRect(&thisGlider->dest, leftClip - kGliderWide, kVGliderAppearsComingDown); thisGlider->whole = thisGlider->dest; thisGlider->destShadow.left = thisGlider->dest.left; thisGlider->destShadow.right = thisGlider->dest.right; thisGlider->wholeShadow = thisGlider->destShadow; FinishGliderDownStairs(thisGlider); } //-------------------------------------------------------------- StartGliderFoilGoing void StartGliderFoilGoing (gliderPtr thisGlider) { if ((thisGlider->mode == kGliderGoingFoil) || (thisGlider->mode == kGliderInLimbo)) return; QuickFoilRefresh(false); thisGlider->mode = kGliderGoingFoil; thisGlider->whole = thisGlider->dest; thisGlider->frame = 0; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; thisGlider->mask = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[10 - thisGlider->frame]; thisGlider->mask = gliderSrc[10 - thisGlider->frame]; } } //-------------------------------------------------------------- StartGliderFoilLosing void StartGliderFoilLosing (gliderPtr thisGlider) { if ((thisGlider->mode == kGliderLosingFoil) || (thisGlider->mode == kGliderInLimbo)) return; QuickFoilRefresh(false); PlayPrioritySound(kFizzleSound, kFizzlePriority); thisGlider->mode = kGliderLosingFoil; thisGlider->whole = thisGlider->dest; thisGlider->frame = 0; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; thisGlider->mask = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[10 - thisGlider->frame]; thisGlider->mask = gliderSrc[10 - thisGlider->frame]; } } //-------------------------------------------------------------- TagGliderIdle void TagGliderIdle (gliderPtr thisGlider) { if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) return; thisGlider->wasMode = thisGlider->mode; thisGlider->mode = kGliderIdle; thisGlider->hVel = 30; // used for 30 frame delay } \ No newline at end of file diff --git a/Sources/Music.c b/Sources/Music.c deleted file mode 100755 index da849f3..0000000 --- a/Sources/Music.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Music.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Environ.h" #include "Externs.h" #define kBaseBufferMusicID 2000 #define kMaxMusic 7 #define kLastMusicPiece 16 #define kLastGamePiece 6 pascal void MusicCallBack (SndChannelPtr, SndCommand *); OSErr LoadMusicSounds (void); OSErr DumpMusicSounds (void); OSErr OpenMusicChannel (void); OSErr CloseMusicChannel (void); SndCallBackUPP musicCallBackUPP; SndChannelPtr musicChannel; Ptr theMusicData[kMaxMusic]; short musicSoundID, musicCursor; short musicScore[kLastMusicPiece]; short gameScore[kLastGamePiece]; short musicMode; Boolean isMusicOn, isPlayMusicIdle, isPlayMusicGame; Boolean failedMusic, dontLoadMusic; extern Boolean isSoundOn; //============================================================== Functions //-------------------------------------------------------------- StartMusic OSErr StartMusic (void) { SndCommand theCommand; OSErr theErr; short soundVolume; theErr = noErr; if (dontLoadMusic) return(theErr); UnivGetSoundVolume(&soundVolume, thisMac.hasSM3); if ((soundVolume != 0) && (!failedMusic)) { theCommand.cmd = bufferCmd; theCommand.param1 = 0; theCommand.param2 = (long)(theMusicData[musicSoundID]); theErr = SndDoCommand(musicChannel, &theCommand, false); if (theErr != noErr) return (theErr); theCommand.cmd = 0; theCommand.param1 = 1964; theCommand.param2 = SetCurrentA5(); theErr = SndDoCommand(musicChannel, &theCommand, false); if (theErr != noErr) return (theErr); musicCursor++; if (musicCursor >= kLastMusicPiece) musicCursor = 0; musicSoundID = musicScore[musicCursor]; theCommand.cmd = bufferCmd; theCommand.param1 = 0; theCommand.param2 = (long)(theMusicData[musicSoundID]); theErr = SndDoCommand(musicChannel, &theCommand, false); if (theErr != noErr) return (theErr); theCommand.cmd = callBackCmd; theCommand.param1 = 0; theCommand.param2 = SetCurrentA5(); theErr = SndDoCommand(musicChannel, &theCommand, false); isMusicOn = true; } return (theErr); } //-------------------------------------------------------------- StopTheMusic void StopTheMusic (void) { SndCommand theCommand; OSErr theErr; if (dontLoadMusic) return; theErr = noErr; if ((isMusicOn) && (!failedMusic)) { theCommand.cmd = flushCmd; theCommand.param1 = 0; theCommand.param2 = 0L; theErr = SndDoImmediate(musicChannel, &theCommand); theCommand.cmd = quietCmd; theCommand.param1 = 0; theCommand.param2 = 0L; theErr = SndDoImmediate(musicChannel, &theCommand); isMusicOn = false; } } //-------------------------------------------------------------- ToggleMusicWhilePlaying void ToggleMusicWhilePlaying (void) { OSErr theErr; if (dontLoadMusic) return; if (isPlayMusicGame) { if (!isMusicOn) theErr = StartMusic(); } else { if (isMusicOn) StopTheMusic(); } } //-------------------------------------------------------------- SetMusicalPiece void SetMusicalMode (short newMode) { if (dontLoadMusic) return; switch (newMode) { case kKickGameScoreMode: musicCursor = 2; break; case kProdGameScoreMode: musicCursor = -1; break; default: musicMode = newMode; musicCursor = 0; break; } } //-------------------------------------------------------------- MusicCallBack pascal void MusicCallBack (SndChannelPtr theChannel, SndCommand *theCommand) { #pragma unused (theChannel) long thisA5, gameA5; OSErr theErr; // gameA5 = theCommand.param2; // thisA5 = SetA5(gameA5); switch (musicMode) { case kPlayGameScoreMode: musicCursor++; if (musicCursor >= kLastGamePiece) musicCursor = 1; musicSoundID = gameScore[musicCursor]; if (musicSoundID < 0) { musicCursor += musicSoundID; musicSoundID = gameScore[musicCursor]; } break; case kPlayWholeScoreMode: musicCursor++; if (musicCursor >= kLastMusicPiece - 1) musicCursor = 0; musicSoundID = musicScore[musicCursor]; break; default: musicSoundID = musicMode; break; } theCommand->cmd = bufferCmd; theCommand->param1 = 0; theCommand->param2 = (long)(theMusicData[musicSoundID]); theErr = SndDoCommand(musicChannel, theCommand, false); theCommand->cmd = callBackCmd; theCommand->param1 = 0; theCommand->param2 = gameA5; theErr = SndDoCommand(musicChannel, theCommand, false); thisA5 = SetA5(thisA5); } //-------------------------------------------------------------- LoadMusicSounds OSErr LoadMusicSounds (void) { Handle theSound; long soundDataSize; OSErr theErr; short i; theErr = noErr; for (i = 0; i < kMaxMusic; i++) theMusicData[i] = nil; for (i = 0; i < kMaxMusic; i++) { theSound = GetResource('snd ', i + kBaseBufferMusicID); if (theSound == nil) return (MemError()); HLock(theSound); soundDataSize = GetHandleSize(theSound) - 20L; HUnlock(theSound); theMusicData[i] = NewPtr(soundDataSize); if (theMusicData[i] == nil) return (MemError()); HLock(theSound); BlockMove((Ptr)(*theSound + 20L), theMusicData[i], soundDataSize); ReleaseResource(theSound); } return (theErr); } //-------------------------------------------------------------- DumpMusicSounds OSErr DumpMusicSounds (void) { OSErr theErr; short i; theErr = noErr; for (i = 0; i < kMaxMusic; i++) { if (theMusicData[i] != nil) DisposePtr(theMusicData[i]); theMusicData[i] = nil; } return (theErr); } //-------------------------------------------------------------- OpenMusicChannel OSErr OpenMusicChannel (void) { OSErr theErr; musicCallBackUPP = NewSndCallBackProc(MusicCallBack); theErr = noErr; if (musicChannel != nil) return (theErr); musicChannel = nil; theErr = SndNewChannel(&musicChannel, sampledSynth, initNoInterp + initMono, (SndCallBackUPP)musicCallBackUPP); return (theErr); } //-------------------------------------------------------------- CloseMusicChannel OSErr CloseMusicChannel (void) { OSErr theErr; theErr = noErr; if (musicChannel != nil) theErr = SndDisposeChannel(musicChannel, true); musicChannel = nil; DisposeSndCallBackUPP(musicCallBackUPP); return (theErr); } //-------------------------------------------------------------- InitMusic void InitMusic (void) { OSErr theErr; if (dontLoadMusic) return; musicChannel = nil; failedMusic = false; isMusicOn = false; theErr = LoadMusicSounds(); if (theErr != noErr) { YellowAlert(kYellowNoMusic, theErr); failedMusic = true; return; } theErr = OpenMusicChannel(); musicScore[0] = 0; musicScore[1] = 1; musicScore[2] = 2; musicScore[3] = 3; musicScore[4] = 4; musicScore[5] = 4; musicScore[6] = 0; musicScore[7] = 1; musicScore[8] = 2; musicScore[9] = 3; musicScore[10] = kPlayChorus; musicScore[11] = kPlayChorus; musicScore[12] = kPlayRefrainSparse1; musicScore[13] = kPlayRefrainSparse2; musicScore[14] = kPlayChorus; musicScore[15] = kPlayChorus; gameScore[0] = kPlayRefrainSparse2; gameScore[1] = kPlayRefrainSparse1; gameScore[2] = -1; gameScore[3] = kPlayRefrainSparse2; gameScore[4] = kPlayChorus; gameScore[5] = kPlayChorus; musicCursor = 0; musicSoundID = musicScore[musicCursor]; musicMode = kPlayWholeScoreMode; if (isPlayMusicIdle) { theErr = StartMusic(); if (theErr != noErr) { YellowAlert(kYellowNoMusic, theErr); failedMusic = true; } } } //-------------------------------------------------------------- KillMusic void KillMusic (void) { OSErr theErr; if (dontLoadMusic) return; theErr = DumpMusicSounds(); theErr = CloseMusicChannel(); } //-------------------------------------------------------------- MusicBytesNeeded long MusicBytesNeeded (void) { Handle theSound; long totalBytes; short i; totalBytes = 0L; SetResLoad(false); for (i = 0; i < kMaxMusic; i++) { theSound = GetResource('snd ', i + kBaseBufferMusicID); if (theSound == nil) { SetResLoad(true); return ((long)ResError()); } totalBytes += GetMaxResourceSize(theSound); // ReleaseResource(theSound); } SetResLoad(true); return totalBytes; } //-------------------------------------------------------------- TellHerNoMusic void TellHerNoMusic (void) { #define kNoMemForMusicAlert 1038 short hitWhat; // CenterAlert(kNoMemForMusicAlert); hitWhat = Alert(kNoMemForMusicAlert, nil); } \ No newline at end of file diff --git a/Sources/ObjectAdd.c b/Sources/ObjectAdd.c deleted file mode 100755 index 8c0c8a1..0000000 --- a/Sources/ObjectAdd.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // ObjectAdd.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "ObjectEdit.h" #include "RectUtils.h" #define kNoMoreObjectsAlert 1008 #define kNoMoreSpecialAlert 1028 #define kMaxSoundTriggers 1 #define kMaxStairs 1 #define kMouseholeBottom 295 #define kFireplaceBottom 297 #define kManholeSits 322 #define kGrecoVentTop 303 #define kSewerBlowerTop 292 short FindEmptyObjectSlot (void); short HowManyCandleObjects (void); short HowManyTikiObjects (void); short HowManyBBQObjects (void); short HowManyCuckooObjects (void); short HowManyBandsObjects (void); short HowManyGreaseObjects (void); short HowManyStarsObjects (void); short HowManySoundObjects (void); short HowManyUpStairsObjects (void); short HowManyDownStairsObjects (void); short HowManyShredderObjects (void); short HowManyDynamicObjects (void); void ShoutNoMoreSpecialObjects (void); short wasFlower; //============================================================== Functions //-------------------------------------------------------------- AddNewObject Boolean AddNewObject (Point where, short what, Boolean showItNow) { KeyMap theseKeys; Rect srcRect, newRect; short direction, dist; Boolean handled, drawWholeRoom; #ifndef COMPILEDEMO objActive = FindEmptyObjectSlot(); if (objActive == -1) { ShoutNoMoreObjects(); return (false); } drawWholeRoom = false; switch (what) { case kFloorVent: case kFloorBlower: case kSewerGrate: case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kInvisBlower: case kGrecoVent: case kSewerBlower: case kLiftArea: if (((what == kTaper) || (what == kCandle) || (what == kStubby)) && (HowManyCandleObjects() >= kMaxCandles)) { ShoutNoMoreSpecialObjects(); return (false); } else if ((what == kTiki) && (HowManyTikiObjects() >= kMaxTikis)) { ShoutNoMoreSpecialObjects(); return (false); } else if ((what == kBBQ) && (HowManyBBQObjects() >= kMaxCoals)) { ShoutNoMoreSpecialObjects(); return (false); } srcRect = srcRects[what]; thisRoom->objects[objActive].data.a.topLeft.h = where.h - HalfRectWide(&srcRect); QSetRect(&newRect, 0, 0, RectWide(&srcRect), RectTall(&srcRect)); if (what == kFloorVent) thisRoom->objects[objActive].data.a.topLeft.v = kFloorVentTop; else if (what == kFloorBlower) thisRoom->objects[objActive].data.a.topLeft.v = kFloorBlowerTop; else if ((what == kTaper) || (what == kCandle) || (what == kStubby) || (what == kTiki) || (what == kBBQ) || (what == kInvisBlower) || (what == kLiftArea)) thisRoom->objects[objActive].data.a.topLeft.v = where.v - HalfRectTall(&srcRect); else if (what == kGrecoVent) thisRoom->objects[objActive].data.a.topLeft.v = kGrecoVentTop; else if (what == kSewerBlower) thisRoom->objects[objActive].data.a.topLeft.v = kSewerBlowerTop; QOffsetRect(&newRect, thisRoom->objects[objActive].data.a.topLeft.h, thisRoom->objects[objActive].data.a.topLeft.v); thisRoom->objects[objActive].data.a.distance = 64; thisRoom->objects[objActive].data.a.initial = true; thisRoom->objects[objActive].data.a.state = true; thisRoom->objects[objActive].data.a.vector = 0x01; if (what == kLiftArea) thisRoom->objects[objActive].data.a.tall = 0x10; else thisRoom->objects[objActive].data.a.tall = 0x00; break; case kCeilingVent: case kCeilingBlower: srcRect = srcRects[what]; thisRoom->objects[objActive].data.a.topLeft.h = where.h - HalfRectWide(&srcRect); QSetRect(&newRect, 0, 0, RectWide(&srcRect), RectTall(&srcRect)); if (what == kCeilingVent) thisRoom->objects[objActive].data.a.topLeft.v = kCeilingVentTop; else if (what == kCeilingBlower) thisRoom->objects[objActive].data.a.topLeft.v = kCeilingBlowerTop; QOffsetRect(&newRect, thisRoom->objects[objActive].data.a.topLeft.h, thisRoom->objects[objActive].data.a.topLeft.v); thisRoom->objects[objActive].data.a.distance = 32; thisRoom->objects[objActive].data.a.initial = true; thisRoom->objects[objActive].data.a.state = true; thisRoom->objects[objActive].data.a.vector = 0x04; break; case kLeftFan: thisRoom->objects[objActive].data.a.topLeft.h = where.h - HalfRectWide(&srcRects[kLeftFan]); thisRoom->objects[objActive].data.a.topLeft.v = where.v - HalfRectTall(&srcRects[kLeftFan]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[kLeftFan]), RectTall(&srcRects[kLeftFan])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.a.topLeft.h, thisRoom->objects[objActive].data.a.topLeft.v); thisRoom->objects[objActive].data.a.distance = 32; thisRoom->objects[objActive].data.a.initial = true; thisRoom->objects[objActive].data.a.state = true; thisRoom->objects[objActive].data.a.vector = 0x08; break; case kRightFan: thisRoom->objects[objActive].data.a.topLeft.h = where.h - HalfRectWide(&srcRects[kRightFan]); thisRoom->objects[objActive].data.a.topLeft.v = where.v - HalfRectTall(&srcRects[kRightFan]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[kRightFan]), RectTall(&srcRects[kRightFan])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.a.topLeft.h, thisRoom->objects[objActive].data.a.topLeft.v); thisRoom->objects[objActive].data.a.distance = 32; thisRoom->objects[objActive].data.a.initial = true; thisRoom->objects[objActive].data.a.state = true; thisRoom->objects[objActive].data.a.vector = 0x02; break; case kTable: case kShelf: case kCabinet: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kCounter: case kDresser: case kDeckTable: case kStool: case kTrunk: case kInvisObstacle: case kBooks: case kInvisBounce: newRect = srcRects[what]; CenterRectOnPoint(&newRect, where); if (what == kCounter) newRect.bottom = kCounterBottom; else if (what == kDresser) newRect.bottom = kDresserBottom; thisRoom->objects[objActive].data.b.bounds = newRect; thisRoom->objects[objActive].data.b.pict = 0; break; case kManhole: newRect = srcRects[kManhole]; CenterRectOnPoint(&newRect, where); newRect.left = (((newRect.left - 3) / 64) * 64) + 3; newRect.right = newRect.left + RectWide(&srcRects[kManhole]); newRect.bottom = kManholeSits; newRect.top = newRect.bottom - RectTall(&srcRects[kManhole]); thisRoom->objects[objActive].data.b.bounds = newRect; thisRoom->objects[objActive].data.b.pict = 0; break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kFoil: case kStar: case kSparkle: case kHelium: if ((what == kCuckoo) && (HowManyCuckooObjects() >= kMaxPendulums)) { ShoutNoMoreSpecialObjects(); return (false); } else if ((what == kBands) && (HowManyBandsObjects() >= kMaxRubberBands)) { ShoutNoMoreSpecialObjects(); return (false); } else if ((what == kStar) && (HowManyStarsObjects() >= kMaxStars)) { ShoutNoMoreSpecialObjects(); return (false); } else if ((what == kSparkle) && (HowManyDynamicObjects() >= kMaxDynamicObs)) { ShoutNoMoreSpecialObjects(); return (false); } thisRoom->objects[objActive].data.c.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.c.topLeft.v = where.v - HalfRectTall(&srcRects[what]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.c.topLeft.h, thisRoom->objects[objActive].data.c.topLeft.v); thisRoom->objects[objActive].data.c.length = 0; thisRoom->objects[objActive].data.c.points = 0; thisRoom->objects[objActive].data.c.state = true; thisRoom->objects[objActive].data.c.initial = true; break; case kGreaseRt: case kGreaseLf: if (HowManyGreaseObjects() >= kMaxGrease) { ShoutNoMoreSpecialObjects(); return (false); } thisRoom->objects[objActive].data.c.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.c.topLeft.v = where.v - HalfRectTall(&srcRects[what]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.c.topLeft.h, thisRoom->objects[objActive].data.c.topLeft.v); thisRoom->objects[objActive].data.c.length = 64; thisRoom->objects[objActive].data.c.points = 0; thisRoom->objects[objActive].data.c.state = true; thisRoom->objects[objActive].data.c.initial = true; break; case kInvisBonus: thisRoom->objects[objActive].data.c.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.c.topLeft.v = where.v - HalfRectTall(&srcRects[what]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.c.topLeft.h, thisRoom->objects[objActive].data.c.topLeft.v); thisRoom->objects[objActive].data.c.length = 0; thisRoom->objects[objActive].data.c.points = 100; thisRoom->objects[objActive].data.c.state = true; thisRoom->objects[objActive].data.c.initial = true; break; case kSlider: thisRoom->objects[objActive].data.c.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.c.topLeft.v = where.v - HalfRectTall(&srcRects[what]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.c.topLeft.h, thisRoom->objects[objActive].data.c.topLeft.v); thisRoom->objects[objActive].data.c.length = 64; thisRoom->objects[objActive].data.c.points = 0; thisRoom->objects[objActive].data.c.state = true; thisRoom->objects[objActive].data.c.initial = true; break; case kUpStairs: case kDownStairs: if ((what == kUpStairs) && (HowManyUpStairsObjects() >= kMaxStairs)) { ShoutNoMoreSpecialObjects(); return (false); } else if ((what == kDownStairs) && (HowManyDownStairsObjects() >= kMaxStairs)) { ShoutNoMoreSpecialObjects(); return (false); } thisRoom->objects[objActive].data.d.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.d.topLeft.v = kStairsTop; QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.d.topLeft.h, thisRoom->objects[objActive].data.d.topLeft.v); thisRoom->objects[objActive].data.d.tall = 0; thisRoom->objects[objActive].data.d.where = -1; thisRoom->objects[objActive].data.d.who = 255; thisRoom->objects[objActive].data.d.wide = 0; break; case kMailboxLf: case kMailboxRt: thisRoom->objects[objActive].data.d.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.d.topLeft.v = where.v - HalfRectTall(&srcRects[what]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.d.topLeft.h, thisRoom->objects[objActive].data.d.topLeft.v); thisRoom->objects[objActive].data.d.tall = 0; thisRoom->objects[objActive].data.d.where = -1; thisRoom->objects[objActive].data.d.who = 255; thisRoom->objects[objActive].data.d.wide = 0; break; case kFloorTrans: thisRoom->objects[objActive].data.d.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.d.topLeft.v = kFloorTransTop; QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.d.topLeft.h, thisRoom->objects[objActive].data.d.topLeft.v); thisRoom->objects[objActive].data.d.tall = 0; thisRoom->objects[objActive].data.d.where = -1; thisRoom->objects[objActive].data.d.who = 255; thisRoom->objects[objActive].data.d.wide = 0; break; case kCeilingTrans: thisRoom->objects[objActive].data.d.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.d.topLeft.v = kCeilingTransTop; QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.d.topLeft.h, thisRoom->objects[objActive].data.d.topLeft.v); thisRoom->objects[objActive].data.d.tall = 0; thisRoom->objects[objActive].data.d.where = -1; thisRoom->objects[objActive].data.d.who = 255; thisRoom->objects[objActive].data.d.wide = 0; break; case kDoorInLf: case kDoorInRt: case kDoorExRt: case kDoorExLf: case kWindowInLf: case kWindowInRt: case kWindowExRt: case kWindowExLf: if ((what == kDoorInLf) || (what == kDoorInRt)) { if (where.h > (kRoomWide / 2)) { what = kDoorInRt; thisRoom->objects[objActive].what = kDoorInRt; thisRoom->objects[objActive].data.d.topLeft.h = kDoorInRtLeft; thisRoom->objects[objActive].data.d.topLeft.v = kDoorInTop; } else { what = kDoorInLf; thisRoom->objects[objActive].what = kDoorInLf; thisRoom->objects[objActive].data.d.topLeft.h = kDoorInLfLeft; thisRoom->objects[objActive].data.d.topLeft.v = kDoorInTop; } } else if ((what == kDoorExRt) || (what == kDoorExLf)) { if (where.h > (kRoomWide / 2)) { what = kDoorExRt; thisRoom->objects[objActive].what = kDoorExRt; thisRoom->objects[objActive].data.d.topLeft.h = kDoorExRtLeft; thisRoom->objects[objActive].data.d.topLeft.v = kDoorExTop; } else { what = kDoorExLf; thisRoom->objects[objActive].what = kDoorExLf; thisRoom->objects[objActive].data.d.topLeft.h = kDoorExLfLeft; thisRoom->objects[objActive].data.d.topLeft.v = kDoorExTop; } } else if ((what == kWindowInLf) || (what == kWindowInRt)) { if (where.h > (kRoomWide / 2)) { what = kWindowInRt; thisRoom->objects[objActive].what = kWindowInRt; thisRoom->objects[objActive].data.d.topLeft.h = kWindowInRtLeft; thisRoom->objects[objActive].data.d.topLeft.v = kWindowInTop; } else { what = kWindowInLf; thisRoom->objects[objActive].what = kWindowInLf; thisRoom->objects[objActive].data.d.topLeft.h = kWindowInLfLeft; thisRoom->objects[objActive].data.d.topLeft.v = kWindowInTop; } } else if ((what == kWindowExRt) || (what == kWindowExLf)) { if (where.h > (kRoomWide / 2)) { what = kWindowExRt; thisRoom->objects[objActive].what = kWindowExRt; thisRoom->objects[objActive].data.d.topLeft.h = kWindowExRtLeft; thisRoom->objects[objActive].data.d.topLeft.v = kWindowExTop; } else { what = kWindowExLf; thisRoom->objects[objActive].what = kWindowExLf; thisRoom->objects[objActive].data.d.topLeft.h = kWindowExLfLeft; thisRoom->objects[objActive].data.d.topLeft.v = kWindowExTop; } } QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.d.topLeft.h, thisRoom->objects[objActive].data.d.topLeft.v); thisRoom->objects[objActive].data.d.tall = 0; thisRoom->objects[objActive].data.d.where = -1; thisRoom->objects[objActive].data.d.who = 255; thisRoom->objects[objActive].data.d.wide = 0; drawWholeRoom = true; break; case kInvisTrans: newRect = srcRects[what]; CenterRectOnPoint(&newRect, where); thisRoom->objects[objActive].data.d.topLeft.h = newRect.left; thisRoom->objects[objActive].data.d.topLeft.v = newRect.top; thisRoom->objects[objActive].data.d.tall = newRect.bottom - newRect.top; thisRoom->objects[objActive].data.d.where = -1; thisRoom->objects[objActive].data.d.who = 255; thisRoom->objects[objActive].data.d.wide = 0; break; case kDeluxeTrans: newRect = srcRects[what]; CenterRectOnPoint(&newRect, where); thisRoom->objects[objActive].data.d.topLeft.h = newRect.left; thisRoom->objects[objActive].data.d.topLeft.v = newRect.top; thisRoom->objects[objActive].data.d.tall = 0x1010; // 64 x 64 thisRoom->objects[objActive].data.d.where = -1; thisRoom->objects[objActive].data.d.who = 255; thisRoom->objects[objActive].data.d.wide = 0x10; // Initially on break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: if ((what == kSoundTrigger) && (HowManySoundObjects() >= kMaxSoundTriggers)) { ShoutNoMoreSpecialObjects(); return (false); } thisRoom->objects[objActive].data.e.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.e.topLeft.v = where.v - HalfRectTall(&srcRects[what]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.e.topLeft.h, thisRoom->objects[objActive].data.e.topLeft.v); thisRoom->objects[objActive].data.e.delay = 0; if (what == kSoundTrigger) thisRoom->objects[objActive].data.e.where = 3000; else thisRoom->objects[objActive].data.e.where = -1; thisRoom->objects[objActive].data.e.who = 255; if ((what == kTrigger) || (what == kLgTrigger)) thisRoom->objects[objActive].data.e.type = kOneShot; else thisRoom->objects[objActive].data.e.type = kToggle; break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: if (what == kCeilingLight) { thisRoom->objects[objActive].data.f.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.f.topLeft.v = kCeilingLightTop; QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, thisRoom->objects[objActive].data.f.topLeft.v); thisRoom->objects[objActive].data.f.length = 64; } else if (what == kHipLamp) { thisRoom->objects[objActive].data.f.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.f.topLeft.v = kHipLampTop; QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, thisRoom->objects[objActive].data.f.topLeft.v); thisRoom->objects[objActive].data.f.length = 0; } else if (what == kDecoLamp) { thisRoom->objects[objActive].data.f.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.f.topLeft.v = kDecoLampTop; QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, thisRoom->objects[objActive].data.f.topLeft.v); thisRoom->objects[objActive].data.f.length = 0; } else if (what == kFlourescent) { thisRoom->objects[objActive].data.f.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.f.topLeft.v = kFlourescentTop; newRect = srcRects[what]; QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, thisRoom->objects[objActive].data.f.topLeft.v); thisRoom->objects[objActive].data.f.length = 64; } else if (what == kTrackLight) { thisRoom->objects[objActive].data.f.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.f.topLeft.v = kTrackLightTop; newRect = srcRects[what]; QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, thisRoom->objects[objActive].data.f.topLeft.v); thisRoom->objects[objActive].data.f.length = 64; } else { thisRoom->objects[objActive].data.f.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.f.topLeft.v = where.v - HalfRectTall(&srcRects[what]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.f.topLeft.h, thisRoom->objects[objActive].data.f.topLeft.v); thisRoom->objects[objActive].data.f.length = 0; } thisRoom->objects[objActive].data.f.initial = true; thisRoom->objects[objActive].data.f.state = true; thisRoom->objects[objActive].data.f.byte0 = 0; thisRoom->objects[objActive].data.f.byte1 = 0; drawWholeRoom = true; break; case kShredder: case kToaster: case kMacPlus: case kGuitar: case kTV: case kCoffee: case kOutlet: case kVCR: case kStereo: case kMicrowave: case kCinderBlock: case kFlowerBox: case kCDs: case kCustomPict: if ((what != kGuitar) && (what != kCinderBlock) && (what != kFlowerBox) && (what != kCDs) && (what != kCustomPict) && (HowManyShredderObjects() >= kMaxShredded)) { ShoutNoMoreSpecialObjects(); return (false); } thisRoom->objects[objActive].data.g.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.g.topLeft.v = where.v - HalfRectTall(&srcRects[what]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.g.topLeft.h, thisRoom->objects[objActive].data.g.topLeft.v); if (what == kToaster) { thisRoom->objects[objActive].data.g.height = 64; thisRoom->objects[objActive].data.g.delay = 10 + RandomInt(10); } else if (what == kOutlet) { thisRoom->objects[objActive].data.g.height = 0; thisRoom->objects[objActive].data.g.delay = 10 + RandomInt(10); } else if (what == kCustomPict) { thisRoom->objects[objActive].data.g.height = 10000; thisRoom->objects[objActive].data.g.delay = 0; } else { thisRoom->objects[objActive].data.g.height = 0; thisRoom->objects[objActive].data.g.delay = 0; } if (what == kMicrowave) thisRoom->objects[objActive].data.g.byte0 = 7; else thisRoom->objects[objActive].data.g.byte0 = 0; thisRoom->objects[objActive].data.g.initial = true; thisRoom->objects[objActive].data.g.state = true; break; case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kCobweb: if ((what != kCobweb) && (HowManyDynamicObjects() >= kMaxDynamicObs)) { ShoutNoMoreSpecialObjects(); return (false); } if (what == kDartLf) { thisRoom->objects[objActive].data.h.topLeft.h = kRoomWide - RectWide(&srcRects[what]); } else if (what == kDartRt) { thisRoom->objects[objActive].data.h.topLeft.h = 0; } else { thisRoom->objects[objActive].data.h.topLeft.h = where.h - HalfRectWide(&srcRects[what]); } if ((what == kDartLf) || (what == kDartRt) || (what == kCobweb)) { thisRoom->objects[objActive].data.h.topLeft.v = where.v - HalfRectTall(&srcRects[what]); } else { thisRoom->objects[objActive].data.h.topLeft.v = (kTileHigh / 2) - HalfRectTall(&srcRects[what]); } QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.h.topLeft.h, thisRoom->objects[objActive].data.h.topLeft.v); thisRoom->objects[objActive].data.h.length = 0; if (what == kCobweb) thisRoom->objects[objActive].data.h.delay = 0; else thisRoom->objects[objActive].data.h.delay = 10 + RandomInt(10); thisRoom->objects[objActive].data.h.byte0 = 0; thisRoom->objects[objActive].data.h.initial = true; thisRoom->objects[objActive].data.h.state = true; break; case kBall: case kDrip: case kFish: if (HowManyDynamicObjects() >= kMaxDynamicObs) { ShoutNoMoreSpecialObjects(); return (false); } thisRoom->objects[objActive].data.h.topLeft.h = where.h - HalfRectWide(&srcRects[what]); thisRoom->objects[objActive].data.h.topLeft.v = where.v - HalfRectTall(&srcRects[what]); QSetRect(&newRect, 0, 0, RectWide(&srcRects[what]), RectTall(&srcRects[what])); QOffsetRect(&newRect, thisRoom->objects[objActive].data.h.topLeft.h, thisRoom->objects[objActive].data.h.topLeft.v); thisRoom->objects[objActive].data.h.length = 64; if (what == kBall) thisRoom->objects[objActive].data.h.delay = 0; else thisRoom->objects[objActive].data.h.delay = 10 + RandomInt(10); thisRoom->objects[objActive].data.h.byte0 = 0; thisRoom->objects[objActive].data.h.initial = true; thisRoom->objects[objActive].data.h.state = true; break; case kMousehole: newRect = srcRects[what]; CenterRectOnPoint(&newRect, where); newRect.bottom = kMouseholeBottom; newRect.top = newRect.bottom - RectTall(&srcRects[what]); thisRoom->objects[objActive].data.i.bounds = newRect; thisRoom->objects[objActive].data.i.pict = 0; break; case kFireplace: newRect = srcRects[what]; CenterRectOnPoint(&newRect, where); newRect.bottom = kFireplaceBottom; newRect.top = newRect.bottom - RectTall(&srcRects[what]); thisRoom->objects[objActive].data.i.bounds = newRect; thisRoom->objects[objActive].data.i.pict = 0; break; case kFlower: GetKeys(theseKeys); if (!BitTst(&theseKeys, kShiftKeyMap)) wasFlower = RandomInt(kNumFlowers); newRect = flowerSrc[wasFlower]; CenterRectOnPoint(&newRect, where); thisRoom->objects[objActive].data.i.bounds = newRect; thisRoom->objects[objActive].data.i.pict = wasFlower; break; case kOzma: case kMirror: case kWallWindow: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: newRect = srcRects[what]; CenterRectOnPoint(&newRect, where); thisRoom->objects[objActive].data.i.bounds = newRect; thisRoom->objects[objActive].data.i.pict = 0; break; default: return (false); break; } thisRoom->objects[objActive].what = what; thisRoom->numObjects++; if (KeepObjectLegal()) { } fileDirty = true; UpdateMenus(false); handled = ObjectHasHandle(&direction, &dist); if (showItNow) { if (drawWholeRoom) ReadyBackground(thisRoom->background, thisRoom->tiles); GetThisRoomsObjRects(); DrawThisRoomsObjects(); InvalWindowRect(mainWindow, &mainWindowRect); if (handled) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else StartMarquee(&roomObjectRects[objActive]); } #endif return (true); } //-------------------------------------------------------------- FindEmptyObjectSlot #ifndef COMPILEDEMO short FindEmptyObjectSlot (void) { short i, emptySlot; emptySlot = -1; for (i = 0; i < kMaxRoomObs; i++) if (thisRoom->objects[i].what == kObjectIsEmpty) { emptySlot = i; break; } return (emptySlot); } //-------------------------------------------------------------- FindObjectSlotInRoom short FindObjectSlotInRoom (short roomNumber) { roomType *testRoomPtr; short i, emptySlot; char wasState; emptySlot = -1; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNumber]); for (i = 0; i < kMaxRoomObs; i++) if (testRoomPtr->objects[i].what == kObjectIsEmpty) { emptySlot = i; break; } HSetState((Handle)thisHouse, wasState); return (emptySlot); } //-------------------------------------------------------------- DoesRoomNumHaveObject Boolean DoesRoomNumHaveObject (short room, short what) { roomType *testRoomPtr; short i; char wasState; Boolean hasIt; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[room]); hasIt = false; for (i = 0; i < kMaxRoomObs; i++) if (testRoomPtr->objects[i].what == what) { hasIt = true; break; } HSetState((Handle)thisHouse, wasState); return (hasIt); } //-------------------------------------------------------------- ShoutNoMoreObjects void ShoutNoMoreObjects (void) { short hitWhat; // CenterAlert(kNoMoreObjectsAlert); hitWhat = Alert(kNoMoreObjectsAlert, nil); } //-------------------------------------------------------------- HowManyCandleObjects short HowManyCandleObjects (void) { short i, aCandle; aCandle = 0; for (i = 0; i < kMaxRoomObs; i++) if ((thisRoom->objects[i].what == kTaper) || (thisRoom->objects[i].what == kCandle) || (thisRoom->objects[i].what == kStubby)) aCandle++; return (aCandle); } //-------------------------------------------------------------- HowManyTikiObjects short HowManyTikiObjects (void) { short i, aTiki; aTiki = 0; for (i = 0; i < kMaxRoomObs; i++) if (thisRoom->objects[i].what == kTiki) aTiki++; return (aTiki); } //-------------------------------------------------------------- HowManyBBQObjects short HowManyBBQObjects (void) { short i, aBBQ; aBBQ = 0; for (i = 0; i < kMaxRoomObs; i++) if (thisRoom->objects[i].what == kBBQ) aBBQ++; return (aBBQ); } //-------------------------------------------------------------- HowManyCuckooObjects short HowManyCuckooObjects (void) { short i, aCuckoo; aCuckoo = 0; for (i = 0; i < kMaxRoomObs; i++) if (thisRoom->objects[i].what == kCuckoo) aCuckoo++; return (aCuckoo); } //-------------------------------------------------------------- HowManyBandsObjects short HowManyBandsObjects (void) { short i, aBands; aBands = 0; for (i = 0; i < kMaxRoomObs; i++) if (thisRoom->objects[i].what == kBands) aBands++; return (aBands); } //-------------------------------------------------------------- HowManyGreaseObjects short HowManyGreaseObjects (void) { short i, aGrease; aGrease = 0; for (i = 0; i < kMaxRoomObs; i++) if ((thisRoom->objects[i].what == kGreaseRt) || (thisRoom->objects[i].what == kGreaseLf)) aGrease++; return (aGrease); } //-------------------------------------------------------------- HowManyStarsObjects short HowManyStarsObjects (void) { short i, aStar; aStar = 0; for (i = 0; i < kMaxRoomObs; i++) if (thisRoom->objects[i].what == kStar) aStar++; return (aStar); } //-------------------------------------------------------------- HowManySoundObjects short HowManySoundObjects (void) { short i, aSound; aSound = 0; for (i = 0; i < kMaxRoomObs; i++) if (thisRoom->objects[i].what == kSoundTrigger) aSound++; return (aSound); } //-------------------------------------------------------------- HowManyUpStairsObjects short HowManyUpStairsObjects (void) { short i, aStair; aStair = 0; for (i = 0; i < kMaxRoomObs; i++) if (thisRoom->objects[i].what == kUpStairs) aStair++; return (aStair); } //-------------------------------------------------------------- HowManyDownStairsObjects short HowManyDownStairsObjects (void) { short i, aStair; aStair = 0; for (i = 0; i < kMaxRoomObs; i++) if (thisRoom->objects[i].what == kDownStairs) aStair++; return (aStair); } //-------------------------------------------------------------- HowManyShredderObjects short HowManyShredderObjects (void) { short i, aShredder; aShredder = 0; for (i = 0; i < kMaxRoomObs; i++) if (thisRoom->objects[i].what == kShredder) aShredder++; return (aShredder); } //-------------------------------------------------------------- HowManyDynamicObjects short HowManyDynamicObjects (void) { short i, aDinah; aDinah = 0; for (i = 0; i < kMaxRoomObs; i++) if ((thisRoom->objects[i].what == kSparkle) || (thisRoom->objects[i].what == kToaster) || (thisRoom->objects[i].what == kMacPlus) || (thisRoom->objects[i].what == kTV) || (thisRoom->objects[i].what == kCoffee) || (thisRoom->objects[i].what == kOutlet) || (thisRoom->objects[i].what == kVCR) || (thisRoom->objects[i].what == kStereo) || (thisRoom->objects[i].what == kMicrowave) || (thisRoom->objects[i].what == kBalloon) || (thisRoom->objects[i].what == kCopterLf) || (thisRoom->objects[i].what == kCopterRt) || (thisRoom->objects[i].what == kDartLf) || (thisRoom->objects[i].what == kDartRt) || (thisRoom->objects[i].what == kBall) || (thisRoom->objects[i].what == kDrip) || (thisRoom->objects[i].what == kFish)) aDinah++; return (aDinah); } //-------------------------------------------------------------- ShoutNoMoreSpecialObjects void ShoutNoMoreSpecialObjects (void) { short hitWhat; // CenterAlert(kNoMoreSpecialAlert); hitWhat = Alert(kNoMoreSpecialAlert, nil); } #endif \ No newline at end of file diff --git a/Sources/ObjectDraw.c b/Sources/ObjectDraw.c deleted file mode 100755 index e8789ba..0000000 --- a/Sources/ObjectDraw.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // ObjectDraw.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" #include "Objects.h" #include "RectUtils.h" #include "Room.h" #define k8WhiteColor 0 #define kYellowColor 5 #define kGoldColor 11 #define k8RedColor 35 #define kPaleVioletColor 42 #define k8LtTanColor 52 #define k8BambooColor 53 #define kDarkFleshColor 58 #define k8TanColor 94 #define k8PissYellowColor 95 #define k8OrangeColor 59 #define k8BrownColor 137 #define k8Red4Color 143 #define k8SkyColor 150 #define k8EarthBlueColor 170 #define k8DkRedColor 222 #define k8DkRed2Color 223 #define kIntenseGreenColor 225 #define kIntenseBlueColor 235 #define k8PumpkinColor 101 #define k8LtstGrayColor 245 #define k8LtstGray2Color 246 #define k8LtstGray3Color 43 #define k8LtstGray4Color 247 #define k8LtstGray5Color 248 #define k8LtGrayColor 249 #define k8GrayColor 250 #define k8Gray2Color 251 #define k8DkGrayColor 252 #define k8DkGray2Color 253 #define k8DkGray3Color 172 #define k8DkstGrayColor 254 #define k8BlackColor 255 void DrawClockDigit (short, Rect *); void DrawClockHands (Point, short, short); void DrawLargeClockHands (Point, short, short); //============================================================== Functions //-------------------------------------------------------------- DrawSimpleBlowers void DrawSimpleBlowers (short what, Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), (BitMap *)*GetGWorldPixMap(blowerMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], &srcRects[what], theRect); } //-------------------------------------------------------------- DrawTiki void DrawTiki (Rect *theRect, short down) { #define kTikiPoleBase 300 long darkGrayC, lightWoodC, darkWoodC; CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); if (thisMac.isDepth == 4) { darkGrayC = 14; lightWoodC = 6; darkWoodC = 9; } else { darkGrayC = k8DkstGrayColor; lightWoodC = k8BambooColor; darkWoodC = k8PissYellowColor; } if (theRect->bottom < kTikiPoleBase + down) { ColorLine(theRect->left + 11, theRect->bottom - 1, theRect->left + 11, kTikiPoleBase + down - 1, darkGrayC); ColorLine(theRect->left + 12, theRect->bottom - 1, theRect->left + 12, kTikiPoleBase + down, lightWoodC); ColorLine(theRect->left + 13, theRect->bottom - 1, theRect->left + 13, kTikiPoleBase + down, darkWoodC); ColorLine(theRect->left + 14, theRect->bottom - 1, theRect->left + 14, kTikiPoleBase + down, darkWoodC); ColorLine(theRect->left + 15, theRect->bottom - 1, theRect->left + 15, kTikiPoleBase + down - 1, darkGrayC); } SetGWorld(wasCPort, wasWorld); CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), (BitMap *)*GetGWorldPixMap(blowerMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kTiki], &srcRects[kTiki], theRect); } //-------------------------------------------------------------- DrawInvisibleBlower void DrawInvisibleBlower (Rect *theRect) { Rect tempRect; CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); QSetRect(&tempRect, 0, 0, 24, 24); QOffsetRect(&tempRect, theRect->left, theRect->top); ColorFrameRect(&tempRect, 192); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawLiftArea void DrawLiftArea (Rect *theRect) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorFrameRect(theRect, 192); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawTable void DrawTable (Rect *tableTop, short down) { #define kTableBaseTop 296 #define kTableShadowTop 312 #define kTableShadowOffset 12 Rect tempRect; long brownC, tanC, dkRedC, blackC; short hCenter, vShadow; CGrafPtr wasCPort; GDHandle wasWorld; Pattern dummyPattern; if (thisMac.isDepth == 4) { brownC = 11; tanC = 9; dkRedC = 14; blackC = 15; } else { brownC = k8BrownColor; tanC = k8TanColor; dkRedC = k8DkRed2Color; blackC = k8BlackColor; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); QSetRect(&tempRect, tableTop->left, 0, tableTop->right, RectWide(tableTop) / 10); QOffsetRect(&tempRect, 0, -HalfRectTall(&tempRect) + kTableShadowTop + down); QOffsetRect(&tempRect, kTableShadowOffset, -kTableShadowOffset); PenPat(GetQDGlobalsGray(&dummyPattern)); PenMode(patOr); if (thisMac.isDepth == 4) ColorOval(&tempRect, 15); else ColorOval(&tempRect, k8DkstGrayColor); PenNormal(); InsetRect(tableTop, 0, 1); ColorRect(tableTop, brownC); InsetRect(tableTop, 0, -1); ColorLine(tableTop->left, tableTop->top + 1, tableTop->left, tableTop->top + 1, k8WhiteColor); ColorLine(tableTop->left + 1, tableTop->top, tableTop->right - 2, tableTop->top, k8WhiteColor); ColorLine(tableTop->right - 1, tableTop->top + 1, tableTop->right - 1, tableTop->top + 1, k8WhiteColor); ColorLine(tableTop->left + 1, tableTop->top + 1, tableTop->right - 2, tableTop->top + 1, tanC); ColorLine(tableTop->left, tableTop->top + 2, tableTop->left, tableTop->bottom - 2, tanC); ColorLine(tableTop->left + 1, tableTop->bottom - 1, tableTop->right - 2, tableTop->bottom - 1, blackC); ColorLine(tableTop->right - 1, tableTop->top + 2, tableTop->right - 1, tableTop->bottom - 2, blackC); ColorLine(tableTop->left + 1, tableTop->bottom - 2, tableTop->right - 2, tableTop->bottom - 2, dkRedC); if (tableTop->bottom < kTableBaseTop + down) { hCenter = (tableTop->left + tableTop->right) / 2; ColorLine(hCenter - 3, tableTop->bottom, hCenter - 3, kTableBaseTop + down, blackC); ColorLine(hCenter - 2, tableTop->bottom, hCenter - 2, kTableBaseTop + down, k8LtGrayColor); ColorLine(hCenter - 1, tableTop->bottom, hCenter - 1, kTableBaseTop + down, k8GrayColor); ColorLine(hCenter, tableTop->bottom, hCenter, kTableBaseTop + down, k8DkGrayColor); ColorLine(hCenter + 1, tableTop->bottom, hCenter + 1, kTableBaseTop + down, blackC); vShadow = tableTop->bottom + RectWide(tableTop) / 4 - 2; if (vShadow > kTableBaseTop + down) { ColorLine(hCenter - 2, tableTop->bottom, hCenter - 2, kTableBaseTop + down, k8DkGrayColor); ColorLine(hCenter - 1, tableTop->bottom, hCenter - 1, kTableBaseTop + down, k8DkGrayColor); ColorLine(hCenter, tableTop->bottom, hCenter, kTableBaseTop + down, blackC); } else { ColorLine(hCenter - 2, tableTop->bottom, hCenter - 2, vShadow, k8DkGrayColor); ColorLine(hCenter - 1, tableTop->bottom, hCenter - 1, vShadow + 1, k8DkGrayColor); ColorLine(hCenter, tableTop->bottom, hCenter, vShadow + 2, blackC); } } SetGWorld(wasCPort, wasWorld); tempRect = tableSrc; QOffsetRect(&tempRect, -HalfRectWide(&tableSrc) + tableTop->left + HalfRectWide(tableTop), kTableBaseTop + down); CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &tableSrc, &tableSrc, &tempRect); } //-------------------------------------------------------------- DrawShelf void DrawShelf (Rect *shelfTop) { #define kBracketInset 18 #define kShelfDeep 4 #define kBracketThick 5 #define kShelfShadowOff 12 Rect tempRect; long brownC, ltTanC, tanC, dkRedC, blackC; RgnHandle shadowRgn; CGrafPtr wasCPort; GDHandle wasWorld; Pattern dummyPattern; if (thisMac.isDepth == 4) { brownC = 11; ltTanC = 7; tanC = 9; dkRedC = 14; blackC = 15; } else { brownC = k8BrownColor; ltTanC = k8LtTanColor; tanC = k8TanColor; dkRedC = k8DkRed2Color; blackC = k8BlackColor; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); MoveTo(shelfTop->left, shelfTop->bottom); shadowRgn = NewRgn(); if (shadowRgn == nil) RedAlert(kErrUnnaccounted); OpenRgn(); Line(kShelfShadowOff, kShelfShadowOff); Line(RectWide(shelfTop) - kShelfDeep, 0); Line(0, -kShelfThick + 1); Line(-kShelfShadowOff, -kShelfShadowOff); LineTo(shelfTop->left, shelfTop->bottom); CloseRgn(shadowRgn); PenPat(GetQDGlobalsGray(&dummyPattern)); PenMode(patOr); if (thisMac.isDepth == 4) ColorRegion(shadowRgn, 15); else ColorRegion(shadowRgn, k8DkstGrayColor); PenNormal(); DisposeRgn(shadowRgn); InsetRect(shelfTop, 0, 1); ColorRect(shelfTop, brownC); InsetRect(shelfTop, 0, -1); ColorLine(shelfTop->left + 1, shelfTop->top, shelfTop->left + 1 + kShelfDeep, shelfTop->top, ltTanC); ColorLine(shelfTop->left, shelfTop->top + 1, shelfTop->left + kShelfDeep, shelfTop->top + 1, tanC); ColorLine(shelfTop->left, shelfTop->top + 2, shelfTop->left + kShelfDeep, shelfTop->top + 2, tanC); ColorLine(shelfTop->left, shelfTop->top + 3, shelfTop->left + kShelfDeep, shelfTop->top + 3, tanC); ColorLine(shelfTop->left + 1, shelfTop->bottom - 1, shelfTop->left + 1 + kShelfDeep, shelfTop->bottom - 1, dkRedC); ColorLine(shelfTop->left + 2 + kShelfDeep, shelfTop->bottom - 1, shelfTop->right - 2, shelfTop->bottom - 1, blackC); ColorLine(shelfTop->left + 2 + kShelfDeep, shelfTop->top, shelfTop->right - 2, shelfTop->top, tanC); ColorLine(shelfTop->right - 1, shelfTop->top + 1, shelfTop->right - 1, shelfTop->bottom - 2, blackC); SetGWorld(wasCPort, wasWorld); tempRect = shelfSrc; ZeroRectCorner(&tempRect); QOffsetRect(&tempRect, shelfTop->left + kBracketInset, shelfTop->bottom); CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &shelfSrc, &shelfSrc, &tempRect); ZeroRectCorner(&tempRect); QOffsetRect(&tempRect, shelfTop->right - kBracketInset - kShelfDeep - kBracketThick, shelfTop->bottom); CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &shelfSrc, &shelfSrc, &tempRect); } //-------------------------------------------------------------- DrawCabinet void DrawCabinet (Rect *cabinet) { #define kCabinetDeep 4 #define kCabinetShadowOff 6 Rect tempRect; long brownC, dkGrayC, ltTanC, tanC, dkRedC, blackC; RgnHandle shadowRgn; CGrafPtr wasCPort; GDHandle wasWorld; Pattern dummyPattern; if (thisMac.isDepth == 4) { brownC = 11; dkGrayC = 14; ltTanC = 7; tanC = 9; dkRedC = 14; blackC = 15; } else { brownC = k8BrownColor; dkGrayC = k8DkstGrayColor; ltTanC = k8LtTanColor; tanC = k8TanColor; dkRedC = k8DkRed2Color; blackC = k8BlackColor; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); MoveTo(cabinet->left, cabinet->bottom); shadowRgn = NewRgn(); if (shadowRgn == nil) RedAlert(kErrUnnaccounted); OpenRgn(); Line(kCabinetShadowOff, kCabinetShadowOff); Line(RectWide(cabinet), 0); Line(0, -RectTall(cabinet) + kCabinetDeep); Line(-kCabinetShadowOff, -kCabinetShadowOff); LineTo(cabinet->left, cabinet->bottom); CloseRgn(shadowRgn); PenPat(GetQDGlobalsGray(&dummyPattern)); PenMode(patOr); if (thisMac.isDepth == 4) ColorRegion(shadowRgn, 15); else ColorRegion(shadowRgn, dkGrayC); PenNormal(); DisposeRgn(shadowRgn); InsetRect(cabinet, 1, 1); // fill bulk of cabinet brown ColorRect(cabinet, brownC); InsetRect(cabinet, -1, -1); tempRect = *cabinet; // add lighter left side tempRect.right = tempRect.left + kCabinetDeep; ColorRect(&tempRect, tanC); // hilight top edge ColorLine(cabinet->left + 1, cabinet->top + 1, cabinet->left + kCabinetDeep, cabinet->top + 1, ltTanC); ColorLine(cabinet->left + kCabinetDeep, cabinet->top + 1, cabinet->right - 3, cabinet->top + 1, tanC); // shadow bottom edge ColorLine(cabinet->left + kCabinetDeep + 3, cabinet->top + 5, cabinet->left + kCabinetDeep + 3, cabinet->bottom - 6, tanC); ColorLine(cabinet->left + kCabinetDeep + 4, cabinet->top + 5, cabinet->left + kCabinetDeep + 4, cabinet->bottom - 6, tanC); ColorLine(cabinet->left + kCabinetDeep + 9, cabinet->top + 10, cabinet->left + kCabinetDeep + 9, cabinet->bottom - 11, dkGrayC); ColorLine(cabinet->right - 4, cabinet->top + 6, cabinet->right - 4, cabinet->bottom - 5, dkRedC); ColorLine(cabinet->right - 5, cabinet->top + 5, cabinet->right - 5, cabinet->bottom - 6, dkGrayC); ColorLine(cabinet->right - 10, cabinet->top + 10, cabinet->right - 10, cabinet->bottom - 11, tanC); ColorLine(cabinet->left + kCabinetDeep + 4, cabinet->top + 4, cabinet->left + kCabinetDeep + 4, cabinet->top + 4, ltTanC); ColorLine(cabinet->left + kCabinetDeep + 5, cabinet->top + 4, cabinet->right - 6, cabinet->top + 4, tanC); ColorLine(cabinet->left + kCabinetDeep + 10, cabinet->top + 9, cabinet->right - 11, cabinet->top + 9, dkGrayC); ColorLine(cabinet->right - 5, cabinet->bottom - 5, cabinet->right - 5, cabinet->bottom - 5, dkRedC); ColorLine(cabinet->left + kCabinetDeep + 6, cabinet->bottom - 4, cabinet->right - 5, cabinet->bottom - 4, dkRedC); ColorLine(cabinet->left + kCabinetDeep + 5, cabinet->bottom - 5, cabinet->right - 6, cabinet->bottom - 5, dkGrayC); ColorLine(cabinet->left + kCabinetDeep + 10, cabinet->bottom - 10, cabinet->right - 11, cabinet->bottom - 10, tanC); SetGWorld(wasCPort, wasWorld); tempRect = hingeSrc; ZeroRectCorner(&tempRect); QOffsetRect(&tempRect, cabinet->left + kCabinetDeep + 2, cabinet->top + 10); CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &hingeSrc, &hingeSrc, &tempRect); tempRect = hingeSrc; ZeroRectCorner(&tempRect); QOffsetRect(&tempRect, cabinet->left + kCabinetDeep + 2, cabinet->bottom - 26); CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &hingeSrc, &hingeSrc, &tempRect); tempRect = handleSrc; ZeroRectCorner(&tempRect); QOffsetRect(&tempRect, cabinet->right - 8, cabinet->top + HalfRectTall(cabinet) - HalfRectTall(&handleSrc)); CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &handleSrc, &handleSrc, &tempRect); FrameRect(cabinet); } //-------------------------------------------------------------- DrawSimpleFurniture void DrawSimpleFurniture (short what, Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], &srcRects[what], theRect); } //-------------------------------------------------------------- DrawCounter void DrawCounter (Rect *counter) { #define kCounterFooterHigh 12 #define kCounterStripWide 6 #define kCounterStripTall 29 #define kCounterPanelDrop 12 Rect tempRect; RgnHandle shadowRgn; long brownC, dkGrayC, tanC, blackC, dkstRedC; short nRects, width, i; CGrafPtr wasCPort; GDHandle wasWorld; Pattern dummyPattern; if (thisMac.isDepth == 4) { brownC = 11; dkGrayC = 14; tanC = 9; blackC = 15; dkstRedC = 15; } else { brownC = k8BrownColor; dkGrayC = k8DkstGrayColor; tanC = k8TanColor; blackC = k8BlackColor; dkstRedC = k8DkRed2Color; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); MoveTo(counter->right - 2, counter->bottom); shadowRgn = NewRgn(); if (shadowRgn == nil) RedAlert(kErrUnnaccounted); OpenRgn(); Line(10, -10); Line(0, -RectTall(counter) + 29); Line(2, 0); Line(0, -7); Line(-12, -12); LineTo(counter->right - 2, counter->bottom); CloseRgn(shadowRgn); PenPat(GetQDGlobalsGray(&dummyPattern)); PenMode(patOr); if (thisMac.isDepth == 4) ColorRegion(shadowRgn, 15); else ColorRegion(shadowRgn, dkGrayC); PenNormal(); DisposeRgn(shadowRgn); InsetRect(counter, 2, 2); ColorRect(counter, brownC); InsetRect(counter, -2, -2); tempRect = *counter; tempRect.top = tempRect.bottom - kCounterFooterHigh; tempRect.left += 2; tempRect.right -= 2; ColorRect(&tempRect, dkGrayC); ColorLine(counter->left + 2, counter->bottom - kCounterFooterHigh, counter->right - 3, counter->bottom - kCounterFooterHigh, blackC); ColorLine(counter->left + 2, counter->bottom - kCounterFooterHigh + 1, counter->right - 3, counter->bottom - kCounterFooterHigh + 1, blackC); ColorLine(counter->right - 3, counter->bottom - kCounterFooterHigh, counter->right - 3, counter->bottom - 1, blackC); ColorLine(counter->left + 2, counter->bottom - kCounterFooterHigh, counter->left + 2, counter->bottom - 1, k8DkGrayColor); ColorLine(counter->right - 2, counter->top, counter->right - 2, counter->bottom - kCounterFooterHigh - 1, dkstRedC); ColorLine(counter->left + 1, counter->top + 8, counter->left + 1, counter->bottom - kCounterFooterHigh - 1, tanC); if (thisMac.isDepth == 4) { ColorLine(counter->left - 1, counter->top, counter->right, counter->top, 1); ColorLine(counter->left - 1, counter->top + 1, counter->right, counter->top + 1, 2); ColorLine(counter->left - 1, counter->top + 2, counter->right, counter->top + 2, 3); ColorLine(counter->left - 1, counter->top + 3, counter->right, counter->top + 3, 4); ColorLine(counter->left - 1, counter->top + 4, counter->right, counter->top + 4, 5); ColorLine(counter->left - 1, counter->top + 5, counter->right, counter->top + 5, 5); ColorLine(counter->left - 1, counter->top + 6, counter->right, counter->top + 6, 5); ColorLine(counter->left - 1, counter->top, counter->left - 1, counter->top + 6, 1); } else { ColorLine(counter->left - 1, counter->top, counter->right, counter->top, k8LtstGrayColor); ColorLine(counter->left - 1, counter->top + 1, counter->right, counter->top + 1, k8LtstGray2Color); ColorLine(counter->left - 1, counter->top + 2, counter->right, counter->top + 2, k8LtstGray3Color); ColorLine(counter->left - 1, counter->top + 3, counter->right, counter->top + 3, k8LtstGray4Color); ColorLine(counter->left - 1, counter->top + 4, counter->right, counter->top + 4, k8LtstGray5Color); ColorLine(counter->left - 1, counter->top + 5, counter->right, counter->top + 5, k8LtstGray5Color); ColorLine(counter->left - 1, counter->top + 6, counter->right, counter->top + 6, k8LtstGray5Color); ColorLine(counter->left - 1, counter->top, counter->left - 1, counter->top + 6, k8LtstGrayColor); } ColorLine(counter->right, counter->top, counter->right, counter->top + 6, k8LtGrayColor); ColorLine(counter->left + 1, counter->top + 7, counter->right - 2, counter->top + 7, dkstRedC); ColorLine(counter->left + 1, counter->top + 8, counter->right - 2, counter->top + 8, dkstRedC); SetGWorld(wasCPort, wasWorld); nRects = RectWide(counter) / 40; if (nRects == 0) nRects = 1; width = ((RectWide(counter) - kCounterStripWide) / nRects) - kCounterStripWide; QSetRect(&tempRect, 0, 0, width, RectTall(counter) - kCounterStripTall); QOffsetRect(&tempRect, counter->left + kCounterStripWide, counter->top + kCounterPanelDrop); for (i = 0; i < nRects; i++) { HiliteRect(&tempRect, tanC, dkstRedC); InsetRect(&tempRect, 4, 4); HiliteRect(&tempRect, dkstRedC, tanC); InsetRect(&tempRect, -4, -4); QOffsetRect(&tempRect, kCounterStripWide + width, 0); } } //-------------------------------------------------------------- DrawDresser void DrawDresser (Rect *dresser) { #define kDresserTopThick 4 #define kDresserCrease 9 #define kDresserDrawerDrop 12 #define kDresserSideSpare 14 Rect tempRect, dest; long yellowC, brownC, dkGrayC, ltTanC, dkstRedC; RgnHandle shadowRgn; short nRects, height, i; CGrafPtr wasCPort; GDHandle wasWorld; Pattern dummyPattern; if (thisMac.isDepth == 4) { yellowC = 9; brownC = 11; dkGrayC = 14; ltTanC = 7; dkstRedC = 15; } else { yellowC = k8PissYellowColor; brownC = k8BrownColor; dkGrayC = k8DkstGrayColor; ltTanC = k8LtTanColor; dkstRedC = k8DkRed2Color; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); MoveTo(dresser->left + 10, dresser->bottom + 9); shadowRgn = NewRgn(); if (shadowRgn == nil) RedAlert(kErrUnnaccounted); OpenRgn(); Line(RectWide(dresser) - 11, 0); Line(9, -9); Line(0, -RectTall(dresser) + 12); Line(-9, -9); Line(-RectWide(dresser) + 11, 0); LineTo(dresser->left + 10, dresser->bottom + 9); CloseRgn(shadowRgn); PenPat(GetQDGlobalsGray(&dummyPattern)); PenMode(patOr); if (thisMac.isDepth == 4) ColorRegion(shadowRgn, 15); else ColorRegion(shadowRgn, k8DkstGrayColor); PenNormal(); DisposeRgn(shadowRgn); InsetRect(dresser, 2, 2); ColorRect(dresser, k8PumpkinColor); HiliteRect(dresser, k8OrangeColor, dkstRedC); InsetRect(dresser, -2, -2); tempRect = *dresser; tempRect.bottom = tempRect.top + kDresserTopThick; ColorRect(&tempRect, k8PissYellowColor); HiliteRect(&tempRect, ltTanC, dkstRedC); ColorLine(dresser->left + 2, dresser->top + kDresserTopThick, dresser->right - 3, dresser->top + kDresserTopThick, k8Red4Color); ColorLine(dresser->left + kDresserCrease, dresser->top + kDresserTopThick + 1, dresser->left + kDresserCrease, dresser->bottom - 4, k8Red4Color); ColorLine(dresser->right - kDresserCrease, dresser->top + kDresserTopThick + 1, dresser->right - kDresserCrease, dresser->bottom - 4, k8OrangeColor); nRects = RectTall(dresser) / 30; if (nRects == 0) nRects = 1; height = (RectTall(dresser) - 14) / nRects - 4; QSetRect(&tempRect, 0, 0, RectWide(dresser) - kDresserSideSpare, height); QOffsetRect(&tempRect, dresser->left + 7, dresser->top + 10); for (i = 0; i < nRects; i++) { ColorLine(tempRect.left + 1, tempRect.bottom, tempRect.right, tempRect.bottom, dkstRedC); ColorLine(tempRect.right, tempRect.top + 1, tempRect.right, tempRect.bottom, dkstRedC); ColorRect(&tempRect, yellowC); HiliteRect(&tempRect, ltTanC, brownC); InsetRect(&tempRect, 1, 1); HiliteRect(&tempRect, ltTanC, brownC); InsetRect(&tempRect, -1, -1); QSetRect(&dest, -4, -4, 4, 4); QOffsetRect(&dest, HalfRectTall(&tempRect), HalfRectTall(&tempRect)); QOffsetRect(&dest, tempRect.left, tempRect.top); CopyBits((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &knobSrc, &dest, srcCopy, nil); QSetRect(&dest, -4, -4, 4, 4); QOffsetRect(&dest, -HalfRectTall(&tempRect), HalfRectTall(&tempRect)); QOffsetRect(&dest, tempRect.right, tempRect.top); CopyBits((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &knobSrc, &dest, srcCopy, nil); QOffsetRect(&tempRect, 0, kDresserTopThick + height); } SetGWorld(wasCPort, wasWorld); dest = leftFootSrc; ZeroRectCorner(&dest); QOffsetRect(&dest, dresser->left + 6, dresser->bottom - 2); CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &leftFootSrc, &leftFootSrc, &dest); dest = rightFootSrc; ZeroRectCorner(&dest); QOffsetRect(&dest, dresser->right - 19, dresser->bottom - 2); CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &rightFootSrc, &rightFootSrc, &dest); } //-------------------------------------------------------------- DrawDeckTable void DrawDeckTable (Rect *tableTop, short down) { #define kTableBaseTop 296 #define kTableShadowTop 312 #define kTableShadowOffset 12 Rect tempRect; long bambooC, brownC, dkGrayC; short hCenter, vShadow; CGrafPtr wasCPort; GDHandle wasWorld; Pattern dummyPattern; if (thisMac.isDepth == 4) { bambooC = 6; brownC = 11; dkGrayC = 14; } else { bambooC = k8BambooColor; brownC = k8BrownColor; dkGrayC = k8DkstGrayColor; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); QSetRect(&tempRect, tableTop->left, 0, tableTop->right, RectWide(tableTop) / 10); QOffsetRect(&tempRect, 0, -HalfRectTall(&tempRect) + kTableShadowTop + down); QOffsetRect(&tempRect, kTableShadowOffset, -kTableShadowOffset); PenPat(GetQDGlobalsGray(&dummyPattern)); PenMode(patOr); ColorOval(&tempRect, dkGrayC); PenNormal(); InsetRect(tableTop, 0, 1); ColorRect(tableTop, kGoldColor); InsetRect(tableTop, 0, -1); ColorLine(tableTop->left, tableTop->top + 1, tableTop->left, tableTop->top + 1, k8WhiteColor); ColorLine(tableTop->left + 1, tableTop->top, tableTop->right - 2, tableTop->top, k8WhiteColor); ColorLine(tableTop->right - 1, tableTop->top + 1, tableTop->right - 1, tableTop->top + 1, k8WhiteColor); ColorLine(tableTop->left + 1, tableTop->top + 1, tableTop->right - 2, tableTop->top + 1, kYellowColor); ColorLine(tableTop->left, tableTop->top + 2, tableTop->left, tableTop->bottom - 2, kYellowColor); ColorLine(tableTop->left + 1, tableTop->bottom - 1, tableTop->right - 2, tableTop->bottom - 1, brownC); ColorLine(tableTop->right - 1, tableTop->top + 2, tableTop->right - 1, tableTop->bottom - 2, brownC); ColorLine(tableTop->left + 1, tableTop->bottom - 2, tableTop->right - 2, tableTop->bottom - 2, bambooC); if (tableTop->bottom < kTableBaseTop + down) { hCenter = (tableTop->left + tableTop->right) / 2; ColorLine(hCenter - 3, tableTop->bottom, hCenter - 3, kTableBaseTop + down, dkGrayC); ColorLine(hCenter - 2, tableTop->bottom, hCenter - 2, kTableBaseTop + down, k8WhiteColor); ColorLine(hCenter - 1, tableTop->bottom, hCenter - 1, kTableBaseTop + down, k8WhiteColor); ColorLine(hCenter, tableTop->bottom, hCenter, kTableBaseTop + down, k8LtGrayColor); ColorLine(hCenter + 1, tableTop->bottom, hCenter + 1, kTableBaseTop + down, dkGrayC); vShadow = tableTop->bottom + RectWide(tableTop) / 4 - 2; if (vShadow > kTableBaseTop + down) { ColorLine(hCenter - 2, tableTop->bottom, hCenter - 2, kTableBaseTop + down, k8LtGrayColor); ColorLine(hCenter - 1, tableTop->bottom, hCenter - 1, kTableBaseTop + down, k8LtGrayColor); ColorLine(hCenter, tableTop->bottom, hCenter, kTableBaseTop + down, dkGrayC); } else { ColorLine(hCenter - 2, tableTop->bottom, hCenter - 2, vShadow, k8LtGrayColor); ColorLine(hCenter - 1, tableTop->bottom, hCenter - 1, vShadow + 1, k8LtGrayColor); ColorLine(hCenter, tableTop->bottom, hCenter, vShadow + 2, dkGrayC); } } SetGWorld(wasCPort, wasWorld); tempRect = deckSrc; ZeroRectCorner(&tempRect); QOffsetRect(&tempRect, -HalfRectWide(&deckSrc) + tableTop->left + HalfRectWide(tableTop), kTableBaseTop + down); CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &deckSrc, &deckSrc, &tempRect); } //-------------------------------------------------------------- DrawStool void DrawStool (Rect *theRect, short down) { #define kStoolBase 304 long grayC, dkGrayC; CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); if (thisMac.isDepth == 4) { grayC = 13; dkGrayC = 14; } else { grayC = k8DkGray2Color; dkGrayC = k8DkstGrayColor; } if (theRect->bottom < kStoolBase + down) { ColorLine(theRect->left + 21, theRect->bottom - 1, theRect->left + 21, kStoolBase + down - 1, k8DkGrayColor); ColorLine(theRect->left + 22, theRect->bottom - 1, theRect->left + 22, kStoolBase + down, k8Gray2Color); ColorLine(theRect->left + 23, theRect->bottom - 1, theRect->left + 23, kStoolBase + down, k8DkGrayColor); ColorLine(theRect->left + 24, theRect->bottom - 1, theRect->left + 24, kStoolBase + down, k8DkGray3Color); ColorLine(theRect->left + 25, theRect->bottom - 1, theRect->left + 25, kStoolBase + down, grayC); ColorLine(theRect->left + 26, theRect->bottom - 1, theRect->left + 26, kStoolBase + down - 1, dkGrayC); } SetGWorld(wasCPort, wasWorld); CopyMask((BitMap *)*GetGWorldPixMap(furnitureSrcMap), (BitMap *)*GetGWorldPixMap(furnitureMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kStool], &srcRects[kStool], theRect); } //-------------------------------------------------------------- DrawInvisObstacle void DrawInvisObstacle (Rect *theRect) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorFrameRect(theRect, k8BrownColor); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawInvisBounce void DrawInvisBounce (Rect *theRect) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorFrameRect(theRect, k8RedColor); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawRedClock void DrawRedClock (Rect *theRect) { DateTimeRec timeRec; Rect dest; short hour, minutes; CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kRedClock], &srcRects[kRedClock], theRect); GetTime(&timeRec); hour = timeRec.hour % 12; if (hour == 0) hour = 12; minutes = timeRec.minute; QSetRect(&dest, 0, 0, 4, 6); QOffsetRect(&dest, theRect->left + 5, theRect->top + 7); if (hour > 9) DrawClockDigit(hour / 10, &dest); QOffsetRect(&dest, 4, 0); DrawClockDigit(hour % 10, &dest); QOffsetRect(&dest, 6, 0); DrawClockDigit(minutes / 10, &dest); QOffsetRect(&dest, 4, 0); DrawClockDigit(minutes % 10, &dest); } //-------------------------------------------------------------- DrawClockDigit void DrawClockDigit (short number, Rect *dest) { CopyBits((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &digits[number], dest, srcCopy, nil); } //-------------------------------------------------------------- DrawBlueClock void DrawBlueClock (Rect *theRect) { DateTimeRec timeRec; Point dest; short hour, minutes; CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kBlueClock], &srcRects[kBlueClock], theRect); dest.h = theRect->left + 13; dest.v = theRect->top + 13; GetTime(&timeRec); hour = timeRec.hour % 12; minutes = ((timeRec.minute + 2) / 5) % 12; DrawClockHands(dest, minutes, hour); } //-------------------------------------------------------------- DrawYellowClock void DrawYellowClock (Rect *theRect) { DateTimeRec timeRec; Point dest; short hour, minutes; CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kYellowClock], &srcRects[kYellowClock], theRect); dest.h = theRect->left + 13; dest.v = theRect->top + 15; GetTime(&timeRec); hour = timeRec.hour % 12; minutes = ((timeRec.minute + 2) / 5) % 12; DrawClockHands(dest, minutes, hour); } //-------------------------------------------------------------- DrawCuckoo void DrawCuckoo (Rect *theRect) { DateTimeRec timeRec; Point dest; short hour, minutes; CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kCuckoo], &srcRects[kCuckoo], theRect); dest.h = theRect->left + 19; dest.v = theRect->top + 31; GetTime(&timeRec); hour = timeRec.hour % 12; minutes = ((timeRec.minute + 2) / 5) % 12; DrawLargeClockHands(dest, minutes, hour); } //-------------------------------------------------------------- DrawClockHands void DrawClockHands (Point where, short bigHand, short littleHand) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); MoveTo(where.h, where.v); switch (bigHand) { case 0: Line(0, -6); break; case 1: Line(3, -5); break; case 2: Line(5, -3); break; case 3: Line(6, 0); break; case 4: Line(5, 3); break; case 5: Line(3, 5); break; case 6: Line(0, 6); break; case 7: Line(-3, 5); break; case 8: Line(-5, 3); break; case 9: Line(-6, 0); break; case 10: Line(-5, -3); break; case 11: Line(-3, -5); break; } MoveTo(where.h, where.v); switch (littleHand) { case 0: Line(0, -4); break; case 1: Line(2, -3); break; case 2: Line(3, -2); break; case 3: Line(4, 0); break; case 4: Line(3, 2); break; case 5: Line(2, 3); break; case 6: Line(0, 4); break; case 7: Line(-2, 3); break; case 8: Line(-3, 2); break; case 9: Line(-4, 0); break; case 10: Line(-3, -2); break; case 11: Line(-2, -3); break; } SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawClockHands void DrawLargeClockHands (Point where, short bigHand, short littleHand) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ForeColor(whiteColor); MoveTo(where.h, where.v); switch (bigHand) { case 0: Line(0, -10); break; case 1: Line(5, -9); break; case 2: Line(9, -5); break; case 3: Line(10, 0); break; case 4: Line(9, 5); break; case 5: Line(5, 9); break; case 6: Line(0, 10); break; case 7: Line(-5, 9); break; case 8: Line(-9, 5); break; case 9: Line(-10, 0); break; case 10: Line(-9, -5); break; case 11: Line(-5, -9); break; } MoveTo(where.h, where.v); switch (littleHand) { case 0: Line(0, -6); break; case 1: Line(3, -5); break; case 2: Line(5, -3); break; case 3: Line(6, 0); break; case 4: Line(5, 3); break; case 5: Line(3, 5); break; case 6: Line(0, 6); break; case 7: Line(-3, 5); break; case 8: Line(-5, 3); break; case 9: Line(-6, 0); break; case 10: Line(-5, -3); break; case 11: Line(-3, -5); break; } ForeColor(blackColor); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawSimplePrizes void DrawSimplePrizes (short what, Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], &srcRects[what], theRect); } //-------------------------------------------------------------- DrawGreaseRt void DrawGreaseRt (Rect *theRect, short distance, Boolean state) { Rect spill, dest; CGrafPtr wasCPort; GDHandle wasWorld; dest = *theRect; if (state) // grease upright { CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &greaseSrcRt[0], &greaseSrcRt[0], &dest); } else // grease spilled { QOffsetRect(&dest, 6, 0); CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &greaseSrcRt[3], &greaseSrcRt[3], &dest); GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); QSetRect(&spill, 0, -2, distance - 5, 0); QOffsetRect(&spill, dest.right - 1, dest.bottom); PaintRect(&spill); SetGWorld(wasCPort, wasWorld); } } //-------------------------------------------------------------- DrawGreaseLf void DrawGreaseLf (Rect *theRect, short distance, Boolean state) { Rect spill, dest; CGrafPtr wasCPort; GDHandle wasWorld; dest = *theRect; if (state) // grease upright { CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &greaseSrcLf[0], &greaseSrcLf[0], &dest); } else // grease spilled { QOffsetRect(&dest, -6, 0); CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &greaseSrcLf[3], &greaseSrcLf[3], &dest); GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); QSetRect(&spill, -distance + 5, -2, 0, 0); QOffsetRect(&spill, dest.left + 1, dest.bottom); PaintRect(&spill); SetGWorld(wasCPort, wasWorld); } } //-------------------------------------------------------------- DrawBands void DrawFoil (Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(bonusSrcMap), (BitMap *)*GetGWorldPixMap(bonusMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kFoil], &srcRects[kFoil], theRect); } //-------------------------------------------------------------- DrawInvisBonus void DrawInvisBonus (Rect *theRect) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorFrameOval(theRect, 227); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawSlider void DrawSlider (Rect *theRect) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); FrameRect(theRect); SetGWorld(wasCPort, wasWorld); } \ No newline at end of file diff --git a/Sources/ObjectDraw2.c b/Sources/ObjectDraw2.c deleted file mode 100755 index 984f542..0000000 --- a/Sources/ObjectDraw2.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // ObjectDraw2.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Externs.h" #include "Environ.h" #include "Objects.h" #include "RectUtils.h" #include "Room.h" #include "Utilities.h" #define k8WhiteColor 0 #define kIntenseYellowColor 5 #define kPaleVioletColor 42 #define kDarkFleshColor 58 #define k8TanColor 94 #define k8PissYellowColor 95 #define k8BrownColor 137 #define k8SkyColor 150 #define k8EarthBlueColor 170 #define k8DkRed2Color 223 #define kIntenseGreenColor 225 #define kIntenseBlueColor 235 #define k8LtstGrayColor 245 #define k8LtstGray4Color 247 #define k8LtstGray5Color 248 #define k8LtGrayColor 249 #define k8Gray2Color 251 #define k8DkGrayColor 252 #define k8DkGray2Color 253 #define kBBQMaskID 3900 #define kUpStairsMaskID 3901 #define kTrunkMaskID 3902 #define kMailboxRightMaskID 3903 #define kMailboxLeftMaskID 3904 #define kDoorInLeftMaskID 3905 #define kDoorInRightMaskID 3906 #define kWindowInLeftMaskID 3907 #define kWindowInRightMaskID 3908 #define kHipLampMaskID 3909 #define kDecoLampMaskID 3910 #define kGuitarMaskID 3911 #define kTVMaskID 3912 #define kVCRMaskID 3913 #define kStereoMaskID 3914 #define kMicrowaveMaskID 3915 #define kFireplaceMaskID 3916 #define kBearMaskID 3917 #define kVase1MaskID 3918 #define kVase2MaskID 3919 #define kManholeMaskID 3920 #define kBooksMaskID 3922 #define kCloudMaskID 3921 #define kRugMaskID 3923 #define kChimesMaskID 3924 #define kCinderMaskID 3925 #define kFlowerBoxMaskID 3926 #define kCobwebMaskID 3927 #define kCobwebPictID 3958 #define kFlowerBoxPictID 3959 #define kCinderPictID 3960 #define kChimesPictID 3961 #define kRugPictID 3962 #define kBooksPictID 3964 #define kCloudPictID 3965 #define kBulletinPictID 3966 #define kManholePictID 3967 #define kVase2PictID 3968 #define kVase1PictID 3969 #define kCalendarPictID 3970 #define kMicrowavePictID 3971 #define kBearPictID 3972 #define kFireplacePictID 3973 #define kOzmaPictID 3975 #define kWindowExRightPictID 3977 #define kWindowExLeftPictID 3978 #define kWindowInRightPictID 3979 #define kWindowInLeftPictID 3980 #define kDoorExLeftPictID 3981 #define kDoorExRightPictID 3982 #define kDoorInRightPictID 3983 #define kDoorInLeftPictID 3984 #define kMailboxRightPictID 3985 #define kMailboxLeftPictID 3986 #define kTrunkPictID 3987 #define kBBQPictID 3988 #define kStereoPictID 3989 #define kVCRPictID 3990 #define kGuitarPictID 3991 #define kTVPictID 3992 #define kDecoLampPictID 3993 #define kHipLampPictID 3994 #define kFilingCabinetPictID 3995 #define kDownStairsPictID 3996 #define kUpStairsPictID 3997 #define kMailboxBase 296 #define kMonthStringID 1005 //============================================================== Functions //-------------------------------------------------------------- DrawMailboxLeft void DrawMailboxLeft (Rect *theRect, short down) { Rect bounds; GWorldPtr tempMap; GWorldPtr tempMask; long darkGrayC, lightWoodC, darkWoodC; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); if (thisMac.isDepth == 4) { darkGrayC = 13; lightWoodC = 9; darkWoodC = 11; } else { darkGrayC = k8DkGray2Color; lightWoodC = k8PissYellowColor; darkWoodC = k8BrownColor; } if (theRect->bottom < down + kMailboxBase) { ColorLine(theRect->left + 49, theRect->bottom, theRect->left + 49, down + kMailboxBase, darkGrayC); ColorLine(theRect->left + 50, theRect->bottom, theRect->left + 50, down + kMailboxBase + 1, lightWoodC); ColorLine(theRect->left + 51, theRect->bottom, theRect->left + 51, down + kMailboxBase + 2, lightWoodC); ColorLine(theRect->left + 52, theRect->bottom, theRect->left + 52, down + kMailboxBase + 3, lightWoodC); ColorLine(theRect->left + 53, theRect->bottom, theRect->left + 53, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 54, theRect->bottom, theRect->left + 54, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 55, theRect->bottom, theRect->left + 55, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 56, theRect->bottom, theRect->left + 56, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 57, theRect->bottom, theRect->left + 57, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 58, theRect->bottom, theRect->left + 58, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 59, theRect->bottom, theRect->left + 59, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 60, theRect->bottom, theRect->left + 60, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 61, theRect->bottom, theRect->left + 61, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 62, theRect->bottom, theRect->left + 62, down + kMailboxBase + 3, darkGrayC); } SetGWorld(wasCPort, wasWorld); bounds = srcRects[kMailboxLf]; theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(kMailboxLeftPictID); theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); SetGWorld(tempMask, nil); LoadGraphic(kMailboxLeftMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(tempMask), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kMailboxLf], &srcRects[kMailboxLf], theRect); SetGWorld(wasCPort, wasWorld); DisposeGWorld(tempMap); DisposeGWorld(tempMask); // SetPort((GrafPtr)backSrcMap); } //-------------------------------------------------------------- DrawMailboxRight void DrawMailboxRight (Rect *theRect, short down) { Rect bounds; GWorldPtr tempMap; GWorldPtr tempMask; long darkGrayC, lightWoodC, darkWoodC; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); if (thisMac.isDepth == 4) { darkGrayC = 13; lightWoodC = 9; darkWoodC = 11; } else { darkGrayC = k8DkGray2Color; lightWoodC = k8PissYellowColor; darkWoodC = k8BrownColor; } if (theRect->bottom < down + kMailboxBase) { ColorLine(theRect->left + 34, theRect->bottom, theRect->left + 34, down + kMailboxBase, darkGrayC); ColorLine(theRect->left + 35, theRect->bottom, theRect->left + 35, down + kMailboxBase + 1, lightWoodC); ColorLine(theRect->left + 36, theRect->bottom, theRect->left + 36, down + kMailboxBase + 2, lightWoodC); ColorLine(theRect->left + 37, theRect->bottom, theRect->left + 37, down + kMailboxBase + 3, lightWoodC); ColorLine(theRect->left + 38, theRect->bottom, theRect->left + 38, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 39, theRect->bottom, theRect->left + 39, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 40, theRect->bottom, theRect->left + 40, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 41, theRect->bottom, theRect->left + 41, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 42, theRect->bottom, theRect->left + 42, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 43, theRect->bottom, theRect->left + 43, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 44, theRect->bottom, theRect->left + 44, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 45, theRect->bottom, theRect->left + 45, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 46, theRect->bottom, theRect->left + 46, down + kMailboxBase + 3, darkWoodC); ColorLine(theRect->left + 47, theRect->bottom, theRect->left + 47, down + kMailboxBase + 3, darkGrayC); } SetGWorld(wasCPort, wasWorld); bounds = srcRects[kMailboxRt]; theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(kMailboxRightPictID); theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); SetGWorld(tempMask, nil); LoadGraphic(kMailboxRightMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(tempMask), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kMailboxRt], &srcRects[kMailboxRt], theRect); SetGWorld(wasCPort, wasWorld); DisposeGWorld(tempMap); DisposeGWorld(tempMask); // SetPort((GrafPtr)backSrcMap); } //-------------------------------------------------------------- DrawSimpleTransport void DrawSimpleTransport (short what, Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(transSrcMap), (BitMap *)*GetGWorldPixMap(transMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], &srcRects[what], theRect); } //-------------------------------------------------------------- DrawInvisTransport void DrawInvisTransport (Rect *theRect) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorFrameRect(theRect, 32); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawLightSwitch void DrawLightSwitch (Rect *theRect, Boolean state) { if (state) { CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &lightSwitchSrc[0], theRect, srcCopy, nil); } else { CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &lightSwitchSrc[1], theRect, srcCopy, nil); } } //-------------------------------------------------------------- DrawMachineSwitch void DrawMachineSwitch (Rect *theRect, Boolean state) { if (state) CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &machineSwitchSrc[0], theRect, srcCopy, nil); else CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &machineSwitchSrc[1], theRect, srcCopy, nil); } //-------------------------------------------------------------- DrawThermostat void DrawThermostat (Rect *theRect, Boolean state) { if (state) CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &thermostatSrc[0], theRect, srcCopy, nil); else CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &thermostatSrc[1], theRect, srcCopy, nil); } //-------------------------------------------------------------- DrawPowerSwitch void DrawPowerSwitch (Rect *theRect, Boolean state) { if (state) CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &powerSrc[0], theRect, srcCopy, nil); else CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &powerSrc[1], theRect, srcCopy, nil); } //-------------------------------------------------------------- DrawKnifeSwitch void DrawKnifeSwitch (Rect *theRect, Boolean state) { if (state) CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &knifeSwitchSrc[0], theRect, srcCopy, nil); else CopyBits((BitMap *)*GetGWorldPixMap(switchSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &knifeSwitchSrc[1], theRect, srcCopy, nil); } //-------------------------------------------------------------- DrawInvisibleSwitch void DrawInvisibleSwitch (Rect *theRect) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorFrameRect(theRect, kIntenseGreenColor); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawTrigger void DrawTrigger (Rect *theRect) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorFrameRect(theRect, kIntenseBlueColor); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawSoundTrigger void DrawSoundTrigger (Rect *theRect) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorFrameRect(theRect, kIntenseYellowColor); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawSimpleLight void DrawSimpleLight (short what, Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), (BitMap *)*GetGWorldPixMap(lightMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], &srcRects[what], theRect); } //-------------------------------------------------------------- DrawFlourescent void DrawFlourescent (Rect *theRect) { Rect partRect; long grayC, gray2C, gray3C, gray4C, violetC; CGrafPtr wasCPort; GDHandle wasWorld; if (thisMac.isDepth == 4) { grayC = 7L; gray2C = 5L; gray3C = 4L; gray4C = 1L; violetC = 3L; } else { grayC = k8LtGrayColor; gray2C = k8LtstGray5Color; gray3C = k8LtstGray4Color; gray4C = k8LtstGrayColor; violetC = kPaleVioletColor; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorLine(theRect->left + 16, theRect->top, theRect->right - 17, theRect->top, grayC); ColorLine(theRect->left + 16, theRect->top + 1, theRect->right - 17, theRect->top + 1, gray2C); ColorLine(theRect->left + 16, theRect->top + 2, theRect->right - 17, theRect->top + 2, gray2C); ColorLine(theRect->left + 16, theRect->top + 3, theRect->right - 17, theRect->top + 3, gray3C); ColorLine(theRect->left + 16, theRect->top + 4, theRect->right - 17, theRect->top + 4, gray4C); ColorLine(theRect->left + 16, theRect->top + 5, theRect->right - 17, theRect->top + 5, violetC); ColorLine(theRect->left + 16, theRect->top + 6, theRect->right - 17, theRect->top + 6, k8WhiteColor); ColorLine(theRect->left + 16, theRect->top + 7, theRect->right - 17, theRect->top + 7, k8WhiteColor); ColorLine(theRect->left + 16, theRect->top + 8, theRect->right - 17, theRect->top + 8, k8WhiteColor); ColorLine(theRect->left + 16, theRect->top + 9, theRect->right - 17, theRect->top + 9, k8WhiteColor); ColorLine(theRect->left + 16, theRect->top + 10, theRect->right - 17, theRect->top + 10, k8WhiteColor); ColorLine(theRect->left + 16, theRect->top + 11, theRect->right - 17, theRect->top + 11, violetC); SetGWorld(wasCPort, wasWorld); partRect = flourescentSrc1; ZeroRectCorner(&partRect); QOffsetRect(&partRect, theRect->left, theRect->top); CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), (BitMap *)*GetGWorldPixMap(lightMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &flourescentSrc1, &flourescentSrc1, &partRect); partRect = flourescentSrc2; ZeroRectCorner(&partRect); QOffsetRect(&partRect, -partRect.right, 0); QOffsetRect(&partRect, theRect->right, theRect->top); CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), (BitMap *)*GetGWorldPixMap(lightMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &flourescentSrc2, &flourescentSrc2, &partRect); } //-------------------------------------------------------------- DrawTrackLight void DrawTrackLight (Rect *theRect) { #define kTrackLightSpacing 64 Rect partRect; long grayC, gray2C, gray3C, gray4C; short which, howMany, i, spread; CGrafPtr wasCPort; GDHandle wasWorld; if (thisMac.isDepth == 4) { grayC = 7L; gray2C = 8L; gray3C = 4L; gray4C = 11L; } else { grayC = k8LtGrayColor; gray2C = k8Gray2Color; gray3C = k8LtstGray4Color; gray4C = k8DkGrayColor; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorLine(theRect->left, theRect->top - 3, theRect->right - 1, theRect->top - 3, gray2C); ColorLine(theRect->left, theRect->top - 2, theRect->right - 1, theRect->top - 2, grayC); ColorLine(theRect->left, theRect->top - 1, theRect->right - 1, theRect->top - 1, grayC); ColorLine(theRect->left, theRect->top, theRect->right - 1, theRect->top, gray3C); ColorLine(theRect->left, theRect->top + 1, theRect->right - 1, theRect->top + 1, gray4C); ColorLine(theRect->left, theRect->top + 2, theRect->right - 1, theRect->top + 2, gray3C); SetGWorld(wasCPort, wasWorld); partRect = trackLightSrc[0]; // left most track light ZeroRectCorner(&partRect); QOffsetRect(&partRect, theRect->left, theRect->top); which = 0; CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), (BitMap *)*GetGWorldPixMap(lightMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &trackLightSrc[which], &trackLightSrc[which], &partRect); partRect = trackLightSrc[0]; // right most track light ZeroRectCorner(&partRect); QOffsetRect(&partRect, -partRect.right, 0); QOffsetRect(&partRect, theRect->right, theRect->top); which = 2; CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), (BitMap *)*GetGWorldPixMap(lightMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &trackLightSrc[which], &trackLightSrc[which], &partRect); howMany = ((RectWide(theRect) - RectWide(&trackLightSrc[0])) / kTrackLightSpacing) - 1; if (howMany > 0) { which = 0; spread = (RectWide(theRect) - RectWide(&trackLightSrc[0])) / (howMany + 1); for (i = 0; i < howMany; i++) { partRect = trackLightSrc[0]; // filler track lights ZeroRectCorner(&partRect); QOffsetRect(&partRect, theRect->left, theRect->top); QOffsetRect(&partRect, spread * (i + 1), 0); which++; if (which >= kNumTrackLights) which = 0; CopyMask((BitMap *)*GetGWorldPixMap(lightSrcMap), (BitMap *)*GetGWorldPixMap(lightMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &trackLightSrc[which], &trackLightSrc[which], &partRect); } } } //-------------------------------------------------------------- DrawInvisLight void DrawInvisLight (Rect *theRect) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); ColorFrameOval(theRect, 17); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawSimpleAppliance void DrawSimpleAppliance (short what, Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(applianceMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], &srcRects[what], theRect); } //-------------------------------------------------------------- DrawMacPlus void DrawMacPlus (Rect *theRect, Boolean isOn, Boolean isLit) { Rect screen; if (isLit) { CopyMask((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(applianceMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kMacPlus], &srcRects[kMacPlus], theRect); } screen = plusScreen1; ZeroRectCorner(&screen); QOffsetRect(&screen, theRect->left + 10, theRect->top + 7); if (isOn) { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &plusScreen2, &screen, srcCopy, nil); } else { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &plusScreen1, &screen, srcCopy, nil); } } //-------------------------------------------------------------- DrawTV void DrawTV (Rect *theRect, Boolean isOn, Boolean isLit) { Rect bounds; GWorldPtr tempMap; GWorldPtr tempMask; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; if (isLit) { GetGWorld(&wasCPort, &wasWorld); bounds = srcRects[kTV]; theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(kTVPictID); theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); SetGWorld(tempMask, nil); LoadGraphic(kTVMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(tempMask), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kTV], &srcRects[kTV], theRect); SetGWorld(wasCPort, wasWorld); DisposeGWorld(tempMap); DisposeGWorld(tempMask); // SetPort((GrafPtr)backSrcMap); } bounds = tvScreen1; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theRect->left + 17, theRect->top + 10); if (isOn) { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &tvScreen2, &bounds, srcCopy, nil); } else { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &tvScreen1, &bounds, srcCopy, nil); } } //-------------------------------------------------------------- DrawCoffee void DrawCoffee (Rect *theRect, Boolean isOn, Boolean isLit) { Rect light; if (isLit) { CopyMask((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(applianceMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kCoffee], &srcRects[kCoffee], theRect); } light = coffeeLight1; ZeroRectCorner(&light); QOffsetRect(&light, theRect->left + 32, theRect->top + 57); if (isOn) { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &coffeeLight2, &light, srcCopy, nil); } else { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &coffeeLight1, &light, srcCopy, nil); } } //-------------------------------------------------------------- DrawOutlet void DrawOutlet (Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(applianceMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kOutlet], &srcRects[kOutlet], theRect); } //-------------------------------------------------------------- DrawVCR void DrawVCR (Rect *theRect, Boolean isOn, Boolean isLit) { Rect bounds; GWorldPtr tempMap; GWorldPtr tempMask; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; if (isLit) { GetGWorld(&wasCPort, &wasWorld); bounds = srcRects[kVCR]; theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(kVCRPictID); theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); SetGWorld(tempMask, nil); LoadGraphic(kVCRMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(tempMask), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kVCR], &srcRects[kVCR], theRect); SetGWorld(wasCPort, wasWorld); DisposeGWorld(tempMap); DisposeGWorld(tempMask); // SetPort((GrafPtr)backSrcMap); } bounds = vcrTime1; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theRect->left + 64, theRect->top + 6); if (isOn) { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &vcrTime2, &bounds, srcCopy, nil); } else { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &vcrTime1, &bounds, srcCopy, nil); } } //-------------------------------------------------------------- DrawStereo void DrawStereo (Rect *theRect, Boolean isOn, Boolean isLit) { Rect bounds; GWorldPtr tempMap; GWorldPtr tempMask; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; if (isLit) { GetGWorld(&wasCPort, &wasWorld); bounds = srcRects[kStereo]; theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(kStereoPictID); theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); SetGWorld(tempMask, nil); LoadGraphic(kStereoMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(tempMask), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kStereo], &srcRects[kStereo], theRect); SetGWorld(wasCPort, wasWorld); DisposeGWorld(tempMap); DisposeGWorld(tempMask); // SetPort((GrafPtr)backSrcMap); } bounds = stereoLight1; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theRect->left + 56, theRect->top + 20); if (isOn) { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &stereoLight2, &bounds, srcCopy, nil); } else { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &stereoLight1, &bounds, srcCopy, nil); } } //-------------------------------------------------------------- DrawMicrowave void DrawMicrowave (Rect *theRect, Boolean isOn, Boolean isLit) { Rect bounds; GWorldPtr tempMap; GWorldPtr tempMask; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; if (isLit) { GetGWorld(&wasCPort, &wasWorld); bounds = srcRects[kMicrowave]; theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(kMicrowavePictID); theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); SetGWorld(tempMask, nil); LoadGraphic(kMicrowaveMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(tempMask), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[kMicrowave], &srcRects[kMicrowave], theRect); SetGWorld(wasCPort, wasWorld); DisposeGWorld(tempMap); DisposeGWorld(tempMask); // SetPort((GrafPtr)backSrcMap); } bounds = microOn; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theRect->left + 14, theRect->top + 13); if (isOn) { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOn, &bounds, srcCopy, nil); QOffsetRect(&bounds, 16, 0); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOn, &bounds, srcCopy, nil); QOffsetRect(&bounds, 16, 0); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOn, &bounds, srcCopy, nil); } else if (isLit) { CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOff, &bounds, srcCopy, nil); QOffsetRect(&bounds, 16, 0); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOff, &bounds, srcCopy, nil); QOffsetRect(&bounds, 16, 0); CopyBits((BitMap *)*GetGWorldPixMap(applianceSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), µOff, &bounds, srcCopy, nil); } } //-------------------------------------------------------------- DrawBalloon void DrawBalloon (Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(balloonSrcMap), (BitMap *)*GetGWorldPixMap(balloonMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &balloonSrc[1], &balloonSrc[1], theRect); } //-------------------------------------------------------------- DrawCopter void DrawCopter (Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(copterSrcMap), (BitMap *)*GetGWorldPixMap(copterMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &copterSrc[1], &copterSrc[1], theRect); } //-------------------------------------------------------------- DrawDart void DrawDart (Rect *theRect, short which) { if (which == kDartLf) { CopyMask((BitMap *)*GetGWorldPixMap(dartSrcMap), (BitMap *)*GetGWorldPixMap(dartMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &dartSrc[0], &dartSrc[0], theRect); } else { CopyMask((BitMap *)*GetGWorldPixMap(dartSrcMap), (BitMap *)*GetGWorldPixMap(dartMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &dartSrc[2], &dartSrc[2], theRect); } } //-------------------------------------------------------------- DrawBall void DrawBall (short what, Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(ballSrcMap), (BitMap *)*GetGWorldPixMap(ballMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], &srcRects[what], theRect); } //-------------------------------------------------------------- DrawFish void DrawFish (short what, Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(enemySrcMap), (BitMap *)*GetGWorldPixMap(enemyMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], &srcRects[what], theRect); } //-------------------------------------------------------------- DrawDrip void DrawDrip (Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(dripSrcMap), (BitMap *)*GetGWorldPixMap(dripMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &dripSrc[3], &dripSrc[3], theRect); } //-------------------------------------------------------------- DrawMirror void DrawMirror (Rect *mirror) { Rect tempRect; long grayC; CGrafPtr wasCPort; GDHandle wasWorld; if (thisMac.isDepth == 4) { grayC = 13; } else { grayC = k8DkGray2Color; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); tempRect = *mirror; ColorRect(&tempRect, k8WhiteColor); ColorFrameRect(&tempRect, grayC); InsetRect(&tempRect, 1, 1); ColorFrameRect(&tempRect, k8EarthBlueColor); InsetRect(&tempRect, 1, 1); ColorFrameRect(&tempRect, k8EarthBlueColor); InsetRect(&tempRect, 1, 1); ColorFrameRect(&tempRect, grayC); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawSimpleClutter void DrawSimpleClutter (short what, Rect *theRect) { CopyMask((BitMap *)*GetGWorldPixMap(clutterSrcMap), (BitMap *)*GetGWorldPixMap(clutterMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], &srcRects[what], theRect); } //-------------------------------------------------------------- DrawFlower void DrawFlower (Rect *theRect, short which) { CopyMask((BitMap *)*GetGWorldPixMap(clutterSrcMap), (BitMap *)*GetGWorldPixMap(clutterMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &flowerSrc[which], &flowerSrc[which], theRect); } //-------------------------------------------------------------- DrawWallWindow void DrawWallWindow (Rect *window) { #define kWindowSillThick 7 Rect tempRect, tempRect2; long brownC, tanC, dkstRedC; short halfWay; CGrafPtr wasCPort; GDHandle wasWorld; if (thisMac.isDepth == 4) { brownC = 11; tanC = 9; dkstRedC = 15; } else { brownC = k8BrownColor; tanC = k8TanColor; dkstRedC = k8DkRed2Color; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); tempRect = *window; InsetRect(&tempRect, 3, 0); ColorRect(&tempRect, brownC); HiliteRect(&tempRect, tanC, dkstRedC); tempRect = *window; // top sill tempRect.bottom = tempRect.top + kWindowSillThick; tempRect.left++; tempRect.right--; ColorRect(&tempRect, brownC); HiliteRect(&tempRect, tanC, dkstRedC); tempRect.left--; tempRect.right++; tempRect.top += 2; tempRect.bottom -= 2; ColorRect(&tempRect, brownC); HiliteRect(&tempRect, tanC, dkstRedC); tempRect = *window; // bottom sill tempRect.top = tempRect.bottom - kWindowSillThick; QOffsetRect(&tempRect, 0, -4); tempRect.left++; tempRect.right--; ColorRect(&tempRect, brownC); HiliteRect(&tempRect, tanC, dkstRedC); tempRect.left--; tempRect.right++; tempRect.top += 2; tempRect.bottom -= 2; ColorRect(&tempRect, brownC); HiliteRect(&tempRect, tanC, dkstRedC); tempRect = *window; // inside frame tempRect.left += 8; tempRect.right -= 8; tempRect.top += 11; tempRect.bottom -= 15; HiliteRect(&tempRect, dkstRedC, tanC); halfWay = (tempRect.top + tempRect.bottom) / 2; tempRect2 = tempRect; // top pane tempRect2.bottom = halfWay + 2; InsetRect(&tempRect2, 5, 5); HiliteRect(&tempRect2, dkstRedC, tanC); InsetRect(&tempRect2, 1, 1); if (thisMac.isDepth == 4) ColorRect(&tempRect2, 5); else ColorRect(&tempRect2, k8SkyColor); tempRect2 = tempRect; // bottom pane tempRect2.top = halfWay - 3; InsetRect(&tempRect2, 5, 5); HiliteRect(&tempRect2, dkstRedC, tanC); InsetRect(&tempRect2, 1, 1); if (thisMac.isDepth == 4) ColorRect(&tempRect2, 5); else ColorRect(&tempRect2, k8SkyColor); ColorLine(tempRect2.left - 5, tempRect2.top - 7, tempRect2.right + 5, tempRect2.top - 7, tanC); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawCalendar void DrawCalendar (Rect *theRect) { DateTimeRec timeRec; Rect bounds; PicHandle thePicture; Str255 monthStr; CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); thePicture = GetPicture(kCalendarPictID); if (thePicture == nil) RedAlert(kErrFailedGraphicLoad); HLock((Handle)thePicture); bounds = (*thePicture)->picFrame; HUnlock((Handle)thePicture); QOffsetRect(&bounds, -bounds.left, -bounds.top); QOffsetRect(&bounds, theRect->left, theRect->top); DrawPicture(thePicture, &bounds); ReleaseResource((Handle)thePicture); SetPort((GrafPtr)backSrcMap); TextFace(bold); TextFont(applFont); TextSize(9); GetTime(&timeRec); GetIndString(monthStr, kMonthStringID, timeRec.month); MoveTo(theRect->left + ((64 - StringWidth(monthStr)) / 2), theRect->top + 55); ColorText(monthStr, kDarkFleshColor); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawBulletin void DrawBulletin (Rect *theRect) { Rect bounds; PicHandle thePicture; CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); thePicture = GetPicture(kBulletinPictID); if (thePicture == nil) RedAlert(kErrFailedGraphicLoad); HLock((Handle)thePicture); bounds = (*thePicture)->picFrame; HUnlock((Handle)thePicture); QOffsetRect(&bounds, -bounds.left, -bounds.top); QOffsetRect(&bounds, theRect->left, theRect->top); DrawPicture(thePicture, &bounds); ReleaseResource((Handle)thePicture); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawPictObject void DrawPictObject (short what, Rect *theRect) { Rect bounds; PicHandle thePicture; short pictID; CGrafPtr wasCPort; GDHandle wasWorld; switch (what) { case kFilingCabinet: pictID = kFilingCabinetPictID; break; case kDownStairs: pictID = kDownStairsPictID; break; case kDoorExRt: pictID = kDoorExRightPictID; break; case kDoorExLf: pictID = kDoorExLeftPictID; break; case kWindowExRt: pictID = kWindowExRightPictID; break; case kWindowExLf: pictID = kWindowExLeftPictID; break; case kOzma: pictID = kOzmaPictID; break; } GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); thePicture = GetPicture(pictID); if (thePicture == nil) RedAlert(kErrFailedGraphicLoad); bounds = srcRects[what]; QOffsetRect(&bounds, theRect->left, theRect->top); DrawPicture(thePicture, &bounds); ReleaseResource((Handle)thePicture); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- DrawPictWithMaskObject void DrawPictWithMaskObject (short what, Rect *theRect) { Rect bounds; GWorldPtr tempMap; GWorldPtr tempMask; short pictID, maskID; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); switch (what) { case kCobweb: pictID = kCobwebPictID; maskID = kCobwebMaskID; break; case kCloud: pictID = kCloudPictID; maskID = kCloudMaskID; break; } bounds = srcRects[what]; theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(pictID); theErr = CreateOffScreenGWorld(&tempMask, &bounds, 1); SetGWorld(tempMask, nil); LoadGraphic(maskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(tempMask), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], &srcRects[what], theRect); SetGWorld(wasCPort, wasWorld); DisposeGWorld(tempMap); DisposeGWorld(tempMask); // SetPort((GrafPtr)backSrcMap); } //-------------------------------------------------------------- DrawPictSansWhiteObject void DrawPictSansWhiteObject (short what, Rect *theRect) { Rect bounds; CGrafPtr tempMap; short pictID; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); switch (what) { case kBBQ: pictID = kBBQPictID; break; case kTrunk: pictID = kTrunkPictID; break; case kManhole: pictID = kManholePictID; break; case kBooks: pictID = kBooksPictID; break; case kUpStairs: pictID = kUpStairsPictID; break; case kDoorInLf: pictID = kDoorInLeftPictID; break; case kDoorInRt: pictID = kDoorInRightPictID; break; case kWindowInLf: pictID = kWindowInLeftPictID; break; case kWindowInRt: pictID = kWindowInRightPictID; break; case kHipLamp: pictID = kHipLampPictID; break; case kDecoLamp: pictID = kDecoLampPictID; break; case kGuitar: pictID = kGuitarPictID; break; case kCinderBlock: pictID = kCinderPictID; break; case kFlowerBox: pictID = kFlowerBoxPictID; break; case kFireplace: pictID = kFireplacePictID; break; case kBear: pictID = kBearPictID; break; case kVase1: pictID = kVase1PictID; break; case kVase2: pictID = kVase2PictID; break; case kRug: pictID = kRugPictID; break; case kChimes: pictID = kChimesPictID; break; } bounds = srcRects[what]; theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(pictID); CopyBits((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &srcRects[what], theRect, transparent, nil); SetGWorld(wasCPort, wasWorld); DisposeGWorld(tempMap); // SetPort((GrafPtr)backSrcMap); } //-------------------------------------------------------------- DrawCustPictSansWhite void DrawCustPictSansWhite (short pictID, Rect *theRect) { Rect bounds; GWorldPtr tempMap; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); bounds = *theRect; ZeroRectCorner(&bounds); theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredDepth); SetGWorld(tempMap, nil); LoadGraphic(pictID); CopyBits((BitMap *)*GetGWorldPixMap(tempMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &bounds, theRect, transparent, nil); SetGWorld(wasCPort, wasWorld); DisposeGWorld(tempMap); // SetPort((GrafPtr)backSrcMap); } \ No newline at end of file diff --git a/Sources/ObjectDrawAll.c b/Sources/ObjectDrawAll.c deleted file mode 100755 index ba65461..0000000 --- a/Sources/ObjectDrawAll.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // ObjectDrawAll.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" #include "RectUtils.h" extern Rect localRoomsDest[], movieRect; extern short localNumbers[]; extern short numLights, tvWithMovieNumber; extern Boolean tvOn; //============================================================== Functions //-------------------------------------------------------------- DrawARoomsObjects void DrawARoomsObjects (short neighbor, Boolean redraw) { objectType thisObject; Rect whoCares, itsRect, rectA, rectB, testRect; RgnHandle theRgn; short i, legit, dynamicNum, n; short floor, suite, room, obj; char wasState; Boolean isLit; if (localNumbers[neighbor] == kRoomIsEmpty) return; testRect = houseRect; ZeroRectCorner(&testRect); isLit = (numLights > 0); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); for (i = 0; i < kMaxRoomObs; i++) { dynamicNum = -1; legit = -1; if (IsThisValid(localNumbers[neighbor], i)) { thisObject = (*thisHouse)->rooms[localNumbers[neighbor]].objects[i]; switch (thisObject.what) { case kObjectIsEmpty: break; case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kLeftFan: case kRightFan: case kGrecoVent: case kSewerBlower: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawSimpleBlowers(thisObject.what, &itsRect); break; case kTaper: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (isLit) DrawSimpleBlowers(thisObject.what, &itsRect); if (neighbor == kCentralRoom) { if (redraw) ReBackUpFlames(localNumbers[neighbor], i); else AddCandleFlame(localNumbers[neighbor], i, itsRect.left + 10, itsRect.top + 7); } else { QSetRect(&rectA, 0, 0, 16, 15); QOffsetRect(&rectA, itsRect.left + 10 - 8, itsRect.top + 7 - 15); rectB = localRoomsDest[kCentralRoom]; rectB.top -= kFloorSupportTall; rectB.bottom += kFloorSupportTall; if (!SectRect(&rectA, &rectB, &whoCares)) { if (redraw) ReBackUpFlames(localNumbers[neighbor], i); else AddCandleFlame(localNumbers[neighbor], i, itsRect.left + 10, itsRect.top + 7); } } } break; case kCandle: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (isLit) DrawSimpleBlowers(thisObject.what, &itsRect); if (neighbor == kCentralRoom) { if (redraw) ReBackUpFlames(localNumbers[neighbor], i); else AddCandleFlame(localNumbers[neighbor], i, itsRect.left + 14, itsRect.top + 7); } else { QSetRect(&rectA, 0, 0, 16, 15); QOffsetRect(&rectA, itsRect.left + 14 - 8, itsRect.top + 7 - 15); rectB = localRoomsDest[kCentralRoom]; rectB.top -= kFloorSupportTall; rectB.bottom += kFloorSupportTall; if (!SectRect(&rectA, &rectB, &whoCares)) { if (redraw) ReBackUpFlames(localNumbers[neighbor], i); else AddCandleFlame(localNumbers[neighbor], i, itsRect.left + 14, itsRect.top + 7); } } } break; case kStubby: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (isLit) DrawSimpleBlowers(thisObject.what, &itsRect); if (neighbor == kCentralRoom) { if (redraw) ReBackUpFlames(localNumbers[neighbor], i); else AddCandleFlame(localNumbers[neighbor], i, itsRect.left + 9, itsRect.top + 7); } else { QSetRect(&rectA, 0, 0, 16, 15); QOffsetRect(&rectA, itsRect.left + 9 - 8, itsRect.top + 7 - 15); rectB = localRoomsDest[kCentralRoom]; rectB.top -= kFloorSupportTall; rectB.bottom += kFloorSupportTall; if (!SectRect(&rectA, &rectB, &whoCares)) { if (redraw) ReBackUpFlames(localNumbers[neighbor], i); else AddCandleFlame(localNumbers[neighbor], i, itsRect.left + 9, itsRect.top + 7); } } } break; case kTiki: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (isLit) DrawTiki(&itsRect, playOriginV + VerticalRoomOffset(neighbor)); if (redraw) ReBackUpTikiFlames(localNumbers[neighbor], i); else AddTikiFlame(localNumbers[neighbor], i, itsRect.left + 10, itsRect.top - 9); break; case kBBQ: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (isLit) DrawPictSansWhiteObject(thisObject.what, &itsRect); if (redraw) ReBackUpBBQCoals(localNumbers[neighbor], i); else AddBBQCoals(localNumbers[neighbor], i, itsRect.left + 16, itsRect.top + 9); } break; case kInvisBlower: case kLiftArea: break; case kTable: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (isLit) DrawTable(&itsRect, playOriginV); break; case kShelf: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (isLit) DrawShelf(&itsRect); break; case kCabinet: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawCabinet(&itsRect); break; case kFilingCabinet: case kOzma: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawPictObject(thisObject.what, &itsRect); break; case kWasteBasket: case kMilkCrate: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawSimpleFurniture(thisObject.what, &itsRect); break; case kCounter: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawCounter(&itsRect); break; case kDresser: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (isLit) DrawDresser(&itsRect); break; case kDeckTable: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (isLit) DrawDeckTable(&itsRect, playOriginV); break; case kStool: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (isLit) DrawStool(&itsRect, playOriginV + VerticalRoomOffset(neighbor)); break; case kInvisObstacle: break; case kManhole: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { AddTempManholeRect(&itsRect); if (isLit) DrawPictSansWhiteObject(thisObject.what, &itsRect); } break; case kInvisBounce: break; case kRedClock: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (redraw) legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); else legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); if (legit != -1) DrawRedClock(&itsRect); } break; case kBlueClock: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (redraw) legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); else legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); if (legit != -1) DrawBlueClock(&itsRect); } break; case kYellowClock: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (redraw) legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); else legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); if (legit != -1) DrawYellowClock(&itsRect); } break; case kCuckoo: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (redraw) legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); else legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); if (legit != -1) { DrawCuckoo(&itsRect); if (redraw) ReBackUpPendulum(localNumbers[neighbor], i); else AddPendulum(localNumbers[neighbor], i, itsRect.left + 4, itsRect.top + 46); } } break; case kPaper: case kBattery: case kBands: case kHelium: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (redraw) legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); else legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); if (legit != -1) DrawSimplePrizes(thisObject.what, &itsRect); } break; case kGreaseRt: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (thisObject.data.c.state) // standing { if (SectRect(&itsRect, &testRect, &whoCares)) { if (redraw) dynamicNum = ReBackUpGrease(localNumbers[neighbor], i); else dynamicNum = AddGrease(localNumbers[neighbor], i, itsRect.left, itsRect.top, thisObject.data.c.length, true); if (dynamicNum != -1) DrawGreaseRt(&itsRect, thisObject.data.c.length, true); } } else // fallen DrawGreaseRt(&itsRect, thisObject.data.c.length, false); break; case kGreaseLf: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (thisObject.data.c.state) { if (SectRect(&itsRect, &testRect, &whoCares)) { if (redraw) dynamicNum = ReBackUpGrease(localNumbers[neighbor], i); else dynamicNum = AddGrease(localNumbers[neighbor], i, itsRect.left, itsRect.top, thisObject.data.c.length, false); if (dynamicNum != -1) DrawGreaseLf(&itsRect, thisObject.data.c.length, true); } } else DrawGreaseLf(&itsRect, thisObject.data.c.length, false); break; case kFoil: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (redraw) legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); else legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); if (legit != -1) DrawFoil(&itsRect); } break; case kInvisBonus: case kSlider: break; case kStar: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (redraw) legit = ReBackUpSavedMap(&itsRect, localNumbers[neighbor], i); else legit = BackUpToSavedMap(&itsRect, localNumbers[neighbor], i); if (legit != -1) { if (redraw) ReBackUpStar(localNumbers[neighbor], i); else AddStar(localNumbers[neighbor], i, itsRect.left, itsRect.top); DrawSimplePrizes(thisObject.what, &itsRect); } } break; case kSparkle: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if ((!redraw) && (neighbor == kCentralRoom)) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kSparkle, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.c.state); } } break; case kUpStairs: case kDoorInLf: case kDoorInRt: case kWindowInLf: case kWindowInRt: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) DrawPictSansWhiteObject(thisObject.what, &itsRect); break; case kDownStairs: case kDoorExRt: case kDoorExLf: case kWindowExRt: case kWindowExLf: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) DrawPictObject(thisObject.what, &itsRect); break; case kMailboxLf: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); DrawMailboxLeft(&itsRect, playOriginV + VerticalRoomOffset(neighbor)); break; case kMailboxRt: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); DrawMailboxRight(&itsRect, playOriginV + VerticalRoomOffset(neighbor)); break; case kFloorTrans: case kCeilingTrans: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) DrawSimpleTransport(thisObject.what, &itsRect); break; case kInvisTrans: case kDeluxeTrans: break; case kLightSwitch: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); room = GetRoomNumber(floor, suite); obj = (short)thisObject.data.e.who; DrawLightSwitch(&itsRect, GetObjectState(room, obj)); } dynamicNum = masterObjects[i].hotNum; break; case kMachineSwitch: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); room = GetRoomNumber(floor, suite); obj = (short)thisObject.data.e.who; DrawMachineSwitch(&itsRect, GetObjectState(room, obj)); } dynamicNum = masterObjects[i].hotNum; break; case kThermostat: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); room = GetRoomNumber(floor, suite); obj = (short)thisObject.data.e.who; DrawThermostat(&itsRect, GetObjectState(room, obj)); } dynamicNum = masterObjects[i].hotNum; break; case kPowerSwitch: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); room = GetRoomNumber(floor, suite); obj = (short)thisObject.data.e.who; DrawPowerSwitch(&itsRect, GetObjectState(room, obj)); } dynamicNum = masterObjects[i].hotNum; break; case kKnifeSwitch: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { ExtractFloorSuite(thisObject.data.e.where, &floor, &suite); room = GetRoomNumber(floor, suite); obj = (short)thisObject.data.e.who; DrawKnifeSwitch(&itsRect, GetObjectState(room, obj)); } dynamicNum = masterObjects[i].hotNum; break; case kInvisSwitch: dynamicNum = masterObjects[i].hotNum; break; case kTrigger: case kLgTrigger: case kSoundTrigger: break; case kCeilingLight: case kLightBulb: case kTableLamp: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawSimpleLight(thisObject.what, &itsRect); break; case kTrunk: case kBooks: case kHipLamp: case kDecoLamp: case kGuitar: case kCinderBlock: case kFlowerBox: case kFireplace: case kBear: case kVase1: case kVase2: case kRug: case kChimes: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawPictSansWhiteObject(thisObject.what, &itsRect); break; case kCustomPict: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawCustPictSansWhite(thisObject.data.g.height, &itsRect); break; case kFlourescent: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawFlourescent(&itsRect); break; case kTrackLight: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawTrackLight(&itsRect); break; case kInvisLight: break; case kShredder: case kCDs: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawSimpleAppliance(thisObject.what, &itsRect); break; case kToaster: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { DrawSimpleAppliance(thisObject.what, &itsRect); if ((!redraw) && (neighbor == kCentralRoom)) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kToaster, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.g.state); } } break; case kMacPlus: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { DrawMacPlus(&itsRect, thisObject.data.g.state, isLit); if (!redraw) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kMacPlus, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.g.state); } } break; case kTV: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { #ifdef COMPILEQT if ((thisMac.hasQT) && (hasMovie) && (neighbor == kCentralRoom) && (!tvInRoom)) { whoCares = tvScreen1; ZeroRectCorner(&whoCares); OffsetRect(&whoCares, itsRect.left + 17, itsRect.top + 10); GetMovieBox(theMovie, &movieRect); CenterRectInRect(&movieRect, &whoCares); SetMovieBox(theMovie, &movieRect); theRgn = NewRgn(); RectRgn(theRgn, &whoCares); SetMovieDisplayClipRgn(theMovie, theRgn); DisposeRgn(theRgn); tvOn = thisObject.data.g.state; } #endif DrawTV(&itsRect, thisObject.data.g.state, isLit); if (!redraw) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kTV, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.g.state); #ifdef COMPILEQT if ((thisMac.hasQT) && (hasMovie) && (neighbor == kCentralRoom) && (!tvInRoom)) { tvWithMovieNumber = dynamicNum; tvInRoom = true; } #endif } } break; case kCoffee: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { DrawCoffee(&itsRect, thisObject.data.g.state, isLit); if (!redraw) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kCoffee, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.g.state); } } break; case kOutlet: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { if (isLit) DrawOutlet(&itsRect); if (!redraw) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kOutlet, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.g.state); } } break; case kVCR: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { DrawVCR(&itsRect, thisObject.data.g.state, isLit); if (!redraw) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kVCR, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.g.state); } } break; case kStereo: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { DrawStereo(&itsRect, isPlayMusicGame, isLit); if (!redraw) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kStereo, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.g.state); } } break; case kMicrowave: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { DrawMicrowave(&itsRect, thisObject.data.g.state, isLit); if (!redraw) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kMicrowave, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.g.state); } } break; case kBalloon: if ((neighbor == kCentralRoom) && (!redraw)) { GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); QOffsetRect(&itsRect, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kBalloon, &itsRect, &thisObject, localNumbers[neighbor], i, thisObject.data.h.state); } break; case kCopterLf: if ((neighbor == kCentralRoom) && (!redraw)) { GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); QOffsetRect(&itsRect, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kCopterLf, &itsRect, &thisObject, localNumbers[neighbor], i, thisObject.data.h.state); } break; case kCopterRt: if ((neighbor == kCentralRoom) && (!redraw)) { GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); QOffsetRect(&itsRect, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kCopterRt, &itsRect, &thisObject, localNumbers[neighbor], i, thisObject.data.h.state); } break; case kDartLf: if ((neighbor == kCentralRoom) && (!redraw)) { GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); QOffsetRect(&itsRect, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kDartLf, &itsRect, &thisObject, localNumbers[neighbor], i, thisObject.data.h.state); } break; case kDartRt: if ((neighbor == kCentralRoom) && (!redraw)) { GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); QOffsetRect(&itsRect, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kDartRt, &itsRect, &thisObject, localNumbers[neighbor], i, thisObject.data.h.state); } break; case kBall: if ((neighbor == kCentralRoom) && (!redraw)) { GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); QOffsetRect(&itsRect, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kBall, &itsRect, &thisObject, localNumbers[neighbor], i, thisObject.data.h.state); } break; case kDrip: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { DrawDrip(&itsRect); if ((!redraw) && (neighbor == kCentralRoom)) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kDrip, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.h.state); } } break; case kFish: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) { DrawFish(thisObject.what, &itsRect); if ((!redraw) && (neighbor == kCentralRoom)) { rectA = itsRect; QOffsetRect(&rectA, -playOriginH, -playOriginV); dynamicNum = AddDynamicObject(kFish, &rectA, &thisObject, localNumbers[neighbor], i, thisObject.data.h.state); } } break; case kCobweb: case kCloud: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawPictWithMaskObject(thisObject.what, &itsRect); break; case kMirror: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawMirror(&itsRect); if ((neighbor == kCentralRoom) && (!redraw)) { InsetRect(&itsRect, 4, 4); AddToMirrorRegion(&itsRect); } break; case kMousehole: case kFaucet: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawSimpleClutter(thisObject.what, &itsRect); break; case kFlower: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawFlower(&itsRect, thisObject.data.i.pict); break; case kWallWindow: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if (SectRect(&itsRect, &testRect, &whoCares)) DrawWallWindow(&itsRect); break; case kCalendar: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawCalendar(&itsRect); break; case kBulletin: GetObjectRect(&thisObject, &itsRect); OffsetRectRoomRelative(&itsRect, neighbor); if ((SectRect(&itsRect, &testRect, &whoCares)) && isLit) DrawBulletin(&itsRect); break; } } if (!redraw) // set up links { for (n = 0; n < numMasterObjects; n++) { if ((masterObjects[n].objectNum == i) && (masterObjects[n].roomNum == localNumbers[neighbor])) masterObjects[n].dynaNum = dynamicNum; } } } HSetState((Handle)thisHouse, wasState); } \ No newline at end of file diff --git a/Sources/ObjectEdit.c b/Sources/ObjectEdit.c deleted file mode 100755 index 62d2930..0000000 --- a/Sources/ObjectEdit.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // ObjectEdit.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Externs.h" #include "House.h" #include "MainWindow.h" #include "Marquee.h" #include "ObjectEdit.h" #include "Objects.h" #include "Play.h" #include "RectUtils.h" #include "Room.h" short FindObjectSelected (Point); void DragHandle (Point); void DragObject (Point); void AddObjectPairing (void); Boolean ObjectIsUpBlower (objectType *); Rect roomObjectRects[kMaxRoomObs]; Rect initialGliderRect; Rect leftStartGliderSrc, rightStartGliderSrc; Rect leftStartGliderDest, rightStartGliderDest; short objActive; Boolean isFirstRoom; extern retroLink retroLinkList[]; extern Rect gliderSrc[kNumGliderSrcRects]; extern short toolSelected, toolMode; extern Boolean noRoomAtAll; //============================================================== Functions //-------------------------------------------------------------- FindObjectSelected #ifndef COMPILEDEMO short FindObjectSelected (Point where) { short found, i; found = kNoObjectSelected; if (PtInRect(where, &initialGliderRect)) return (kInitialGliderSelected); else if (PtInRect(where, &leftStartGliderDest)) return (kLeftGliderSelected); else if (PtInRect(where, &rightStartGliderDest)) return (kRightGliderSelected); for (i = kMaxRoomObs - 1; i >= 0; i--) { if (PtInRect(where, &roomObjectRects[i])) { found = i; break; } } return (found); } #endif //-------------------------------------------------------------- DoSelectionClick void DoSelectionClick (Point where, Boolean isDoubleClick) { #ifndef COMPILEDEMO short direction, dist; StopMarquee(); if ((PtInMarqueeHandle(where)) && (objActive != kNoObjectSelected)) { if (StillDown()) DragHandle(where); if (ObjectHasHandle(&direction, &dist)) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else StartMarquee(&roomObjectRects[objActive]); } else { objActive = FindObjectSelected(where); if (objActive == kNoObjectSelected) { if (isDoubleClick) DoRoomInfo(); } else { if (isDoubleClick) { DoObjectInfo(); if (ObjectHasHandle(&direction, &dist)) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else StartMarquee(&roomObjectRects[objActive]); } else { if (StillDown()) DragObject(where); if (ObjectHasHandle(&direction, &dist)) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else { if (objActive == kInitialGliderSelected) StartMarquee(&initialGliderRect); else if (objActive == kLeftGliderSelected) StartMarquee(&leftStartGliderDest); else if (objActive == kRightGliderSelected) StartMarquee(&rightStartGliderDest); else StartMarquee(&roomObjectRects[objActive]); } } } } UpdateMenus(false); #endif } //-------------------------------------------------------------- DragHandle #ifndef COMPILEDEMO void DragHandle (Point where) { short hDelta, vDelta; Boolean whoCares; switch (thisRoom->objects[objActive].what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kGrecoVent: case kSewerBlower: vDelta = thisRoom->objects[objActive].data.a.distance; DragMarqueeHandle(where, &vDelta); thisRoom->objects[objActive].data.a.distance = vDelta; whoCares = KeepObjectLegal(); break; case kLiftArea: hDelta = thisRoom->objects[objActive].data.a.distance; vDelta = thisRoom->objects[objActive].data.a.tall * 2; DragMarqueeCorner(where, &hDelta, &vDelta, false); thisRoom->objects[objActive].data.a.distance = hDelta; thisRoom->objects[objActive].data.a.tall = vDelta / 2; whoCares = KeepObjectLegal(); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); break; case kLeftFan: case kRightFan: hDelta = thisRoom->objects[objActive].data.a.distance; DragMarqueeHandle(where, &hDelta); thisRoom->objects[objActive].data.a.distance = hDelta; whoCares = KeepObjectLegal(); break; case kInvisBlower: if (((thisRoom->objects[objActive].data.a.vector & 0x0F) == 1) || ((thisRoom->objects[objActive].data.a.vector & 0x0F) == 4)) { vDelta = thisRoom->objects[objActive].data.a.distance; DragMarqueeHandle(where, &vDelta); thisRoom->objects[objActive].data.a.distance = vDelta; } else { hDelta = thisRoom->objects[objActive].data.a.distance; DragMarqueeHandle(where, &hDelta); thisRoom->objects[objActive].data.a.distance = hDelta; } whoCares = KeepObjectLegal(); break; case kTable: case kShelf: case kDeckTable: hDelta = RectWide(&thisRoom->objects[objActive].data.b.bounds); DragMarqueeHandle(where, &hDelta); thisRoom->objects[objActive].data.b.bounds.right = thisRoom->objects[objActive].data.b.bounds.left + hDelta; whoCares = KeepObjectLegal(); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); break; case kCabinet: case kInvisObstacle: case kInvisBounce: hDelta = RectWide(&thisRoom->objects[objActive].data.b.bounds); vDelta = RectTall(&thisRoom->objects[objActive].data.b.bounds); DragMarqueeCorner(where, &hDelta, &vDelta, false); thisRoom->objects[objActive].data.b.bounds.right = thisRoom->objects[objActive].data.b.bounds.left + hDelta; thisRoom->objects[objActive].data.b.bounds.bottom = thisRoom->objects[objActive].data.b.bounds.top + vDelta; whoCares = KeepObjectLegal(); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); break; case kCounter: case kDresser: hDelta = RectWide(&thisRoom->objects[objActive].data.b.bounds); vDelta = RectTall(&thisRoom->objects[objActive].data.b.bounds); DragMarqueeCorner(where, &hDelta, &vDelta, true); thisRoom->objects[objActive].data.b.bounds.right = thisRoom->objects[objActive].data.b.bounds.left + hDelta; thisRoom->objects[objActive].data.b.bounds.top = thisRoom->objects[objActive].data.b.bounds.bottom - vDelta; whoCares = KeepObjectLegal(); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); break; case kGreaseRt: case kGreaseLf: case kSlider: hDelta = thisRoom->objects[objActive].data.c.length; DragMarqueeHandle(where, &hDelta); thisRoom->objects[objActive].data.c.length = hDelta; whoCares = KeepObjectLegal(); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); break; case kInvisTrans: hDelta = thisRoom->objects[objActive].data.d.wide; vDelta = thisRoom->objects[objActive].data.d.tall; DragMarqueeCorner(where, &hDelta, &vDelta, false); if (hDelta > 127) hDelta = 127; thisRoom->objects[objActive].data.d.wide = (Byte)hDelta; thisRoom->objects[objActive].data.d.tall = vDelta; whoCares = KeepObjectLegal(); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); break; case kDeluxeTrans: hDelta = ((thisRoom->objects[objActive].data.d.tall & 0xFF00) >> 8) * 4; vDelta = (thisRoom->objects[objActive].data.d.tall & 0x00FF) * 4; DragMarqueeCorner(where, &hDelta, &vDelta, false); if (hDelta < 64) hDelta = 64; if (vDelta < 32) vDelta = 32; thisRoom->objects[objActive].data.d.tall = ((hDelta / 4) << 8) + (vDelta / 4); whoCares = KeepObjectLegal(); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); break; case kFlourescent: case kTrackLight: hDelta = thisRoom->objects[objActive].data.f.length; DragMarqueeHandle(where, &hDelta); thisRoom->objects[objActive].data.f.length = hDelta; whoCares = KeepObjectLegal(); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); break; case kToaster: vDelta = thisRoom->objects[objActive].data.g.height; DragMarqueeHandle(where, &vDelta); thisRoom->objects[objActive].data.g.height = vDelta; whoCares = KeepObjectLegal(); break; case kBall: case kDrip: case kFish: vDelta = thisRoom->objects[objActive].data.h.length; DragMarqueeHandle(where, &vDelta); thisRoom->objects[objActive].data.h.length = vDelta; whoCares = KeepObjectLegal(); break; case kMirror: case kWallWindow: hDelta = RectWide(&thisRoom->objects[objActive].data.i.bounds); vDelta = RectTall(&thisRoom->objects[objActive].data.i.bounds); DragMarqueeCorner(where, &hDelta, &vDelta, false); thisRoom->objects[objActive].data.i.bounds.right = thisRoom->objects[objActive].data.i.bounds.left + hDelta; thisRoom->objects[objActive].data.i.bounds.bottom = thisRoom->objects[objActive].data.i.bounds.top + vDelta; whoCares = KeepObjectLegal(); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); break; } fileDirty = true; UpdateMenus(false); } #endif //-------------------------------------------------------------- DragObject #ifndef COMPILEDEMO void DragObject (Point where) { Rect newRect, wasRect; short deltaH, deltaV, increment; char wasState; Boolean invalAll; if (objActive == kInitialGliderSelected) { wasRect = initialGliderRect; newRect = initialGliderRect; DragMarqueeRect(where, &newRect, false, false); } else if (objActive == kLeftGliderSelected) { wasRect = leftStartGliderDest; newRect = leftStartGliderDest; DragMarqueeRect(where, &newRect, false, true); } else if (objActive == kRightGliderSelected) { wasRect = rightStartGliderDest; newRect = rightStartGliderDest; DragMarqueeRect(where, &newRect, false, true); } else { wasRect = roomObjectRects[objActive]; newRect = roomObjectRects[objActive]; switch (thisRoom->objects[objActive].what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kGrecoVent: case kSewerBlower: case kManhole: case kUpStairs: case kDownStairs: case kCeilingLight: case kHipLamp: case kDecoLamp: case kFlourescent: case kFloorTrans: case kCeilingTrans: case kDoorInLf: case kDoorInRt: case kDoorExRt: case kDoorExLf: case kWindowInLf: case kWindowInRt: case kWindowExRt: case kWindowExLf: case kBalloon: case kCopterLf: case kCopterRt: case kMousehole: case kFireplace: DragMarqueeRect(where, &newRect, true, false); invalAll = false; break; case kDartLf: case kDartRt: DragMarqueeRect(where, &newRect, false, true); invalAll = false; break; case kTiki: case kTable: case kShelf: case kCabinet: case kDeckTable: case kStool: case kInvisObstacle: case kInvisBounce: case kGreaseRt: case kGreaseLf: case kSlider: case kMailboxLf: case kMailboxRt: case kInvisTrans: case kDeluxeTrans: case kMirror: case kWallWindow: DragMarqueeRect(where, &newRect, false, false); invalAll = true; break; case kCounter: case kDresser: case kTrackLight: DragMarqueeRect(where, &newRect, true, false); invalAll = true; break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: case kLeftFan: case kRightFan: case kTaper: case kCandle: case kStubby: case kBBQ: case kInvisBlower: case kLiftArea: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kTrunk: case kBooks: case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: case kLightBulb: case kTableLamp: case kInvisLight: case kShredder: case kToaster: case kMacPlus: case kGuitar: case kTV: case kCoffee: case kOutlet: case kVCR: case kStereo: case kMicrowave: case kCinderBlock: case kFlowerBox: case kCDs: case kCustomPict: case kBall: case kDrip: case kFish: case kCobweb: case kOzma: case kFlower: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: DragMarqueeRect(where, &newRect, false, false); invalAll = false; break; } } deltaH = newRect.left - wasRect.left; deltaV = newRect.top - wasRect.top; if ((deltaH != 0) || (deltaV != 0)) { fileDirty = true; UpdateMenus(false); } if (objActive == kInitialGliderSelected) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); (*thisHouse)->initial.h += deltaH; (*thisHouse)->initial.v += deltaV; HSetState((Handle)thisHouse, wasState); } else if (objActive == kLeftGliderSelected) { increment = thisRoom->leftStart + deltaV; if (increment > 255) increment = 255; else if (increment < 0) increment = 0; thisRoom->leftStart = (Byte)increment; QSetRect(&leftStartGliderDest, 0, 0, 48, 16); QOffsetRect(&leftStartGliderDest, 0, kGliderStartsDown + (short)thisRoom->leftStart); } else if (objActive == kRightGliderSelected) { increment = thisRoom->rightStart + deltaV; if (increment > 255) increment = 255; else if (increment < 0) increment = 0; thisRoom->rightStart = (Byte)increment; QSetRect(&rightStartGliderDest, 0, 0, 48, 16); QOffsetRect(&rightStartGliderDest, 0, kGliderStartsDown + (short)thisRoom->rightStart); } else { switch (thisRoom->objects[objActive].what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kGrecoVent: case kSewerBlower: thisRoom->objects[objActive].data.a.topLeft.h += deltaH; break; case kLeftFan: case kRightFan: case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kInvisBlower: case kLiftArea: thisRoom->objects[objActive].data.a.topLeft.h += deltaH; thisRoom->objects[objActive].data.a.topLeft.v += deltaV; break; case kTable: case kShelf: case kCabinet: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kDeckTable: case kStool: case kTrunk: case kInvisObstacle: case kBooks: case kInvisBounce: thisRoom->objects[objActive].data.b.bounds.left += deltaH; thisRoom->objects[objActive].data.b.bounds.right += deltaH; thisRoom->objects[objActive].data.b.bounds.top += deltaV; thisRoom->objects[objActive].data.b.bounds.bottom += deltaV; break; case kCounter: case kDresser: case kManhole: thisRoom->objects[objActive].data.b.bounds.left += deltaH; thisRoom->objects[objActive].data.b.bounds.right += deltaH; break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kGreaseRt: case kGreaseLf: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: case kSlider: thisRoom->objects[objActive].data.c.topLeft.h += deltaH; thisRoom->objects[objActive].data.c.topLeft.v += deltaV; break; case kUpStairs: case kDownStairs: case kFloorTrans: case kCeilingTrans: case kDoorInLf: case kDoorInRt: case kDoorExRt: case kDoorExLf: case kWindowInLf: case kWindowInRt: case kWindowExRt: case kWindowExLf: thisRoom->objects[objActive].data.d.topLeft.h += deltaH; break; case kMailboxLf: case kMailboxRt: case kInvisTrans: case kDeluxeTrans: thisRoom->objects[objActive].data.d.topLeft.h += deltaH; thisRoom->objects[objActive].data.d.topLeft.v += deltaV; break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: thisRoom->objects[objActive].data.e.topLeft.h += deltaH; thisRoom->objects[objActive].data.e.topLeft.v += deltaV; break; case kCeilingLight: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: thisRoom->objects[objActive].data.f.topLeft.h += deltaH; break; case kLightBulb: case kTableLamp: case kInvisLight: thisRoom->objects[objActive].data.f.topLeft.h += deltaH; thisRoom->objects[objActive].data.f.topLeft.v += deltaV; break; case kShredder: case kToaster: case kMacPlus: case kGuitar: case kTV: case kCoffee: case kOutlet: case kVCR: case kStereo: case kMicrowave: case kCinderBlock: case kFlowerBox: case kCDs: case kCustomPict: thisRoom->objects[objActive].data.g.topLeft.h += deltaH; thisRoom->objects[objActive].data.g.topLeft.v += deltaV; break; case kBalloon: case kCopterLf: case kCopterRt: thisRoom->objects[objActive].data.h.topLeft.h += deltaH; break; case kDartLf: case kDartRt: thisRoom->objects[objActive].data.h.topLeft.v += deltaV; break; case kBall: case kDrip: case kFish: case kCobweb: thisRoom->objects[objActive].data.h.topLeft.h += deltaH; thisRoom->objects[objActive].data.h.topLeft.v += deltaV; break; case kOzma: case kMirror: case kFlower: case kWallWindow: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: thisRoom->objects[objActive].data.i.bounds.left += deltaH; thisRoom->objects[objActive].data.i.bounds.right += deltaH; thisRoom->objects[objActive].data.i.bounds.top += deltaV; thisRoom->objects[objActive].data.i.bounds.bottom += deltaV; break; case kMousehole: case kFireplace: thisRoom->objects[objActive].data.i.bounds.left += deltaH; thisRoom->objects[objActive].data.i.bounds.right += deltaH; break; } } if (KeepObjectLegal()) { } GetThisRoomsObjRects(); if (invalAll) InvalWindowRect(mainWindow, &mainWindowRect); else { InvalWindowRect(mainWindow, &wasRect); if (objActive == kInitialGliderSelected) InvalWindowRect(mainWindow, &initialGliderRect); else if (objActive == kLeftGliderSelected) InvalWindowRect(mainWindow, &leftStartGliderDest); else if (objActive == kRightGliderSelected) InvalWindowRect(mainWindow, &rightStartGliderDest); else InvalWindowRect(mainWindow, &roomObjectRects[objActive]); } ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); } #endif //-------------------------------------------------------------- DoNewObjectClick void DoNewObjectClick (Point where) { #ifndef COMPILEDEMO short whatObject; StopMarquee(); objActive = kNoObjectSelected; whatObject = toolSelected + ((toolMode - 1) * 0x0010); if (AddNewObject(where, whatObject, true)) IgnoreThisClick(); UpdateMenus(false); AddObjectPairing(); #endif } //-------------------------------------------------------------- AddObjectPairing void AddObjectPairing (void) { roomType *testRoomPtr; short roomNum, emptySlot; char wasState; Str255 message; if (thisRoom->objects[objActive].what == kDoorInRt) { roomNum = DoesNeighborRoomExist(kRoomToRight); if (roomNum != -1) { emptySlot = FindObjectSlotInRoom(roomNum); if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kDoorExLf))) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNum]); testRoomPtr->objects[emptySlot].what = kDoorExLf; testRoomPtr->objects[emptySlot].data.d.topLeft.h = kDoorExLfLeft; testRoomPtr->objects[emptySlot].data.d.topLeft.v = kDoorExTop; testRoomPtr->objects[emptySlot].data.d.tall = 0; testRoomPtr->objects[emptySlot].data.d.where = -1; testRoomPtr->objects[emptySlot].data.d.who = 255; testRoomPtr->objects[emptySlot].data.d.wide = 0; testRoomPtr->numObjects++; HSetState((Handle)thisHouse, wasState); GetLocalizedString(45, message); OpenMessageWindow(message); ForeColor(blueColor); GetLocalizedString(46, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); CloseMessageWindow(); } } } else if (thisRoom->objects[objActive].what == kDoorInLf) { roomNum = DoesNeighborRoomExist(kRoomToLeft); if (roomNum != -1) { emptySlot = FindObjectSlotInRoom(roomNum); if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kDoorExRt))) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNum]); testRoomPtr->objects[emptySlot].what = kDoorExRt; testRoomPtr->objects[emptySlot].data.d.topLeft.h = kDoorExRtLeft; testRoomPtr->objects[emptySlot].data.d.topLeft.v = kDoorExTop; testRoomPtr->objects[emptySlot].data.d.tall = 0; testRoomPtr->objects[emptySlot].data.d.where = -1; testRoomPtr->objects[emptySlot].data.d.who = 255; testRoomPtr->objects[emptySlot].data.d.wide = 0; testRoomPtr->numObjects++; HSetState((Handle)thisHouse, wasState); GetLocalizedString(45, message); OpenMessageWindow(message); ForeColor(blueColor); GetLocalizedString(46, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); CloseMessageWindow(); } } } else if (thisRoom->objects[objActive].what == kDoorExRt) { roomNum = DoesNeighborRoomExist(kRoomToRight); if (roomNum != -1) { emptySlot = FindObjectSlotInRoom(roomNum); if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kDoorInLfLeft))) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNum]); testRoomPtr->objects[emptySlot].what = kDoorInLf; testRoomPtr->objects[emptySlot].data.d.topLeft.h = kDoorInLfLeft; testRoomPtr->objects[emptySlot].data.d.topLeft.v = kDoorInTop; testRoomPtr->objects[emptySlot].data.d.tall = 0; testRoomPtr->objects[emptySlot].data.d.where = -1; testRoomPtr->objects[emptySlot].data.d.who = 255; testRoomPtr->objects[emptySlot].data.d.wide = 0; testRoomPtr->numObjects++; HSetState((Handle)thisHouse, wasState); GetLocalizedString(45, message); OpenMessageWindow(message); ForeColor(blueColor); GetLocalizedString(47, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); CloseMessageWindow(); } } } else if (thisRoom->objects[objActive].what == kDoorExLf) { roomNum = DoesNeighborRoomExist(kRoomToLeft); if (roomNum != -1) { emptySlot = FindObjectSlotInRoom(roomNum); if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kDoorInRtLeft))) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNum]); testRoomPtr->objects[emptySlot].what = kDoorInRt; testRoomPtr->objects[emptySlot].data.d.topLeft.h = kDoorInRtLeft; testRoomPtr->objects[emptySlot].data.d.topLeft.v = kDoorInTop; testRoomPtr->objects[emptySlot].data.d.tall = 0; testRoomPtr->objects[emptySlot].data.d.where = -1; testRoomPtr->objects[emptySlot].data.d.who = 255; testRoomPtr->objects[emptySlot].data.d.wide = 0; testRoomPtr->numObjects++; HSetState((Handle)thisHouse, wasState); GetLocalizedString(45, message); OpenMessageWindow(message); ForeColor(blueColor); GetLocalizedString(47, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); CloseMessageWindow(); } } } else if (thisRoom->objects[objActive].what == kWindowInLf) { roomNum = DoesNeighborRoomExist(kRoomToLeft); if (roomNum != -1) { emptySlot = FindObjectSlotInRoom(roomNum); if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kWindowExRt))) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNum]); testRoomPtr->objects[emptySlot].what = kWindowExRt; testRoomPtr->objects[emptySlot].data.d.topLeft.h = kWindowExRtLeft; testRoomPtr->objects[emptySlot].data.d.topLeft.v = kWindowExTop; testRoomPtr->objects[emptySlot].data.d.tall = 0; testRoomPtr->objects[emptySlot].data.d.where = -1; testRoomPtr->objects[emptySlot].data.d.who = 255; testRoomPtr->objects[emptySlot].data.d.wide = 0; testRoomPtr->numObjects++; HSetState((Handle)thisHouse, wasState); GetLocalizedString(45, message); OpenMessageWindow(message); ForeColor(blueColor); GetLocalizedString(48, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); CloseMessageWindow(); } } } else if (thisRoom->objects[objActive].what == kWindowInRt) { roomNum = DoesNeighborRoomExist(kRoomToRight); if (roomNum != -1) { emptySlot = FindObjectSlotInRoom(roomNum); if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kWindowExLf))) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNum]); testRoomPtr->objects[emptySlot].what = kWindowExLf; testRoomPtr->objects[emptySlot].data.d.topLeft.h = kWindowExLfLeft; testRoomPtr->objects[emptySlot].data.d.topLeft.v = kWindowExTop; testRoomPtr->objects[emptySlot].data.d.tall = 0; testRoomPtr->objects[emptySlot].data.d.where = -1; testRoomPtr->objects[emptySlot].data.d.who = 255; testRoomPtr->objects[emptySlot].data.d.wide = 0; testRoomPtr->numObjects++; HSetState((Handle)thisHouse, wasState); GetLocalizedString(45, message); OpenMessageWindow(message); ForeColor(blueColor); GetLocalizedString(48, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); CloseMessageWindow(); } } } else if (thisRoom->objects[objActive].what == kWindowExRt) { roomNum = DoesNeighborRoomExist(kRoomToRight); if (roomNum != -1) { emptySlot = FindObjectSlotInRoom(roomNum); if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kWindowInLf))) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNum]); testRoomPtr->objects[emptySlot].what = kWindowInLf; testRoomPtr->objects[emptySlot].data.d.topLeft.h = kWindowInLfLeft; testRoomPtr->objects[emptySlot].data.d.topLeft.v = kWindowInTop; testRoomPtr->objects[emptySlot].data.d.tall = 0; testRoomPtr->objects[emptySlot].data.d.where = -1; testRoomPtr->objects[emptySlot].data.d.who = 255; testRoomPtr->objects[emptySlot].data.d.wide = 0; testRoomPtr->numObjects++; HSetState((Handle)thisHouse, wasState); GetLocalizedString(45, message); OpenMessageWindow(message); ForeColor(blueColor); GetLocalizedString(49, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); CloseMessageWindow(); } } } else if (thisRoom->objects[objActive].what == kWindowExLf) { roomNum = DoesNeighborRoomExist(kRoomToLeft); if (roomNum != -1) { emptySlot = FindObjectSlotInRoom(roomNum); if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kWindowInRt))) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNum]); testRoomPtr->objects[emptySlot].what = kWindowInRt; testRoomPtr->objects[emptySlot].data.d.topLeft.h = kWindowInRtLeft; testRoomPtr->objects[emptySlot].data.d.topLeft.v = kWindowInTop; testRoomPtr->objects[emptySlot].data.d.tall = 0; testRoomPtr->objects[emptySlot].data.d.where = -1; testRoomPtr->objects[emptySlot].data.d.who = 255; testRoomPtr->objects[emptySlot].data.d.wide = 0; testRoomPtr->numObjects++; HSetState((Handle)thisHouse, wasState); GetLocalizedString(45, message); OpenMessageWindow(message); ForeColor(blueColor); GetLocalizedString(49, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); CloseMessageWindow(); } } } else if (thisRoom->objects[objActive].what == kUpStairs) { roomNum = DoesNeighborRoomExist(kRoomAbove); if (roomNum != -1) { emptySlot = FindObjectSlotInRoom(roomNum); if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kDownStairs))) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNum]); testRoomPtr->objects[emptySlot].what = kDownStairs; testRoomPtr->objects[emptySlot].data.d.topLeft.h = thisRoom->objects[objActive].data.d.topLeft.h; testRoomPtr->objects[emptySlot].data.d.topLeft.v = kStairsTop; testRoomPtr->objects[emptySlot].data.d.tall = 0; testRoomPtr->objects[emptySlot].data.d.where = -1; testRoomPtr->objects[emptySlot].data.d.who = 255; testRoomPtr->objects[emptySlot].data.d.wide = 0; testRoomPtr->numObjects++; HSetState((Handle)thisHouse, wasState); GetLocalizedString(45, message); OpenMessageWindow(message); ForeColor(blueColor); GetLocalizedString(50, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); CloseMessageWindow(); } } } else if (thisRoom->objects[objActive].what == kDownStairs) { roomNum = DoesNeighborRoomExist(kRoomBelow); if (roomNum != -1) { emptySlot = FindObjectSlotInRoom(roomNum); if ((emptySlot != -1) && (!DoesRoomNumHaveObject(roomNum, kUpStairs))) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); testRoomPtr = &((*thisHouse)->rooms[roomNum]); testRoomPtr->objects[emptySlot].what = kUpStairs; testRoomPtr->objects[emptySlot].data.d.topLeft.h = thisRoom->objects[objActive].data.d.topLeft.h; testRoomPtr->objects[emptySlot].data.d.topLeft.v = kStairsTop; testRoomPtr->objects[emptySlot].data.d.tall = 0; testRoomPtr->objects[emptySlot].data.d.where = -1; testRoomPtr->objects[emptySlot].data.d.who = 255; testRoomPtr->objects[emptySlot].data.d.wide = 0; testRoomPtr->numObjects++; HSetState((Handle)thisHouse, wasState); GetLocalizedString(45, message); OpenMessageWindow(message); ForeColor(blueColor); GetLocalizedString(51, message); SetMessageWindowMessage(message); ForeColor(blackColor); DelayTicks(60); CloseMessageWindow(); } } } } //-------------------------------------------------------------- DeleteObject void DeleteObject (void) { #ifndef COMPILEDEMO short i; if ((theMode != kEditMode) || (objActive == kNoObjectSelected)) return; if ((objActive == kInitialGliderSelected) || (objActive == kLeftGliderSelected) || (objActive == kRightGliderSelected)) { SysBeep(1); return; } for (i = 0; i < kMaxRoomObs; i++) { if ((retroLinkList[i].room == thisRoomNumber) && (retroLinkList[i].object == objActive)) retroLinkList[i].room = -1; } thisRoom->objects[objActive].what = kObjectIsEmpty; thisRoom->numObjects--; fileDirty = true; UpdateMenus(false); InvalWindowRect(mainWindow, &mainWindowRect); QSetRect(&roomObjectRects[objActive], -1, -1, 0, 0); DeselectObject(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); #endif } //-------------------------------------------------------------- DuplicateObject void DuplicateObject (void) { objectType tempObject; Point placePt; short direction, dist; Boolean handled; tempObject = thisRoom->objects[objActive]; placePt.h = roomObjectRects[objActive].left + HalfRectWide(&roomObjectRects[objActive]) + 64; placePt.v = roomObjectRects[objActive].top + HalfRectTall(&roomObjectRects[objActive]); StopMarquee(); if (AddNewObject(placePt, tempObject.what, false)) { switch (tempObject.what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kLeftFan: case kRightFan: case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kInvisBlower: case kGrecoVent: case kSewerBlower: thisRoom->objects[objActive].data.a.distance = tempObject.data.a.distance; thisRoom->objects[objActive].data.a.initial = tempObject.data.a.initial; thisRoom->objects[objActive].data.a.state = tempObject.data.a.state; thisRoom->objects[objActive].data.a.vector = tempObject.data.a.vector; thisRoom->objects[objActive].data.a.tall = tempObject.data.a.tall; break; case kLiftArea: thisRoom->objects[objActive].data.a.topLeft.h = tempObject.data.a.topLeft.h + 64; thisRoom->objects[objActive].data.a.topLeft.v = tempObject.data.a.topLeft.v; thisRoom->objects[objActive].data.a.distance = tempObject.data.a.distance; thisRoom->objects[objActive].data.a.initial = tempObject.data.a.initial; thisRoom->objects[objActive].data.a.state = tempObject.data.a.state; thisRoom->objects[objActive].data.a.vector = tempObject.data.a.vector; thisRoom->objects[objActive].data.a.tall = tempObject.data.a.tall; break; case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kStool: case kTrunk: case kManhole: case kBooks: thisRoom->objects[objActive].data.b.pict = tempObject.data.b.pict; break; case kTable: case kShelf: case kCabinet: case kCounter: case kDresser: case kDeckTable: case kInvisObstacle: case kInvisBounce: thisRoom->objects[objActive].data.b.bounds = tempObject.data.b.bounds; QOffsetRect(&thisRoom->objects[objActive].data.b.bounds, 64, 0); thisRoom->objects[objActive].data.b.pict = tempObject.data.b.pict; break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kGreaseRt: case kGreaseLf: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: thisRoom->objects[objActive].data.c.length = tempObject.data.c.length; thisRoom->objects[objActive].data.c.points = tempObject.data.c.points; thisRoom->objects[objActive].data.c.state = tempObject.data.c.state; thisRoom->objects[objActive].data.c.initial = tempObject.data.c.initial; break; case kSlider: thisRoom->objects[objActive].data.c.topLeft.h = tempObject.data.c.topLeft.h + 64; thisRoom->objects[objActive].data.c.length = tempObject.data.c.length; thisRoom->objects[objActive].data.c.points = tempObject.data.c.points; thisRoom->objects[objActive].data.c.state = tempObject.data.c.state; thisRoom->objects[objActive].data.c.initial = tempObject.data.c.initial; break; case kUpStairs: case kDownStairs: case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kDoorInLf: case kDoorInRt: case kDoorExRt: case kDoorExLf: case kWindowInLf: case kWindowInRt: case kWindowExRt: case kWindowExLf: thisRoom->objects[objActive].data.d.tall = tempObject.data.d.tall; thisRoom->objects[objActive].data.d.where = tempObject.data.d.where; thisRoom->objects[objActive].data.d.who = tempObject.data.d.who; thisRoom->objects[objActive].data.d.wide = tempObject.data.d.wide; break; case kInvisTrans: case kDeluxeTrans: thisRoom->objects[objActive].data.d.topLeft.h = tempObject.data.d.topLeft.h + 64; thisRoom->objects[objActive].data.d.topLeft.v = tempObject.data.d.topLeft.v; thisRoom->objects[objActive].data.d.tall = tempObject.data.d.tall; thisRoom->objects[objActive].data.d.where = tempObject.data.d.where; thisRoom->objects[objActive].data.d.who = tempObject.data.d.who; thisRoom->objects[objActive].data.d.wide = tempObject.data.d.wide; break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: thisRoom->objects[objActive].data.e.delay = tempObject.data.e.delay; thisRoom->objects[objActive].data.e.where = tempObject.data.e.where; thisRoom->objects[objActive].data.e.who = tempObject.data.e.who; thisRoom->objects[objActive].data.e.type = tempObject.data.e.type; break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: thisRoom->objects[objActive].data.f.length = tempObject.data.f.length; thisRoom->objects[objActive].data.f.byte0 = tempObject.data.f.byte0; thisRoom->objects[objActive].data.f.byte1 = tempObject.data.f.byte1; thisRoom->objects[objActive].data.f.initial = tempObject.data.f.initial; thisRoom->objects[objActive].data.f.state = tempObject.data.f.state; break; case kShredder: case kToaster: case kMacPlus: case kGuitar: case kTV: case kCoffee: case kOutlet: case kVCR: case kStereo: case kMicrowave: case kCinderBlock: case kFlowerBox: case kCDs: thisRoom->objects[objActive].data.g.height = tempObject.data.g.height; thisRoom->objects[objActive].data.g.byte0 = tempObject.data.g.byte0; thisRoom->objects[objActive].data.g.delay = tempObject.data.g.delay; thisRoom->objects[objActive].data.g.initial = tempObject.data.g.initial; thisRoom->objects[objActive].data.g.state = tempObject.data.g.state; break; case kCustomPict: thisRoom->objects[objActive].data.g.topLeft.h = tempObject.data.g.topLeft.h + 64; thisRoom->objects[objActive].data.g.topLeft.v = tempObject.data.g.topLeft.v; thisRoom->objects[objActive].data.g.height = tempObject.data.g.height; thisRoom->objects[objActive].data.g.byte0 = tempObject.data.g.byte0; thisRoom->objects[objActive].data.g.delay = tempObject.data.g.delay; thisRoom->objects[objActive].data.g.initial = tempObject.data.g.initial; thisRoom->objects[objActive].data.g.state = tempObject.data.g.state; break; case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kBall: case kDrip: case kFish: case kCobweb: thisRoom->objects[objActive].data.h.length = tempObject.data.h.length; thisRoom->objects[objActive].data.h.delay = tempObject.data.h.delay; thisRoom->objects[objActive].data.h.byte0 = tempObject.data.h.byte0; thisRoom->objects[objActive].data.h.initial = tempObject.data.h.initial; thisRoom->objects[objActive].data.h.state = tempObject.data.h.state; break; case kOzma: case kMousehole: case kFireplace: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: thisRoom->objects[objActive].data.i.pict = tempObject.data.i.pict; break; case kMirror: case kFlower: case kWallWindow: thisRoom->objects[objActive].data.i.bounds = tempObject.data.i.bounds; QOffsetRect(&thisRoom->objects[objActive].data.i.bounds, 64, 0); thisRoom->objects[objActive].data.i.pict = tempObject.data.i.pict; break; } if (KeepObjectLegal()) { } handled = ObjectHasHandle(&direction, &dist); ReadyBackground(thisRoom->background, thisRoom->tiles); GetThisRoomsObjRects(); DrawThisRoomsObjects(); InvalWindowRect(mainWindow, &mainWindowRect); if (handled) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else StartMarquee(&roomObjectRects[objActive]); } } //-------------------------------------------------------------- MoveObject void MoveObject (short whichWay, Boolean shiftDown) { #ifndef COMPILEDEMO Rect wasRect; short deltaH, deltaV, increment; short dist, direction; char wasState; if (theMode != kEditMode) return; StopMarquee(); if (shiftDown) increment = 10; else { if (objActive == kInitialGliderSelected) { increment = 1; } else { if ((whichWay == kBumpRight) || (whichWay == kBumpLeft)) { switch (thisRoom->objects[objActive].what) { case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kGreaseRt: case kGreaseLf: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: case kSlider: case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: case kToaster: case kMacPlus: case kTV: case kCoffee: case kOutlet: case kVCR: case kStereo: case kMicrowave: case kBalloon: case kCopterLf: case kCopterRt: case kBall: case kDrip: case kFish: case kMirror: increment = 2; break; case kManhole: increment = 64; break; default: increment = 1; break; } } else increment = 1; } } switch (whichWay) { case kBumpUp: deltaH = 0; deltaV = -increment; break; case kBumpDown: deltaH = 0; deltaV = increment; break; case kBumpRight: deltaH = increment; deltaV = 0; break; case kBumpLeft: deltaH = -increment; deltaV = 0; break; } if (objActive == kInitialGliderSelected) { wasRect = initialGliderRect; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); (*thisHouse)->initial.h += deltaH; (*thisHouse)->initial.v += deltaV; HSetState((Handle)thisHouse, wasState); } else if (objActive == kLeftGliderSelected) { wasRect = leftStartGliderDest; increment = thisRoom->leftStart + deltaV; if (increment > 255) increment = 255; else if (increment < 0) increment = 0; thisRoom->leftStart = (Byte)increment; QSetRect(&leftStartGliderDest, 0, 0, 48, 16); QOffsetRect(&leftStartGliderDest, 0, kGliderStartsDown + (short)thisRoom->leftStart); } else if (objActive == kRightGliderSelected) { wasRect = rightStartGliderDest; increment = thisRoom->rightStart + deltaV; if (increment > 255) increment = 255; else if (increment < 0) increment = 0; thisRoom->rightStart = (Byte)increment; QSetRect(&rightStartGliderDest, 0, 0, 48, 16); QOffsetRect(&rightStartGliderDest, kRoomWide - 48, kGliderStartsDown + (short)thisRoom->rightStart); } else { wasRect = roomObjectRects[objActive]; switch (thisRoom->objects[objActive].what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kGrecoVent: case kSewerBlower: thisRoom->objects[objActive].data.a.topLeft.h += deltaH; break; case kLeftFan: case kRightFan: case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kInvisBlower: case kLiftArea: thisRoom->objects[objActive].data.a.topLeft.h += deltaH; thisRoom->objects[objActive].data.a.topLeft.v += deltaV; break; case kTable: case kShelf: case kCabinet: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kDeckTable: case kStool: case kTrunk: case kInvisObstacle: case kBooks: case kInvisBounce: thisRoom->objects[objActive].data.b.bounds.left += deltaH; thisRoom->objects[objActive].data.b.bounds.right += deltaH; thisRoom->objects[objActive].data.b.bounds.top += deltaV; thisRoom->objects[objActive].data.b.bounds.bottom += deltaV; break; case kCounter: case kDresser: case kManhole: thisRoom->objects[objActive].data.b.bounds.left += deltaH; thisRoom->objects[objActive].data.b.bounds.right += deltaH; break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kGreaseRt: case kGreaseLf: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: case kSlider: thisRoom->objects[objActive].data.c.topLeft.h += deltaH; thisRoom->objects[objActive].data.c.topLeft.v += deltaV; break; case kUpStairs: case kDownStairs: case kFloorTrans: case kCeilingTrans: thisRoom->objects[objActive].data.d.topLeft.h += deltaH; break; case kMailboxLf: case kMailboxRt: case kInvisTrans: case kDeluxeTrans: thisRoom->objects[objActive].data.d.topLeft.h += deltaH; thisRoom->objects[objActive].data.d.topLeft.v += deltaV; break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: thisRoom->objects[objActive].data.e.topLeft.h += deltaH; thisRoom->objects[objActive].data.e.topLeft.v += deltaV; break; case kCeilingLight: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: thisRoom->objects[objActive].data.f.topLeft.h += deltaH; break; case kLightBulb: case kTableLamp: case kInvisLight: thisRoom->objects[objActive].data.f.topLeft.h += deltaH; thisRoom->objects[objActive].data.f.topLeft.v += deltaV; break; case kShredder: case kToaster: case kMacPlus: case kGuitar: case kTV: case kCoffee: case kOutlet: case kVCR: case kStereo: case kMicrowave: case kCinderBlock: case kFlowerBox: case kCDs: case kCustomPict: thisRoom->objects[objActive].data.g.topLeft.h += deltaH; thisRoom->objects[objActive].data.g.topLeft.v += deltaV; break; case kBalloon: case kCopterLf: case kCopterRt: thisRoom->objects[objActive].data.h.topLeft.h += deltaH; break; case kDartLf: case kDartRt: thisRoom->objects[objActive].data.h.topLeft.v += deltaV; break; case kBall: case kDrip: case kFish: case kCobweb: thisRoom->objects[objActive].data.h.topLeft.h += deltaH; thisRoom->objects[objActive].data.h.topLeft.v += deltaV; break; case kOzma: case kMirror: case kFlower: case kWallWindow: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: thisRoom->objects[objActive].data.i.bounds.left += deltaH; thisRoom->objects[objActive].data.i.bounds.right += deltaH; thisRoom->objects[objActive].data.i.bounds.top += deltaV; thisRoom->objects[objActive].data.i.bounds.bottom += deltaV; break; case kMousehole: case kFireplace: thisRoom->objects[objActive].data.i.bounds.left += deltaH; thisRoom->objects[objActive].data.i.bounds.right += deltaH; break; } } if (KeepObjectLegal()) { } fileDirty = true; UpdateMenus(false); GetThisRoomsObjRects(); if (objActive == kInitialGliderSelected) { InvalWindowRect(mainWindow, &wasRect); InvalWindowRect(mainWindow, &initialGliderRect); } else if (objActive == kLeftGliderSelected) { InvalWindowRect(mainWindow, &wasRect); InvalWindowRect(mainWindow, &leftStartGliderDest); } else if (objActive == kRightGliderSelected) { InvalWindowRect(mainWindow, &wasRect); InvalWindowRect(mainWindow, &rightStartGliderDest); } else { switch (thisRoom->objects[objActive].what) { case kTiki: case kTable: case kShelf: case kCabinet: case kDeckTable: case kStool: case kCounter: case kDresser: case kGreaseRt: case kGreaseLf: case kSlider: case kMailboxLf: case kMailboxRt: case kTrackLight: case kMirror: case kWallWindow: InvalWindowRect(mainWindow, &mainWindowRect); break; default: InvalWindowRect(mainWindow, &wasRect); InvalWindowRect(mainWindow, &roomObjectRects[objActive]); break; } } ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); if (ObjectHasHandle(&direction, &dist)) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else { if (objActive == kInitialGliderSelected) StartMarquee(&initialGliderRect); else if (objActive == kLeftGliderSelected) StartMarquee(&leftStartGliderDest); else if (objActive == kRightGliderSelected) StartMarquee(&rightStartGliderDest); else StartMarquee(&roomObjectRects[objActive]); } #endif } //-------------------------------------------------------------- DeselectObject void DeselectObject (void) { #ifndef COMPILEDEMO if ((theMode != kEditMode) || (objActive == kNoObjectSelected)) return; objActive = kNoObjectSelected; StopMarquee(); UpdateMenus(false); #endif } //-------------------------------------------------------------- ObjectHasHandle #ifndef COMPILEDEMO Boolean ObjectHasHandle (short *direction, short *dist) { if ((objActive == kInitialGliderSelected) || (objActive == kNoObjectSelected)) return (false); switch (thisRoom->objects[objActive].what) { case kFloorVent: case kFloorBlower: case kSewerGrate: case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kGrecoVent: case kSewerBlower: *direction = kAbove; *dist = thisRoom->objects[objActive].data.a.distance; return (true); break; case kCeilingVent: case kCeilingBlower: *direction = kBelow; *dist = thisRoom->objects[objActive].data.a.distance; return (true); break; case kLeftFan: *direction = kToLeft; *dist = thisRoom->objects[objActive].data.a.distance; return (true); break; case kRightFan: *direction = kToRight; *dist = thisRoom->objects[objActive].data.a.distance; return (true); break; case kInvisBlower: switch (thisRoom->objects[objActive].data.a.vector & 0x0F) { case 1: // up *direction = kAbove; break; case 2: // right *direction = kToRight; break; case 4: // down *direction = kBelow; break; case 8: // left *direction = kToLeft; break; } *dist = thisRoom->objects[objActive].data.a.distance; return (true); break; case kTable: case kShelf: case kDeckTable: *direction = kToRight; *dist = 0; return (true); break; case kLiftArea: case kCabinet: case kInvisObstacle: case kInvisBounce: case kMirror: case kWallWindow: *direction = kBottomCorner; *dist = 0; return (true); break; case kCounter: case kDresser: *direction = kTopCorner; *dist = 0; return (true); break; case kGreaseRt: *direction = kToRight; *dist = thisRoom->objects[objActive].data.c.length; return (true); break; case kGreaseLf: *direction = kToLeft; *dist = thisRoom->objects[objActive].data.c.length; return (true); break; case kSlider: *direction = kToRight; *dist = 0; return (true); break; case kInvisTrans: case kDeluxeTrans: *direction = kBottomCorner; *dist = 0; return (true); break; case kFlourescent: case kTrackLight: *direction = kToRight; *dist = 0; return (true); break; case kToaster: *direction = kAbove; *dist = thisRoom->objects[objActive].data.g.height; return (true); break; case kBall: case kFish: *direction = kAbove; *dist = thisRoom->objects[objActive].data.h.length; return (true); break; case kDrip: *direction = kBelow; *dist = thisRoom->objects[objActive].data.h.length; return (true); break; default: return (false); break; } } #endif //-------------------------------------------------------------- ObjectIsUpBlower Boolean ObjectIsUpBlower (objectType *who) { if ((who->what == kFloorVent) || (who->what == kFloorBlower) || (who->what == kSewerGrate) || (who->what == kTaper) || (who->what == kCandle) || (who->what == kStubby) || (who->what == kTiki) || (who->what == kBBQ) || (who->what == kGrecoVent) || (who->what == kSewerBlower)) return (true); else if ((who->what == kInvisBlower) || (who->what == kLiftArea)) { if ((who->data.a.vector & 0x01) == 0x01) return (true); else return (false); } else return (false); } //-------------------------------------------------------------- HandleBlowerGlider void HandleBlowerGlider (void) { #ifndef COMPILEDEMO short direction, dist; if (ObjectIsUpBlower(&thisRoom->objects[objActive])) { if (ObjectHasHandle(&direction, &dist)) { SetMarqueeGliderRect(((roomObjectRects[objActive].right + roomObjectRects[objActive].left) / 2), roomObjectRects[objActive].top - dist); } } #endif } //-------------------------------------------------------------- SelectNextObject void SelectNextObject (void) { #ifndef COMPILEDEMO short direction, dist; Boolean noneFound; if ((theMode != kEditMode) || (thisRoom->numObjects <= 0)) return; noneFound = true; while (noneFound) { objActive++; if (objActive >= kMaxRoomObs) objActive = 0; if (thisRoom->objects[objActive].what != kObjectIsEmpty) noneFound = false; } UpdateMenus(false); if (ObjectHasHandle(&direction, &dist)) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else StartMarquee(&roomObjectRects[objActive]); #endif } //-------------------------------------------------------------- SelectPrevObject void SelectPrevObject (void) { #ifndef COMPILEDEMO short direction, dist; Boolean noneFound; if ((theMode != kEditMode) || (thisRoom->numObjects <= 0)) return; noneFound = true; while (noneFound) { objActive--; if (objActive < 0) objActive = kMaxRoomObs - 1; if (thisRoom->objects[objActive].what != kObjectIsEmpty) noneFound = false; } UpdateMenus(false); if (ObjectHasHandle(&direction, &dist)) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else StartMarquee(&roomObjectRects[objActive]); #endif } //-------------------------------------------------------------- GetThisRoomsObjRects #ifndef COMPILEDEMO void GetThisRoomsObjRects (void) { PicHandle thePict; short i, wide, tall; isFirstRoom = (GetFirstRoomNumber() == thisRoomNumber); if ((isFirstRoom) && (!noRoomAtAll) && (houseUnlocked)) WhereDoesGliderBegin(&initialGliderRect, kNewGameMode); else QSetRect(&initialGliderRect, 0, 0, 0, 0); QSetRect(&leftStartGliderDest, 0, 0, 48, 16); QOffsetRect(&leftStartGliderDest, 0, kGliderStartsDown + (short)thisRoom->leftStart); QSetRect(&rightStartGliderDest, 0, 0, 48, 16); QOffsetRect(&rightStartGliderDest, kRoomWide - 48, kGliderStartsDown + (short)thisRoom->rightStart); if ((noRoomAtAll) || (!houseUnlocked)) { return; } else { for (i = 0; i < kMaxRoomObs; i++) { switch (thisRoom->objects[i].what) { case kObjectIsEmpty: QSetRect(&roomObjectRects[i], -2, -2, -1, -1); break; case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kLeftFan: case kRightFan: case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kInvisBlower: case kGrecoVent: case kSewerBlower: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.a.topLeft.h, thisRoom->objects[i].data.a.topLeft.v); break; case kLiftArea: QSetRect(&roomObjectRects[i], 0, 0, thisRoom->objects[i].data.a.distance, thisRoom->objects[i].data.a.tall * 2); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.a.topLeft.h, thisRoom->objects[i].data.a.topLeft.v); break; case kTable: case kShelf: case kCabinet: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kCounter: case kDresser: case kDeckTable: case kStool: case kTrunk: case kInvisObstacle: case kManhole: case kBooks: case kInvisBounce: roomObjectRects[i] = thisRoom->objects[i].data.b.bounds; break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.c.topLeft.h, thisRoom->objects[i].data.c.topLeft.v); break; case kGreaseRt: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.c.topLeft.h, thisRoom->objects[i].data.c.topLeft.v); if (!thisRoom->objects[i].data.c.initial) QOffsetRect(&roomObjectRects[i], 8, 0); break; case kGreaseLf: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.c.topLeft.h, thisRoom->objects[i].data.c.topLeft.v); if (!thisRoom->objects[i].data.c.initial) QOffsetRect(&roomObjectRects[i], -8, 0); break; case kSlider: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.c.topLeft.h, thisRoom->objects[i].data.c.topLeft.v); roomObjectRects[i].right = roomObjectRects[i].left + thisRoom->objects[i].data.c.length; break; case kUpStairs: case kDownStairs: case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kDoorInLf: case kDoorInRt: case kDoorExRt: case kDoorExLf: case kWindowInLf: case kWindowInRt: case kWindowExRt: case kWindowExLf: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.d.topLeft.h, thisRoom->objects[i].data.d.topLeft.v); break; case kInvisTrans: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.d.topLeft.h, thisRoom->objects[i].data.d.topLeft.v); roomObjectRects[i].bottom = roomObjectRects[i].top + thisRoom->objects[i].data.d.tall; roomObjectRects[i].right += (short)thisRoom->objects[i].data.d.wide; break; case kDeluxeTrans: // Uses a kludge to get width & height (x4) wide = (thisRoom->objects[i].data.d.tall & 0xFF00) >> 8; tall = thisRoom->objects[i].data.d.tall & 0x00FF; QSetRect(&roomObjectRects[i], 0, 0, wide * 4, tall * 4); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.d.topLeft.h, thisRoom->objects[i].data.d.topLeft.v); break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.e.topLeft.h, thisRoom->objects[i].data.e.topLeft.v); break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kInvisLight: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.f.topLeft.h, thisRoom->objects[i].data.f.topLeft.v); break; case kFlourescent: case kTrackLight: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); roomObjectRects[i].right = thisRoom->objects[i].data.f.length; QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.f.topLeft.h, thisRoom->objects[i].data.f.topLeft.v); break; case kShredder: case kToaster: case kMacPlus: case kGuitar: case kTV: case kCoffee: case kOutlet: case kVCR: case kStereo: case kMicrowave: case kCinderBlock: case kFlowerBox: case kCDs: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.g.topLeft.h, thisRoom->objects[i].data.g.topLeft.v); break; case kCustomPict: thePict = GetPicture(thisRoom->objects[i].data.g.height); if (thePict == nil) { thisRoom->objects[i].data.g.height = 10000; roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; } else { HLock((Handle)thePict); roomObjectRects[i] = (*thePict)->picFrame; HUnlock((Handle)thePict); } ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.g.topLeft.h, thisRoom->objects[i].data.g.topLeft.v); break; case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kBall: case kDrip: case kFish: case kCobweb: roomObjectRects[i] = srcRects[thisRoom->objects[i].what]; ZeroRectCorner(&roomObjectRects[i]); QOffsetRect(&roomObjectRects[i], thisRoom->objects[i].data.h.topLeft.h, thisRoom->objects[i].data.h.topLeft.v); break; case kOzma: case kMirror: case kMousehole: case kFireplace: case kFlower: case kWallWindow: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: roomObjectRects[i] = thisRoom->objects[i].data.i.bounds; break; default: QSetRect(&roomObjectRects[i], -2, -2, -1, -1); break; } } } } #endif //-------------------------------------------------------------- DrawThisRoomsObjects #ifndef COMPILEDEMO void DrawThisRoomsObjects (void) { Rect tempRect; short i; CGrafPtr wasCPort; GDHandle wasWorld; Pattern dummyPattern; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); if ((noRoomAtAll) || (!houseUnlocked)) return; else { if (GetNumberOfLights(thisRoomNumber) <= 0) { PenMode(srcOr); PenPat(GetQDGlobalsGray(&dummyPattern)); PaintRect(&backSrcRect); PenNormal(); } for (i = 0; i < kMaxRoomObs; i++) { switch (thisRoom->objects[i].what) { case kObjectIsEmpty: break; case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kLeftFan: case kRightFan: case kTaper: case kCandle: case kStubby: case kGrecoVent: case kSewerBlower: DrawSimpleBlowers(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kTiki: DrawTiki(&roomObjectRects[i], 0); break; case kInvisBlower: DrawInvisibleBlower(&roomObjectRects[i]); break; case kLiftArea: DrawLiftArea(&roomObjectRects[i]); break; case kTable: DrawTable(&roomObjectRects[i], 0); break; case kShelf: DrawShelf(&roomObjectRects[i]); break; case kCabinet: DrawCabinet(&roomObjectRects[i]); break; case kFilingCabinet: case kDownStairs: case kDoorExRt: case kDoorExLf: case kWindowExRt: case kWindowExLf: case kOzma: DrawPictObject(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kWasteBasket: case kMilkCrate: DrawSimpleFurniture(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kCounter: DrawCounter(&roomObjectRects[i]); break; case kDresser: DrawDresser(&roomObjectRects[i]); break; case kDeckTable: DrawDeckTable(&roomObjectRects[i], 0); break; case kStool: DrawStool(&roomObjectRects[i], 0); break; case kInvisObstacle: DrawInvisObstacle(&roomObjectRects[i]); break; case kInvisBounce: DrawInvisBounce(&roomObjectRects[i]); break; case kRedClock: DrawRedClock(&roomObjectRects[i]); break; case kBlueClock: DrawBlueClock(&roomObjectRects[i]); break; case kYellowClock: DrawYellowClock(&roomObjectRects[i]); break; case kCuckoo: DrawCuckoo(&roomObjectRects[i]); break; case kPaper: case kBattery: case kBands: case kStar: case kSparkle: case kHelium: DrawSimplePrizes(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kGreaseRt: tempRect = roomObjectRects[i]; if (!thisRoom->objects[i].data.c.initial) QOffsetRect(&tempRect, -8, 0); DrawGreaseRt(&tempRect, thisRoom->objects[i].data.c.length, thisRoom->objects[i].data.c.initial); break; case kGreaseLf: tempRect = roomObjectRects[i]; if (!thisRoom->objects[i].data.c.initial) QOffsetRect(&tempRect, 8, 0); DrawGreaseLf(&tempRect, thisRoom->objects[i].data.c.length, thisRoom->objects[i].data.c.initial); break; case kFoil: DrawFoil(&roomObjectRects[i]); break; case kInvisBonus: DrawInvisBonus(&roomObjectRects[i]); break; case kSlider: DrawSlider(&roomObjectRects[i]); break; case kBBQ: case kTrunk: case kManhole: case kBooks: case kUpStairs: case kDoorInLf: case kDoorInRt: case kWindowInLf: case kWindowInRt: case kHipLamp: case kDecoLamp: case kGuitar: case kCinderBlock: case kFlowerBox: case kFireplace: case kBear: case kVase1: case kVase2: case kRug: case kChimes: DrawPictSansWhiteObject(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kCustomPict: DrawCustPictSansWhite(thisRoom->objects[i].data.g.height, &roomObjectRects[i]); break; case kMailboxLf: DrawMailboxLeft(&roomObjectRects[i], 0); break; case kMailboxRt: DrawMailboxRight(&roomObjectRects[i], 0); break; case kFloorTrans: case kCeilingTrans: DrawSimpleTransport(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kInvisTrans: case kDeluxeTrans: DrawInvisTransport(&roomObjectRects[i]); break; case kLightSwitch: DrawLightSwitch(&roomObjectRects[i], true); break; case kMachineSwitch: DrawMachineSwitch(&roomObjectRects[i], true); break; case kThermostat: DrawThermostat(&roomObjectRects[i], true); break; case kPowerSwitch: DrawPowerSwitch(&roomObjectRects[i], true); break; case kKnifeSwitch: DrawKnifeSwitch(&roomObjectRects[i], true); break; case kInvisSwitch: DrawInvisibleSwitch(&roomObjectRects[i]); break; case kTrigger: case kLgTrigger: DrawTrigger(&roomObjectRects[i]); break; case kSoundTrigger: DrawSoundTrigger(&roomObjectRects[i]); break; case kCeilingLight: case kLightBulb: case kTableLamp: DrawSimpleLight(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kFlourescent: DrawFlourescent(&roomObjectRects[i]); break; case kTrackLight: DrawTrackLight(&roomObjectRects[i]); break; case kInvisLight: DrawInvisLight(&roomObjectRects[i]); break; case kShredder: case kToaster: case kCDs: DrawSimpleAppliance(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kMacPlus: DrawMacPlus(&roomObjectRects[i], thisRoom->objects[i].data.g.initial, true); break; case kTV: DrawTV(&roomObjectRects[i], thisRoom->objects[i].data.g.initial, true); break; case kCoffee: DrawCoffee(&roomObjectRects[i], thisRoom->objects[i].data.g.initial, true); break; case kOutlet: DrawOutlet(&roomObjectRects[i]); break; case kVCR: DrawVCR(&roomObjectRects[i], thisRoom->objects[i].data.g.initial, true); break; case kStereo: DrawStereo(&roomObjectRects[i], isPlayMusicGame, true); break; case kMicrowave: DrawMicrowave(&roomObjectRects[i], thisRoom->objects[i].data.g.initial, true); break; case kBalloon: DrawBalloon(&roomObjectRects[i]); break; case kCopterLf: case kCopterRt: DrawCopter(&roomObjectRects[i]); break; case kDartLf: case kDartRt: DrawDart(&roomObjectRects[i], thisRoom->objects[i].what); break; case kBall: DrawBall(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kDrip: DrawDrip(&roomObjectRects[i]); break; case kFish: DrawFish(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kCobweb: case kCloud: DrawPictWithMaskObject(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kMirror: DrawMirror(&roomObjectRects[i]); break; case kMousehole: case kFaucet: DrawSimpleClutter(thisRoom->objects[i].what, &roomObjectRects[i]); break; case kFlower: DrawFlower(&roomObjectRects[i], thisRoom->objects[i].data.i.pict); break; case kWallWindow: DrawWallWindow(&roomObjectRects[i]); break; case kCalendar: DrawCalendar(&roomObjectRects[i]); break; case kBulletin: DrawBulletin(&roomObjectRects[i]); break; default: break; } } } SetGWorld(wasCPort, wasWorld); if (isFirstRoom) { CopyMask((BitMap *)*GetGWorldPixMap(glidSrcMap), (BitMap *)*GetGWorldPixMap(glidMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &gliderSrc[0], &gliderSrc[0], &initialGliderRect); } CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), (BitMap *)*GetGWorldPixMap(blowerMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &leftStartGliderSrc, &leftStartGliderSrc, &leftStartGliderDest); CopyMask((BitMap *)*GetGWorldPixMap(blowerSrcMap), (BitMap *)*GetGWorldPixMap(blowerMaskMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &rightStartGliderSrc, &rightStartGliderSrc, &rightStartGliderDest); CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &backSrcRect, &backSrcRect, srcCopy, nil); } #endif //-------------------------------------------------------------- HiliteAllObjects void HiliteAllObjects (void) { #ifndef COMPILEDEMO KeyMap theseKeys; short i; Pattern dummyPattern; if (theMode != kEditMode) return; PauseMarquee(); SetPort((GrafPtr)mainWindow); PenPat(GetQDGlobalsGray(&dummyPattern)); PenMode(patXor); for (i = 0; i < kMaxRoomObs; i++) FrameRect(&roomObjectRects[i]); do { GetKeys(theseKeys); } while ((BitTst(&theseKeys, kCommandKeyMap)) && (BitTst(&theseKeys, kOptionKeyMap))); for (i = 0; i < kMaxRoomObs; i++) FrameRect(&roomObjectRects[i]); PenNormal(); ResumeMarquee(); #endif } //-------------------------------------------------------------- GoToObjectInRoom void GoToObjectInRoom (short object, short floor, short suite) { #ifndef COMPILEDEMO short itsNumber, direction, dist; if (RoomExists(suite, floor, &itsNumber)) { if (itsNumber != thisRoomNumber) { CopyRoomToThisRoom(itsNumber); DeselectObject(); ReflectCurrentRoom(false); } else DeselectObject(); if (thisRoom->objects[object].what != kObjectIsEmpty) { objActive = object; if (ObjectHasHandle(&direction, &dist)) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else StartMarquee(&roomObjectRects[objActive]); UpdateMenus(false); } } #endif } //-------------------------------------------------------------- GoToObjectInRoomNum void GoToObjectInRoomNum (short object, short roomNum) { short floor, suite; if (GetRoomFloorSuite(roomNum, &floor, &suite)) GoToObjectInRoom(object, floor, suite); } \ No newline at end of file diff --git a/Sources/ObjectInfo.c b/Sources/ObjectInfo.c deleted file mode 100755 index f080b59..0000000 --- a/Sources/ObjectInfo.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // ObjectInfo.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include "DialogUtils.h" #include "Externs.h" #include "ObjectEdit.h" #include "RectUtils.h" #define kBlowerInfoDialogID 1007 #define kFurnitureInfoDialogID 1010 #define kSwitchInfoDialogID 1011 #define kLightInfoDialogID 1013 #define kApplianceInfoDialogID 1014 #define kInvisBonusInfoDialogID 1015 #define kGreaseInfoDialogID 1019 #define kTransInfoDialogID 1022 #define kEnemyInfoDialogID 1027 #define kFlowerInfoDialogID 1033 #define kTriggerInfoDialogID 1034 #define kMicrowaveInfoDialogID 1035 #define kCustPictInfoDialogID 1045 #define kCustPictIDItem 7 #define kInitialStateCheckbox 6 #define kForceCheckbox 7 #define kDirectionText 9 #define kLeftFacingRadio 16 #define kRightFacingRadio 17 #define kToggleRadio 6 #define kForceOnRadio 7 #define kForceOffRadio 8 #define kDelay3Item 6 #define kDelayItem 8 #define kDelayLabelItem 9 #define k100PtRadio 6 #define k300PtRadio 7 #define k500PtRadio 8 #define kGreaseItem 6 #define kLinkTransButton 6 #define kInitialStateCheckbox3 13 #define kTransRoomText 8 #define kTransObjectText 9 #define kKillBandsCheckbox 8 #define kKillBatteryCheckbox 9 #define kKillFoilCheckbox 10 #define kDelay2Item 7 #define kDelay2LabelItem 8 #define kDelay2LabelItem2 9 #define kInitialStateCheckbox2 10 #define kRadioFlower1 6 #define kRadioFlower6 11 #define kFlowerCancel 12 #define kGotoButton1 11 #define kGotoButton2 14 void UpdateBlowerInfo (DialogPtr); void UpdateFurnitureInfo (DialogPtr); void UpdateCustPictInfo (DialogPtr); void UpdateSwitchInfo (DialogPtr); void UpdateTriggerInfo (DialogPtr); void UpdateLightInfo (DialogPtr); void UpdateApplianceInfo (DialogPtr); void UpdateMicrowaveInfo (DialogPtr); void UpdateGreaseInfo (DialogPtr); void UpdateInvisBonusInfo (DialogPtr); void UpdateTransInfo (DialogPtr); void UpdateEnemyInfo (DialogPtr); void UpdateFlowerInfo (DialogPtr); pascal Boolean BlowerFilter (DialogPtr, EventRecord *, short *); pascal Boolean FurnitureFilter (DialogPtr, EventRecord *, short *); pascal Boolean CustPictFilter (DialogPtr, EventRecord *, short *); pascal Boolean SwitchFilter (DialogPtr, EventRecord *, short *); pascal Boolean TriggerFilter (DialogPtr, EventRecord *, short *); pascal Boolean LightFilter (DialogPtr, EventRecord *, short *); pascal Boolean ApplianceFilter (DialogPtr, EventRecord *, short *); pascal Boolean MicrowaveFilter (DialogPtr, EventRecord *, short *); pascal Boolean GreaseFilter (DialogPtr, EventRecord *, short *); pascal Boolean InvisBonusFilter (DialogPtr, EventRecord *, short *); pascal Boolean TransFilter (DialogPtr, EventRecord *, short *); pascal Boolean EnemyFilter (DialogPtr, EventRecord *, short *); pascal Boolean FlowerFilter (DialogPtr, EventRecord *, short *); void DoBlowerObjectInfo (short); void DoFurnitureObjectInfo (void); void DoCustPictObjectInfo (void); void DoSwitchObjectInfo (void); void DoTriggerObjectInfo (void); void DoLightObjectInfo (void); void DoApplianceObjectInfo (short); void DoMicrowaveObjectInfo (void); void DoGreaseObjectInfo (void); void DoInvisBonusObjectInfo (void); void DoTransObjectInfo (short); void DoEnemyObjectInfo (short); void DoFlowerObjectInfo (void); short newDirection, newPoint; Byte newType; extern retroLink retroLinkList[]; extern short linkRoom, linkType, wasFlower; extern Byte linkObject; extern Boolean linkerIsSwitch; #ifndef COMPILEDEMO //============================================================== Functions //-------------------------------------------------------------- UpdateBlowerInfo void UpdateBlowerInfo (DialogPtr theDialog) { #define kArrowheadLength 4 Rect bounds; DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 5, kRedOrangeColor8); if ((thisRoom->objects[objActive].what != kLeftFan) && (thisRoom->objects[objActive].what != kRightFan)) { GetDialogItemRect(theDialog, 8, &bounds); bounds.right += 2; bounds.bottom += 2; EraseRect(&bounds); bounds.right -= 2; bounds.bottom -= 2; PenSize(2, 2); switch (newDirection) { case 1: // up MoveTo(bounds.left + HalfRectWide(&bounds), bounds.top); Line(0, RectTall(&bounds)); MoveTo(bounds.left + HalfRectWide(&bounds), bounds.top); Line(kArrowheadLength, kArrowheadLength); MoveTo(bounds.left + HalfRectWide(&bounds), bounds.top); Line(-kArrowheadLength, kArrowheadLength); break; case 2: // right MoveTo(bounds.right, bounds.top + HalfRectTall(&bounds)); Line(-RectWide(&bounds), 0); MoveTo(bounds.right, bounds.top + HalfRectTall(&bounds)); Line(-kArrowheadLength, kArrowheadLength); MoveTo(bounds.right, bounds.top + HalfRectTall(&bounds)); Line(-kArrowheadLength, -kArrowheadLength); break; case 4: // down MoveTo(bounds.left + HalfRectWide(&bounds), bounds.top); Line(0, RectTall(&bounds)); MoveTo(bounds.left + HalfRectWide(&bounds), bounds.bottom); Line(kArrowheadLength, -kArrowheadLength); MoveTo(bounds.left + HalfRectWide(&bounds), bounds.bottom); Line(-kArrowheadLength, -kArrowheadLength); break; case 8: // left MoveTo(bounds.left, bounds.top + HalfRectTall(&bounds)); Line(RectWide(&bounds), 0); MoveTo(bounds.left, bounds.top + HalfRectTall(&bounds)); Line(kArrowheadLength, -kArrowheadLength); MoveTo(bounds.left, bounds.top + HalfRectTall(&bounds)); Line(kArrowheadLength, kArrowheadLength); break; default: break; } PenNormal(); if ((thisRoom->objects[objActive].what == kInvisBlower) || (thisRoom->objects[objActive].what == kLiftArea)) { switch (newDirection) { case 1: // up EraseDialogItem(theDialog, 11); FrameOvalDialogItem(theDialog, 12); FrameOvalDialogItem(theDialog, 13); FrameOvalDialogItem(theDialog, 14); break; case 2: // right FrameOvalDialogItem(theDialog, 11); EraseDialogItem(theDialog, 12); FrameOvalDialogItem(theDialog, 13); FrameOvalDialogItem(theDialog, 14); break; case 4: // down FrameOvalDialogItem(theDialog, 11); FrameOvalDialogItem(theDialog, 12); EraseDialogItem(theDialog, 13); FrameOvalDialogItem(theDialog, 14); break; case 8: // left FrameOvalDialogItem(theDialog, 11); FrameOvalDialogItem(theDialog, 12); FrameOvalDialogItem(theDialog, 13); EraseDialogItem(theDialog, 14); break; } } } } //-------------------------------------------------------------- UpdateFurnitureInfo void UpdateFurnitureInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 4, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateCustPictInfo void UpdateCustPictInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 5, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateSwitchInfo void UpdateSwitchInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); SelectFromRadioGroup(theDialog, newType + kToggleRadio, kToggleRadio, kForceOffRadio); FrameDialogItemC(theDialog, 4, kRedOrangeColor8); FrameDialogItemC(theDialog, 13, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateTriggerInfo void UpdateTriggerInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 4, kRedOrangeColor8); FrameDialogItemC(theDialog, 13, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateLightInfo void UpdateLightInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 5, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateApplianceInfo void UpdateApplianceInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 5, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateMicrowaveInfo void UpdateMicrowaveInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 5, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateGreaseInfo void UpdateGreaseInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 5, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateInvisBonusInfo void UpdateInvisBonusInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); SelectFromRadioGroup(theDialog, newPoint + k100PtRadio, k100PtRadio, k500PtRadio); FrameDialogItemC(theDialog, 4, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateTransInfo void UpdateTransInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 4, kRedOrangeColor8); FrameDialogItemC(theDialog, 10, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateEnemyInfo void UpdateEnemyInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 4, kRedOrangeColor8); } //-------------------------------------------------------------- UpdateFlowerInfo void UpdateFlowerInfo (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); FrameDialogItemC(theDialog, 4, kRedOrangeColor8); } //-------------------------------------------------------------- BlowerFilter pascal Boolean BlowerFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; case kTabKeyASCII: // SelectDialogItemText(dial, kRoomNameItem, 0, 1024); return(true); break; default: return(false); } break; case mouseDown: return(false); break; case mouseUp: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateBlowerInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- FurnitureFilter pascal Boolean FurnitureFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; default: return(false); } break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateFurnitureInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- CustPictFilter pascal Boolean CustPictFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; default: return(false); } break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateCustPictInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- SwitchFilter pascal Boolean SwitchFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; default: return(false); } break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateSwitchInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- TriggerFilter pascal Boolean TriggerFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; case kTabKeyASCII: SelectDialogItemText(dial, kDelay3Item, 0, 1024); return(true); break; default: return(false); } break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateTriggerInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- LightFilter pascal Boolean LightFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; default: return(false); } break; case mouseDown: return(false); break; case mouseUp: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateLightInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- ApplianceFilter pascal Boolean ApplianceFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; case kTabKeyASCII: SelectDialogItemText(dial, kDelayItem, 0, 1024); return(true); break; default: return(false); } break; case mouseDown: return(false); break; case mouseUp: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateApplianceInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- MicrowaveFilter pascal Boolean MicrowaveFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; default: return(false); } break; case mouseDown: return(false); break; case mouseUp: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateMicrowaveInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- GreaseFilter pascal Boolean GreaseFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; default: return(false); } break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateGreaseInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- InvisBonusFilter pascal Boolean InvisBonusFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; default: return(false); } break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateInvisBonusInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- TransFilter pascal Boolean TransFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; default: return(false); } break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateTransInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- EnemyFilter pascal Boolean EnemyFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; case kTabKeyASCII: SelectDialogItemText(dial, kDelay2Item, 0, 1024); return(true); break; default: return(false); } break; case mouseDown: return(false); break; case mouseUp: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateEnemyInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- EnemyFilter pascal Boolean FlowerFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; default: return(false); } break; case mouseDown: return(false); break; case mouseUp: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateFlowerInfo(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- DoBlowerObjectInfo void DoBlowerObjectInfo (short what) { DialogPtr infoDial; Str255 numberStr, kindStr, distStr; short item, initial; Boolean leaving, doReturn, leftFacing; ModalFilterUPP blowerFilterUPP; blowerFilterUPP = NewModalFilterUPP(BlowerFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); NumToString(thisRoom->objects[objActive].data.a.distance, distStr); ParamText(numberStr, kindStr, distStr, "\p"); // CenterDialog(kBlowerInfoDialogID); infoDial = GetNewDialog(kBlowerInfoDialogID, nil, kPutInFront); if (infoDial == nil) RedAlert(kErrDialogDidntLoad); SetPort((GrafPtr)infoDial); newDirection = thisRoom->objects[objActive].data.a.vector & 0x0F; if (thisRoom->objects[objActive].data.a.initial) SetDialogItemValue(infoDial, kInitialStateCheckbox, 1); else SetDialogItemValue(infoDial, kInitialStateCheckbox, 0); if ((what == kTaper) || (what == kCandle) || (what == kStubby) || (what == kTiki) || (what == kBBQ)) { HideDialogItem(infoDial, kInitialStateCheckbox); } if ((what == kLeftFan) || (what == kRightFan)) { if (what == kLeftFan) { SelectFromRadioGroup(infoDial, kLeftFacingRadio, kLeftFacingRadio, kRightFacingRadio); leftFacing = true; } else { SelectFromRadioGroup(infoDial, kRightFacingRadio, kLeftFacingRadio, kRightFacingRadio); leftFacing = false; } HideDialogItem(infoDial, kDirectionText); } else { HideDialogItem(infoDial, kLeftFacingRadio); HideDialogItem(infoDial, kRightFacingRadio); } if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 15); ShowWindow(GetDialogWindow(infoDial)); leaving = false; doReturn = false; while (!leaving) { ModalDialog(blowerFilterUPP, &item); if (item == kOkayButton) { GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); if (initial == 1) thisRoom->objects[objActive].data.a.initial = true; else thisRoom->objects[objActive].data.a.initial = false; thisRoom->objects[objActive].data.a.vector = (Byte)newDirection; if ((what == kLeftFan) || (what == kRightFan)) { if (leftFacing) thisRoom->objects[objActive].what = kLeftFan; else thisRoom->objects[objActive].what = kRightFan; if (KeepObjectLegal()) { } InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); } fileDirty = true; UpdateMenus(false); leaving = true; } else if (item == kCancelButton) leaving = true; else if (item == kInitialStateCheckbox) ToggleDialogItemValue(infoDial, kInitialStateCheckbox); else if (item == 15) // Linked From? button. { GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); if (initial == 1) thisRoom->objects[objActive].data.a.initial = true; else thisRoom->objects[objActive].data.a.initial = false; thisRoom->objects[objActive].data.a.vector = (Byte)newDirection; if ((what == kLeftFan) || (what == kRightFan)) { if (leftFacing) thisRoom->objects[objActive].what = kLeftFan; else thisRoom->objects[objActive].what = kRightFan; if (KeepObjectLegal()) { } InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); } fileDirty = true; UpdateMenus(false); leaving = true; doReturn = true; } else if (item == kLeftFacingRadio) { leftFacing = true; SelectFromRadioGroup(infoDial, kLeftFacingRadio, kLeftFacingRadio, kRightFacingRadio); } else if (item == kRightFacingRadio) { leftFacing = false; SelectFromRadioGroup(infoDial, kRightFacingRadio, kLeftFacingRadio, kRightFacingRadio); } else if ((thisRoom->objects[objActive].what == kInvisBlower) || (thisRoom->objects[objActive].what == kLiftArea)) { switch (item) { case 11: newDirection = 0x01; break; case 12: newDirection = 0x02; break; case 13: newDirection = 0x04; break; case 14: newDirection = 0x08; break; } UpdateBlowerInfo(infoDial); } } DisposeDialog(infoDial); DisposeModalFilterUPP(blowerFilterUPP); if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoFurnitureObjectInfo void DoFurnitureObjectInfo (void) { DialogPtr infoDial; Str255 numberStr, kindStr; short item; Boolean leaving, doReturn; ModalFilterUPP furnitureFilterUPP; furnitureFilterUPP = NewModalFilterUPP(FurnitureFilter); if (objActive == kInitialGliderSelected) { PasStringCopy("\p-", numberStr); PasStringCopy("\pGlider Begins", kindStr); } else if (objActive == kLeftGliderSelected) { PasStringCopy("\p-", numberStr); PasStringCopy("\pNew Glider (left)", kindStr); } else if (objActive == kRightGliderSelected) { PasStringCopy("\p-", numberStr); PasStringCopy("\pNew Glider (right)", kindStr); } else { NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); } ParamText(numberStr, kindStr, "\p", "\p"); BringUpDialog(&infoDial, kFurnitureInfoDialogID); if ((objActive < 0) || (retroLinkList[objActive].room == -1)) HideDialogItem(infoDial, 6); leaving = false; doReturn = false; while (!leaving) { ModalDialog(furnitureFilterUPP, &item); if (item == kOkayButton) leaving = true; else if (item == 6) // Linked From? button. { leaving = true; doReturn = true; } } DisposeDialog(infoDial); DisposeModalFilterUPP(furnitureFilterUPP); if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoCustPictObjectInfo void DoCustPictObjectInfo (void) { DialogPtr infoDial; Str255 numberStr, kindStr; long wasPict; short item; Boolean leaving; ModalFilterUPP custPictFilterUPP; custPictFilterUPP = NewModalFilterUPP(CustPictFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); if (thisRoom->objects[objActive].what == kCustomPict) ParamText(numberStr, kindStr, "\pPICT", "\p10000"); else ParamText(numberStr, kindStr, "\pSound", "\p3000"); BringUpDialog(&infoDial, kCustPictInfoDialogID); if (thisRoom->objects[objActive].what == kCustomPict) { wasPict = (long)(thisRoom->objects[objActive].data.g.height); SetDialogNumToStr(infoDial, kCustPictIDItem, wasPict); } else { wasPict = (long)(thisRoom->objects[objActive].data.e.where); SetDialogNumToStr(infoDial, kCustPictIDItem, wasPict); } SelectDialogItemText(infoDial, kCustPictIDItem, 0, 1024); leaving = false; while (!leaving) { ModalDialog(custPictFilterUPP, &item); if (item == kOkayButton) { GetDialogNumFromStr(infoDial, kCustPictIDItem, &wasPict); if (thisRoom->objects[objActive].what == kCustomPict) { if ((wasPict < 10000L) || (wasPict > 32767L)) { SysBeep(1); wasPict = (long)(thisRoom->objects[objActive].data.g.height); SetDialogNumToStr(infoDial, kCustPictIDItem, wasPict); SelectDialogItemText(infoDial, kCustPictIDItem, 0, 1024); } else { thisRoom->objects[objActive].data.g.height = (short)wasPict; if (KeepObjectLegal()) { } fileDirty = true; UpdateMenus(false); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); leaving = true; } } else { if ((wasPict < 3000L) || (wasPict > 32767L)) { SysBeep(1); wasPict = (long)(thisRoom->objects[objActive].data.e.where); SetDialogNumToStr(infoDial, kCustPictIDItem, wasPict); SelectDialogItemText(infoDial, kCustPictIDItem, 0, 1024); } else { thisRoom->objects[objActive].data.e.where = (short)wasPict; fileDirty = true; UpdateMenus(false); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); leaving = true; } } } else if (item == kCancelButton) { leaving = true; } } DisposeDialog(infoDial); DisposeModalFilterUPP(custPictFilterUPP); } //-------------------------------------------------------------- DoSwitchObjectInfo void DoSwitchObjectInfo (void) { DialogPtr infoDial; Str255 numberStr, kindStr, roomStr, tempStr, objStr; short item, floor, suite; Boolean leaving, doLink, doGoTo, doReturn; ModalFilterUPP switchFilterUPP; switchFilterUPP = NewModalFilterUPP(SwitchFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); if (thisRoom->objects[objActive].data.e.where == -1) PasStringCopy("\pnone", roomStr); else { ExtractFloorSuite(thisRoom->objects[objActive].data.e.where, &floor, &suite); NumToString((long)floor, roomStr); PasStringConcat(roomStr, "\p / "); NumToString((long)suite, tempStr); PasStringConcat(roomStr, tempStr); } if (thisRoom->objects[objActive].data.e.who == 255) PasStringCopy("\pnone", objStr); else NumToString((long)thisRoom->objects[objActive].data.e.who + 1, objStr); ParamText(numberStr, kindStr, roomStr, objStr); newType = thisRoom->objects[objActive].data.e.type; BringUpDialog(&infoDial, kSwitchInfoDialogID); leaving = false; doLink = false; doGoTo = false; doReturn = false; if (thisRoom->objects[objActive].data.e.who == 255) MyDisableControl(infoDial, kGotoButton2); if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 15); while (!leaving) { ModalDialog(switchFilterUPP, &item); if (item == kOkayButton) { thisRoom->objects[objActive].data.e.type = newType; fileDirty = true; UpdateMenus(false); leaving = true; } else if (item == kCancelButton) leaving = true; else if (item == kToggleRadio) { SelectFromRadioGroup(infoDial, item, kToggleRadio, kForceOffRadio); newType = kToggle; } else if (item == kForceOnRadio) { SelectFromRadioGroup(infoDial, item, kToggleRadio, kForceOffRadio); newType = kForceOn; } else if (item == kForceOffRadio) { SelectFromRadioGroup(infoDial, item, kToggleRadio, kForceOffRadio); newType = kForceOff; } else if (item == 9) { thisRoom->objects[objActive].data.e.type = newType; fileDirty = true; UpdateMenus(false); leaving = true; doLink = true; } else if (item == kGotoButton2) { thisRoom->objects[objActive].data.e.type = newType; fileDirty = true; UpdateMenus(false); leaving = true; doGoTo = true; } else if (item == 15) // Linked From? button. { thisRoom->objects[objActive].data.e.type = newType; fileDirty = true; UpdateMenus(false); leaving = true; doReturn = true; } } DisposeDialog(infoDial); DisposeModalFilterUPP(switchFilterUPP); if (doLink) { linkType = kSwitchLinkOnly; linkerIsSwitch = true; OpenLinkWindow(); linkRoom = thisRoomNumber; linkObject = (Byte)objActive; DeselectObject(); } else if (doGoTo) { GoToObjectInRoom((short)thisRoom->objects[objActive].data.e.who, floor, suite); } else if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoTriggerObjectInfo void DoTriggerObjectInfo (void) { DialogPtr infoDial; Str255 numberStr, kindStr, roomStr, tempStr, objStr; long delayIs; short item, floor, suite; Boolean leaving, doLink, doGoTo, doReturn; ModalFilterUPP triggerFilterUPP; triggerFilterUPP = NewModalFilterUPP(TriggerFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); if (thisRoom->objects[objActive].data.e.where == -1) PasStringCopy("\pnone", roomStr); else { ExtractFloorSuite(thisRoom->objects[objActive].data.e.where, &floor, &suite); NumToString((long)floor, roomStr); PasStringConcat(roomStr, "\p / "); NumToString((long)suite, tempStr); PasStringConcat(roomStr, tempStr); } if (thisRoom->objects[objActive].data.e.who == 255) PasStringCopy("\pnone", objStr); else NumToString((long)thisRoom->objects[objActive].data.e.who + 1, objStr); ParamText(numberStr, kindStr, roomStr, objStr); newType = thisRoom->objects[objActive].data.e.type; BringUpDialog(&infoDial, kTriggerInfoDialogID); leaving = false; doLink = false; doGoTo = false; doReturn = false; if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 15); if (thisRoom->objects[objActive].data.e.who == 255) MyDisableControl(infoDial, kGotoButton2); SetDialogNumToStr(infoDial, kDelay3Item, (long)thisRoom->objects[objActive].data.e.delay); SelectDialogItemText(infoDial, kDelay3Item, 0, 1024); while (!leaving) { ModalDialog(triggerFilterUPP, &item); if (item == kOkayButton) { GetDialogNumFromStr(infoDial, kDelay3Item, &delayIs); if ((delayIs < 0L) || (delayIs > 32767L)) { SysBeep(1); SetDialogNumToStr(infoDial, kDelay3Item, (long)thisRoom->objects[objActive].data.e.delay); SelectDialogItemText(infoDial, kDelay3Item, 0, 1024); } else { thisRoom->objects[objActive].data.e.delay = (short)delayIs; fileDirty = true; UpdateMenus(false); leaving = true; } } else if (item == kCancelButton) leaving = true; else if (item == 9) { GetDialogNumFromStr(infoDial, kDelay3Item, &delayIs); if ((delayIs < 0L) || (delayIs > 32767L)) { SysBeep(1); SetDialogNumToStr(infoDial, kDelay3Item, (long)thisRoom->objects[objActive].data.e.delay); SelectDialogItemText(infoDial, kDelay3Item, 0, 1024); } else { thisRoom->objects[objActive].data.e.delay = (short)delayIs; fileDirty = true; UpdateMenus(false); leaving = true; doLink = true; } } else if (item == kGotoButton2) { GetDialogNumFromStr(infoDial, kDelay3Item, &delayIs); if ((delayIs < 0L) || (delayIs > 32767L)) { SysBeep(1); SetDialogNumToStr(infoDial, kDelay3Item, (long)thisRoom->objects[objActive].data.e.delay); SelectDialogItemText(infoDial, kDelay3Item, 0, 1024); } else { thisRoom->objects[objActive].data.e.delay = (short)delayIs; fileDirty = true; UpdateMenus(false); leaving = true; doGoTo = true; } } else if (item == 15) // Linked From? button. { GetDialogNumFromStr(infoDial, kDelay3Item, &delayIs); if ((delayIs < 0L) || (delayIs > 32767L)) { SysBeep(1); SetDialogNumToStr(infoDial, kDelay3Item, (long)thisRoom->objects[objActive].data.e.delay); SelectDialogItemText(infoDial, kDelay3Item, 0, 1024); } else { thisRoom->objects[objActive].data.e.delay = (short)delayIs; fileDirty = true; UpdateMenus(false); leaving = true; doReturn = true; } } } DisposeDialog(infoDial); DisposeModalFilterUPP(triggerFilterUPP); if (doLink) { linkType = kTriggerLinkOnly; linkerIsSwitch = true; OpenLinkWindow(); linkRoom = thisRoomNumber; linkObject = (Byte)objActive; DeselectObject(); } else if (doGoTo) { GoToObjectInRoom((short)thisRoom->objects[objActive].data.e.who, floor, suite); } else if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoLightObjectInfo void DoLightObjectInfo (void) { DialogPtr infoDial; Str255 numberStr, kindStr; short item, initial; Boolean leaving, doReturn; ModalFilterUPP lightFilterUPP; lightFilterUPP = NewModalFilterUPP(LightFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); ParamText(numberStr, kindStr, "\p", "\p"); // CenterDialog(kLightInfoDialogID); infoDial = GetNewDialog(kLightInfoDialogID, nil, kPutInFront); if (infoDial == nil) RedAlert(kErrDialogDidntLoad); SetPort((GrafPtr)infoDial); if (thisRoom->objects[objActive].data.f.initial) SetDialogItemValue(infoDial, kInitialStateCheckbox, 1); else SetDialogItemValue(infoDial, kInitialStateCheckbox, 0); if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 8); ShowWindow(GetDialogWindow(infoDial)); leaving = false; doReturn = false; while (!leaving) { ModalDialog(lightFilterUPP, &item); if (item == kOkayButton) { GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); if (initial == 1) thisRoom->objects[objActive].data.f.initial = true; else thisRoom->objects[objActive].data.f.initial = false; ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); InvalWindowRect(mainWindow, &mainWindowRect); fileDirty = true; UpdateMenus(false); leaving = true; } else if (item == kCancelButton) leaving = true; else if (item == kInitialStateCheckbox) ToggleDialogItemValue(infoDial, kInitialStateCheckbox); else if (item == 8) // Linked From? button. { GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); if (initial == 1) thisRoom->objects[objActive].data.f.initial = true; else thisRoom->objects[objActive].data.f.initial = false; ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); InvalWindowRect(mainWindow, &mainWindowRect); fileDirty = true; UpdateMenus(false); leaving = true; doReturn = true; } } DisposeDialog(infoDial); DisposeModalFilterUPP(lightFilterUPP); if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoApplianceObjectInfo void DoApplianceObjectInfo (short what) { DialogPtr infoDial; Str255 numberStr, kindStr; long delay; short item, initial; Boolean leaving, doReturn; ModalFilterUPP applianceFilterUPP; applianceFilterUPP = NewModalFilterUPP(ApplianceFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); ParamText(numberStr, kindStr, "\p", "\p"); BringUpDialog(&infoDial, kApplianceInfoDialogID); if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 10); if (thisRoom->objects[objActive].data.g.initial) SetDialogItemValue(infoDial, kInitialStateCheckbox, 1); else SetDialogItemValue(infoDial, kInitialStateCheckbox, 0); if ((what == kShredder) || (what == kMacPlus) || (what == kTV) || (what == kCoffee) || (what == kVCR) || (what == kMicrowave)) { HideDialogItem(infoDial, kDelayItem); HideDialogItem(infoDial, kDelayLabelItem); } delay = thisRoom->objects[objActive].data.g.delay; SetDialogNumToStr(infoDial, kDelayItem, (long)delay); SelectDialogItemText(infoDial, kDelayItem, 0, 1024); leaving = false; doReturn = false; while (!leaving) { ModalDialog(applianceFilterUPP, &item); if (item == kOkayButton) { GetDialogNumFromStr(infoDial, kDelayItem, &delay); if ((delay < 0L) || (delay > 255L)) { SysBeep(0); delay = thisRoom->objects[objActive].data.g.delay; SetDialogNumToStr(infoDial, kDelayItem, (long)delay); SelectDialogItemText(infoDial, kDelayItem, 0, 1024); } else { thisRoom->objects[objActive].data.g.delay = (Byte)delay; GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); if (initial == 1) thisRoom->objects[objActive].data.g.initial = true; else thisRoom->objects[objActive].data.g.initial = false; fileDirty = true; UpdateMenus(false); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); leaving = true; } } else if (item == kCancelButton) leaving = true; else if (item == kInitialStateCheckbox) ToggleDialogItemValue(infoDial, kInitialStateCheckbox); else if (item == 10) // Linked From? button. { GetDialogNumFromStr(infoDial, kDelayItem, &delay); if ((delay < 0L) || (delay > 255L)) { SysBeep(0); delay = thisRoom->objects[objActive].data.g.delay; SetDialogNumToStr(infoDial, kDelayItem, (long)delay); SelectDialogItemText(infoDial, kDelayItem, 0, 1024); } else { thisRoom->objects[objActive].data.g.delay = (Byte)delay; GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); if (initial == 1) thisRoom->objects[objActive].data.g.initial = true; else thisRoom->objects[objActive].data.g.initial = false; fileDirty = true; UpdateMenus(false); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); leaving = true; doReturn = true; } } } DisposeDialog(infoDial); DisposeModalFilterUPP(applianceFilterUPP); if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoMicrowaveObjectInfo void DoMicrowaveObjectInfo (void) { DialogPtr infoDial; Str255 numberStr, kindStr; short item, initial, kills; Boolean leaving, doReturn; ModalFilterUPP microwaveFilterUPP; microwaveFilterUPP = NewModalFilterUPP(MicrowaveFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); ParamText(numberStr, kindStr, "\p", "\p"); BringUpDialog(&infoDial, kMicrowaveInfoDialogID); if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 11); if (thisRoom->objects[objActive].data.g.initial) SetDialogItemValue(infoDial, kInitialStateCheckbox, 1); else SetDialogItemValue(infoDial, kInitialStateCheckbox, 0); kills = (short)thisRoom->objects[objActive].data.g.byte0; if ((kills & 0x0001) == 0x0001) SetDialogItemValue(infoDial, kKillBandsCheckbox, 1); else SetDialogItemValue(infoDial, kKillBandsCheckbox, 0); if ((kills & 0x0002) == 0x0002) SetDialogItemValue(infoDial, kKillBatteryCheckbox, 1); else SetDialogItemValue(infoDial, kKillBatteryCheckbox, 0); if ((kills & 0x0004) == 0x0004) SetDialogItemValue(infoDial, kKillFoilCheckbox, 1); else SetDialogItemValue(infoDial, kKillFoilCheckbox, 0); leaving = false; doReturn = false; while (!leaving) { ModalDialog(microwaveFilterUPP, &item); if (item == kOkayButton) { GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); if (initial == 1) thisRoom->objects[objActive].data.g.initial = true; else thisRoom->objects[objActive].data.g.initial = false; kills = 0; GetDialogItemValue(infoDial, kKillBandsCheckbox, &initial); if (initial == 1) kills += 1; GetDialogItemValue(infoDial, kKillBatteryCheckbox, &initial); if (initial == 1) kills += 2; GetDialogItemValue(infoDial, kKillFoilCheckbox, &initial); if (initial == 1) kills += 4; thisRoom->objects[objActive].data.g.byte0 = (Byte)kills; fileDirty = true; UpdateMenus(false); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); leaving = true; } else if (item == kCancelButton) leaving = true; else if (item == kInitialStateCheckbox) ToggleDialogItemValue(infoDial, kInitialStateCheckbox); else if (item == kKillBandsCheckbox) ToggleDialogItemValue(infoDial, kKillBandsCheckbox); else if (item == kKillBatteryCheckbox) ToggleDialogItemValue(infoDial, kKillBatteryCheckbox); else if (item == kKillFoilCheckbox) ToggleDialogItemValue(infoDial, kKillFoilCheckbox); else if (item == 11) // Linked From? button. { GetDialogItemValue(infoDial, kInitialStateCheckbox, &initial); if (initial == 1) thisRoom->objects[objActive].data.g.initial = true; else thisRoom->objects[objActive].data.g.initial = false; kills = 0; GetDialogItemValue(infoDial, kKillBandsCheckbox, &initial); if (initial == 1) kills += 1; GetDialogItemValue(infoDial, kKillBatteryCheckbox, &initial); if (initial == 1) kills += 2; GetDialogItemValue(infoDial, kKillFoilCheckbox, &initial); if (initial == 1) kills += 4; thisRoom->objects[objActive].data.g.byte0 = (Byte)kills; fileDirty = true; UpdateMenus(false); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); leaving = true; doReturn = true; } } DisposeDialog(infoDial); DisposeModalFilterUPP(microwaveFilterUPP); if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoGreaseObjectInfo void DoGreaseObjectInfo (void) { DialogPtr infoDial; Str255 numberStr, kindStr; short item; Boolean leaving, wasSpilled, doReturn; ModalFilterUPP greaseFilterUPP; greaseFilterUPP = NewModalFilterUPP(GreaseFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); ParamText(numberStr, kindStr, "\p", "\p"); BringUpDialog(&infoDial, kGreaseInfoDialogID); if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 8); wasSpilled = !(thisRoom->objects[objActive].data.c.initial); SetDialogItemValue(infoDial, kGreaseItem, (short)wasSpilled); leaving = false; doReturn = false; while (!leaving) { ModalDialog(greaseFilterUPP, &item); if (item == kOkayButton) { thisRoom->objects[objActive].data.c.initial = !wasSpilled; fileDirty = true; UpdateMenus(false); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); leaving = true; } else if (item == kCancelButton) { leaving = true; } else if (item == kGreaseItem) { wasSpilled = !wasSpilled; SetDialogItemValue(infoDial, kGreaseItem, (short)wasSpilled); } else if (item == 8) // Linked From? button. { thisRoom->objects[objActive].data.c.initial = !wasSpilled; fileDirty = true; UpdateMenus(false); InvalWindowRect(mainWindow, &mainWindowRect); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); leaving = true; doReturn = true; } } DisposeDialog(infoDial); DisposeModalFilterUPP(greaseFilterUPP); if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoInvisBonusObjectInfo void DoInvisBonusObjectInfo (void) { DialogPtr infoDial; Str255 numberStr, kindStr; short item; Boolean leaving, doReturn; ModalFilterUPP invisBonusFilterUPP; invisBonusFilterUPP = NewModalFilterUPP(InvisBonusFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); ParamText(numberStr, kindStr, "\p", "\p"); switch (thisRoom->objects[objActive].data.c.points) { case 300: newPoint = 1; break; case 500: newPoint = 2; break; default: newPoint = 0; break; } BringUpDialog(&infoDial, kInvisBonusInfoDialogID); if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 9); leaving = false; doReturn = false; while (!leaving) { ModalDialog(invisBonusFilterUPP, &item); if (item == kOkayButton) { switch (newPoint) { case 0: thisRoom->objects[objActive].data.c.points = 100; break; case 1: thisRoom->objects[objActive].data.c.points = 300; break; case 2: thisRoom->objects[objActive].data.c.points = 500; break; } fileDirty = true; UpdateMenus(false); leaving = true; } else if (item == kCancelButton) leaving = true; else if (item == k100PtRadio) { SelectFromRadioGroup(infoDial, item, k100PtRadio, k500PtRadio); newPoint = 0; } else if (item == k300PtRadio) { SelectFromRadioGroup(infoDial, item, k100PtRadio, k500PtRadio); newPoint = 1; } else if (item == k500PtRadio) { SelectFromRadioGroup(infoDial, item, k100PtRadio, k500PtRadio); newPoint = 2; } else if (item == 9) // Linked From? button. { switch (newPoint) { case 0: thisRoom->objects[objActive].data.c.points = 100; break; case 1: thisRoom->objects[objActive].data.c.points = 300; break; case 2: thisRoom->objects[objActive].data.c.points = 500; break; } fileDirty = true; UpdateMenus(false); leaving = true; doReturn = true; } } DisposeDialog(infoDial); DisposeModalFilterUPP(invisBonusFilterUPP); if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoTransObjectInfo void DoTransObjectInfo (short what) { DialogPtr infoDial; Str255 numberStr, kindStr, roomStr, tempStr, objStr; short item, floor, suite; Boolean leaving, doLink, doGoTo, doReturn, wasState; ModalFilterUPP transFilterUPP; transFilterUPP = NewModalFilterUPP(TransFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); if (thisRoom->objects[objActive].data.d.where == -1) PasStringCopy("\pnone", roomStr); else { ExtractFloorSuite(thisRoom->objects[objActive].data.d.where, &floor, &suite); NumToString((long)floor, roomStr); PasStringConcat(roomStr, "\p / "); NumToString((long)suite, tempStr); PasStringConcat(roomStr, tempStr); } if (thisRoom->objects[objActive].data.d.who == 255) PasStringCopy("\pnone", objStr); else NumToString((long)thisRoom->objects[objActive].data.d.who + 1, objStr); ParamText(numberStr, kindStr, roomStr, objStr); BringUpDialog(&infoDial, kTransInfoDialogID); if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 12); if (what != kDeluxeTrans) HideDialogItem(infoDial, kInitialStateCheckbox3); else { wasState = (thisRoom->objects[objActive].data.d.wide & 0xF0) >> 4; SetDialogItemValue(infoDial, kInitialStateCheckbox3, (short)wasState); } leaving = false; doLink = false; doGoTo = false; doReturn = false; if (thisRoom->objects[objActive].data.d.who == 255) MyDisableControl(infoDial, kGotoButton1); while (!leaving) { ModalDialog(transFilterUPP, &item); if (item == kOkayButton) { if (what == kDeluxeTrans) thisRoom->objects[objActive].data.d.wide = wasState << 4; fileDirty = true; UpdateMenus(false); leaving = true; } else if (item == kCancelButton) leaving = true; else if (item == kLinkTransButton) { if (what == kDeluxeTrans) thisRoom->objects[objActive].data.d.wide = wasState << 4; fileDirty = true; UpdateMenus(false); leaving = true; doLink = true; } else if (item == kGotoButton1) { if (what == kDeluxeTrans) thisRoom->objects[objActive].data.d.wide = wasState << 4; fileDirty = true; UpdateMenus(false); leaving = true; doGoTo = true; } else if (item == 12) // Linked From? button. { if (what == kDeluxeTrans) thisRoom->objects[objActive].data.d.wide = wasState << 4; fileDirty = true; UpdateMenus(false); leaving = true; doReturn = true; } else if (item == kInitialStateCheckbox3) { wasState = !wasState; SetDialogItemValue(infoDial, kInitialStateCheckbox3, (short)wasState); } } DisposeDialog(infoDial); DisposeModalFilterUPP(transFilterUPP); if (doLink) { linkType = kTransportLinkOnly; linkerIsSwitch = false; OpenLinkWindow(); linkRoom = thisRoomNumber; linkObject = (Byte)objActive; DeselectObject(); } else if (doGoTo) { GoToObjectInRoom((short)thisRoom->objects[objActive].data.d.who, floor, suite); } else if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoEnemyObjectInfo void DoEnemyObjectInfo (short what) { DialogPtr infoDial; Str255 numberStr, kindStr; long delay; short item, initial; Boolean leaving, doReturn; ModalFilterUPP enemyFilterUPP; enemyFilterUPP = NewModalFilterUPP(EnemyFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); ParamText(numberStr, kindStr, "\p", "\p"); BringUpDialog(&infoDial, kEnemyInfoDialogID); if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 11); delay = thisRoom->objects[objActive].data.h.delay; SetDialogNumToStr(infoDial, kDelay2Item, (long)delay); SelectDialogItemText(infoDial, kDelay2Item, 0, 1024); if (thisRoom->objects[objActive].data.h.initial) SetDialogItemValue(infoDial, kInitialStateCheckbox2, 1); else SetDialogItemValue(infoDial, kInitialStateCheckbox2, 0); if (what == kBall) { HideDialogItem(infoDial, kDelay2Item); HideDialogItem(infoDial, 8); HideDialogItem(infoDial, 9); } leaving = false; doReturn = false; while (!leaving) { ModalDialog(enemyFilterUPP, &item); if (item == kOkayButton) { GetDialogNumFromStr(infoDial, kDelay2Item, &delay); if (((delay < 0L) || (delay > 255L)) && (what != kBall)) { SysBeep(0); delay = thisRoom->objects[objActive].data.h.delay; SetDialogNumToStr(infoDial, kDelay2Item, (long)delay); SelectDialogItemText(infoDial, kDelay2Item, 0, 1024); } else { GetDialogItemValue(infoDial, kInitialStateCheckbox2, &initial); if (initial == 1) thisRoom->objects[objActive].data.h.initial = true; else thisRoom->objects[objActive].data.h.initial = false; if (what != kBall) thisRoom->objects[objActive].data.h.delay = (Byte)delay; fileDirty = true; UpdateMenus(false); leaving = true; } } else if (item == kCancelButton) leaving = true; else if (item == kInitialStateCheckbox2) ToggleDialogItemValue(infoDial, kInitialStateCheckbox2); else if (item == 11) // Linked From? button. { GetDialogNumFromStr(infoDial, kDelay2Item, &delay); if (((delay < 0L) || (delay > 255L)) && (what != kBall)) { SysBeep(0); delay = thisRoom->objects[objActive].data.h.delay; SetDialogNumToStr(infoDial, kDelay2Item, (long)delay); SelectDialogItemText(infoDial, kDelay2Item, 0, 1024); } else { GetDialogItemValue(infoDial, kInitialStateCheckbox2, &initial); if (initial == 1) thisRoom->objects[objActive].data.h.initial = true; else thisRoom->objects[objActive].data.h.initial = false; if (what != kBall) thisRoom->objects[objActive].data.h.delay = (Byte)delay; fileDirty = true; UpdateMenus(false); leaving = true; doReturn = true; } } } DisposeDialog(infoDial); DisposeModalFilterUPP(enemyFilterUPP); if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoFlowerObjectInfo void DoFlowerObjectInfo (void) { DialogPtr infoDial; Str255 numberStr, kindStr; short item, flower; Boolean leaving, doReturn; ModalFilterUPP flowerFilterUPP; flowerFilterUPP = NewModalFilterUPP(FlowerFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); ParamText(numberStr, kindStr, "\p", "\p"); BringUpDialog(&infoDial, kFlowerInfoDialogID); if (retroLinkList[objActive].room == -1) HideDialogItem(infoDial, 13); flower = thisRoom->objects[objActive].data.i.pict + kRadioFlower1; SelectFromRadioGroup(infoDial, flower, kRadioFlower1, kRadioFlower6); leaving = false; doReturn = false; while (!leaving) { ModalDialog(flowerFilterUPP, &item); if (item == kOkayButton) { flower -= kRadioFlower1; if (flower != thisRoom->objects[objActive].data.i.pict) { InvalWindowRect(mainWindow, &thisRoom->objects[objActive].data.i.bounds); thisRoom->objects[objActive].data.i.bounds.right = thisRoom->objects[objActive].data.i.bounds.left + RectWide(&flowerSrc[flower]); thisRoom->objects[objActive].data.i.bounds.top = thisRoom->objects[objActive].data.i.bounds.bottom - RectTall(&flowerSrc[flower]); thisRoom->objects[objActive].data.i.pict = flower; InvalWindowRect(mainWindow, &thisRoom->objects[objActive].data.i.bounds); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); fileDirty = true; UpdateMenus(false); wasFlower = flower; } leaving = true; } else if ((item >= kRadioFlower1) && (item <= kRadioFlower6)) { flower = item; SelectFromRadioGroup(infoDial, flower, kRadioFlower1, kRadioFlower6); } else if (item == kFlowerCancel) { leaving = true; } else if (item == 13) // Linked From? button. { flower -= kRadioFlower1; if (flower != thisRoom->objects[objActive].data.i.pict) { InvalWindowRect(mainWindow, &thisRoom->objects[objActive].data.i.bounds); thisRoom->objects[objActive].data.i.bounds.right = thisRoom->objects[objActive].data.i.bounds.left + RectWide(&flowerSrc[flower]); thisRoom->objects[objActive].data.i.bounds.top = thisRoom->objects[objActive].data.i.bounds.bottom - RectTall(&flowerSrc[flower]); thisRoom->objects[objActive].data.i.pict = flower; InvalWindowRect(mainWindow, &thisRoom->objects[objActive].data.i.bounds); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); fileDirty = true; UpdateMenus(false); wasFlower = flower; } leaving = true; doReturn = true; } } DisposeDialog(infoDial); DisposeModalFilterUPP(flowerFilterUPP); if (doReturn) { GoToObjectInRoomNum(retroLinkList[objActive].object, retroLinkList[objActive].room); } } //-------------------------------------------------------------- DoObjectInfo void DoObjectInfo (void) { if ((objActive == kInitialGliderSelected) || (objActive == kLeftGliderSelected) || (objActive == kRightGliderSelected)) { DoFurnitureObjectInfo(); return; } switch (thisRoom->objects[objActive].what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kLeftFan: case kRightFan: case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kInvisBlower: case kGrecoVent: case kSewerBlower: case kLiftArea: DoBlowerObjectInfo(thisRoom->objects[objActive].what); break; case kTable: case kShelf: case kCabinet: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kCounter: case kDresser: case kDeckTable: case kStool: case kTrunk: case kInvisObstacle: case kManhole: case kBooks: case kInvisBounce: case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kFoil: case kStar: case kSparkle: case kHelium: case kSlider: case kUpStairs: case kDownStairs: case kDoorInLf: case kDoorInRt: case kDoorExRt: case kDoorExLf: case kWindowInLf: case kWindowInRt: case kWindowExRt: case kWindowExLf: case kCinderBlock: case kFlowerBox: case kCDs: case kGuitar: case kStereo: case kCobweb: case kOzma: case kMirror: case kMousehole: case kFireplace: case kWallWindow: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: DoFurnitureObjectInfo(); break; case kGreaseRt: case kGreaseLf: DoGreaseObjectInfo(); break; case kInvisBonus: DoInvisBonusObjectInfo(); break; case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kInvisTrans: case kDeluxeTrans: DoTransObjectInfo(thisRoom->objects[objActive].what); break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: DoSwitchObjectInfo(); break; case kTrigger: case kLgTrigger: DoTriggerObjectInfo(); break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: DoLightObjectInfo(); break; case kShredder: case kToaster: case kMacPlus: case kTV: case kCoffee: case kOutlet: case kVCR: DoApplianceObjectInfo(thisRoom->objects[objActive].what); break; case kMicrowave: DoMicrowaveObjectInfo(); break; case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kBall: case kDrip: case kFish: DoEnemyObjectInfo(thisRoom->objects[objActive].what); break; case kFlower: DoFlowerObjectInfo(); break; case kSoundTrigger: case kCustomPict: DoCustPictObjectInfo(); break; default: SysBeep(1); break; } } #endif \ No newline at end of file diff --git a/Sources/ObjectRects.c b/Sources/ObjectRects.c deleted file mode 100755 index 1ada2f5..0000000 --- a/Sources/ObjectRects.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // ObjectRects.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "RectUtils.h" #define kFloorColumnWide 4 #define kCeilingColumnWide 24 #define kFanColumnThick 16 #define kFanColumnDown 20 #define kDeadlyFlameHeight 24 #define kStoolThick 25 #define kShredderActiveHigh 40 short AddActiveRect (Rect *, short, short, Boolean, Boolean); extern hotPtr hotSpots; extern short nHotSpots, numChimes; //============================================================== Functions //-------------------------------------------------------------- GetObjectRect void GetObjectRect (objectPtr who, Rect *itsRect) { PicHandle thePict; short wide, tall; switch (who->what) { case kObjectIsEmpty: QSetRect(itsRect, 0, 0, 0, 0); break; case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kSewerGrate: case kLeftFan: case kRightFan: case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: case kInvisBlower: case kGrecoVent: case kSewerBlower: *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.a.topLeft.h, who->data.a.topLeft.v); break; case kLiftArea: QSetRect(itsRect, 0, 0, who->data.a.distance, who->data.a.tall * 2); QOffsetRect(itsRect, who->data.a.topLeft.h, who->data.a.topLeft.v); break; *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.a.topLeft.h, who->data.a.topLeft.v); break; case kTable: case kShelf: case kCabinet: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kCounter: case kDresser: case kStool: case kTrunk: case kDeckTable: case kInvisObstacle: case kManhole: case kBooks: case kInvisBounce: *itsRect = who->data.b.bounds; break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kGreaseRt: case kGreaseLf: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.c.topLeft.h, who->data.c.topLeft.v); break; case kSlider: *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.c.topLeft.h, who->data.c.topLeft.v); itsRect->right = itsRect->left + who->data.c.length; break; case kUpStairs: case kDownStairs: case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kDoorInLf: case kDoorInRt: case kDoorExRt: case kDoorExLf: case kWindowInLf: case kWindowInRt: case kWindowExRt: case kWindowExLf: *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.d.topLeft.h, who->data.d.topLeft.v); break; case kInvisTrans: *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.d.topLeft.h, who->data.d.topLeft.v); itsRect->bottom = itsRect->top + who->data.d.tall; itsRect->right += (short)who->data.d.wide; break; case kDeluxeTrans: wide = (who->data.d.tall & 0xFF00) >> 8; // Get high byte tall = who->data.d.tall & 0x00FF; // Get low byte QSetRect(itsRect, 0, 0, wide * 4, tall * 4); // Scale by 4 QOffsetRect(itsRect, who->data.d.topLeft.h, who->data.d.topLeft.v); break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.e.topLeft.h, who->data.e.topLeft.v); break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kInvisLight: *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.f.topLeft.h, who->data.f.topLeft.v); break; case kFlourescent: case kTrackLight: *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); itsRect->right = who->data.f.length; QOffsetRect(itsRect, who->data.f.topLeft.h, who->data.f.topLeft.v); break; case kShredder: case kToaster: case kMacPlus: case kGuitar: case kTV: case kCoffee: case kOutlet: case kVCR: case kStereo: case kMicrowave: case kCinderBlock: case kFlowerBox: case kCDs: *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.g.topLeft.h, who->data.g.topLeft.v); break; case kCustomPict: thePict = GetPicture(who->data.g.height); if (thePict == nil) { who->data.g.height = 10000; *itsRect = srcRects[who->what]; } else { HLock((Handle)thePict); *itsRect = (*thePict)->picFrame; HUnlock((Handle)thePict); } ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.g.topLeft.h, who->data.g.topLeft.v); break; case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kBall: case kDrip: case kFish: case kCobweb: *itsRect = srcRects[who->what]; ZeroRectCorner(itsRect); QOffsetRect(itsRect, who->data.h.topLeft.h, who->data.h.topLeft.v); break; case kOzma: case kMirror: case kMousehole: case kFireplace: case kFlower: case kWallWindow: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: *itsRect = who->data.i.bounds; break; } } //-------------------------------------------------------------- AddActiveRect short AddActiveRect (Rect *bounds, short action, short who, Boolean isOn, Boolean doScrutinize) { if (nHotSpots >= kMaxHotSpots) return (-1); hotSpots[nHotSpots].bounds = *bounds; // the active rect hotSpots[nHotSpots].action = action; // what it does hotSpots[nHotSpots].who = who; // local obj. linked to hotSpots[nHotSpots].isOn = isOn; // is it active? hotSpots[nHotSpots].stillOver = false; hotSpots[nHotSpots].doScrutinize = doScrutinize; nHotSpots++; return (nHotSpots - 1); } //-------------------------------------------------------------- CreateActiveRects short CreateActiveRects (short who) { objectType theObject; Rect bounds; short hotSpotNumber, wide, tall; Boolean isOn; hotSpotNumber = -1; theObject = masterObjects[who].theObject; switch (theObject.what) { case kObjectIsEmpty: break; case kFloorVent: QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); QOffsetRect(&bounds, HalfRectWide(&srcRects[kFloorVent]) - kFloorColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, false); break; case kCeilingVent: QSetRect(&bounds, 0, 0, kCeilingColumnWide, theObject.data.a.distance); QOffsetRect(&bounds, HalfRectWide(&srcRects[kCeilingVent]) - kCeilingColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kDropIt, who, theObject.data.a.state, false); break; case kFloorBlower: QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); QOffsetRect(&bounds, HalfRectWide(&srcRects[kFloorBlower]) - kFloorColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, false); break; case kCeilingBlower: QSetRect(&bounds, 0, 0, kCeilingColumnWide, theObject.data.a.distance); QOffsetRect(&bounds, HalfRectWide(&srcRects[kCeilingBlower]) - kCeilingColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kDropIt, who, theObject.data.a.state, false); break; case kSewerGrate: QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); QOffsetRect(&bounds, HalfRectWide(&srcRects[kSewerGrate]) - kFloorColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, false); break; case kLeftFan: QSetRect(&bounds, 0, 0, 13, 43); QOffsetRect(&bounds, theObject.data.a.topLeft.h + 16, theObject.data.a.topLeft.v + 12); hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); QSetRect(&bounds, 0, 0, theObject.data.a.distance, kFanColumnThick); QOffsetRect(&bounds, -(theObject.data.a.distance), kFanColumnDown); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kPushItLeft, who, theObject.data.a.state, false); break; case kRightFan: QSetRect(&bounds, 0, 0, 13, 43); QOffsetRect(&bounds, theObject.data.a.topLeft.h + 6, theObject.data.a.topLeft.v + 12); hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); QSetRect(&bounds, 0, 0, theObject.data.a.distance, kFanColumnThick); QOffsetRect(&bounds, RectWide(&srcRects[kRightFan]), kFanColumnDown); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kPushItRight, who, theObject.data.a.state, false); break; case kTaper: QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); QOffsetRect(&bounds, HalfRectWide(&srcRects[kTaper]) - kFloorColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); if ((bounds.bottom - bounds.top) > kDeadlyFlameHeight) { bounds.bottom -= kDeadlyFlameHeight; hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, true, false); bounds.bottom += kDeadlyFlameHeight; bounds.top = bounds.bottom - kDeadlyFlameHeight + 2; hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); } else hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); QSetRect(&bounds, 0, 0, 7, 48); QOffsetRect(&bounds, theObject.data.a.topLeft.h + 6, theObject.data.a.topLeft.v + 11); hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); break; case kCandle: QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); QOffsetRect(&bounds, HalfRectWide(&srcRects[kCandle]) - kFloorColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h - 2, theObject.data.a.topLeft.v); if ((bounds.bottom - bounds.top) > kDeadlyFlameHeight) { bounds.bottom -= kDeadlyFlameHeight; hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, true, false); bounds.bottom += kDeadlyFlameHeight; bounds.top = bounds.bottom - kDeadlyFlameHeight + 2; hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); } else hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); QSetRect(&bounds, 0, 0, 8, 20); QOffsetRect(&bounds, theObject.data.a.topLeft.h + 9, theObject.data.a.topLeft.v + 11); hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); break; case kStubby: QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); QOffsetRect(&bounds, (HalfRectWide(&srcRects[kStubby]) - kFloorColumnWide / 2) - 1, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); if ((bounds.bottom - bounds.top) > kDeadlyFlameHeight) { bounds.bottom -= kDeadlyFlameHeight; hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, true, false); bounds.bottom += kDeadlyFlameHeight; bounds.top = bounds.bottom - kDeadlyFlameHeight + 2; hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); } else hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); QSetRect(&bounds, 0, 0, 15, 26); QOffsetRect(&bounds, theObject.data.a.topLeft.h + 1, theObject.data.a.topLeft.v + 11); hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); break; case kTiki: QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); QOffsetRect(&bounds, HalfRectWide(&srcRects[kTiki]) - kFloorColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); if ((bounds.bottom - bounds.top) > kDeadlyFlameHeight) { bounds.bottom -= kDeadlyFlameHeight; hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, true, false); bounds.bottom += kDeadlyFlameHeight; bounds.top = bounds.bottom - kDeadlyFlameHeight + 2; hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); } else hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); QSetRect(&bounds, 0, 0, 15, 14); QOffsetRect(&bounds, theObject.data.a.topLeft.h + 6, theObject.data.a.topLeft.v + 6); hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); break; case kBBQ: QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 8); QOffsetRect(&bounds, HalfRectWide(&srcRects[kBBQ]) - kFloorColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); if ((bounds.bottom - bounds.top) > kDeadlyFlameHeight) { bounds.bottom -= kDeadlyFlameHeight; hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, true, false); bounds.bottom += kDeadlyFlameHeight; bounds.top = bounds.bottom - kDeadlyFlameHeight + 2; hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); } else hotSpotNumber = AddActiveRect(&bounds, kBurnIt, who, true, false); QSetRect(&bounds, 0, 0, 52, 17); QOffsetRect(&bounds, theObject.data.a.topLeft.h + 6, theObject.data.a.topLeft.v + 8); hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); break; case kInvisBlower: switch (theObject.data.a.vector & 0x0F) { case 1: // up QSetRect(&bounds, 0, -theObject.data.a.distance - 24, kFloorColumnWide, 0); QOffsetRect(&bounds, 12 - kFloorColumnWide / 2, 24); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, false); break; case 2: // right QSetRect(&bounds, 0, 0, theObject.data.a.distance + 24, kFanColumnThick); QOffsetRect(&bounds, 0, 12 - kFanColumnThick / 2); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kPushItRight, who, theObject.data.a.state, false); break; case 4: // down QSetRect(&bounds, 0, 0, kFloorColumnWide, theObject.data.a.distance + 24); QOffsetRect(&bounds, 12 - kFloorColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kDropIt, who, theObject.data.a.state, false); break; case 8: // left QSetRect(&bounds, 0, 0, theObject.data.a.distance + 24, kFanColumnThick); QOffsetRect(&bounds, -(theObject.data.a.distance), 12 - kFanColumnThick / 2); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kPushItLeft, who, theObject.data.a.state, false); break; } break; case kGrecoVent: QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); QOffsetRect(&bounds, HalfRectWide(&srcRects[kGrecoVent]) - kFloorColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, false); break; case kSewerBlower: QSetRect(&bounds, 0, -theObject.data.a.distance, kFloorColumnWide, 0); QOffsetRect(&bounds, HalfRectWide(&srcRects[kSewerBlower]) - kFloorColumnWide / 2, 0); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, false); break; case kLiftArea: QSetRect(&bounds, 0, 0, theObject.data.a.distance, theObject.data.a.tall * 2); QOffsetRect(&bounds, theObject.data.a.topLeft.h, theObject.data.a.topLeft.v); switch (theObject.data.a.vector & 0x0F) { case 1: // up hotSpotNumber = AddActiveRect(&bounds, kLiftIt, who, theObject.data.a.state, false); break; case 2: // right hotSpotNumber = AddActiveRect(&bounds, kPushItRight, who, theObject.data.a.state, false); break; case 4: // down hotSpotNumber = AddActiveRect(&bounds, kDropIt, who, theObject.data.a.state, false); break; case 8: // left hotSpotNumber = AddActiveRect(&bounds, kPushItLeft, who, theObject.data.a.state, false); break; } break; case kTable: case kShelf: case kCabinet: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kCounter: case kDresser: case kDeckTable: case kTrunk: case kInvisObstacle: bounds = theObject.data.b.bounds; hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); break; case kBooks: bounds = theObject.data.b.bounds; bounds.right -= 2; hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); break; case kManhole: bounds = theObject.data.b.bounds; bounds.left += kGliderWide + 3; bounds.right -= kGliderWide + 3; bounds.top = kFloorLimit - 1; bounds.bottom = kTileHigh; hotSpotNumber = AddActiveRect(&bounds, kIgnoreGround, who, true, false); break; case kInvisBounce: bounds = theObject.data.b.bounds; hotSpotNumber = AddActiveRect(&bounds, kBounceIt, who, true, true); break; case kStool: bounds = theObject.data.b.bounds; InsetRect(&bounds, 1, 1); bounds.bottom = bounds.top + kStoolThick; hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kFoil: case kInvisBonus: case kStar: case kHelium: bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.c.topLeft.h, theObject.data.c.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kRewardIt, who, theObject.data.c.state, false); break; case kGreaseRt: if (theObject.data.c.state) { bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.c.topLeft.h, theObject.data.c.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kRewardIt, who, true, false); } else { QSetRect(&bounds, 0, -2, theObject.data.c.length - 5, 0); QOffsetRect(&bounds, 32 - 1, 27); QOffsetRect(&bounds, theObject.data.c.topLeft.h, theObject.data.c.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kSlideIt, who, true, false); } break; case kGreaseLf: if (theObject.data.c.state) { bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.c.topLeft.h, theObject.data.c.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kRewardIt, who, true, false); } else { QSetRect(&bounds, -theObject.data.c.length + 5, -2, 0, 0); QOffsetRect(&bounds, 1, 27); QOffsetRect(&bounds, theObject.data.c.topLeft.h, theObject.data.c.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kSlideIt, who, true, false); } break; case kSparkle: bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.c.topLeft.h, theObject.data.c.topLeft.v); break; case kSlider: QSetRect(&bounds, 0, 0, theObject.data.c.length, 16); QOffsetRect(&bounds, theObject.data.c.topLeft.h, theObject.data.c.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kSlideIt, who, true, false); break; case kUpStairs: QSetRect(&bounds, 0, 0, 112, 32); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kMoveItUp, who, true, false); break; case kDownStairs: QSetRect(&bounds, -80, -56, 0, 0); QOffsetRect(&bounds, srcRects[kDownStairs].right, 170); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kMoveItDown, who, true, false); break; case kMailboxLf: if (theObject.data.d.who != 255) { QSetRect(&bounds, -72, 0, 0, 40); QOffsetRect(&bounds, 30, 16); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kMailItLeft, who, true, false); } break; case kMailboxRt: if (theObject.data.d.who != 255) { QSetRect(&bounds, 0, 0, 72, 40); QOffsetRect(&bounds, 79, 16); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kMailItRight, who, true, false); } break; case kFloorTrans: if (theObject.data.d.who != 255) { QSetRect(&bounds, 0, -48, 76, 0); QOffsetRect(&bounds, -8, RectTall(&srcRects[kFloorTrans])); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kDuctItDown, who, true, false); } break; case kCeilingTrans: if (theObject.data.d.who != 255) { QSetRect(&bounds, 0, 0, 76, 48); QOffsetRect(&bounds, -8, 0); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kDuctItUp, who, true, false); } break; case kDoorInLf: QSetRect(&bounds, 0, 0, 16, 240); QOffsetRect(&bounds, 0, 52); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kIgnoreLeftWall, who, true, false); break; case kDoorInRt: QSetRect(&bounds, 0, 0, 16, 240); QOffsetRect(&bounds, 128, 52); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kIgnoreRightWall, who, true, false); break; case kDoorExRt: QSetRect(&bounds, 0, 0, 16, 240); QOffsetRect(&bounds, 0, 52); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kIgnoreRightWall, who, true, false); break; case kDoorExLf: QSetRect(&bounds, 0, 0, 16, 240); QOffsetRect(&bounds, 0, 52); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kIgnoreLeftWall, who, true, false); break; case kWindowInLf: QSetRect(&bounds, 0, 0, 16, 44); QOffsetRect(&bounds, 0, 96); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kIgnoreLeftWall, who, true, false); break; case kWindowInRt: QSetRect(&bounds, 0, 0, 16, 44); QOffsetRect(&bounds, 4, 96); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kIgnoreRightWall, who, true, false); break; case kWindowExRt: QSetRect(&bounds, 0, 0, 16, 44); QOffsetRect(&bounds, 0, 96); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kIgnoreRightWall, who, true, false); break; case kWindowExLf: QSetRect(&bounds, 0, 0, 16, 44); QOffsetRect(&bounds, 0, 96); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kIgnoreLeftWall, who, true, false); break; case kInvisTrans: if (theObject.data.d.who != 255) { QSetRect(&bounds, 0, 0, 64, 32); QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); bounds.bottom = bounds.top + theObject.data.d.tall; bounds.right += (short)theObject.data.d.wide; hotSpotNumber = AddActiveRect(&bounds, kTransportIt, who, true, false); } break; case kDeluxeTrans: if (theObject.data.d.who != 255) { wide = (theObject.data.d.tall & 0xFF00) >> 8; // Get high byte tall = theObject.data.d.tall & 0x00FF; // Get low byte QSetRect(&bounds, 0, 0, wide * 4, tall * 4); // Scale by 4 QOffsetRect(&bounds, theObject.data.d.topLeft.h, theObject.data.d.topLeft.v); isOn = theObject.data.d.wide & 0x0F; hotSpotNumber = AddActiveRect(&bounds, kTransportIt, who, isOn, false); } break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.e.topLeft.h, theObject.data.e.topLeft.v); if ((theObject.what == kTrigger) || (theObject.what == kLgTrigger)) { if (theObject.data.e.where != -1) hotSpotNumber = AddActiveRect(&bounds, kTriggerIt, who, true, false); } else { if (theObject.data.e.where != -1) hotSpotNumber = AddActiveRect(&bounds, kSwitchIt, who, true, false); } break; case kSoundTrigger: QSetRect(&bounds, 0, 0, 48, 48); QOffsetRect(&bounds, theObject.data.e.topLeft.h, theObject.data.e.topLeft.v); if (LoadTriggerSound(theObject.data.e.where) == noErr) hotSpotNumber = AddActiveRect(&bounds, kSoundIt, who, true, false); break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: break; case kShredder: bounds = srcRects[theObject.what]; bounds.bottom = bounds.top + kShredderActiveHigh; bounds.right += 48; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.g.topLeft.h, theObject.data.g.topLeft.v); QOffsetRect(&bounds, -24, -36); hotSpotNumber = AddActiveRect(&bounds, kShredIt, who, theObject.data.g.state, true); break; case kGuitar: QSetRect(&bounds, 0, 0, 8, 96); QOffsetRect(&bounds, theObject.data.g.topLeft.h + 34, theObject.data.g.topLeft.v + 32); hotSpotNumber = AddActiveRect(&bounds, kStrumIt, who, true, false); break; case kOutlet: bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.g.topLeft.h, theObject.data.g.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kIgnoreIt, who, theObject.data.g.state, false); break; case kMicrowave: bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.g.topLeft.h, theObject.data.g.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); bounds.bottom = bounds.top; bounds.top = 0; hotSpotNumber = AddActiveRect(&bounds, kMicrowaveIt, who, true, true); break; case kToaster: case kMacPlus: case kTV: case kCoffee: case kVCR: case kStereo: case kCinderBlock: case kFlowerBox: case kCDs: bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.g.topLeft.h, theObject.data.g.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); break; case kCustomPict: break; case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kBall: case kDrip: bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.h.topLeft.h, theObject.data.h.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kIgnoreIt, who, true, false); break; case kFish: bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.h.topLeft.h, theObject.data.h.topLeft.v); hotSpotNumber = AddActiveRect(&bounds, kDissolveIt, who, true, true); break; case kCobweb: bounds = srcRects[theObject.what]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.h.topLeft.h, theObject.data.h.topLeft.v); InsetRect(&bounds, -24, -10); hotSpotNumber = AddActiveRect(&bounds, kWebIt, who, true, true); break; case kOzma: case kMirror: case kMousehole: case kFireplace: case kFlower: case kWallWindow: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: break; case kChimes: numChimes++; bounds = srcRects[kChimes]; ZeroRectCorner(&bounds); QOffsetRect(&bounds, theObject.data.i.bounds.left, theObject.data.i.bounds.top); hotSpotNumber = AddActiveRect(&bounds, kChimeIt, who, true, false); break; } return (hotSpotNumber); } //-------------------------------------------------------------- VerticalRoomOffset short VerticalRoomOffset (short neighbor) { short offset; offset = 0; switch (neighbor) { case kNorthRoom: case kNorthEastRoom: case kNorthWestRoom: offset -= kVertLocalOffset; break; case kSouthEastRoom: case kSouthRoom: case kSouthWestRoom: offset += kVertLocalOffset; break; } return (offset); } //-------------------------------------------------------------- OffsetRectRoomRelative void OffsetRectRoomRelative (Rect *theRect, short neighbor) { QOffsetRect(theRect, playOriginH, playOriginV); switch (neighbor) { case kNorthRoom: QOffsetRect(theRect, 0, -kVertLocalOffset); break; case kNorthEastRoom: QOffsetRect(theRect, kRoomWide, -kVertLocalOffset); break; case kEastRoom: QOffsetRect(theRect, kRoomWide, 0); break; case kSouthEastRoom: QOffsetRect(theRect, kRoomWide, kVertLocalOffset); break; case kSouthRoom: QOffsetRect(theRect, 0, kVertLocalOffset); break; case kSouthWestRoom: QOffsetRect(theRect, -kRoomWide, kVertLocalOffset); break; case kWestRoom: QOffsetRect(theRect, -kRoomWide, 0); break; case kNorthWestRoom: QOffsetRect(theRect, -kRoomWide, -kVertLocalOffset); break; } } //-------------------------------------------------------------- GetUpStairsRightEdge short GetUpStairsRightEdge (void) { objectType thisObject; short i, rightEdge; char wasState; rightEdge = kRoomWide; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); for (i = 0; i < kMaxRoomObs; i++) { thisObject = (*thisHouse)->rooms[thisRoomNumber].objects[i]; if (thisObject.what == kDownStairs) { rightEdge = thisObject.data.d.topLeft.h + srcRects[kDownStairs].right - 1; break; } } HSetState((Handle)thisHouse, wasState); return (rightEdge); } //-------------------------------------------------------------- GetDownStairsLeftEdge short GetDownStairsLeftEdge (void) { objectType thisObject; short i, leftEdge; char wasState; leftEdge = 0; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); for (i = 0; i < kMaxRoomObs; i++) { thisObject = (*thisHouse)->rooms[thisRoomNumber].objects[i]; if (thisObject.what == kUpStairs) { leftEdge = thisObject.data.d.topLeft.h + 1; break; } } HSetState((Handle)thisHouse, wasState); return (leftEdge); } \ No newline at end of file diff --git a/Sources/Objects.c b/Sources/Objects.c deleted file mode 100755 index 1e3b86c..0000000 --- a/Sources/Objects.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Objects.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "ObjectEdit.h" #define kMaxTempManholes 8 short GetObjectLinked (objectType *); void ListOneRoomsObjects (short); Rect blowerSrcRect; // Blowers GWorldPtr blowerSrcMap; GWorldPtr blowerMaskMap; Rect flame[kNumCandleFlames], tikiFlame[kNumTikiFlames]; Rect coals[kNumBBQCoals]; Rect furnitureSrcRect; // Furniture GWorldPtr furnitureSrcMap; GWorldPtr furnitureMaskMap; Rect tableSrc, shelfSrc, hingeSrc, handleSrc, knobSrc; Rect leftFootSrc, rightFootSrc, deckSrc; Rect bonusSrcRect; // Bonuses GWorldPtr bonusSrcMap; GWorldPtr bonusMaskMap; Rect pointsSrcRect; GWorldPtr pointsSrcMap; GWorldPtr pointsMaskMap; Rect starSrc[6], sparkleSrc[kNumSparkleModes]; Rect digits[11], pendulumSrc[3], greaseSrcRt[4], greaseSrcLf[4]; Rect transSrcRect; // Transport GWorldPtr transSrcMap; GWorldPtr transMaskMap; Rect switchSrcRect; // Switches GWorldPtr switchSrcMap; Rect lightSwitchSrc[2], machineSwitchSrc[2], thermostatSrc[2]; Rect powerSrc[2], knifeSwitchSrc[2]; Rect lightSrcRect; // Lights GWorldPtr lightSrcMap; GWorldPtr lightMaskMap; Rect flourescentSrc1, flourescentSrc2, trackLightSrc[kNumTrackLights]; Rect applianceSrcRect, toastSrcRect, shredSrcRect; // Appliances GWorldPtr applianceSrcMap, toastSrcMap, shredSrcMap; GWorldPtr applianceMaskMap, toastMaskMap, shredMaskMap; Rect plusScreen1, plusScreen2, tvScreen1, tvScreen2; Rect coffeeLight1, coffeeLight2, vcrTime1, vcrTime2; Rect stereoLight1, stereoLight2, microOn, microOff; Rect outletSrc[kNumOutletPicts]; Rect balloonSrcRect, copterSrcRect, dartSrcRect; // Enemies Rect ballSrcRect, dripSrcRect, enemySrcRect; Rect fishSrcRect; GWorldPtr balloonSrcMap, copterSrcMap, dartSrcMap; GWorldPtr ballSrcMap, dripSrcMap, enemySrcMap; GWorldPtr fishSrcMap; GWorldPtr balloonMaskMap, copterMaskMap, dartMaskMap; GWorldPtr ballMaskMap, dripMaskMap, enemyMaskMap; GWorldPtr fishMaskMap; Rect balloonSrc[kNumBalloonFrames], copterSrc[kNumCopterFrames]; Rect dartSrc[kNumDartFrames], ballSrc[kNumBallFrames]; Rect dripSrc[kNumDripFrames], fishSrc[kNumFishFrames]; GWorldPtr clutterSrcMap; // Clutter GWorldPtr clutterMaskMap; Rect clutterSrcRect; Rect flowerSrc[kNumFlowers]; Rect *srcRects; Rect tempManholes[kMaxTempManholes]; savedType savedMaps[kMaxSavedMaps]; objDataPtr masterObjects; hotPtr hotSpots; short nLocalObj, nHotSpots, numMasterObjects, numLocalMasterObjects; short numTempManholes, tvWithMovieNumber; Boolean newState; extern linksPtr linksList; extern short srcLocations[], destLocations[]; extern short localNumbers[]; extern short numNeighbors; //============================================================== Functions //-------------------------------------------------------------- IsThisValid Boolean IsThisValid (short where, short who) { char wasState; Boolean itsGood; itsGood = true; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); switch ((*thisHouse)->rooms[where].objects[who].what) { case kObjectIsEmpty: itsGood = false; break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: itsGood = (*thisHouse)->rooms[where].objects[who].data.c.state; break; } HSetState((Handle)thisHouse, wasState); return (itsGood); } //-------------------------------------------------------------- GetRoomLinked short GetRoomLinked (objectType *who) { short compoundRoomNumber, whereLinked; short floor, suite; switch (who->what) { case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kInvisTrans: case kDeluxeTrans: compoundRoomNumber = who->data.d.where; if (compoundRoomNumber != -1) // is object linked { ExtractFloorSuite(compoundRoomNumber, &floor, &suite); whereLinked = GetRoomNumber(floor, suite); } else whereLinked = -1; // not linked break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: compoundRoomNumber = who->data.e.where; if (compoundRoomNumber != -1) // is object linked { ExtractFloorSuite(compoundRoomNumber, &floor, &suite); whereLinked = GetRoomNumber(floor, suite); } else whereLinked = -1; // not linked break; default: whereLinked = -1; break; } return (whereLinked); } //-------------------------------------------------------------- GetObjectLinked short GetObjectLinked (objectType *who) { short whoLinked; switch (who->what) { case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kInvisTrans: case kDeluxeTrans: if (who->data.d.who != 255) // is it linked? whoLinked = (short)who->data.d.who; else whoLinked = -1; // object not linked break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: if (who->data.e.who != 255) // is it linked? whoLinked = (short)who->data.e.who; else whoLinked = -1; // object not linked break; default: whoLinked = -1; break; } return (whoLinked); } //-------------------------------------------------------------- ObjectIsLinkTransport Boolean ObjectIsLinkTransport (objectType *who) { Boolean itIs; itIs = false; if ((who->what == kMailboxLf) || (who->what == kMailboxRt) || (who->what == kFloorTrans) || (who->what == kCeilingTrans) || (who->what == kInvisTrans) || (who->what == kDeluxeTrans)) { itIs = true; } return (itIs); } //-------------------------------------------------------------- ObjectIsLinkSwitch Boolean ObjectIsLinkSwitch (objectType *who) { Boolean itIs; itIs = false; if ((who->what == kLightSwitch) || (who->what == kMachineSwitch) || (who->what == kThermostat) || (who->what == kPowerSwitch) || (who->what == kKnifeSwitch) || (who->what == kInvisSwitch) || (who->what == kTrigger) || (who->what == kLgTrigger)) { itIs = true; } return (itIs); } //-------------------------------------------------------------- ListOneRoomsObjects void ListOneRoomsObjects (short where) { objectType thisObject; short roomNum, n; char wasState; roomNum = localNumbers[where]; if (roomNum == kRoomIsEmpty) return; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); for (n = 0; n < kMaxRoomObs; n++) { if (numMasterObjects < kMaxMasterObjects) { thisObject = (*thisHouse)->rooms[roomNum].objects[n]; masterObjects[numMasterObjects].roomNum = roomNum; masterObjects[numMasterObjects].objectNum = n; masterObjects[numMasterObjects].roomLink = GetRoomLinked(&thisObject); masterObjects[numMasterObjects].objectLink = GetObjectLinked(&thisObject); masterObjects[numMasterObjects].localLink = -1; masterObjects[numMasterObjects].theObject = (*thisHouse)->rooms[roomNum].objects[n]; if ((where == kCentralRoom) && (IsThisValid(roomNum, n))) masterObjects[numMasterObjects].hotNum = CreateActiveRects(n); else masterObjects[numMasterObjects].hotNum = -1; masterObjects[numMasterObjects].dynaNum = -1; numMasterObjects++; if (where == kCentralRoom) numLocalMasterObjects++; } } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- ListAllLocalObjects void ListAllLocalObjects (void) { short i, n; char wasState; numMasterObjects = 0; numLocalMasterObjects = 0; nHotSpots = 0; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); ListOneRoomsObjects(kCentralRoom); if (numNeighbors > 1) { ListOneRoomsObjects(kEastRoom); ListOneRoomsObjects(kWestRoom); } if (numNeighbors > 3) { ListOneRoomsObjects(kNorthRoom); ListOneRoomsObjects(kNorthEastRoom); ListOneRoomsObjects(kSouthEastRoom); ListOneRoomsObjects(kSouthRoom); ListOneRoomsObjects(kSouthWestRoom); ListOneRoomsObjects(kNorthWestRoom); } HSetState((Handle)thisHouse, wasState); for (i = 0; i < numMasterObjects; i++) // correlate links withÉ { // index into this list if ((masterObjects[i].roomLink != -1) && // if object has a link (masterObjects[i].objectLink != -1)) { for (n = 0; n < numMasterObjects; n++) // search for the objectÉ { // linked to in this list if ((masterObjects[i].roomLink == masterObjects[n].roomNum) && (masterObjects[i].objectLink == masterObjects[n].objectNum)) { masterObjects[i].localLink = n; // log the index } } } } } //-------------------------------------------------------------- AddTempManholeRect void AddTempManholeRect (Rect *manHole) { Rect tempRect; if (numTempManholes < kMaxTempManholes) { tempRect = *manHole; tempRect.bottom = tempRect.top + kFloorSupportTall; tempManholes[numTempManholes] = tempRect; numTempManholes++; } } //-------------------------------------------------------------- SetObjectState Boolean SetObjectState (short room, short object, short action, short local) { char wasState; Boolean changed; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); switch ((*thisHouse)->rooms[room].objects[object].what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kLeftFan: case kRightFan: case kSewerGrate: case kInvisBlower: case kGrecoVent: case kSewerBlower: case kLiftArea: switch (action) { case kToggle: newState = !(*thisHouse)->rooms[room].objects[object].data.a.state; (*thisHouse)->rooms[room].objects[object].data.a.state = newState; changed = true; break; case kForceOn: changed = ((*thisHouse)->rooms[room].objects[object].data.a.state == false); newState = true; (*thisHouse)->rooms[room].objects[object].data.a.state = newState; break; case kForceOff: changed = ((*thisHouse)->rooms[room].objects[object].data.a.state == true); newState = false; (*thisHouse)->rooms[room].objects[object].data.a.state = newState; break; } if ((changed) && (local != -1)) { masterObjects[local].theObject.data.a.state = newState; if (room == thisRoomNumber) thisRoom->objects[object].data.a.state = newState; if (newState) PlayPrioritySound(kBlowerOn, kBlowerOnPriority); else PlayPrioritySound(kBlowerOff, kBlowerOffPriority); if (masterObjects[local].hotNum != -1) hotSpots[masterObjects[local].hotNum].isOn = newState; } break; case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: changed = false; // Cannot switch on/off these break; case kTable: case kShelf: case kCabinet: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kCounter: case kDresser: case kStool: case kTrunk: case kDeckTable: case kInvisObstacle: case kManhole: case kBooks: case kInvisBounce: changed = false; // Cannot switch on/off these break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kGreaseRt: case kGreaseLf: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: changed = ((*thisHouse)->rooms[room].objects[object].data.c.state == true); newState = false; (*thisHouse)->rooms[room].objects[object].data.c.state = newState; if ((changed) && (local != -1)) { masterObjects[local].theObject.data.a.state = false; if (room == thisRoomNumber) { thisRoom->objects[object].data.c.state = false; if (masterObjects[local].hotNum != -1) hotSpots[masterObjects[local].hotNum].isOn = false; } } break; case kSlider: break; case kUpStairs: case kDownStairs: case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kDoorInLf: case kDoorInRt: case kDoorExRt: case kDoorExLf: case kWindowInLf: case kWindowInRt: case kWindowExRt: case kWindowExLf: case kInvisTrans: changed = false; break; case kDeluxeTrans: switch (action) { case kToggle: newState = (*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F; newState = !newState; (*thisHouse)->rooms[room].objects[object].data.d.wide &= 0xF0; (*thisHouse)->rooms[room].objects[object].data.d.wide += newState; changed = true; break; case kForceOn: changed = (((*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F) == 0x00); newState = true; (*thisHouse)->rooms[room].objects[object].data.d.wide &= 0xF0; (*thisHouse)->rooms[room].objects[object].data.d.wide += newState; break; case kForceOff: changed = (((*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F) != 0x00); newState = false; (*thisHouse)->rooms[room].objects[object].data.d.wide &= 0xF0; (*thisHouse)->rooms[room].objects[object].data.d.wide += newState; break; } if ((changed) && (local != -1)) { masterObjects[local].theObject.data.d.wide = (*thisHouse)->rooms[room].objects[object].data.d.wide; if (room == thisRoomNumber) thisRoom->objects[object].data.d.wide = (*thisHouse)->rooms[room].objects[object].data.d.wide; if (masterObjects[local].hotNum != -1) hotSpots[masterObjects[local].hotNum].isOn = newState; } break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: changed = false; break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: switch (action) { case kToggle: newState = !(*thisHouse)->rooms[room].objects[object].data.f.state; (*thisHouse)->rooms[room].objects[object].data.f.state = newState; changed = true; break; case kForceOn: changed = ((*thisHouse)->rooms[room].objects[object].data.f.state == false); newState = true; (*thisHouse)->rooms[room].objects[object].data.f.state = newState; break; case kForceOff: changed = ((*thisHouse)->rooms[room].objects[object].data.f.state == true); newState = false; (*thisHouse)->rooms[room].objects[object].data.f.state = newState; break; } if ((changed) && (local != -1)) { masterObjects[local].theObject.data.f.state = newState; if (room == thisRoomNumber) thisRoom->objects[object].data.f.state = newState; } break; case kGuitar: // really no point to change this state changed = false; break; case kStereo: newState = !isPlayMusicGame; isPlayMusicGame = newState; changed = true; break; case kShredder: case kToaster: case kMacPlus: case kTV: case kCoffee: case kOutlet: case kVCR: case kMicrowave: switch (action) { case kToggle: newState = !(*thisHouse)->rooms[room].objects[object].data.g.state; (*thisHouse)->rooms[room].objects[object].data.g.state = newState; changed = true; break; case kForceOn: changed = ((*thisHouse)->rooms[room].objects[object].data.g.state == false); newState = true; (*thisHouse)->rooms[room].objects[object].data.g.state = newState; break; case kForceOff: changed = ((*thisHouse)->rooms[room].objects[object].data.g.state == true); newState = false; (*thisHouse)->rooms[room].objects[object].data.g.state = newState; break; } if ((changed) && (local != -1)) { masterObjects[local].theObject.data.g.state = newState; if (room == thisRoomNumber) { thisRoom->objects[object].data.g.state = newState; if ((*thisHouse)->rooms[room].objects[object].what == kShredder) hotSpots[masterObjects[local].hotNum].isOn = newState; } } break; case kCinderBlock: case kFlowerBox: case kCDs: case kCustomPict: changed = false; break; case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kBall: case kDrip: case kFish: switch (action) { case kToggle: newState = !(*thisHouse)->rooms[room].objects[object].data.h.state; (*thisHouse)->rooms[room].objects[object].data.h.state = newState; changed = true; break; case kForceOn: changed = ((*thisHouse)->rooms[room].objects[object].data.h.state == false); newState = true; (*thisHouse)->rooms[room].objects[object].data.h.state = newState; break; case kForceOff: changed = ((*thisHouse)->rooms[room].objects[object].data.h.state == true); newState = false; (*thisHouse)->rooms[room].objects[object].data.h.state = newState; break; } if ((changed) && (local != -1)) { masterObjects[local].theObject.data.h.state = newState; if (room == thisRoomNumber) thisRoom->objects[object].data.h.state = newState; } break; case kCobweb: changed = false; break; case kOzma: case kMirror: case kMousehole: case kFireplace: case kFlower: case kWallWindow: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: changed = false; break; } HSetState((Handle)thisHouse, wasState); return (changed); } //-------------------------------------------------------------- GetObjectState Boolean GetObjectState (short room, short object) { char wasState; Boolean theState; theState = true; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); switch ((*thisHouse)->rooms[room].objects[object].what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kLeftFan: case kRightFan: case kSewerGrate: case kInvisBlower: case kGrecoVent: case kSewerBlower: case kLiftArea: theState = (*thisHouse)->rooms[room].objects[object].data.a.state; break; case kTaper: case kCandle: case kStubby: case kTiki: case kBBQ: break; case kTable: case kShelf: case kCabinet: case kFilingCabinet: case kWasteBasket: case kMilkCrate: case kCounter: case kDresser: case kDeckTable: case kStool: case kTrunk: case kInvisObstacle: case kManhole: case kBooks: case kInvisBounce: break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kGreaseRt: case kGreaseLf: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: theState = (*thisHouse)->rooms[room].objects[object].data.c.state; break; case kSlider: break; case kUpStairs: case kDownStairs: case kMailboxLf: case kMailboxRt: case kFloorTrans: case kCeilingTrans: case kDoorInLf: case kDoorInRt: case kDoorExRt: case kDoorExLf: case kWindowInLf: case kWindowInRt: case kWindowExRt: case kWindowExLf: case kInvisTrans: break; case kDeluxeTrans: theState = (*thisHouse)->rooms[room].objects[object].data.d.wide & 0x0F; break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: case kSoundTrigger: break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: theState = (*thisHouse)->rooms[room].objects[object].data.f.state; break; case kStereo: theState = isPlayMusicGame; break; case kShredder: case kToaster: case kMacPlus: case kGuitar: case kTV: case kCoffee: case kOutlet: case kVCR: case kMicrowave: theState = (*thisHouse)->rooms[room].objects[object].data.g.state; break; case kCinderBlock: case kFlowerBox: case kCDs: case kCustomPict: break; case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kBall: case kDrip: case kFish: theState = (*thisHouse)->rooms[room].objects[object].data.h.state; break; case kCobweb: break; case kOzma: case kMirror: case kMousehole: case kFireplace: case kFlower: case kWallWindow: case kBear: case kCalendar: case kVase1: case kVase2: case kBulletin: case kCloud: case kFaucet: case kRug: case kChimes: break; } HSetState((Handle)thisHouse, wasState); return (theState); } //-------------------------------------------------------------- SendObjectToBack #ifndef COMPILEDEMO void BringSendFrontBack (Boolean bringFront) { houseType *thisHousePtr; objectType savedObject; short numLinks, i; short srcRoom, srcObj; short sorting[kMaxRoomObs]; short sorted[kMaxRoomObs]; char wasState; if (bringFront) // No need to bring to frontÉ { // or send to back if the objectÉ if (objActive == (kMaxRoomObs - 1)) // in question is already front- return; // most or backmost. } else { if (objActive == 0) return; } CopyThisRoomToRoom(); // Any changes to room writtenÉ // back to the house handle. numLinks = CountHouseLinks(); // Determine space needed for all links. if (numLinks != 0) // Create links list of ALL house links. { linksList = nil; linksList = (linksPtr)NewPtr(sizeof(linksType) * numLinks); if (linksList == nil) { YellowAlert(kYellowCantOrderLinks, MemError()); return; } GenerateLinksList(); // Fill in links list with src/destÉ } // data on objects and room numbers. wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); // Lock down house. thisHousePtr = *thisHouse; // Get a pointer to house structure. for (i = 0; i < kMaxRoomObs; i++) // Set up an ordered array. sorting[i] = i; savedObject = (*thisHouse)->rooms[thisRoomNumber].objects[objActive]; if (bringFront) { for (i = objActive; i < kMaxRoomObs - 1; i++) { // Pull all objects down to fill hole. (*thisHouse)->rooms[thisRoomNumber].objects[i] = (*thisHouse)->rooms[thisRoomNumber].objects[i + 1]; sorting[i] = sorting[i + 1]; SpinCursor(2); } // Insert object at end of array. (*thisHouse)->rooms[thisRoomNumber].objects[kMaxRoomObs - 1] = savedObject; sorting[kMaxRoomObs - 1] = objActive; } else { for (i = objActive; i > 0; i--) { // Move all objects up to fill hole. (*thisHouse)->rooms[thisRoomNumber].objects[i] = (*thisHouse)->rooms[thisRoomNumber].objects[i - 1]; sorting[i] = sorting[i - 1]; SpinCursor(2); } // Insert object at beginning of array. (*thisHouse)->rooms[thisRoomNumber].objects[0] = savedObject; sorting[0] = objActive; } for (i = 0; i < kMaxRoomObs; i++) // Set up retro-ordered array. sorted[sorting[i]] = i; for (i = 0; i < numLinks; i++) // Walk links list in order to assignÉ { // corrected links to objects moved. if (linksList[i].destRoom == thisRoomNumber) { // Does link point to room we re-ordered? srcRoom = linksList[i].srcRoom; // Room where-which an object is linked from. if (srcRoom == thisRoomNumber) // Handle special case for local links. srcObj = sorted[linksList[i].srcObj]; else srcObj = linksList[i].srcObj; switch ((*thisHouse)->rooms[srcRoom].objects[srcObj].what) { case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: case kTrigger: case kLgTrigger: (*thisHouse)->rooms[srcRoom].objects[srcObj].data.d.who = sorted[linksList[i].destObj]; break; default: (*thisHouse)->rooms[srcRoom].objects[srcObj].data.e.who = sorted[linksList[i].destObj]; break; } } } HSetState((Handle)thisHouse, wasState); if (linksList != nil) DisposePtr((Ptr)linksList); ForceThisRoom(thisRoomNumber); fileDirty = true; UpdateMenus(false); InvalWindowRect(mainWindow, &mainWindowRect); DeselectObject(); GetThisRoomsObjRects(); ReadyBackground(thisRoom->background, thisRoom->tiles); DrawThisRoomsObjects(); GenerateRetroLinks(); InitCursor(); } #endif \ No newline at end of file diff --git a/Sources/Play.c b/Sources/Play.c deleted file mode 100755 index 12c3154..0000000 --- a/Sources/Play.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Play.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "Environ.h" #include "House.h" #include "MainWindow.h" #include "RectUtils.h" #include "Scoreboard.h" #define kHouseBannerAlert 1009 #define kInitialGliders 2 #define kRingDelay 90 #define kRingSpread 25000 // 25000 #define kRingBaseDelay 5000 // 5000 #define kChimeDelay 180 typedef struct { short nextRing; short rings; short delay; } phoneType, *phonePtr; void InitGlider (gliderPtr, short); void SetHouseToFirstRoom (void); void SetHouseToSavedRoom (void); void HandlePlayEvent (void); void PlayGame (void); void HandleRoomVisitation (void); void SetObjectsToDefaults (void); void InitTelephone (void); void HandleTelephone (void); Boolean DoesStarCodeExist (short); short GetNumStarsRemaining (short, short); phoneType thePhone, theChimes; Rect glidSrcRect, justRoomsRect; GWorldPtr glidSrcMap, glid2SrcMap; GWorldPtr glidMaskMap; long gameFrame; short batteryTotal, bandsTotal, foilTotal, mortals; Boolean playing, evenFrame, twoPlayerGame, showFoil, demoGoing; Boolean doBackground, playerSuicide, phoneBitSet, tvOn; extern WindowPtr menuWindow; extern FSSpecPtr theHousesSpecs; extern demoPtr demoData; extern gameType smallGame; extern Rect gliderSrc[kNumGliderSrcRects]; extern Rect boardDestRect, boardSrcRect; extern long incrementModeTime; extern short numBands, otherPlayerEscaped, demoIndex, demoHouseIndex; extern short splashOriginH, splashOriginV, countDown, thisHouseIndex; extern short numStarsRemaining, numChimes, saidFollow; extern Boolean quitting, isMusicOn, gameOver, hasMirror, onePlayerLeft; extern Boolean isPlayMusicIdle, failedMusic, quickerTransitions; extern Boolean switchedOut; //============================================================== Functions //-------------------------------------------------------------- NewGame void NewGame (short mode) { Rect tempRect; Size freeBytes, growBytes; OSErr theErr; Boolean wasPlayMusicPref; AdjustScoreboardHeight(); gameOver = false; theMode = kPlayMode; if (isPlayMusicGame) { if (!isMusicOn) { theErr = StartMusic(); if (theErr != noErr) { YellowAlert(kYellowNoMusic, theErr); failedMusic = true; } } SetMusicalMode(kPlayGameScoreMode); } else { if (isMusicOn) StopTheMusic(); } if (mode != kResumeGameMode) SetObjectsToDefaults(); HideCursor(); if (mode == kResumeGameMode) SetHouseToSavedRoom(); else if (mode == kNewGameMode) SetHouseToFirstRoom(); DetermineRoomOpenings(); NilSavedMaps(); gameFrame = 0L; numBands = 0; demoIndex = 0; saidFollow = 0; otherPlayerEscaped = kNoOneEscaped; onePlayerLeft = false; playerSuicide = false; if (twoPlayerGame) // initialize glider(s) { InitGlider(&theGlider, kNewGameMode); InitGlider(&theGlider2, kNewGameMode); SetPort((GrafPtr)glidSrcMap); LoadGraphic(kGliderPictID); SetPort((GrafPtr)glid2SrcMap); LoadGraphic(kGlider2PictID); } else { InitGlider(&theGlider, mode); SetPort((GrafPtr)glidSrcMap); LoadGraphic(kGliderPictID); SetPort((GrafPtr)glid2SrcMap); LoadGraphic(kGliderFoilPictID); } #if !BUILD_ARCADE_VERSION // HideMenuBarOld(); // TEMP #endif SetPort((GrafPtr)mainWindow); // paint strip on screen black tempRect = thisMac.screen; tempRect.top = tempRect.bottom - 20; // thisMac.menuHigh PaintRect(&tempRect); #ifdef COMPILEQT if ((thisMac.hasQT) && (hasMovie)) { SetMovieGWorld(theMovie, (CGrafPtr)mainWindow, nil); } #endif SetPort((GrafPtr)workSrcMap); PaintRect(&workSrcRect); // if (quickerTransitions) // DissBitsChunky(&workSrcRect); // else // DissBits(&workSrcRect); // DebugStr("\pIf screen isn't black, exit to shell."); // TEMP TEMP TEMP DrawLocale(); RefreshScoreboard(kNormalTitleMode); // if (quickerTransitions) // DissBitsChunky(&justRoomsRect); // else // DissBits(&justRoomsRect); if (mode == kNewGameMode) { BringUpBanner(); DumpScreenOn(&justRoomsRect); } else if (mode == kResumeGameMode) { DisplayStarsRemaining(); DumpScreenOn(&justRoomsRect); } else { DumpScreenOn(&justRoomsRect); } InitGarbageRects(); StartGliderFadingIn(&theGlider); if (twoPlayerGame) { StartGliderFadingIn(&theGlider2); TagGliderIdle(&theGlider2); theGlider2.dontDraw = true; } InitTelephone(); wasPlayMusicPref = isPlayMusicGame; freeBytes = MaxMem(&growBytes); #ifdef CREATEDEMODATA SysBeep(1); #endif #ifdef COMPILEQT if ((thisMac.hasQT) && (hasMovie) && (tvInRoom)) { SetMovieActive(theMovie, true); if (tvOn) { StartMovie(theMovie); MoviesTask(theMovie, 0); } } #endif playing = true; // everything before this line is game set-up PlayGame(); // everything following is after a game has ended #ifdef CREATEDEMODATA DumpToResEditFile((Ptr)demoData, sizeof(demoType) * (long)demoIndex); #endif isPlayMusicGame = wasPlayMusicPref; ZeroMirrorRegion(); #ifdef COMPILEQT if ((thisMac.hasQT) && (hasMovie) && (tvInRoom)) { tvInRoom = false; StopMovie(theMovie); SetMovieActive(theMovie, false); } #endif twoPlayerGame = false; theMode = kSplashMode; InitCursor(); if (isPlayMusicIdle) { if (!isMusicOn) { theErr = StartMusic(); if (theErr != noErr) { YellowAlert(kYellowNoMusic, theErr); failedMusic = true; } } SetMusicalMode(kPlayWholeScoreMode); } else { if (isMusicOn) StopTheMusic(); } NilSavedMaps(); SetPortWindowPort(mainWindow); BlackenScoreboard(); UpdateMenus(false); if (!gameOver) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); InvalWindowRect(mainWindow, &mainWindowRect); SetGWorld(workSrcMap, nil); PaintRect(&workSrcRect); QSetRect(&tempRect, 0, 0, 640, 460); QOffsetRect(&tempRect, splashOriginH, splashOriginV); LoadScaledGraphic(kSplash8BitPICT, &tempRect); SetGWorld(wasCPort, wasWorld); } WaitCommandQReleased(); demoGoing = false; incrementModeTime = TickCount() + kIdleSplashTicks; } //-------------------------------------------------------------- DoDemoGame void DoDemoGame (void) { short wasHouseIndex; Boolean whoCares; wasHouseIndex = thisHouseIndex; whoCares = CloseHouse(); thisHouseIndex = demoHouseIndex; PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); if (OpenHouse()) { whoCares = ReadHouse(); demoGoing = true; NewGame(kNewGameMode); } whoCares = CloseHouse(); thisHouseIndex = wasHouseIndex; PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); if (OpenHouse()) whoCares = ReadHouse(); incrementModeTime = TickCount() + kIdleSplashTicks; } //-------------------------------------------------------------- InitGlider void InitGlider (gliderPtr thisGlider, short mode) { WhereDoesGliderBegin(&thisGlider->dest, mode); if (mode == kResumeGameMode) numStarsRemaining = smallGame.wasStarsLeft; else if (mode == kNewGameMode) numStarsRemaining = CountStarsInHouse(); if (mode == kResumeGameMode) { theScore = smallGame.score; mortals = smallGame.numGliders; batteryTotal = smallGame.energy; bandsTotal = smallGame.bands; foilTotal = smallGame.foil; thisGlider->mode = smallGame.gliderState; thisGlider->facing = smallGame.facing; showFoil = smallGame.showFoil; switch (thisGlider->mode) { case kGliderBurning: FlagGliderBurning(thisGlider); break; default: FlagGliderNormal(thisGlider); break; } } else { theScore = 0L; mortals = kInitialGliders; if (twoPlayerGame) mortals += kInitialGliders; batteryTotal = 0; bandsTotal = 0; foilTotal = 0; thisGlider->mode = kGliderNormal; thisGlider->facing = kFaceRight; thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; showFoil = false; } QSetRect(&thisGlider->destShadow, 0, 0, kGliderWide, kShadowHigh); QOffsetRect(&thisGlider->destShadow, thisGlider->dest.left, kShadowTop); thisGlider->wholeShadow = thisGlider->destShadow; thisGlider->hVel = 0; thisGlider->vVel = 0; thisGlider->hDesiredVel = 0; thisGlider->vDesiredVel = 0; thisGlider->tipped = false; thisGlider->sliding = false; thisGlider->dontDraw = false; } //-------------------------------------------------------------- SetHouseToFirstRoom void SetHouseToFirstRoom (void) { short firstRoom; firstRoom = GetFirstRoomNumber(); ForceThisRoom(firstRoom); } //-------------------------------------------------------------- SetHouseToSavedRoom void SetHouseToSavedRoom (void) { ForceThisRoom(smallGame.roomNumber); } //-------------------------------------------------------------- HandlePlayEvent void HandlePlayEvent (void) { EventRecord theEvent; GrafPtr wasPort; long sleep = 2; if (WaitNextEvent(everyEvent, &theEvent, sleep, nil)) { if ((theEvent.what == updateEvt) && ((WindowPtr)theEvent.message == mainWindow)) { GetPort(&wasPort); SetPortWindowPort(mainWindow); BeginUpdate(mainWindow); CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &justRoomsRect, &justRoomsRect, srcCopy, nil); RefreshScoreboard(kNormalTitleMode); EndUpdate(mainWindow); SetPort(wasPort); } else if ((theEvent.what == osEvt) && (theEvent.message & 0x01000000)) { if (theEvent.message & 0x00000001) // resume event { switchedOut = false; ToggleMusicWhilePlaying(); HideCursor(); // HideMenuBarOld(); // TEMP } else // suspend event { InitCursor(); switchedOut = true; ToggleMusicWhilePlaying(); // ShowMenuBarOld(); // TEMP replace with Carbon calls } } } } //-------------------------------------------------------------- PlayGame void PlayGame (void) { while ((playing) && (!quitting)) { gameFrame++; evenFrame = !evenFrame; if (doBackground) { do { HandlePlayEvent(); } while (switchedOut); } HandleTelephone(); if (twoPlayerGame) { HandleDynamics(); if (!gameOver) { GetInput(&theGlider); GetInput(&theGlider2); HandleInteraction(); } HandleTriggers(); HandleBands(); if (!gameOver) { HandleGlider(&theGlider); HandleGlider(&theGlider2); } if (playing) { #ifdef COMPILEQT if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) MoviesTask(theMovie, 0); #endif RenderFrame(); HandleDynamicScoreboard(); } } else { HandleDynamics(); if (!gameOver) { if (demoGoing) GetDemoInput(&theGlider); else GetInput(&theGlider); HandleInteraction(); } HandleTriggers(); HandleBands(); if (!gameOver) HandleGlider(&theGlider); if (playing) { #ifdef COMPILEQT if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) MoviesTask(theMovie, 0); #endif RenderFrame(); HandleDynamicScoreboard(); } } if (gameOver) { countDown--; if (countDown <= 0) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); HideGlider(&theGlider); RefreshScoreboard(kNormalTitleMode); #if BUILD_ARCADE_VERSION // Need to paint over the scoreboard black. SetGWorld(boardSrcMap, nil); PaintRect(&boardSrcRect); CopyBits((BitMap *)*GetGWorldPixMap(boardSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &boardSrcRect, &boardDestRect, srcCopy, 0L); { Rect bounds; PicHandle thePicture; SInt16 hOffset; if (boardSrcRect.right >= 640) hOffset = (RectWide(&boardSrcRect) - kMaxViewWidth) / 2; else hOffset = -576; thePicture = GetPicture(kScoreboardPictID); if (!thePicture) RedAlert(kErrFailedGraphicLoad); HLock((Handle)thePicture); bounds = (*thePicture)->picFrame; HUnlock((Handle)thePicture); QOffsetRect(&bounds, -bounds.left, -bounds.top); QOffsetRect(&bounds, hOffset, 0); DrawPicture(thePicture, &bounds); ReleaseResource((Handle)thePicture); } #else // ShowMenuBarOld(); // TEMP #endif if (mortals < 0) DoDiedGameOver(); else DoGameOver(); SetGWorld(wasCPort, wasWorld); } } } #if BUILD_ARCADE_VERSION { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(boardSrcMap, nil); PaintRect(&boardSrcRect); CopyBits((BitMap *)*GetGWorldPixMap(boardSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &boardSrcRect, &boardDestRect, srcCopy, 0L); SetGWorld(wasCPort, wasWorld); } { Rect bounds; PicHandle thePicture; SInt16 hOffset; if (boardSrcRect.right >= 640) hOffset = (RectWide(&boardSrcRect) - kMaxViewWidth) / 2; else hOffset = -576; thePicture = GetPicture(kScoreboardPictID); if (!thePicture) RedAlert(kErrFailedGraphicLoad); HLock((Handle)thePicture); bounds = (*thePicture)->picFrame; HUnlock((Handle)thePicture); QOffsetRect(&bounds, -bounds.left, -bounds.top); QOffsetRect(&bounds, hOffset, 0); DrawPicture(thePicture, &bounds); ReleaseResource((Handle)thePicture); } #else // ShowMenuBarOld(); // TEMP #endif } //-------------------------------------------------------------- SetObjectsToDefaults void SetObjectsToDefaults (void) { houseType *thisHousePtr; short numRooms; short r, i; char wasState; Boolean initState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; numRooms = thisHousePtr->nRooms; for (r = 0; r < numRooms; r++) { thisHousePtr->rooms[r].visited = false; for (i = 0; i < kMaxRoomObs; i++) { switch (thisHousePtr->rooms[r].objects[i].what) { case kFloorVent: case kCeilingVent: case kFloorBlower: case kCeilingBlower: case kLeftFan: case kRightFan: case kSewerGrate: case kInvisBlower: case kGrecoVent: case kSewerBlower: case kLiftArea: thisHousePtr->rooms[r].objects[i].data.a.state = thisHousePtr->rooms[r].objects[i].data.a.initial; break; case kRedClock: case kBlueClock: case kYellowClock: case kCuckoo: case kPaper: case kBattery: case kBands: case kGreaseRt: case kGreaseLf: case kFoil: case kInvisBonus: case kStar: case kSparkle: case kHelium: thisHousePtr->rooms[r].objects[i].data.c.state = thisHousePtr->rooms[r].objects[i].data.c.initial; break; case kDeluxeTrans: initState = (thisHousePtr->rooms[r].objects[i].data.d.wide & 0xF0) >> 4; thisHousePtr->rooms[r].objects[i].data.d.wide &= 0xF0; thisHousePtr->rooms[r].objects[i].data.d.wide += initState; break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: thisHousePtr->rooms[r].objects[i].data.f.state = thisHousePtr->rooms[r].objects[i].data.f.initial; break; case kStereo: thisHousePtr->rooms[r].objects[i].data.g.state = isPlayMusicGame; break; case kShredder: case kToaster: case kMacPlus: case kGuitar: case kTV: case kCoffee: case kOutlet: case kVCR: case kMicrowave: thisHousePtr->rooms[r].objects[i].data.g.state = thisHousePtr->rooms[r].objects[i].data.g.initial; break; case kBalloon: case kCopterLf: case kCopterRt: case kDartLf: case kDartRt: case kBall: case kDrip: case kFish: thisHousePtr->rooms[r].objects[i].data.h.state = thisHousePtr->rooms[r].objects[i].data.h.initial; break; } } } HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- HideGlider void HideGlider (gliderPtr thisGlider) { Rect tempRect; tempRect = thisGlider->whole; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); if (hasMirror) { QOffsetRect(&tempRect, -20, -16); CopyRectWorkToMain(&tempRect); } tempRect = thisGlider->wholeShadow; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); } //-------------------------------------------------------------- InitTelephone void InitTelephone (void) { thePhone.nextRing = RandomInt(kRingSpread) + kRingBaseDelay; thePhone.rings = RandomInt(3) + 3; thePhone.delay = kRingDelay; theChimes.nextRing = RandomInt(kChimeDelay) + 1; } //-------------------------------------------------------------- HandleTelephone void HandleTelephone (void) { short delayTime; if (!phoneBitSet) { if (thePhone.nextRing == 0) { if (thePhone.delay == 0) { thePhone.delay = kRingDelay; PlayPrioritySound(kPhoneRingSound, kPhoneRingPriority); thePhone.rings--; if (thePhone.rings == 0) { thePhone.nextRing = RandomInt(kRingSpread) + kRingBaseDelay; thePhone.rings = RandomInt(3) + 3; } } else thePhone.delay--; } else thePhone.nextRing--; } // handle also the wind chimes (if they are present) if (numChimes > 0) { if (theChimes.nextRing == 0) { if (RandomInt(2) == 0) PlayPrioritySound(kChime1Sound, kChime1Priority); else PlayPrioritySound(kChime2Sound, kChime2Priority); delayTime = kChimeDelay / numChimes; if (delayTime < 2) delayTime = 2; theChimes.nextRing = RandomInt(delayTime) + 1; } else theChimes.nextRing--; } } //-------------------------------------------------------------- StrikeChime void StrikeChime (void) { theChimes.nextRing = 0; } //-------------------------------------------------------------- RestoreEntireGameScreen void RestoreEntireGameScreen (void) { Rect tempRect; HideCursor(); #if !BUILD_ARCADE_VERSION // HideMenuBarOld(); // TEMP #endif SetPort((GrafPtr)mainWindow); tempRect = thisMac.screen; PaintRect(&tempRect); DrawLocale(); RefreshScoreboard(kNormalTitleMode); // if (quickerTransitions) // DissBitsChunky(&justRoomsRect); // else // DissBits(&justRoomsRect); } \ No newline at end of file diff --git a/Sources/Player.c b/Sources/Player.c deleted file mode 100755 index f36208a..0000000 --- a/Sources/Player.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Player.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Play.h" #include "RectUtils.h" #define kGravity 3 #define kHImpulse 2 #define kVImpulse 2 #define kMaxHVel 16 #define kShredderCountdown -68 void MoveGlider (gliderPtr); void MoveGliderNormal (gliderPtr); void MoveGliderBurning (gliderPtr); void FadeGliderIn (gliderPtr); void TransportGliderIn (gliderPtr); void FadeGliderOut (gliderPtr); void MoveGliderUpStairs (gliderPtr); void MoveGliderDownStairs (gliderPtr); void MoveGliderFaceLeft (gliderPtr); void MoveGliderFaceRight (gliderPtr); void TransportGliderOut (gliderPtr); void MoveGliderDownDuct (gliderPtr); void MoveGliderUpDuct (gliderPtr); void MoveGliderInMailLeft (gliderPtr); void MoveGliderInMailRight (gliderPtr); void FinishGliderMailingLeft (gliderPtr); void FinishGliderMailingRight (gliderPtr); void MoveGliderFoilGoing (gliderPtr); void MoveGliderFoilLosing (gliderPtr); void MoveGliderShredding (gliderPtr); void HandleIdleGlider (gliderPtr); gliderType theGlider, theGlider2; Rect shadowSrcRect; GWorldPtr shadowSrcMap; GWorldPtr shadowMaskMap; Rect shadowSrc[kNumShadowSrcRects]; Rect gliderSrc[kNumGliderSrcRects]; Rect transRect; long theScore; short fadeInSequence[kLastFadeSequence]; short rightClip, leftClip, transRoom; Boolean shadowVisible, onePlayerLeft, playerDead; extern short numShredded, otherPlayerEscaped; extern Boolean playing, twoPlayerGame, gameOver, hasMirror; extern Boolean takingTheStairs, playerSuicide; //============================================================== Functions //-------------------------------------------------------------- MoveGlider void MoveGlider (gliderPtr thisGlider) { if (thisGlider->hVel > thisGlider->hDesiredVel) { thisGlider->hVel -= kHImpulse; if (thisGlider->hVel < thisGlider->hDesiredVel) thisGlider->hVel = thisGlider->hDesiredVel; } else if (thisGlider->hVel < thisGlider->hDesiredVel) { thisGlider->hVel += kHImpulse; if (thisGlider->hVel > thisGlider->hDesiredVel) thisGlider->hVel = thisGlider->hDesiredVel; } thisGlider->hDesiredVel = 0; if (thisGlider->vVel > thisGlider->vDesiredVel) { thisGlider->vVel -= kVImpulse; if (thisGlider->vVel < thisGlider->vDesiredVel) thisGlider->vVel = thisGlider->vDesiredVel; } else if (thisGlider->vVel < thisGlider->vDesiredVel) { thisGlider->vVel += kVImpulse; if (thisGlider->vVel > thisGlider->vDesiredVel) thisGlider->vVel = thisGlider->vDesiredVel; } thisGlider->vDesiredVel = kGravity; if (thisGlider->hVel < 0) { if (thisGlider->hVel < -kMaxHVel) thisGlider->hVel = -kMaxHVel; thisGlider->wasHVel = thisGlider->hVel; thisGlider->whole.right = thisGlider->dest.right; thisGlider->dest.left += thisGlider->hVel; thisGlider->dest.right += thisGlider->hVel; thisGlider->whole.left = thisGlider->dest.left; thisGlider->wholeShadow.right = thisGlider->destShadow.right; thisGlider->destShadow.left += thisGlider->hVel; thisGlider->destShadow.right += thisGlider->hVel; thisGlider->wholeShadow.left = thisGlider->destShadow.left; } else { if (thisGlider->hVel > kMaxHVel) thisGlider->hVel = kMaxHVel; thisGlider->wasHVel = thisGlider->hVel; thisGlider->whole.left = thisGlider->dest.left; thisGlider->dest.left += thisGlider->hVel; thisGlider->dest.right += thisGlider->hVel; thisGlider->whole.right = thisGlider->dest.right; thisGlider->wholeShadow.left = thisGlider->destShadow.left; thisGlider->destShadow.left += thisGlider->hVel; thisGlider->destShadow.right += thisGlider->hVel; thisGlider->wholeShadow.right = thisGlider->destShadow.right; } if (thisGlider->vVel < 0) { thisGlider->wasVVel = thisGlider->vVel; thisGlider->whole.bottom = thisGlider->dest.bottom; thisGlider->dest.top += thisGlider->vVel; thisGlider->dest.bottom += thisGlider->vVel; thisGlider->whole.top = thisGlider->dest.top; } else { thisGlider->wasVVel = thisGlider->vVel; thisGlider->whole.top = thisGlider->dest.top; thisGlider->dest.top += thisGlider->vVel; thisGlider->dest.bottom += thisGlider->vVel; thisGlider->whole.bottom = thisGlider->dest.bottom; } } //-------------------------------------------------------------- MoveGliderNormal void MoveGliderNormal (gliderPtr thisGlider) { if (thisGlider->facing == kFaceLeft) { if (thisGlider->sliding) { thisGlider->src = gliderSrc[30]; thisGlider->mask = gliderSrc[30]; thisGlider->sliding = false; } else { if (thisGlider->tipped) { thisGlider->src = gliderSrc[3]; thisGlider->mask = gliderSrc[3]; } else { thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } } } else { if (thisGlider->sliding) { thisGlider->src = gliderSrc[29]; thisGlider->mask = gliderSrc[29]; thisGlider->sliding = false; } else { if (thisGlider->tipped) { thisGlider->src = gliderSrc[1]; thisGlider->mask = gliderSrc[1]; } else { thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; } } } MoveGlider(thisGlider); } //-------------------------------------------------------------- MoveGliderBurning void MoveGliderBurning (gliderPtr thisGlider) { thisGlider->frame++; if (thisGlider->frame > 3) thisGlider->frame = 0; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[25 + thisGlider->frame]; thisGlider->mask = gliderSrc[25 + thisGlider->frame]; } else { thisGlider->src = gliderSrc[21 + thisGlider->frame]; thisGlider->mask = gliderSrc[21 + thisGlider->frame]; } thisGlider->wasMode--; if (thisGlider->wasMode <= 0) { StartGliderFadingOut(thisGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); } MoveGlider(thisGlider); } //-------------------------------------------------------------- FadeGliderIn void FadeGliderIn (gliderPtr thisGlider) { if (thisGlider->frame == 0) PlayPrioritySound(kFadeInSound, kFadeInPriority); thisGlider->frame++; if (thisGlider->frame >= kLastFadeSequence) { FlagGliderNormal(thisGlider); thisGlider->enteredRect = thisGlider->dest; } else { if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; } } } //-------------------------------------------------------------- TransportGliderIn void TransportGliderIn (gliderPtr thisGlider) { if (thisGlider->frame == 0) PlayPrioritySound(kTransInSound, kTransInPriority); thisGlider->frame++; if (thisGlider->frame >= kLastFadeSequence) { FlagGliderNormal(thisGlider); thisGlider->enteredRect = thisGlider->dest; } else { if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; } } } //-------------------------------------------------------------- FadeGliderOut void FadeGliderOut (gliderPtr thisGlider) { thisGlider->frame--; if (thisGlider->frame < 0) OffAMortal(thisGlider); else { if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; } } } //-------------------------------------------------------------- MoveGliderUpStairs void MoveGliderUpStairs (gliderPtr thisGlider) { #define kClimbStairsSpeed -4 short vNotClipped; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } else { thisGlider->src = gliderSrc[1]; thisGlider->mask = gliderSrc[1]; } thisGlider->whole.bottom = thisGlider->dest.bottom; thisGlider->dest.top += kClimbStairsSpeed; thisGlider->dest.bottom += kClimbStairsSpeed; thisGlider->whole.top = thisGlider->dest.top; vNotClipped = thisGlider->dest.bottom - 29; if (vNotClipped < kGliderHigh) { if (vNotClipped <= 0) { thisGlider->dest.top = thisGlider->dest.bottom; thisGlider->src.top = thisGlider->src.bottom; thisGlider->mask.top = thisGlider->mask.bottom; takingTheStairs = true; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == kPlayer1) MoveRoomToRoom(&theGlider2, kAbove); else MoveRoomToRoom(&theGlider, kAbove); } else { if (otherPlayerEscaped == kPlayerEscapedUpStairs) { otherPlayerEscaped = kNoOneEscaped; MoveRoomToRoom(thisGlider, kAbove); } else { otherPlayerEscaped = kPlayerEscapedUpStairs; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } } } else MoveRoomToRoom(thisGlider, kAbove); } else { thisGlider->dest.top = thisGlider->dest.bottom - vNotClipped; thisGlider->src.top = thisGlider->src.bottom - vNotClipped; thisGlider->mask.top = thisGlider->mask.bottom - vNotClipped; } } } //-------------------------------------------------------------- FinishGliderUpStairs void FinishGliderUpStairs (gliderPtr thisGlider) { #define kVClimbStairsSpeed -4 #define kHClimbStairsSpeed -4 short hNotClipped; thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; thisGlider->whole.bottom = thisGlider->dest.bottom; thisGlider->dest.top += kVClimbStairsSpeed; thisGlider->dest.bottom += kVClimbStairsSpeed; thisGlider->whole.top = thisGlider->dest.top; thisGlider->whole.right = thisGlider->dest.right; thisGlider->dest.left += kHClimbStairsSpeed; thisGlider->dest.right += kHClimbStairsSpeed; thisGlider->whole.left = thisGlider->dest.left; thisGlider->wholeShadow.right = thisGlider->destShadow.right; thisGlider->destShadow.left += kHClimbStairsSpeed; thisGlider->destShadow.right += kHClimbStairsSpeed; thisGlider->wholeShadow.left = thisGlider->destShadow.left; hNotClipped = rightClip - thisGlider->dest.left; if (hNotClipped < kGliderWide) { thisGlider->dest.right = thisGlider->dest.left + hNotClipped; thisGlider->src.right = thisGlider->src.left + hNotClipped; thisGlider->mask.right = thisGlider->mask.left + hNotClipped; thisGlider->destShadow.right = thisGlider->dest.right; } else { if (thisGlider->frame == kWasBurning) FlagGliderBurning(thisGlider); else FlagGliderNormal(thisGlider); thisGlider->hVel = kHClimbStairsSpeed; thisGlider->hDesiredVel = kHClimbStairsSpeed; thisGlider->vVel = kVClimbStairsSpeed; thisGlider->vDesiredVel = kVClimbStairsSpeed; thisGlider->enteredRect = thisGlider->dest; } } //-------------------------------------------------------------- MoveGliderDownStairs void MoveGliderDownStairs (gliderPtr thisGlider) { #define kVDropStairsSpeed 4 #define kHDropStairsSpeed 4 short hNotClipped; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } else { thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; } thisGlider->whole.left = thisGlider->dest.left; thisGlider->dest.left += kHDropStairsSpeed; thisGlider->dest.right += kHDropStairsSpeed; thisGlider->whole.right = thisGlider->dest.right; thisGlider->wholeShadow.left = thisGlider->destShadow.left; thisGlider->destShadow.left += kHDropStairsSpeed; thisGlider->destShadow.right += kHDropStairsSpeed; thisGlider->wholeShadow.right = thisGlider->destShadow.right; thisGlider->whole.top = thisGlider->dest.top; thisGlider->dest.top += kVDropStairsSpeed; thisGlider->dest.bottom += kVDropStairsSpeed; thisGlider->whole.bottom = thisGlider->dest.bottom; hNotClipped = rightClip - thisGlider->dest.left; if (hNotClipped < kGliderWide) { if (hNotClipped <= 0) { thisGlider->dest.right = thisGlider->dest.left; thisGlider->src.right = thisGlider->src.left; thisGlider->mask.right = thisGlider->mask.left; thisGlider->destShadow.right = thisGlider->dest.right; takingTheStairs = true; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == kPlayer1) MoveRoomToRoom(&theGlider2, kBelow); else MoveRoomToRoom(&theGlider, kBelow); } else { if (otherPlayerEscaped == kPlayerEscapedDownStairs) { otherPlayerEscaped = kNoOneEscaped; MoveRoomToRoom(thisGlider, kBelow); } else { otherPlayerEscaped = kPlayerEscapedDownStairs; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } } } else MoveRoomToRoom(thisGlider, kBelow); } else { thisGlider->dest.right = thisGlider->dest.left + hNotClipped; thisGlider->src.right = thisGlider->src.left + hNotClipped; thisGlider->mask.right = thisGlider->mask.left + hNotClipped; thisGlider->destShadow.right = thisGlider->dest.right; } } } //-------------------------------------------------------------- FinishGliderDownStairs void FinishGliderDownStairs (gliderPtr thisGlider) { #define kVDropStairsSpeed 4 #define kHDropStairsSpeed 4 short hNotClipped; thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; thisGlider->whole.left = thisGlider->dest.left; thisGlider->dest.left += kHDropStairsSpeed; thisGlider->dest.right += kHDropStairsSpeed; thisGlider->whole.right = thisGlider->dest.right; thisGlider->wholeShadow.left = thisGlider->destShadow.left; thisGlider->destShadow.left += kHDropStairsSpeed; thisGlider->destShadow.right += kHDropStairsSpeed; thisGlider->wholeShadow.right = thisGlider->destShadow.right; thisGlider->whole.top = thisGlider->dest.top; thisGlider->dest.top += kVDropStairsSpeed; thisGlider->dest.bottom += kVDropStairsSpeed; thisGlider->whole.bottom = thisGlider->dest.bottom; hNotClipped = thisGlider->dest.right - leftClip; if (hNotClipped < kGliderWide) { thisGlider->dest.left = thisGlider->dest.right - hNotClipped; thisGlider->src.left = thisGlider->src.right - hNotClipped; thisGlider->mask.left = thisGlider->mask.right - hNotClipped; thisGlider->destShadow.left = thisGlider->dest.left; } else { if (thisGlider->frame == kWasBurning) FlagGliderBurning(thisGlider); else FlagGliderNormal(thisGlider); thisGlider->hVel = kHDropStairsSpeed; thisGlider->hDesiredVel = kHDropStairsSpeed; thisGlider->vVel = kVDropStairsSpeed; thisGlider->vDesiredVel = kVDropStairsSpeed; thisGlider->enteredRect = thisGlider->dest; } } //-------------------------------------------------------------- MoveGliderFaceLeft void MoveGliderFaceLeft (gliderPtr thisGlider) { thisGlider->src = gliderSrc[thisGlider->frame]; thisGlider->mask = gliderSrc[thisGlider->frame]; MoveGlider(thisGlider); thisGlider->frame--; if (thisGlider->frame < kFirstAboutFaceFrame) { thisGlider->mode = kGliderNormal; thisGlider->facing = kFaceLeft; } } //-------------------------------------------------------------- MoveGliderFaceRight void MoveGliderFaceRight (gliderPtr thisGlider) { thisGlider->src = gliderSrc[thisGlider->frame]; thisGlider->mask = gliderSrc[thisGlider->frame]; MoveGlider(thisGlider); thisGlider->frame++; if (thisGlider->frame > kLastAboutFaceFrame) { thisGlider->mode = kGliderNormal; thisGlider->facing = kFaceRight; } } //-------------------------------------------------------------- TransportGliderOut void TransportGliderOut (gliderPtr thisGlider) { Rect tempRect; thisGlider->frame--; if (thisGlider->frame < 0) { tempRect = thisGlider->whole; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); tempRect = thisGlider->wholeShadow; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); thisGlider->dontDraw = true; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == kPlayer1) TransportRoomToRoom(&theGlider2); else TransportRoomToRoom(&theGlider); } else { if (otherPlayerEscaped == kPlayerTransportedOut) { otherPlayerEscaped = kNoOneEscaped; TransportRoomToRoom(thisGlider); } else { otherPlayerEscaped = kPlayerTransportedOut; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } } } else { TransportRoomToRoom(thisGlider); } } else { if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame] + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[fadeInSequence[thisGlider->frame]]; thisGlider->mask = gliderSrc[fadeInSequence[thisGlider->frame]]; } } } //-------------------------------------------------------------- MoveGliderDownDuct void MoveGliderDownDuct (gliderPtr thisGlider) { #define kVDropDuctSpeed 4 Rect tempRect; short vNotClipped; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } else { thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; } if (thisGlider->dest.left < thisGlider->clip.left) { thisGlider->whole.left = thisGlider->dest.left; thisGlider->dest.left++; thisGlider->dest.right++; thisGlider->whole.right = thisGlider->dest.right; thisGlider->wholeShadow.left = thisGlider->destShadow.left; thisGlider->destShadow.left++; thisGlider->destShadow.right++; thisGlider->wholeShadow.right = thisGlider->destShadow.right; } else if (thisGlider->dest.left > thisGlider->clip.left) { thisGlider->whole.right = thisGlider->dest.right; thisGlider->dest.left--; thisGlider->dest.right--; thisGlider->whole.left = thisGlider->dest.left; thisGlider->wholeShadow.right = thisGlider->destShadow.right; thisGlider->destShadow.left--; thisGlider->destShadow.right--; thisGlider->wholeShadow.left = thisGlider->destShadow.left; } thisGlider->whole.top = thisGlider->dest.top; thisGlider->dest.top += kVDropDuctSpeed; thisGlider->dest.bottom += kVDropDuctSpeed; thisGlider->whole.bottom = thisGlider->dest.bottom; vNotClipped = 315 - thisGlider->dest.top; if (vNotClipped < kGliderHigh) { if (vNotClipped <= 0) { tempRect = thisGlider->whole; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); tempRect = thisGlider->wholeShadow; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); thisGlider->dontDraw = true; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == kPlayer1) MoveDuctToDuct(&theGlider2); else MoveDuctToDuct(&theGlider); } else { if (otherPlayerEscaped == kPlayerDuckedOut) { otherPlayerEscaped = kNoOneEscaped; MoveDuctToDuct(thisGlider); } else { otherPlayerEscaped = kPlayerDuckedOut; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } } } else MoveDuctToDuct(thisGlider); } else { thisGlider->dest.bottom = thisGlider->dest.top + vNotClipped; thisGlider->src.bottom = thisGlider->src.top + vNotClipped; thisGlider->mask.bottom = thisGlider->mask.top + vNotClipped; } } } //-------------------------------------------------------------- MoveGliderUpDuct void MoveGliderUpDuct (gliderPtr thisGlider) { #define kVRiseDuctSpeed -4 Rect tempRect; short vNotClipped; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } else { thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; } if (thisGlider->dest.left < thisGlider->clip.left) { thisGlider->whole.left = thisGlider->dest.left; thisGlider->dest.left++; thisGlider->dest.right++; thisGlider->whole.right = thisGlider->dest.right; thisGlider->wholeShadow.left = thisGlider->destShadow.left; thisGlider->destShadow.left++; thisGlider->destShadow.right++; thisGlider->wholeShadow.right = thisGlider->destShadow.right; } else if (thisGlider->dest.left > thisGlider->clip.left) { thisGlider->whole.right = thisGlider->dest.right; thisGlider->dest.left--; thisGlider->dest.right--; thisGlider->whole.left = thisGlider->dest.left; thisGlider->wholeShadow.right = thisGlider->destShadow.right; thisGlider->destShadow.left--; thisGlider->destShadow.right--; thisGlider->wholeShadow.left = thisGlider->destShadow.left; } thisGlider->whole.bottom = thisGlider->dest.bottom; thisGlider->dest.top += kVRiseDuctSpeed; thisGlider->dest.bottom += kVRiseDuctSpeed; thisGlider->whole.top = thisGlider->dest.top; vNotClipped = thisGlider->dest.bottom - (kCeilingTransTop + 1); if (vNotClipped < kGliderHigh) { if (vNotClipped <= 0) { tempRect = thisGlider->whole; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); tempRect = thisGlider->wholeShadow; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); thisGlider->dontDraw = true; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == kPlayer1) MoveDuctToDuct(&theGlider2); else MoveDuctToDuct(&theGlider); } else { if (otherPlayerEscaped == kPlayerDuckedOut) { otherPlayerEscaped = kNoOneEscaped; MoveDuctToDuct(thisGlider); } else { otherPlayerEscaped = kPlayerDuckedOut; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } } } else MoveDuctToDuct(thisGlider); } else { thisGlider->dest.top = thisGlider->dest.bottom - vNotClipped; thisGlider->src.top = thisGlider->src.bottom - vNotClipped; thisGlider->mask.top = thisGlider->mask.bottom - vNotClipped; } } } //-------------------------------------------------------------- FinishGliderMailingLeft void FinishGliderMailingLeft (gliderPtr thisGlider) { #define kHPushMailSpeed -4 short hNotClipped; if (thisGlider->dest.left == thisGlider->dest.right) PlayPrioritySound(kTransInSound, kTransInPriority); thisGlider->whole.right = thisGlider->dest.right; thisGlider->dest.left += kHPushMailSpeed; thisGlider->dest.right += kHPushMailSpeed; thisGlider->whole.left = thisGlider->dest.left; thisGlider->wholeShadow.right = thisGlider->destShadow.right; thisGlider->destShadow.left += kHPushMailSpeed; thisGlider->destShadow.right += kHPushMailSpeed; thisGlider->wholeShadow.left = thisGlider->destShadow.left; hNotClipped = thisGlider->clip.right - thisGlider->dest.left; if (hNotClipped < kGliderWide) { thisGlider->dest.right = thisGlider->dest.left + hNotClipped; thisGlider->src.right = thisGlider->src.left + hNotClipped; thisGlider->mask.right = thisGlider->mask.left + hNotClipped; thisGlider->destShadow.right = thisGlider->dest.right; } else { if (thisGlider->frame == kWasBurning) FlagGliderBurning(thisGlider); else FlagGliderNormal(thisGlider); thisGlider->enteredRect = thisGlider->dest; } } //-------------------------------------------------------------- FinishGliderMailingRight void FinishGliderMailingRight (gliderPtr thisGlider) { #define kHPushMailRtSpeed 4 short hNotClipped; if (thisGlider->dest.left == thisGlider->dest.right) PlayPrioritySound(kTransInSound, kTransInPriority); thisGlider->whole.left = thisGlider->dest.left; thisGlider->dest.left += kHPushMailRtSpeed; thisGlider->dest.right += kHPushMailRtSpeed; thisGlider->whole.right = thisGlider->dest.right; thisGlider->wholeShadow.left = thisGlider->destShadow.left; thisGlider->destShadow.left += kHPushMailRtSpeed; thisGlider->destShadow.right += kHPushMailRtSpeed; thisGlider->wholeShadow.right = thisGlider->destShadow.right; hNotClipped = thisGlider->dest.right - thisGlider->clip.left; if (hNotClipped < kGliderWide) { thisGlider->dest.left = thisGlider->dest.right - hNotClipped; thisGlider->src.left = thisGlider->src.right - hNotClipped; thisGlider->mask.left = thisGlider->mask.right - hNotClipped; thisGlider->destShadow.left = thisGlider->dest.left; } else { if (thisGlider->frame == kWasBurning) FlagGliderBurning(thisGlider); else FlagGliderNormal(thisGlider); thisGlider->enteredRect = thisGlider->dest; } } //-------------------------------------------------------------- FinishGliderDuctingIn void FinishGliderDuctingIn (gliderPtr thisGlider) { #define kVDropStairsSpeed 4 short vNotClipped; if (thisGlider->dest.top == thisGlider->dest.bottom) PlayPrioritySound(kTransInSound, kTransInPriority); thisGlider->whole.top = thisGlider->dest.top; thisGlider->dest.top += kVDropDuctSpeed; thisGlider->dest.bottom += kVDropDuctSpeed; thisGlider->whole.bottom = thisGlider->dest.bottom; vNotClipped = thisGlider->dest.bottom - (kCeilingTransTop + 1); if (vNotClipped < kGliderHigh) { thisGlider->dest.top = thisGlider->dest.bottom - vNotClipped; thisGlider->src.top = thisGlider->src.bottom - vNotClipped; thisGlider->mask.top = thisGlider->mask.bottom - vNotClipped; } else { if (thisGlider->frame == kWasBurning) FlagGliderBurning(thisGlider); else FlagGliderNormal(thisGlider); thisGlider->enteredRect = thisGlider->dest; FlagStillOvers(thisGlider); } } //-------------------------------------------------------------- MoveGliderInMailLeft void MoveGliderInMailLeft (gliderPtr thisGlider) { #define kHMailPullSpeed 4 #define kVMailDropSpeed 2 Rect tempRect; short fromIdealTop, hNotClipped; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } else { thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; } if (thisGlider->dest.top < thisGlider->clip.top) { fromIdealTop = thisGlider->clip.top - thisGlider->dest.top; if (fromIdealTop > kVMailDropSpeed) fromIdealTop = kVMailDropSpeed; thisGlider->whole.top = thisGlider->dest.top; thisGlider->dest.top += fromIdealTop; thisGlider->dest.bottom += fromIdealTop; thisGlider->whole.bottom = thisGlider->dest.bottom; } thisGlider->whole.left = thisGlider->dest.left; thisGlider->dest.left += kHMailPullSpeed; thisGlider->dest.right += kHMailPullSpeed; thisGlider->whole.right = thisGlider->dest.right; thisGlider->wholeShadow.left = thisGlider->destShadow.left; thisGlider->destShadow.left += kHMailPullSpeed; thisGlider->destShadow.right += kHMailPullSpeed; thisGlider->wholeShadow.right = thisGlider->destShadow.right; hNotClipped = thisGlider->clip.right - thisGlider->dest.left; if (hNotClipped < kGliderWide) { if (hNotClipped <= 0) { tempRect = thisGlider->whole; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); tempRect = thisGlider->wholeShadow; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); thisGlider->dontDraw = true; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == kPlayer1) MoveMailToMail(&theGlider2); else MoveMailToMail(&theGlider); } else { if (otherPlayerEscaped == kPlayerMailedOut) { otherPlayerEscaped = kNoOneEscaped; MoveMailToMail(thisGlider); } else { otherPlayerEscaped = kPlayerMailedOut; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } } } else MoveMailToMail(thisGlider); } else { thisGlider->dest.right = thisGlider->dest.left + hNotClipped; thisGlider->src.right = thisGlider->src.left + hNotClipped; thisGlider->mask.right = thisGlider->mask.left + hNotClipped; thisGlider->destShadow.right = thisGlider->dest.right; } } } //-------------------------------------------------------------- MoveGliderInMailRight void MoveGliderInMailRight (gliderPtr thisGlider) { #define kHMailPullRtSpeed -4 #define kVMailDropSpeed 2 Rect tempRect; short fromIdealTop, hNotClipped; if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } else { thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; } if (thisGlider->dest.top < thisGlider->clip.top) { fromIdealTop = thisGlider->clip.top - thisGlider->dest.top; if (fromIdealTop > kVMailDropSpeed) fromIdealTop = kVMailDropSpeed; thisGlider->whole.top = thisGlider->dest.top; thisGlider->dest.top += fromIdealTop; thisGlider->dest.bottom += fromIdealTop; thisGlider->whole.bottom = thisGlider->dest.bottom; } thisGlider->whole.right = thisGlider->dest.right; thisGlider->dest.left += kHMailPullRtSpeed; thisGlider->dest.right += kHMailPullRtSpeed; thisGlider->whole.left = thisGlider->dest.left; thisGlider->wholeShadow.right = thisGlider->destShadow.right; thisGlider->destShadow.left += kHMailPullRtSpeed; thisGlider->destShadow.right += kHMailPullRtSpeed; thisGlider->wholeShadow.left = thisGlider->destShadow.left; hNotClipped = thisGlider->dest.right - thisGlider->clip.left; if (hNotClipped < kGliderWide) { if (hNotClipped <= 0) { tempRect = thisGlider->whole; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); tempRect = thisGlider->wholeShadow; QOffsetRect(&tempRect, playOriginH, playOriginV); CopyRectWorkToMain(&tempRect); thisGlider->dontDraw = true; if (twoPlayerGame) { if (onePlayerLeft) { if (playerDead == kPlayer1) MoveMailToMail(&theGlider2); else MoveMailToMail(&theGlider); } else { if (otherPlayerEscaped == kPlayerMailedOut) { otherPlayerEscaped = kNoOneEscaped; MoveMailToMail(thisGlider); } else { otherPlayerEscaped = kPlayerMailedOut; RefreshScoreboard(kEscapedTitleMode); FlagGliderInLimbo(thisGlider, true); } } } else MoveMailToMail(thisGlider); } else { thisGlider->dest.left = thisGlider->dest.right - hNotClipped; thisGlider->src.left = thisGlider->src.right - hNotClipped; thisGlider->mask.left = thisGlider->mask.right - hNotClipped; thisGlider->destShadow.left = thisGlider->dest.left; } } } //-------------------------------------------------------------- DeckGliderInFoil void DeckGliderInFoil (gliderPtr thisGlider) { showFoil = true; if (twoPlayerGame) { SetPort((GrafPtr)glidSrcMap); LoadGraphic(kGliderFoilPictID); SetPort((GrafPtr)glid2SrcMap); LoadGraphic(kGliderFoil2PictID); } if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[(thisGlider->frame + 2) + kLeftFadeOffset]; thisGlider->mask = gliderSrc[(thisGlider->frame + 2) + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[thisGlider->frame + 2]; thisGlider->mask = gliderSrc[thisGlider->frame + 2]; } } //-------------------------------------------------------------- MoveGliderFoilGoing void MoveGliderFoilGoing (gliderPtr thisGlider) { thisGlider->frame++; if (thisGlider->frame > 8) { FlagGliderNormal(thisGlider); } else { if (thisGlider->frame < 5) { if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; thisGlider->mask = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[10 - thisGlider->frame]; thisGlider->mask = gliderSrc[10 - thisGlider->frame]; } } else DeckGliderInFoil(thisGlider); } MoveGlider(thisGlider); } //-------------------------------------------------------------- xxxx void RemoveFoilFromGlider (gliderPtr thisGlider) { showFoil = false; if (twoPlayerGame) { SetPort((GrafPtr)glidSrcMap); LoadGraphic(kGliderPictID); SetPort((GrafPtr)glid2SrcMap); LoadGraphic(kGlider2PictID); } if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[(thisGlider->frame + 2) + kLeftFadeOffset]; thisGlider->mask = gliderSrc[(thisGlider->frame + 2) + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[thisGlider->frame + 2]; thisGlider->mask = gliderSrc[thisGlider->frame + 2]; } } //-------------------------------------------------------------- MoveGliderFoilLosing void MoveGliderFoilLosing (gliderPtr thisGlider) { thisGlider->frame++; if (thisGlider->frame > 8) FlagGliderNormal(thisGlider); else { if (thisGlider->frame < 5) { if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; thisGlider->mask = gliderSrc[(10 - thisGlider->frame) + kLeftFadeOffset]; } else { thisGlider->src = gliderSrc[10 - thisGlider->frame]; thisGlider->mask = gliderSrc[10 - thisGlider->frame]; } } else RemoveFoilFromGlider(thisGlider); } MoveGlider(thisGlider); } //-------------------------------------------------------------- MoveGliderShredding void MoveGliderShredding (gliderPtr thisGlider) { #define kDropShredSlow 1 #define kDropShredFast 4 short vNotClipped; if (thisGlider->frame > 0) { if (thisGlider->facing == kFaceLeft) { thisGlider->src = gliderSrc[2]; thisGlider->mask = gliderSrc[2]; } else { thisGlider->src = gliderSrc[0]; thisGlider->mask = gliderSrc[0]; } vNotClipped = thisGlider->frame - thisGlider->dest.top; if (vNotClipped < kGliderHigh) { thisGlider->whole.top = thisGlider->dest.top; thisGlider->dest.top += kDropShredSlow; thisGlider->dest.bottom += kDropShredSlow; thisGlider->whole.bottom = thisGlider->dest.bottom; shadowVisible = false; PlayPrioritySound(kShredSound, kShredPriority); } else { thisGlider->whole.top = thisGlider->dest.top; thisGlider->dest.top += kDropShredFast; thisGlider->dest.bottom += kDropShredFast; thisGlider->whole.bottom = thisGlider->dest.bottom; } vNotClipped = thisGlider->frame - thisGlider->dest.top; if (vNotClipped < kGliderHigh) { if (vNotClipped <= 0) { AddAShreddedGlider(&thisGlider->dest); thisGlider->frame = kShredderCountdown; } else { thisGlider->dest.bottom = thisGlider->dest.top + vNotClipped; thisGlider->src.bottom = thisGlider->src.top + vNotClipped; thisGlider->mask.bottom = thisGlider->mask.top + vNotClipped; } } } else { thisGlider->frame++; if (thisGlider->frame >= 0) OffAMortal(thisGlider); } } //-------------------------------------------------------------- HandleIdleGlider void HandleIdleGlider (gliderPtr thisGlider) { thisGlider->hVel--; if (thisGlider->hVel <= 0) { thisGlider->mode = thisGlider->wasMode; thisGlider->dontDraw = false; } } //-------------------------------------------------------------- HandleGlider void HandleGlider (gliderPtr thisGlider) { switch (thisGlider->mode) { case kGliderNormal: MoveGliderNormal(thisGlider); break; case kGliderFadingIn: FadeGliderIn(thisGlider); break; case kGliderFadingOut: FadeGliderOut(thisGlider); break; case kGliderGoingUp: MoveGliderUpStairs(thisGlider); break; case kGliderComingUp: FinishGliderUpStairs(thisGlider); break; case kGliderGoingDown: MoveGliderDownStairs(thisGlider); break; case kGliderComingDown: FinishGliderDownStairs(thisGlider); break; case kGliderFaceLeft: MoveGliderFaceLeft(thisGlider); break; case kGliderFaceRight: MoveGliderFaceRight(thisGlider); break; case kGliderBurning: MoveGliderBurning(thisGlider); break; case kGliderTransporting: TransportGliderOut(thisGlider); break; case kGliderDuctingDown: MoveGliderDownDuct(thisGlider); break; case kGliderDuctingUp: MoveGliderUpDuct(thisGlider); break; case kGliderDuctingIn: FinishGliderDuctingIn(thisGlider); break; case kGliderMailInLeft: MoveGliderInMailLeft(thisGlider); break; case kGliderMailOutLeft: // <-- G _[] FinishGliderMailingLeft(thisGlider); break; case kGliderMailInRight: MoveGliderInMailRight(thisGlider); break; case kGliderMailOutRight: // []_ G --> FinishGliderMailingRight(thisGlider); break; case kGliderGoingFoil: MoveGliderFoilGoing(thisGlider); break; case kGliderLosingFoil: MoveGliderFoilLosing(thisGlider); break; case kGliderShredding: MoveGliderShredding(thisGlider); break; case kGliderInLimbo: break; case kGliderIdle: HandleIdleGlider(thisGlider); break; case kGliderTransportingIn: TransportGliderIn(thisGlider); break; } thisGlider->ignoreLeft = false; thisGlider->ignoreRight = false; thisGlider->ignoreGround = false; } //-------------------------------------------------------------- OffsetGlider void OffsetGlider (gliderPtr thisGlider, short where) { if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) return; switch (where) { case kToRight: thisGlider->dest.left += kRoomWide; thisGlider->dest.right += kRoomWide; thisGlider->destShadow.left += kRoomWide; thisGlider->destShadow.right += kRoomWide; thisGlider->whole = thisGlider->dest; thisGlider->wholeShadow = thisGlider->destShadow; break; case kToLeft: thisGlider->dest.left -= kRoomWide; thisGlider->dest.right -= kRoomWide; thisGlider->destShadow.left -= kRoomWide; thisGlider->destShadow.right -= kRoomWide; thisGlider->whole = thisGlider->dest; thisGlider->wholeShadow = thisGlider->destShadow; break; case kAbove: thisGlider->dest.top -= kTileHigh; thisGlider->dest.bottom -= kTileHigh; thisGlider->whole = thisGlider->dest; break; case kBelow: thisGlider->dest.top += kTileHigh; thisGlider->dest.bottom += kTileHigh; thisGlider->whole = thisGlider->dest; break; } } //-------------------------------------------------------------- OffAMortal void OffAMortal (gliderPtr thisGlider) { if (gameOver) return; if (numShredded > 0) RemoveShreds(); mortals--; if (mortals < 0) { HideGlider(thisGlider); if (twoPlayerGame) { if (mortals < -1) // both players are now dead { FlagGameOver(); thisGlider->dontDraw = true; } else { FlagGliderInLimbo(thisGlider, false); thisGlider->dontDraw = true; onePlayerLeft = true; playerDead = thisGlider->which; } } else { FlagGameOver(); thisGlider->dontDraw = true; } } else { QuickGlidersRefresh(); HideGlider(thisGlider); } if (mortals >= 0) { if (thisGlider->mode == kGliderGoingFoil) DeckGliderInFoil(thisGlider); FlagGliderNormal(thisGlider); if (playerSuicide) FollowTheLeader(); else { StartGliderFadingIn(thisGlider); thisGlider->dest = thisGlider->enteredRect; thisGlider->whole = thisGlider->dest; thisGlider->destShadow.left = thisGlider->dest.left; thisGlider->destShadow.right = thisGlider->dest.right; thisGlider->wholeShadow = thisGlider->destShadow; } } else if ((mortals == -1) && (onePlayerLeft) && (!gameOver)) { switch (otherPlayerEscaped) { case kPlayerEscapedUp: case kPlayerEscapingUpStairs: case kPlayerEscapedUpStairs: if (playerDead == kPlayer1) MoveRoomToRoom(&theGlider2, kAbove); else MoveRoomToRoom(&theGlider, kAbove); break; case kPlayerEscapedDown: case kPlayerEscapingDownStairs: case kPlayerEscapedDownStairs: if (playerDead == kPlayer1) MoveRoomToRoom(&theGlider2, kBelow); else MoveRoomToRoom(&theGlider, kBelow); break; case kPlayerEscapedLeft: if (playerDead == kPlayer1) MoveRoomToRoom(&theGlider2, kToLeft); else MoveRoomToRoom(&theGlider, kToLeft); break; case kPlayerEscapedRight: if (playerDead == kPlayer1) MoveRoomToRoom(&theGlider2, kToRight); else MoveRoomToRoom(&theGlider, kToRight); break; case kPlayerTransportedOut: if (playerDead == kPlayer1) TransportRoomToRoom(&theGlider2); else TransportRoomToRoom(&theGlider); break; case kPlayerMailedOut: if (playerDead == kPlayer1) MoveMailToMail(&theGlider2); else MoveMailToMail(&theGlider); break; case kPlayerDuckedOut: if (playerDead == kPlayer1) MoveDuctToDuct(&theGlider2); else MoveDuctToDuct(&theGlider); break; default: break; } otherPlayerEscaped = kPlayerIsDeadForever; } } \ No newline at end of file diff --git a/Sources/Prefs.c b/Sources/Prefs.c deleted file mode 100755 index 1a544b0..0000000 --- a/Sources/Prefs.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Prefs.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include #include #include "Externs.h" #include "Environ.h" #define kPrefCreatorType 'ozm5' #define kPrefFileType 'gliP' #define kPrefFileName "\pGlider Prefs" #define kDefaultPrefFName "\pPreferences" #define kPrefsStringsID 160 #define kNewPrefsAlertID 160 #define kPrefsFNameIndex 1 Boolean CanUseFindFolder (void); Boolean GetPrefsFPath (long *, short *); Boolean CreatePrefsFolder (short *); Boolean WritePrefs (long *, short *, prefsInfo *); OSErr ReadPrefs (long *, short *, prefsInfo *); Boolean DeletePrefs (long *, short *); void BringUpDeletePrefsAlert (void); //============================================================== Functions //-------------------------------------------------------------- CanUseFindFolder Boolean CanUseFindFolder (void) { OSErr theErr; long theFeature; if (!thisMac.hasGestalt) return(false); theErr = Gestalt(gestaltFindFolderAttr, &theFeature); if (theErr != noErr) return(false); if (!BitTst(&theFeature, 31 - gestaltFindFolderPresent)) return(false); else return(true); } //-------------------------------------------------------------- GetPrefsFPath Boolean GetPrefsFPath (long *prefDirID, short *systemVolRef) { OSErr theErr; theErr = FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder, systemVolRef, prefDirID); if (theErr != noErr) return(false); return(true); } //-------------------------------------------------------------- CreatePrefsFolder Boolean CreatePrefsFolder (short *systemVolRef) { HFileParam fileParamBlock; Str255 folderName; OSErr theErr; GetIndString(folderName, kPrefsStringsID, kPrefsFNameIndex); fileParamBlock.ioVRefNum = *systemVolRef; fileParamBlock.ioDirID = 0; fileParamBlock.ioNamePtr = folderName; fileParamBlock.ioCompletion = nil; theErr = PBDirCreate((HParmBlkPtr)&fileParamBlock, false); if (theErr != noErr) { CheckFileError(theErr, "\pPreferences"); return(false); } return(true); } //-------------------------------------------------------------- WritePrefs Boolean WritePrefs (long *prefDirID, short *systemVolRef, prefsInfo *thePrefs) { OSErr theErr; short fileRefNum; long byteCount; FSSpec theSpecs; Str255 fileName = kPrefFileName; theErr = FSMakeFSSpec(*systemVolRef, *prefDirID, fileName, &theSpecs); if (theErr != noErr) { if (theErr != fnfErr) { CheckFileError(theErr, "\pPreferences"); return(false); } theErr = FSpCreate(&theSpecs, kPrefCreatorType, kPrefFileType, smSystemScript); if (theErr != noErr) { CheckFileError(theErr, "\pPreferences"); return(false); } } theErr = FSpOpenDF(&theSpecs, fsRdWrPerm, &fileRefNum); if (theErr != noErr) { CheckFileError(theErr, "\pPreferences"); return(false); } byteCount = sizeof(*thePrefs); theErr = FSWrite(fileRefNum, &byteCount, thePrefs); if (theErr != noErr) { CheckFileError(theErr, "\pPreferences"); return(false); } theErr = FSClose(fileRefNum); if (theErr != noErr) { CheckFileError(theErr, "\pPreferences"); return(false); } return(true); } //-------------------------------------------------------------- SavePrefs Boolean SavePrefs (prefsInfo *thePrefs, short versionNow) { long prefDirID; short systemVolRef; thePrefs->prefVersion = versionNow; if (!GetPrefsFPath(&prefDirID, &systemVolRef)) return(false); if (!WritePrefs(&prefDirID, &systemVolRef, thePrefs)) return(false); return(true); } //-------------------------------------------------------------- ReadPrefs OSErr ReadPrefs (long *prefDirID, short *systemVolRef, prefsInfo *thePrefs) { OSErr theErr; short fileRefNum; long byteCount; FSSpec theSpecs; Str255 fileName = kPrefFileName; theErr = FSMakeFSSpec(*systemVolRef, *prefDirID, fileName, &theSpecs); if (theErr != noErr) { if (theErr == fnfErr) return(theErr); else { CheckFileError(theErr, "\pPreferences"); return(theErr); } } theErr = FSpOpenDF(&theSpecs, fsRdWrPerm, &fileRefNum); if (theErr != noErr) { CheckFileError(theErr, "\pPreferences"); return(theErr); } byteCount = sizeof(*thePrefs); theErr = FSRead(fileRefNum, &byteCount, thePrefs); if (theErr != noErr) { if (theErr == eofErr) theErr = FSClose(fileRefNum); else { CheckFileError(theErr, "\pPreferences"); theErr = FSClose(fileRefNum); } return(theErr); } theErr = FSClose(fileRefNum); if (theErr != noErr) { CheckFileError(theErr, "\pPreferences"); return(theErr); } return(theErr); } //-------------------------------------------------------------- DeletePrefs Boolean DeletePrefs (long *dirID, short *volRef) { FSSpec theSpecs; Str255 fileName = kPrefFileName; OSErr theErr; theErr = FSMakeFSSpec(*volRef, *dirID, fileName, &theSpecs); if (theErr != noErr) return(false); else theErr = FSpDelete(&theSpecs); if (theErr != noErr) return(false); return(true); } //-------------------------------------------------------------- LoadPrefs Boolean LoadPrefs (prefsInfo *thePrefs, short versionNeed) { long prefDirID; OSErr theErr; short systemVolRef; Boolean noProblems; noProblems = GetPrefsFPath(&prefDirID, &systemVolRef); if (!noProblems) return(false); theErr = ReadPrefs(&prefDirID, &systemVolRef, thePrefs); if (theErr == eofErr) { BringUpDeletePrefsAlert(); noProblems = DeletePrefs(&prefDirID, &systemVolRef); return (false); } else if (theErr != noErr) return (false); if (thePrefs->prefVersion != versionNeed) { BringUpDeletePrefsAlert(); noProblems = DeletePrefs(&prefDirID, &systemVolRef); return(false); } return (true); } //-------------------------------------------------------------- BringUpDeletePrefsAlert void BringUpDeletePrefsAlert (void) { short whoCares; InitCursor(); // CenterAlert(kNewPrefsAlertID); whoCares = Alert(kNewPrefsAlertID, nil); } \ No newline at end of file diff --git a/Sources/RectUtils.c b/Sources/RectUtils.c deleted file mode 100755 index 0a01c0f..0000000 --- a/Sources/RectUtils.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // 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); } \ No newline at end of file diff --git a/Sources/Render.c b/Sources/Render.c deleted file mode 100755 index 422c0e1..0000000 --- a/Sources/Render.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // 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; } \ No newline at end of file diff --git a/Sources/Room.c b/Sources/Room.c deleted file mode 100755 index 4248936..0000000 --- a/Sources/Room.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Room.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Externs.h" #include "House.h" #include "MainWindow.h" #include "RectUtils.h" #define kDeleteRoomAlert 1005 #define kYesDoDeleteRoom 1 Boolean QueryDeleteRoom (void); void SetToNearestNeighborRoom (short, short); roomPtr thisRoom; Rect backSrcRect; GWorldPtr backSrcMap; short numberRooms, thisRoomNumber, previousRoom; short leftThresh, rightThresh, lastBackground; Boolean autoRoomEdit, newRoomNow, noRoomAtAll; Boolean leftOpen, rightOpen, topOpen, bottomOpen; Boolean doBitchDialogs; extern short tempTiles[]; //============================================================== Functions //-------------------------------------------------------------- SetInitialTiles #ifndef COMPILEDEMO void SetInitialTiles (short background, Boolean doRoom) { short i; if (background >= kUserBackground) { for (i = 0; i < kNumTiles; i++) { if (doRoom) thisRoom->tiles[i] = i; else tempTiles[i] = i; } } else { switch (background) { case kSimpleRoom: case kPaneledRoom: case kBasement: case kChildsRoom: case kAsianRoom: case kUnfinishedRoom: case kSwingersRoom: case kBathroom: case kLibrary: for (i = 0; i < kNumTiles; i++) { if (doRoom) thisRoom->tiles[i] = 1; else tempTiles[i] = 1; } if (doRoom) { thisRoom->tiles[0] = 0; thisRoom->tiles[kNumTiles - 1] = kNumTiles - 1; } else { tempTiles[0] = 0; tempTiles[kNumTiles - 1] = kNumTiles - 1; } break; case kSkywalk: for (i = 0; i < kNumTiles; i++) { if (doRoom) thisRoom->tiles[i] = i; else tempTiles[i] = i; } break; case kField: case kGarden: case kDirt: for (i = 0; i < kNumTiles; i++) { if (doRoom) thisRoom->tiles[i] = 0; else tempTiles[i] = 0; } break; case kMeadow: for (i = 0; i < kNumTiles; i++) { if (doRoom) thisRoom->tiles[i] = 1; else tempTiles[i] = 1; } break; case kRoof: for (i = 0; i < kNumTiles; i++) { if (doRoom) thisRoom->tiles[i] = 3; else tempTiles[i] = 3; } break; case kSky: for (i = 0; i < kNumTiles; i++) { if (doRoom) thisRoom->tiles[i] = 2; else tempTiles[i] = 2; } break; case kStratosphere: case kStars: for (i = 0; i < kNumTiles; i++) { if (doRoom) thisRoom->tiles[i] = i; else tempTiles[i] = i; } break; default: break; } } } #endif //-------------------------------------------------------------- CreateNewRoom #ifndef COMPILEDEMO Boolean CreateNewRoom (short h, short v) { KeyMap theKeys; long howMuch; OSErr theErr; short i, availableRoom; char wasState; CopyThisRoomToRoom(); // save off current room PasStringCopy("\pUntitled Room", thisRoom->name); thisRoom->leftStart = 32; // fill out fields of new room thisRoom->rightStart = 32; thisRoom->bounds = 0; thisRoom->unusedByte = 0; thisRoom->visited = false; thisRoom->background = lastBackground; SetInitialTiles(thisRoom->background, true); thisRoom->floor = v; thisRoom->suite = h; thisRoom->openings = 0; thisRoom->numObjects = 0; for (i = 0; i < kMaxRoomObs; i++) // zero out all objects thisRoom->objects[i].what = kObjectIsEmpty; wasState = HGetState((Handle)thisHouse); MoveHHi((Handle)thisHouse); HLock((Handle)thisHouse); availableRoom = -1; // assume no available rooms if ((*thisHouse)->nRooms > 0) // look for an empty room for (i = 0; i < (*thisHouse)->nRooms; i++) if ((*thisHouse)->rooms[i].suite == kRoomIsEmpty) { availableRoom = i; break; } if (availableRoom == -1) // found no available rooms { HUnlock((Handle)thisHouse); howMuch = sizeof(roomType); // add new room to end of house theErr = PtrAndHand((Ptr)thisRoom, (Handle)thisHouse, howMuch); if (theErr != noErr) { YellowAlert(kYellowUnaccounted, theErr); MoveHHi((Handle)thisHouse); HLock((Handle)thisHouse); return (false); } MoveHHi((Handle)thisHouse); HLock((Handle)thisHouse); (*thisHouse)->nRooms++; // increment nRooms numberRooms = (*thisHouse)->nRooms; previousRoom = thisRoomNumber; thisRoomNumber = numberRooms - 1; } else { previousRoom = thisRoomNumber; thisRoomNumber = availableRoom; } if (noRoomAtAll) (*thisHouse)->firstRoom = thisRoomNumber; HSetState((Handle)thisHouse, wasState); CopyThisRoomToRoom(); UpdateEditWindowTitle(); noRoomAtAll = false; fileDirty = true; UpdateMenus(false); GetKeys(theKeys); if (BitTst(&theKeys, kShiftKeyMap)) newRoomNow = false; else newRoomNow = autoRoomEdit; // Flag to bring up RoomInfo return (true); } #endif //-------------------------------------------------------------- ReadyBackground void ReadyBackground (short theID, short *theTiles) { Rect src, dest; PicHandle thePicture; short i; SetPort((GrafPtr)workSrcMap); if ((noRoomAtAll) || (!houseUnlocked)) { LtGrayForeColor(); PaintRect(&workSrcRect); ForeColor(blackColor); MoveTo(10, 20); if (houseUnlocked) DrawString("\pNo rooms"); else DrawString("\pNothing to show"); CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &workSrcRect, &workSrcRect, srcCopy, nil); return; } thePicture = GetPicture(theID); if (thePicture == nil) { thePicture = (PicHandle)GetResource('Date', theID); if (thePicture == nil) { YellowAlert(kYellowNoBackground, 0); return; } } HLock((Handle)thePicture); dest = (*thePicture)->picFrame; HUnlock((Handle)thePicture); QOffsetRect(&dest, -dest.left, -dest.top); DrawPicture(thePicture, &dest); ReleaseResource((Handle)thePicture); QSetRect(&src, 0, 0, kTileWide, kTileHigh); QSetRect(&dest, 0, 0, kTileWide, kTileHigh); for (i = 0; i < kNumTiles; i++) { src.left = theTiles[i] * kTileWide; src.right = src.left + kTileWide; CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &src, &dest, srcCopy, nil); QOffsetRect(&dest, kTileWide, 0); } QSetRect(&src, 0, 0, kRoomWide, kTileHigh); QSetRect(&dest, 0, 0, kRoomWide, kTileHigh); CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &src, &dest, srcCopy, nil); } //-------------------------------------------------------------- ReflectCurrentRoom void ReflectCurrentRoom (Boolean forceMapRedraw) { #ifndef COMPILEDEMO if (theMode != kEditMode) return; if ((noRoomAtAll) || (!houseUnlocked)) { CenterMapOnRoom(64, 1); UpdateMapWindow(); } else { if ((!ThisRoomVisibleOnMap()) || (forceMapRedraw)) { CenterMapOnRoom(thisRoom->suite, thisRoom->floor); UpdateMapWindow(); // whole map window redrawm } else { FindNewActiveRoomRect(); // find newly selected room rect FlagMapRoomsForUpdate(); // redraw only the portions required } } GenerateRetroLinks(); UpdateEditWindowTitle(); ReadyBackground(thisRoom->background, thisRoom->tiles); GetThisRoomsObjRects(); DrawThisRoomsObjects(); InvalWindowRect(mainWindow, &mainWindowRect); #endif } //-------------------------------------------------------------- CopyRoomToThisRoom void CopyRoomToThisRoom (short roomNumber) { if (roomNumber == -1) return; CopyThisRoomToRoom(); // copy back to house ForceThisRoom(roomNumber); // load new room from house } //-------------------------------------------------------------- CopyThisRoomToRoom void CopyThisRoomToRoom (void) { char tagByte; if ((noRoomAtAll) || (thisRoomNumber == -1)) return; tagByte = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); // copy back to house (*thisHouse)->rooms[thisRoomNumber] = *thisRoom; HSetState((Handle)thisHouse, tagByte); } //-------------------------------------------------------------- ForceThisRoom void ForceThisRoom (short roomNumber) { char tagByte; if (roomNumber == -1) return; tagByte = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); if (roomNumber < (*thisHouse)->nRooms) *thisRoom = (*thisHouse)->rooms[roomNumber]; else YellowAlert(kYellowIllegalRoomNum, 0); HSetState((Handle)thisHouse, tagByte); previousRoom = thisRoomNumber; thisRoomNumber = roomNumber; } //-------------------------------------------------------------- RoomExists Boolean RoomExists (short suite, short floor, short *roomNum) { // pass in a suite and floor; returns true is it is a legitimate room houseType *thisHousePtr; short i; char wasState; Boolean foundIt; foundIt = false; if (suite < 0) return (foundIt); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; for (i = 0; i < numberRooms; i++) { if ((thisHousePtr->rooms[i].floor == floor) && (thisHousePtr->rooms[i].suite == suite)) { foundIt = true; *roomNum = i; break; } } HSetState((Handle)thisHouse, wasState); return (foundIt); } //-------------------------------------------------------------- RoomNumExists Boolean RoomNumExists (short roomNum) { short floor, suite, whoCares; Boolean exists; exists = false; if (GetRoomFloorSuite(roomNum, &floor, &suite)) exists = RoomExists(suite, floor, &whoCares); return (exists); } //-------------------------------------------------------------- DeleteRoom void DeleteRoom (Boolean doWarn) { #ifndef COMPILEDEMO short wasFloor, wasSuite; char wasState; Boolean firstDeleted; if ((theMode != kEditMode) || (noRoomAtAll)) return; if (doWarn) { if (!QueryDeleteRoom()) return; } DeselectObject(); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); wasFloor = (*thisHouse)->rooms[thisRoomNumber].floor; wasSuite = (*thisHouse)->rooms[thisRoomNumber].suite; firstDeleted = ((*thisHouse)->firstRoom == thisRoomNumber); // is room "first" thisRoom->suite = kRoomIsEmpty; (*thisHouse)->rooms[thisRoomNumber].suite = kRoomIsEmpty; HSetState((Handle)thisHouse, wasState); noRoomAtAll = (RealRoomNumberCount() == 0); // see if now no rooms if (noRoomAtAll) thisRoomNumber = kRoomIsEmpty; else SetToNearestNeighborRoom(wasFloor, wasSuite); if (firstDeleted) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); (*thisHouse)->firstRoom = thisRoomNumber; HSetState((Handle)thisHouse, wasState); } newRoomNow = false; fileDirty = true; UpdateMenus(false); ReflectCurrentRoom(false); #endif } //-------------------------------------------------------------- QueryDeleteRoom #ifndef COMPILEDEMO Boolean QueryDeleteRoom (void) { short hitWhat; // CenterAlert(kDeleteRoomAlert); hitWhat = Alert(kDeleteRoomAlert, nil); if (hitWhat == kYesDoDeleteRoom) return (true); else return (false); } #endif //-------------------------------------------------------------- DoesNeighborRoomExist short DoesNeighborRoomExist (short whichNeighbor) { #ifndef COMPILEDEMO short newH, newV, newRoomNumber; if (theMode != kEditMode) return(-1); newH = thisRoom->suite; newV = thisRoom->floor; switch (whichNeighbor) { case kRoomAbove: newV++; break; case kRoomBelow: newV--; break; case kRoomToRight: newH++; break; case kRoomToLeft: newH--; break; } if (RoomExists(newH, newV, &newRoomNumber)) return (newRoomNumber); else return (-1); #endif } //-------------------------------------------------------------- SelectNeighborRoom void SelectNeighborRoom (short whichNeighbor) { #ifndef COMPILEDEMO short newRoomNumber; newRoomNumber = DoesNeighborRoomExist(whichNeighbor); if (newRoomNumber != -1) { DeselectObject(); CopyRoomToThisRoom(newRoomNumber); ReflectCurrentRoom(false); } #endif } //-------------------------------------------------------------- GetNeighborRoomNumber short GetNeighborRoomNumber (short which) { short hDelta, vDelta, i; short roomH, roomV; short roomNum; char wasState; switch (which) { case kCentralRoom: hDelta = 0; vDelta = 0; break; case kNorthRoom: hDelta = 0; vDelta = 1; break; case kNorthEastRoom: hDelta = 1; vDelta = 1; break; case kEastRoom: hDelta = 1; vDelta = 0; break; case kSouthEastRoom: hDelta = 1; vDelta = -1; break; case kSouthRoom: hDelta = 0; vDelta = -1; break; case kSouthWestRoom: hDelta = -1; vDelta = -1; break; case kWestRoom: hDelta = -1; vDelta = 0; break; case kNorthWestRoom: hDelta = -1; vDelta = 1; break; } roomNum = kRoomIsEmpty; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); roomH = (*thisHouse)->rooms[thisRoomNumber].suite + hDelta; roomV = (*thisHouse)->rooms[thisRoomNumber].floor + vDelta; for (i = 0; i < numberRooms; i++) { if (((*thisHouse)->rooms[i].suite == roomH) && ((*thisHouse)->rooms[i].floor == roomV)) { roomNum = i; break; } } HSetState((Handle)thisHouse, wasState); return (roomNum); } //-------------------------------------------------------------- SetToNearestNeighborRoom void SetToNearestNeighborRoom (short wasFloor, short wasSuite) { // searches in a clockwise spiral pattern (from thisRoom) for aÉ // legitimate neighboring room - then sets thisRoom to it short distance, h, v; short hStep, vStep; short testRoomNum, testH, testV; char wasState; Boolean finished; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); finished = false; distance = 1; // we begin our walk a distance of one from source room h = -1; // we begin with the neighbor to the leftÉ v = 0; // and on the same floor hStep = 0; // we don't 'walk' left or rightÉ vStep = -1; // instead, we 'walk' up do { testH = wasSuite + h; testV = wasFloor + v; if (RoomExists(testH, testV, &testRoomNum)) // if a legitimate room { CopyRoomToThisRoom(testRoomNum); finished = true; } else { h += hStep; v += vStep; if ((h > distance) || (h < -distance) || (v > distance) || (v < -distance)) { // we have walked beyond the bounds of our spiral if ((hStep == -1) && (vStep == 0)) // we expand our spiral out { distance++; hStep = 0; // begin travelling up again vStep = -1; } else { h -= hStep; // first, back up a step v -= vStep; if (hStep == 0) // we were travelling up or down { if (vStep == -1) // we were travelling upÉ hStep = 1; // so begin travelling right else // we were travelling downÉ hStep = -1; // so begin travelling left vStep = 0; } else { hStep = 0; // begin travelling down vStep = 1; } h += hStep; // proceed a step now v += vStep; } } } } while (!finished); HSetState((Handle)thisHouse, wasState); } //-------------------------------------------------------------- GetRoomFloorSuite Boolean GetRoomFloorSuite (short room, short *floor, short *suite) { char wasState; Boolean isRoom; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); if ((*thisHouse)->rooms[room].suite == kRoomIsEmpty) { *floor = 0; *suite = kRoomIsEmpty; isRoom = false; } else { *suite = (*thisHouse)->rooms[room].suite; *floor = (*thisHouse)->rooms[room].floor; isRoom = true; } HSetState((Handle)thisHouse, wasState); return (isRoom); } //-------------------------------------------------------------- GetRoomNumber short GetRoomNumber (short floor, short suite) { // pass in a floor and suite; returns the room index into the house file short roomNum, i; char wasState; roomNum = kRoomIsEmpty; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); for (i = 0; i < numberRooms; i++) { if (((*thisHouse)->rooms[i].suite == suite) && ((*thisHouse)->rooms[i].floor == floor)) { roomNum = i; break; } } HSetState((Handle)thisHouse, wasState); return (roomNum); } //-------------------------------------------------------------- IsRoomAStructure Boolean IsRoomAStructure (short roomNum) { char wasState; Boolean isStructure; if (roomNum == kRoomIsEmpty) return (false); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); if ((*thisHouse)->rooms[roomNum].background >= kUserBackground) { if ((*thisHouse)->rooms[roomNum].bounds != 0) { isStructure = (((*thisHouse)->rooms[roomNum].bounds & 32) == 32); } else { if ((*thisHouse)->rooms[roomNum].background < kUserStructureRange) isStructure = true; else isStructure = false; } } else { switch ((*thisHouse)->rooms[roomNum].background) { case kPaneledRoom: case kSimpleRoom: case kChildsRoom: case kAsianRoom: case kUnfinishedRoom: case kSwingersRoom: case kBathroom: case kLibrary: case kSkywalk: case kRoof: isStructure = true; break; default: isStructure = false; break; } } HSetState((Handle)thisHouse, wasState); return (isStructure); } //-------------------------------------------------------------- DetermineRoomOpenings void DetermineRoomOpenings (void) { short whichBack, leftTile, rightTile; short boundsCode; whichBack = thisRoom->background; leftTile = thisRoom->tiles[0]; rightTile = thisRoom->tiles[kNumTiles - 1]; if (whichBack >= kUserBackground) { if (thisRoom->bounds != 0) boundsCode = thisRoom->bounds >> 1; else boundsCode = GetOriginalBounding(whichBack); leftOpen = ((boundsCode & 0x0001) == 0x0001); rightOpen = ((boundsCode & 0x0004) == 0x0004); if (leftOpen) leftThresh = kNoLeftWallLimit; else leftThresh = kLeftWallLimit; if (rightOpen) rightThresh = kNoRightWallLimit; else rightThresh = kRightWallLimit; } else { switch (whichBack) { case kSimpleRoom: case kPaneledRoom: case kBasement: case kChildsRoom: case kAsianRoom: case kUnfinishedRoom: case kSwingersRoom: case kBathroom: case kLibrary: case kSky: if (leftTile == 0) leftThresh = kLeftWallLimit; else leftThresh = kNoLeftWallLimit; if (rightTile == (kNumTiles - 1)) rightThresh = kRightWallLimit; else rightThresh = kNoRightWallLimit; leftOpen = (leftTile != 0); rightOpen = (rightTile != (kNumTiles - 1)); break; case kDirt: if (leftTile == 1) leftThresh = kLeftWallLimit; else leftThresh = kNoLeftWallLimit; if (rightTile == (kNumTiles - 1)) rightThresh = kRightWallLimit; else rightThresh = kNoRightWallLimit; leftOpen = (leftTile != 0); rightOpen = (rightTile != (kNumTiles - 1)); break; case kMeadow: if (leftTile == 6) leftThresh = kLeftWallLimit; else leftThresh = kNoLeftWallLimit; if (rightTile == 7) rightThresh = kRightWallLimit; else rightThresh = kNoRightWallLimit; leftOpen = (leftTile != 6); rightOpen = (rightTile != 7); break; case kGarden: case kSkywalk: case kField: case kStratosphere: case kStars: leftThresh = kNoLeftWallLimit; rightThresh = kNoRightWallLimit; leftOpen = true; rightOpen = true; break; default: if (leftTile == 0) leftThresh = kLeftWallLimit; else leftThresh = kNoLeftWallLimit; if (rightTile == (kNumTiles - 1)) rightThresh = kRightWallLimit; else rightThresh = kNoRightWallLimit; leftOpen = (leftTile != 0); rightOpen = (rightTile != (kNumTiles - 1)); break; } } if (DoesRoomHaveFloor()) bottomOpen = false; else bottomOpen = true; if (DoesRoomHaveCeiling()) topOpen = false; else topOpen = true; } //-------------------------------------------------------------- GetOriginalBounding short GetOriginalBounding (short theID) { boundsHand boundsRes; short boundCode; boundsRes = (boundsHand)GetResource('bnds', theID); if (boundsRes == nil) { if (PictIDExists(theID)) YellowAlert(kYellowNoBoundsRes, 0); boundCode = 0; } else { boundCode = 0; HLock((Handle)boundsRes); if ((*boundsRes)->left) boundCode += 1; if ((*boundsRes)->top) boundCode += 2; if ((*boundsRes)->right) boundCode += 4; if ((*boundsRes)->bottom) boundCode += 8; HUnlock((Handle)boundsRes); ReleaseResource((Handle)boundsRes); } return (boundCode); } //-------------------------------------------------------------- GetNumberOfLights short GetNumberOfLights (short where) { houseType *thisHousePtr; short i, count; char wasState; if (theMode == kEditMode) { switch (thisRoom->background) { case kGarden: case kSkywalk: case kMeadow: case kField: case kRoof: case kSky: case kStratosphere: case kStars: count = 1; break; case kDirt: count = 0; if ((thisRoom->tiles[0] == 0) && (thisRoom->tiles[1] == 0) && (thisRoom->tiles[2] == 0) && (thisRoom->tiles[3] == 0) && (thisRoom->tiles[4] == 0) && (thisRoom->tiles[5] == 0) && (thisRoom->tiles[6] == 0) && (thisRoom->tiles[7] == 0)) count = 1; break; default: count = 0; break; } if (count == 0) { for (i = 0; i < kMaxRoomObs; i++) { switch (thisRoom->objects[i].what) { case kDoorInLf: case kDoorInRt: case kWindowInLf: case kWindowInRt: case kWallWindow: count++; break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: if (thisRoom->objects[i].data.f.initial) count++; break; } } } } else { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; switch (thisHousePtr->rooms[where].background) { case kGarden: case kSkywalk: case kMeadow: case kField: case kRoof: case kSky: case kStratosphere: case kStars: count = 1; break; case kDirt: count = 0; if ((thisHousePtr->rooms[where].tiles[0] == 0) && (thisHousePtr->rooms[where].tiles[1] == 0) && (thisHousePtr->rooms[where].tiles[2] == 0) && (thisHousePtr->rooms[where].tiles[3] == 0) && (thisHousePtr->rooms[where].tiles[4] == 0) && (thisHousePtr->rooms[where].tiles[5] == 0) && (thisHousePtr->rooms[where].tiles[6] == 0) && (thisHousePtr->rooms[where].tiles[7] == 0)) count = 1; break; default: count = 0; break; } if (count == 0) { for (i = 0; i < kMaxRoomObs; i++) { switch (thisHousePtr->rooms[where].objects[i].what) { case kDoorInLf: case kDoorInRt: case kWindowInLf: case kWindowInRt: case kWallWindow: count++; break; case kCeilingLight: case kLightBulb: case kTableLamp: case kHipLamp: case kDecoLamp: case kFlourescent: case kTrackLight: case kInvisLight: if (thisHousePtr->rooms[where].objects[i].data.f.state) count++; break; } } } HSetState((Handle)thisHouse, wasState); } return (count); } //-------------------------------------------------------------- IsShadowVisible Boolean IsShadowVisible (void) { short boundsCode; Boolean hasFloor; if (thisRoom->background >= kUserBackground) { if (thisRoom->bounds != 0) // is this a version 2.0 house? boundsCode = (thisRoom->bounds >> 1); else boundsCode = GetOriginalBounding(thisRoom->background); hasFloor = ((boundsCode & 0x0008) != 0x0008); } else { switch (thisRoom->background) { case kRoof: case kSky: case kStratosphere: case kStars: hasFloor = false; break; default: hasFloor = true; break; } } return (hasFloor); } //-------------------------------------------------------------- DoesRoomHaveFloor Boolean DoesRoomHaveFloor (void) { short boundsCode; Boolean hasFloor; if (thisRoom->background >= kUserBackground) { if (thisRoom->bounds != 0) // is this a version 2.0 house? boundsCode = (thisRoom->bounds >> 1); else boundsCode = GetOriginalBounding(thisRoom->background); hasFloor = ((boundsCode & 0x0008) != 0x0008); } else { switch (thisRoom->background) { case kSky: case kStratosphere: case kStars: hasFloor = false; break; default: hasFloor = true; break; } } return (hasFloor); } //-------------------------------------------------------------- DoesRoomHaveCeiling Boolean DoesRoomHaveCeiling (void) { short boundsCode; Boolean hasCeiling; if (thisRoom->background >= kUserBackground) { if (thisRoom->bounds != 0) // is this a version 2.0 house? boundsCode = (thisRoom->bounds >> 1); else boundsCode = GetOriginalBounding(thisRoom->background); hasCeiling = ((boundsCode & 0x0002) != 0x0002); } else { switch (thisRoom->background) { case kGarden: case kMeadow: case kField: case kRoof: case kSky: case kStratosphere: case kStars: hasCeiling = false; break; default: hasCeiling = true; break; } } return (hasCeiling); } \ No newline at end of file diff --git a/Sources/RoomGraphics.c b/Sources/RoomGraphics.c deleted file mode 100755 index e1de36b..0000000 --- a/Sources/RoomGraphics.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // RoomGraphics.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "Environ.h" #include "MainWindow.h" #include "RectUtils.h" #include "Room.h" #define kManholeThruFloor 3957 void LoadGraphicSpecial (short); void DrawRoomBackground (short, short, short); void DrawFloorSupport (void); void ReadyBackMap (void); void RestoreWorkMap (void); void DrawLighting (void); Rect suppSrcRect; GWorldPtr suppSrcMap; Rect localRoomsDest[9]; Rect houseRect; short numNeighbors, numLights, thisTiles[kNumTiles]; short localNumbers[9], thisBackground; Boolean isStructure[9], wardBitSet; extern CGrafPtr savedMaps[]; extern Rect tempManholes[]; extern short numTempManholes, tvWithMovieNumber; extern Boolean shadowVisible, takingTheStairs; //============================================================== Functions //-------------------------------------------------------------- DrawLocale void DrawLocale (void) { short i, roomV; char wasState; CGrafPtr wasCPort; GDHandle wasWorld; ZeroFlamesAndTheLike(); ZeroDinahs(); KillAllBands(); ZeroMirrorRegion(); ZeroTriggers(); numTempManholes = 0; FlushAnyTriggerPlaying(); DumpTriggerSound(); tvInRoom = false; tvWithMovieNumber = -1; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); roomV = (*thisHouse)->rooms[thisRoomNumber].floor; HSetState((Handle)thisHouse, wasState); for (i = 0; i < 9; i++) { localNumbers[i] = GetNeighborRoomNumber(i); isStructure[i] = IsRoomAStructure(localNumbers[i]); } ListAllLocalObjects(); GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); PaintRect(&backSrcRect); if (numNeighbors > 3) { numLights = GetNumberOfLights(localNumbers[kNorthWestRoom]); DrawRoomBackground(localNumbers[kNorthWestRoom], kNorthWestRoom, roomV + 1); DrawARoomsObjects(kNorthWestRoom, false); numLights = GetNumberOfLights(localNumbers[kNorthEastRoom]); DrawRoomBackground(localNumbers[kNorthEastRoom], kNorthEastRoom, roomV + 1); DrawARoomsObjects(kNorthEastRoom, false); numLights = GetNumberOfLights(localNumbers[kNorthRoom]); DrawRoomBackground(localNumbers[kNorthRoom], kNorthRoom, roomV + 1); DrawARoomsObjects(kNorthRoom, false); numLights = GetNumberOfLights(localNumbers[kSouthWestRoom]); DrawRoomBackground(localNumbers[kSouthWestRoom], kSouthWestRoom, roomV - 1); DrawARoomsObjects(kSouthWestRoom, false); numLights = GetNumberOfLights(localNumbers[kSouthEastRoom]); DrawRoomBackground(localNumbers[kSouthEastRoom], kSouthEastRoom, roomV - 1); DrawARoomsObjects(kSouthEastRoom, false); numLights = GetNumberOfLights(localNumbers[kSouthRoom]); DrawRoomBackground(localNumbers[kSouthRoom], kSouthRoom, roomV - 1); DrawARoomsObjects(kSouthRoom, false); } if (numNeighbors > 1) { numLights = GetNumberOfLights(localNumbers[kWestRoom]); DrawRoomBackground(localNumbers[kWestRoom], kWestRoom, roomV); DrawARoomsObjects(kWestRoom, false); DrawLighting(); numLights = GetNumberOfLights(localNumbers[kEastRoom]); DrawRoomBackground(localNumbers[kEastRoom], kEastRoom, roomV); DrawARoomsObjects(kEastRoom, false); DrawLighting(); } numLights = GetNumberOfLights(localNumbers[kCentralRoom]); DrawRoomBackground(localNumbers[kCentralRoom], kCentralRoom, roomV); DrawARoomsObjects(kCentralRoom, false); DrawLighting(); if (numNeighbors > 3) DrawFloorSupport(); RestoreWorkMap(); shadowVisible = IsShadowVisible(); takingTheStairs = false; SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- LoadGraphicSpecial void LoadGraphicSpecial (short resID) { Rect bounds; PicHandle thePicture; thePicture = GetPicture(resID); if (thePicture == nil) { thePicture = (PicHandle)GetResource('Date', resID); if (thePicture == nil) { thePicture = GetPicture(2000); if (thePicture == nil) RedAlert(kErrFailedGraphicLoad); } } HLock((Handle)thePicture); bounds = (*thePicture)->picFrame; HUnlock((Handle)thePicture); OffsetRect(&bounds, -bounds.left, -bounds.top); DrawPicture(thePicture, &bounds); ReleaseResource((Handle)thePicture); } //-------------------------------------------------------------- DrawRoomBackground void DrawRoomBackground (short who, short where, short elevation) { Rect src, dest; short i, pictID; short tiles[kNumTiles]; char wasState; if (where == kCentralRoom) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisBackground = (*thisHouse)->rooms[who].background; for (i = 0; i < kNumTiles; i++) thisTiles[i] = (*thisHouse)->rooms[who].tiles[i]; HSetState((Handle)thisHouse, wasState); } if ((numLights == 0) && (who != kRoomIsEmpty)) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); PaintRect(&localRoomsDest[where]); SetGWorld(wasCPort, wasWorld); return; } if (who == kRoomIsEmpty) // This call should be smarter than this { if (wardBitSet) { CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); PaintRect(&localRoomsDest[where]); SetGWorld(wasCPort, wasWorld); return; } if (elevation > 1) { pictID = kSky; for (i = 0; i < kNumTiles; i++) tiles[i] = 2; } else if (elevation == 1) { pictID = kMeadow; for (i = 0; i < kNumTiles; i++) tiles[i] = 0; } else { pictID = kDirt; for (i = 0; i < kNumTiles; i++) tiles[i] = 0; } } else { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); pictID = (*thisHouse)->rooms[who].background; for (i = 0; i < kNumTiles; i++) tiles[i] = (*thisHouse)->rooms[who].tiles[i]; HSetState((Handle)thisHouse, wasState); } SetPort((GrafPtr)workSrcMap); LoadGraphicSpecial(pictID); QSetRect(&src, 0, 0, kTileWide, kTileHigh); QSetRect(&dest, 0, 0, kTileWide, kTileHigh); QOffsetRect(&dest, localRoomsDest[where].left, localRoomsDest[where].top); for (i = 0; i < kNumTiles; i++) { src.left = tiles[i] * kTileWide; src.right = src.left + kTileWide; CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &src, &dest, srcCopy, nil); QOffsetRect(&dest, kTileWide, 0); } } //-------------------------------------------------------------- DrawFloorSupport void DrawFloorSupport (void) { Rect src, dest, whoCares; short i; CGrafPtr wasCPort; GDHandle wasWorld; GetGWorld(&wasCPort, &wasWorld); SetGWorld(backSrcMap, nil); src = suppSrcRect; if (isStructure[kNorthWestRoom]) { dest = suppSrcRect; // left room's ceiling QOffsetRect(&dest, localRoomsDest[kWestRoom].left, localRoomsDest[kCentralRoom].top - suppSrcRect.bottom); CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &src, &dest, srcCopy, nil); for (i = 0; i < numTempManholes; i++) if (SectRect(&dest, &tempManholes[i], &whoCares)) { tempManholes[i].top = dest.top; tempManholes[i].bottom = dest.bottom; LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); } } if (isStructure[kWestRoom]) { dest = suppSrcRect; // left room's floor QOffsetRect(&dest, localRoomsDest[kWestRoom].left, localRoomsDest[kCentralRoom].bottom); CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &src, &dest, srcCopy, nil); for (i = 0; i < numTempManholes; i++) if (SectRect(&dest, &tempManholes[i], &whoCares)) { tempManholes[i].top = dest.top; tempManholes[i].bottom = dest.bottom; LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); } } if (isStructure[kNorthRoom]) { dest = suppSrcRect; // directly above main room QOffsetRect(&dest, localRoomsDest[kCentralRoom].left, localRoomsDest[kCentralRoom].top - suppSrcRect.bottom); CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &src, &dest, srcCopy, nil); for (i = 0; i < numTempManholes; i++) if (SectRect(&dest, &tempManholes[i], &whoCares)) { tempManholes[i].top = dest.top; tempManholes[i].bottom = dest.bottom; LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); } } if (isStructure[kCentralRoom]) { dest = suppSrcRect; // directly below main room QOffsetRect(&dest, localRoomsDest[kCentralRoom].left, localRoomsDest[kCentralRoom].bottom); CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &src, &dest, srcCopy, nil); for (i = 0; i < numTempManholes; i++) if (SectRect(&dest, &tempManholes[i], &whoCares)) { tempManholes[i].top = dest.top; tempManholes[i].bottom = dest.bottom; LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); } } if (isStructure[kNorthEastRoom]) { dest = suppSrcRect; QOffsetRect(&dest, localRoomsDest[kEastRoom].left, localRoomsDest[kCentralRoom].top - suppSrcRect.bottom); CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &src, &dest, srcCopy, nil); for (i = 0; i < numTempManholes; i++) if (SectRect(&dest, &tempManholes[i], &whoCares)) { tempManholes[i].top = dest.top; tempManholes[i].bottom = dest.bottom; LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); } } if (isStructure[kEastRoom]) { dest = suppSrcRect; QOffsetRect(&dest, localRoomsDest[kEastRoom].left, localRoomsDest[kCentralRoom].bottom); CopyBits((BitMap *)*GetGWorldPixMap(suppSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &src, &dest, srcCopy, nil); for (i = 0; i < numTempManholes; i++) if (SectRect(&dest, &tempManholes[i], &whoCares)) { tempManholes[i].top = dest.top; tempManholes[i].bottom = dest.bottom; LoadScaledGraphic(kManholeThruFloor, &tempManholes[i]); } } SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- ReadyBackMap void ReadyBackMap (void) { CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), (BitMap *)*GetGWorldPixMap(backSrcMap), &workSrcRect, &workSrcRect, srcCopy, nil); } //-------------------------------------------------------------- RestoreWorkMap void RestoreWorkMap (void) { Rect dest; dest = backSrcRect; CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), (BitMap *)*GetGWorldPixMap(workSrcMap), &backSrcRect, &backSrcRect, srcCopy, nil); } //-------------------------------------------------------------- ReadyLevel void ReadyLevel (void) { NilSavedMaps(); #ifdef COMPILEQT if ((thisMac.hasQT) && (hasMovie) && (tvInRoom)) { tvInRoom = false; tvWithMovieNumber = -1; StopMovie(theMovie); } #endif DetermineRoomOpenings(); DrawLocale(); InitGarbageRects(); } //-------------------------------------------------------------- DrawLighting void DrawLighting (void) { if (numLights == 0) return; else { // for future construction } } //-------------------------------------------------------------- RedrawRoomLighting void RedrawRoomLighting (void) { short roomV; char wasState; Boolean wasLit, isLit; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); roomV = (*thisHouse)->rooms[thisRoomNumber].floor; HSetState((Handle)thisHouse, wasState); wasLit = numLights > 0; numLights = GetNumberOfLights(localNumbers[kCentralRoom]); isLit = numLights > 0; if (wasLit != isLit) { DrawRoomBackground(localNumbers[kCentralRoom], kCentralRoom, roomV); DrawARoomsObjects(kCentralRoom, true); DrawLighting(); UpdateOutletsLighting(localNumbers[kCentralRoom], numLights); if (numNeighbors > 3) DrawFloorSupport(); RestoreWorkMap(); AddRectToWorkRects(&localRoomsDest[kCentralRoom]); shadowVisible = IsShadowVisible(); } } \ No newline at end of file diff --git a/Sources/RoomInfo.c b/Sources/RoomInfo.c deleted file mode 100755 index ee736de..0000000 --- a/Sources/RoomInfo.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // RoomInfo.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include "DialogUtils.h" #include "Externs.h" #include "RectUtils.h" #include "Utilities.h" #define kRoomInfoDialogID 1003 #define kOriginalArtDialogID 1016 #define kNoPICTFoundAlert 1036 #define kRoomNameItem 3 #define kRoomLocationBox 6 #define kRoomTilesBox 10 #define kRoomPopupItem 11 #define kRoomDividerLine 12 #define kRoomTilesBox2 15 #define kRoomFirstCheck 17 #define kLitUnlitText 18 #define kMiniTileWide 16 #define kBoundsButton 19 #define kOriginalArtworkItem 19 #define kPICTIDItem 5 #define kFloorSupportCheck 12 void UpdateRoomInfoDialog (DialogPtr); void DragMiniTile (Point, short *); void HiliteTileOver (Point); pascal Boolean RoomFilter (DialogPtr, EventRecord *, short *); short ChooseOriginalArt (short); void UpdateOriginalArt (DialogPtr); pascal Boolean OriginalArtFilter (DialogPtr, EventRecord *, short *); Boolean PictIDExists (short); short GetFirstPICT (void); void BitchAboutPICTNotFound (void); Rect tileSrc, tileDest, tileSrcRect, editTETextBox; Rect leftBound, topBound, rightBound, bottomBound; CGrafPtr tileSrcMap; short tempTiles[kNumTiles]; short tileOver, tempBack, cursorIs; Boolean originalLeftOpen, originalTopOpen, originalRightOpen, originalBottomOpen; Boolean originalFloor; extern Cursor handCursor, beamCursor; extern short houseResFork, lastBackground; //============================================================== Functions //-------------------------------------------------------------- UpdateRoomInfoDialog #ifndef COMPILEDEMO void UpdateRoomInfoDialog (DialogPtr theDialog) { Rect src, dest; short i; DrawDialog(theDialog); if (tempBack >= kUserBackground) SetPopUpMenuValue(theDialog, kRoomPopupItem, kOriginalArtworkItem); else SetPopUpMenuValue(theDialog, kRoomPopupItem, (tempBack - kBaseBackgroundID) + 1); CopyBits(GetPortBitMapForCopyBits(tileSrcMap), GetPortBitMapForCopyBits(GetDialogPort(theDialog)), &tileSrcRect, &tileSrc, srcCopy, nil); /* CopyBits(&((GrafPtr)tileSrcMap)->portBits, &(((GrafPtr)theDialog)->portBits), &tileSrcRect, &tileSrc, srcCopy, nil); */ dest = tileDest; dest.right = dest.left + kMiniTileWide; for (i = 0; i < kNumTiles; i++) { QSetRect(&src, 0, 0, kMiniTileWide, 80); QOffsetRect(&src, tempTiles[i] * kMiniTileWide, 0); CopyBits(GetPortBitMapForCopyBits(tileSrcMap), GetPortBitMapForCopyBits(GetDialogPort(theDialog)), &src, &dest, srcCopy, nil); /* CopyBits(&((GrafPtr)tileSrcMap)->portBits, &(((GrafPtr)theDialog)->portBits), &src, &dest, srcCopy, nil); */ QOffsetRect(&dest, kMiniTileWide, 0); } if (GetNumberOfLights(thisRoomNumber) == 0) SetDialogString(theDialog, kLitUnlitText, "\p(Room Is Dark)"); else SetDialogString(theDialog, kLitUnlitText, "\p(Room Is Lit)"); FrameDialogItemC(theDialog, kRoomLocationBox, kRedOrangeColor8); FrameDialogItem(theDialog, kRoomTilesBox); FrameDialogItemC(theDialog, kRoomDividerLine, kRedOrangeColor8); FrameDialogItem(theDialog, kRoomTilesBox2); } #endif //-------------------------------------------------------------- DragMiniTile #ifndef COMPILEDEMO void DragMiniTile (Point mouseIs, short *newTileOver) { Rect dragRect; Point mouseWas; short wasTileOver; Pattern dummyPattern; tileOver = (mouseIs.h - tileSrc.left) / kMiniTileWide; wasTileOver = -1; QSetRect(&dragRect, 0, 0, kMiniTileWide, 80); QOffsetRect(&dragRect, tileSrc.left + (tileOver * kMiniTileWide), tileSrc.top); PenMode(patXor); PenPat(GetQDGlobalsGray(&dummyPattern)); FrameRect(&dragRect); mouseWas = mouseIs; while (WaitMouseUp()) // loop until mouse button let up { GetMouse(&mouseIs); // get mouse coords if (DeltaPoint(mouseWas, mouseIs) != 0L) // the mouse has moved { FrameRect(&dragRect); QOffsetRect(&dragRect, mouseIs.h - mouseWas.h, 0); FrameRect(&dragRect); if (PtInRect(mouseIs, &tileDest)) // is cursor in the drop rect { *newTileOver = (mouseIs.h - tileDest.left) / kMiniTileWide; if (*newTileOver != wasTileOver) { PenNormal(); PenSize(1, 2); ForeColor(blueColor); MoveTo(tileDest.left + (*newTileOver * kMiniTileWide), tileDest.top - 3); Line(kMiniTileWide, 0); MoveTo(tileDest.left + (*newTileOver * kMiniTileWide), tileDest.bottom + 1); Line(kMiniTileWide, 0); if (wasTileOver != -1) { ForeColor(whiteColor); MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), tileDest.top - 3); Line(kMiniTileWide, 0); MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), tileDest.bottom + 1); Line(kMiniTileWide, 0); } ForeColor(blackColor); PenNormal(); PenMode(patXor); PenPat(GetQDGlobalsGray(&dummyPattern)); wasTileOver = *newTileOver; } } else { *newTileOver = -1; // we're not in the drop zone if (wasTileOver != -1) { PenNormal(); PenSize(1, 2); ForeColor(whiteColor); MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), tileDest.top - 3); Line(kMiniTileWide, 0); MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), tileDest.bottom + 1); Line(kMiniTileWide, 0); ForeColor(blackColor); PenNormal(); PenMode(patXor); PenPat(GetQDGlobalsGray(&dummyPattern)); wasTileOver = -1; } } mouseWas = mouseIs; } } if (wasTileOver != -1) { PenNormal(); PenSize(1, 2); ForeColor(whiteColor); MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), tileDest.top - 3); Line(kMiniTileWide, 0); MoveTo(tileDest.left + (wasTileOver * kMiniTileWide), tileDest.bottom + 1); Line(kMiniTileWide, 0); ForeColor(blackColor); PenNormal(); PenMode(patXor); PenPat(GetQDGlobalsGray(&dummyPattern)); wasTileOver = -1; } FrameRect(&dragRect); PenNormal(); } #endif //-------------------------------------------------------------- HiliteTileOver #ifndef COMPILEDEMO void HiliteTileOver (Point mouseIs) { short newTileOver; if (PtInRect(mouseIs, &tileSrc)) { if (cursorIs != kHandCursor) { SetCursor(&handCursor); cursorIs = kHandCursor; } newTileOver = (mouseIs.h - tileSrc.left) / kMiniTileWide; if (newTileOver != tileOver) { PenSize(1, 2); ForeColor(redColor); MoveTo(tileSrc.left + (newTileOver * kMiniTileWide), tileSrc.top - 3); Line(kMiniTileWide, 0); MoveTo(tileSrc.left + (newTileOver * kMiniTileWide), tileSrc.bottom + 1); Line(kMiniTileWide, 0); if (tileOver != -1) { ForeColor(whiteColor); MoveTo(tileSrc.left + (tileOver * kMiniTileWide), tileSrc.top - 3); Line(kMiniTileWide, 0); MoveTo(tileSrc.left + (tileOver * kMiniTileWide), tileSrc.bottom + 1); Line(kMiniTileWide, 0); } ForeColor(blackColor); PenNormal(); tileOver = newTileOver; } } else { if (tileOver != -1) { PenSize(1, 2); ForeColor(whiteColor); MoveTo(tileSrc.left + (tileOver * kMiniTileWide), tileSrc.top - 3); Line(kMiniTileWide, 0); MoveTo(tileSrc.left + (tileOver * kMiniTileWide), tileSrc.bottom + 1); Line(kMiniTileWide, 0); ForeColor(blackColor); PenNormal(); tileOver = -1; } if (PtInRect(mouseIs, &editTETextBox)) { if (cursorIs != kBeamCursor) { SetCursor(&beamCursor); cursorIs = kBeamCursor; } } else { if (cursorIs != kArrowCursor) { InitCursor(); cursorIs = kArrowCursor; } } } } #endif //-------------------------------------------------------------- RoomFilter #ifndef COMPILEDEMO pascal Boolean RoomFilter (DialogPtr dial, EventRecord *event, short *item) { Point mouseIs; short newTileOver; switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; case kTabKeyASCII: SelectDialogItemText(dial, kRoomNameItem, 0, 1024); return(true); break; default: return(false); } break; case mouseDown: mouseIs = event->where; GlobalToLocal(&mouseIs); if (PtInRect(mouseIs, &tileSrc)) { if (StillDown()) { DragMiniTile(mouseIs, &newTileOver); if ((newTileOver >= 0) && (newTileOver < kNumTiles)) { tempTiles[newTileOver] = tileOver; UpdateRoomInfoDialog(dial); } } return(true); } else return(false); break; case mouseUp: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateRoomInfoDialog(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: GetMouse(&mouseIs); HiliteTileOver(mouseIs); return(false); break; } } #endif //-------------------------------------------------------------- DoRoomInfo void DoRoomInfo (void) { #ifndef COMPILEDEMO #define kBackgroundsMenuID 140 DialogPtr roomInfoDialog; MenuHandle backgroundsMenu; Str255 floorStr, suiteStr, objectsStr, tempStr; short item, i, newBack; char wasState; Boolean leaving, wasFirstRoom, forceDraw; ModalFilterUPP roomFilterUPP; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); roomFilterUPP = NewModalFilterUPP(RoomFilter); tileOver = -1; cursorIs = kArrowCursor; tempBack = thisRoom->background; backgroundsMenu = GetMenu(kBackgroundsMenuID); // SetMenuItemTextStyle(backgroundsMenu, kOriginalArtworkItem, italic); if (HouseHasOriginalPicts()) EnableMenuItem(backgroundsMenu, kOriginalArtworkItem); NumToString(thisRoom->floor, floorStr); NumToString(thisRoom->suite, suiteStr); NumToString(thisRoom->numObjects, objectsStr); ParamText(floorStr, suiteStr, objectsStr, "\p"); theErr = CreateOffScreenGWorld(&tileSrcMap, &tileSrcRect, kPreferredDepth); SetGWorld(tileSrcMap, nil); // CreateOffScreenPixMap(&tileSrcRect, &tileSrcMap); // SetPort((GrafPtr)tileSrcMap); if ((tempBack > kStars) && (!PictIDExists(tempBack))) { BitchAboutPICTNotFound(); tempBack = kSimpleRoom; } if ((tempBack == 2002) || (tempBack == 2011) || (tempBack == 2016) || (tempBack == 2017)) LoadScaledGraphic(tempBack - 800, &tileSrcRect); else LoadScaledGraphic(tempBack, &tileSrcRect); SetGWorld(wasCPort, wasWorld); for (i = 0; i < kNumTiles; i++) tempTiles[i] = thisRoom->tiles[i]; // CenterDialog(kRoomInfoDialogID); roomInfoDialog = GetNewDialog(kRoomInfoDialogID, nil, kPutInFront); if (roomInfoDialog == nil) RedAlert(kErrDialogDidntLoad); SetPort((GrafPtr)roomInfoDialog); // Fix this later. TEMP // AddMenuToPopUp(roomInfoDialog, kRoomPopupItem, backgroundsMenu); if (tempBack >= kUserBackground) SetPopUpMenuValue(roomInfoDialog, kRoomPopupItem, kOriginalArtworkItem); else SetPopUpMenuValue(roomInfoDialog, kRoomPopupItem, (tempBack - kBaseBackgroundID) + 1); SetDialogString(roomInfoDialog, kRoomNameItem, thisRoom->name); GetDialogItemRect(roomInfoDialog, kRoomTilesBox, &tileSrc); GetDialogItemRect(roomInfoDialog, kRoomTilesBox2, &tileDest); GetDialogItemRect(roomInfoDialog, kRoomNameItem, &editTETextBox); SelectDialogItemText(roomInfoDialog, kRoomNameItem, 0, 1024); ShowWindow(GetDialogWindow(roomInfoDialog)); DrawDefaultButton(roomInfoDialog); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); wasFirstRoom = ((*thisHouse)->firstRoom == thisRoomNumber); HSetState((Handle)thisHouse, wasState); SetDialogItemValue(roomInfoDialog, kRoomFirstCheck, (short)wasFirstRoom); if (tempBack >= kUserBackground) MyEnableControl(roomInfoDialog, kBoundsButton); else MyDisableControl(roomInfoDialog, kBoundsButton); leaving = false; while (!leaving) { ModalDialog(roomFilterUPP, &item); if (item == kOkayButton) { for (i = 0; i < kNumTiles; i++) thisRoom->tiles[i] = tempTiles[i]; GetDialogString(roomInfoDialog, kRoomNameItem, tempStr); PasStringCopyNum(tempStr, thisRoom->name, 27); if (wasFirstRoom) { HLock((Handle)thisHouse); (*thisHouse)->firstRoom = thisRoomNumber; HUnlock((Handle)thisHouse); } thisRoom->background = tempBack; if (tempBack < kUserBackground) lastBackground = tempBack; CopyThisRoomToRoom(); ReflectCurrentRoom(false); fileDirty = true; UpdateMenus(false); leaving = true; } else if (item == kCancelButton) { leaving = true; } else if (item == kRoomFirstCheck) { wasFirstRoom = !wasFirstRoom; SetDialogItemValue(roomInfoDialog, kRoomFirstCheck, (short)wasFirstRoom); } else if (item == kRoomPopupItem) { GetPopUpMenuValue(roomInfoDialog, kRoomPopupItem, &newBack); if (newBack == kOriginalArtworkItem) // original art item selected? { if (tempBack < kUserBackground) // was previous bg built-in? { tempBack = GetFirstPICT(); // then assign 1st PICT forceDraw = true; } else forceDraw = false; newBack = ChooseOriginalArt(tempBack); // bring up dialog if ((tempBack != newBack) || (forceDraw)) { tempBack = newBack; SetPort((GrafPtr)tileSrcMap); LoadScaledGraphic(tempBack, &tileSrcRect); InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileSrc); InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileDest); } } else { newBack += (kBaseBackgroundID - 1); // adjust to get real PICT ID if (newBack != tempBack) // if background has changed SetInitialTiles(newBack, false); } if (newBack >= kUserBackground) { MyEnableControl(roomInfoDialog, kBoundsButton); if (newBack != tempBack) // if background has changed SetInitialTiles(newBack, false); } else MyDisableControl(roomInfoDialog, kBoundsButton); if (newBack != tempBack) { tempBack = newBack; SetPort((GrafPtr)tileSrcMap); if ((tempBack == 2002) || (tempBack == 2011) || (tempBack == 2016) || (tempBack == 2017)) LoadScaledGraphic(tempBack - 800, &tileSrcRect); else LoadScaledGraphic(tempBack, &tileSrcRect); InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileSrc); InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileDest); } } else if (item == kBoundsButton) { newBack = ChooseOriginalArt(tempBack); if (tempBack != newBack) { tempBack = newBack; SetPort((GrafPtr)tileSrcMap); LoadScaledGraphic(tempBack, &tileSrcRect); InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileSrc); InvalWindowRect(GetDialogWindow(roomInfoDialog), &tileDest); } } } InitCursor(); DisposeDialog(roomInfoDialog); DisposeModalFilterUPP(roomFilterUPP); // KillOffScreenPixMap(tileSrcMap); DisposeGWorld(tileSrcMap); tileSrcMap = nil; #endif } //-------------------------------------------------------------- UpdateOriginalArt #ifndef COMPILEDEMO void UpdateOriginalArt (DialogPtr theDialog) { Pattern dummyPattern; DrawDialog(theDialog); DrawDefaultButton(theDialog); PenSize(2, 1); if (!originalLeftOpen) BorderDialogItem(theDialog, 7, 8); else { PenPat(GetQDGlobalsGray(&dummyPattern)); BorderDialogItem(theDialog, 7, 8); PenPat(GetQDGlobalsBlack(&dummyPattern)); } PenSize(1, 2); if (!originalTopOpen) BorderDialogItem(theDialog, 8, 4); else { PenPat(GetQDGlobalsGray(&dummyPattern)); BorderDialogItem(theDialog, 8, 4); PenPat(GetQDGlobalsBlack(&dummyPattern)); } PenSize(2, 1); if (!originalRightOpen) BorderDialogItem(theDialog, 9, 1); else { PenPat(GetQDGlobalsGray(&dummyPattern)); BorderDialogItem(theDialog, 9, 1); PenPat(GetQDGlobalsBlack(&dummyPattern)); } PenSize(1, 2); if (!originalBottomOpen) BorderDialogItem(theDialog, 10, 2); else { PenPat(GetQDGlobalsGray(&dummyPattern)); BorderDialogItem(theDialog, 10, 2); PenPat(GetQDGlobalsBlack(&dummyPattern)); } PenSize(1, 1); } #endif //-------------------------------------------------------------- OriginalArtFilter #ifndef COMPILEDEMO pascal Boolean OriginalArtFilter (DialogPtr dial, EventRecord *event, short *item) { Point mouseIs; switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; case kTabKeyASCII: SelectDialogItemText(dial, kPICTIDItem, 0, 1024); return(true); break; default: return(false); } break; case mouseDown: mouseIs = event->where; GlobalToLocal(&mouseIs); if (PtInRect(mouseIs, &leftBound)) { *item = 7; return(true); } else if (PtInRect(mouseIs, &topBound)) { *item = 8; return(true); } else if (PtInRect(mouseIs, &rightBound)) { *item = 9; return(true); } else if (PtInRect(mouseIs, &bottomBound)) { *item = 10; return(true); } else return(false); break; case mouseUp: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateOriginalArt(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } #endif //-------------------------------------------------------------- ChooseOriginalArt #ifndef COMPILEDEMO short ChooseOriginalArt (short was) { DialogPtr theDialog; long longID; short item, newPictID, tempShort, wasPictID; Boolean leaving; ModalFilterUPP originalArtFilterUPP; originalArtFilterUPP = NewModalFilterUPP(OriginalArtFilter); if (was < kUserBackground) was = kUserBackground; InitCursor(); BringUpDialog(&theDialog, kOriginalArtDialogID); if (was >= kOriginalArtworkItem) { newPictID = was; wasPictID = was; } else { newPictID = kUserBackground; wasPictID = 0; } SetDialogNumToStr(theDialog, kPICTIDItem, (long)newPictID); SelectDialogItemText(theDialog, kPICTIDItem, 0, 16); GetDialogItemRect(theDialog, 7, &leftBound); GetDialogItemRect(theDialog, 8, &topBound); GetDialogItemRect(theDialog, 9, &rightBound); GetDialogItemRect(theDialog, 10, &bottomBound); tempShort = thisRoom->bounds >> 1; // version 2.0 house originalLeftOpen = ((tempShort & 1) == 1); originalTopOpen = ((tempShort & 2) == 2); originalRightOpen = ((tempShort & 4) == 4); originalBottomOpen = ((tempShort & 8) == 8); originalFloor = ((tempShort & 16) == 16); SetDialogItemValue(theDialog, kFloorSupportCheck, (short)originalFloor); leaving = false; while (!leaving) { ModalDialog(originalArtFilterUPP, &item); if (item == kOkayButton) { GetDialogNumFromStr(theDialog, kPICTIDItem, &longID); if ((longID >= 3000) && (longID < 3800) && (PictIDExists((short)longID))) { newPictID = (short)longID; if (newPictID != wasPictID) SetInitialTiles(tempBack, false); tempShort = 0; if (originalLeftOpen) tempShort += 1; if (originalTopOpen) tempShort += 2; if (originalRightOpen) tempShort += 4; if (originalBottomOpen) tempShort += 8; if (originalFloor) tempShort += 16; tempShort = tempShort << 1; // shift left 1 bit tempShort += 1; // flag that says orginal bounds used thisRoom->bounds = tempShort; leaving = true; } else { SysBeep(1); SetDialogNumToStr(theDialog, kPICTIDItem, (long)newPictID); } } else if (item == kCancelButton) { newPictID = was; leaving = true; } else if (item == 7) { originalLeftOpen = !originalLeftOpen; UpdateOriginalArt(theDialog); } else if (item == 8) { originalTopOpen = !originalTopOpen; UpdateOriginalArt(theDialog); } else if (item == 9) { originalRightOpen = !originalRightOpen; UpdateOriginalArt(theDialog); } else if (item == 10) { originalBottomOpen = !originalBottomOpen; UpdateOriginalArt(theDialog); } else if (item == kFloorSupportCheck) { originalFloor = !originalFloor; ToggleDialogItemValue(theDialog, kFloorSupportCheck); } } DisposeDialog(theDialog); DisposeModalFilterUPP(originalArtFilterUPP); return (newPictID); } #endif //-------------------------------------------------------------- PictIDExists Boolean PictIDExists (short theID) { PicHandle thePicture; // Handle resHandle; // Str255 resName; // ResType resType; // short numPicts, i; // short resID; Boolean foundIt; foundIt = true; thePicture = GetPicture(theID); if (thePicture == nil) { thePicture = (PicHandle)GetResource('Date', theID); if (thePicture == nil) { foundIt = false; } else ReleaseResource((Handle)thePicture); } else ReleaseResource((Handle)thePicture); // foundIt = false; // numPicts = Count1Resources('PICT'); // for (i = 1; i <= numPicts; i++) // { // resHandle = Get1IndResource('PICT', i); // if (resHandle != nil) // { // GetResInfo(resHandle, &resID, &resType, resName); // ReleaseResource(resHandle); // if (resID == theID) // { // foundIt = true; // break; // } // } // } return (foundIt); } //-------------------------------------------------------------- GetFirstPICT short GetFirstPICT (void) { Handle resHandle; Str255 resName; ResType resType; short resID; resHandle = Get1IndResource('PICT', 1); if (resHandle != nil) { GetResInfo(resHandle, &resID, &resType, resName); ReleaseResource(resHandle); return (resID); } else return (-1); } //-------------------------------------------------------------- BitchAboutPICTNotFound #ifndef COMPILEDEMO void BitchAboutPICTNotFound (void) { short hitWhat; // CenterAlert(kNoPICTFoundAlert); hitWhat = Alert(kNoPICTFoundAlert, nil); } #endif \ No newline at end of file diff --git a/Sources/RubberBands.c b/Sources/RubberBands.c deleted file mode 100755 index 657f6ba..0000000 --- a/Sources/RubberBands.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // RubberBands.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "RectUtils.h" #define kRubberBandVelocity 20 #define kBandFallCount 4 #define kKillBandMode -1 void CheckBandCollision (short); void KillBand (short); bandPtr bands; Rect bandsSrcRect; Rect bandRects[3]; GWorldPtr bandsSrcMap; GWorldPtr bandsMaskMap; short numBands, bandHitLast; extern hotPtr hotSpots; extern long gameFrame; extern short nHotSpots, leftThresh, rightThresh; extern Boolean twoPlayerGame, onePlayerLeft, playerDead; //============================================================== Functions //-------------------------------------------------------------- CheckBandCollision void CheckBandCollision (short who) { short i, action, whoLinked; Boolean collided, nothingCollided; nothingCollided = true; if ((leftThresh == kLeftWallLimit) && (bands[who].dest.left < kLeftWallLimit)) { if (bands[who].hVel < 0) bands[who].hVel = -bands[who].hVel; bands[who].dest.left = kLeftWallLimit; bands[who].dest.right = bands[who].dest.left + 16; PlayPrioritySound(kBandReboundSound, kBandReboundPriority); collided = true; } else if ((rightThresh == kRightWallLimit) && (bands[who].dest.right > kRightWallLimit)) { if (bands[who].hVel > 0) bands[who].hVel = -bands[who].hVel; bands[who].dest.right = kRightWallLimit; bands[who].dest.left = bands[who].dest.right - 16; PlayPrioritySound(kBandReboundSound, kBandReboundPriority); collided = true; } for (i = 0; i < nHotSpots; i++) { if (hotSpots[i].isOn) { action = hotSpots[i].action; if ((action == kDissolveIt) || (action == kRewardIt) || (action == kSwitchIt) || (action == kTriggerIt) || (action == kBounceIt)) { if (bands[who].dest.bottom < hotSpots[i].bounds.top) collided = false; else if (bands[who].dest.top > hotSpots[i].bounds.bottom) collided = false; else if (bands[who].dest.right < hotSpots[i].bounds.left) collided = false; else if (bands[who].dest.left > hotSpots[i].bounds.right) collided = false; else collided = true; if (collided) { nothingCollided = false; // we have detected a collision if (bandHitLast != i) // don't count it if same as last frame { // we don't want rapid on/off toggles bandHitLast = i; // note who so we don't double-toggle it if ((action == kDissolveIt) || (action == kBounceIt)) { if (bands[who].hVel > 0) { if ((bands[who].dest.right - bands[who].hVel) < hotSpots[i].bounds.left) { bands[who].hVel = -bands[who].hVel; bands[who].dest.right = hotSpots[i].bounds.left; bands[who].dest.left = bands[who].dest.right - 16; } else bands[who].mode = kKillBandMode; } else { if ((bands[who].dest.left - bands[who].hVel) > hotSpots[i].bounds.right) { bands[who].hVel = -bands[who].hVel; bands[who].dest.left = hotSpots[i].bounds.right; bands[who].dest.right = bands[who].dest.left + 16; } else bands[who].mode = kKillBandMode; } PlayPrioritySound(kBandReboundSound, kBandReboundPriority); break; } else if (action == kRewardIt) { whoLinked = hotSpots[i].who; if ((masterObjects[whoLinked].theObject.what == kGreaseRt) || (masterObjects[whoLinked].theObject.what == kGreaseLf)) { if (SetObjectState(thisRoomNumber, masterObjects[whoLinked].objectNum, 0, whoLinked)) SpillGrease(masterObjects[whoLinked].dynaNum, masterObjects[whoLinked].hotNum); hotSpots[i].isOn = false; } } else if (action == kSwitchIt) { HandleSwitches(&hotSpots[i]); } else if (action == kTriggerIt) { ArmTrigger(&hotSpots[i]); } } } } } } if (nothingCollided) // the rubberband has hit nothing bandHitLast = -1; // so make note of that for the next time if (bands[who].hVel != 0) { if (bands[who].dest.bottom < theGlider.dest.top) collided = false; else if (bands[who].dest.top > theGlider.dest.bottom) collided = false; else if (bands[who].dest.right < theGlider.dest.left) collided = false; else if (bands[who].dest.left > theGlider.dest.right) collided = false; else collided = true; if (collided) { if ((!twoPlayerGame) || (!onePlayerLeft) || (playerDead == kPlayer2)) { theGlider.hVel += (bands[who].hVel / 2); bands[who].hVel = 0; PlayPrioritySound(kHitWallSound, kHitWallPriority); } } if (twoPlayerGame) { if (bands[who].dest.bottom < theGlider2.dest.top) collided = false; else if (bands[who].dest.top > theGlider2.dest.bottom) collided = false; else if (bands[who].dest.right < theGlider2.dest.left) collided = false; else if (bands[who].dest.left > theGlider2.dest.right) collided = false; else collided = true; if (collided) { if ((!onePlayerLeft) || (playerDead == kPlayer1)) { theGlider2.hVel += (bands[who].hVel / 2); bands[who].hVel = 0; PlayPrioritySound(kHitWallSound, kHitWallPriority); } } } } if ((bands[who].dest.left < kLeftWallLimit) || (bands[who].dest.right > kRightWallLimit)) { bands[who].mode = kKillBandMode; } else if (bands[who].dest.bottom > kFloorLimit) { bands[who].mode = kKillBandMode; } } //-------------------------------------------------------------- HandleBands void HandleBands (void) { Rect dest; short i, count; if (numBands == 0) return; for (i = 0; i < numBands; i++) { bands[i].mode++; if (bands[i].mode > 2) bands[i].mode = 0; bands[i].count++; if (bands[i].count >= kBandFallCount) { bands[i].vVel++; bands[i].count = 0; } dest = bands[i].dest; QOffsetRect(&dest, playOriginH, playOriginV); AddRectToWorkRects(&dest); bands[i].dest.left += bands[i].hVel; bands[i].dest.right += bands[i].hVel; bands[i].dest.top += bands[i].vVel; bands[i].dest.bottom += bands[i].vVel; CheckBandCollision(i); } count = 0; do { while (bands[count].mode == kKillBandMode) { bands[count].mode = 0; KillBand(count); } count++; } while (count < numBands); } //-------------------------------------------------------------- AddBand Boolean AddBand (gliderPtr thisGlider, short h, short v, Boolean direction) { if (numBands >= kMaxRubberBands) return (false); bands[numBands].mode = 0; bands[numBands].count = 0; if (thisGlider->tipped) bands[numBands].vVel = -2; else bands[numBands].vVel = 0; bands[numBands].dest.left = h - 8; bands[numBands].dest.right = h + 8; bands[numBands].dest.top = v - 3; bands[numBands].dest.bottom = v + 3; if (direction == kFaceLeft) { bands[numBands].dest.left -= 32; bands[numBands].dest.right -= 32; bands[numBands].hVel = -kRubberBandVelocity; } else { bands[numBands].dest.left += 32; bands[numBands].dest.right += 32; bands[numBands].hVel = kRubberBandVelocity; } thisGlider->hVel -= (bands[numBands].hVel / 2); numBands++; PlayPrioritySound(kFireBandSound, kFireBandPriority); return (true); } //-------------------------------------------------------------- KillBand void KillBand (short which) { short lastBand; lastBand = numBands - 1; if (which != lastBand) bands[which] = bands[lastBand]; numBands--; } //-------------------------------------------------------------- KillAllBands void KillAllBands (void) { short i; for (i = 0; i < kMaxRubberBands; i++) { bands[i].mode = 0; } numBands = 0; } \ No newline at end of file diff --git a/Sources/SavedGames.c b/Sources/SavedGames.c deleted file mode 100755 index cd9f08c..0000000 --- a/Sources/SavedGames.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // SavedGames.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "House.h" #define kSavedGameVersion 0x0200 void SavedGameMismatchError (StringPtr); gameType smallGame; extern FSSpecPtr theHousesSpecs; extern short numStarsRemaining, thisHouseIndex; extern Boolean twoPlayerGame; //============================================================== Functions //-------------------------------------------------------------- SaveGame2 void SaveGame2 (void) { // Add NavServices later. /* StandardFileReply theReply; FSSpec tempSpec; Str255 gameNameStr; Size byteCount; OSErr theErr; houseType *thisHousePtr; roomType *srcRoom; savedRoom *destRoom; gamePtr savedGame; short r, i, numRooms, gameRefNum; char wasState; FlushEvents(everyEvent, 0); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; numRooms = thisHousePtr->nRooms; HSetState((Handle)thisHouse, wasState); byteCount = sizeof(game2Type) + sizeof(savedRoom) * numRooms; savedGame = (gamePtr)NewPtr(byteCount); if (savedGame == nil) { YellowAlert(kYellowFailedSaveGame, MemError()); return; } GetFirstWordOfString(thisHouseName, gameNameStr); if (gameNameStr[0] > 23) gameNameStr[0] = 23; PasStringConcat(gameNameStr, "\p Game"); StandardPutFile("\pSave Game As:", gameNameStr, &theReply); if (!theReply.sfGood) return; if (theReply.sfReplacing) { theErr = FSMakeFSSpec(theReply.sfFile.vRefNum, theReply.sfFile.parID, theReply.sfFile.name, &tempSpec); if (!CheckFileError(theErr, "\pSaved Game")) return; theErr = FSpDelete(&tempSpec); if (!CheckFileError(theErr, "\pSaved Game")) return; } wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; savedGame->house = theHousesSpecs[thisHouseIndex]; savedGame->version = kSavedGameVersion; savedGame->wasStarsLeft = numStarsRemaining; savedGame->timeStamp = thisHousePtr->timeStamp; savedGame->where.h = theGlider.dest.left; savedGame->where.v = theGlider.dest.top; savedGame->score = theScore; savedGame->unusedLong = 0L; savedGame->unusedLong2 = 0L; savedGame->energy = batteryTotal; savedGame->bands = bandsTotal; savedGame->roomNumber = thisRoomNumber; savedGame->gliderState = theGlider.mode; savedGame->numGliders = mortals; savedGame->foil = foilTotal; savedGame->nRooms = numRooms; savedGame->facing = theGlider.facing; savedGame->showFoil = showFoil; for (r = 0; r < numRooms; r++) { destRoom = &(savedGame->savedData[r]); srcRoom = &(thisHousePtr->rooms[r]); destRoom->unusedShort = 0; destRoom->unusedByte = 0; destRoom->visited = srcRoom->visited; for (i = 0; i < kMaxRoomObs; i++) destRoom->objects[i] = srcRoom->objects[i]; } HSetState((Handle)thisHouse, wasState); theErr = FSpCreate(&theReply.sfFile, 'ozm5', 'gliG', theReply.sfScript); if (CheckFileError(theErr, "\pSaved Game")) { theErr = FSpOpenDF(&theReply.sfFile, fsCurPerm, &gameRefNum); if (CheckFileError(theErr, "\pSaved Game")) { theErr = SetFPos(gameRefNum, fsFromStart, 0L); if (CheckFileError(theErr, "\pSaved Game")) { theErr = FSWrite(gameRefNum, &byteCount, (Ptr)savedGame); if (CheckFileError(theErr, "\pSaved Game")) { theErr = SetEOF(gameRefNum, byteCount); if (CheckFileError(theErr, "\pSaved Game")) { } } } theErr = FSClose(gameRefNum); if (CheckFileError(theErr, "\pSaved Game")) { } } } DisposePtr((Ptr)savedGame); */ } //-------------------------------------------------------------- SavedGameMismatchError void SavedGameMismatchError (StringPtr gameName) { #define kSavedGameErrorAlert 1044 short whoCares; InitCursor(); // CenterAlert(kSavedGameErrorAlert); ParamText(gameName, thisHouseName, "\p", "\p"); whoCares = Alert(kSavedGameErrorAlert, nil); } //-------------------------------------------------------------- OpenSavedGame Boolean OpenSavedGame (void) { return false; // TEMP fix this iwth NavServices /* StandardFileReply theReply; SFTypeList theList; houseType *thisHousePtr; roomType *destRoom; savedRoom *srcRoom; gamePtr savedGame; long byteCount; OSErr theErr; short r, i, gameRefNum; char wasState; theList[0] = 'gliG'; StandardGetFile(nil, 1, theList, &theReply); if (!theReply.sfGood) return(false); theErr = FSpOpenDF(&theReply.sfFile, fsCurPerm, &gameRefNum); if (!CheckFileError(theErr, "\pSaved Game")) return(false); theErr = GetEOF(gameRefNum, &byteCount); if (!CheckFileError(theErr, "\pSaved Game")) { theErr = FSClose(gameRefNum); return(false); } savedGame = (gamePtr)NewPtr(byteCount); if (savedGame == nil) { YellowAlert(kYellowFailedSaveGame, MemError()); theErr = FSClose(gameRefNum); return(false); } theErr = SetFPos(gameRefNum, fsFromStart, 0L); if (!CheckFileError(theErr, "\pSaved Game")) { DisposePtr((Ptr)savedGame); theErr = FSClose(gameRefNum); return(false); } theErr = FSRead(gameRefNum, &byteCount, savedGame); if (!CheckFileError(theErr, "\pSaved Game")) { DisposePtr((Ptr)savedGame); theErr = FSClose(gameRefNum); return(false); } wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; if (!EqualString(savedGame->house.name, thisHouseName, true, true)) { SavedGameMismatchError(savedGame->house.name); HSetState((Handle)thisHouse, wasState); DisposePtr((Ptr)savedGame); theErr = FSClose(gameRefNum); return(false); } else if (thisHousePtr->timeStamp != savedGame->timeStamp) { YellowAlert(kYellowSavedTimeWrong, 0); HSetState((Handle)thisHouse, wasState); DisposePtr((Ptr)savedGame); theErr = FSClose(gameRefNum); return(false); } else if (savedGame->version != kSavedGameVersion) { YellowAlert(kYellowSavedVersWrong, kSavedGameVersion); HSetState((Handle)thisHouse, wasState); DisposePtr((Ptr)savedGame); theErr = FSClose(gameRefNum); return(false); } else if (savedGame->nRooms != thisHousePtr->nRooms) { YellowAlert(kYellowSavedRoomsWrong, savedGame->nRooms - thisHousePtr->nRooms); HSetState((Handle)thisHouse, wasState); DisposePtr((Ptr)savedGame); theErr = FSClose(gameRefNum); return(false); } else { smallGame.wasStarsLeft = savedGame->wasStarsLeft; smallGame.where.h = savedGame->where.h; smallGame.where.v = savedGame->where.v; smallGame.score = savedGame->score; smallGame.unusedLong = savedGame->unusedLong; smallGame.unusedLong2 = savedGame->unusedLong2; smallGame.energy = savedGame->energy; smallGame.bands = savedGame->bands; smallGame.roomNumber = savedGame->roomNumber; smallGame.gliderState = savedGame->gliderState; smallGame.numGliders = savedGame->numGliders; smallGame.foil = savedGame->foil; smallGame.unusedShort = 0; smallGame.facing = savedGame->facing; smallGame.showFoil = savedGame->showFoil; for (r = 0; r < savedGame->nRooms; r++) { srcRoom = &(savedGame->savedData[r]); destRoom = &(thisHousePtr->rooms[r]); destRoom->visited = srcRoom->visited; for (i = 0; i < kMaxRoomObs; i++) destRoom->objects[i] = srcRoom->objects[i]; } } HSetState((Handle)thisHouse, wasState); DisposePtr((Ptr)savedGame); theErr = FSClose(gameRefNum); if (!CheckFileError(theErr, "\pSaved Game")) return (false); return (true); */ } //-------------------------------------------------------------- SaveGame // This is probably about 3 days away from becoming the "old" functionÉ // for saving games. void SaveGame (Boolean doSave) { houseType *thisHousePtr; UInt32 stamp; char wasState; if (twoPlayerGame) return; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; if (doSave) { thisHousePtr->savedGame.version = kSavedGameVersion; thisHousePtr->savedGame.wasStarsLeft = numStarsRemaining; GetDateTime(&stamp); thisHousePtr->savedGame.timeStamp = (long)stamp; thisHousePtr->savedGame.where.h = theGlider.dest.left; thisHousePtr->savedGame.where.v = theGlider.dest.top; thisHousePtr->savedGame.score = theScore; thisHousePtr->savedGame.unusedLong = 0L; thisHousePtr->savedGame.unusedLong2 = 0L; thisHousePtr->savedGame.energy = batteryTotal; thisHousePtr->savedGame.bands = bandsTotal; thisHousePtr->savedGame.roomNumber = thisRoomNumber; thisHousePtr->savedGame.gliderState = theGlider.mode; thisHousePtr->savedGame.numGliders = mortals; thisHousePtr->savedGame.foil = foilTotal; thisHousePtr->savedGame.unusedShort = 0; thisHousePtr->savedGame.facing = theGlider.facing; thisHousePtr->savedGame.showFoil = showFoil; thisHousePtr->hasGame = true; } else { thisHousePtr->hasGame = false; } HSetState((Handle)thisHouse, wasState); if (doSave) { if (!WriteHouse(theMode == kEditMode)) YellowAlert(kYellowFailedWrite, 0); } } \ No newline at end of file diff --git a/Sources/Scoreboard.c b/Sources/Scoreboard.c deleted file mode 100755 index 85db244..0000000 --- a/Sources/Scoreboard.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Scoreboard.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "Environ.h" #include "RectUtils.h" #define kGrayBackgroundColor 251 #define kGrayBackgroundColor4 10 #define kFoilBadge 0 #define kBandsBadge 1 #define kBatteryBadge 2 #define kHeliumBadge 3 #define kScoreRollAmount 13 void RefreshRoomTitle (short); void RefreshNumGliders (void); void RefreshPoints (void); Rect boardSrcRect, badgeSrcRect, boardDestRect; GWorldPtr boardSrcMap, badgeSrcMap; Rect boardTSrcRect, boardTDestRect; GWorldPtr boardTSrcMap; Rect boardGSrcRect, boardGDestRect; GWorldPtr boardGSrcMap; Rect boardPSrcRect, boardPDestRect; Rect boardPQDestRect, boardGQDestRect; Rect badgesBlankRects[4], badgesBadgesRects[4]; Rect badgesDestRects[4]; GWorldPtr boardPSrcMap; long displayedScore; short wasScoreboardMode; Boolean doRollScore; extern Rect localRoomsDest[], justRoomsRect; extern long gameFrame; extern short numNeighbors, otherPlayerEscaped; extern Boolean evenFrame, onePlayerLeft; //============================================================== Functions //-------------------------------------------------------------- RefreshScoreboard void RefreshScoreboard (short mode) { doRollScore = true; RefreshRoomTitle(mode); RefreshNumGliders(); RefreshPoints(); CopyBits((BitMap *)*GetGWorldPixMap(boardSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &boardSrcRect, &boardDestRect, srcCopy, 0L); QuickBatteryRefresh(false); QuickBandsRefresh(false); QuickFoilRefresh(false); } //-------------------------------------------------------------- HandleDynamicScoreboard void HandleDynamicScoreboard (void) { #define kFoilLow 2 // 25% #define kBatteryLow 17 // 25% #define kHeliumLow -38 // 25% #define kBandsLow 2 // 25% long whosTurn; if (theScore > displayedScore) { if (doRollScore) { displayedScore += kScoreRollAmount; if (displayedScore > theScore) displayedScore = theScore; } else displayedScore = theScore; PlayPrioritySound(kScoreTikSound, kScoreTikPriority); QuickScoreRefresh(); } whosTurn = gameFrame & 0x00000007; switch (whosTurn) { case 0: // show foil if ((foilTotal > 0) && (foilTotal < kFoilLow)) QuickFoilRefresh(false); break; case 1: // hide battery if ((batteryTotal > 0) && (batteryTotal < kBatteryLow)) QuickBatteryRefresh(true); else if ((batteryTotal < 0) && (batteryTotal > kHeliumLow)) QuickBatteryRefresh(true); break; case 2: // show rubber bands if ((bandsTotal > 0) && (bandsTotal < kBandsLow)) QuickBandsRefresh(false); break; case 4: // show battery if ((batteryTotal > 0) && (batteryTotal < kBatteryLow)) QuickBatteryRefresh(false); else if ((batteryTotal < 0) && (batteryTotal > kHeliumLow)) QuickBatteryRefresh(false); break; case 5: // hide foil if ((foilTotal > 0) && (foilTotal < kFoilLow)) QuickFoilRefresh(true); break; case 7: // hide rubber bands if ((bandsTotal > 0) && (bandsTotal < kBandsLow)) QuickBandsRefresh(true); break; } } //-------------------------------------------------------------- RefreshRoomTitle void RefreshRoomTitle (short mode) { RGBColor theRGBColor, wasColor; SetPort((GrafPtr)boardTSrcMap); GetForeColor(&wasColor); if (thisMac.isDepth == 4) Index2Color(kGrayBackgroundColor4, &theRGBColor); else Index2Color(kGrayBackgroundColor, &theRGBColor); RGBForeColor(&theRGBColor); PaintRect(&boardTSrcRect); RGBForeColor(&wasColor); MoveTo(1, 10); ForeColor(blackColor); switch (mode) { case kEscapedTitleMode: DrawString("\pHit Delete key if unable to Follow"); break; case kSavingTitleMode: DrawString("\pSaving GameÉ"); break; default: DrawString(thisRoom->name); break; } MoveTo(0, 9); ForeColor(whiteColor); switch (mode) { case kEscapedTitleMode: DrawString("\pHit Delete key if unable to Follow"); break; case kSavingTitleMode: DrawString("\pSaving GameÉ"); break; default: DrawString(thisRoom->name); break; } ForeColor(blackColor); CopyBits((BitMap *)*GetGWorldPixMap(boardTSrcMap), (BitMap *)*GetGWorldPixMap(boardSrcMap), &boardTSrcRect, &boardTDestRect, srcCopy, nil); } //-------------------------------------------------------------- RefreshNumGliders void RefreshNumGliders (void) { RGBColor theRGBColor, wasColor; Str255 nGlidersStr; long displayMortals; SetPort((GrafPtr)boardGSrcMap); GetForeColor(&wasColor); if (thisMac.isDepth == 4) Index2Color(kGrayBackgroundColor4, &theRGBColor); else Index2Color(kGrayBackgroundColor, &theRGBColor); RGBForeColor(&theRGBColor); PaintRect(&boardGSrcRect); RGBForeColor(&wasColor); displayMortals = mortals; if (displayMortals < 0) displayMortals = 0; NumToString(displayMortals, nGlidersStr); MoveTo(1, 10); ForeColor(blackColor); DrawString(nGlidersStr); MoveTo(0, 9); ForeColor(whiteColor); DrawString(nGlidersStr); ForeColor(blackColor); CopyBits((BitMap *)*GetGWorldPixMap(boardGSrcMap), (BitMap *)*GetGWorldPixMap(boardSrcMap), &boardGSrcRect, &boardGDestRect, srcCopy, nil); } //-------------------------------------------------------------- RefreshPoints void RefreshPoints (void) { RGBColor theRGBColor, wasColor; Str255 scoreStr; SetPort((GrafPtr)boardPSrcMap); GetForeColor(&wasColor); if (thisMac.isDepth == 4) Index2Color(kGrayBackgroundColor4, &theRGBColor); else Index2Color(kGrayBackgroundColor, &theRGBColor); RGBForeColor(&theRGBColor); PaintRect(&boardPSrcRect); RGBForeColor(&wasColor); NumToString(theScore, scoreStr); MoveTo(1, 10); ForeColor(blackColor); DrawString(scoreStr); MoveTo(0, 9); ForeColor(whiteColor); DrawString(scoreStr); ForeColor(blackColor); CopyBits((BitMap *)*GetGWorldPixMap(boardPSrcMap), (BitMap *)*GetGWorldPixMap(boardSrcMap), &boardPSrcRect, &boardPDestRect, srcCopy, nil); displayedScore = theScore; } //-------------------------------------------------------------- QuickGlidersRefresh void QuickGlidersRefresh (void) { RGBColor theRGBColor, wasColor; Str255 nGlidersStr; SetPort((GrafPtr)boardGSrcMap); GetForeColor(&wasColor); if (thisMac.isDepth == 4) Index2Color(kGrayBackgroundColor4, &theRGBColor); else Index2Color(kGrayBackgroundColor, &theRGBColor); RGBForeColor(&theRGBColor); PaintRect(&boardGSrcRect); RGBForeColor(&wasColor); NumToString((long)mortals, nGlidersStr); MoveTo(1, 10); ForeColor(blackColor); DrawString(nGlidersStr); MoveTo(0, 9); ForeColor(whiteColor); DrawString(nGlidersStr); ForeColor(blackColor); CopyBits((BitMap *)*GetGWorldPixMap(boardGSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &boardGSrcRect, &boardGQDestRect, srcCopy, nil); } //-------------------------------------------------------------- QuickScoreRefresh void QuickScoreRefresh (void) { RGBColor theRGBColor, wasColor; Str255 scoreStr; SetPort((GrafPtr)boardPSrcMap); GetForeColor(&wasColor); if (thisMac.isDepth == 4) Index2Color(kGrayBackgroundColor4, &theRGBColor); else Index2Color(kGrayBackgroundColor, &theRGBColor); RGBForeColor(&theRGBColor); PaintRect(&boardPSrcRect); RGBForeColor(&wasColor); NumToString(displayedScore, scoreStr); MoveTo(1, 10); ForeColor(blackColor); DrawString(scoreStr); MoveTo(0, 9); ForeColor(whiteColor); DrawString(scoreStr); ForeColor(blackColor); CopyBits((BitMap *)*GetGWorldPixMap(boardPSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &boardPSrcRect, &boardPQDestRect, srcCopy, nil); } //-------------------------------------------------------------- QuickBatteryRefresh void QuickBatteryRefresh (Boolean flash) { if ((batteryTotal > 0) && (!flash)) { CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &badgesBadgesRects[kBatteryBadge], &badgesDestRects[kBatteryBadge], srcCopy, nil); } else if ((batteryTotal < 0) && (!flash)) { CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &badgesBadgesRects[kHeliumBadge], &badgesDestRects[kHeliumBadge], srcCopy, nil); } else { CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &badgesBlankRects[kBatteryBadge], &badgesDestRects[kBatteryBadge], srcCopy, nil); } } //-------------------------------------------------------------- QuickBandsRefresh void QuickBandsRefresh (Boolean flash) { if ((bandsTotal > 0) && (!flash)) { CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &badgesBadgesRects[kBandsBadge], &badgesDestRects[kBandsBadge], srcCopy, nil); } else { CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &badgesBlankRects[kBandsBadge], &badgesDestRects[kBandsBadge], srcCopy, nil); } } //-------------------------------------------------------------- QuickFoilRefresh void QuickFoilRefresh (Boolean flash) { if ((foilTotal > 0) && (!flash)) { CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &badgesBadgesRects[kFoilBadge], &badgesDestRects[kFoilBadge], srcCopy, nil); } else { CopyBits((BitMap *)*GetGWorldPixMap(badgeSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &badgesBlankRects[kFoilBadge], &badgesDestRects[kFoilBadge], srcCopy, nil); } } //-------------------------------------------------------------- AdjustScoreboardHeight void AdjustScoreboardHeight (void) { short offset, newMode; if (numNeighbors == 9) newMode = kScoreboardHigh; else newMode = kScoreboardLow; if (wasScoreboardMode != newMode) { switch (newMode) { case kScoreboardHigh: // 9 neighbors offset = localRoomsDest[kCentralRoom].top; offset = -offset; justRoomsRect = workSrcRect; break; case kScoreboardLow: // 1 or 3 neighbors offset = localRoomsDest[kCentralRoom].top; justRoomsRect = workSrcRect; justRoomsRect.top = localRoomsDest[kCentralRoom].top; justRoomsRect.bottom = localRoomsDest[kCentralRoom].bottom; break; } QOffsetRect(&boardDestRect, 0, offset); QOffsetRect(&boardGQDestRect, 0, offset); QOffsetRect(&boardPQDestRect, 0, offset); QOffsetRect(&badgesDestRects[kBatteryBadge], 0, offset); QOffsetRect(&badgesDestRects[kBandsBadge], 0, offset); QOffsetRect(&badgesDestRects[kFoilBadge], 0, offset); QOffsetRect(&badgesDestRects[kHeliumBadge], 0, offset); wasScoreboardMode = newMode; } } //-------------------------------------------------------------- BlackenScoreboard void BlackenScoreboard (void) { UpdateMenuBarWindow(); } \ No newline at end of file diff --git a/Sources/SelectHouse.c b/Sources/SelectHouse.c deleted file mode 100755 index e829e21..0000000 --- a/Sources/SelectHouse.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // SelectHouse.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include #include "DialogUtils.h" #include "Externs.h" #include "Environ.h" #include "House.h" #include "RectUtils.h" #define kLoadHouseDialogID 1000 #define kDispFiles 12 #define kLoadTitlePictItem 3 #define kLoadNameFirstItem 5 #define kLoadNameLastItem 16 #define kLoadIconFirstItem 17 #define kLoadIconLastItem 28 #define kScrollUpItem 29 #define kScrollDownItem 30 #define kLoadTitlePict1 1001 #define kLoadTitlePict8 1002 #define kDefaultHousePict1 1003 #define kDefaultHousePict8 1004 #define kGrayedOutUpArrow 1052 #define kGrayedOutDownArrow 1053 #define kMaxExtraHouses 8 void UpdateLoadDialog (DialogPtr); void PageUpHouses (DialogPtr); void PageDownHouses (DialogPtr); pascal Boolean LoadFilter (DialogPtr, EventRecord *, short *); void SortHouseList (void); void DoDirSearch (void); Rect loadHouseRects[12]; FSSpecPtr theHousesSpecs; FSSpec extraHouseSpecs[kMaxExtraHouses]; long lastWhenClick; Point lastWhereClick; short housesFound, thisHouseIndex, maxFiles, willMaxFiles; short housePage, demoHouseIndex, numExtraHouses; char fileFirstChar[12]; extern UInt32 doubleTime; //============================================================== Functions //-------------------------------------------------------------- UpdateLoadWindow #ifndef COMPILEDEMO void UpdateLoadDialog (DialogPtr theDialog) { Rect tempRect, dialogRect, dummyRect; short houseStart, houseStop, i, wasResFile, isResFile, count; // char wasState; WindowRef theWindow; // RgnHandle theRegion; theWindow = GetDialogWindow(theDialog); GetWindowBounds(theWindow, kWindowContentRgn, &dialogRect); /* wasState = HGetState((Handle)(((DialogPeek)theDialog)->window).port.visRgn); HLock((Handle)(((DialogPeek)theDialog)->window).port.visRgn); dialogRect = (**((((DialogPeek)theDialog)->window).port.visRgn)).rgnBBox; HSetState((Handle)(((DialogPeek)theDialog)->window).port.visRgn, wasState); */ DrawDialog(theDialog); ColorFrameWHRect(8, 39, 413, 184, kRedOrangeColor8); // box around files houseStart = housePage; houseStop = housesFound; if ((houseStop - houseStart) > kDispFiles) houseStop = houseStart + kDispFiles; wasResFile = CurResFile(); count = 0; for (i = 0; i < 12; i++) fileFirstChar[i] = 0x7F; for (i = houseStart; i < houseStop; i++) { SpinCursor(1); GetDialogItemRect(theDialog, kLoadIconFirstItem + i - housePage, &tempRect); if (SectRect(&dialogRect, &tempRect, &dummyRect)) { isResFile = HOpenResFile(theHousesSpecs[i].vRefNum, theHousesSpecs[i].parID, theHousesSpecs[i].name, fsRdPerm); if (isResFile != -1) { if (Get1Resource('icl8', -16455) != nil) { LargeIconPlot(&tempRect, -16455); } else LoadDialogPICT(theDialog, kLoadIconFirstItem + i - housePage, kDefaultHousePict8); CloseResFile(isResFile); } else LoadDialogPICT(theDialog, kLoadIconFirstItem + i - housePage, kDefaultHousePict8); } fileFirstChar[count] = theHousesSpecs[i].name[1]; if ((fileFirstChar[count] <= 0x7A) && (fileFirstChar[count] > 0x60)) fileFirstChar[count] -= 0x20; count++; DrawDialogUserText(theDialog, kLoadNameFirstItem + i - housePage, theHousesSpecs[i].name, i == (thisHouseIndex + housePage)); } InitCursor(); UseResFile(wasResFile); } #endif //-------------------------------------------------------------- PageUpHouses #ifndef COMPILEDEMO void PageUpHouses (DialogPtr theDial) { Rect tempRect; if (housePage < kDispFiles) { SysBeep(1); return; } housePage -= kDispFiles; thisHouseIndex = kDispFiles - 1; ShowDialogItem(theDial, kScrollDownItem); if (housePage < kDispFiles) { GetDialogItemRect(theDial, kScrollUpItem, &tempRect); HideDialogItem(theDial, kScrollUpItem); DrawCIcon(kGrayedOutUpArrow, tempRect.left, tempRect.top); } QSetRect(&tempRect, 8, 39, 421, 223); EraseRect(&tempRect); InvalWindowRect(GetDialogWindow(theDial), &tempRect); } #endif //-------------------------------------------------------------- PageDownHouses #ifndef COMPILEDEMO void PageDownHouses (DialogPtr theDial) { Rect tempRect; if (housePage >= (housesFound - kDispFiles)) { SysBeep(1); return; } housePage += kDispFiles; thisHouseIndex = 0; ShowDialogItem(theDial, kScrollUpItem); if (housePage >= (housesFound - kDispFiles)) { GetDialogItemRect(theDial, kScrollDownItem, &tempRect); HideDialogItem(theDial, kScrollDownItem); DrawCIcon(kGrayedOutDownArrow, tempRect.left, tempRect.top); } QSetRect(&tempRect, 8, 39, 421, 223); EraseRect(&tempRect); InvalWindowRect(GetDialogWindow(theDial), &tempRect); } #endif //-------------------------------------------------------------- LoadFilter #ifndef COMPILEDEMO pascal Boolean LoadFilter (DialogPtr dial, EventRecord *event, short *item) { short screenCount, i, wasIndex; char theChar; switch (event->what) { case keyDown: theChar = (event->message) & charCodeMask; switch (theChar) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; case kPageUpKeyASCII: *item = kScrollUpItem; return (true); break; case kPageDownKeyASCII: *item = kScrollDownItem; return (true); break; case kUpArrowKeyASCII: InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); thisHouseIndex -= 4; if (thisHouseIndex < 0) { screenCount = housesFound - housePage; if (screenCount > kDispFiles) screenCount = kDispFiles; thisHouseIndex += 4; thisHouseIndex = (((screenCount - 1) / 4) * 4) + (thisHouseIndex % 4); if (thisHouseIndex >= screenCount) thisHouseIndex -= 4; } InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); return(true); break; case kDownArrowKeyASCII: InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); thisHouseIndex += 4; screenCount = housesFound - housePage; if (screenCount > kDispFiles) screenCount = kDispFiles; if (thisHouseIndex >= screenCount) thisHouseIndex %= 4; InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); return(true); break; case kLeftArrowKeyASCII: InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); thisHouseIndex--; if (thisHouseIndex < 0) { screenCount = housesFound - housePage; if (screenCount > kDispFiles) screenCount = kDispFiles; thisHouseIndex = screenCount - 1; } InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); return(true); break; case kTabKeyASCII: case kRightArrowKeyASCII: InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); thisHouseIndex++; screenCount = housesFound - housePage; if (screenCount > kDispFiles) screenCount = kDispFiles; if (thisHouseIndex >= screenCount) thisHouseIndex = 0; InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); return(true); break; default: if (((theChar > 0x40) && (theChar <= 0x5A)) || ((theChar > 0x60) && (theChar <= 0x7A))) { if ((theChar > 0x60) && (theChar <= 0x7A)) theChar -= 0x20; wasIndex = thisHouseIndex; thisHouseIndex = -1; i = 0; do { if ((fileFirstChar[i] >= theChar) && (fileFirstChar[i] != 0x7F)) thisHouseIndex = i; i++; } while ((thisHouseIndex == -1) && (i < 12)); if (thisHouseIndex == -1) { screenCount = housesFound - housePage; if (screenCount > kDispFiles) screenCount = kDispFiles; thisHouseIndex = screenCount - 1; } if (wasIndex != thisHouseIndex) { InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[wasIndex]); InvalWindowRect(GetDialogWindow(dial), &loadHouseRects[thisHouseIndex]); } return(true); } else return(false); } break; case mouseDown: lastWhenClick = event->when - lastWhenClick; SubPt(event->where, &lastWhereClick); return(false); break; case mouseUp: lastWhenClick = event->when; lastWhereClick = event->where; return(false); break; case updateEvt: BeginUpdate(GetDialogWindow(dial)); UpdateLoadDialog(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } #endif //-------------------------------------------------------------- DoLoadHouse #ifndef COMPILEDEMO void DoLoadHouse (void) { Rect tempRect; DialogPtr theDial; short i, item, wasIndex, screenCount; Boolean leaving, whoCares; ModalFilterUPP loadFilterUPP; loadFilterUPP = NewModalFilterUPP(LoadFilter); BringUpDialog(&theDial, kLoadHouseDialogID); if (housesFound <= kDispFiles) { GetDialogItemRect(theDial, kScrollUpItem, &tempRect); HideDialogItem(theDial, kScrollUpItem); DrawCIcon(kGrayedOutUpArrow, tempRect.left, tempRect.top); GetDialogItemRect(theDial, kScrollDownItem, &tempRect); HideDialogItem(theDial, kScrollDownItem); DrawCIcon(kGrayedOutDownArrow, tempRect.left, tempRect.top); } else { if (thisHouseIndex < kDispFiles) { GetDialogItemRect(theDial, kScrollUpItem, &tempRect); HideDialogItem(theDial, kScrollUpItem); DrawCIcon(kGrayedOutUpArrow, tempRect.left, tempRect.top); } else if (thisHouseIndex > (housesFound - kDispFiles)) { GetDialogItemRect(theDial, kScrollDownItem, &tempRect); HideDialogItem(theDial, kScrollDownItem); DrawCIcon(kGrayedOutDownArrow, tempRect.left, tempRect.top); } } wasIndex = thisHouseIndex; housePage = (thisHouseIndex / kDispFiles) * kDispFiles; thisHouseIndex -= housePage; for (i = 0; i < 12; i++) { GetDialogItemRect(theDial, kLoadNameFirstItem + i, &loadHouseRects[i]); GetDialogItemRect(theDial, kLoadIconFirstItem + i, &tempRect); loadHouseRects[i].top = tempRect.top; loadHouseRects[i].bottom++; } leaving = false; while (!leaving) { ModalDialog(loadFilterUPP, &item); if (item == kOkayButton) { thisHouseIndex += housePage; if (thisHouseIndex != wasIndex) { whoCares = CloseHouse(); PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); if (OpenHouse()) whoCares = ReadHouse(); } leaving = true; } else if (item == kCancelButton) { thisHouseIndex = wasIndex; leaving = true; } else if ((item >= kLoadNameFirstItem) && (item <= kLoadNameLastItem)) { screenCount = housesFound - housePage; if (screenCount > kDispFiles) screenCount = kDispFiles; if ((item - kLoadNameFirstItem != thisHouseIndex) && (item - kLoadNameFirstItem < screenCount)) { InvalWindowRect(GetDialogWindow(theDial), &loadHouseRects[thisHouseIndex]); thisHouseIndex = item - kLoadNameFirstItem; InvalWindowRect(GetDialogWindow(theDial), &loadHouseRects[thisHouseIndex]); } if (lastWhereClick.h < 0) lastWhereClick.h = -lastWhereClick.h; if (lastWhereClick.v < 0) lastWhereClick.v = -lastWhereClick.v; if ((lastWhenClick < doubleTime) && (lastWhereClick.h < 5) && (lastWhereClick.v < 5)) { thisHouseIndex += housePage; if (thisHouseIndex != wasIndex) { MyDisableControl(theDial, kOkayButton); MyDisableControl(theDial, kCancelButton); whoCares = CloseHouse(); PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); if (OpenHouse()) whoCares = ReadHouse(); } leaving = true; } } else if ((item >= kLoadIconFirstItem) && (item <= kLoadIconLastItem)) { screenCount = housesFound - housePage; if (screenCount > kDispFiles) screenCount = kDispFiles; if ((item - kLoadIconFirstItem != thisHouseIndex) && (item - kLoadIconFirstItem < screenCount)) { InvalWindowRect(GetDialogWindow(theDial), &loadHouseRects[thisHouseIndex]); thisHouseIndex = item - kLoadIconFirstItem; InvalWindowRect(GetDialogWindow(theDial), &loadHouseRects[thisHouseIndex]); } if (lastWhereClick.h < 0) lastWhereClick.h = -lastWhereClick.h; if (lastWhereClick.v < 0) lastWhereClick.v = -lastWhereClick.v; if ((lastWhenClick < doubleTime) && (lastWhereClick.h < 5) && (lastWhereClick.v < 5)) { thisHouseIndex += housePage; if (thisHouseIndex != wasIndex) { MyDisableControl(theDial, kOkayButton); MyDisableControl(theDial, kCancelButton); whoCares = CloseHouse(); PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); if (OpenHouse()) whoCares = ReadHouse(); } leaving = true; } } else if (item == kScrollUpItem) { PageUpHouses(theDial); } else if (item == kScrollDownItem) { PageDownHouses(theDial); } } DisposeDialog(theDial); DisposeModalFilterUPP(loadFilterUPP); } #endif //-------------------------------------------------------------- SortHouseList void SortHouseList (void) { FSSpec tempSpec; short i, h, whosFirst; i = 0; // remove exact duplicate houses while (i < housesFound) { h = i + 1; while (h < housesFound) { if ((EqualString(theHousesSpecs[i].name, theHousesSpecs[h].name, true, true)) && (theHousesSpecs[i].vRefNum == theHousesSpecs[i].vRefNum) && (theHousesSpecs[i].parID == theHousesSpecs[i].parID)) { theHousesSpecs[h] = theHousesSpecs[housesFound - 1]; housesFound--; } h++; } i++; } for (i = 0; i < housesFound - 1; i++) { for (h = 0; h < (housesFound - i - 1); h++) { whosFirst = WhichStringFirst(theHousesSpecs[h].name, theHousesSpecs[h + 1].name); if (whosFirst == 1) { tempSpec = theHousesSpecs[h + 1]; theHousesSpecs[h + 1] = theHousesSpecs[h]; theHousesSpecs[h] = tempSpec; } } } } //-------------------------------------------------------------- DoDirSearch void DoDirSearch (void) { #define kMaxDirectories 32 CInfoPBRec theBlock; Str255 nameString; long theDirs[kMaxDirectories]; OSErr theErr, notherErr; short count, i, currentDir, numDirs; for (i = 0; i < kMaxDirectories; i++) theDirs[i] = 0L; currentDir = 0; theDirs[currentDir] = thisMac.dirID; numDirs = 1; theBlock.hFileInfo.ioCompletion = nil; theBlock.hFileInfo.ioVRefNum = thisMac.vRefNum; theBlock.hFileInfo.ioNamePtr = nameString; while ((currentDir < numDirs) && (currentDir < kMaxDirectories)) { count = 1; theErr = noErr; while (theErr == noErr) { SpinCursor(1); theBlock.hFileInfo.ioFDirIndex = count; theBlock.hFileInfo.ioDirID = theDirs[currentDir]; theErr = PBGetCatInfo(&theBlock, false); if (theErr == noErr) { if ((theBlock.hFileInfo.ioFlAttrib & 0x10) == 0x00) { if ((theBlock.hFileInfo.ioFlFndrInfo.fdType == 'gliH') && (theBlock.hFileInfo.ioFlFndrInfo.fdCreator == 'ozm5') && (housesFound < maxFiles)) { notherErr = FSMakeFSSpec(thisMac.vRefNum, theBlock.hFileInfo.ioFlParID, nameString, &theHousesSpecs[housesFound]); if (notherErr == noErr) housesFound++; } } else if ((theBlock.hFileInfo.ioFlAttrib & 0x10) == 0x10) { if (numDirs < kMaxDirectories) { theDirs[numDirs] = theBlock.hFileInfo.ioDirID; numDirs++; } } count++; } } currentDir++; } if (housesFound < 1) { thisHouseIndex = -1; YellowAlert(kYellowNoHouses, 0); } else { SortHouseList(); thisHouseIndex = 0; for (i = 0; i < housesFound; i++) { if (EqualString(theHousesSpecs[i].name, thisHouseName, false, true)) { thisHouseIndex = i; break; } } PasStringCopy(theHousesSpecs[thisHouseIndex].name, thisHouseName); demoHouseIndex = -1; for (i = 0; i < housesFound; i++) { if (EqualString(theHousesSpecs[i].name, "\pDemo House", false, true)) { demoHouseIndex = i; break; } } } } //-------------------------------------------------------------- BuildHouseList void BuildHouseList (void) { short i; if (thisMac.hasSystem7) { housesFound = 0; // zero the number of houses found for (i = 0; i < numExtraHouses; i++) // 1st, insert extra houses into list { theHousesSpecs[housesFound] = extraHouseSpecs[i]; housesFound++; } DoDirSearch(); // now, search folders for the rest } } //-------------------------------------------------------------- AddExtraHouse void AddExtraHouse (FSSpec *newHouse) { if (numExtraHouses >= kMaxExtraHouses) return; extraHouseSpecs[numExtraHouses] = *newHouse; numExtraHouses++; } \ No newline at end of file diff --git a/Sources/Settings.c b/Sources/Settings.c deleted file mode 100755 index aefbe11..0000000 --- a/Sources/Settings.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Settings.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "DialogUtils.h" #include "Externs.h" #include "Environ.h" #include "House.h" #define kMainPrefsDialID 1012 #define kDisplayPrefsDialID 1017 #define kSoundPrefsDialID 1018 #define kControlPrefsDialID 1023 #define kBrainsPrefsDialID 1024 #define kDisplayButton 3 #define kSoundButton 4 #define kControlsButton 5 #define kBrainsButton 6 #define kDisplay1Item 3 #define kDisplay3Item 4 #define kDisplay9Item 5 #define kDoColorFadeItem 9 #define kCurrentDepth 10 #define k256Depth 11 #define k16Depth 12 #define kDispDefault 15 #define kUseQDItem 16 #define kUseScreen2Item 17 #define kSofterItem 4 #define kLouderItem 5 #define kVolNumberItem 7 #define kIdleMusicItem 8 #define kPlayMusicItem 9 #define kSoundDefault 13 #define kRightControl 5 #define kLeftControl 6 #define kBattControl 7 #define kBandControl 8 #define kControlDefaults 13 #define kESCPausesRadio 14 #define kTABPausesRadio 15 #define kMaxFilesItem 5 #define kQuickTransitCheck 7 #define kDoZoomsCheck 8 #define kBrainsDefault 9 #define kDoDemoCheck 10 #define kDoBackgroundCheck 11 #define kDoErrorCheck 12 #define kDoPrettyMapCheck 13 #define kDoBitchDlgsCheck 14 void SetBrainsToDefaults (DialogPtr); void UpdateSettingsBrains (DialogPtr); pascal Boolean BrainsFilter (DialogPtr, EventRecord *, short *); void DoBrainsPrefs (void); void SetControlsToDefaults (DialogPtr); void UpdateControlKeyName (DialogPtr); void UpdateSettingsControl (DialogPtr); pascal Boolean ControlFilter (DialogPtr, EventRecord *, short *); void DoControlPrefs (void); void SoundDefaults (DialogPtr); void UpdateSettingsSound (DialogPtr); void HandleSoundMusicChange (short, Boolean); pascal Boolean SoundFilter (DialogPtr, EventRecord *, short *); void DoSoundPrefs (void); void DisplayDefaults (void); void FrameDisplayIcon (DialogPtr); void DisplayUpdate (DialogPtr); pascal Boolean DisplayFilter (DialogPtr, EventRecord *, short *); void DoDisplayPrefs (void); void SetAllDefaults (void); void FlashSettingsButton (short); void UpdateSettingsMain (DialogPtr); pascal Boolean PrefsFilter (DialogPtr, EventRecord *, short *); void BitchAboutChanges (void); Rect prefButton[4], controlRects[4]; Str15 leftName, rightName, batteryName, bandName; Str15 tempLeftStr, tempRightStr, tempBattStr, tempBandStr; long tempLeftMap, tempRightMap, tempBattMap, tempBandMap; short whichCtrl, wasDepthPref; Boolean wasFade, wasIdle, wasPlay, wasTransit, wasZooms, wasBackground; Boolean wasEscPauseKey, wasDemos, wasScreen2, nextRestartChange, wasErrorCheck; Boolean wasPrettyMap, wasBitchDialogs; extern short numNeighbors, isDepthPref, maxFiles, willMaxFiles; extern Boolean isDoColorFade, isPlayMusicIdle, isUseSecondScreen; extern Boolean isHouseChecks, doBitchDialogs; extern Boolean isEscPauseKey, failedMusic, isSoundOn, doBackground; extern Boolean isMusicOn, quickerTransitions, doAutoDemo; extern Boolean changeLockStateOfHouse, saveHouseLocked, doPrettyMap; //============================================================== Functions //-------------------------------------------------------------- SetBrainsToDefaults void SetBrainsToDefaults (DialogPtr theDialog) { SetDialogNumToStr(theDialog, kMaxFilesItem, 24L); #ifdef powerc wasTransit = false; #else wasTransit = true; #endif wasZooms = true; wasDemos = true; wasBackground = false; wasErrorCheck = true; wasPrettyMap = true; wasBitchDialogs = true; SetDialogItemValue(theDialog, kQuickTransitCheck, (short)wasTransit); SetDialogItemValue(theDialog, kDoZoomsCheck, (short)wasZooms); SetDialogItemValue(theDialog, kDoDemoCheck, (short)wasDemos); SetDialogItemValue(theDialog, kDoBackgroundCheck, (short)wasBackground); SetDialogItemValue(theDialog, kDoErrorCheck, (short)wasErrorCheck); SetDialogItemValue(theDialog, kDoPrettyMapCheck, (short)wasPrettyMap); SetDialogItemValue(theDialog, kDoBitchDlgsCheck, (short)wasBitchDialogs); } //-------------------------------------------------------------- UpdateSettingsBrains void UpdateSettingsBrains (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); SetDialogNumToStr(theDialog, kMaxFilesItem, (long)willMaxFiles); SelectDialogItemText(theDialog, kMaxFilesItem, 0, 1024); FrameDialogItemC(theDialog, 3, kRedOrangeColor8); } //-------------------------------------------------------------- BrainsFilter pascal Boolean BrainsFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; case kCapAKeyASCII: case kAKeyASCII: *item = kDoDemoCheck; return(true); break; case kCapBKeyASCII: case kBKeyASCII: *item = kDoBackgroundCheck; return(true); break; case kCapDKeyASCII: case kDKeyASCII: *item = kBrainsDefault; FlashDialogButton(dial, kBrainsDefault); return(true); break; case kCapEKeyASCII: case kEKeyASCII: *item = kDoErrorCheck; return(true); break; case kCapQKeyASCII: case kQKeyASCII: *item = kQuickTransitCheck; return(true); break; case kCapZKeyASCII: case kZKeyASCII: *item = kDoZoomsCheck; return(true); break; default: return(false); } break; case mouseDown: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateSettingsBrains(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- DoBrainsPrefs void DoBrainsPrefs (void) { DialogPtr prefDlg; long tempLong; short itemHit, wasMaxFiles; Boolean leaving; ModalFilterUPP brainsFilterUPP; brainsFilterUPP = NewModalFilterUPP(BrainsFilter); BringUpDialog(&prefDlg, kBrainsPrefsDialID); leaving = false; wasMaxFiles = willMaxFiles; wasTransit = quickerTransitions; wasZooms = doZooms; wasDemos = doAutoDemo; wasBackground = doBackground; wasErrorCheck = isHouseChecks; wasPrettyMap = doPrettyMap; wasBitchDialogs = doBitchDialogs; SetDialogItemValue(prefDlg, kQuickTransitCheck, (short)wasTransit); SetDialogItemValue(prefDlg, kDoZoomsCheck, (short)wasZooms); SetDialogItemValue(prefDlg, kDoDemoCheck, (short)wasDemos); SetDialogItemValue(prefDlg, kDoBackgroundCheck, (short)wasBackground); SetDialogItemValue(prefDlg, kDoErrorCheck, (short)wasErrorCheck); SetDialogItemValue(prefDlg, kDoPrettyMapCheck, (short)wasPrettyMap); SetDialogItemValue(prefDlg, kDoBitchDlgsCheck, (short)wasBitchDialogs); while (!leaving) { ModalDialog(brainsFilterUPP, &itemHit); switch (itemHit) { case kOkayButton: GetDialogNumFromStr(prefDlg, kMaxFilesItem, &tempLong); if (tempLong > 500) tempLong = 500; else if (tempLong < 12) tempLong = 12; willMaxFiles = tempLong; if (willMaxFiles != wasMaxFiles) nextRestartChange = true; quickerTransitions = wasTransit; doZooms = wasZooms; doAutoDemo = wasDemos; doBackground = wasBackground; isHouseChecks = wasErrorCheck; doPrettyMap = wasPrettyMap; doBitchDialogs = wasBitchDialogs; leaving = true; break; case kCancelButton: willMaxFiles = wasMaxFiles; leaving = true; break; case kQuickTransitCheck: wasTransit = !wasTransit; SetDialogItemValue(prefDlg, kQuickTransitCheck, (short)wasTransit); break; case kDoZoomsCheck: wasZooms = !wasZooms; SetDialogItemValue(prefDlg, kDoZoomsCheck, (short)wasZooms); break; case kDoDemoCheck: wasDemos = !wasDemos; SetDialogItemValue(prefDlg, kDoDemoCheck, (short)wasDemos); break; case kDoBackgroundCheck: wasBackground = !wasBackground; SetDialogItemValue(prefDlg, kDoBackgroundCheck, (short)wasBackground); break; case kBrainsDefault: SetBrainsToDefaults(prefDlg); break; case kDoErrorCheck: wasErrorCheck = !wasErrorCheck; SetDialogItemValue(prefDlg, kDoErrorCheck, (short)wasErrorCheck); break; case kDoPrettyMapCheck: wasPrettyMap = !wasPrettyMap; SetDialogItemValue(prefDlg, kDoPrettyMapCheck, (short)wasPrettyMap); break; case kDoBitchDlgsCheck: wasBitchDialogs = !wasBitchDialogs; SetDialogItemValue(prefDlg, kDoBitchDlgsCheck, (short)wasBitchDialogs); break; } } DisposeDialog(prefDlg); DisposeModalFilterUPP(brainsFilterUPP); } //-------------------------------------------------------------- SetControlsToDefaults void SetControlsToDefaults (DialogPtr theDialog) { PasStringCopy("\plf arrow", tempLeftStr); PasStringCopy("\prt arrow", tempRightStr); PasStringCopy("\pdn arrow", tempBattStr); PasStringCopy("\pup arrow", tempBandStr); tempLeftMap = kLeftArrowKeyMap; tempRightMap = kRightArrowKeyMap; tempBattMap = kDownArrowKeyMap; tempBandMap = kUpArrowKeyMap; wasEscPauseKey = false; SelectFromRadioGroup(theDialog, kTABPausesRadio, kESCPausesRadio, kTABPausesRadio); } //-------------------------------------------------------------- UpdateControlKeyName void UpdateControlKeyName (DialogPtr theDialog) { DrawDialogUserText(theDialog, kRightControl + 4, tempRightStr, whichCtrl == 0); DrawDialogUserText(theDialog, kLeftControl + 4, tempLeftStr, whichCtrl == 1); DrawDialogUserText(theDialog, kBattControl + 4, tempBattStr, whichCtrl == 2); DrawDialogUserText(theDialog, kBandControl + 4, tempBandStr, whichCtrl == 3); } //-------------------------------------------------------------- UpdateSettingsControl void UpdateSettingsControl (DialogPtr theDialog) { short i; DrawDialog(theDialog); PenSize(2, 2); ForeColor(whiteColor); for (i = 0; i < 4; i++) FrameRect(&controlRects[i]); ForeColor(redColor); FrameRect(&controlRects[whichCtrl]); ForeColor(blackColor); PenNormal(); UpdateControlKeyName(theDialog); FrameDialogItemC(theDialog, 3, kRedOrangeColor8); } //-------------------------------------------------------------- ControlFilter pascal Boolean ControlFilter (DialogPtr dial, EventRecord *event, short *item) { long wasKeyMap; switch (event->what) { case keyDown: switch (whichCtrl) { case 0: wasKeyMap = (long)GetKeyMapFromMessage(event->message); if ((wasKeyMap == tempLeftMap) || (wasKeyMap == tempBattMap) || (wasKeyMap == tempBandMap) || (wasKeyMap == kTabKeyMap) || (wasKeyMap == kEscKeyMap) || (wasKeyMap == kDeleteKeyMap)) { if (wasKeyMap == kEscKeyMap) { FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); } else SysBeep(1); } else { GetKeyName(event->message, tempRightStr); tempRightMap = wasKeyMap; } break; case 1: wasKeyMap = (long)GetKeyMapFromMessage(event->message); if ((wasKeyMap == tempRightMap) || (wasKeyMap == tempBattMap) || (wasKeyMap == tempBandMap) || (wasKeyMap == kTabKeyMap) || (wasKeyMap == kEscKeyMap) || (wasKeyMap == kDeleteKeyMap)) { if (wasKeyMap == kEscKeyMap) { FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); } else SysBeep(1); } else { GetKeyName(event->message, tempLeftStr); tempLeftMap = wasKeyMap; } break; case 2: wasKeyMap = (long)GetKeyMapFromMessage(event->message); if ((wasKeyMap == tempRightMap) || (wasKeyMap == tempLeftMap) || (wasKeyMap == tempBandMap) || (wasKeyMap == kTabKeyMap) || (wasKeyMap == kEscKeyMap) || (wasKeyMap == kDeleteKeyMap)) { if (wasKeyMap == kEscKeyMap) { FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); } else SysBeep(1); } else { GetKeyName(event->message, tempBattStr); tempBattMap = wasKeyMap; } break; case 3: wasKeyMap = (long)GetKeyMapFromMessage(event->message); if ((wasKeyMap == tempRightMap) || (wasKeyMap == tempLeftMap) || (wasKeyMap == tempBattMap) || (wasKeyMap == kTabKeyMap) || (wasKeyMap == kEscKeyMap) || (wasKeyMap == kDeleteKeyMap)) { if (wasKeyMap == kEscKeyMap) { FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); } else SysBeep(1); } else { GetKeyName(event->message, tempBandStr); tempBandMap = wasKeyMap; } break; } UpdateControlKeyName(dial); return(false); break; case mouseDown: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateSettingsControl(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- DoControlPrefs void DoControlPrefs (void) { DialogPtr prefDlg; short i, itemHit; Boolean leaving; ModalFilterUPP controlFilterUPP; controlFilterUPP = NewModalFilterUPP(ControlFilter); // CenterDialog(kControlPrefsDialID); prefDlg = GetNewDialog(kControlPrefsDialID, nil, kPutInFront); if (prefDlg == nil) RedAlert(kErrDialogDidntLoad); SetPort((GrafPtr)prefDlg); for (i = 0; i < 4; i++) { GetDialogItemRect(prefDlg, i + kRightControl, &controlRects[i]); InsetRect(&controlRects[i], -3, -3); } whichCtrl = 1; PasStringCopy(leftName, tempLeftStr); PasStringCopy(rightName, tempRightStr); PasStringCopy(batteryName, tempBattStr); PasStringCopy(bandName, tempBandStr); tempLeftMap = theGlider.leftKey; tempRightMap = theGlider.rightKey; tempBattMap = theGlider.battKey; tempBandMap = theGlider.bandKey; wasEscPauseKey = isEscPauseKey; leaving = false; ShowWindow(GetDialogWindow(prefDlg)); if (isEscPauseKey) SelectFromRadioGroup(prefDlg, kESCPausesRadio, kESCPausesRadio, kTABPausesRadio); else SelectFromRadioGroup(prefDlg, kTABPausesRadio, kESCPausesRadio, kTABPausesRadio); while (!leaving) { ModalDialog(controlFilterUPP, &itemHit); switch (itemHit) { case kOkayButton: PasStringCopy(tempLeftStr, leftName); PasStringCopy(tempRightStr, rightName); PasStringCopy(tempBattStr, batteryName); PasStringCopy(tempBandStr, bandName); theGlider.leftKey = tempLeftMap; theGlider.rightKey = tempRightMap; theGlider.battKey = tempBattMap; theGlider.bandKey = tempBandMap; isEscPauseKey = wasEscPauseKey; leaving = true; break; case kCancelButton: leaving = true; break; case kRightControl: case kLeftControl: case kBattControl: case kBandControl: PenSize(2, 2); ForeColor(whiteColor); FrameRect(&controlRects[whichCtrl]); whichCtrl = itemHit - kRightControl; ForeColor(redColor); FrameRect(&controlRects[whichCtrl]); ForeColor(blackColor); PenNormal(); UpdateControlKeyName(prefDlg); break; case kESCPausesRadio: case kTABPausesRadio: SelectFromRadioGroup(prefDlg, itemHit, kESCPausesRadio, kTABPausesRadio); wasEscPauseKey = !wasEscPauseKey; break; case kControlDefaults: SetControlsToDefaults(prefDlg); UpdateControlKeyName(prefDlg); break; } } DisposeDialog(prefDlg); DisposeModalFilterUPP(controlFilterUPP); } //-------------------------------------------------------------- SoundDefaults void SoundDefaults (DialogPtr theDialog) { wasIdle = true; wasPlay = true; SetDialogItemValue(theDialog, kIdleMusicItem, (short)wasIdle); SetDialogItemValue(theDialog, kPlayMusicItem, (short)wasPlay); UnivSetSoundVolume(3, thisMac.hasSM3); SetDialogNumToStr(theDialog, kVolNumberItem, 3L); HandleSoundMusicChange(3, true); } //-------------------------------------------------------------- UpdateSettingsSound void UpdateSettingsSound (DialogPtr theDialog) { short howLoudNow; DrawDialog(theDialog); DrawDefaultButton(theDialog); UnivGetSoundVolume(&howLoudNow, thisMac.hasSM3); if (howLoudNow >= 7) SetDialogNumToStr(theDialog, kVolNumberItem, 11L); else SetDialogNumToStr(theDialog, kVolNumberItem, (long)howLoudNow); FrameDialogItemC(theDialog, 11, kRedOrangeColor8); } //-------------------------------------------------------------- HandleSoundMusicChange void HandleSoundMusicChange (short newVolume, Boolean sayIt) { OSErr theErr; isSoundOn = (newVolume != 0); if (wasIdle) { if (newVolume == 0) StopTheMusic(); else { if (!isMusicOn) { theErr = StartMusic(); if (theErr != noErr) { YellowAlert(kYellowNoMusic, theErr); failedMusic = true; } } } } if ((newVolume != 0) && (sayIt)) PlayPrioritySound(kChord2Sound, kChord2Priority); } //-------------------------------------------------------------- SoundFilter pascal Boolean SoundFilter (DialogPtr dial, EventRecord *event, short *item) { short newVolume; switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; case kUpArrowKeyASCII: *item = kLouderItem; return(true); break; case kDownArrowKeyASCII: *item = kSofterItem; return(true); break; case k0KeyASCII: case k1KeyASCII: case k2KeyASCII: case k3KeyASCII: case k4KeyASCII: case k5KeyASCII: case k6KeyASCII: case k7KeyASCII: newVolume = (((event->message) & charCodeMask) - k0KeyASCII); if (newVolume == 7L) SetDialogNumToStr(dial, kVolNumberItem, 11L); else SetDialogNumToStr(dial, kVolNumberItem, (long)newVolume); UnivSetSoundVolume(newVolume, thisMac.hasSM3); HandleSoundMusicChange(newVolume, true); return(false); break; case kCapDKeyASCII: case kDKeyASCII: *item = kSoundDefault; FlashDialogButton(dial, kSoundDefault); return(true); break; case kCapGKeyASCII: case kGKeyASCII: *item = kPlayMusicItem; return(true); break; case kCapIKeyASCII: case kIKeyASCII: *item = kIdleMusicItem; return(true); break; default: return(false); } break; case mouseDown: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); UpdateSettingsSound(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- DoSettingsMain void DoSoundPrefs (void) { Rect tempRect; DialogPtr prefDlg; short wasLoudness, tempVolume; OSErr theErr; short itemHit; Boolean leaving; ModalFilterUPP soundFilterUPP; soundFilterUPP = NewModalFilterUPP(SoundFilter); BringUpDialog(&prefDlg, kSoundPrefsDialID); UnivGetSoundVolume(&wasLoudness, thisMac.hasSM3); wasIdle = isPlayMusicIdle; wasPlay = isPlayMusicGame; SetDialogItemValue(prefDlg, kIdleMusicItem, (short)wasIdle); SetDialogItemValue(prefDlg, kPlayMusicItem, (short)wasPlay); leaving = false; while (!leaving) { ModalDialog(soundFilterUPP, &itemHit); switch (itemHit) { case kOkayButton: isPlayMusicIdle = wasIdle; isPlayMusicGame = wasPlay; leaving = true; UnivGetSoundVolume(&tempVolume, thisMac.hasSM3); isSoundOn = (tempVolume != 0); break; case kCancelButton: UnivSetSoundVolume(wasLoudness, thisMac.hasSM3); HandleSoundMusicChange(wasLoudness, false); if (isPlayMusicIdle != wasIdle) { if (isPlayMusicIdle) { if (wasLoudness != 0) { theErr = StartMusic(); if (theErr != noErr) { YellowAlert(kYellowNoMusic, theErr); failedMusic = true; } } } else StopTheMusic(); } leaving = true; break; case kSofterItem: UnivGetSoundVolume(&tempVolume, thisMac.hasSM3); if (tempVolume > 0) { GetDialogItemRect(prefDlg, kSofterItem, &tempRect); DrawCIcon(1034, tempRect.left, tempRect.top); tempVolume--; SetDialogNumToStr(prefDlg, kVolNumberItem, (long)tempVolume); UnivSetSoundVolume(tempVolume, thisMac.hasSM3); HandleSoundMusicChange(tempVolume, true); InvalWindowRect(GetDialogWindow(prefDlg), &tempRect); DelayTicks(8); } break; case kLouderItem: UnivGetSoundVolume(&tempVolume, thisMac.hasSM3); if (tempVolume < 7) { GetDialogItemRect(prefDlg, kLouderItem, &tempRect); DrawCIcon(1033, tempRect.left, tempRect.top); tempVolume++; if (tempVolume == 7) SetDialogNumToStr(prefDlg, kVolNumberItem, 11L); else SetDialogNumToStr(prefDlg, kVolNumberItem, tempVolume); UnivSetSoundVolume(tempVolume, thisMac.hasSM3); HandleSoundMusicChange(tempVolume, true); InvalWindowRect(GetDialogWindow(prefDlg), &tempRect); DelayTicks(8); } break; case kIdleMusicItem: wasIdle = !wasIdle; SetDialogItemValue(prefDlg, kIdleMusicItem, (short)wasIdle); if (wasIdle) { UnivGetSoundVolume(&tempVolume, thisMac.hasSM3); if (tempVolume != 0) { theErr = StartMusic(); if (theErr != noErr) { YellowAlert(kYellowNoMusic, theErr); failedMusic = true; } } } else StopTheMusic(); break; case kPlayMusicItem: wasPlay = !wasPlay; SetDialogItemValue(prefDlg, kPlayMusicItem, (short)wasPlay); break; case kSoundDefault: SoundDefaults(prefDlg); break; } } DisposeDialog(prefDlg); DisposeModalFilterUPP(soundFilterUPP); } //-------------------------------------------------------------- DisplayDefaults void DisplayDefaults (void) { numNeighbors = 9; wasDepthPref = kSwitchIfNeeded; wasFade = true; wasScreen2 = false; } //-------------------------------------------------------------- FrameDisplayIcon void FrameDisplayIcon (DialogPtr theDialog) { Rect theRect; switch (numNeighbors) { case 1: GetDialogItemRect(theDialog, kDisplay1Item, &theRect); break; case 3: GetDialogItemRect(theDialog, kDisplay3Item, &theRect); break; default: GetDialogItemRect(theDialog, kDisplay9Item, &theRect); break; } theRect.left -= 3; theRect.top += 0; theRect.right += 3; theRect.bottom -= 1; FrameRect(&theRect); InsetRect(&theRect, 1, 1); FrameRect(&theRect); } //-------------------------------------------------------------- DisplayUpdate void DisplayUpdate (DialogPtr theDialog) { DrawDialog(theDialog); DrawDefaultButton(theDialog); SetDialogItemValue(theDialog, kDoColorFadeItem, (short)wasFade); SelectFromRadioGroup(theDialog, kCurrentDepth + wasDepthPref, kCurrentDepth, k16Depth); // SetDialogItemValue(theDialog, kUseQDItem, (short)wasQD); SetDialogItemValue(theDialog, kUseScreen2Item, (short)wasScreen2); ForeColor(redColor); FrameDisplayIcon(theDialog); ForeColor(blackColor); FrameDialogItemC(theDialog, 8, kRedOrangeColor8); FrameDialogItemC(theDialog, 13, kRedOrangeColor8); FrameDialogItemC(theDialog, 14, kRedOrangeColor8); } //-------------------------------------------------------------- DisplayFilter pascal Boolean DisplayFilter (DialogPtr dial, EventRecord *event, short *item) { switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kEscapeKeyASCII: FlashDialogButton(dial, kCancelButton); *item = kCancelButton; return(true); break; case kLeftArrowKeyASCII: switch (numNeighbors) { case 1: *item = kDisplay9Item; break; case 3: *item = kDisplay1Item; break; case 9: *item = kDisplay3Item; break; } return(true); break; case kRightArrowKeyASCII: switch (numNeighbors) { case 1: *item = kDisplay3Item; break; case 3: *item = kDisplay9Item; break; case 9: *item = kDisplay1Item; break; } return(true); break; case kUpArrowKeyASCII: switch (wasDepthPref) { case kSwitchIfNeeded: *item = k16Depth; break; case kSwitchTo256Colors: *item = kCurrentDepth; break; case kSwitchTo16Grays: *item = k256Depth; break; } return(true); break; case kDownArrowKeyASCII: switch (wasDepthPref) { case kSwitchIfNeeded: *item = k256Depth; break; case kSwitchTo256Colors: *item = k16Depth; break; case kSwitchTo16Grays: *item = kCurrentDepth; break; } return(true); break; case k1KeyASCII: *item = kDisplay1Item; return(true); break; case k3KeyASCII: *item = kDisplay3Item; return(true); break; case k9KeyASCII: *item = kDisplay9Item; return(true); break; case kCapBKeyASCII: case kBKeyASCII: *item = kDoColorFadeItem; return(true); break; case kCapDKeyASCII: case kDKeyASCII: *item = kDispDefault; FlashDialogButton(dial, kDispDefault); return(true); break; case kCapRKeyASCII: case kRKeyASCII: *item = kUseScreen2Item; FlashDialogButton(dial, kUseQDItem); return(true); break; case kCapUKeyASCII: case kUKeyASCII: *item = kUseQDItem; return(true); break; default: return(false); } break; case mouseDown: return(false); break; case updateEvt: SetPort((GrafPtr)dial); BeginUpdate(GetDialogWindow(dial)); DisplayUpdate(dial); EndUpdate(GetDialogWindow(dial)); event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- DoDisplayPrefs void DoDisplayPrefs (void) { DialogPtr prefDlg; short itemHit, wasNeighbors; Boolean leaving; ModalFilterUPP displayFilterUPP; displayFilterUPP = NewModalFilterUPP(DisplayFilter); BringUpDialog(&prefDlg, kDisplayPrefsDialID); if (!thisMac.can8Bit) { MyDisableControl(prefDlg, kDoColorFadeItem); MyDisableControl(prefDlg, k256Depth); } if (!thisMac.can4Bit) MyDisableControl(prefDlg, k16Depth); if (thisMac.numScreens < 2) MyDisableControl(prefDlg, kUseScreen2Item); wasNeighbors = numNeighbors; wasFade = isDoColorFade; wasDepthPref = isDepthPref; wasScreen2 = isUseSecondScreen; leaving = false; while (!leaving) { ModalDialog(displayFilterUPP, &itemHit); switch (itemHit) { case kOkayButton: isDoColorFade = wasFade; isDepthPref = wasDepthPref; if (isUseSecondScreen != wasScreen2) nextRestartChange = true; isUseSecondScreen = wasScreen2; leaving = true; break; case kCancelButton: numNeighbors = wasNeighbors; leaving = true; break; case kDisplay1Item: ForeColor(whiteColor); FrameDisplayIcon(prefDlg); numNeighbors = 1; ForeColor(redColor); FrameDisplayIcon(prefDlg); ForeColor(blackColor); break; case kDisplay3Item: if (thisMac.screen.right > 512) { ForeColor(whiteColor); FrameDisplayIcon(prefDlg); numNeighbors = 3; ForeColor(redColor); FrameDisplayIcon(prefDlg); ForeColor(blackColor); } break; case kDisplay9Item: if (thisMac.screen.right > 512) { ForeColor(whiteColor); FrameDisplayIcon(prefDlg); numNeighbors = 9; ForeColor(redColor); FrameDisplayIcon(prefDlg); ForeColor(blackColor); } break; case kDoColorFadeItem: wasFade = !wasFade; SetDialogItemValue(prefDlg, kDoColorFadeItem, (short)wasFade); break; case kCurrentDepth: case k256Depth: case k16Depth: wasDepthPref = itemHit - kCurrentDepth; SelectFromRadioGroup(prefDlg, itemHit, kCurrentDepth, k16Depth); break; case kDispDefault: ForeColor(whiteColor); FrameDisplayIcon(prefDlg); ForeColor(blackColor); DisplayDefaults(); DisplayUpdate(prefDlg); break; case kUseQDItem: // wasQD = !wasQD; // SetDialogItemValue(prefDlg, kUseQDItem, (short)wasQD); break; case kUseScreen2Item: wasScreen2 = !wasScreen2; SetDialogItemValue(prefDlg, kUseScreen2Item, (short)wasScreen2); break; } } DisposeDialog(prefDlg); DisposeModalFilterUPP(displayFilterUPP); } //-------------------------------------------------------------- SetAllDefaults void SetAllDefaults (void) { OSErr theErr; // Default brain settings willMaxFiles = 48; doZooms = true; doAutoDemo = true; doBackground = false; isHouseChecks = true; doPrettyMap = true; doBitchDialogs = true; // Default control settings PasStringCopy("\plf arrow", leftName); PasStringCopy("\prt arrow", rightName); PasStringCopy("\pdn arrow", batteryName); PasStringCopy("\pup arrow", bandName); theGlider.leftKey = kLeftArrowKeyMap; theGlider.rightKey = kRightArrowKeyMap; theGlider.battKey = kDownArrowKeyMap; theGlider.bandKey = kUpArrowKeyMap; isEscPauseKey = false; // Default sound settings isPlayMusicIdle = true; isPlayMusicGame = true; UnivSetSoundVolume(3, thisMac.hasSM3); isSoundOn = true; if (!isMusicOn) { theErr = StartMusic(); if (theErr != noErr) { YellowAlert(kYellowNoMusic, theErr); failedMusic = true; } } // Default display settings numNeighbors = 9; quickerTransitions = false; isDepthPref = kSwitchIfNeeded; isDoColorFade = true; } //-------------------------------------------------------------- FlashSettingsButton void FlashSettingsButton (short who) { #define kNormalSettingsIcon 1010 #define kInvertedSettingsIcon 1014 short theID; theID = kInvertedSettingsIcon + who; DrawCIcon (theID, prefButton[who].left + 4, prefButton[who].top + 4); DelayTicks(8); theID = kNormalSettingsIcon + who; DrawCIcon (theID, prefButton[who].left + 4, prefButton[who].top + 4); } //-------------------------------------------------------------- UpdateSettingsMain void UpdateSettingsMain (DialogPtr theDialog) { Str255 theStr; DrawDialog(theDialog); DrawDefaultButton(theDialog); GetIndString(theStr, 129, 1); DrawDialogUserText(theDialog, 7, theStr, false); GetIndString(theStr, 129, 2); DrawDialogUserText(theDialog, 8, theStr, false); GetIndString(theStr, 129, 3); DrawDialogUserText(theDialog, 9, theStr, false); GetIndString(theStr, 129, 4); DrawDialogUserText(theDialog, 10, theStr, false); ColorFrameRect(&prefButton[0], kRedOrangeColor8); ColorFrameRect(&prefButton[1], kRedOrangeColor8); ColorFrameRect(&prefButton[2], kRedOrangeColor8); ColorFrameRect(&prefButton[3], kRedOrangeColor8); } //-------------------------------------------------------------- PrefsFilter pascal Boolean PrefsFilter (DialogPtr dial, EventRecord *event, short *item) { Point testPt; short i; Boolean foundHit; switch (event->what) { case keyDown: switch ((event->message) & charCodeMask) { case kReturnKeyASCII: case kEnterKeyASCII: FlashDialogButton(dial, kOkayButton); *item = kOkayButton; return(true); break; case kCapBKeyASCII: case kBKeyASCII: *item = kBrainsButton; return(true); break; case kCapCKeyASCII: case kCKeyASCII: *item = kControlsButton; return(true); break; case kCapDKeyASCII: case kDKeyASCII: *item = kDisplayButton; return(true); break; case kCapSKeyASCII: case kSKeyASCII: *item = kSoundButton; return(true); break; default: return(false); } break; case mouseDown: testPt = event->where; GlobalToLocal(&testPt); foundHit = false; for (i = 0; i < 4; i++) { if (PtInRect(testPt, &prefButton[i])) { *item = kDisplayButton + i; foundHit = true; } } return(foundHit); break; case updateEvt: if ((WindowPtr)event->message == (WindowPtr)mainWindow) { SetPortWindowPort(mainWindow); BeginUpdate(mainWindow); UpdateMainWindow(); EndUpdate(mainWindow); SetPort((GrafPtr)dial); } else if ((WindowPtr)event->message == GetDialogWindow(dial)) { SetPortDialogPort(dial); BeginUpdate(GetDialogWindow(dial)); UpdateSettingsMain(dial); EndUpdate(GetDialogWindow(dial)); } event->what = nullEvent; return(false); break; default: return(false); break; } } //-------------------------------------------------------------- DoSettingsMain void DoSettingsMain (void) { #define kAllDefaultsButton 11 DialogPtr prefDlg; short itemHit; Boolean leaving; ModalFilterUPP prefsFilterUPP; prefsFilterUPP = NewModalFilterUPP(PrefsFilter); BringUpDialog(&prefDlg, kMainPrefsDialID); GetDialogItemRect(prefDlg, kDisplayButton, &prefButton[0]); InsetRect(&prefButton[0], -4, -4); GetDialogItemRect(prefDlg, 4, &prefButton[1]); InsetRect(&prefButton[1], -4, -4); GetDialogItemRect(prefDlg, 5, &prefButton[2]); InsetRect(&prefButton[2], -4, -4); GetDialogItemRect(prefDlg, 6, &prefButton[3]); InsetRect(&prefButton[3], -4, -4); leaving = false; nextRestartChange = false; while (!leaving) { ModalDialog(prefsFilterUPP, &itemHit); switch (itemHit) { case kOkayButton: leaving = true; break; case kDisplayButton: FlashSettingsButton(0); DoDisplayPrefs(); SetPort((GrafPtr)prefDlg); break; case kSoundButton: FlashSettingsButton(1); DoSoundPrefs(); SetPort((GrafPtr)prefDlg); FlushEvents(everyEvent, 0); break; case kControlsButton: FlashSettingsButton(2); DoControlPrefs(); SetPort((GrafPtr)prefDlg); break; case kBrainsButton: if ((OptionKeyDown()) && (!houseUnlocked)) { houseUnlocked = true; changeLockStateOfHouse = true; saveHouseLocked = false; } FlashSettingsButton(3); DoBrainsPrefs(); SetPort((GrafPtr)prefDlg); break; case kAllDefaultsButton: SetAllDefaults(); break; } } DisposeDialog(prefDlg); DisposeModalFilterUPP(prefsFilterUPP); if (nextRestartChange) BitchAboutChanges(); } //-------------------------------------------------------------- BitchAboutChanges void BitchAboutChanges (void) { #define kChangesEffectAlert 1040 short hitWhat; // CenterAlert(kChangesEffectAlert); hitWhat = Alert(kChangesEffectAlert, nil); } \ No newline at end of file diff --git a/Sources/Sound.c b/Sources/Sound.c deleted file mode 100755 index 6861749..0000000 --- a/Sources/Sound.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Sound.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include "Externs.h" #define kBaseBufferSoundID 1000 #define kMaxSounds 64 #define kNoSoundPlaying -1 pascal void CallBack0 (SndChannelPtr, SndCommand *); pascal void CallBack1 (SndChannelPtr, SndCommand *); pascal void CallBack2 (SndChannelPtr, SndCommand *); OSErr LoadBufferSounds (void); void DumpBufferSounds (void); OSErr OpenSoundChannels (void); OSErr CloseSoundChannels (void); SndCallBackUPP callBack0UPP, callBack1UPP, callBack2UPP; SndChannelPtr channel0, channel1, channel2; Ptr theSoundData[kMaxSounds]; short numSoundsLoaded, priority0, priority1, priority2; short soundPlaying0, soundPlaying1, soundPlaying2; Boolean soundLoaded[kMaxSounds], dontLoadSounds; Boolean channelOpen, isSoundOn, failedSound; //============================================================== Functions //-------------------------------------------------------------- PlayPrioritySound void PlayPrioritySound (short which, short priority) { short lowestPriority, whosLowest; if (failedSound || dontLoadSounds) return; if ((priority == kTriggerPriority) && ((priority0 == kTriggerPriority) || ((priority1 == kTriggerPriority)) || ((priority2 == kTriggerPriority)))) return; whosLowest = 0; lowestPriority = priority0; if (priority1 < lowestPriority) { lowestPriority = priority1; whosLowest = 1; } if (priority2 < lowestPriority) { lowestPriority = priority2; whosLowest = 2; } if (priority >= lowestPriority) { switch (whosLowest) { case 0: PlaySound0(which, priority); break; case 1: PlaySound1(which, priority); break; case 2: PlaySound2(which, priority); break; } } } //-------------------------------------------------------------- FlushAnyTriggerPlaying void FlushAnyTriggerPlaying (void) { SndCommand theCommand; OSErr theErr; if (priority0 == kTriggerPriority) { theCommand.cmd = quietCmd; theCommand.param1 = 0; theCommand.param2 = 0; theErr = SndDoImmediate(channel0, &theCommand); theCommand.cmd = flushCmd; theCommand.param1 = 0; theCommand.param2 = 0; theErr = SndDoImmediate(channel0, &theCommand); } if (priority1 == kTriggerPriority) { theCommand.cmd = quietCmd; theCommand.param1 = 0; theCommand.param2 = 0; theErr = SndDoImmediate(channel1, &theCommand); theCommand.cmd = flushCmd; theCommand.param1 = 0; theCommand.param2 = 0; theErr = SndDoImmediate(channel1, &theCommand); } if (priority2 == kTriggerPriority) { theCommand.cmd = quietCmd; theCommand.param1 = 0; theCommand.param2 = 0; theErr = SndDoImmediate(channel2, &theCommand); theCommand.cmd = flushCmd; theCommand.param1 = 0; theCommand.param2 = 0; theErr = SndDoImmediate(channel2, &theCommand); } } //-------------------------------------------------------------- PlaySound0 void PlaySound0 (short soundID, short priority) { SndCommand theCommand; OSErr theErr; if (failedSound || dontLoadSounds) return; theErr = noErr; if (isSoundOn) { priority0 = priority; soundPlaying0 = soundID; theCommand.cmd = bufferCmd; theCommand.param1 = 0; theCommand.param2 = (long)(theSoundData[soundID]); theErr = SndDoImmediate(channel0, &theCommand); theCommand.cmd = callBackCmd; theCommand.param1 = 0; theCommand.param2 = SetCurrentA5(); theErr = SndDoCommand(channel0, &theCommand, true); } } //-------------------------------------------------------------- PlaySound1 void PlaySound1 (short soundID, short priority) { SndCommand theCommand; OSErr theErr; if (failedSound || dontLoadSounds) return; theErr = noErr; if (isSoundOn) { priority1 = priority; soundPlaying1 = soundID; theCommand.cmd = bufferCmd; theCommand.param1 = 0; theCommand.param2 = (long)(theSoundData[soundID]); theErr = SndDoImmediate(channel1, &theCommand); theCommand.cmd = callBackCmd; theCommand.param1 = 0; theCommand.param2 = SetCurrentA5(); theErr = SndDoCommand(channel1, &theCommand, true); } } //-------------------------------------------------------------- PlaySound2 void PlaySound2 (short soundID, short priority) { SndCommand theCommand; OSErr theErr; if (failedSound || dontLoadSounds) return; theErr = noErr; if (isSoundOn) { theCommand.cmd = bufferCmd; theCommand.param1 = 0; theCommand.param2 = (long)(theSoundData[soundID]); theErr = SndDoImmediate(channel2, &theCommand); theCommand.cmd = callBackCmd; theCommand.param1 = 0; theCommand.param2 = SetCurrentA5(); theErr = SndDoCommand(channel2, &theCommand, true); priority2 = priority; soundPlaying2 = soundID; } } //-------------------------------------------------------------- CallBack0 pascal void CallBack0 (SndChannelPtr theChannel, SndCommand *theCommand) { #pragma unused (theChannel) long thisA5, gameA5; gameA5 = theCommand->param2; thisA5 = SetA5(gameA5); priority0 = 0; soundPlaying0 = kNoSoundPlaying; thisA5 = SetA5(thisA5); } //-------------------------------------------------------------- CallBack1 pascal void CallBack1 (SndChannelPtr theChannel, SndCommand *theCommand) { #pragma unused (theChannel) long thisA5, gameA5; gameA5 = theCommand->param2; thisA5 = SetA5(gameA5); priority1 = 0; soundPlaying1 = kNoSoundPlaying; thisA5 = SetA5(thisA5); } //-------------------------------------------------------------- CallBack2 pascal void CallBack2 (SndChannelPtr theChannel, SndCommand *theCommand) { #pragma unused (theChannel) long thisA5, gameA5; gameA5 = theCommand->param2; thisA5 = SetA5(gameA5); priority2 = 0; soundPlaying2 = kNoSoundPlaying; thisA5 = SetA5(thisA5); } //-------------------------------------------------------------- LoadTriggerSound OSErr LoadTriggerSound (short soundID) { Handle theSound; long soundDataSize; OSErr theErr; if ((dontLoadSounds) || (theSoundData[kMaxSounds - 1] != nil)) theErr = -1; else { // FlushAnyTriggerPlaying(); theErr = noErr; theSound = GetResource('snd ', soundID); if (theSound == nil) { theErr = -1; } else { soundDataSize = GetHandleSize(theSound) - 20L; theSoundData[kMaxSounds - 1] = NewPtr(soundDataSize); HLock(theSound); if (theSoundData[kMaxSounds - 1] == nil) { ReleaseResource(theSound); theErr = MemError(); } else { BlockMove((Ptr)(*theSound + 20L), theSoundData[kMaxSounds - 1], soundDataSize); ReleaseResource(theSound); } } } return (theErr); } //-------------------------------------------------------------- DumpTriggerSound void DumpTriggerSound (void) { if (theSoundData[kMaxSounds - 1] != nil) DisposePtr(theSoundData[kMaxSounds - 1]); theSoundData[kMaxSounds - 1] = nil; } //-------------------------------------------------------------- LoadBufferSounds OSErr LoadBufferSounds (void) { Handle theSound; long soundDataSize; OSErr theErr; short i; theErr = noErr; for (i = 0; i < kMaxSounds - 1; i++) { theSound = GetResource('snd ', i + kBaseBufferSoundID); if (theSound == nil) return (MemError()); HLock(theSound); soundDataSize = GetHandleSize(theSound) - 20L; HUnlock(theSound); theSoundData[i] = NewPtr(soundDataSize); if (theSoundData[i] == nil) return (MemError()); HLock(theSound); BlockMove((Ptr)(*theSound + 20L), theSoundData[i], soundDataSize); ReleaseResource(theSound); } theSoundData[kMaxSounds - 1] = nil; return (theErr); } //-------------------------------------------------------------- DumpBufferSounds void DumpBufferSounds (void) { short i; for (i = 0; i < kMaxSounds; i++) { if (theSoundData[i] != nil) DisposePtr(theSoundData[i]); theSoundData[i] = nil; } } //-------------------------------------------------------------- OpenSoundChannels OSErr OpenSoundChannels (void) { OSErr theErr; callBack0UPP = NewSndCallBackProc(CallBack0); callBack1UPP = NewSndCallBackProc(CallBack1); callBack2UPP = NewSndCallBackProc(CallBack2); theErr = noErr; if (channelOpen) return (theErr); theErr = SndNewChannel(&channel0, sampledSynth, initNoInterp + initMono, (SndCallBackUPP)callBack0UPP); if (theErr == noErr) channelOpen = true; else return (theErr); theErr = SndNewChannel(&channel1, sampledSynth, initNoInterp + initMono, (SndCallBackUPP)callBack1UPP); if (theErr == noErr) channelOpen = true; else return (theErr); theErr = SndNewChannel(&channel2, sampledSynth, initNoInterp + initMono, (SndCallBackUPP)callBack2UPP); if (theErr == noErr) channelOpen = true; return (theErr); } //-------------------------------------------------------------- CloseSoundChannels OSErr CloseSoundChannels (void) { OSErr theErr; theErr = noErr; if (!channelOpen) return (theErr); if (channel0 != nil) theErr = SndDisposeChannel(channel0, true); channel0 = nil; if (channel1 != nil) theErr = SndDisposeChannel(channel1, true); channel1 = nil; if (channel2 != nil) theErr = SndDisposeChannel(channel2, true); channel2 = nil; if (theErr == noErr) channelOpen = false; DisposeSndCallBackUPP(callBack0UPP); DisposeSndCallBackUPP(callBack1UPP); DisposeSndCallBackUPP(callBack2UPP); return (theErr); } //-------------------------------------------------------------- InitSound void InitSound (void) { OSErr theErr; if (dontLoadSounds) return; failedSound = false; channel0 = nil; channel1 = nil; channel2 = nil; priority0 = 0; priority1 = 0; priority2 = 0; soundPlaying0 = kNoSoundPlaying; soundPlaying1 = kNoSoundPlaying; soundPlaying2 = kNoSoundPlaying; theErr = LoadBufferSounds(); if (theErr != noErr) { YellowAlert(kYellowFailedSound, theErr); failedSound = true; } if (!failedSound) { theErr = OpenSoundChannels(); if (theErr != noErr) { YellowAlert(kYellowFailedSound, theErr); failedSound = true; } } } //-------------------------------------------------------------- KillSound void KillSound (void) { OSErr theErr; if (dontLoadSounds) return; DumpBufferSounds(); theErr = CloseSoundChannels(); } //-------------------------------------------------------------- SoundBytesNeeded long SoundBytesNeeded (void) { Handle theSound; long totalBytes; short i; totalBytes = 0L; SetResLoad(false); for (i = 0; i < kMaxSounds - 1; i++) { theSound = GetResource('snd ', i + kBaseBufferSoundID); if (theSound == nil) { SetResLoad(true); return ((long)ResError()); } totalBytes += GetMaxResourceSize(theSound); // ReleaseResource(theSound); } SetResLoad(true); return totalBytes; } //-------------------------------------------------------------- TellHerNoSounds void TellHerNoSounds (void) { #define kNoMemForSoundsAlert 1039 short hitWhat; // CenterAlert(kNoMemForSoundsAlert); hitWhat = Alert(kNoMemForSoundsAlert, nil); } //-------------------------------------------------------------- BitchAboutSM3 void BitchAboutSM3 (void) { #define kNoSoundManager3Alert 1030 short hitWhat; // CenterAlert(kNoSoundManager3Alert); hitWhat = Alert(kNoSoundManager3Alert, nil); } \ No newline at end of file diff --git a/Sources/StringUtils.c b/Sources/StringUtils.c deleted file mode 100755 index 9f317f2..0000000 --- a/Sources/StringUtils.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // StringUtils.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" //============================================================== Functions //-------------------------------------------------------------- PasStringCopy // Given a source string and storage for a second, this functionÉ // copies from one to the other. It assumes Pascal style strings. void PasStringCopy (StringPtr p1, StringPtr p2) { register short stringLength; stringLength = *p2++ = *p1++; while (--stringLength >= 0) *p2++ = *p1++; } //-------------------------------------------------------------- WhichStringFirst // This is a sorting function that handles two Pascal strings. ItÉ // will return a 1 to indicate the 1st string is "greater", a 1 toÉ // indicate the 2nd was greater and a 0 to indicate that the stringsÉ // are equal. short WhichStringFirst (StringPtr p1, StringPtr p2) { short smallestLength, seek, greater; char char1, char2; Boolean foundIt; smallestLength = p1[0]; if (p2[0] < smallestLength) smallestLength = p2[0]; greater = 0; // neither are greater, they are equal seek = 1; // start at character #1 foundIt = false; do { char1 = p1[seek]; // make upper case (if applicable) if ((char1 > 0x60) && (char1 < 0x7B)) char1 -= 0x20; char2 = p2[seek]; // make upper case (if applicable) if ((char2 > 0x60) && (char2 < 0x7B)) char2 -= 0x20; if (char1 > char2) // first string is greater { greater = 1; foundIt = true; } else if (char1 < char2) // second string is greater { greater = 2; foundIt = true; } seek++; if (seek > smallestLength) // we've reached the end of the line { if (!foundIt) { if (p1[0] < p2[0]) // shortest string wins greater = 1; else if (p1[0] > p2[0]) greater = 2; } foundIt = true; } } while (!foundIt); return (greater); } //-------------------------------------------------------------- PasStringCopyNum // This function copies a specified number of characters from oneÉ // Pascal string to another. void PasStringCopyNum (StringPtr p1, StringPtr p2, short charsToCopy) { short i; if (charsToCopy > *p1) // if trying to copy more chars than there are charsToCopy = *p1; // reduce the number of chars to copy to this size *p2 = charsToCopy; *p2++; *p1++; for (i = 0; i < charsToCopy; i++) *p2++ = *p1++; } //-------------------------------------------------------------- PasStringConcat // This function concatenates the second Pascal string to the end ofÉ // the first Pascal string. void PasStringConcat (StringPtr p1, StringPtr p2) { short wasLength, addedLength, i; wasLength = *p1; if (wasLength > 255) wasLength = 255; addedLength = *p2; if ((wasLength + addedLength) > 255) addedLength = 255 - wasLength; *p1 = wasLength + addedLength; *p1++; *p2++; for (i = 0; i < wasLength; i++) *p1++; for (i = 0; i < addedLength; i++) *p1++ = *p2++; } //-------------------------------------------------------------- GetLineOfText // This function walks through a source string and looks for anÉ // entire line of text. A "line" of text is assumed to be boundedÉ // by carriage returns. The index variable indicates which lineÉ // is sought. void GetLineOfText (StringPtr srcStr, short index, StringPtr textLine) { short i, srcLength, count, start, stop; Boolean foundIt; PasStringCopy("\p", textLine); srcLength = srcStr[0]; if (index == 0) // walk through to "index" start = 1; else { start = 0; count = 0; i = 0; foundIt = false; do { i++; if (srcStr[i] == kReturnKeyASCII) { count++; if (count == index) { start = i + 1; foundIt = true; } } } while ((i < srcLength) && (!foundIt)); } if (start != 0) { i = start; foundIt = false; do { if (srcStr[i] == kReturnKeyASCII) { stop = i; foundIt = true; } i++; } while ((i < srcLength) && (!foundIt)); if (!foundIt) { if (start > srcLength) { start = srcLength; stop = srcLength - 1; } else stop = i; } count = 0; for (i = start; i <= stop; i++) { count++; textLine[count] = srcStr[i]; } textLine[0] = count; } } //-------------------------------------------------------------- WrapText // Given a string and the maximum number of characters to put onÉ // one line, this function goes through and inserts carriage returnsÉ // in order to ensure that no line of text exceeds maxChars. void WrapText (StringPtr theText, short maxChars) { short lastChar, count, chars, spaceIs; Boolean foundEdge, foundSpace; lastChar = theText[0]; count = 0; do { chars = 0; foundEdge = false; foundSpace = false; do { count++; chars++; if (theText[count] == kReturnKeyASCII) foundEdge = true; else if (theText[count] == kSpaceBarASCII) { foundSpace = true; spaceIs = count; } } while ((count < lastChar) && (chars < maxChars) && (!foundEdge)); if ((!foundEdge) && (count < lastChar) && (foundSpace)) { theText[spaceIs] = kReturnKeyASCII; count = spaceIs + 1; } } while (count < lastChar); } //-------------------------------------------------------------- GetFirstWordOfString // Walks a string looking for a space (denoting first word of string). void GetFirstWordOfString (StringPtr stringIn, StringPtr stringOut) { short isLong, spaceAt, i; isLong = stringIn[0]; spaceAt = isLong; for (i = 1; i < isLong; i++) { if ((stringIn[i] == ' ') && (spaceAt == isLong)) spaceAt = i - 1; } if (spaceAt <= 0) PasStringCopy("\p", stringOut); else PasStringCopyNum(stringIn, stringOut, spaceAt); } //-------------------------------------------------------------- CollapseStringToWidth // Given a string and a maximum width (in pixels), this functionÉ // calculates how wide the text would be drawn with the currentÉ // font. If the text would exceed our width limit, charactersÉ // are dropped off the end of the string and "É" appended. void CollapseStringToWidth (StringPtr theStr, short wide) { short dotsWide; Boolean tooWide; dotsWide = StringWidth("\pÉ"); tooWide = StringWidth(theStr) > wide; while (tooWide) { theStr[0]--; tooWide = ((StringWidth(theStr) + dotsWide) > wide); if (!tooWide) PasStringConcat(theStr, "\pÉ"); } } //-------------------------------------------------------------- GetChooserName // This function extracts the user name stored away by the Chooser. void GetChooserName (StringPtr thisName) { #define kChooserStringID -16096 Handle theNameHandle; Byte oldState; theNameHandle = (Handle)GetString(kChooserStringID); if (theNameHandle != nil) { oldState = HGetState(theNameHandle); HLock(theNameHandle); PasStringCopy((StringPtr)*theNameHandle, thisName); HSetState(theNameHandle, oldState); } else thisName[0] = 0; } //-------------------------------------------------------------- GetLocalizedString StringPtr GetLocalizedString (short index, StringPtr theString) { #define kLocalizedStringsID 150 GetIndString(theString, kLocalizedStringsID, index); return (theString); } \ No newline at end of file diff --git a/Sources/StructuresInit.c b/Sources/StructuresInit.c deleted file mode 100755 index 9153acf..0000000 --- a/Sources/StructuresInit.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // StructuresInit.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "Objects.h" #include "Play.h" #include "Player.h" #include "RectUtils.h" #include "RubberBands.h" #include "Scoreboard.h" #include "Utilities.h" #define kShadowPictID 3998 #define kBlowerPictID 4000 #define kFurniturePictID 4001 #define kBonusPictID 4002 #define kSwitchPictID 4003 #define kLightPictID 4004 #define kAppliancePictID 4005 #define kPointsPictID 4006 #define kRubberBandsPictID 4007 #define kTransportPictID 4008 #define kToastPictID 4009 #define kShreddedPictID 4010 #define kBalloonPictID 4011 #define kCopterPictID 4012 #define kDartPictID 4013 #define kBallPictID 4014 #define kDripPictID 4015 #define kEnemyPictID 4016 #define kFishPictID 4017 #define kBadgePictID 1996 extern Rect glidSrcRect, leftStartGliderSrc, rightStartGliderSrc; extern Rect gliderSrc[], shadowSrcRect, shadowSrc[]; extern Rect bandsSrcRect, bandRects[], boardSrcRect, boardDestRect; extern Rect boardTSrcRect, boardTDestRect, badgeSrcRect; extern Rect boardGSrcRect, boardGDestRect, boardPSrcRect, boardPDestRect; extern Rect boardPQDestRect, boardGQDestRect, badgesBlankRects[]; extern Rect badgesBadgesRects[], badgesDestRects[]; extern Rect nailSrcRect, sparkleSrc[]; extern Rect pointsSrc[], breadSrc[]; extern short wasScoreboardMode; //============================================================== Functions //-------------------------------------------------------------- InitScoreboardMap // Any graphics and structures relating to the scoreboard that appearsÉ // across the top of the game are initialized and loaded up here. void InitScoreboardMap (void) { Rect bounds; PicHandle thePicture; CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; short hOffset; GetGWorld(&wasCPort, &wasWorld); wasScoreboardMode = kScoreboardHigh; boardSrcRect = houseRect; ZeroRectCorner(&boardSrcRect); boardSrcRect.bottom = kScoreboardTall; theErr = CreateOffScreenGWorld(&boardSrcMap, &boardSrcRect, kPreferredDepth); SetGWorld(boardSrcMap, nil); if (boardSrcRect.right >= 640) hOffset = (RectWide(&boardSrcRect) - kMaxViewWidth) / 2; else hOffset = -576; thePicture = GetPicture(kScoreboardPictID); if (thePicture == nil) RedAlert(kErrFailedGraphicLoad); HLock((Handle)thePicture); bounds = (*thePicture)->picFrame; HUnlock((Handle)thePicture); QOffsetRect(&bounds, -bounds.left, -bounds.top); QOffsetRect(&bounds, hOffset, 0); DrawPicture(thePicture, &bounds); ReleaseResource((Handle)thePicture); QSetRect(&badgeSrcRect, 0, 0, 32, 66); // 2144 pixels theErr = CreateOffScreenGWorld(&badgeSrcMap, &badgeSrcRect, kPreferredDepth); SetGWorld(badgeSrcMap, nil); LoadGraphic(kBadgePictID); boardDestRect = boardSrcRect; QOffsetRect(&boardDestRect, 0, -kScoreboardTall); hOffset = (RectWide(&houseRect) - 640) / 2; if (hOffset < 0) hOffset = -128; QSetRect(&boardTSrcRect, 0, 0, 256, 12); // room title theErr = CreateOffScreenGWorld(&boardTSrcMap, &boardTSrcRect, kPreferredDepth); SetGWorld(boardTSrcMap, nil); boardTDestRect = boardTSrcRect; QOffsetRect(&boardTDestRect, 137 + hOffset, 5); TextFont(applFont); TextSize(12); TextFace(bold); QSetRect(&boardGSrcRect, 0, 0, 20, 10); // # gliders theErr = CreateOffScreenGWorld(&boardGSrcMap, &boardGSrcRect, kPreferredDepth); SetGWorld(boardGSrcMap, nil); boardGDestRect = boardGSrcRect; QOffsetRect(&boardGDestRect, 526 + hOffset, 5); TextFont(applFont); TextSize(12); TextFace(bold); QSetRect(&boardPSrcRect, 0, 0, 64, 10); // points theErr = CreateOffScreenGWorld(&boardPSrcMap, &boardPSrcRect, kPreferredDepth); SetGWorld(boardPSrcMap, nil); boardPDestRect = boardPSrcRect; QOffsetRect(&boardPDestRect, 570 + hOffset, 5); // total = 6396 pixels boardPQDestRect = boardPDestRect; QOffsetRect(&boardPQDestRect, 0, -kScoreboardTall); boardGQDestRect = boardGDestRect; QOffsetRect(&boardGQDestRect, 0, -kScoreboardTall); TextFont(applFont); TextSize(12); TextFace(bold); QSetRect(&badgesBlankRects[0], 0, 0, 16, 16); // foil QOffsetRect(&badgesBlankRects[0], 0, 0); QSetRect(&badgesBlankRects[1], 0, 0, 16, 16); // rubber bands QOffsetRect(&badgesBlankRects[1], 0, 16); QSetRect(&badgesBlankRects[2], 0, 0, 16, 17); // battery QOffsetRect(&badgesBlankRects[2], 0, 32); QSetRect(&badgesBlankRects[3], 0, 0, 16, 17); // helium QOffsetRect(&badgesBlankRects[3], 0, 49); QSetRect(&badgesBadgesRects[0], 0, 0, 16, 16); // foil QOffsetRect(&badgesBadgesRects[0], 16, 0); QSetRect(&badgesBadgesRects[1], 0, 0, 16, 16); // rubber bands QOffsetRect(&badgesBadgesRects[1], 16, 16); QSetRect(&badgesBadgesRects[2], 0, 0, 16, 17); // battery QOffsetRect(&badgesBadgesRects[2], 16, 32); QSetRect(&badgesBadgesRects[3], 0, 0, 16, 17); // helium QOffsetRect(&badgesBadgesRects[3], 16, 49); QSetRect(&badgesDestRects[0], 0, 0, 16, 16); // foil QOffsetRect(&badgesDestRects[0], 432 + hOffset, 2 - kScoreboardTall); QSetRect(&badgesDestRects[1], 0, 0, 16, 16); // rubber bands QOffsetRect(&badgesDestRects[1], 449 + hOffset, 2 - kScoreboardTall); QSetRect(&badgesDestRects[2], 0, 0, 16, 17); // battery QOffsetRect(&badgesDestRects[2], 467 + hOffset, 1 - kScoreboardTall); QSetRect(&badgesDestRects[3], 0, 0, 16, 17); // helium QOffsetRect(&badgesDestRects[3], 467 + hOffset, 1 - kScoreboardTall); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitGliderMap // Graphics and structures relating to the little paper glider (theÉ // player) are cretaed, loaded up and initialized here. void InitGliderMap (void) { CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; short i; GetGWorld(&wasCPort, &wasWorld); QSetRect(&glidSrcRect, 0, 0, kGliderWide, 668); // 32112 pixels theErr = CreateOffScreenGWorld(&glidSrcMap, &glidSrcRect, kPreferredDepth); SetGWorld(glidSrcMap, nil); LoadGraphic(kGliderPictID); theErr = CreateOffScreenGWorld(&glid2SrcMap, &glidSrcRect, kPreferredDepth); SetGWorld(glid2SrcMap, nil); LoadGraphic(kGlider2PictID); theErr = CreateOffScreenGWorld(&glidMaskMap, &glidSrcRect, 1); SetGWorld(glidMaskMap, nil); LoadGraphic(kGliderPictID + 1000); for (i = 0; i <= 20; i++) { QSetRect(&gliderSrc[i], 0, 0, kGliderWide, kGliderHigh); QOffsetRect(&gliderSrc[i], 0, kGliderHigh * i); } for (i = 21; i <= 28; i++) { QSetRect(&gliderSrc[i], 0, 0, kGliderWide, kGliderBurningHigh); QOffsetRect(&gliderSrc[i], 0, 420 + (kGliderBurningHigh * (i - 21))); } QSetRect(&gliderSrc[29], 0, 0, kGliderWide, kGliderHigh); QOffsetRect(&gliderSrc[29], 0, 628); QSetRect(&gliderSrc[30], 0, 0, kGliderWide, kGliderHigh); QOffsetRect(&gliderSrc[30], 0, 648); QSetRect(&shadowSrcRect, 0, 0, kGliderWide, kShadowHigh * kNumShadowSrcRects); theErr = CreateOffScreenGWorld(&shadowSrcMap, &shadowSrcRect, kPreferredDepth); SetGWorld(shadowSrcMap, nil); LoadGraphic(kShadowPictID); theErr = CreateOffScreenGWorld(&shadowMaskMap, &shadowSrcRect, 1); SetGWorld(shadowMaskMap, nil); LoadGraphic(kShadowPictID + 1000); for (i = 0; i < kNumShadowSrcRects; i++) { QSetRect(&shadowSrc[i], 0, 0, kGliderWide, kShadowHigh); QOffsetRect(&shadowSrc[i], 0, kShadowHigh * i); } QSetRect(&bandsSrcRect, 0, 0, 16, 18); // 304 pixels theErr = CreateOffScreenGWorld(&bandsSrcMap, &bandsSrcRect, kPreferredDepth); SetGWorld(bandsSrcMap, nil); LoadGraphic(kRubberBandsPictID); theErr = CreateOffScreenGWorld(&bandsMaskMap, &bandsSrcRect, 1); SetGWorld(bandsMaskMap, nil); LoadGraphic(kRubberBandsPictID + 1000); for (i = 0; i < 3; i++) { QSetRect(&bandRects[i], 0, 0, 16, 6); QOffsetRect(&bandRects[i], 0, 6 * i); } SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitBlowers // All blower graphics and structures are loaded up and initialized here. // Blowers include vents, ducts, candles, fans, etc. void InitBlowers (void) { CGrafPtr wasCPort; GDHandle wasWorld; short i; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&blowerSrcRect, 0, 0, 48, 402); // 19344 pixels theErr = CreateOffScreenGWorld(&blowerSrcMap, &blowerSrcRect, kPreferredDepth); SetGWorld(blowerSrcMap, nil); LoadGraphic(kBlowerPictID); theErr = CreateOffScreenGWorld(&blowerMaskMap, &blowerSrcRect, 1); SetGWorld(blowerMaskMap, nil); LoadGraphic(kBlowerPictID + 1000); for (i = 0; i < kNumCandleFlames; i++) { QSetRect(&flame[i], 0, 0, 16, 15); QOffsetRect(&flame[i], 32, 179 + (i * 15)); } for (i = 0; i < kNumTikiFlames; i++) { QSetRect(&tikiFlame[i], 0, 0, 8, 10); QOffsetRect(&tikiFlame[i], 40, 69 + (i * 10)); } for (i = 0; i < kNumBBQCoals; i++) { QSetRect(&coals[i], 0, 0, 32, 9); QOffsetRect(&coals[i], 0, 304 + (i * 9)); } QSetRect(&leftStartGliderSrc, 0, 0, 48, 16); QOffsetRect(&leftStartGliderSrc, 0, 358); QSetRect(&rightStartGliderSrc, 0, 0, 48, 16); QOffsetRect(&rightStartGliderSrc, 0, 374); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitFurniture // Structures and graphics relating to the furniture is loaded up. // Furniture includes tables, cabinets, shelves, etc. void InitFurniture (void) { CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&furnitureSrcRect, 0, 0, 64, 278); // 17856 pixels theErr = CreateOffScreenGWorld(&furnitureSrcMap, &furnitureSrcRect, kPreferredDepth); SetGWorld(furnitureSrcMap, nil); LoadGraphic(kFurniturePictID); theErr = CreateOffScreenGWorld(&furnitureMaskMap, &furnitureSrcRect, 1); SetGWorld(furnitureMaskMap, nil); LoadGraphic(kFurniturePictID + 1000); QSetRect(&tableSrc, 0, 0, 64, 22); QOffsetRect(&tableSrc, 0, 0); QSetRect(&shelfSrc, 0, 0, 16, 21); QOffsetRect(&shelfSrc, 0, 22); QSetRect(&hingeSrc, 0, 0, 4, 16); QOffsetRect(&hingeSrc, 16, 22); QSetRect(&handleSrc, 0, 0, 4, 21); QOffsetRect(&handleSrc, 20, 22); QSetRect(&knobSrc, 0, 0, 8, 8); QOffsetRect(&knobSrc, 24, 22); QSetRect(&leftFootSrc, 0, 0, 16, 16); QOffsetRect(&leftFootSrc, 32, 22); QSetRect(&rightFootSrc, 0, 0, 16, 16); QOffsetRect(&rightFootSrc, 48, 22); QSetRect(&deckSrc, 0, 0, 64, 21); QOffsetRect(&deckSrc, 0, 162); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitPrizes // Structures and graphics relating to the prizes (bonuses) are loaded up. // Prizes includes clocks, rubber bands, extra gliders, etc. void InitPrizes (void) { CGrafPtr wasCPort; GDHandle wasWorld; short i; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&bonusSrcRect, 0, 0, 88, 378); // 33264 pixels theErr = CreateOffScreenGWorld(&bonusSrcMap, &bonusSrcRect, kPreferredDepth); SetGWorld(bonusSrcMap, nil); LoadGraphic(kBonusPictID); theErr = CreateOffScreenGWorld(&bonusMaskMap, &bonusSrcRect, 1); SetGWorld(bonusMaskMap, nil); LoadGraphic(kBonusPictID + 1000); for (i = 0; i < 11; i++) { QSetRect(&digits[i], 0, 0, 4, 6); QOffsetRect(&digits[i], 28, i * 6); } for (i = 0; i < 3; i++) { QSetRect(&pendulumSrc[i], 0, 0, 32, 28); QOffsetRect(&pendulumSrc[i], 56, 186 + (i * 28)); } QSetRect(&greaseSrcRt[0], 0, 0, 32, 27); QOffsetRect(&greaseSrcRt[0], 0, 243); QSetRect(&greaseSrcRt[1], 0, 0, 32, 27); QOffsetRect(&greaseSrcRt[1], 0, 270); QSetRect(&greaseSrcRt[2], 0, 0, 32, 27); QOffsetRect(&greaseSrcRt[2], 0, 297); QSetRect(&greaseSrcRt[3], 0, 0, 32, 27); QOffsetRect(&greaseSrcRt[3], 32, 297); QSetRect(&greaseSrcLf[0], 0, 0, 32, 27); QOffsetRect(&greaseSrcLf[0], 0, 324); QSetRect(&greaseSrcLf[1], 0, 0, 32, 27); QOffsetRect(&greaseSrcLf[1], 32, 324); QSetRect(&greaseSrcLf[2], 0, 0, 32, 27); QOffsetRect(&greaseSrcLf[2], 0, 351); QSetRect(&greaseSrcLf[3], 0, 0, 32, 27); QOffsetRect(&greaseSrcLf[3], 32, 351); for (i = 0; i < 6; i++) { QSetRect(&starSrc[i], 0, 0, 32, 31); QOffsetRect(&starSrc[i], 48, i * 31); } for (i = 0; i < 3; i++) { QSetRect(&sparkleSrc[i + 2], 0, 0, 20, 19); QOffsetRect(&sparkleSrc[i + 2], 0, 70 + (i * 19)); } sparkleSrc[0] = sparkleSrc[4]; sparkleSrc[1] = sparkleSrc[3]; QSetRect(&pointsSrcRect, 0, 0, 24, 120); // 2880 pixels theErr = CreateOffScreenGWorld(&pointsSrcMap, &pointsSrcRect, kPreferredDepth); SetGWorld(pointsSrcMap, nil); LoadGraphic(kPointsPictID); theErr = CreateOffScreenGWorld(&pointsMaskMap, &pointsSrcRect, 1); SetGWorld(pointsMaskMap, nil); LoadGraphic(kPointsPictID + 1000); for (i = 0; i < 15; i++) { QSetRect(&pointsSrc[i], 0, 0, 24, 8); QOffsetRect(&pointsSrc[i], 0, i * 8); } SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitTransports // Structures and graphics relating to the transports is loaded up. // Transports includes transport ducts, mailboxes, etc. void InitTransports (void) { CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; QSetRect(&transSrcRect, 0, 0, 56, 32); // 1848 pixels theErr = CreateOffScreenGWorld(&transSrcMap, &transSrcRect, kPreferredDepth); SetGWorld(transSrcMap, nil); LoadGraphic(kTransportPictID); theErr = CreateOffScreenGWorld(&transMaskMap, &transSrcRect, 1); SetGWorld(transMaskMap, nil); LoadGraphic(kTransportPictID + 1000); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitSwitches // Structures and graphics relating to switches are loaded up. // Switches includes triggers, light switches, etc. void InitSwitches (void) { CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&switchSrcRect, 0, 0, 32, 104); // 3360 pixels theErr = CreateOffScreenGWorld(&switchSrcMap, &switchSrcRect, kPreferredDepth); SetGWorld(switchSrcMap, nil); LoadGraphic(kSwitchPictID); QSetRect(&lightSwitchSrc[0], 0, 0, 15, 24); QOffsetRect(&lightSwitchSrc[0], 0, 0); QSetRect(&lightSwitchSrc[1], 0, 0, 15, 24); QOffsetRect(&lightSwitchSrc[1], 16, 0); QSetRect(&machineSwitchSrc[0], 0, 0, 16, 24); QOffsetRect(&machineSwitchSrc[0], 0, 24); QSetRect(&machineSwitchSrc[1], 0, 0, 16, 24); QOffsetRect(&machineSwitchSrc[1], 16, 24); QSetRect(&thermostatSrc[0], 0, 0, 15, 24); QOffsetRect(&thermostatSrc[0], 0, 48); QSetRect(&thermostatSrc[1], 0, 0, 15, 24); QOffsetRect(&thermostatSrc[1], 16, 48); QSetRect(&powerSrc[0], 0, 0, 8, 8); QOffsetRect(&powerSrc[0], 0, 72); QSetRect(&powerSrc[1], 0, 0, 8, 8); QOffsetRect(&powerSrc[1], 8, 72); QSetRect(&knifeSwitchSrc[0], 0, 0, 16, 24); QOffsetRect(&knifeSwitchSrc[0], 0, 80); QSetRect(&knifeSwitchSrc[1], 0, 0, 16, 24); QOffsetRect(&knifeSwitchSrc[1], 16, 80); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitLights // Structures and graphics relating to lights are loaded up. // Lights includes table lamps, flourescent lights, track lights, etc. void InitLights (void) { CGrafPtr wasCPort; GDHandle wasWorld; short i; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&lightSrcRect, 0, 0, 72, 126); // 9144 pixels theErr = CreateOffScreenGWorld(&lightSrcMap, &lightSrcRect, kPreferredDepth); SetGWorld(lightSrcMap, nil); LoadGraphic(kLightPictID); theErr = CreateOffScreenGWorld(&lightMaskMap, &lightSrcRect, 1); SetGWorld(lightMaskMap, nil); LoadGraphic(kLightPictID + 1000); QSetRect(&flourescentSrc1, 0, 0, 16, 12); QOffsetRect(&flourescentSrc1, 0, 78); QSetRect(&flourescentSrc2, 0, 0, 16, 12); QOffsetRect(&flourescentSrc2, 0, 90); for (i = 0; i < kNumTrackLights; i++) { QSetRect(&trackLightSrc[i], 0, 0, 24, 24); QOffsetRect(&trackLightSrc[i], 24 * i, 102); } SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitAppliances // Structures and graphics relating to appliances are loaded up. // Appliances includes toasters, T.V.s, etc. void InitAppliances (void) { CGrafPtr wasCPort; GDHandle wasWorld; short i; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&applianceSrcRect, 0, 0, 80, 269); // 21600 pixels theErr = CreateOffScreenGWorld(&applianceSrcMap, &applianceSrcRect, kPreferredDepth); SetGWorld(applianceSrcMap, nil); LoadGraphic(kAppliancePictID); theErr = CreateOffScreenGWorld(&applianceMaskMap, &applianceSrcRect, 1); SetGWorld(applianceMaskMap, nil); LoadGraphic(kAppliancePictID + 1000); QSetRect(&toastSrcRect, 0, 0, 32, 174); // 5600 pixels theErr = CreateOffScreenGWorld(&toastSrcMap, &toastSrcRect, kPreferredDepth); SetGWorld(toastSrcMap, nil); LoadGraphic(kToastPictID); theErr = CreateOffScreenGWorld(&toastMaskMap, &toastSrcRect, 1); SetGWorld(toastMaskMap, nil); LoadGraphic(kToastPictID + 1000); QSetRect(&shredSrcRect, 0, 0, 40, 35); // 1440 pixels theErr = CreateOffScreenGWorld(&shredSrcMap, &shredSrcRect, kPreferredDepth); SetGWorld(shredSrcMap, nil); LoadGraphic(kShreddedPictID); theErr = CreateOffScreenGWorld(&shredMaskMap, &shredSrcRect, 1); SetGWorld(shredMaskMap, nil); LoadGraphic(kShreddedPictID + 1000); QSetRect(&plusScreen1, 0, 0, 32, 22); QOffsetRect(&plusScreen1, 48, 127); QSetRect(&plusScreen2, 0, 0, 32, 22); QOffsetRect(&plusScreen2, 48, 149); QSetRect(&tvScreen1, 0, 0, 64, 49); QOffsetRect(&tvScreen1, 0, 171); QSetRect(&tvScreen2, 0, 0, 64, 49); QOffsetRect(&tvScreen2, 0, 220); QSetRect(&coffeeLight1, 0, 0, 8, 4); QOffsetRect(&coffeeLight1, 72, 171); QSetRect(&coffeeLight2, 0, 0, 8, 4); QOffsetRect(&coffeeLight2, 72, 175); for (i = 0; i < kNumOutletPicts; i++) { QSetRect(&outletSrc[i], 0, 0, 16, 24); QOffsetRect(&outletSrc[i], 64, 22 + (i * 24)); } for (i = 0; i < kNumBreadPicts; i++) { QSetRect(&breadSrc[i], 0, 0, 32, 29); QOffsetRect(&breadSrc[i], 0, i * 29); } QSetRect(&vcrTime1, 0, 0, 16, 4); QOffsetRect(&vcrTime1, 64, 179); QSetRect(&vcrTime2, 0, 0, 16, 4); QOffsetRect(&vcrTime2, 64, 183); QSetRect(&stereoLight1, 0, 0, 4, 1); QOffsetRect(&stereoLight1, 68, 171); QSetRect(&stereoLight2, 0, 0, 4, 1); QOffsetRect(&stereoLight2, 68, 172); QSetRect(µOn, 0, 0, 16, 35); QOffsetRect(µOn, 64, 222); QSetRect(µOff, 0, 0, 16, 35); QOffsetRect(µOff, 64, 187); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitEnemies // Structures and graphics relating to enemies are loaded up. // Enemies includes darts, balloons, fish, etc. void InitEnemies (void) { CGrafPtr wasCPort; GDHandle wasWorld; short i; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&balloonSrcRect, 0, 0, 24, 30 * kNumBalloonFrames); theErr = CreateOffScreenGWorld(&balloonSrcMap, &balloonSrcRect, kPreferredDepth); SetGWorld(balloonSrcMap, nil); LoadGraphic(kBalloonPictID); theErr = CreateOffScreenGWorld(&balloonMaskMap, &balloonSrcRect, 1); SetGWorld(balloonMaskMap, nil); LoadGraphic(kBalloonPictID + 1000); QSetRect(&copterSrcRect, 0, 0, 32, 30 * kNumCopterFrames); theErr = CreateOffScreenGWorld(&copterSrcMap, &copterSrcRect, kPreferredDepth); SetGWorld(copterSrcMap, nil); LoadGraphic(kCopterPictID); theErr = CreateOffScreenGWorld(&copterMaskMap, &copterSrcRect, 1); SetGWorld(copterMaskMap, nil); LoadGraphic(kCopterPictID + 1000); QSetRect(&dartSrcRect, 0, 0, 64, 19 * kNumDartFrames); theErr = CreateOffScreenGWorld(&dartSrcMap, &dartSrcRect, kPreferredDepth); SetGWorld(dartSrcMap, nil); LoadGraphic(kDartPictID); theErr = CreateOffScreenGWorld(&dartMaskMap, &dartSrcRect, 1); SetGWorld(dartMaskMap, nil); LoadGraphic(kDartPictID + 1000); QSetRect(&ballSrcRect, 0, 0, 32, 32 * kNumBallFrames); theErr = CreateOffScreenGWorld(&ballSrcMap, &ballSrcRect, kPreferredDepth); SetGWorld(ballSrcMap, nil); LoadGraphic(kBallPictID); theErr = CreateOffScreenGWorld(&ballMaskMap, &ballSrcRect, 1); SetGWorld(ballMaskMap, nil); LoadGraphic(kBallPictID + 1000); QSetRect(&dripSrcRect, 0, 0, 16, 12 * kNumDripFrames); theErr = CreateOffScreenGWorld(&dripSrcMap, &dripSrcRect, kPreferredDepth); SetGWorld(dripSrcMap, nil); LoadGraphic(kDripPictID); theErr = CreateOffScreenGWorld(&dripMaskMap, &dripSrcRect, 1); SetGWorld(dripMaskMap, nil); LoadGraphic(kDripPictID + 1000); QSetRect(&enemySrcRect, 0, 0, 36, 33); theErr = CreateOffScreenGWorld(&enemySrcMap, &enemySrcRect, kPreferredDepth); SetGWorld(enemySrcMap, nil); LoadGraphic(kEnemyPictID); theErr = CreateOffScreenGWorld(&enemyMaskMap, &enemySrcRect, 1); SetGWorld(enemyMaskMap, nil); LoadGraphic(kEnemyPictID + 1000); QSetRect(&fishSrcRect, 0, 0, 16, 16 * kNumFishFrames); theErr = CreateOffScreenGWorld(&fishSrcMap, &fishSrcRect, kPreferredDepth); SetGWorld(fishSrcMap, nil); LoadGraphic(kFishPictID); theErr = CreateOffScreenGWorld(&fishMaskMap, &fishSrcRect, 1); SetGWorld(fishMaskMap, nil); LoadGraphic(kFishPictID + 1000); for (i = 0; i < kNumBalloonFrames; i++) { QSetRect(&balloonSrc[i], 0, 0, 24, 30); QOffsetRect(&balloonSrc[i], 0, 30 * i); } for (i = 0; i < kNumCopterFrames; i++) { QSetRect(&copterSrc[i], 0, 0, 32, 30); QOffsetRect(&copterSrc[i], 0, 30 * i); } for (i = 0; i < kNumDartFrames; i++) { QSetRect(&dartSrc[i], 0, 0, 64, 19); QOffsetRect(&dartSrc[i], 0, 19 * i); } for (i = 0; i < kNumBallFrames; i++) { QSetRect(&ballSrc[i], 0, 0, 32, 32); QOffsetRect(&ballSrc[i], 0, 32 * i); } for (i = 0; i < kNumDripFrames; i++) { QSetRect(&dripSrc[i], 0, 0, 16, 12); QOffsetRect(&dripSrc[i], 0, 12 * i); } for (i = 0; i < kNumFishFrames; i++) { QSetRect(&fishSrc[i], 0, 0, 16, 16); QOffsetRect(&fishSrc[i], 0, 16 * i); } SetGWorld(wasCPort, wasWorld); } \ No newline at end of file diff --git a/Sources/StructuresInit2.c b/Sources/StructuresInit2.c deleted file mode 100755 index 1999b39..0000000 --- a/Sources/StructuresInit2.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // StructuresInit2.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "Environ.h" #include "GameOver.h" #include "MainWindow.h" #include "Objects.h" #include "RectUtils.h" #include "Room.h" #include "RoomGraphics.h" #include "Utilities.h" #define kAngelPictID 1019 #define kSupportPictID 1999 #define kClutterPictID 4018 void InitClutter (void); void InitSupport (void); void InitAngel (void); extern Rect suppSrcRect, justRoomsRect; extern Rect tileSrcRect, angelSrcRect; extern GDHandle thisGDevice; extern CGrafPtr tileSrcMap; extern FSSpecPtr theHousesSpecs; extern hotPtr hotSpots; extern sparklePtr sparkles; extern flyingPtPtr flyingPoints; extern flamePtr flames, tikiFlames, bbqCoals; extern pendulumPtr pendulums; extern savedPtr savedMaps; extern bandPtr bands; extern greasePtr grease; extern starPtr theStars; extern shredPtr shreds; extern dynaPtr dinahs; extern demoPtr demoData; extern short maxFiles; //============================================================== Functions //-------------------------------------------------------------- InitClutter // Structures and graphics relating to clutter are loaded up. // Clutter includes mirrors, teddy bears, fireplaces, calendars, etc. void InitClutter (void) { CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&clutterSrcRect, 0, 0, 128, 69); theErr = CreateOffScreenGWorld(&clutterSrcMap, &clutterSrcRect, kPreferredDepth); SetGWorld(clutterSrcMap, nil); LoadGraphic(kClutterPictID); theErr = CreateOffScreenGWorld(&clutterMaskMap, &clutterSrcRect, 1); SetGWorld(clutterMaskMap, nil); LoadGraphic(kClutterPictID + 1000); QSetRect(&flowerSrc[0], 0, 0, 10, 28); QOffsetRect(&flowerSrc[0], 0, 23); QSetRect(&flowerSrc[1], 0, 0, 24, 35); QOffsetRect(&flowerSrc[1], 10, 16); QSetRect(&flowerSrc[2], 0, 0, 34, 35); QOffsetRect(&flowerSrc[2], 34, 16); QSetRect(&flowerSrc[3], 0, 0, 27, 23); QOffsetRect(&flowerSrc[3], 68, 14); QSetRect(&flowerSrc[4], 0, 0, 27, 14); QOffsetRect(&flowerSrc[4], 68, 37); QSetRect(&flowerSrc[5], 0, 0, 32, 51); QOffsetRect(&flowerSrc[5], 95, 0); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitSupport // The floor support grphic is loaded up. It is only visible whenÉ // playing in 9-room mode. It is the horizontal wooden beam thatÉ // seperates floors from one another. void InitSupport (void) { CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&suppSrcRect, 0, 0, kRoomWide, kFloorSupportTall); // 44 theErr = CreateOffScreenGWorld(&suppSrcMap, &suppSrcRect, kPreferredDepth); SetGWorld(suppSrcMap, nil); LoadGraphic(kSupportPictID); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- InitAngel // This loads the graphic of the girl riding the glider. It is seenÉ // only upon completing a house. She flies across the screen droppingÉ // stars below. void InitAngel (void) { CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); QSetRect(&angelSrcRect, 0, 0, 96, 44); theErr = CreateOffScreenGWorld(&angelSrcMap, &angelSrcRect, kPreferredDepth); SetGWorld(angelSrcMap, nil); LoadGraphic(kAngelPictID); theErr = CreateOffScreenGWorld(&angelMaskMap, &angelSrcRect, 1); SetGWorld(angelMaskMap, nil); LoadGraphic(kAngelPictID + 1); SetGWorld(wasCPort, wasWorld); } //-------------------------------------------------------------- CreateOffscreens // All "utility" or "work" offscreen pix/bit maps are created here. // These would be offscreens that are reused throughout a game - theyÉ // are not static (mere repositories for graphics). Most are usedÉ // to facilitate the animation when a game is in progress. void CreateOffscreens (void) { CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; GetGWorld(&wasCPort, &wasWorld); justRoomsRect = houseRect; ZeroRectCorner(&justRoomsRect); workSrcRect = houseRect; // Set up work map ZeroRectCorner(&workSrcRect); theErr = CreateOffScreenGWorld(&workSrcMap, &workSrcRect, kPreferredDepth); backSrcRect = houseRect; // Set up background map ZeroRectCorner(&backSrcRect); theErr = CreateOffScreenGWorld(&backSrcMap, &backSrcRect, kPreferredDepth); InitScoreboardMap(); SpinCursor(1); InitGliderMap(); SpinCursor(1); InitBlowers(); SpinCursor(1); InitFurniture(); SpinCursor(1); InitPrizes(); SpinCursor(1); InitTransports(); SpinCursor(1); InitSwitches(); SpinCursor(1); InitLights(); SpinCursor(1); InitAppliances(); SpinCursor(1); InitEnemies(); SpinCursor(1); InitClutter(); SpinCursor(1); InitSupport(); SpinCursor(1); InitAngel(); SpinCursor(1); QSetRect(&tileSrcRect, 0, 0, 128, 80); tileSrcMap = nil; // ???? } //-------------------------------------------------------------- CreatePointers // This function allocates other large structures. Pointers to holdÉ // large arrays, etc. void CreatePointers (void) { Handle tempHandle; short i; thisRoom = nil; thisRoom = (roomPtr)NewPtr(sizeof(roomType)); if (thisRoom == nil) RedAlert(kErrNoMemory); hotSpots = nil; hotSpots = (hotPtr)NewPtr(sizeof(hotObject) * kMaxHotSpots); if (hotSpots == nil) RedAlert(kErrNoMemory); sparkles = nil; sparkles = (sparklePtr)NewPtr(sizeof(sparkleType) * kMaxSparkles); if (sparkles == nil) RedAlert(kErrNoMemory); flyingPoints = nil; flyingPoints = (flyingPtPtr)NewPtr(sizeof(flyingPtType) * kMaxFlyingPts); if (flyingPoints == nil) RedAlert(kErrNoMemory); flames = nil; flames = (flamePtr)NewPtr(sizeof(flameType) * kMaxCandles); if (flames == nil) RedAlert(kErrNoMemory); tikiFlames = nil; tikiFlames = (flamePtr)NewPtr(sizeof(flameType) * kMaxTikis); if (tikiFlames == nil) RedAlert(kErrNoMemory); bbqCoals = nil; bbqCoals = (flamePtr)NewPtr(sizeof(flameType) * kMaxCoals); if (bbqCoals == nil) RedAlert(kErrNoMemory); pendulums = nil; pendulums = (pendulumPtr)NewPtr(sizeof(pendulumType) * kMaxPendulums); if (pendulums == nil) RedAlert(kErrNoMemory); savedMaps = nil; savedMaps = (savedPtr)NewPtr(sizeof(savedType) * kMaxSavedMaps); if (savedMaps == nil) RedAlert(kErrNoMemory); for (i = 0; i < kMaxSavedMaps; i++) savedMaps[i].map = nil; bands = nil; bands = (bandPtr)NewPtr(sizeof(bandType) * kMaxRubberBands); if (bands == nil) RedAlert(kErrNoMemory); grease = nil; grease = (greasePtr)NewPtr(sizeof(greaseType) * kMaxGrease); if (grease == nil) RedAlert(kErrNoMemory); theStars = nil; theStars = (starPtr)NewPtr(sizeof(starType) * kMaxStars); if (theStars == nil) RedAlert(kErrNoMemory); shreds = nil; shreds = (shredPtr)NewPtr(sizeof(shredType) * kMaxShredded); if (shreds == nil) RedAlert(kErrNoMemory); dinahs = nil; dinahs = (dynaPtr)NewPtr(sizeof(dynaType) * kMaxDynamicObs); if (dinahs == nil) RedAlert(kErrNoMemory); masterObjects = nil; masterObjects = (objDataPtr)NewPtr(sizeof(objDataType) * kMaxMasterObjects); if (masterObjects == nil) RedAlert(kErrNoMemory); srcRects = nil; srcRects = (Rect *)NewPtr(sizeof(Rect) * kNumSrcRects); if (srcRects == nil) RedAlert(kErrNoMemory); theHousesSpecs = nil; theHousesSpecs = (FSSpecPtr)NewPtr(sizeof(FSSpec) * maxFiles); if (theHousesSpecs == nil) RedAlert(kErrNoMemory); #ifdef CREATEDEMODATA demoData = nil; demoData = (demoPtr)NewPtr(sizeof(demoType) * 2000); if (demoData == nil) RedAlert(kErrNoMemory); #else demoData = nil; demoData = (demoPtr)NewPtr(kDemoLength); if (demoData == nil) RedAlert(kErrNoMemory); tempHandle = GetResource('demo', 128); if (tempHandle == nil) RedAlert(kErrNoMemory); else { BlockMove(*tempHandle, demoData, kDemoLength); ReleaseResource(tempHandle); } #endif } //-------------------------------------------------------------- InitSrcRects // This is a nasty, ugly function that initializes all global rectanglesÉ // used in Glider PRO. void InitSrcRects (void) { QSetRect(&srcRects[kFloorVent], 0, 0, 48, 11); // Blowers QOffsetRect(&srcRects[kFloorVent], 0, 0); QSetRect(&srcRects[kCeilingVent], 0, 0, 48, 11); QOffsetRect(&srcRects[kCeilingVent], 0, 11); QSetRect(&srcRects[kFloorBlower], 0, 0, 48, 15); QOffsetRect(&srcRects[kFloorBlower], 0, 22); QSetRect(&srcRects[kCeilingBlower], 0, 0, 48, 15); QOffsetRect(&srcRects[kCeilingBlower], 0, 37); QSetRect(&srcRects[kSewerGrate], 0, 0, 48, 17); QOffsetRect(&srcRects[kSewerGrate], 0, 52); QSetRect(&srcRects[kLeftFan], 0, 0, 40, 55); QOffsetRect(&srcRects[kLeftFan], 0, 69); QSetRect(&srcRects[kRightFan], 0, 0, 40, 55); QOffsetRect(&srcRects[kRightFan], 0, 124); QSetRect(&srcRects[kTaper], 0, 0, 20, 59); QOffsetRect(&srcRects[kTaper], 0, 209); QSetRect(&srcRects[kCandle], 0, 0, 32, 30); QOffsetRect(&srcRects[kCandle], 0, 179); QSetRect(&srcRects[kStubby], 0, 0, 20, 36); QOffsetRect(&srcRects[kStubby], 0, 268); QSetRect(&srcRects[kTiki], 0, 0, 27, 28); QOffsetRect(&srcRects[kTiki], 21, 268); QSetRect(&srcRects[kBBQ], 0, 0, 64, 33); QSetRect(&srcRects[kInvisBlower], 0, 0, 24, 24); QSetRect(&srcRects[kGrecoVent], 0, 0, 48, 18); QOffsetRect(&srcRects[kGrecoVent], 0, 340); QSetRect(&srcRects[kSewerBlower], 0, 0, 32, 12); QOffsetRect(&srcRects[kSewerBlower], 0, 390); QSetRect(&srcRects[kLiftArea], 0, 0, 64, 32); QSetRect(&srcRects[kTable], 0, 0, 64, kTableThick); // Furniture QSetRect(&srcRects[kShelf], 0, 0, 64, kShelfThick); QSetRect(&srcRects[kCabinet], 0, 0, 64, 64); QSetRect(&srcRects[kFilingCabinet], 0, 0, 74, 107); QSetRect(&srcRects[kWasteBasket], 0, 0, 64, 61); QOffsetRect(&srcRects[kWasteBasket], 0, 43); QSetRect(&srcRects[kMilkCrate], 0, 0, 64, 58); QOffsetRect(&srcRects[kMilkCrate], 0, 104); QSetRect(&srcRects[kCounter], 0, 0, 128, 64); QSetRect(&srcRects[kDresser], 0, 0, 128, 64); QSetRect(&srcRects[kDeckTable], 0, 0, 64, kTableThick); QSetRect(&srcRects[kStool], 0, 0, 48, 38); QOffsetRect(&srcRects[kStool], 0, 183); QSetRect(&srcRects[kTrunk], 0, 0, 144, 80); QSetRect(&srcRects[kInvisObstacle], 0, 0, 64, 64); QSetRect(&srcRects[kManhole], 0, 0, 123, 22); QSetRect(&srcRects[kBooks], 0, 0, 64, 51); QSetRect(&srcRects[kInvisBounce], 0, 0, 64, 64); QSetRect(&srcRects[kRedClock], 0, 0, 28, 17); // Prizes QSetRect(&srcRects[kBlueClock], 0, 0, 28, 25); QOffsetRect(&srcRects[kBlueClock], 0, 17); QSetRect(&srcRects[kYellowClock], 0, 0, 28, 28); QOffsetRect(&srcRects[kYellowClock], 0, 42); QSetRect(&srcRects[kCuckoo], 0, 0, 40, 80); QOffsetRect(&srcRects[kCuckoo], 0, 148); QSetRect(&srcRects[kPaper], 0, 0, 48, 21); QOffsetRect(&srcRects[kPaper], 0, 127); QSetRect(&srcRects[kBattery], 0, 0, 16, 25); QOffsetRect(&srcRects[kBattery], 32, 0); QSetRect(&srcRects[kBands], 0, 0, 28, 23); QOffsetRect(&srcRects[kBands], 20, 70); QSetRect(&srcRects[kGreaseRt], 0, 0, 32, 27); QOffsetRect(&srcRects[kGreaseRt], 0, 243); QSetRect(&srcRects[kGreaseLf], 0, 0, 32, 27); QOffsetRect(&srcRects[kGreaseLf], 0, 324); QSetRect(&srcRects[kFoil], 0, 0, 55, 15); QOffsetRect(&srcRects[kFoil], 0, 228); QSetRect(&srcRects[kInvisBonus], 0, 0, 24, 24); QSetRect(&srcRects[kStar], 0, 0, 32, 31); QOffsetRect(&srcRects[kStar], 48, 0); QSetRect(&srcRects[kSparkle], 0, 0, 20, 19); QOffsetRect(&srcRects[kSparkle], 0, 70); QSetRect(&srcRects[kHelium], 0, 0, 56, 16); QOffsetRect(&srcRects[kHelium], 32, 270); QSetRect(&srcRects[kSlider], 0, 0, 64, 16); QSetRect(&srcRects[kUpStairs], 0, 0, 160, 267); // Transport QSetRect(&srcRects[kDownStairs], 0, 0, 160, 267); QSetRect(&srcRects[kMailboxLf], 0, 0, 94, 80); QSetRect(&srcRects[kMailboxRt], 0, 0, 94, 80); QSetRect(&srcRects[kFloorTrans], 0, 0, 56, 15); QOffsetRect(&srcRects[kFloorTrans], 0, 1); QSetRect(&srcRects[kCeilingTrans], 0, 0, 56, 15); QOffsetRect(&srcRects[kCeilingTrans], 0, 16); QSetRect(&srcRects[kDoorInLf], 0, 0, 144, 322); QSetRect(&srcRects[kDoorInRt], 0, 0, 144, 322); QSetRect(&srcRects[kDoorExRt], 0, 0, 16, 322); QSetRect(&srcRects[kDoorExLf], 0, 0, 16, 322); QSetRect(&srcRects[kWindowInLf], 0, 0, 20, 170); QSetRect(&srcRects[kWindowInRt], 0, 0, 20, 170); QSetRect(&srcRects[kWindowExRt], 0, 0, 16, 170); QSetRect(&srcRects[kWindowExLf], 0, 0, 16, 170); QSetRect(&srcRects[kInvisTrans], 0, 0, 64, 32); QSetRect(&srcRects[kDeluxeTrans], 0, 0, 64, 64); QSetRect(&srcRects[kLightSwitch], 0, 0, 15, 24); // Switch QSetRect(&srcRects[kMachineSwitch], 0, 0, 16, 24); QOffsetRect(&srcRects[kMachineSwitch], 0, 48); QSetRect(&srcRects[kThermostat], 0, 0, 15, 24); QOffsetRect(&srcRects[kThermostat], 0, 48); QSetRect(&srcRects[kPowerSwitch], 0, 0, 8, 8); QOffsetRect(&srcRects[kPowerSwitch], 0, 72); QSetRect(&srcRects[kKnifeSwitch], 0, 0, 16, 24); QOffsetRect(&srcRects[kKnifeSwitch], 0, 80); QSetRect(&srcRects[kInvisSwitch], 0, 0, 12, 12); QSetRect(&srcRects[kTrigger], 0, 0, 12, 12); QSetRect(&srcRects[kLgTrigger], 0, 0, 48, 48); QSetRect(&srcRects[kSoundTrigger], 0, 0, 32, 32); QSetRect(&srcRects[kCeilingLight], 0, 0, 64, 20); // Lights QOffsetRect(&srcRects[kCeilingLight], 0, 0); QSetRect(&srcRects[kLightBulb], 0, 0, 16, 28); QOffsetRect(&srcRects[kLightBulb], 0, 20); QSetRect(&srcRects[kTableLamp], 0, 0, 48, 70); QOffsetRect(&srcRects[kTableLamp], 16, 20); QSetRect(&srcRects[kHipLamp], 0, 0, 72, 276); QSetRect(&srcRects[kDecoLamp], 0, 0, 64, 212); QSetRect(&srcRects[kFlourescent], 0, 0, 64, 12); QSetRect(&srcRects[kTrackLight], 0, 0, 64, 24); QSetRect(&srcRects[kInvisLight], 0, 0, 16, 16); QSetRect(&srcRects[kShredder], 0, 0, 73, 22); // Appliances QSetRect(&srcRects[kToaster], 0, 0, 48, 27); QOffsetRect(&srcRects[kToaster], 0, 22); QSetRect(&srcRects[kMacPlus], 0, 0, 48, 58); QOffsetRect(&srcRects[kMacPlus], 0, 49); QSetRect(&srcRects[kGuitar], 0, 0, 64, 172); QSetRect(&srcRects[kTV], 0, 0, 92, 77); QSetRect(&srcRects[kCoffee], 0, 0, 43, 64); QOffsetRect(&srcRects[kCoffee], 0, 107); QSetRect(&srcRects[kOutlet], 0, 0, 16, 24); QOffsetRect(&srcRects[kOutlet], 64, 22); QSetRect(&srcRects[kVCR], 0, 0, 96, 22); QSetRect(&srcRects[kStereo], 0, 0, 128, 53); QSetRect(&srcRects[kMicrowave], 0, 0, 92, 59); QSetRect(&srcRects[kCinderBlock], 0, 0, 40, 62); QSetRect(&srcRects[kFlowerBox], 0, 0, 80, 32); QSetRect(&srcRects[kCDs], 0, 0, 16, 30); QOffsetRect(&srcRects[kCDs], 48, 22); QSetRect(&srcRects[kCustomPict], 0, 0, 72, 34); QSetRect(&srcRects[kBalloon], 0, 0, 24, 30); // Enemies QSetRect(&srcRects[kCopterLf], 0, 0, 32, 30); QSetRect(&srcRects[kCopterRt], 0, 0, 32, 30); QSetRect(&srcRects[kDartLf], 0, 0, 64, 19); QSetRect(&srcRects[kDartRt], 0, 0, 64, 19); QSetRect(&srcRects[kBall], 0, 0, 32, 32); QSetRect(&srcRects[kDrip], 0, 0, 16, 12); QSetRect(&srcRects[kFish], 0, 0, 36, 33); QSetRect(&srcRects[kCobweb], 0, 0, 54, 45); QSetRect(&srcRects[kOzma], 0, 0, 102, 92); // Clutter QSetRect(&srcRects[kMirror], 0, 0, 64, 64); QSetRect(&srcRects[kMousehole], 0, 0, 10, 11); QSetRect(&srcRects[kFireplace], 0, 0, 180, 142); QSetRect(&srcRects[kWallWindow], 0, 0, 64, 80); QSetRect(&srcRects[kBear], 0, 0, 56, 58); QSetRect(&srcRects[kCalendar], 0, 0, 63, 92); QSetRect(&srcRects[kVase1], 0, 0, 36, 45); QSetRect(&srcRects[kVase2], 0, 0, 35, 57); QSetRect(&srcRects[kBulletin], 0, 0, 80, 58); QSetRect(&srcRects[kCloud], 0, 0, 128, 30); QSetRect(&srcRects[kFaucet], 0, 0, 56, 18); QOffsetRect(&srcRects[kFaucet], 0, 51); QSetRect(&srcRects[kRug], 0, 0, 144, 18); QSetRect(&srcRects[kChimes], 0, 0, 28, 74); } \ No newline at end of file diff --git a/Sources/Tools.c b/Sources/Tools.c deleted file mode 100755 index b8c281e..0000000 --- a/Sources/Tools.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Tools.c //---------------------------------------------------------------------------- //============================================================================ #include #include "Externs.h" #include "Environ.h" #include "RectUtils.h" #include "Utilities.h" #define kToolsHigh 4 #define kToolsWide 4 #define kTotalTools 16 // kToolsHigh * kToolsWide #define kPopUpControl 129 #define kFirstBlower 1 #define kLastBlower 15 #define kBlowerBase 1 #define kFirstFurniture 1 #define kLastFurniture 15 #define kFurnitureBase 21 #define kFirstBonus 1 #define kLastBonus 15 #define kBonusBase 41 #define kFirstTransport 1 #define kLastTransport 12 #define kTransportBase 61 #define kFirstSwitch 1 #define kLastSwitch 9 #define kSwitchBase 81 #define kFirstLight 1 #define kLastLight 8 #define kLightBase 101 #define kFirstAppliance 1 #define kLastAppliance 14 #define kApplianceBase 121 #define kFirstEnemy 1 #define kLastEnemy 9 #define kEnemyBase 141 #define kFirstClutter 1 #define kLastClutter 15 #define kClutterBase 161 #define kToolsPictID 1011 void CreateToolsOffscreen (void); void KillToolsOffscreen (void); void FrameSelectedTool (void); void DrawToolName (void); void DrawToolTiles (void); void SwitchToolModes (short); Rect toolsWindowRect, toolSrcRect, toolTextRect; Rect toolRects[kTotalTools]; ControlHandle classPopUp; GWorldPtr toolSrcMap; WindowPtr toolsWindow; short isToolsH, isToolsV; short toolSelected, toolMode; short firstTool, lastTool, objectBase; Boolean isToolsOpen; //============================================================== Functions //-------------------------------------------------------------- CreateToolsOffscreen #ifndef COMPILEDEMO void CreateToolsOffscreen (void) { CGrafPtr wasCPort; GDHandle wasWorld; OSErr theErr; if (toolSrcMap == nil) { GetGWorld(&wasCPort, &wasWorld); QSetRect(&toolSrcRect, 0, 0, 360, 216); theErr = CreateOffScreenGWorld(&toolSrcMap, &toolSrcRect, kPreferredDepth); SetGWorld(toolSrcMap, nil); LoadGraphic(kToolsPictID); SetGWorld(wasCPort, wasWorld); } } #endif //-------------------------------------------------------------- KillToolsOffscreen #ifndef COMPILEDEMO void KillToolsOffscreen (void) { if (toolSrcMap != nil) { DisposeGWorld(toolSrcMap); // KillOffScreenPixMap(toolSrcMap); toolSrcMap = nil; } } #endif //-------------------------------------------------------------- FrameSelectedTool #ifndef COMPILEDEMO void FrameSelectedTool (void) { Rect theRect; short toolIcon; toolIcon = toolSelected; if ((toolMode == kBlowerMode) && (toolIcon >= 7)) { toolIcon--; } else if ((toolMode == kTransportMode) && (toolIcon >= 7)) { if (toolIcon >= 15) toolIcon -= 4; else toolIcon = ((toolIcon - 7) / 2) + 7; } theRect = toolRects[toolIcon]; PenSize(2, 2); ForeColor(redColor); FrameRect(&theRect); PenNormal(); ForeColor(blackColor); } #endif //-------------------------------------------------------------- DrawToolName #ifndef COMPILEDEMO void DrawToolName (void) { Str255 theString; if (toolSelected == 0) PasStringCopy("\pSelection Tool", theString); else GetIndString(theString, kObjectNameStrings, toolSelected + ((toolMode - 1) * 0x0010)); EraseRect(&toolTextRect); MoveTo(toolTextRect.left + 3, toolTextRect.bottom - 6); TextFont(applFont); TextSize(9); TextFace(bold); ColorText(theString, 171L); } #endif //-------------------------------------------------------------- DrawToolTiles #ifndef COMPILEDEMO void DrawToolTiles (void) { Rect srcRect, destRect; short i; DrawCIcon(2000, toolRects[0].left, toolRects[0].top); // Selection Tool for (i = 0; i < 15; i++) // Other tools { QSetRect(&srcRect, 0, 0, 24, 24); QSetRect(&destRect, 0, 0, 24, 24); QOffsetRect(&srcRect, i * 24, (toolMode - 1) * 24); QOffsetRect(&destRect, toolRects[i + 1].left + 2, toolRects[i + 1].top + 2); CopyBits((BitMap *)*GetGWorldPixMap(toolSrcMap), GetPortBitMapForCopyBits(GetWindowPort(toolsWindow)), &srcRect, &destRect, srcCopy, nil); } } #endif //-------------------------------------------------------------- EraseSelectedTool void EraseSelectedTool (void) { #ifndef COMPILEDEMO Rect theRect; short toolIcon; if (toolsWindow == nil) return; SetPort((GrafPtr)toolsWindow); toolIcon = toolSelected; if ((toolMode == kBlowerMode) && (toolIcon >= 7)) { toolIcon--; } else if ((toolMode == kTransportMode) && (toolIcon >= 7)) { if (toolIcon >= 15) toolIcon -= 4; else toolIcon = ((toolIcon - 7) / 2) + 7; } theRect = toolRects[toolIcon]; PenSize(2, 2); ForeColor(whiteColor); FrameRect(&theRect); #endif } //-------------------------------------------------------------- SelectTool void SelectTool (short which) { #ifndef COMPILEDEMO Rect theRect; short toolIcon; if (toolsWindow == nil) return; SetPort((GrafPtr)toolsWindow); toolIcon = which; if ((toolMode == kBlowerMode) && (toolIcon >= 7)) { toolIcon--; } else if ((toolMode == kTransportMode) && (toolIcon >= 7)) { if (toolIcon >= 15) toolIcon -= 4; else toolIcon = ((toolIcon - 7) / 2) + 7; } theRect = toolRects[toolIcon]; ForeColor(redColor); FrameRect(&theRect); PenNormal(); ForeColor(blackColor); toolSelected = which; DrawToolName(); #endif } //-------------------------------------------------------------- UpdateToolsWindow void UpdateToolsWindow (void) { #ifndef COMPILEDEMO if (toolsWindow == nil) return; SetPortWindowPort(toolsWindow); DrawControls(toolsWindow); DkGrayForeColor(); MoveTo(4, 25); Line(108, 0); ForeColor(blackColor); DrawToolTiles(); FrameSelectedTool(); DrawToolName(); #endif } //-------------------------------------------------------------- OpenToolsWindow void OpenToolsWindow (void) { #ifndef COMPILEDEMO Rect src, dest; Point globalMouse; short h, v; if (toolsWindow == nil) { QSetRect(&toolsWindowRect, 0, 0, 116, 152); // 143 QSetRect(&toolTextRect, 0, 0, 116, 12); InsetRect(&toolTextRect, -1, -1); QOffsetRect(&toolTextRect, 0, 157 - 15); if (thisMac.hasColor) toolsWindow = NewCWindow(nil, &toolsWindowRect, "\pTools", false, kWindoidWDEF, kPutInFront, true, 0L); else toolsWindow = NewWindow(nil, &toolsWindowRect, "\pTools", false, kWindoidWDEF, kPutInFront, true, 0L); if (toolsWindow == nil) RedAlert(kErrNoMemory); // if (OptionKeyDown()) // { // isToolsH = qd.screenBits.bounds.right - 120; // isToolsV = 35; // } MoveWindow(toolsWindow, isToolsH, isToolsV, true); globalMouse = MyGetGlobalMouse(); QSetRect(&src, 0, 0, 1, 1); QOffsetRect(&src, globalMouse.h, globalMouse.v); GetWindowRect(toolsWindow, &dest); BringToFront(toolsWindow); ShowHide(toolsWindow, true); // FlagWindowFloating(toolsWindow); TEMP - use flaoting windows HiliteAllWindows(); classPopUp = GetNewControl(kPopUpControl, toolsWindow); if (classPopUp == nil) RedAlert(kErrFailedResourceLoad); SetControlValue(classPopUp, toolMode); for (v = 0; v < kToolsHigh; v++) for (h = 0; h < kToolsWide; h++) { QSetRect(&toolRects[(v * kToolsWide) + h], 2, 29, 30, 57); QOffsetRect(&toolRects[(v * kToolsWide) + h], h * 28, v * 28); } CreateToolsOffscreen(); SwitchToolModes(toolMode); toolSelected = kSelectTool; } UpdateToolsCheckmark(true); #endif } //-------------------------------------------------------------- CloseToolsWindow void CloseToolsWindow (void) { #ifndef COMPILEDEMO CloseThisWindow(&toolsWindow); KillToolsOffscreen(); UpdateToolsCheckmark(false); #endif } //-------------------------------------------------------------- ToggleToolsWindow void ToggleToolsWindow (void) { #ifndef COMPILEDEMO if (toolsWindow == nil) { OpenToolsWindow(); isToolsOpen = true; } else { CloseToolsWindow(); isToolsOpen = true; } #endif } //-------------------------------------------------------------- SwitchToolModes #ifndef COMPILEDEMO void SwitchToolModes (short newMode) { if (toolsWindow == nil) return; SelectTool(kSelectTool); switch (newMode) { case kBlowerMode: firstTool = kFirstBlower; lastTool = kLastBlower; objectBase = kBlowerBase; break; case kFurnitureMode: firstTool = kFirstFurniture; lastTool = kLastFurniture; objectBase = kFurnitureBase; break; case kBonusMode: firstTool = kFirstBonus; lastTool = kLastBonus; objectBase = kBonusBase; break; case kTransportMode: firstTool = kFirstTransport; lastTool = kLastTransport; objectBase = kTransportBase; break; case kSwitchMode: firstTool = kFirstSwitch; lastTool = kLastSwitch; objectBase = kSwitchBase; break; case kLightMode: firstTool = kFirstLight; lastTool = kLastLight; objectBase = kLightBase; break; case kApplianceMode: firstTool = kFirstAppliance; lastTool = kLastAppliance; objectBase = kApplianceBase; break; case kEnemyMode: firstTool = kFirstEnemy; lastTool = kLastEnemy; objectBase = kEnemyBase; break; case kClutterMode: firstTool = kFirstClutter; lastTool = kLastClutter; objectBase = kClutterBase; break; } toolMode = newMode; InvalWindowRect(toolsWindow, &toolsWindowRect); } #endif //-------------------------------------------------------------- HandleToolsClick void HandleToolsClick (Point wherePt) { #ifndef COMPILEDEMO ControlHandle theControl; short i, part, newMode, toolIcon; if (toolsWindow == nil) return; SetPortWindowPort(toolsWindow); GlobalToLocal(&wherePt); part = FindControl(wherePt, toolsWindow, &theControl); if ((theControl != nil) && (part != 0)) { part = TrackControl(theControl, wherePt, (ControlActionUPP)-1L); if (part != 0) { newMode = GetControlValue(theControl); if (newMode != toolMode) { EraseSelectedTool(); SwitchToolModes(newMode); } } } else { for (i = 0; i < kTotalTools; i++) if ((PtInRect(wherePt, &toolRects[i])) && (i <= lastTool)) { EraseSelectedTool(); toolIcon = i; if ((toolMode == kBlowerMode) && (toolIcon >= 7)) { toolIcon++; } if ((toolMode == kTransportMode) && (toolIcon >= 7)) { if (toolIcon >= 11) toolIcon += 4; else toolIcon = ((toolIcon - 7) * 2) + 7; } SelectTool(toolIcon); break; } } #endif } //-------------------------------------------------------------- NextToolMode void NextToolMode (void) { #ifndef COMPILEDEMO if (toolsWindow == nil) return; if ((theMode == kEditMode) && (toolMode < kClutterMode)) { EraseSelectedTool(); toolMode++; SetControlValue(classPopUp, toolMode); SwitchToolModes(toolMode); toolSelected = kSelectTool; } #endif } //-------------------------------------------------------------- PrevToolMode void PrevToolMode (void) { #ifndef COMPILEDEMO if (toolsWindow == nil) return; if ((theMode == kEditMode) && (toolMode > kBlowerMode)) { EraseSelectedTool(); toolMode--; SetControlValue(classPopUp, toolMode); SwitchToolModes(toolMode); toolSelected = kSelectTool; } #endif } //-------------------------------------------------------------- SetSpecificToolMode void SetSpecificToolMode (short modeToSet) { #ifndef COMPILEDEMO if ((toolsWindow == nil) || (theMode != kEditMode)) return; EraseSelectedTool(); toolMode = modeToSet; SetControlValue(classPopUp, toolMode); SwitchToolModes(toolMode); toolSelected = kSelectTool; #endif } \ No newline at end of file diff --git a/Sources/Transit.c b/Sources/Transit.c deleted file mode 100755 index 627c6ab..0000000 --- a/Sources/Transit.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Transit.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" #include "RectUtils.h" void HandleRoomVisitation (void); short linkedToWhat; Boolean takingTheStairs, firstPlayer; extern Rect justRoomsRect, transRect; extern short transRoom, otherPlayerEscaped; extern short localNumbers[9]; extern Boolean topOpen, twoPlayerGame, onePlayerLeft; extern Boolean playerDead, playerSuicide, tvOn; //============================================================== Functions //-------------------------------------------------------------- WhatAreWeLinkedTo short WhatAreWeLinkedTo (short where, Byte who) { short what, whatType; char wasState; wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); what = (*thisHouse)->rooms[where].objects[who].what; HSetState((Handle)thisHouse, wasState); switch (what) { case kMailboxLf: whatType = kLinkedToLeftMailbox; break; case kMailboxRt: whatType = kLinkedToRightMailbox; break; case kCeilingTrans: whatType = kLinkedToCeilingDuct; break; default: whatType = kLinkedToOther; break; } return (whatType); } //-------------------------------------------------------------- ReadyGliderFromTransit void ReadyGliderFromTransit (gliderPtr thisGlider, short toWhat) { Rect tempRect; if ((twoPlayerGame) && (onePlayerLeft) && (thisGlider->which == playerDead)) return; FlagGliderNormal(thisGlider); switch (toWhat) { case kLinkedToOther: StartGliderTransportingIn(thisGlider); // set glider's mode tempRect = thisGlider->dest; // position glider CenterRectInRect(&tempRect, &transRect); thisGlider->dest.left = tempRect.left; thisGlider->dest.right = tempRect.right; thisGlider->dest.top = tempRect.top; thisGlider->dest.bottom = tempRect.bottom; thisGlider->destShadow.left = tempRect.left; thisGlider->destShadow.right = tempRect.right; thisGlider->whole = thisGlider->dest; thisGlider->wholeShadow = thisGlider->destShadow; thisGlider->enteredRect = thisGlider->dest; break; case kLinkedToLeftMailbox: StartGliderMailingOut(thisGlider); thisGlider->clip = transRect; // fix clip thisGlider->clip.right -= 64; thisGlider->clip.bottom -= 25; tempRect = thisGlider->dest; thisGlider->dest.left = thisGlider->clip.right; thisGlider->dest.right = thisGlider->dest.left; thisGlider->dest.bottom = thisGlider->clip.bottom - 4; thisGlider->dest.top = thisGlider->dest.bottom - RectTall(&tempRect); thisGlider->destShadow.left = thisGlider->dest.left; thisGlider->destShadow.right = thisGlider->dest.right; thisGlider->whole = thisGlider->dest; thisGlider->wholeShadow = thisGlider->destShadow; break; case kLinkedToRightMailbox: StartGliderMailingOut(thisGlider); thisGlider->clip = transRect; // fix clip thisGlider->clip.left += 79; thisGlider->clip.bottom -= 25; tempRect = thisGlider->dest; thisGlider->dest.right = thisGlider->clip.left; thisGlider->dest.left = thisGlider->dest.right; thisGlider->dest.bottom = thisGlider->clip.bottom - 4; thisGlider->dest.top = thisGlider->dest.bottom - RectTall(&tempRect); thisGlider->destShadow.left = thisGlider->dest.left; thisGlider->destShadow.right = thisGlider->dest.right; thisGlider->whole = thisGlider->dest; thisGlider->wholeShadow = thisGlider->destShadow; break; case kLinkedToCeilingDuct: StartGliderDuctingIn(thisGlider); tempRect = thisGlider->dest; // set glider's position CenterRectInRect(&tempRect, &transRect); thisGlider->dest.left = tempRect.left; thisGlider->dest.right = tempRect.right; thisGlider->dest.top = tempRect.top; thisGlider->dest.bottom = thisGlider->dest.top; QOffsetRect(&thisGlider->dest, 0, -RectTall(&tempRect)); thisGlider->destShadow.left = tempRect.left; thisGlider->destShadow.right = tempRect.right; thisGlider->whole = thisGlider->dest; thisGlider->wholeShadow = thisGlider->destShadow; break; case kLinkedToFloorDuct: break; default: break; } if ((twoPlayerGame) && (thisGlider->which != firstPlayer)) TagGliderIdle(thisGlider); } //-------------------------------------------------------------- MoveRoomToRoom void MoveRoomToRoom (gliderPtr thisGlider, short where) { Rect enterRect; HandleRoomVisitation(); switch (where) { case kToRight: SetMusicalMode(kProdGameScoreMode); if (twoPlayerGame) { UndoGliderLimbo(&theGlider); UndoGliderLimbo(&theGlider2); InsureGliderFacingRight(&theGlider); InsureGliderFacingRight(&theGlider2); } else InsureGliderFacingRight(thisGlider); ForceThisRoom(localNumbers[kEastRoom]); if (twoPlayerGame) { OffsetGlider(&theGlider, kToLeft); OffsetGlider(&theGlider2, kToLeft); QSetRect(&enterRect, 0, 0, 48, 20); QOffsetRect(&enterRect, 0, kGliderStartsDown + (short)thisRoom->leftStart - 2); theGlider.enteredRect = enterRect; theGlider2.enteredRect = enterRect; } else { OffsetGlider(thisGlider, kToLeft); QSetRect(&enterRect, 0, 0, 48, 20); QOffsetRect(&enterRect, 0, kGliderStartsDown + (short)thisRoom->leftStart - 2); thisGlider->enteredRect = enterRect; } break; case kToLeft: SetMusicalMode(kProdGameScoreMode); if (twoPlayerGame) { UndoGliderLimbo(&theGlider); UndoGliderLimbo(&theGlider2); InsureGliderFacingLeft(&theGlider); InsureGliderFacingLeft(&theGlider2); } else InsureGliderFacingLeft(thisGlider); ForceThisRoom(localNumbers[kWestRoom]); if (twoPlayerGame) { OffsetGlider(&theGlider, kToRight); OffsetGlider(&theGlider2, kToRight); QSetRect(&enterRect, 0, 0, 48, 20); QOffsetRect(&enterRect, kRoomWide - 48, kGliderStartsDown + (short)thisRoom->rightStart - 2); theGlider.enteredRect = enterRect; theGlider2.enteredRect = enterRect; } else { OffsetGlider(thisGlider, kToRight); QSetRect(&enterRect, 0, 0, 48, 20); QOffsetRect(&enterRect, kRoomWide - 48, kGliderStartsDown + (short)thisRoom->rightStart - 2); thisGlider->enteredRect = enterRect; } break; case kAbove: SetMusicalMode(kKickGameScoreMode); ForceThisRoom(localNumbers[kNorthRoom]); if (!takingTheStairs) { if (twoPlayerGame) { UndoGliderLimbo(&theGlider); UndoGliderLimbo(&theGlider2); OffsetGlider(&theGlider, kBelow); OffsetGlider(&theGlider2, kBelow); theGlider.enteredRect = theGlider.dest; theGlider2.enteredRect = theGlider2.dest; } else { OffsetGlider(thisGlider, kBelow); thisGlider->enteredRect = thisGlider->dest; } } else { if (twoPlayerGame) { ReadyGliderForTripUpStairs(&theGlider); ReadyGliderForTripUpStairs(&theGlider2); } else ReadyGliderForTripUpStairs(thisGlider); } break; case kBelow: SetMusicalMode(kKickGameScoreMode); ForceThisRoom(localNumbers[kSouthRoom]); if (!takingTheStairs) { if (twoPlayerGame) { UndoGliderLimbo(&theGlider); UndoGliderLimbo(&theGlider2); OffsetGlider(&theGlider, kAbove); OffsetGlider(&theGlider2, kAbove); theGlider.enteredRect = theGlider.dest; theGlider2.enteredRect = theGlider2.dest; } else { OffsetGlider(thisGlider, kAbove); thisGlider->enteredRect = thisGlider->dest; } } else { if (twoPlayerGame) { ReadyGliderForTripDownStairs(&theGlider); ReadyGliderForTripDownStairs(&theGlider2); } else ReadyGliderForTripDownStairs(thisGlider); } break; default: break; } if ((twoPlayerGame) && (!onePlayerLeft)) { if (firstPlayer == kPlayer1) TagGliderIdle(&theGlider2); else TagGliderIdle(&theGlider); } ReadyLevel(); RefreshScoreboard(kNormalTitleMode); WipeScreenOn(where, &justRoomsRect); #ifdef COMPILEQT RenderFrame(); if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) { GoToBeginningOfMovie(theMovie); StartMovie(theMovie); } #endif } //-------------------------------------------------------------- TransportRoomToRoom void TransportRoomToRoom (gliderPtr thisGlider) { Boolean sameRoom; SetMusicalMode(kKickGameScoreMode); HandleRoomVisitation(); sameRoom = (transRoom == thisRoomNumber); if (!sameRoom) ForceThisRoom(transRoom); if (twoPlayerGame) { UndoGliderLimbo(&theGlider); // turn off limbo if needed UndoGliderLimbo(&theGlider2); // turn off limbo if needed ReadyGliderFromTransit(&theGlider, linkedToWhat); ReadyGliderFromTransit(&theGlider2, linkedToWhat); } else ReadyGliderFromTransit(thisGlider, linkedToWhat); if (!sameRoom) ReadyLevel(); RefreshScoreboard(kNormalTitleMode); if (!sameRoom) WipeScreenOn(kAbove, &justRoomsRect); #ifdef COMPILEQT RenderFrame(); if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) { GoToBeginningOfMovie(theMovie); StartMovie(theMovie); } #endif } //-------------------------------------------------------------- MoveDuctToDuct void MoveDuctToDuct (gliderPtr thisGlider) { Boolean sameRoom; SetMusicalMode(kKickGameScoreMode); HandleRoomVisitation(); sameRoom = (transRoom == thisRoomNumber); if (!sameRoom) ForceThisRoom(transRoom); if (twoPlayerGame) { UndoGliderLimbo(&theGlider); // turn off limbo if needed UndoGliderLimbo(&theGlider2); // turn off limbo if needed ReadyGliderFromTransit(&theGlider, linkedToWhat); ReadyGliderFromTransit(&theGlider2, linkedToWhat); } else ReadyGliderFromTransit(thisGlider, linkedToWhat); if (!sameRoom) ReadyLevel(); RefreshScoreboard(kNormalTitleMode); if (!sameRoom) WipeScreenOn(kAbove, &justRoomsRect); #ifdef COMPILEQT RenderFrame(); if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) { GoToBeginningOfMovie(theMovie); StartMovie(theMovie); } #endif } //-------------------------------------------------------------- MoveMailToMail void MoveMailToMail (gliderPtr thisGlider) { Boolean sameRoom; SetMusicalMode(kKickGameScoreMode); HandleRoomVisitation(); sameRoom = (transRoom == thisRoomNumber); if (!sameRoom) ForceThisRoom(transRoom); if (twoPlayerGame) { UndoGliderLimbo(&theGlider); // turn off limbo if needed UndoGliderLimbo(&theGlider2); // turn off limbo if needed ReadyGliderFromTransit(&theGlider, linkedToWhat); ReadyGliderFromTransit(&theGlider2, linkedToWhat); } else ReadyGliderFromTransit(thisGlider, linkedToWhat); if (!sameRoom) ReadyLevel(); RefreshScoreboard(kNormalTitleMode); if (!sameRoom) WipeScreenOn(kAbove, &justRoomsRect); #ifdef COMPILEQT RenderFrame(); if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvOn)) { GoToBeginningOfMovie(theMovie); StartMovie(theMovie); } #endif } //-------------------------------------------------------------- HandleRoomVisitation void HandleRoomVisitation (void) { houseType *thisHousePtr; char wasState; if (!thisRoom->visited) { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); thisHousePtr = *thisHouse; thisHousePtr->rooms[localNumbers[kCentralRoom]].visited = true; HSetState((Handle)thisHouse, wasState); theScore += kRoomVisitScore; thisRoom->visited = true; } } //-------------------------------------------------------------- ForceKillGlider void ForceKillGlider (void) { if (theGlider.mode == kGliderInLimbo) { if (theGlider2.mode != kGliderFadingOut) { StartGliderFadingOut(&theGlider2); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); playerSuicide = true; } } else if (theGlider2.mode == kGliderInLimbo) { if (theGlider.mode != kGliderFadingOut) { StartGliderFadingOut(&theGlider); PlayPrioritySound(kFadeOutSound, kFadeOutPriority); playerSuicide = true; } } } //-------------------------------------------------------------- FollowTheLeader void FollowTheLeader (void) { short wasEscaped; Boolean oneOrTwo; playerSuicide = false; wasEscaped = otherPlayerEscaped; otherPlayerEscaped = kNoOneEscaped; if (theGlider.mode == kGliderInLimbo) { oneOrTwo = true; theGlider2.dest = theGlider.dest; theGlider2.destShadow = theGlider.destShadow; theGlider2.whole = theGlider2.dest; theGlider2.wholeShadow = theGlider2.destShadow; } else if (theGlider2.mode == kGliderInLimbo) { oneOrTwo = false; theGlider.dest = theGlider2.dest; theGlider.destShadow = theGlider2.destShadow; theGlider.whole = theGlider.dest; theGlider.wholeShadow = theGlider.destShadow; } switch (wasEscaped) { case kPlayerEscapedUp: case kPlayerEscapingUpStairs: case kPlayerEscapedUpStairs: if (oneOrTwo) MoveRoomToRoom(&theGlider2, kAbove); else MoveRoomToRoom(&theGlider, kAbove); break; case kPlayerEscapedDown: case kPlayerEscapingDownStairs: case kPlayerEscapedDownStairs: if (oneOrTwo) MoveRoomToRoom(&theGlider2, kBelow); else MoveRoomToRoom(&theGlider, kBelow); break; case kPlayerEscapedLeft: if (oneOrTwo) MoveRoomToRoom(&theGlider2, kToLeft); else MoveRoomToRoom(&theGlider, kToLeft); break; case kPlayerEscapedRight: if (oneOrTwo) MoveRoomToRoom(&theGlider2, kToRight); else MoveRoomToRoom(&theGlider, kToRight); break; case kPlayerTransportedOut: if (oneOrTwo) TransportRoomToRoom(&theGlider2); else TransportRoomToRoom(&theGlider); break; case kPlayerMailedOut: if (oneOrTwo) MoveMailToMail(&theGlider2); else MoveMailToMail(&theGlider); break; case kPlayerDuckedOut: if (oneOrTwo) MoveDuctToDuct(&theGlider2); else MoveDuctToDuct(&theGlider); break; default: break; } } \ No newline at end of file diff --git a/Sources/Transitions.c b/Sources/Transitions.c deleted file mode 100755 index 86ccef8..0000000 --- a/Sources/Transitions.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Transitions.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" #include "MainWindow.h" #include "RectUtils.h" //============================================================== Functions //-------------------------------------------------------------- PourScreenOn void PourScreenOn (Rect *theRect) { #define kMaxColumnsWide 96 #define kChipHigh 20 #define kChipWide 16 Rect columnRects[kMaxColumnsWide]; short columnProgress[kMaxColumnsWide]; short i, colsComplete, colWide, rowTall; Boolean working; colWide = theRect->right / kChipWide; // determine # of cols rowTall = (theRect->bottom / kChipHigh) + 1; // determine # of rows working = true; colsComplete = 0; for (i = 0; i < colWide; i++) { columnProgress[i] = 0; QSetRect(&columnRects[i], 0, 0, kChipWide, kChipHigh); QOffsetRect(&columnRects[i], (i * kChipWide) + theRect->left, theRect->top); } while (working) { do { i = RandomInt(colWide); } while (columnProgress[i] >= rowTall); if (columnRects[i].left < theRect->left) columnRects[i].left = theRect->left; if (columnRects[i].top < theRect->top) columnRects[i].top = theRect->top; if (columnRects[i].right > theRect->right) columnRects[i].right = theRect->right; if (columnRects[i].bottom > theRect->bottom) columnRects[i].bottom = theRect->bottom; CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &columnRects[i], &columnRects[i], srcCopy, nil); QOffsetRect(&columnRects[i], 0, kChipHigh); columnProgress[i]++; if (columnProgress[i] >= rowTall) { colsComplete++; if (colsComplete >= colWide) working = false; } } } //-------------------------------------------------------------- WipeScreenOn void WipeScreenOn (short direction, Rect *theRect) { #define kWipeRectThick 4 Rect wipeRect; RgnHandle dummyRgn; short hOffset, vOffset; short i, count; wipeRect = *theRect; switch (direction) { case kAbove: wipeRect.bottom = wipeRect.top + kWipeRectThick; hOffset = 0; vOffset = kWipeRectThick; count = ((theRect->bottom - theRect->top) / kWipeRectThick) + 1; break; case kToRight: wipeRect.left = wipeRect.right - kWipeRectThick; hOffset = -kWipeRectThick; vOffset = 0; count = workSrcRect.right / kWipeRectThick; break; case kBelow: wipeRect.top = wipeRect.bottom - kWipeRectThick; hOffset = 0; vOffset = -kWipeRectThick; count = ((theRect->bottom - theRect->top) / kWipeRectThick) + 1; break; case kToLeft: wipeRect.right = wipeRect.left + kWipeRectThick; hOffset = kWipeRectThick; vOffset = 0; count = workSrcRect.right / kWipeRectThick; break; } dummyRgn = NewRgn(); for (i = 0; i < count; i++) { CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), &wipeRect, &wipeRect, srcCopy, GetPortVisibleRegion(GetWindowPort(mainWindow), dummyRgn)); QOffsetRect(&wipeRect, hOffset, vOffset); if (wipeRect.top < theRect->top) wipeRect.top = theRect->top; else if (wipeRect.top > theRect->bottom) wipeRect.top = theRect->bottom; if (wipeRect.bottom < theRect->top) wipeRect.bottom = theRect->top; else if (wipeRect.bottom > theRect->bottom) wipeRect.bottom = theRect->bottom; } DisposeRgn(dummyRgn); } //-------------------------------------------------------------- DumpScreenOn void DumpScreenOn (Rect *theRect) { CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), theRect, theRect, srcCopy, nil); } \ No newline at end of file diff --git a/Sources/Triggers.c b/Sources/Triggers.c deleted file mode 100755 index 7e742e2..0000000 --- a/Sources/Triggers.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Triggers.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #define kMaxTriggers 16 typedef struct { short object, room; short index, timer; short what; Boolean armed; } trigType, *trigPtr; short FindEmptyTriggerSlot (void); void FireTrigger (short); trigType triggers[kMaxTriggers]; //============================================================== Functions //-------------------------------------------------------------- ArmTrigger void ArmTrigger (hotPtr who) { short where, whoLinked; if (who->stillOver) return; where = FindEmptyTriggerSlot(); if (where != -1) { whoLinked = who->who; // what is trigger's obj. # triggers[where].room = masterObjects[whoLinked].roomLink; triggers[where].object = masterObjects[whoLinked].objectLink; triggers[where].index = whoLinked; triggers[where].timer = masterObjects[whoLinked].theObject.data.e.delay * 3; triggers[where].what = masterObjects[triggers[where].object].theObject.what; triggers[where].armed = true; } who->stillOver = true; } //-------------------------------------------------------------- FindEmptyTriggerSlot short FindEmptyTriggerSlot (void) { short where, i; where = -1; for (i = 0; i < kMaxTriggers; i++) { if (!triggers[i].armed) { where = i; break; } } return (where); } //-------------------------------------------------------------- HandleTriggers void HandleTriggers (void) { short i; for (i = 0; i < kMaxTriggers; i++) { if (triggers[i].armed) { triggers[i].timer--; if (triggers[i].timer <= 0) { triggers[i].timer = 0; triggers[i].armed = false; FireTrigger(i); } } } } //-------------------------------------------------------------- FireTrigger void FireTrigger (short index) { short triggerIs, triggeredIs; char wasState; triggerIs = triggers[index].index; if (masterObjects[triggerIs].localLink != -1) { triggeredIs = masterObjects[triggerIs].localLink; switch (masterObjects[triggeredIs].theObject.what) { case kGreaseRt: case kGreaseLf: if (SetObjectState(triggers[index].room, triggers[index].object, kForceOn, triggeredIs)) { SpillGrease(masterObjects[triggeredIs].dynaNum, masterObjects[triggeredIs].hotNum); } break; case kLightSwitch: case kMachineSwitch: case kThermostat: case kPowerSwitch: case kKnifeSwitch: case kInvisSwitch: TriggerSwitch(masterObjects[triggeredIs].dynaNum); break; case kSoundTrigger: PlayPrioritySound(kChordSound, kChordPriority); // Change me break; case kToaster: TriggerToast(masterObjects[triggeredIs].dynaNum); break; case kGuitar: PlayPrioritySound(kChordSound, kChordPriority); break; case kCoffee: PlayPrioritySound(kCoffeeSound, kCoffeePriority); break; case kOutlet: TriggerOutlet(masterObjects[triggeredIs].dynaNum); break; case kBalloon: TriggerBalloon(masterObjects[triggeredIs].dynaNum); break; case kCopterLf: case kCopterRt: TriggerCopter(masterObjects[triggeredIs].dynaNum); break; case kDartLf: case kDartRt: TriggerDart(masterObjects[triggeredIs].dynaNum); break; case kDrip: TriggerDrip(masterObjects[triggeredIs].dynaNum); break; case kFish: TriggerFish(masterObjects[triggeredIs].dynaNum); break; } } else { wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); triggeredIs = masterObjects[triggerIs].localLink; switch ((*thisHouse)->rooms[triggers[index].room]. objects[triggers[index].object].what) { case kGreaseRt: case kGreaseLf: if (SetObjectState(triggers[index].room, triggers[index].object, kForceOn, triggeredIs)) { SpillGrease(masterObjects[triggeredIs].dynaNum, masterObjects[triggeredIs].hotNum); } break; } HSetState((Handle)thisHouse, wasState); } } //-------------------------------------------------------------- ZeroTriggers void ZeroTriggers (void) { short i; for (i = 0; i < kMaxTriggers; i++) triggers[i].armed = false; } \ No newline at end of file diff --git a/Sources/Trip.c b/Sources/Trip.c deleted file mode 100755 index 18b5031..0000000 --- a/Sources/Trip.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // Trip.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" extern dynaPtr dinahs; extern hotPtr hotSpots; extern short numDynamics, tvWithMovieNumber; extern Boolean tvOn; //============================================================== Functions //-------------------------------------------------------------- ToggleToaster void ToggleToaster (short index) { dinahs[index].active = !dinahs[index].active; } //-------------------------------------------------------------- ToggleMacPlus void ToggleMacPlus (short index) { dinahs[index].active = !dinahs[index].active; if (dinahs[index].active) dinahs[index].timer = 40; else dinahs[index].timer = 10; } //-------------------------------------------------------------- ToggleTV void ToggleTV (short index) { dinahs[index].active = !dinahs[index].active; if ((thisMac.hasQT) && (hasMovie) && (tvInRoom) && (tvWithMovieNumber == index)) { if (dinahs[index].active) { GoToBeginningOfMovie(theMovie); StartMovie(theMovie); tvOn = true; } else { StopMovie(theMovie); tvOn = false; } } dinahs[index].timer = 4; } //-------------------------------------------------------------- ToggleCoffee void ToggleCoffee (short index) { dinahs[index].active = !dinahs[index].active; dinahs[index].timer = 4; } //-------------------------------------------------------------- ToggleOutlet void ToggleOutlet (short index) { dinahs[index].active = !dinahs[index].active; } //-------------------------------------------------------------- ToggleVCR void ToggleVCR (short index) { dinahs[index].active = !dinahs[index].active; dinahs[index].timer = 4; } //-------------------------------------------------------------- ToggleStereo void ToggleStereos (short index) { if (dinahs[index].timer == 0) { dinahs[index].active = !dinahs[index].active; dinahs[index].timer = 4; } } //-------------------------------------------------------------- ToggleMicrowave void ToggleMicrowave (short index) { dinahs[index].active = !dinahs[index].active; dinahs[index].timer = 4; } //-------------------------------------------------------------- ToggleBalloon void ToggleBalloon (short index) { dinahs[index].active = !dinahs[index].active; } //-------------------------------------------------------------- ToggleCopter void ToggleCopter (short index) { dinahs[index].active = !dinahs[index].active; } //-------------------------------------------------------------- ToggleDart void ToggleDart (short index) { dinahs[index].active = !dinahs[index].active; } //-------------------------------------------------------------- ToggleBall void ToggleBall (short index) { dinahs[index].active = !dinahs[index].active; } //-------------------------------------------------------------- ToggleDrip void ToggleDrip (short index) { dinahs[index].active = !dinahs[index].active; } //-------------------------------------------------------------- ToggleFish void ToggleFish (short index) { dinahs[index].active = !dinahs[index].active; } //-------------------------------------------------------------- TriggerSwitch void TriggerSwitch (short who) { HandleSwitches(&hotSpots[who]); } //-------------------------------------------------------------- TriggerToast void TriggerToast (short who) { if (!dinahs[who].moving) { if (dinahs[who].active) { dinahs[who].vVel = (short)-dinahs[who].count; dinahs[who].frame = 0; dinahs[who].moving = true; PlayPrioritySound(kToastLaunchSound, kToastLaunchPriority); } else dinahs[who].frame = dinahs[who].timer; } } //-------------------------------------------------------------- TriggerOutlet void TriggerOutlet (short who) { if (dinahs[who].position == 0) { if (dinahs[who].active) { dinahs[who].position = 1; dinahs[who].timer = kLengthOfZap; PlayPrioritySound(kZapSound, kZapPriority); } else dinahs[who].timer = dinahs[who].count; } } //-------------------------------------------------------------- TriggerDrip void TriggerDrip (short who) { if ((!dinahs[who].moving) && (dinahs[who].timer > 7)) dinahs[who].timer = 7; // kick off drip } //-------------------------------------------------------------- TriggerFish void TriggerFish (short who) { if ((dinahs[who].active) && (!dinahs[who].moving)) { dinahs[who].whole = dinahs[who].dest; dinahs[who].moving = true; dinahs[who].frame = 4; PlayPrioritySound(kFishOutSound, kFishOutPriority); } } //-------------------------------------------------------------- TriggerBalloon void TriggerBalloon (short who) { if (!dinahs[who].moving) dinahs[who].timer = kStartSparkle + 1; } //-------------------------------------------------------------- TriggerCopter void TriggerCopter (short who) { if (!dinahs[who].moving) dinahs[who].timer = kStartSparkle + 1; } //-------------------------------------------------------------- TriggerDart void TriggerDart (short who) { if (!dinahs[who].moving) dinahs[who].timer = kStartSparkle + 1; } //-------------------------------------------------------------- UpdateOutletsLighting void UpdateOutletsLighting (short room, short nLights) { short i; for (i = 0; i < numDynamics; i++) { if ((dinahs[i].type == kOutlet) && (dinahs[i].room == room)) dinahs[i].hVel = nLights; } } \ No newline at end of file diff --git a/Sources/Utilities.c b/Sources/Utilities.c deleted file mode 100755 index 533cb5f..0000000 --- a/Sources/Utilities.c +++ /dev/null @@ -1 +0,0 @@ -//============================================================================ //---------------------------------------------------------------------------- // Utilities.c //---------------------------------------------------------------------------- //============================================================================ #include #include #include #include #include #include #include "Externs.h" #include "Utilities.h" GDHandle thisGDevice; UInt32 theSeed; extern Boolean switchedOut; //============================================================== Functions //-------------------------------------------------------------- MyGetGlobalMouse // Returns the position of the mouse in global coordinates. Point MyGetGlobalMouse (void) { Point localWhere; GetMouse(&localWhere); LocalToGlobal(&localWhere); return (localWhere); } //-------------------------------------------------------------- ToolBoxInit // The standard ToolBox intialization that must happen when any MacÉ // program first launches. void ToolBoxInit (void) { #if !TARGET_CARBON InitGraf(&qd.thePort); InitFonts(); FlushEvents(everyEvent, 0); InitWindows(); InitMenus(); TEInit(); InitDialogs(nil); MaxApplZone(); MoreMasters(); MoreMasters(); MoreMasters(); MoreMasters(); GetDateTime((UInt32 *)&qd.randSeed); #endif InitCursor(); switchedOut = false; } //-------------------------------------------------------------- RandomInt // Returns a random integer (short) within "range". short RandomInt (short range) { register long rawResult; rawResult = Random(); if (rawResult < 0L) rawResult *= -1L; rawResult = (rawResult * (long)range) / 32768L; return ((short)rawResult); } //-------------------------------------------------------------- RandomLong // Returns a random long interger within "range". long RandomLong (long range) { register long highWord, lowWord; register long rawResultHi, rawResultLo; highWord = (range & 0xFFFF0000) >> 16; lowWord = range & 0x0000FFFF; rawResultHi = Random(); if (rawResultHi < 0L) rawResultHi *= -1L; rawResultHi = (rawResultHi * highWord) / 32768L; rawResultLo = Random(); if (rawResultLo < 0L) rawResultLo *= -1L; rawResultLo = (rawResultLo * lowWord) / 32768L; rawResultHi = (rawResultHi << 16) + rawResultLo; return (rawResultHi); } //-------------------------------------------------------------- InitRandomLongQUS // Initializes random seed for quick & dirty long random number function (below). void InitRandomLongQUS (void) { GetDateTime(&theSeed); } //-------------------------------------------------------------- RandomLongQUS // Very simple (but fast) pseudo-random number generator. UInt32 RandomLongQUS (void) { theSeed = theSeed * 1103515245 + 12345; return (theSeed); } //-------------------------------------------------------------- RedAlert // Called when we must quit app. Brings up a dialog informing userÉ // of the problem and the exits to shell. void RedAlert (short errorNumber) { #define rDeathAlertID 170 // alert res. ID for death error #define rErrTitleID 170 // string ID for death error title #define rErrMssgID 171 // string ID for death error message short dummyInt; Str255 errTitle, errMessage, errNumberString; InitCursor(); if (errorNumber > 1) // <= 0 is unaccounted for { GetIndString(errTitle, rErrTitleID, errorNumber); GetIndString(errMessage, rErrMssgID, errorNumber); } else { GetIndString(errTitle, rErrTitleID, 1); GetIndString(errMessage, rErrMssgID, 1); } NumToString((long)errorNumber, errNumberString); ParamText(errTitle, errMessage, errNumberString, "\p"); // CenterAlert(rDeathAlertID); dummyInt = Alert(rDeathAlertID, nil); ExitToShell(); } //-------------------------------------------------------------- FindOurDevice // Finds the main device (monitor with the menu bar on it). void FindOurDevice (void) { thisGDevice = GetMainDevice(); if (thisGDevice == nil) RedAlert(kErrFailedGetDevice); } //-------------------------------------------------------------- CreateOffScreenBitMap // Creates an offscreen bit map (b&w - 1 bit depth). /* void CreateOffScreenBitMap (Rect *theRect, GrafPtr *offScreen) { GrafPtr theBWPort; BitMap theBitMap; long theRowBytes; theBWPort = (GrafPtr)(NewPtr(sizeof(GrafPort))); OpenPort(theBWPort); theRowBytes = (long)((theRect->right - theRect->left + 15L) / 16L) * 2L; theBitMap.rowBytes = (short)theRowBytes; theBitMap.baseAddr = NewPtr((long)theBitMap.rowBytes * (theRect->bottom - theRect->top)); if (theBitMap.baseAddr == nil) RedAlert(kErrNoMemory); theBitMap.bounds = *theRect; if (MemError() != noErr) RedAlert(kErrNoMemory); SetPortBits(&theBitMap); ClipRect(theRect); RectRgn(theBWPort->visRgn, theRect); EraseRect(theRect); *offScreen = theBWPort; } */ //-------------------------------------------------------------- CreateOffScreenPixMap // Creates an offscreen pix map using the depth of the current device. /* void CreateOffScreenPixMap (Rect *theRect, CGrafPtr *offScreen) { CTabHandle thisColorTable; GDHandle oldDevice; CGrafPtr newCGrafPtr; Ptr theseBits; long sizeOfOff, offRowBytes; OSErr theErr; short thisDepth; char wasState; oldDevice = GetGDevice(); SetGDevice(thisGDevice); newCGrafPtr = nil; newCGrafPtr = (CGrafPtr)NewPtr(sizeof(CGrafPort)); if (newCGrafPtr != nil) { OpenCPort(newCGrafPtr); thisDepth = (**(*newCGrafPtr).portPixMap).pixelSize; offRowBytes = ((((long)thisDepth * (long)(theRect->right - theRect->left)) + 15L) >> 4L) << 1L; sizeOfOff = (long)(theRect->bottom - theRect->top + 1) * offRowBytes; // sizeOfOff = (long)(theRect->bottom - theRect->top) * offRowBytes; OffsetRect(theRect, -theRect->left, -theRect->top); theseBits = NewPtr(sizeOfOff); if (theseBits != nil) { // workaround (**(*newCGrafPtr).portPixMap).baseAddr = theseBits + offRowBytes; // (**(*newCGrafPtr).portPixMap).baseAddr = theseBits; (**(*newCGrafPtr).portPixMap).rowBytes = (short)offRowBytes + 0x8000; (**(*newCGrafPtr).portPixMap).bounds = *theRect; wasState = HGetState((Handle)thisGDevice); HLock((Handle)thisGDevice); thisColorTable = (**(**thisGDevice).gdPMap).pmTable; HSetState((Handle)thisGDevice, wasState); theErr = HandToHand((Handle *)&thisColorTable); (**(*newCGrafPtr).portPixMap).pmTable = thisColorTable; ClipRect(theRect); RectRgn(newCGrafPtr->visRgn, theRect); ForeColor(blackColor); BackColor(whiteColor); EraseRect(theRect); } else { CloseCPort(newCGrafPtr); DisposePtr((Ptr)newCGrafPtr); newCGrafPtr = nil; RedAlert(kErrNoMemory); } } else RedAlert(kErrNoMemory); *offScreen = newCGrafPtr; SetGDevice(oldDevice); } */ //-------------------------------------------------------------------- CreateOffScreenGWorld // Creates an offscreen GWorldÊusing the depth passed in. OSErr CreateOffScreenGWorld (GWorldPtr *theGWorld, Rect *bounds, short depth) { OSErr theErr; theErr = NewGWorld(theGWorld, depth, bounds, nil, nil, useTempMem); if (theErr) theErr = NewGWorld(theGWorld, depth, bounds, nil, nil, 0); LockPixels(GetGWorldPixMap(*theGWorld)); return theErr; } //-------------------------------------------------------------- KillOffScreenPixMap // Destroys memory allocated by an offscreen pix map. /* void KillOffScreenPixMap (CGrafPtr offScreen) { Ptr theseBits; if (offScreen != nil) { theseBits = (**(*offScreen).portPixMap).baseAddr; theseBits -= (**(*offScreen).portPixMap).rowBytes & 0x7FFF; // workaround DisposePtr(theseBits); DisposeHandle((Handle)(**(*offScreen).portPixMap).pmTable); CloseCPort(offScreen); DisposePtr((Ptr)offScreen); } } */ //-------------------------------------------------------------- KillOffScreenBitMap // Destroys memory allocated by an offscreen bit map. /* void KillOffScreenBitMap (GrafPtr offScreen) { if (offScreen != nil) { DisposePtr((Ptr)(offScreen->portBits.baseAddr)); ClosePort(offScreen); DisposePtr((Ptr)offScreen); } } */ //-------------------------------------------------------------- LoadGraphic // Function loads the specified 'PICT' from disk and draws it toÉ // the current port (no scaling, clipping, etc, are done). AlwaysÉ // draws in the upper left corner of current port. void LoadGraphic (short resID) { Rect bounds; PicHandle thePicture; thePicture = GetPicture(resID); if (thePicture == nil) RedAlert(kErrFailedGraphicLoad); HLock((Handle)thePicture); bounds = (*thePicture)->picFrame; HUnlock((Handle)thePicture); OffsetRect(&bounds, -bounds.left, -bounds.top); DrawPicture(thePicture, &bounds); ReleaseResource((Handle)thePicture); } //-------------------------------------------------------------- LoadScaledGraphic // Loads the specified 'PICT' and draws it mapped to the rectangleÉ // specified. If this rect isn't the same size of the 'PICT', scalingÉ // will occur. void LoadScaledGraphic (short resID, Rect *theRect) { PicHandle thePicture; thePicture = GetPicture(resID); if (thePicture == nil) RedAlert(kErrFailedGraphicLoad); DrawPicture(thePicture, theRect); ReleaseResource((Handle)thePicture); } //-------------------------------------------------------------- PlotSICN // Draws a small icon (16 x 16 pixels). /* void PlotSICN (Rect *theRect, SICNHand theSICN, long theIndex) { char state; BitMap srcBits; if ((theSICN != nil) && ((GetHandleSize((Handle)theSICN) / sizeof(SICN)) > theIndex)) { state = HGetState((Handle)theSICN); HLock((Handle)theSICN); srcBits.baseAddr = (Ptr)(*theSICN)[theIndex]; srcBits.rowBytes = 2; SetRect(&srcBits.bounds, 0, 0, 16, 16); CopyBits(&srcBits,&(*qd.thePort).portBits, &srcBits.bounds, theRect, srcCopy, nil); HSetState((Handle) theSICN, state); } } */ //-------------------------------------------------------------- LargeIconPlot // Draws a standard b&w icon (32 x 32) - resource is an 'ICON'. void LargeIconPlot (Rect *theRect, short theID) { OSErr theErr; Handle theSuite; theErr = GetIconSuite(&theSuite, theID, svAllLargeData); if (theErr == noErr) theErr = PlotIconSuite(theRect, atNone, ttNone, theSuite); } //-------------------------------------------------------------- DrawCIcon // Draws a standard color icon (32 x 32) - resource is a 'CICN'. void DrawCIcon (short theID, short h, short v) { CIconHandle theIcon; Rect theRect; theIcon = GetCIcon(theID); if (theIcon != nil) { SetRect(&theRect, 0, 0, 32, 32); OffsetRect(&theRect, h, v); PlotCIcon(&theRect, theIcon); DisposeCIcon(theIcon); } } //-------------------------------------------------------------- LongSquareRoot // This is a quick and dirty square root function that returns prettyÉ // accurate long integer results. It uses no transcendental functions orÉ // floating point. long LongSquareRoot (long theNumber) { long currentAnswer; long nextTrial; if (theNumber <= 1L) return (theNumber); nextTrial = theNumber / 2; do { currentAnswer = nextTrial; nextTrial = (nextTrial + theNumber / nextTrial) / 2; } while (nextTrial < currentAnswer); return(currentAnswer); } //-------------------------------------------------------------- WaitForInputEvent // Wait for either a key to be hit or the mouse button to be clicked. // Also has a "timeout" parameter ("seconds"). Boolean WaitForInputEvent (short seconds) { EventRecord theEvent; KeyMap theKeys; long timeToBail; Boolean waiting, didResume; timeToBail = TickCount() + 60L * (long)seconds; FlushEvents(everyEvent, 0); waiting = true; didResume = false; while (waiting) { GetKeys(theKeys); if ((BitTst(&theKeys, kCommandKeyMap)) || (BitTst(&theKeys, kOptionKeyMap)) || (BitTst(&theKeys, kShiftKeyMap)) || (BitTst(&theKeys, kControlKeyMap))) waiting = false; if (GetNextEvent(everyEvent, &theEvent)) { if ((theEvent.what == mouseDown) || (theEvent.what == keyDown)) waiting = false; else if ((theEvent.what == osEvt) && (theEvent.message & 0x01000000)) { if (theEvent.message & 0x00000001) // resuming { didResume = true; waiting = false; } else // suspending { InitCursor(); } } } if ((seconds != -1) && (TickCount() >= timeToBail)) waiting = false; } FlushEvents(everyEvent, 0); return (didResume); } //-------------------------------------------------------------- WaitCommandQReleased // Waits until the Command-Q key combination is released. void WaitCommandQReleased (void) { KeyMap theKeys; Boolean waiting; waiting = true; while (waiting) { GetKeys(theKeys); if ((!BitTst(&theKeys, kCommandKeyMap)) || (!BitTst(&theKeys, kQKeyMap))) waiting = false; } FlushEvents(everyEvent, 0); } //-------------------------------------------------------------- KeyMapOffsetFromRawKey // Converts a raw key code to keymap offset (ugly stuff). char KeyMapOffsetFromRawKey (char rawKeyCode) { char hiByte, loByte, theOffset; hiByte = rawKeyCode & 0xF0; loByte = rawKeyCode & 0x0F; if (loByte <= 0x07) theOffset = hiByte + (0x07 - loByte); else theOffset = hiByte + (0x17 - loByte); return (theOffset); } //-------------------------------------------------------------- GetKeyMapFromMessage // Gets the key map offset from a keyDown event's message field. char GetKeyMapFromMessage (long message) { long theVirtual; char offset; theVirtual = (message & keyCodeMask) >> 8; offset = KeyMapOffsetFromRawKey((char)theVirtual); return (offset); } //-------------------------------------------------------------- GetKeyName // Given a keyDown event (it's message field), this function returnsÉ // a string with that key's name (so we get "Shift" and "Esc", etc.). void GetKeyName (long message, StringPtr theName) { long theASCII, theVirtual; theASCII = message & charCodeMask; theVirtual = (message & keyCodeMask) >> 8; if ((theASCII >= kExclamationASCII) && (theASCII <= kZKeyASCII)) { if ((theVirtual >= 0x0041) && (theVirtual <= 0x005C)) { PasStringCopy("\p( )", theName); theName[2] = (char)theASCII; } else { PasStringCopy("\p key", theName); theName[1] = (char)theASCII; } } else { switch (theASCII) { case kHomeKeyASCII: PasStringCopy("\phome", theName); break; case kEnterKeyASCII: PasStringCopy("\penter", theName); break; case kEndKeyASCII: PasStringCopy("\pend", theName); break; case kHelpKeyASCII: PasStringCopy("\phelp", theName); break; case kDeleteKeyASCII: PasStringCopy("\pdelete", theName); break; case kTabKeyASCII: PasStringCopy("\ptab", theName); break; case kPageUpKeyASCII: PasStringCopy("\ppg up", theName); break; case kPageDownKeyASCII: PasStringCopy("\ppg dn", theName); break; case kReturnKeyASCII: PasStringCopy("\preturn", theName); break; case kFunctionKeyASCII: switch (theVirtual) { case 0x0060: PasStringCopy("\pF5", theName); break; case 0x0061: PasStringCopy("\pF6", theName); break; case 0x0062: PasStringCopy("\pF7", theName); break; case 0x0063: PasStringCopy("\pF3", theName); break; case 0x0064: PasStringCopy("\pF8", theName); break; case 0x0065: PasStringCopy("\pF9", theName); break; case 0x0067: PasStringCopy("\pF11", theName); break; case 0x0069: PasStringCopy("\pF13", theName); break; case 0x006B: PasStringCopy("\pF14", theName); break; case 0x006D: PasStringCopy("\pF10", theName); break; case 0x006F: PasStringCopy("\pF12", theName); break; case 0x0071: PasStringCopy("\pF15", theName); break; case 0x0076: PasStringCopy("\pF4", theName); break; case 0x0078: PasStringCopy("\pF2", theName); break; case 0x007A: PasStringCopy("\pF1", theName); break; default: NumToString(theVirtual, theName); break; } break; case kClearKeyASCII: PasStringCopy("\pclear", theName); break; case kEscapeKeyASCII: if (theVirtual == 0x0047) PasStringCopy("\pclear", theName); else PasStringCopy("\pesc", theName); break; case kLeftArrowKeyASCII: PasStringCopy("\plf arrow", theName); break; case kRightArrowKeyASCII: PasStringCopy("\prt arrow", theName); break; case kUpArrowKeyASCII: PasStringCopy("\pup arrow", theName); break; case kDownArrowKeyASCII: PasStringCopy("\pdn arrow", theName); break; case kSpaceBarASCII: PasStringCopy("\pspace", theName); break; case kForwardDeleteASCII: PasStringCopy("\pfrwd del", theName); break; default: PasStringCopy("\p????", theName); break; } } } //-------------------------------------------------------------- OptionKeyDown // Returns true is the Option key is being held down. Boolean OptionKeyDown (void) { KeyMap theKeys; GetKeys(theKeys); if (BitTst(&theKeys, kOptionKeyMap)) return (true); else return (false); } //-------------------------------------------------------------- ExtractCTSeed // Very esoteric - gets the "color table seed" from a specified graf port. /* long ExtractCTSeed (CGrafPtr porter) { long theSeed; theSeed = (**((**(porter->portPixMap)).pmTable)).ctSeed; return(theSeed); } */ //-------------------------------------------------------------- ForceCTSeed // Forces the "color table seed" from a specified graf port to aÉ // specified value. /* void ForceCTSeed (CGrafPtr porter, long newSeed) { (**((**(porter->portPixMap)).pmTable)).ctSeed = newSeed; } */ //-------------------------------------------------------------- DelayTicks // Lil' function that just sits and waits a specified number ofÉ // Ticks (1/60 of a second). void DelayTicks (long howLong) { UInt32 whoCares; Delay(howLong, &whoCares); } //-------------------------------------------------------------- UnivGetSoundVolume // Returns the speaker volume (as set by the user) in the range ofÉ // zero to seven (handles Sound Manager 3 case as well). void UnivGetSoundVolume (short *volume, Boolean hasSM3) { #pragma unused (hasSM3) long longVol; OSErr theErr; // if (hasSM3) // { theErr = GetDefaultOutputVolume(&longVol); *volume = LoWord(longVol) / 0x0024; // } // else // GetSoundVol(volume); if (*volume > 7) *volume = 7; else if (*volume < 0) *volume = 0; } //-------------------------------------------------------------- UnivSetSoundVolume // Sets the speaker volume to a specified value (in the range ofÉ // zero to seven (handles Sound Manager 3 case as well). void UnivSetSoundVolume (short volume, Boolean hasSM3) { #pragma unused (hasSM3) long longVol; OSErr theErr; if (volume > 7) volume = 7; else if (volume < 0) volume = 0; // if (hasSM3) // { longVol = (long)volume * 0x0025; if (longVol > 0x00000100) longVol = 0x00000100; longVol = longVol + (longVol << 16); theErr = SetDefaultOutputVolume(longVol); // } // else // SetSoundVol(volume); } \ No newline at end of file diff --git a/Sources/WindowUtils.c b/Sources/WindowUtils.c deleted file mode 100755 index c0d1d72..0000000 --- a/Sources/WindowUtils.c +++ /dev/null @@ -1 +0,0 @@ - //============================================================================ //---------------------------------------------------------------------------- // WindowUtils.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include "Environ.h" #include "RectUtils.h" #define kFloatingKind 2048 #define kMessageWindowTall 48 WindowPtr mssgWindow; //============================================================== Functions //-------------------------------------------------------------- GetWindowTopLeft // Returns the top left coordinate of the specified window. CorrdinatesÉ // are (of course) global (local coordinates would always be (0, 0)). void GetWindowLeftTop (WindowPtr theWindow, short *left, short *top) { Point thePoint; Rect bounds; *left = 0; *top = 0; if (theWindow != nil) { SetPortWindowPort(theWindow); GetWindowBounds(theWindow, kWindowContentRgn, &bounds); thePoint.h = bounds.left; thePoint.v = bounds.top; LocalToGlobal(&thePoint); *left = thePoint.h; *top = thePoint.v; } } //-------------------------------------------------------------- GetWindowRect // Returns bounding rectangle of the specified window in global coords. void GetWindowRect (WindowPtr theWindow, Rect *bounds) { if (theWindow != nil) { SetPortWindowPort(theWindow); GetWindowBounds(theWindow, kWindowContentRgn, bounds); LocalToGlobalRect(bounds); } } //-------------------------------------------------------------- GetLocalWindowRect // Returns bounding rectangle of the specified window in local coords. // (When you just need its width and height.) void GetLocalWindowRect (WindowPtr theWindow, Rect *bounds) { if (theWindow != nil) { SetPortWindowPort(theWindow); GetWindowBounds(theWindow, kWindowContentRgn, bounds); } } //-------------------------------------------------------------- FlagWindowFloating // Sets the specified window's windowKind field to my own kFloatingKindÉ // variable. This way I can examine a window later and determine ifÉ // it's supposed to "float" above all other windows. /* void FlagWindowFloating (WindowPtr theWindow) { if (theWindow != nil) { ((WindowPeek)theWindow)->windowKind = kFloatingKind; BringToFront(theWindow); } } //-------------------------------------------------------------- IsWindowFloating // Tests a specific window to see if it is supposed to "float" above allÉ // other windows. Boolean IsWindowFloating (WindowPtr theWindow) { if (theWindow != nil) { return (((WindowPeek)theWindow)->windowKind == kFloatingKind); } else return (false); } */ //-------------------------------------------------------------- OpenMessageWindow // Brings up a simple message window. Nice sort of utility function. // Anytime you want a small, quick message to come up, call this. void OpenMessageWindow (StringPtr title) { Rect mssgWindowRect; SetRect(&mssgWindowRect, 0, 0, 256, kMessageWindowTall); if (thisMac.hasColor) mssgWindow = NewCWindow(nil, &mssgWindowRect, title, false, noGrowDocProc, kPutInFront, false, 0L); else mssgWindow = NewWindow(nil, &mssgWindowRect, title, false, noGrowDocProc, kPutInFront, false, 0L); if (mssgWindow != nil) { ShowWindow(mssgWindow); SetPort((GrafPtr)mssgWindow); ClipRect(&mssgWindowRect); ForeColor(blackColor); BackColor(whiteColor); TextFont(systemFont); } } //-------------------------------------------------------------- SetMessageWindowMessage // For the above message window, this function displays a string of textÉ // in the center of the window. void SetMessageWindowMessage (StringPtr message) { Rect mssgWindowRect; if (mssgWindow != nil) { SetPort((GrafPtr)mssgWindow); SetRect(&mssgWindowRect, 0, 0, 256, kMessageWindowTall); InsetRect(&mssgWindowRect, 16, 16); EraseRect(&mssgWindowRect); MoveTo(mssgWindowRect.left, mssgWindowRect.bottom - 6); DrawString(message); } } //-------------------------------------------------------------- CloseMessageWindow // Closes the previously referred to "message window". void CloseMessageWindow (void) { if (mssgWindow != nil) DisposeWindow(mssgWindow); mssgWindow = nil; } //-------------------------------------------------------------- CloseThisWindow // Given a specific window, this function will close it and set the windowÉ // pointer to null. void CloseThisWindow (WindowPtr *theWindow) { if (*theWindow != nil) DisposeWindow(*theWindow); *theWindow = nil; } \ No newline at end of file diff --git a/hqx2bin/hqx2bin.aps b/hqx2bin/hqx2bin.aps new file mode 100644 index 0000000..9f64a7c Binary files /dev/null and b/hqx2bin/hqx2bin.aps differ diff --git a/hqx2bin/hqx2bin.cpp b/hqx2bin/hqx2bin.cpp new file mode 100644 index 0000000..270811f --- /dev/null +++ b/hqx2bin/hqx2bin.cpp @@ -0,0 +1,76 @@ +#include + +/* +Copyright 2019 Eric Lasota + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "CFileStream.h" +#include "ScopedPtr.h" +#include "BinHex4.h" +#include "MacBinary2.h" +#include "MacFileMem.h" + +using namespace PortabilityLayer; + +int main(int argc, const char **argv) +{ + if (argc != 3) + { + fprintf(stderr, "Usage: hqx2bin "); + return -1; + } + +#ifdef _CRT_INSECURE_DEPRECATE + FILE *f = nullptr; + if (fopen_s(&f, argv[1], "rb")) + f = nullptr; +#else + FILE *f = fopen(argv[1], "rb"); +#endif + + if (!f) + { + fprintf(stderr, "Could not open input file"); + return -1; + } + + CFileStream fs(f, true, false, true); + + ScopedPtr memFile = BinHex4::LoadHQX(&fs); + + fs.Close(); + +#ifdef _CRT_INSECURE_DEPRECATE + FILE *outF = nullptr; + if (fopen_s(&outF, argv[2], "wb")) + outF = nullptr; +#else + FILE *outF = fopen(argv[2], "wb"); +#endif + + CFileStream outFS(outF, false, true, true); + + MacBinary2::WriteBin(memFile, &outFS); + + outFS.Close(); + + return 0; +} diff --git a/hqx2bin/hqx2bin.vcxproj b/hqx2bin/hqx2bin.vcxproj new file mode 100644 index 0000000..ea4d9f0 --- /dev/null +++ b/hqx2bin/hqx2bin.vcxproj @@ -0,0 +1,136 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {45B1B18C-C846-4044-9206-74F58DFC5E88} + hqx2bin + 10.0.16299.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + + + + {6ec62b0f-9353-40a4-a510-3788f1368b33} + + + + + + \ No newline at end of file diff --git a/hqx2bin/hqx2bin.vcxproj.filters b/hqx2bin/hqx2bin.vcxproj.filters new file mode 100644 index 0000000..764ae5e --- /dev/null +++ b/hqx2bin/hqx2bin.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/hqx2bin/x64/Debug/RCa77828 b/hqx2bin/x64/Debug/RCa77828 new file mode 100644 index 0000000..6ef5c74 Binary files /dev/null and b/hqx2bin/x64/Debug/RCa77828 differ diff --git a/hqx2bin/x64/Debug/vc141.idb b/hqx2bin/x64/Debug/vc141.idb new file mode 100644 index 0000000..6ec4267 Binary files /dev/null and b/hqx2bin/x64/Debug/vc141.idb differ diff --git a/hqx2gp/hqx2gp.cpp b/hqx2gp/hqx2gp.cpp new file mode 100644 index 0000000..893e0cc --- /dev/null +++ b/hqx2gp/hqx2gp.cpp @@ -0,0 +1,116 @@ +#include + +/* +Copyright 2019 Eric Lasota + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "CFileStream.h" +#include "ScopedPtr.h" +#include "BinHex4.h" +#include "MacBinary2.h" +#include "MacFileMem.h" + +#include + +using namespace PortabilityLayer; + +int main(int argc, const char **argv) +{ + if (argc != 3) + { + fprintf(stderr, "Usage: hqx2gp "); + return -1; + } + +#ifdef _CRT_INSECURE_DEPRECATE + FILE *f = nullptr; + if (fopen_s(&f, argv[1], "rb")) + f = nullptr; +#else + FILE *f = fopen(argv[1], "rb"); +#endif + + if (!f) + { + fprintf(stderr, "Could not open input file"); + return -1; + } + + CFileStream fs(f, true, false, true); + + ScopedPtr memFile = BinHex4::LoadHQX(&fs); + + fs.Close(); + + std::string fname = argv[2]; + + const char* extensions[] = { ".gpf", ".gpr", ".gpd", ".gpc" }; + + MacFilePropertiesSerialized sp; + sp.Serialize(memFile->FileInfo().m_properties); + + for (int i = 0; i < 4; i++) + { + const void *bufferToWrite = nullptr; + size_t sizeToWrite = 0; + + switch (i) + { + case 0: + bufferToWrite = sp.m_data; + sizeToWrite = sp.kSize; + break; + case 1: + bufferToWrite = memFile->ResourceFork(); + sizeToWrite = memFile->FileInfo().m_resourceForkSize; + break; + case 2: + bufferToWrite = memFile->DataFork(); + sizeToWrite = memFile->FileInfo().m_dataForkSize; + break; + case 3: + bufferToWrite = memFile->Comment(); + sizeToWrite = memFile->FileInfo().m_commentSize; + break; + }; + + if (sizeToWrite == 0) + continue; + + std::string path = fname + extensions[i]; + +#ifdef _CRT_INSECURE_DEPRECATE + FILE *outF = nullptr; + if (fopen_s(&outF, path.c_str(), "wb")) + outF = nullptr; +#else + FILE *outF = fopen(path.c_str(), "wb"); +#endif + + if (!outF) + continue; + + fwrite(bufferToWrite, 1, sizeToWrite, outF); + fclose(outF); + } + + return 0; +} diff --git a/hqx2gp/hqx2gp.vcxproj b/hqx2gp/hqx2gp.vcxproj new file mode 100644 index 0000000..e974956 --- /dev/null +++ b/hqx2gp/hqx2gp.vcxproj @@ -0,0 +1,136 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 15.0 + {5FDE4822-C771-46A5-B6B2-FD12BACE86BF} + hqx2gp + 10.0.17763.0 + + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + Application + true + v141 + MultiByte + + + Application + false + v141 + true + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Level3 + Disabled + true + true + + + + + Level3 + Disabled + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + Level3 + MaxSpeed + true + true + true + true + + + true + true + + + + + + + + {6ec62b0f-9353-40a4-a510-3788f1368b33} + + + + + + \ No newline at end of file diff --git a/hqx2gp/hqx2gp.vcxproj.filters b/hqx2gp/hqx2gp.vcxproj.filters new file mode 100644 index 0000000..721f55e --- /dev/null +++ b/hqx2gp/hqx2gp.vcxproj.filters @@ -0,0 +1,22 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Source Files + + + \ No newline at end of file diff --git a/hqx2gp/x64/Debug/vc141.idb b/hqx2gp/x64/Debug/vc141.idb new file mode 100644 index 0000000..ab5e992 Binary files /dev/null and b/hqx2gp/x64/Debug/vc141.idb differ diff --git a/notes.txt b/notes.txt new file mode 100644 index 0000000..b8c630f --- /dev/null +++ b/notes.txt @@ -0,0 +1,6 @@ +QuickDraw oval/rect drawing: + +https://www.folklore.org/StoryView.py?story=Round_Rects_Are_Everywhere.txt + +Bill's technique used the fact the sum of a sequence of odd numbers is always the next perfect square (For example, 1 + 3 = 4, 1 + 3 + 5 = 9, 1 + 3 + 5 + 7 = 16, etc). +So he could figure out when to bump the dependent coordinate value by iterating in a loop until a threshold was exceeded. This allowed QuickDraw to draw ovals very quickly.