diff --git a/CarbonLib b/CarbonLib new file mode 100755 index 0000000..c134d7a Binary files /dev/null and b/CarbonLib differ diff --git a/Glider PRO CW5.mcp b/Glider PRO CW5.mcp new file mode 100755 index 0000000..85e1daa Binary files /dev/null and b/Glider PRO CW5.mcp differ diff --git a/Glider PRO.mcp b/Glider PRO.mcp new file mode 100755 index 0000000..589be91 Binary files /dev/null and b/Glider PRO.mcp differ diff --git a/Glider PRO.rsrc b/Glider PRO.rsrc new file mode 100755 index 0000000..e69de29 diff --git a/Headers/About.h b/Headers/About.h new file mode 100755 index 0000000..1f8c23d --- /dev/null +++ b/Headers/About.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // About.h //---------------------------------------------------------------------------- //============================================================================ void DoAbout (void); \ No newline at end of file diff --git a/Headers/DialogUtils.h b/Headers/DialogUtils.h new file mode 100755 index 0000000..1a81109 --- /dev/null +++ b/Headers/DialogUtils.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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/DynamicMaps.h b/Headers/DynamicMaps.h new file mode 100755 index 0000000..d409392 --- /dev/null +++ b/Headers/DynamicMaps.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // DynamicMaps.h //---------------------------------------------------------------------------- //============================================================================ \ No newline at end of file diff --git a/Headers/Environ.h b/Headers/Environ.h new file mode 100755 index 0000000..1c972bc --- /dev/null +++ b/Headers/Environ.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..39b299f --- /dev/null +++ b/Headers/Externs.h @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..d90c6f9 --- /dev/null +++ b/Headers/GameOver.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..015e91d --- /dev/null +++ b/Headers/GliderDefines.h @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..af611a5 --- /dev/null +++ b/Headers/GliderProtos.h @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..1744a30 --- /dev/null +++ b/Headers/GliderStructs.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..4d4e19a --- /dev/null +++ b/Headers/GliderVars.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..fd64fed --- /dev/null +++ b/Headers/House.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..f932866 --- /dev/null +++ b/Headers/MainWindow.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // MainWindow.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr workSrcMap; \ No newline at end of file diff --git a/Headers/Map.h b/Headers/Map.h new file mode 100755 index 0000000..8e4e8bd --- /dev/null +++ b/Headers/Map.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..fb21eb2 --- /dev/null +++ b/Headers/Marquee.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..dfebe55 --- /dev/null +++ b/Headers/ObjectEdit.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..083b420 --- /dev/null +++ b/Headers/Objects.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..b863d2f --- /dev/null +++ b/Headers/Play.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..a78a38e --- /dev/null +++ b/Headers/Player.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..7ff4de5 --- /dev/null +++ b/Headers/RectUtils.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..434913e --- /dev/null +++ b/Headers/Room.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // Room.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr backSrcMap; \ No newline at end of file diff --git a/Headers/RoomGraphics.h b/Headers/RoomGraphics.h new file mode 100755 index 0000000..5538be1 --- /dev/null +++ b/Headers/RoomGraphics.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // RoomGraphics.h //---------------------------------------------------------------------------- //============================================================================ #include extern GWorldPtr suppSrcMap; \ No newline at end of file diff --git a/Headers/RubberBands.h b/Headers/RubberBands.h new file mode 100755 index 0000000..566ab20 --- /dev/null +++ b/Headers/RubberBands.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..9d989ea --- /dev/null +++ b/Headers/Scoreboard.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..ff80070 --- /dev/null +++ b/Headers/Tools.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..3f57af2 --- /dev/null +++ b/Headers/Utilities.h @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // Utilities.c //---------------------------------------------------------------------------- //============================================================================ #include OSErr CreateOffScreenGWorld (GWorldPtr *theGWorld, Rect *bounds, short depth); \ No newline at end of file diff --git a/Houses/Art Museum b/Houses/Art Museum new file mode 100755 index 0000000..d7e03cc Binary files /dev/null and b/Houses/Art Museum differ diff --git a/Houses/Art Museum.mov b/Houses/Art Museum.mov new file mode 100755 index 0000000..a4bd4a8 Binary files /dev/null and b/Houses/Art Museum.mov differ diff --git a/Houses/CD Demo House b/Houses/CD Demo House new file mode 100755 index 0000000..742ad6a Binary files /dev/null and b/Houses/CD Demo House differ diff --git a/Houses/CD Demo House.mov b/Houses/CD Demo House.mov new file mode 100755 index 0000000..8839406 Binary files /dev/null and b/Houses/CD Demo House.mov differ diff --git a/Houses/California or Bust! b/Houses/California or Bust! new file mode 100755 index 0000000..80a87c1 Binary files /dev/null and b/Houses/California or Bust! differ diff --git a/Houses/Castle o' the Air b/Houses/Castle o' the Air new file mode 100755 index 0000000..b528e95 Binary files /dev/null and b/Houses/Castle o' the Air differ diff --git a/Houses/Castle o' the Air.mov b/Houses/Castle o' the Air.mov new file mode 100755 index 0000000..3bc49c5 Binary files /dev/null and b/Houses/Castle o' the Air.mov differ diff --git a/Houses/Davis Station b/Houses/Davis Station new file mode 100755 index 0000000..996ba75 Binary files /dev/null and b/Houses/Davis Station differ diff --git a/Houses/Davis Station.mov b/Houses/Davis Station.mov new file mode 100755 index 0000000..0fd4115 Binary files /dev/null and b/Houses/Davis Station.mov differ diff --git a/Houses/Demo House b/Houses/Demo House new file mode 100755 index 0000000..53f1f91 Binary files /dev/null and b/Houses/Demo House differ diff --git a/Houses/Demo House.mov b/Houses/Demo House.mov new file mode 100755 index 0000000..e2fbd0e Binary files /dev/null and b/Houses/Demo House.mov differ diff --git a/Houses/Empty House b/Houses/Empty House new file mode 100755 index 0000000..3109989 Binary files /dev/null and b/Houses/Empty House differ diff --git a/Houses/Fun House b/Houses/Fun House new file mode 100755 index 0000000..7cdaa65 Binary files /dev/null and b/Houses/Fun House differ diff --git a/Houses/Grand Prix b/Houses/Grand Prix new file mode 100755 index 0000000..7ef1328 Binary files /dev/null and b/Houses/Grand Prix differ diff --git a/Houses/Grand Prix.mov b/Houses/Grand Prix.mov new file mode 100755 index 0000000..5fd19b1 Binary files /dev/null and b/Houses/Grand Prix.mov differ diff --git a/Houses/ImagineHouse PRO II b/Houses/ImagineHouse PRO II new file mode 100755 index 0000000..992c266 Binary files /dev/null and b/Houses/ImagineHouse PRO II differ diff --git a/Houses/ImagineHouse PRO II.mov b/Houses/ImagineHouse PRO II.mov new file mode 100755 index 0000000..9ba10f6 Binary files /dev/null and b/Houses/ImagineHouse PRO II.mov differ diff --git a/Houses/In The Mirror b/Houses/In The Mirror new file mode 100755 index 0000000..9ce0f87 Binary files /dev/null and b/Houses/In The Mirror differ diff --git a/Houses/Land of Illusion b/Houses/Land of Illusion new file mode 100755 index 0000000..751b199 Binary files /dev/null and b/Houses/Land of Illusion differ diff --git a/Houses/Land of Illusion.mov b/Houses/Land of Illusion.mov new file mode 100755 index 0000000..7c35d47 Binary files /dev/null and b/Houses/Land of Illusion.mov differ diff --git a/Houses/Leviathan b/Houses/Leviathan new file mode 100755 index 0000000..efadfe1 Binary files /dev/null and b/Houses/Leviathan differ diff --git a/Houses/Leviathan.mov b/Houses/Leviathan.mov new file mode 100755 index 0000000..3696a07 Binary files /dev/null and b/Houses/Leviathan.mov differ diff --git a/Houses/Metropolis b/Houses/Metropolis new file mode 100755 index 0000000..c07b589 Binary files /dev/null and b/Houses/Metropolis differ diff --git a/Houses/Nemo's Market b/Houses/Nemo's Market new file mode 100755 index 0000000..0be74e7 Binary files /dev/null and b/Houses/Nemo's Market differ diff --git a/Houses/Nemo's Market.mov b/Houses/Nemo's Market.mov new file mode 100755 index 0000000..3885765 Binary files /dev/null and b/Houses/Nemo's Market.mov differ diff --git a/Houses/Rainbow's End b/Houses/Rainbow's End new file mode 100755 index 0000000..c58fafc Binary files /dev/null and b/Houses/Rainbow's End differ diff --git a/Houses/Rainbow's End.mov b/Houses/Rainbow's End.mov new file mode 100755 index 0000000..68db5b2 Binary files /dev/null and b/Houses/Rainbow's End.mov differ diff --git a/Houses/Sampler b/Houses/Sampler new file mode 100755 index 0000000..a4400b9 Binary files /dev/null and b/Houses/Sampler differ diff --git a/Houses/Slumberland b/Houses/Slumberland new file mode 100755 index 0000000..98c824c Binary files /dev/null and b/Houses/Slumberland differ diff --git a/Houses/Slumberland.mov b/Houses/Slumberland.mov new file mode 100755 index 0000000..65f98f3 Binary files /dev/null and b/Houses/Slumberland.mov differ diff --git a/Houses/SpacePods b/Houses/SpacePods new file mode 100755 index 0000000..2b8d591 Binary files /dev/null and b/Houses/SpacePods differ diff --git a/Houses/SpacePods.mov b/Houses/SpacePods.mov new file mode 100755 index 0000000..e069d1b Binary files /dev/null and b/Houses/SpacePods.mov differ diff --git a/Houses/Teddy World b/Houses/Teddy World new file mode 100755 index 0000000..1b480c0 Binary files /dev/null and b/Houses/Teddy World differ diff --git a/Houses/Teddy World.mov b/Houses/Teddy World.mov new file mode 100755 index 0000000..238dd8a Binary files /dev/null and b/Houses/Teddy World.mov differ diff --git a/Houses/The Asylum Pro b/Houses/The Asylum Pro new file mode 100755 index 0000000..708f811 Binary files /dev/null and b/Houses/The Asylum Pro differ diff --git a/Houses/Titanic b/Houses/Titanic new file mode 100755 index 0000000..efcebe1 Binary files /dev/null and b/Houses/Titanic differ diff --git a/Houses/Titanic.mov b/Houses/Titanic.mov new file mode 100755 index 0000000..db4d283 Binary files /dev/null and b/Houses/Titanic.mov differ diff --git a/Prefix.h b/Prefix.h new file mode 100755 index 0000000..1db6eb0 --- /dev/null +++ b/Prefix.h @@ -0,0 +1 @@ +#define TARGET_CARBON 1 #define ACCESSOR_CALLS_ARE_FUNCTIONS 1 #define OPAQUE_TOOLBOX_STRUCTS 1 #define OPAQUE_UPP_TYPES 1 #define forCarbon 1 #define BUILDING_RUN_LINKED_IN 0 #define DEBUG 1 \ No newline at end of file diff --git a/Sources/About.c b/Sources/About.c new file mode 100755 index 0000000..37ea79e --- /dev/null +++ b/Sources/About.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..102d1b8 --- /dev/null +++ b/Sources/AnimCursor.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..44d3ec9 --- /dev/null +++ b/Sources/AppleEvents.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..730dd35 --- /dev/null +++ b/Sources/Banner.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..3b81c06 --- /dev/null +++ b/Sources/ColorUtils.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..6831426 --- /dev/null +++ b/Sources/Coordinates.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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/DebugUtilities.c b/Sources/DebugUtilities.c new file mode 100755 index 0000000..099ae3a --- /dev/null +++ b/Sources/DebugUtilities.c @@ -0,0 +1 @@ +/*============================================================*/ /*============================================================*/ /*== ==*/ /*== Debugging Utility Routines ==*/ /*== ==*/ /*============================================================*/ /*============================================================*/ #include #include "Externs.h" short barGraphHori = 0; //============================================================== Functions //-------------------------------------------------------------- MonitorWait void MonitorWait (void) { GrafPtr wasPort, tempPort; Rect tempRect; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); SetRect(&tempRect, 8, 28, 16, 36); InvertRect(&tempRect); ClosePort(tempPort); SetPort((GrafPtr)wasPort); } //-------------------------------------------------------------- DisplayRect void DisplayRect (Rect *theRect) { GrafPtr wasPort, tempPort; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); InvertRect(theRect); ClosePort(tempPort); SetPort((GrafPtr)wasPort); } //-------------------------------------------------------------- FlashRect void FlashRect (Rect *theRect) { GrafPtr wasPort, tempPort; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); InvertRect(theRect); InvertRect(theRect); InvertRect(theRect); InvertRect(theRect); ClosePort(tempPort); SetPort((GrafPtr)wasPort); } //-------------------------------------------------------------- CheckLegitRect void CheckLegitRect(Rect *srcRect, Rect *inRect) { Rect dummyRect; if ((srcRect->left > srcRect->right) || (srcRect->top > srcRect->bottom)) DebugStr("\pSource Rectangle not dimensional"); if (!SectRect(srcRect, inRect, &dummyRect)) DebugStr("\pSource Rectangle not Secting Target Rectangle"); } /*============================================================== DisplayLong */ void DisplayLong (long theValue) { GrafPtr wasPort, tempPort; Str255 tempStr; Rect tempRect; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); NumToString(theValue, tempStr); MoveTo(20,40); SetRect(&tempRect, 18, 20, 122, 42); EraseRect(&tempRect); DrawString(tempStr); while (Button()) { } while (!Button()) { } ClosePort(tempPort); SetPort((GrafPtr)wasPort); } /*============================================================== DisplayShort */ void DisplayShort(short theValue) { GrafPtr wasPort, tempPort; Str255 tempStr; Rect tempRect; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); NumToString((long)theValue, tempStr); MoveTo(20,40); SetRect(&tempRect, 18, 20, 122, 42); EraseRect(&tempRect); DrawString(tempStr); while (Button()) { } while (!Button()) { } ClosePort(tempPort); SetPort((GrafPtr)wasPort); } /*============================================================== FlashLong */ void FlashLong(long theValue) { GrafPtr wasPort, tempPort; Str255 tempStr; Rect tempRect; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); NumToString(theValue, tempStr); MoveTo(20,40); SetRect(&tempRect, 18, 20, 122, 42); EraseRect(&tempRect); DrawString(tempStr); ClosePort(tempPort); SetPort((GrafPtr)wasPort); } /*============================================================== FlashShort */ void FlashShort (short theValue) { GrafPtr wasPort, tempPort; Str255 tempStr; Rect tempRect; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); NumToString((long)theValue, tempStr); MoveTo(20,40); SetRect(&tempRect, 18, 20, 122, 42); EraseRect(&tempRect); DrawString(tempStr); ClosePort(tempPort); SetPort((GrafPtr)wasPort); } /*============================================================== DoBarGraph */ void DoBarGraph (short theValue, short downScreen, short maxDown, short scaleIt) { GrafPtr wasPort, tempPort; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); theValue *= scaleIt; PenPat(&qd.white); MoveTo(barGraphHori, 0); Line(0, maxDown); MoveTo(barGraphHori, downScreen); PenPat(&qd.black); if (theValue == 0) { theValue = 1; ForeColor(greenColor); } else if (theValue < 0) { if (theValue < -downScreen) { theValue = -downScreen; ForeColor(magentaColor); } else ForeColor(redColor); } else { if (theValue > downScreen) { ForeColor(cyanColor); theValue = downScreen; } else ForeColor(blueColor); } Line(0, -theValue); ForeColor(blackColor); barGraphHori++; if (barGraphHori >= 512) barGraphHori = 0; ClosePort(tempPort); SetPort((GrafPtr)wasPort); } /*============================================================== BetaOkay */ short BetaOkay (void) { DateTimeRec dateRecord; UInt32 theseSeconds; Boolean stillCool; GetDateTime(&theseSeconds); SecondsToDate(theseSeconds, &dateRecord); if (dateRecord.month < 8) stillCool = true; else stillCool = false; return((short)stillCool); } //-------------------------------------------------------------- DebugNum void DebugNum (long theNum) { Str255 theStr; NumToString(theNum, theStr); DebugStr(theStr); } //-------------------------------------------------------------- DisplayCTSeed void DisplayCTSeed (CGrafPtr who) { long theSeed; theSeed = (**((**(who->portPixMap)).pmTable)).ctSeed; DisplayLong(theSeed); } //-------------------------------------------------------------- FillScreenRed void FillScreenRed (void) { GrafPtr wasPort, tempPort; GetPort(&wasPort); tempPort = (GrafPtr)NewPtrClear(sizeof(GrafPort)); OpenPort(tempPort); PenNormal(); ForeColor(redColor); PaintRect(&qd.screenBits.bounds); ClosePort(tempPort); SetPort((GrafPtr)wasPort); } //-------------------------------------------------------------- DumpToResEditFile void DumpToResEditFile (Ptr data, long dataSize) { DateTimeRec timeRec; Str32 filesName, dateStr; Handle newResource; UInt32 dateTime; long tempLong; OSErr theErr; short iFileRef; PasStringCopy("\pTerrain ", filesName); GetDateTime(&dateTime); SecondsToDate(dateTime, &timeRec); tempLong = (long)timeRec.hour; NumToString(tempLong, dateStr); PasStringConcat(filesName, dateStr); PasStringConcat(filesName, "\p-"); tempLong = (long)timeRec.minute; NumToString(tempLong, dateStr); PasStringConcat(filesName, dateStr); theErr = Create(filesName, 0, 'RSED', 'rsrc'); if (theErr != noErr) DebugStr("\p Create"); CreateResFile(filesName); if (ResError() != noErr) DebugStr("\p CreateResFile"); iFileRef = OpenResFile(filesName); if ((ResError() != noErr) || (iFileRef == -1)) DebugStr("\p OpenResFile"); if (PtrToHand(data, &newResource, dataSize) != noErr) DebugStr("\pPtrToHand"); AddResource(newResource, 'demo', 128, "\p"); ChangedResource(newResource); } \ No newline at end of file diff --git a/Sources/DialogUtils.c b/Sources/DialogUtils.c new file mode 100755 index 0000000..eae9cf3 --- /dev/null +++ b/Sources/DialogUtils.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..390cf49 --- /dev/null +++ b/Sources/DynamicMaps.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..37ed103 --- /dev/null +++ b/Sources/Dynamics.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..0300e7d --- /dev/null +++ b/Sources/Dynamics2.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..10c50d0 --- /dev/null +++ b/Sources/Dynamics3.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..a1143ba --- /dev/null +++ b/Sources/Environ.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..cf449dc --- /dev/null +++ b/Sources/Events.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..bb68187 --- /dev/null +++ b/Sources/FileError.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..706c884 --- /dev/null +++ b/Sources/GameOver.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..a734cca --- /dev/null +++ b/Sources/Grease.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..27cdab0 --- /dev/null +++ b/Sources/HighScores.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..cfd8641 --- /dev/null +++ b/Sources/House.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..46517c2 --- /dev/null +++ b/Sources/HouseIO.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..da7bb14 --- /dev/null +++ b/Sources/HouseInfo.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..2e50a8d --- /dev/null +++ b/Sources/HouseLegal.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..5637c2b --- /dev/null +++ b/Sources/Input.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..a8f1a65 --- /dev/null +++ b/Sources/Interactions.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..13bd6bf --- /dev/null +++ b/Sources/InterfaceInit.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..de0d209 --- /dev/null +++ b/Sources/Link.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..c41f189 --- /dev/null +++ b/Sources/Main.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..8f2829f --- /dev/null +++ b/Sources/MainWindow.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..bb302ac --- /dev/null +++ b/Sources/Map.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..53a9712 --- /dev/null +++ b/Sources/Marquee.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..5b77619 --- /dev/null +++ b/Sources/Menu.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..df9a0e8 --- /dev/null +++ b/Sources/Modes.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..da849f3 --- /dev/null +++ b/Sources/Music.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..8c0c8a1 --- /dev/null +++ b/Sources/ObjectAdd.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..e8789ba --- /dev/null +++ b/Sources/ObjectDraw.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..984f542 --- /dev/null +++ b/Sources/ObjectDraw2.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..ba65461 --- /dev/null +++ b/Sources/ObjectDrawAll.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..62d2930 --- /dev/null +++ b/Sources/ObjectEdit.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..f080b59 --- /dev/null +++ b/Sources/ObjectInfo.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..1ada2f5 --- /dev/null +++ b/Sources/ObjectRects.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..1e3b86c --- /dev/null +++ b/Sources/Objects.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..12c3154 --- /dev/null +++ b/Sources/Play.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..f36208a --- /dev/null +++ b/Sources/Player.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..1a544b0 --- /dev/null +++ b/Sources/Prefs.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..0a01c0f --- /dev/null +++ b/Sources/RectUtils.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..422c0e1 --- /dev/null +++ b/Sources/Render.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..4248936 --- /dev/null +++ b/Sources/Room.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..e1de36b --- /dev/null +++ b/Sources/RoomGraphics.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..ee736de --- /dev/null +++ b/Sources/RoomInfo.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..657f6ba --- /dev/null +++ b/Sources/RubberBands.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..cd9f08c --- /dev/null +++ b/Sources/SavedGames.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..85db244 --- /dev/null +++ b/Sources/Scoreboard.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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/Scrap.c b/Sources/Scrap.c new file mode 100755 index 0000000..2d9fc26 --- /dev/null +++ b/Sources/Scrap.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // Scrap.c //---------------------------------------------------------------------------- //============================================================================ /* #include "Externs.h" #include "Environ.h" #include Boolean DropLocationIsTrash (AEDesc *); Boolean hasScrap, scrapIsARoom; extern WindowPtr mapWindow; extern Rect roomObjectRects[]; extern short objActive; //============================================================== Functions //-------------------------------------------------------------- PutRoomScrap #ifndef COMPILEDEMO void PutRoomScrap (void) { // this function copies the current room into the clipboard Rect largeBounds, smallBounds; PicHandle smallPict; long theErr; theErr = ZeroScrap(); if (theErr == noErr) { SetRect(&largeBounds, 0, 0, kRoomWide, kTileHigh); SetRect(&smallBounds, 0, 0, kRoomWide / 4, kTileHigh / 4); smallPict = OpenPicture(&smallBounds); CopyBits(&(((GrafPtr)mainWindow)->portBits), &(((GrafPtr)mainWindow)->portBits), &largeBounds, &smallBounds, srcCopy, nil); ClosePicture(); HLock((Handle)smallPict); theErr = PutScrap(GetHandleSize((Handle)smallPict), 'PICT', (Ptr)(*smallPict)); theErr = PutScrap(sizeof(roomType), 'Room', (Ptr)thisRoom); if (theErr == noErr) { if (!hasScrap) { hasScrap = true; UpdateMenus(false); } scrapIsARoom = true; } else YellowAlert(kYellowScrapError, theErr); KillPicture(smallPict); } else YellowAlert(kYellowScrapError, theErr); } #endif //-------------------------------------------------------------- PutObjectScrap #ifndef COMPILEDEMO void PutObjectScrap (void) { // this function copies the currently selected object into the clipboard Str255 kindStr; objectPtr scrapObjPtr; long theErr; theErr = ZeroScrap(); if (theErr == noErr) { GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); theErr = PutScrap(kindStr[0], 'TEXT', (Ptr)(kindStr + 1)); scrapObjPtr = &(thisRoom->objects[objActive]); theErr = PutScrap(sizeof(objectType), 'Obj.', (Ptr)scrapObjPtr); if (theErr == noErr) { if (!hasScrap) { hasScrap = true; UpdateMenus(false); } scrapIsARoom = false; } else YellowAlert(kYellowScrapError, theErr); } else YellowAlert(kYellowScrapError, theErr); } #endif //-------------------------------------------------------------- GetRoomScrap #ifndef COMPILEDEMO void GetRoomScrap (void) { // this function pastes a room from the clipboard Handle tempRoom; long theErr, scrapOffset; short wasFloor, wasSuite, srcRoomNumber, destRoomNumber, i; short linkRoomNumber; tempRoom = NewHandle(0L); if (tempRoom == nil) { YellowAlert(kYellowNoMemory, 0); return; } theErr = GetScrap(tempRoom, 'Room', &scrapOffset); if (theErr < 0) YellowAlert(kYellowScrapError, theErr); else { DeselectObject(); wasFloor = thisRoom->floor; wasSuite = thisRoom->suite; destRoomNumber = GetRoomNumber(thisRoom->floor, thisRoom->suite); HLock(tempRoom); BlockMove(*tempRoom, (Ptr)thisRoom, sizeof(roomType)); HUnlock(tempRoom); DisposeHandle(tempRoom); srcRoomNumber = GetRoomNumber(thisRoom->floor, thisRoom->suite); thisRoom->floor = wasFloor; thisRoom->suite = wasSuite; for (i = 0; i < kMaxRoomObs; i++) // fix links { // first see if a linkable object if ((ObjectIsLinkTransport(&thisRoom->objects[i])) || (ObjectIsLinkSwitch(&thisRoom->objects[i]))) { linkRoomNumber = GetRoomLinked (&thisRoom->objects[i]); if (linkRoomNumber == srcRoomNumber) { // if linked to an object in same roomÉ if (ObjectIsLinkSwitch(&thisRoom->objects[i])) { // point to new room location thisRoom->objects[i].data.d.where = (wasSuite * 100) + wasFloor + kNumUndergroundFloors; } else { // point to new room location thisRoom->objects[i].data.e.where = (wasSuite * 100) + wasFloor + kNumUndergroundFloors; } } } } CopyThisRoomToRoom(); ReflectCurrentRoom(false); fileDirty = true; UpdateMenus(false); } } #endif //-------------------------------------------------------------- GetObjectScrap #ifndef COMPILEDEMO void GetObjectScrap (void) { // this function pastes an object from the clipboard objectType tempObject; Handle tempObjectHand; Point noPoint; long theErr, scrapOffset; short direction, dist; tempObjectHand = NewHandle(0L); if (tempObjectHand == nil) { YellowAlert(kYellowNoMemory, 0); return; } theErr = GetScrap(tempObjectHand, 'Obj.', &scrapOffset); if (theErr < 0) YellowAlert(kYellowScrapError, theErr); else { DeselectObject(); HLock(tempObjectHand); noPoint.h = 100; noPoint.v = 100; BlockMove(*tempObjectHand, (Ptr)(&tempObject), sizeof(objectType)); if (AddNewObject(noPoint, tempObject.what, false)) { thisRoom->objects[objActive] = tempObject; ReadyBackground(thisRoom->background, thisRoom->tiles); GetThisRoomsObjRects(); DrawThisRoomsObjects(); SetPort((GrafPtr)mainWindow); InvalRect(&mainWindowRect); if (ObjectHasHandle(&direction, &dist)) { StartMarqueeHandled(&roomObjectRects[objActive], direction, dist); HandleBlowerGlider(); } else StartMarquee(&roomObjectRects[objActive]); } HUnlock(tempObjectHand); DisposeHandle(tempObjectHand); } } #endif //-------------------------------------------------------------- SeeIfValidScrapAvailable #ifndef COMPILEDEMO void SeeIfValidScrapAvailable (Boolean updateMenus) { Handle tempRoom, tempObject; long theErr, scrapOffset; hasScrap = false; tempRoom = NewHandle(0L); if (tempRoom != nil) { theErr = GetScrap(tempRoom, 'Room', &scrapOffset); if (theErr >= 0) { hasScrap = true; scrapIsARoom = true; } DisposeHandle(tempRoom); } tempObject = NewHandle(0L); if (tempObject != nil) { theErr = GetScrap(tempObject, 'Obj.', &scrapOffset); if (theErr >= 0) { hasScrap = true; scrapIsARoom = false; } DisposeHandle(tempObject); } if (updateMenus) UpdateClipboardMenus(); } #endif //-------------------------------------------------------------- DropLocationIsTrash Boolean DropLocationIsTrash (AEDesc *dropLocation) { AEDesc dropSpec; FSSpec *theSpec; CInfoPBRec thePB; long trashDirID; OSErr theErr; short trashVRefNum; if ((dropLocation->descriptorType != typeNull) && (AECoerceDesc(dropLocation, typeFSS, &dropSpec) == noErr)) { HLock(dropSpec.dataHandle); theSpec = (FSSpec *) *dropSpec.dataHandle; thePB.dirInfo.ioCompletion = 0L; thePB.dirInfo.ioNamePtr = (StringPtr) &theSpec->name; thePB.dirInfo.ioVRefNum = theSpec->vRefNum; thePB.dirInfo.ioFDirIndex = 0; thePB.dirInfo.ioDrDirID = theSpec->parID; theErr = PBGetCatInfo(&thePB, false); HUnlock(dropSpec.dataHandle); AEDisposeDesc(&dropSpec); if (theErr != noErr) return(false); if (!(thePB.dirInfo.ioFlAttrib & (1 << 4))) return(false); FindFolder(theSpec->vRefNum, kTrashFolderType, kCreateFolder, &trashVRefNum, &trashDirID); if (thePB.dirInfo.ioDrDirID == trashDirID) return(true); } return(false); } //-------------------------------------------------------------- DragTrackingFunc #if 0 pascal OSErr DragTrackingFunc (DragTrackingMessage theMessage, WindowPtr theWindow, void *theRefCon, DragReference theDrag) { DragAttributes attributes; OSErr theErr; theErr = noErr; GetDragAttributes(theDrag, &attributes); switch (theMessage) { case dragTrackingEnterWindow: xxx; break; case dragTrackingInWindow: xxx; break; case dragTrackingLeaveWindow: xxx; break; } return (theErr); } #endif //-------------------------------------------------------------- DragRoom Boolean DragRoom (EventRecord *theEvent, Rect *roomSrc, short roomNumber) { DragReference theDrag; DragAttributes attributes; AEDesc dropLocation; Rect largeBounds, smallBounds; PicHandle smallPict; roomType *theRoom; RgnHandle boundsRgn, tempRgn; // Point dragPoint; OSErr theErr; short mouseDnMods, mouseUpMods, copyRoom; char wasState; if (thisMac.hasDrag) { if (!WaitMouseMoved(theEvent->where)) return(false); SetPort((GrafPtr)mainWindow); BeginUpdate((GrafPtr)mainWindow); UpdateMainWindow(); EndUpdate((GrafPtr)mainWindow); theErr = NewDrag(&theDrag); if (theErr != noErr) return (false); wasState = HGetState((Handle)thisHouse); HLock((Handle)thisHouse); theRoom = &((*thisHouse)->rooms[roomNumber]); theErr = AddDragItemFlavor(theDrag, (ItemReference)roomNumber, (FlavorType)'Room', (Ptr)theRoom, sizeof(roomType), (FlavorFlags)0); if (theErr != noErr) { HSetState((Handle)thisHouse, wasState); DisposeDrag(theDrag); return (false); } SetRect(&largeBounds, 0, 0, kRoomWide, kTileHigh); SetRect(&smallBounds, 0, 0, kRoomWide / 4, kTileHigh / 4); smallPict = OpenPicture(&smallBounds); CopyBits(&(((GrafPtr)mainWindow)->portBits), &(((GrafPtr)mainWindow)->portBits), &largeBounds, &smallBounds, srcCopy, nil); ClosePicture(); HLock((Handle)smallPict); theErr = AddDragItemFlavor(theDrag, (ItemReference)roomNumber, (FlavorType)'PICT', (Ptr)(*smallPict), GetHandleSize((Handle)smallPict), (FlavorFlags)0); HUnlock((Handle)smallPict); KillPicture(smallPict); HSetState((Handle)thisHouse, wasState); if (theErr != noErr) { DisposeDrag(theDrag); return (false); } theErr = SetDragItemBounds(theDrag, (ItemReference)roomNumber, roomSrc); if (theErr != noErr) { DisposeDrag(theDrag); return (false); } boundsRgn = NewRgn(); RectRgn(boundsRgn, roomSrc); tempRgn = NewRgn(); CopyRgn(boundsRgn, tempRgn); InsetRgn(tempRgn, 1, 1); DiffRgn(boundsRgn, tempRgn, boundsRgn); DisposeRgn(tempRgn); theErr = TrackDrag(theDrag, theEvent, boundsRgn); if ((theErr != noErr) && (theErr != userCanceledErr)) { DisposeRgn(boundsRgn); DisposeDrag(theDrag); return(true); } theErr = GetDragAttributes(theDrag, &attributes); if (theErr != noErr) { DisposeRgn(boundsRgn); DisposeDrag(theDrag); return(true); } theErr = GetDropLocation(theDrag, &dropLocation); if (theErr != noErr) { DisposeRgn(boundsRgn); DisposeDrag(theDrag); return(true); } theErr = GetDragModifiers(theDrag, 0L, &mouseDnMods, &mouseUpMods); if (theErr != noErr) { DisposeRgn(boundsRgn); DisposeDrag(theDrag); return(true); } copyRoom = (mouseDnMods | mouseUpMods) & optionKey; if (!(attributes & kDragInsideSenderApplication)) { if ((!copyRoom) && (DropLocationIsTrash(&dropLocation))) { DeselectObject(); DeleteRoom(true); } } else if (attributes & kDragInsideSenderWindow) { // SetPort(mapWindow); // GetDragMouse(theDrag, &dragPoint, 0L); // GlobalToLocal(&dragPoint); // MoveRoom(dragPoint); } DisposeRgn(boundsRgn); DisposeDrag(theDrag); } return (true); } //-------------------------------------------------------------- InitDragInfo #if 0 OSErr InitDragInfo (DragInfoHandle dragInfo) { OSErr theErr; DragTrackingHandlerUPP trackingProc; DragReceiveHandlerUPP receiveProc; if (!HasDragManager()) return (noErr); trackingProc = NewDragTrackingHandlerProc(DragTrackingFunc); (**dragInfo).dragTrackingProc = trackingProc; theErr = InstallTrackingHandler(trackingProc, mapWindow, dragInfo); if (theErr != noErr) return (theErr); receiveProc = NewDragReceiveHandlerProc(DragReceiveFunc); (**dragInfo).dragReceiveProc = receiveProc; theErr = InstallReceiveHandler(receiveProc, (**dragInfo).window, dragInfo); return err; } #endif //-------------------------------------------------------------- KillDragInfo #if 0 void KillDragInfo (DragInfoHandle dragInfo) { OSErr theErr; if (!HasDragManager()) return (noErr); theErr = RemoveTrackingHandler((**dragInfo).dragTrackingProc, (**dragInfo).window); theErr = RemoveReceiveHandler((**dragInfo).dragReceiveProc, (**dragInfo).window); } #endif */ \ No newline at end of file diff --git a/Sources/SelectHouse.c b/Sources/SelectHouse.c new file mode 100755 index 0000000..e829e21 --- /dev/null +++ b/Sources/SelectHouse.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..aefbe11 --- /dev/null +++ b/Sources/Settings.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..6861749 --- /dev/null +++ b/Sources/Sound.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..9f317f2 --- /dev/null +++ b/Sources/StringUtils.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..9153acf --- /dev/null +++ b/Sources/StructuresInit.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..1999b39 --- /dev/null +++ b/Sources/StructuresInit2.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..b8c281e --- /dev/null +++ b/Sources/Tools.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..627c6ab --- /dev/null +++ b/Sources/Transit.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..86ccef8 --- /dev/null +++ b/Sources/Transitions.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..7e742e2 --- /dev/null +++ b/Sources/Triggers.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..18b5031 --- /dev/null +++ b/Sources/Trip.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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 new file mode 100755 index 0000000..533cb5f --- /dev/null +++ b/Sources/Utilities.c @@ -0,0 +1 @@ +//============================================================================ //---------------------------------------------------------------------------- // 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/Validate.c b/Sources/Validate.c new file mode 100755 index 0000000..2d6b829 --- /dev/null +++ b/Sources/Validate.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // Validate.c //---------------------------------------------------------------------------- //============================================================================ #include "Externs.h" #include #ifndef COMPILEDEMO #define kEncryptMask 0x05218947 #define kLegalVolumeCreation 0xAA2D3E41 #define kMasterDialogID 1026 #define kMasterFinderButton 1 #define kMasterNetOnlyButton 2 #define kMasterUserBalloon 3 #define kMasterTitleLeft 6 #define kMasterTitleTop 16 short GetSystemVolume (void); long VolumeCreated (void); Boolean VolumeMatchesPrefs (long, long *); Boolean NoFloppyException (void); OSErr GetIndVolumeDate (short, long *); Boolean LoopThruMountedVolumes (void); Boolean SpecificVolumeCreated (void); pascal Boolean MasterFilter (DialogPtr, EventRecord *, short *); Boolean GetMasterDisk (void); long encryptedNumber; short theSystemVol; Boolean legitMasterDisk, bailOut, didValidation; /* //============================================================== Functions //-------------------------------------------------------------- GetSystemVolume // Finds a hard volume reference number for the volume the System folderÉ // resides on. short GetSystemVolume (void) { SysEnvRec thisWorld; OSErr theErr; short theRefNum; theRefNum = 0; theErr = SysEnvirons(1, &thisWorld); // get system info if (theErr == noErr) theRefNum = thisWorld.sysVRefNum; return(theRefNum); } //-------------------------------------------------------------- VolumeCreated // Returns the creation date (date formatted) of the volume the System is on. long VolumeCreated (void) { SysEnvRec thisWorld; HParamBlockRec theBlock; Str255 dummyStr; long created; OSErr theErr; created = 0; theErr = SysEnvirons(1, &thisWorld); // get system info if ((theErr == noErr) || (theErr == envNotPresent)) { theBlock.volumeParam.ioVolIndex = 0; // set up paramBlock theBlock.volumeParam.ioNamePtr = dummyStr; theBlock.volumeParam.ioVRefNum = thisWorld.sysVRefNum; theBlock.volumeParam.ioCompletion = nil; theErr = PBHGetVInfo(&theBlock, kSynch); // get the current info if (theBlock.volumeParam.ioResult == noErr) created = theBlock.volumeParam.ioVCrDate; } return (created); } //-------------------------------------------------------------- VolumeMatchesPrefs // Uses an "encryption mask" on the volume creation date and comparesÉ // it with a value stored in the games prefs. Returns whether or notÉ // we have a match. Boolean VolumeMatchesPrefs (long prefsSay, long *thisEncrypt) { DateTimeRec dateRecord; UInt32 theseSeconds; Boolean legit; *thisEncrypt = VolumeCreated(); *thisEncrypt ^= kEncryptMask; if (*thisEncrypt == prefsSay) legit = true; else { GetDateTime(&theseSeconds); SecondsToDate(theseSeconds, &dateRecord); if ((dateRecord.month == 6) && (dateRecord.day == 22) && (dateRecord.year == 1966)) legit = true; else legit = false; } return (legit); } //-------------------------------------------------------------- NoFloppyException // Some machines may not have floppy drives on them at all. This functionÉ // determines if this is one of those "special cases". Boolean NoFloppyException (void) { long response; OSErr theErr; Boolean isFloppyless; isFloppyless = false; theErr = Gestalt(gestaltMachineType, &response); if (theErr == noErr) { if ((response == gestaltPowerBook100) || (response == 27)) // Duo's too isFloppyless = true; } return (isFloppyless); } //-------------------------------------------------------------- GetIndVolumeDate OSErr GetIndVolumeDate (short volIndex, long *theDate) { HParamBlockRec theBlock; Str255 namePtr; OSErr theErr; theBlock.volumeParam.ioVolIndex = volIndex; // set up param block theBlock.volumeParam.ioNamePtr = namePtr; theBlock.volumeParam.ioVRefNum = 0; theBlock.volumeParam.ioCompletion = nil; theErr = PBHGetVInfo(&theBlock, kSynch); // get the nitty if (theErr == noErr) *theDate = theBlock.volumeParam.ioVCrDate; // get volume created return (theErr); } //-------------------------------------------------------------- LoopThruMountedVolumes Boolean LoopThruMountedVolumes (void) { long theDate; OSErr theErr; short i; Boolean foundIt; foundIt = false; i = 0; do { theErr = GetIndVolumeDate(i, &theDate); if (theDate == kLegalVolumeCreation) foundIt = true; i++; } while ((theErr != nsvErr) && (!foundIt)); return (foundIt); } //-------------------------------------------------------------- SpecificVolumeCreated // This function looks at floppy disks inserted and reads the creationÉ // date off. It is looking for a specific creation date. Boolean SpecificVolumeCreated (void) { Str255 namePtr; HParamBlockRec theBlock; OSErr theErr; short vRefNum; long spaceHas, theDate, tempLong; Boolean dummyBool; theDate = 0; theErr = GetVInfo(1, namePtr, &vRefNum, &spaceHas); // try drive 1 if (theErr == nsvErr) theErr = GetVInfo(2, namePtr, &vRefNum, &spaceHas); // no volume? try 2 if (theErr == noErr) { theBlock.volumeParam.ioVolIndex = 0; // set up param block theBlock.volumeParam.ioNamePtr = namePtr; theBlock.volumeParam.ioVRefNum = vRefNum; theBlock.volumeParam.ioCompletion = nil; theErr = PBHGetVInfo(&theBlock, kSynch); // get the nitty if (theBlock.volumeParam.ioResult == noErr) theDate = theBlock.volumeParam.ioVCrDate; // get volume created } else if (theErr != nsvErr) { dummyBool = CheckFileError(theErr, "\pValidation"); RedAlert(kErrFailedValidation); } else { theBlock.volumeParam.ioVolIndex = 0; // set up param block theBlock.volumeParam.ioNamePtr = namePtr; theBlock.volumeParam.ioVRefNum = vRefNum; theBlock.volumeParam.ioCompletion = nil; theErr = PBHGetVInfo(&theBlock, kSynch); // get the nitty if (theBlock.volumeParam.ioResult == noErr) theDate = theBlock.volumeParam.ioVCrDate; // get volume created } tempLong = theDate; return (theDate == kLegalVolumeCreation); } //-------------------------------------------------------------- MasterFilter // Dialog filter for the function that follows this one. It handlesÉ // disk inserts and ejects disks that don't match in the previous function. pascal Boolean MasterFilter (DialogPtr theDialog, EventRecord *theEvent, short *itemHit) { #pragma unused (theDialog, theEvent, itemHit) EventRecord diskEvent; Str255 wasName; long freeBytes; OSErr theErr; short volRefNum; Boolean handledIt, dummyBool; theErr = GetVInfo(1, (StringPtr)&wasName, &volRefNum, &freeBytes); if (theErr == nsvErr) theErr = GetVInfo(2, (StringPtr)&wasName, &volRefNum, &freeBytes); if (theErr == noErr) { theErr = Eject((StringPtr)&wasName, volRefNum); if (theErr != noErr) { dummyBool = CheckFileError(theErr, "\pValidation"); RedAlert(kErrFailedValidation); } if (volRefNum != theSystemVol) { theErr = UnmountVol((StringPtr)&wasName, volRefNum); if ((theErr != noErr) && (theErr != fBsyErr)) { dummyBool = CheckFileError(theErr, "\pValidation"); RedAlert(kErrFailedValidation); } } } else if (theErr != nsvErr) { dummyBool = CheckFileError(theErr, "\pValidation"); RedAlert(kErrFailedValidation); } handledIt = false; if (GetNextEvent(diskMask, &diskEvent)) { // legitMasterDisk = SpecificVolumeCreated(); legitMasterDisk = LoopThruMountedVolumes(); if (legitMasterDisk) { theErr = GetVInfo(1, (StringPtr)&wasName, &volRefNum, &freeBytes); if (theErr == nsvErr) theErr = GetVInfo(2, (StringPtr)&wasName, &volRefNum, &freeBytes); if (theErr == noErr) { theErr = Eject((StringPtr)&wasName, volRefNum); if (theErr != noErr) { dummyBool = CheckFileError(theErr, "\pValidation"); RedAlert(kErrFailedValidation); } if (volRefNum != theSystemVol) { theErr = UnmountVol((StringPtr)&wasName, volRefNum); if ((theErr != noErr) && (theErr != fBsyErr)) { dummyBool = CheckFileError(theErr, "\pValidation"); RedAlert(kErrFailedValidation); } } } else if (theErr != nsvErr) { dummyBool = CheckFileError(theErr, "\pValidation"); RedAlert(kErrFailedValidation); } } handledIt = true; } return (handledIt); } //-------------------------------------------------------------- GetMasterDisk // Brings up a dialog asking the user to insert their "master disk" orÉ // quit. It returns true if disk verification succeeded. Boolean GetMasterDisk (void) { DialogPtr masterDialog; short itemHit; Boolean done; ModalFilterUPP masterFilterUPP; masterFilterUPP = NewModalFilterUPP(MasterFilter); InitCursor(); CenterDialog(kMasterDialogID); masterDialog = GetNewDialog(kMasterDialogID, nil, kPutInFront); if (masterDialog == nil) RedAlert(kErrDialogDidntLoad); SetPort((GrafPtr)masterDialog); ShowWindow(GetDialogWindow(masterDialog)); legitMasterDisk = false; done = false; bailOut = false; while ((!done) && (!legitMasterDisk)) { ModalDialog(masterFilterUPP, &itemHit); if (itemHit == kMasterFinderButton) { bailOut = true; legitMasterDisk = false; done = true; } } DisposeDialog(masterDialog); DisposeModalFilterUPP(masterFilterUPP); if (legitMasterDisk) didValidation = true; return (legitMasterDisk); } */ //-------------------------------------------------------------- ValidInstallation // "Master function" tha calls all the above. It coordinates a keyÉ // disk copy protection scheme. Boolean ValidInstallation (Boolean returnToFinder) { #pragma unused (returnToFinder) return true; /* long actualEncrypted; Boolean isValid; theSystemVol = GetSystemVolume(); isValid = VolumeMatchesPrefs(encryptedNumber, &actualEncrypted); if (!isValid) isValid = NoFloppyException(); if (!isValid) isValid = LoopThruMountedVolumes(); // isValid = SpecificVolumeCreated(); if (!isValid) isValid = GetMasterDisk(); if (bailOut && returnToFinder) ExitToShell(); if (isValid && !bailOut) encryptedNumber = actualEncrypted; return (isValid); */ } #endif \ No newline at end of file diff --git a/Sources/WindowUtils.c b/Sources/WindowUtils.c new file mode 100755 index 0000000..c0d1d72 --- /dev/null +++ b/Sources/WindowUtils.c @@ -0,0 +1 @@ + //============================================================================ //---------------------------------------------------------------------------- // 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