From 7a70d18ba68affc7508910e05e227181d7304e7b Mon Sep 17 00:00:00 2001 From: John Calhoun Date: Thu, 28 Jan 2016 08:10:38 -0800 Subject: [PATCH] First check-in. Sources for Glider PRO, a Macintosh game written by John Calhoun and published by Casady & Greene, Inc. I believe it was using CodeWarrior IDE to create a fat (68K and PowerPC) binary. --- CarbonLib | Bin 0 -> 234308 bytes Glider PRO CW5.mcp | Bin 0 -> 171219 bytes Glider PRO.mcp | Bin 0 -> 201821 bytes Glider PRO.rsrc | 0 Headers/About.h | 1 + Headers/DialogUtils.h | 1 + Headers/DynamicMaps.h | 1 + Headers/Environ.h | 1 + Headers/Externs.h | 1 + Headers/GameOver.h | 1 + Headers/GliderDefines.h | 1 + Headers/GliderProtos.h | 1 + Headers/GliderStructs.h | 1 + Headers/GliderVars.h | 1 + Headers/House.h | 1 + Headers/MainWindow.h | 1 + Headers/Map.h | 1 + Headers/Marquee.h | 1 + Headers/ObjectEdit.h | 1 + Headers/Objects.h | 1 + Headers/Play.h | 1 + Headers/Player.h | 1 + Headers/RectUtils.h | 1 + Headers/Room.h | 1 + Headers/RoomGraphics.h | 1 + Headers/RubberBands.h | 1 + Headers/Scoreboard.h | 1 + Headers/Tools.h | 1 + Headers/Utilities.h | 1 + Houses/Art Museum | Bin 0 -> 38798 bytes Houses/Art Museum.mov | Bin 0 -> 28232 bytes Houses/CD Demo House | Bin 0 -> 72554 bytes Houses/CD Demo House.mov | Bin 0 -> 33042 bytes Houses/California or Bust! | Bin 0 -> 6434 bytes Houses/Castle o' the Air | Bin 0 -> 30446 bytes Houses/Castle o' the Air.mov | Bin 0 -> 21960 bytes Houses/Davis Station | Bin 0 -> 23486 bytes Houses/Davis Station.mov | Bin 0 -> 34504 bytes Houses/Demo House | Bin 0 -> 16526 bytes Houses/Demo House.mov | Bin 0 -> 119789 bytes Houses/Empty House | Bin 0 -> 13046 bytes Houses/Fun House | Bin 0 -> 15830 bytes Houses/Grand Prix | Bin 0 -> 61766 bytes Houses/Grand Prix.mov | Bin 0 -> 26407 bytes Houses/ImagineHouse PRO II | Bin 0 -> 97958 bytes Houses/ImagineHouse PRO II.mov | Bin 0 -> 30707 bytes Houses/In The Mirror | Bin 0 -> 34622 bytes Houses/Land of Illusion | Bin 0 -> 106310 bytes Houses/Land of Illusion.mov | Bin 0 -> 16016 bytes Houses/Leviathan | Bin 0 -> 165122 bytes Houses/Leviathan.mov | Bin 0 -> 65920 bytes Houses/Metropolis | Bin 0 -> 45062 bytes Houses/Nemo's Market | Bin 0 -> 44018 bytes Houses/Nemo's Market.mov | Bin 0 -> 28541 bytes Houses/Rainbow's End | Bin 0 -> 78470 bytes Houses/Rainbow's End.mov | Bin 0 -> 7021 bytes Houses/Sampler | Bin 0 -> 1564 bytes Houses/Slumberland | Bin 0 -> 134150 bytes Houses/Slumberland.mov | Bin 0 -> 37640 bytes Houses/SpacePods | Bin 0 -> 140762 bytes Houses/SpacePods.mov | Bin 0 -> 51291 bytes Houses/Teddy World | Bin 0 -> 185654 bytes Houses/Teddy World.mov | Bin 0 -> 28587 bytes Houses/The Asylum Pro | Bin 0 -> 49586 bytes Houses/Titanic | Bin 0 -> 73250 bytes Houses/Titanic.mov | Bin 0 -> 6534 bytes Prefix.h | 1 + Sources/About.c | 1 + Sources/AnimCursor.c | 1 + Sources/AppleEvents.c | 1 + Sources/Banner.c | 1 + Sources/ColorUtils.c | 1 + Sources/Coordinates.c | 1 + Sources/DebugUtilities.c | 1 + Sources/DialogUtils.c | 1 + Sources/DynamicMaps.c | 1 + Sources/Dynamics.c | 1 + Sources/Dynamics2.c | 1 + Sources/Dynamics3.c | 1 + Sources/Environ.c | 1 + Sources/Events.c | 1 + Sources/FileError.c | 1 + Sources/GameOver.c | 1 + Sources/Grease.c | 1 + Sources/HighScores.c | 1 + Sources/House.c | 1 + Sources/HouseIO.c | 1 + Sources/HouseInfo.c | 1 + Sources/HouseLegal.c | 1 + Sources/Input.c | 1 + Sources/Interactions.c | 1 + Sources/InterfaceInit.c | 1 + Sources/Link.c | 1 + Sources/Main.c | 1 + Sources/MainWindow.c | 1 + Sources/Map.c | 1 + Sources/Marquee.c | 1 + Sources/Menu.c | 1 + Sources/Modes.c | 1 + Sources/Music.c | 1 + Sources/ObjectAdd.c | 1 + Sources/ObjectDraw.c | 1 + Sources/ObjectDraw2.c | 1 + Sources/ObjectDrawAll.c | 1 + Sources/ObjectEdit.c | 1 + Sources/ObjectInfo.c | 1 + Sources/ObjectRects.c | 1 + Sources/Objects.c | 1 + Sources/Play.c | 1 + Sources/Player.c | 1 + Sources/Prefs.c | 1 + Sources/RectUtils.c | 1 + Sources/Render.c | 1 + Sources/Room.c | 1 + Sources/RoomGraphics.c | 1 + Sources/RoomInfo.c | 1 + Sources/RubberBands.c | 1 + Sources/SavedGames.c | 1 + Sources/Scoreboard.c | 1 + Sources/Scrap.c | 1 + Sources/SelectHouse.c | 1 + Sources/Settings.c | 1 + Sources/Sound.c | 1 + Sources/StringUtils.c | 1 + Sources/StructuresInit.c | 1 + Sources/StructuresInit2.c | 1 + Sources/Tools.c | 1 + Sources/Transit.c | 1 + Sources/Transitions.c | 1 + Sources/Triggers.c | 1 + Sources/Trip.c | 1 + Sources/Utilities.c | 1 + Sources/Validate.c | 1 + Sources/WindowUtils.c | 1 + 134 files changed, 93 insertions(+) create mode 100755 CarbonLib create mode 100755 Glider PRO CW5.mcp create mode 100755 Glider PRO.mcp create mode 100755 Glider PRO.rsrc create mode 100755 Headers/About.h create mode 100755 Headers/DialogUtils.h create mode 100755 Headers/DynamicMaps.h create mode 100755 Headers/Environ.h create mode 100755 Headers/Externs.h create mode 100755 Headers/GameOver.h create mode 100755 Headers/GliderDefines.h create mode 100755 Headers/GliderProtos.h create mode 100755 Headers/GliderStructs.h create mode 100755 Headers/GliderVars.h create mode 100755 Headers/House.h create mode 100755 Headers/MainWindow.h create mode 100755 Headers/Map.h create mode 100755 Headers/Marquee.h create mode 100755 Headers/ObjectEdit.h create mode 100755 Headers/Objects.h create mode 100755 Headers/Play.h create mode 100755 Headers/Player.h create mode 100755 Headers/RectUtils.h create mode 100755 Headers/Room.h create mode 100755 Headers/RoomGraphics.h create mode 100755 Headers/RubberBands.h create mode 100755 Headers/Scoreboard.h create mode 100755 Headers/Tools.h create mode 100755 Headers/Utilities.h create mode 100755 Houses/Art Museum create mode 100755 Houses/Art Museum.mov create mode 100755 Houses/CD Demo House create mode 100755 Houses/CD Demo House.mov create mode 100755 Houses/California or Bust! create mode 100755 Houses/Castle o' the Air create mode 100755 Houses/Castle o' the Air.mov create mode 100755 Houses/Davis Station create mode 100755 Houses/Davis Station.mov create mode 100755 Houses/Demo House create mode 100755 Houses/Demo House.mov create mode 100755 Houses/Empty House create mode 100755 Houses/Fun House create mode 100755 Houses/Grand Prix create mode 100755 Houses/Grand Prix.mov create mode 100755 Houses/ImagineHouse PRO II create mode 100755 Houses/ImagineHouse PRO II.mov create mode 100755 Houses/In The Mirror create mode 100755 Houses/Land of Illusion create mode 100755 Houses/Land of Illusion.mov create mode 100755 Houses/Leviathan create mode 100755 Houses/Leviathan.mov create mode 100755 Houses/Metropolis create mode 100755 Houses/Nemo's Market create mode 100755 Houses/Nemo's Market.mov create mode 100755 Houses/Rainbow's End create mode 100755 Houses/Rainbow's End.mov create mode 100755 Houses/Sampler create mode 100755 Houses/Slumberland create mode 100755 Houses/Slumberland.mov create mode 100755 Houses/SpacePods create mode 100755 Houses/SpacePods.mov create mode 100755 Houses/Teddy World create mode 100755 Houses/Teddy World.mov create mode 100755 Houses/The Asylum Pro create mode 100755 Houses/Titanic create mode 100755 Houses/Titanic.mov create mode 100755 Prefix.h create mode 100755 Sources/About.c create mode 100755 Sources/AnimCursor.c create mode 100755 Sources/AppleEvents.c create mode 100755 Sources/Banner.c create mode 100755 Sources/ColorUtils.c create mode 100755 Sources/Coordinates.c create mode 100755 Sources/DebugUtilities.c create mode 100755 Sources/DialogUtils.c create mode 100755 Sources/DynamicMaps.c create mode 100755 Sources/Dynamics.c create mode 100755 Sources/Dynamics2.c create mode 100755 Sources/Dynamics3.c create mode 100755 Sources/Environ.c create mode 100755 Sources/Events.c create mode 100755 Sources/FileError.c create mode 100755 Sources/GameOver.c create mode 100755 Sources/Grease.c create mode 100755 Sources/HighScores.c create mode 100755 Sources/House.c create mode 100755 Sources/HouseIO.c create mode 100755 Sources/HouseInfo.c create mode 100755 Sources/HouseLegal.c create mode 100755 Sources/Input.c create mode 100755 Sources/Interactions.c create mode 100755 Sources/InterfaceInit.c create mode 100755 Sources/Link.c create mode 100755 Sources/Main.c create mode 100755 Sources/MainWindow.c create mode 100755 Sources/Map.c create mode 100755 Sources/Marquee.c create mode 100755 Sources/Menu.c create mode 100755 Sources/Modes.c create mode 100755 Sources/Music.c create mode 100755 Sources/ObjectAdd.c create mode 100755 Sources/ObjectDraw.c create mode 100755 Sources/ObjectDraw2.c create mode 100755 Sources/ObjectDrawAll.c create mode 100755 Sources/ObjectEdit.c create mode 100755 Sources/ObjectInfo.c create mode 100755 Sources/ObjectRects.c create mode 100755 Sources/Objects.c create mode 100755 Sources/Play.c create mode 100755 Sources/Player.c create mode 100755 Sources/Prefs.c create mode 100755 Sources/RectUtils.c create mode 100755 Sources/Render.c create mode 100755 Sources/Room.c create mode 100755 Sources/RoomGraphics.c create mode 100755 Sources/RoomInfo.c create mode 100755 Sources/RubberBands.c create mode 100755 Sources/SavedGames.c create mode 100755 Sources/Scoreboard.c create mode 100755 Sources/Scrap.c create mode 100755 Sources/SelectHouse.c create mode 100755 Sources/Settings.c create mode 100755 Sources/Sound.c create mode 100755 Sources/StringUtils.c create mode 100755 Sources/StructuresInit.c create mode 100755 Sources/StructuresInit2.c create mode 100755 Sources/Tools.c create mode 100755 Sources/Transit.c create mode 100755 Sources/Transitions.c create mode 100755 Sources/Triggers.c create mode 100755 Sources/Trip.c create mode 100755 Sources/Utilities.c create mode 100755 Sources/Validate.c create mode 100755 Sources/WindowUtils.c diff --git a/CarbonLib b/CarbonLib new file mode 100755 index 0000000000000000000000000000000000000000..c134d7a25e7886b136532e0ee29bf10c29b381f2 GIT binary patch literal 234308 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 TDtwak6UyF-za{m1nuPy-% literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..d7e03cc44e6837909a47a0a355a6bf9260529bcc GIT binary patch literal 38798 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 literal 0 HcmV?d00001 diff --git a/Houses/Art Museum.mov b/Houses/Art Museum.mov new file mode 100755 index 0000000000000000000000000000000000000000..a4bd4a8ee75da010f19ad47b88a0dc29a0387ba0 GIT binary patch literal 28232 zcmeI5y>cU2mfsT&C`0oWpbR99LOb&cI}XtXFDF9e7}}62Ihr*pF%gSf711Eq&_02h zV^o3@i<=qINWOt&Z1ozAq|xbZWtxRFv|Y$gAiwlGsFCy%&F*5c0A%Lo$^xIYRb>m-!wtEPxHPV(l8#P;rtc<13wu3cZ!>+#q9gJ(x>IEvdg>r z-Y&SzxpmZxzm?i`Nk0r;I;8xa2VOSx$&lyX%aHc7=}{?KFw)C~s-~)PYFFJVr=CAu zEPv;e?-tc^;EKFA`+SJ^gY=}M`Q4DmL;9&ZO`S%SC0CmNh9Xt5CJu zS1V|sl}zE!p1->wQxP|$qjNZ z?b0FY2Q{&rlbX(^lX6;*s-v9GA@w>*)vPk_KQ` zrl`g=zdTxFtDKgWnpQ=j=FoN- zVGJybhdI*o!kSiA#Tb87SG2$2O4};=fL)o-rXP|XlVk{)+{|NKl*7EMc|EH~MRkD@ zOvls01i7bgl=OVWrF>OQzieOc1qqS%-?&6vZPH7&~Vgh4E@ zb=IRcnrR&RJWiqx8}e?o(&p%DMbFC#&$*(l$2K4Gb#*r@in3t%xMRuxs-Ca3YW4>| z9avdCLz%h8XwRh)^{FgWQB5a&SPlL#obE2qJs(@+ax8<$z+P8#H~cb$eHiy?5O*0T_cQ5T9vMfz9lN$cnXwP_9%F&vYcGD(NAZyeQhsax4nt|4* zAWyPx=efG=Q`}JAc?sSrHatJ;Hl1blx9ysK8(2kce!_pdenP`G6@F~ZKdoc>i+1d}{;)h+w$dTb&T(wg zhGA$-oNbNiTGO2tyZ*5=V!VCwQmb*LbuqE6W%p;ClwHeGoYgu{J0?NAfH+js=Urgd zm}PHHzH7YQ=3mn|?~)T{CljjdTdix{0ERVIw%d7;FBUAzD2+VRHaQPBZPX3kw%K-l zmv54^%XLvqtZF(PSs0B|U{=<&REtyArrtgsS{j)#gTc?H3wslqti`*v>(;cU-*-db z&sp~@U#pN6Ds5+NU7ZZ`m*m(t&1Mc0v667K>0C%$-zc1lZpYFU}~L{IGN-@ENEbS?>f{O>;T z;;c`)LmOln3(EAn*bHLcVH$c&P`G0GDD5b(8~&}lP#L zhdZrTb2S&I*M#9ppK4Y@gKG(JpZNdI+vCL>!&=5)(wVONBy$Kz2~xkyjkcGatGD69 ze(SNm9ldp91Dv5lUs&V)p>Gqv$1g;k39(<(hf&r=N$y4Yz&tPKby-x6e*ZCM7;Ei% z9uvR+#G9C3Yy9ls5t2+Zn9g_x)9r`$)oX`@wUOn?^G|AQEwyXjnKd335415u1{BF6 zI*#|lkK{wx?(smoE(*JC-bW^n68!V<+<~*U#j$E$^p2Y}P8W51US@4|KF%-bdh9f7 z%@5rdL)*=v-QnVL<0bhE;l*SrF%S=2ly&pZ>i9#)7;$5K|6mfILF=QJ{CRLYZs@gM zU`%AZA6lYp-uLYxW}>=4;ZjHTQW@iNH7>iO1B8x$9&ta%yS;4;d|F@Fbdpf!yR}~ zu7B@(Pb^pf36707#I<_lHQsUbEk=q>D6 zG=e)A0C7Lq7@pVj8H+A$dBOC)>upbZso$|8yaUY~cpPIU;4|-bLzMb^78>UD%p#>d zS&rFpvtV!5k7m#6aksZhZMJ+pZ8#=Za4(PYtUyr$ZNBlMUZy&Nv|C5 z4dNSr4{oHf)<$6 z9{7;fsxxidnb-EkWQMh}2LWah26#r&CSlucT5Ty}Mm@*l5x5mou++AgpZqscGuO{r z)>Tg2$FLZcW_o9-OW<*FYlE~@JrewBT@@1$lp6B(dm@Io@N$gzRQh9Q(lG0B{1U(S z!=QK)4$>iTzbPl>ADp77a8%`QRPC7Hpf4^3{Sm=s<^(m z9Mxc40zde(2D=u&Bg_%hUzea)!H)&Oi~Cr2JEA&X4-?9RF7dl)RoM0Q+_|_0x~MT7 zq370UO2`1~ySFs~M6NACw_uAJFA=3VE(7bptkSdvlnMUCxdQz8AjnxhU9>?Gk(rDy zz*7LQ$=JHEk4iVevsf?A8q4kpk_)vM0Xi46sWY!8v-vHdPJL@Dci%_uEzjgSn>G;2 zrpuF~H-vc>JNF<$fPnS)KtHV=SNQoY{H3jzZ-?XT~p8}|~#%RQ% z!C0)*lU7G_>zH$ zfIlY}j2MGR6iBtI1b+e_i|J@0__L_qRLboRNzAiZ$**{T#l{?e@Kz^xU4J;wQejQX z6N}XUcp{k~1k22ozgK$xeOaA=5@Z&*u_WneLXQhL02EEV)cT&zbBT2^2g|VV^f&nI z(!z$+a?!i@TK~i+#e*jOOWFm3GV|9Q0H9ZbKgm8YM5~xPzzRaadAQnYVoh}4rJY`{ zQWLc}1zZQK-OIZu%{GRt(zO3u@Tau5D$BCzBLM(Iul0|DKefq{=7)vLRWF1V#vbfP z5=SbPyqL5Zf_$x6o`pTS0e@D;i#jjHKkX0TPi^TSZ3Tbg%}wiSk0^peBTNfQYTGQ0 z+6O%Nnx!&VmgAfZJ}x@7*_}3?s|rvwP~;wr{6rSC+mILc5m_jXuus-IRwaLY6Bb3? z>`r$~5iJ}{i7Q;+tE06b5--bdwFZA)s{4?>GXvNF|K;sNo;A1>)290AA#Dyu0knCG zl>p=~M{lg9w{|LAf;AbjTpIDrX+-*hXA2XP;m3F2&mb{6a@I&l>UXV{n2eV zjl1T)27Dn|0n2v)KwkivN!uK~D9Vvl-GD#WWPZf$NMHzNM%Vxhbca5p_u>`sjl9hS z3&~@ByHJ;9wKFRjzUeL5qCCJ4Fkx@-2tEK7p4BBmPGHz`r({U|fzaS3A+Eu$^;>1y zq_N39wR0a5>A);`?+F>w<)rdhVLk}l=id>7;C zi_&K<^7{lt!9wZ-?9mTR3U>cW4G^@6)A<>HPRBILn7c+hcdqO9WE)(PCni6~f;=bx zIFCY~r>{+)1m2-dqyq`dPk*%kFaGRSCwjxn#XHp~>B@{V4eJ&zZ?EoPIcX1aJ^v4E#5*nNR-HHzo>`NY*#T2u|vj zZIHljI%YtKGygJ~U6ZCIS70CQQHxXT9dC2p4s_cx^4wN<^f)7aPJ5{m!vbdWKg(FYV{{z7KBhQ|}er=ca%o&-f?OjCTx1VnC>pqDqV$Omo1l zAS?v7u(qWWe2YTn0b4MPAx&+%?kU*m`|sT5h4wK{d}iol0bt~s-LCIrkO!UaQh}9n zFQzFY{qlyLdH>66Xqpe^G@p@VgfZy{H^-RBNdzju77YXn6M23F0ULze!waGex5sK^ zF?7I00=&CYz{4Q!O$Ss0|0V%xA?aElamNF}3e4BPlDh$($#X#ycv4ve9z?Eoo}ctO zNFhb?2p55^;8I-1mQb>w+x|=I zdAxA`2OpE4yVmRE6THedCZVr!v*na=uNW8pvnyTzsO43jr|G_`N_pj~w3!@xi0!hl zC7zeIUCOKi%pij#`oV5;yYnQ`0r?EfHDiztaSZN~x8+lUSU^nSCHUx79|GD^zKcP#3nQw${RM=b!um#Z) zzHKsC8*Y>~*)UP>LJ521eHkvi7yh$ze^Kg27trDM^|Y9bZg9RpYvR8=`%EEQV|zR< zuV>1Q4)~q}V-W;&NN?7wp8}T6+FsIrJ`d*5%%ktZe_Bvj(xLLqe_qxa8ieJJ9l!xF zWjJgfgy#NoyL{(rdu+kp7ME9U{@O;N6js!Xrh`9eBWrVWe1g7!9w58Mok$+SGVF}L zUy!ysg;kR%Ol?P;j0dt{xD2B@Ip*QM*AHgD!R{G3tWEMKa+pDqxqj3AZ{2*<(%))y zU9$4YQSss{y?$?|^}_i3%?A8Q+LPvwXS=2GLl1q?fqT**TWj(|023n!{_J3e$?x(g z%p=l5{b}e04{hRzZ^#Ox&!aE~2vMp(cd_!9tG!+&Z6tI+ATTdsa=T~+Fh=h($! zcQWow_)j74!mma!3~M}Z0&t6sPlezoqwCx6c~lyiSye0ksjMfE;S&DSU7jX@!9CVY z1B5^Y@x0%rIR70aLa!GlZoTF|YVl05atcB(@z+|m;7>_YncKS35#$#u5Qa%OPzH-` z3I6PMN6ZPV5kO&PohznL7L%DxA&uk(GZ;@)_3;s~#f2RtD1#_rL-d!j!`hbB0gJcAc1o-E-$*wp4&hv6&(B_%k-yh=6o>bOo z0`R?@t2@#evBO1eP1pR9S0h1?>v%T+sGp@| zUW7FvNe{EvFDr*7p@En1pMO)$+=T&Q5K0G+?D3U;av?PUX1jl3A$ag3(LRTu#*t(H zzO$%Fym!NE3;%ig9tJ~WtUxya2yC$c80Z8N(ku^>Jt^5HO1zh!sWH)@EQS93NLf#k zZfbuEy*Mtn-5Q&r_(YaMOcOr{B2QZr;|wD|>manq3K$$*{pK`Xl2)46GdgsSZ%>3_ zhE~45gxTlez)}oi$p0wV!TD?&?_Z*f=H;!hx4xtz(TTP3tboB z7vP^fZ$oftQk-l42}C9M(^j)J{`m+y??AlZ^M%^}EJh>#oABmsz@PBq*{=822Drh1 zNSPMEln!n!vE$NdK2pW$V|gYqmoXyniEg09Oq1*6C&eXJDv!oV|%@0@%9rx$6VGjhr`BOzE#{+Hjm`n2dmHnd>g^9V{ z4>(EP2t7!a4dNk8NVLEq_B-1CiTW{SN^T%FL{ostVKHP0j@SjZ{z5;WJ z{b2^$X2ci=rY-Uls8L_I;l85`6@p3`)0AvMnnr}vCwFxN#ZUUx8Xz}g$$IM`*ulK; z@+9w4nxzMXC`cL%ecyT!BseZr>D9_H?qZD(Y5-%I)CcmfRM>T)P@LP z@M_>sL6U*jhJq{snxM-^4`$@~UwMbrO`xWLQ$d~$e@GztYUQK8AW`Bv0JE|y@SaV4 zWtJ$8S0KxzFBzXy;AkPAnA;dpF@QVEH@utMc2$8EMI0dzQLIF$dYNa&mk;poOxSPv zNxn%Dgjt1!VT#3DVX6X2<f$%(Vm+ zY?bv))Wj%hg$KK&9G+585+}`8SI!MQXzftus#f#6(ebI$-~(Jc;S?@`hks=)A_g{3 zUIRT9)Cze@o%J_1)a3lG;Q8fr^j1}uPC0WV(_^KBj7V4aJwYpN(M&JSb0gt&wKSI-)2wG0qz;-|Pq92*l%Qp()M_H5~ zsIMb`QP)?+?~c&rI3{NX`CVG`Nkt|2fl>{%3Z|8Ih~rgteRV4W44BsIEA%63fdZhy z;V~jLfoi!rv%e!)P3W7ah>8=HSCX?7H#_7HP;zs6tcn|y8Y8&@6#BTjxZpK4>^tXD z=v%mJ!O?g3uB5swEe2ES9jWm5&L8+}`8Ok!A2ywz*56Kn{aA#F8%=fvYN87TARhE= zs0@kc!Nzm!BKze+3Bd*HS(bKz28ISzWer6^lwh1$z)=VOBrq+(pYT@jnY#5Q{^nUM z7#7wGo`3*y=08b^7*xHL%F7b`3G&n^jMf1_VAZUQYun(@gSbTsuz0C7Bjj{Fz%4Z| zh2@y-NgZ8sCa?`-@U{NFKnn9=K6l;a5tWUWu)-3;CMCkOEg?gycV>_0&GF-E$p?o1 zmU-9ibYhQ%|Gb*nRmosrt{0l8 zql3yZLqNJeyqbn#riu@D<53e0387N`>pzL*kx^hf*f~GWVaKZzL@O}^4jo@A4rk%6 zPEvnYCk^iq2Iz(uU7;kZVmh{}3F(j07j;?H#R$0!;F&;3eVzGjxDEAsL$4RRk;CEAQ^ zr!SoL;|XSx7`=5@j^6z#`y%DPK7nu+5gd^i=D$BcUWP0KjPmgLkn|x_1b?=qG&U;1 zzb+Ajkm33-;ivP!^=N-+`0xcB+QYZC&{h1?3xduoM!cZ=a#h1B1lBwxdOXOMxoFWzP9a|+en$8Jmg{Rf`DJCH_^ z(@6iQ7c)p6Rm}0#a`y;m;mIAIOLPF_EHOF4FN{LUb^8ai#7qH;&(z-&k&%EwV?ha- zK7DLmA;*MX##qysZa{v5cnti$@?C^3pboeJnI#Y{;r|Oa{Bl zL{1`kkJP})^ZUVsDb9p;cW%F-NJRaenLJl{1cG3sG$Z$SSgnVM3i1QzBOsc_bunWN zN;JFo7!RJHy_NcV5~2Vi31%GVso)hq$on|+#kFV&J)cVyeb_?agY60E)ITK62ThPawCH}KGye(CzsAGi#1632SQ{(J zJ*|zPr=&+O0*g=Q@($`$y5LhQ5W;06_4g0p&!c0AP(%J1sTw4|@Sl2h^RmN2%|7&h zCSOAxfNmuV`ur6SM5zV+i11iYv0%vnp1KPkrC{%itOJbMb&uV%2RjNdeFTR7MfguX z4D$^=8hDL>RSD@}%b8vBNLxlXA1;$QhNqZmY}y|PP8*#@Peb`uhJdS%;u z3hNX+$#4r&5nE-RJt7F z2?6?L8_>lUPFmEUXZ>=0jc6Cg=sm}>ATqI8e6}PaKU0t48g-n3KaWQw$Y;<30O1yO z1uB!To#0RYr=zSKk?-R6aZX+y_i9R}1ZP@)z%kFJs2J1<-21&CV}NL>7c)&(#xR&6 z&QdT3eV5TW-*NEU)09RMU#jXYlQy5$D3DPvz!(Yd;n=f3Qs^3B=nZ;Avb|LJ64E(F zGHWqTU5zUWbZ|;`y)2fV(6tr?sWP??-y;)S|te%;8?CgJrLbe#~q$BQjyCuBzKf2~T%bAitg$ zJoI8NQbExBe3N&}g&+uMG(e!5eMCRP!zBj*)B_UC8{i(oL`K0z+o!%AIo9oz68cDS zD|{TRA@mvGQDBJ3x3)M7o-d9V-<`}$>-$@-hUhBni}~>_SYtMwGm6Tgq`ms9dfJ9X zM!&3dOKBEM#SYFmwl~GMVh@Jt?bewV?Nic2THU)Os&a*;+T)x_fgavSr%N7}AXk_48*J%m;!H^v>iC z9(qo`icz7>sCWQnw8iV4=6)vXk z8omF`t(2_k0n=xd_4S=z-D|UQ_fQIqKhF4d2yb2JL=1@{h9-pdVq4 zyZcDkW$dU6Ka(8*oj2ZT34gCyA1Fx=QlS+C13S!dWzlGjrnE%k_EsTU$5B8M`Me~zFI@F9Inj)2R>Edi*bj6frZuo;O6opkOidunY+GK@MtE!C5I>cMJ+ z2Sk(jF$C~2{HHiI`i@bu(ZUOV#x_B?S+YP4S2=Tx29-HA7JWPsi1Tb8KqbLodu>ch z%^Jp)IrH-uI0nQ4ea8&*9o5MN_4gI{6MWUWuES*SB}+(SfE8JgC;&h0f8KZz#cIDt zJsCz3kN{9N46o$Bm1CEer~Af5sIO+^SX_YOfj`U~xlSLoLrn5BAb;@<*s6yx0{IZt zDSrz8Sy*@9x$R&1&j(`~$-zY)F6n&SLHbgpg)^ogH^d;I zBPNUbK{6l{vlF0A{^xU+`^_%&)@xss0%sE@FUCitL4RZojmxwC6SpU>muv;lA?ijM z24>uI!*-`znA3Kf#cLp)P_w*2T=qf-?^hutLTk&a=zCx%7S0S(`^9KTM!<)$*)2_j z@VG<&Ndu%%iJhcC@mwFDI`AjsCis&9qY*5f{uApMC5#s~TNkw6w$01(FYuqD1Sr(K~y%PkAZ@XpY)F;BV4nGuWvqdsCMHXg^z5XU?PS!XpriQ>>~j) zy)`Y>wM+!NR00lw0IjQR1HfOC*P*j#nG@Sdg(UxlOz{R%nXmjO=##QU$M5S(K-+BJ?Ea>!Hf=M|? zn-%yIwH(0gYyJJ4SK@cMn(P3y4M#(#F;(D(fHz*}O@<^#`^4Ij9D-LdHUZ~+NW7LH z&6wBa4wxGM{AzG#>Qr9l0{Kk37wcd#a8I5rZ-Xc2msGWXLlB+c+m7gmm|Preg!y4l zXv?_*0h#chl{K%`d=6kGHC?I-K9VozNZAp@_3zodVP8K4k|mH+LJtU(ls=?FShf0( zN)xi3O8<@QpS!P1YUvA`{Yz{olES(a;EgarQY4fyqH4%|Nta2=P^V3A)eRxF)Gi;b zl>K&&LJIz~(zZKS6H>A8z>8R6mVSlI6bQkeZ)N}74DJmz?LI?kJussl&x`?jNp6=fO92!3kCt3DHKv3$d#eQT!c6< z;|l%q5!Mr+d1a~j1pP8day+@?DR#F%}RVRkuSybqk)u@^u=d2y}Bx)+Ofeq`=US|KkLZr*PJs4_UFZFCdQIjg_>+1+&$nt} z-}G;VNf!?Ey#JDM7?&9K2e`)gT*3Fj5}j_qpD=ysmo?9kmRjWkkHyB7Iidj(gVV3m zTRnd&Nem&wa9sE*0wH!l2oU{MrN~bIlKk=Pz}9NV?@a(OGoDtVyt95GkKa z?52Vmq78O6W3a&b}4reqa@_pGTx+Ywhj4 zi*n+yR_8556ab1M_h0oRaMD_{;(#c=dwRx?F+Y1aE-=BCT4d(!+E(-Yg>XMU6lE|4FHct%opnb#u(zz_&>o6QKKM=vCy&XAu^XN!!q7(|QR4+~D0VPaf9X1i2Y_Qp5p%1VII+XjWIE|1>!O4PhYidq&F$ zzQ_0ig7iT|JjqW@bbxvFDO{gR(loDQ4-$dh`5o@m){BM$FbZh)*acXQ0IU8Hhyr0p zCZ8q{sK`FfbYe8njPtZIe#ztJNd5hTYXF|Ow6FXp{Z3H;qHr9jNU;z=`hX3x4-e=^ zeHCQJ(;+%v_tf9(+lSEI=q3A)Jj(7EP4b#_pV1cqXh=n)=PmVj)6h#w@jI}^7Ikg_ zr)Q`VfInHjB|T90KgAL|5njli8?pcasNk~P6_r`@i&XE?5d0IHjKP>aL4&~Mhf2Jc zCHNBy5W5%8O*JrmsgPj9SU%TF2o^{Pq+|&(%@2$`Z#0ztDHJ{3 zo!U>5AYz16T5&N#qyYlXiQgH#z77pqWA1_(?HN>(5GG)|kIZhf14V4i{>v+#UJQwK zdWNx-%V8`1y=?W#Pz40C!hGzB!5%V^K)(+EOopX53)S>7%Utkh9>^{|6tcOA1usG? z=0Bn&l@uf<8Hx}fq#jf_d2iCm1`!AT_#F;v!xG!e2BLxeVy=GLVvb^XpYz8}_n2`v zGCpt`|DpfnmRsuY;7@(8?~M0}+5qVtp29m2ukW>r8gKL5AON5#25|wq{1`q^s2F>K z?NdV%r6;7OF9mg~@UWgO-jNL!Qgip(PrU65-zmj+$WcCo^WsC^qxX+;131B&Eb=yj-jKNfms|zP=Rvxd3;e{{*->e{$I6 z0Eq{Dtghc5=rlriDl)W6+Q+w+61Kt2*q@~SB>d;{_}%f&27l@~kG^r#&7CcWK^!;W zOsq^watH?nLW(exEqJ8gN6~+lck>Ixy&wqqPo$hcf!UQV5$#>-h0=%$a`r~b0EqM) z`#YRt^jwttS0zrTk7Zg=}1$1MnFQ zjb?u{&$*TYwgZxt`nz*mk1po7K-j9XcUW)Nx%V9FaD4B)BiqSjc4W^bzMvQWvywg5 z+~CTortqIvG<@!`{R{l8*b?ATPp2+T5z|&1wnlSxP6mJ(Fl7Uqx@-G5668|;hCQ0> z0%IWR8oKLN-Oii5U)~D?33UjJsM$Fk;VEGa#9qXdS_nhH@g@7`DF3s6u5b!U=#;`i zGc~SuaUms8lyib&IlqC;yC7$_Trvy&Ax~6kIS@?Bo)mB9MfH1rP#lCYKG)y7U+(S6 zCHNC)JF#X~aYOuIDltA-OcGcMJC|4TI1A7VLwB9erZt)dYtA+uLU6aN#;A8erqX`y zQyEM_GIx^hJP`HI3VGQzqd(>Lu$Z^Pe{x^~1TsVA(jl(of0#F5D5dwqS(+s4gEAHa z;V~|7#Unv?@R#x#!JpIOzmwyf0OV74gK+~kkCzuW@ShSJ$!gBCxW}JkWcJ*-IkEGP z>m`9Z-tgGl1q_+&p96lCZ|MF6D1BPOe-dk0PUR zO#=Ru{c~?15d{(g?8(!Rw(5^8Wg5Z7)VTY5eX}sfrxjhkqou-M0>V-7?Hg!(LDXo1 zi}FIY@311t#M>O~F6$5o8c^^zoQ+^u%EvMMCuYdwl++mn5;J(PzXhsbA%H>gw)()t zXRjbwm=H|)^zm8$1iIq{!5C9$`Mf_vm z`iJnIs+-_XIC5coFRLd+S-E#&GH%IRrlMaCUD&)8Dn9l^;PO27hp?su!%{x*2#m4)mdn5W~_Rn2RZT4j& z{Gf^n{yguWL$7PlFXM*^9HKw?YQ*fqrs^)#O7tVls#mgi4hUSs-+T(?BidkxVHmmx@Mjc0d@*0v@Z6#wxjC_c_t0rSTcV0~Yxd8HeuSyt zJYgk9@=#Ir4{6LO{s^sth=acQBo14%tnb)Ahx7l@#<_q$(Jv#nUjqI=E{~Vf;{rh7 zNt~d8ASoW!|C`x`X4|cvD74G@4a{DWG4{-stU%F^%&@<5G%jw`l9DxXmG#MAu!V6H zd!k?N_pLDL?BNmNVbaTS6y&{=-%gdgI9DQA44mK4NZumqhcg=(m}eT`HFB&%*1{j6 z=@mquMd+7{(VS|;sKUr0A*U1r)RX4i65Kcl87G2{;`7${uqR8i!*+1 z_4KABMvry91v!CQh8Hm-_(aOQq90kKAbAIU+paJPHXaeGhLw~K-p~Sjd2%JMgkdo6 z{}O>e zHh2oe0jH3l|7^C2Nn}|1#CtN&pehe&WjkY3<9(w`WEwkn>-psIJbg7*?)wAgU^tc@+dAM z)j;$_{T5;h2R1 zHgUc^{-ke@D+et!5hh^EKI0&ppr|^bQsMNVeYabpGyJwz#-u2N82m}Rlf=u~r&^@+)5h=^RJ8v*zk^z_! zC#E6@CDaWzlK?6Op2}BgLuy_DK>!h{Vy+ZwmSUvfhRi#K_kROE?2e3N916HB;Wex5lJrR9E-tKiMxZKw43(pgaOqjV#v;y0Vw^(KR3A2f?4Lm4d&4pua~sIkP!W=|;`2 z-(i|036BX5oqaFTEpa_SpL6{k;8y=t|EXpb6?OENeAP-2FgW;^kTfEtOv0d`UO69o zM3dRL!S>?oD(0+u&IVdgtnCP!)|R@Tt_e(Rm!G)CdI<(LW;25SviN6e#huIP2mt03 z=s&5WOZ|PU?(vg=haFHEO^gPA){S~cRxZ#@juweO4>9F2OZ1<>1|H9&r%T(`&h51` zttRuENv)A!Q34h02mk4~C-YeXkHk-=lJK1~X4P@@2G9)ASRVg4R(G`+99Rq>M4UhK zpM?KnGP&UVFxg%}lVWiQIEUO!Z!IS3vK}cILyP`9bY?7okeVr@CEIr;hyWxk>#cw% z(aa!f5&I&@f!OGAu`DJar%U0H2{6bSV6p!WQb7Y9pp=R$;XgS+LYoJ{&*BLwJp%zZ z$cLwF%VuY|HJwfe5kzpB+I&(f^ctND7Lx5_fqQ=r;^-cla#IZu%?#XN@{Brd41sH=qGCPEgSAsHvPYda?+_R^$*$V>7plnbhB{Z(tbJZ*L`VzX<-MTh!lW z5N&%3|A~N)Gj?(x+;$EhX~frTA$Ns$%42^byM~%nsiXuDhqW&&J2>hIKXWZlJ z!4(OCEOkf+9QpC27Q5Rg5gDJ)4|{{XSaT7Ktf?Mj3Y;m%`C}sn2&4QRZFtYIIg$^O z98q%xf4Yy<-|N|eX%oCyTojdfc(S27k`gPu(F!v5JeM*q-`Fv%cRP z*kXI$KPT{+#;$~3{HVV@Q>Ov}sEwR#XZnqLab-_08dP~QyxB_s_>S`%PE@A_ zf3n+v0t!+8|GHD0D1i#mcvQ|$}fOeeUAdYK8KVWY7 z${0T4GJJT1rVc7&*T~GF;hAw>1Q_Kg`sKDmf%s$sHdmhcPaLG#e8!8#!~yZ=$r{9$ zH9?a!0oHE}fb#=181$FTQFd!xJC^Qtr)4$QPalq~HH}k@&rzm_GfFwrZ*Q6}o!RvF z3-D(T{zS){#Eu+;$No9a4{ICt&ykulxwX6tbYzBE!FU2A72NHg5$E(~)w%!1&WRW7 zD(T&?r^iWp{^l&!7eBo&E!L(DoqvG~)AdZjuj; zZ%(@A>Z#E0f6`nnft`C$GNryItgDcB8Kv0+MDiC{A(Rb~cV6|9eV20>2D|{)adnjK zL8ugnq7?HO!4t*<_q0Xe^nA!a2jEG-A6s2|bt(9>xMba|*v4enR;isI@c#?|m19CK z9C7ajZ2m*N{GcCTeK`1!n+D`hL$86HUvua0(T|8LprZF~4K)pT4A~Jujh0o&5Q4@1 zLyl({p25anbtMb{RVnn#WjWupngz(-3}J$?9ocq+Vwq0*Y)Akl?OCuJq2eR#oAV{) z{4n$*w~Rf)2Q{uM=>014sMWGhgUzHEBV4})&%kwpl6`<^p6rW2qa^flEV2yh*? zz->Vz(hq9W)H!HBb(-U2p9Mj|~Ng9K(0NAYr! zTnLQh6SyRnG#HbQE~O>BkuFZmho@U-*gTm@eW|9K_cq2N#I>+qlV z?0=UBGf~1=!y@AG4zmBK`nvzfp2L66@CsD{{|UqLJ@t1$h`>qpjqHENjfW(}uw|me zg#na9WZ7DI16?`)fBTRApk|`4JL6CI%$xbG-~tj^Iqyk2NC$u&GOv=m<%zGTzXP4- z$lLiO;Td^8Kgcn2w*I!B=*8co{{(1JR{>n36yi2ST~W`lV!X~3{3-mW@SXFjU@uQW z$;y5+g_E2*_O}j|1_69#+aM{5!JgF1`~%ZMY>JTnjk&VCX0uM^jJ`uS=uDgw8;#Xs zdWD45hSI0O;7>r&gY%B(3PVj=i1WmVvqb^^JQE8AXcd~lp6TxylQ$K3lzlFEDW@)k z!9)d$do*OMU#FGzjkg}uH|Rgd*A#%O5zG`!Y;{x2zrj@j-oK?9gRD^S42~c0arJ>@ zS*D-piLQt#H`5yns=A2UO_podZ_upIEnArqwj7y}ea zijMyl{`1ID2atOpr}D^Iy9z)%!qGl8ajWf-(4W9p@F%nuJOe`_&IY@K{mV8bd!onG zS0SE8(>KE%B&L0j{*x%n31iC=EJWY}K*?=*5dh8r%I4#PpCi)KBNU0ZPI=8KK~&0= z^c=;T9Tc0&OF}tmhhMe zMW6~HdSb~TWM^qgS#nzo|Ea4hWV8iSFXg&Y?=VqS+vsn>Phjs!aWfZr60VpnfvkB9 zfdX+KpO(mKZ}F}4oT1_zVm_-Rys~419JR#5#C&V*3)Y;X+gMW#QK;GNLrLK=`$50V!9{JujMU#fQa!B5pq~d z6mb5^P6$KNC;V6g%4JhD_4n4(cOyte;XilO-#Nc_w;^ib)(HK0`Ft&ai9dVYarxK! zJIOX1U}l^o0{&Fi;>B#1)A@=0b8yK>li5K^c!kb_|3sAlgrkJN-RnggBRd0OlB8#% zLBH2iGMA;-aGW=ZAwx;)sFBldDZviI3z7y7O9Q~U#L;EH`S0PDa(c`O2Y*I)A=LwN zT22kQBr~z8Ym}T{i@+8HAX{Y4_?v<`m2-$~PAKOf3E=sbtUuFYOkd9rqkc&eNP2E2r7_IT_|>FkjOXV<)p2;GBgM5Db5&X&4 z8CqoIa5uCyd#b}4=TltcyJY_yi6C)Nna4FJj5$9Zz2y!_m*h*lB-h*fK^20q< zN$}@!%Oh;09h{#Hsv&9mLh>VsPfno{S3vA%FgY0l{0WDPyblnW1-qr_m$e*+0RFt? z{93`E@QIMmoc0O1hZq-D5y^GT{yhX0Z13qgdQ5yH_Sr53e_9A~<^0+srX%OqO8!qL zIju~Dy6Bwn$x=+=v?>YJzW=kFP9^#k&IEMXkWA94A3`7JchbLbGAWpi;rT3QDR2YI zlSC>wrcVIlJuobNfz$*F27@8z_1r}O=0#r0{<+hJ9Xy~RuoWCSd*u)rgb8#d1qh_q zW(^^HfMGfB&!=TeBzgq^7)xGRG1LUOCI8LB1m=;zIZ~>@5+L(6R+fb9#*Z z@Y&s-P#$r9LzM0xWe3`4q6cJB{s~0I;>+Q#X#;>9vJ{CdYnw?m**PJ> z8&d}m<>@~Vi8-pr+sXO0TTVfYh6j`(WQag~sW=BdB0cMhq7TXz&d*|Mcr-AcDMq05 z6CLO`JC7tlqkG{5wubW?1hox`2v~SfN)?{-!(`I&oZM1^A0x;1t?m^yo+ta~*dWQn zJJ~JXsT1N%Awd_f>!S5#NrfK^H%mDys=W|7zyAIQ;r@R8{SUwX{s%ckgtKl)QOGr5YFqjJ G5B~@IC@FjZ literal 0 HcmV?d00001 diff --git a/Houses/CD Demo House b/Houses/CD Demo House new file mode 100755 index 0000000000000000000000000000000000000000..742ad6a35783253419eb771fb99def70a725db78 GIT binary patch literal 72554 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 MRc<5YI|aA@4^|Xo00000 literal 0 HcmV?d00001 diff --git a/Houses/CD Demo House.mov b/Houses/CD Demo House.mov new file mode 100755 index 0000000000000000000000000000000000000000..88394066d4067b6eebf1e5ffb38acd032edbc7e8 GIT binary patch literal 33042 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 YrRP6;Ekmyse&SjNIi!?-RM#^6KV8l^761SM literal 0 HcmV?d00001 diff --git a/Houses/California or Bust! b/Houses/California or Bust! new file mode 100755 index 0000000000000000000000000000000000000000..80a87c1444f4c2d5fb412cfbcc7ad13065c06e69 GIT binary patch literal 6434 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 DIltwZ literal 0 HcmV?d00001 diff --git a/Houses/Castle o' the Air b/Houses/Castle o' the Air new file mode 100755 index 0000000000000000000000000000000000000000..b528e95d7957581c695724e57971a91ff7605a51 GIT binary patch literal 30446 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 YeY$g-wPlX^jT0k-2MzB3Y3BC70X>GGj{pDw literal 0 HcmV?d00001 diff --git a/Houses/Davis Station.mov b/Houses/Davis Station.mov new file mode 100755 index 0000000000000000000000000000000000000000..0fd4115f009fed5de241421bc45c22bf46b94600 GIT binary patch literal 34504 zcmeI5OL8135I{8}Y1OM<=`ej5Vj{-N+4&N6mpNgD?HZ`!mykbT!ji45g&L}PNs=U= z>@L(#Pft(({QcM0qrEo%YKyn|?fbvX_3hi%0!@DVaU4JV^&P){0)N$wH$v9`*ml=6 zsbt+QHUC)Ux$2KYRDj1t0TM0<2>7-=9*^x&jCLGfzI-V+xF&esPud9O%@i~D%%?Im;B6!~0-(Qe`Ie~|Tk(}|A zc|-rp*Qd4L-ck)GV zBDY<0QOl3l^IZI;Kd?P*PN3W3ZQkOC-L*E!dD?Yykxw5#6ieVK&W4%|7{hCD?fwD8 zJfJ1C0G=B}P4ow~m-^r1Ezsn7 z{qGX4S-+baVV18Smc??$QwuO0znJa9J+t4O{T`d28W!xAriE$yZ;$82{yPOs*B>hP z*9ebIrXxHynU3(-WIDj3lj#VLO{N3I|Uw<_%k@ZhIl?IGiktZX+ zOMt}Fk)MvowJvw1`b$YXCGg?%D>8Ns5(WNvp#DuSmDE0B<#i4 z&!Xp>##8#UoCzhO%vX*_+fX!4(LU@UMbE^VhWzaxwSVcz~iC-2^R#&I4@w4*WjE2#=GLj zWQulTv!B@yKCFm2k?22b@xvj6Z&Lgrg>Mp%H5uF!+Yd_jnUBt6pPARKkoD&sK;)m< z$4ABfd(J!cTI-S)>n}yo)HELrJHV%}e3BlgVF&o8BQC=Z@ILN%O?4kfH0%g}9JPQ; z)EHl?PbrpnsTBEY@dIg^@P@??y9;(eFWU7=ac&c(;5nSz`$h$LTofSTf&dxk1uXI! zoKwJfSNxbv(N1jkGy9Qllix7^*|IHQ;)9JJA`lqpzh?h=oL>#x@x$&&1JSNq5N;7r@Ep#K{ipzsivlEE5Fq2cfJI(|a|#$w zyMA$S+KJ76X20SmR7&ul_A}E?jKGtdza&WD{pJsQ>iVS59ks;!%^xYi3s>xalcwh@ zILaG#)N=hb503JlJL*BcJIXuCw?}!0`Q|9^Am1J39pn3>yn}q*8E5*Z@<oeZAmwttr>foHdWL4wG48p9j&{B^Wo zp1(enoZ!jB}ia$2cc=5D$#=|5yKCa;$#ugy==j-}RxK zIs27)X^KBb&V2t}BWIqk%{8TeCE&N_UDZ%LY4HPYmw4CWhux6|qK8gF=t+!QdNa@A z3IRMW3XpI?K*pI55jh)XzRcFyFe$@)sfeu8VXegON7@mp(>mnS?3rK%bU3n+=L8^p+Q{ess>ARop4CrHp#`vfK9)Jh zmt&c8d~U|Cv;Rw+$04*(|6Kf+n{NBp zV2TC%pO!R!%N_+2-TVRHjybcR*$;J$@UQnB{!Vq*;)lu@ebVBG-St+9cj&37AlxLT z;CsB@hKT}t+-p{C!vp~+o_Efnk*oj$KaF!f*y4ZLj1z$JCw(>|JP6A?KFt2~h8GYX z#2tQqIM(i8w(y%iE4+V_c!`fs^3n$6%oiFEF0Ka!KAK{>{#9Q2`E8CgV|~?&a{pV6 zmkK`OfA$gE55`L+K>7J?i8L#=N{aPYWwE63eh{G72lxM|v-O|#AL_os`j;5; z0#lrTMP7ry*Z#S918o3a|KtsmeD;PpzU*q}c<%)9p|)w>8z4NCHqHA8F#I^&Jnth2 zFJOf~{LjlR@k{N$2BOu!U54oX^5ZWR|M>PRb4}8@e%0uo=9-#IX$7C>n#9zvGGFGJ wnoDV!PbKkJ<9~Pm$NN3qW&7WyQsk@SdHLt3Y2F8bnv3c_uW}gq;su)aA5H`Q;{X5v literal 0 HcmV?d00001 diff --git a/Houses/Demo House b/Houses/Demo House new file mode 100755 index 0000000000000000000000000000000000000000..53f1f919d2e2db397a4a86a3d0021302e778a782 GIT binary patch literal 16526 zcmeHO3vg8B75+}L$wIOr1r)GGy+KHVJOT=c6oDiJVtt!n(Ap`R5xYe!S(>$E42zMrFU~HUt(sGtr$yCybN5au56?Lv%#~SO{ zNRM^A6SLP$K$ObZ1ao=)ucFOPB;5-ptS2(+K?|kdjl|AO#RuKaXhEX zjGrVmM+}jg!?y%fQ#0|Nt==(g@*c;`oO29t{#?%Yzt1@zk#qie&Uq;3yalM*+27+&#YUhxv1(-<)vjq2Ki zRi;ZU;x+Eaxls3b4+qIq`IeDiz{l94y;J`H4!{SHB9;G&N2zu7FX0R$s{Sw700h<# zQ~7z^khYO}{0j?pY`b?;9tq36uGGtjtc>S+$v3BEJcZe{2daH}t5VfT@yJ>`kq6rc zbWAze&Zlk!PDKdaGF|)O*)=#5H^?vf&A0JKyo)!4NEmq)-oUS1S-PpehH?$gH{WYp z#d)-p8=TkSV64L`xsWz>_#rlHOV>uOH_u2=iwpFsX+7>T&lkjhn%r7jZS*mmBX(_r zkw;;-jFqFLgH2+1Q|fBnF~{T}nO1wUYfpK$D}Pluk7zwRlI-lZ6IPAYL@JBg3FP?g zgL)G=*mBIMAf9i@IJ__0)q?ocaojxAKQTipv4;Agct#fDHdWKUN9vG}SE(O?jZ%Z( znYNwyt^ABSJuapX--}1+H$Wrq##O)pJ*95{Tk)>xU*CnNz4wKFEmyMN`)GeK*2r@9 zdzQM7)8W$hMa+zoNx5KksS$FZ>V=#wKc~DH-;-PTseX7CuEZvg zXgv7~a*-#?T+c?I*I5S7fId6vF?bdehZnHPeeWnAi9fTSKb0y!yp12=6Rbsm@~b$8 zqv-5X3BN7RW5Gy$?x;-SF2AB z)^9l?~rcQWAk9!*KdpIw+-$+Gu|!ut;_8` zv99{9)uPkcps@A)serBfZgLLw!M3tF)|F1^)qB++`|z#H2wBc8GI^Q4rv<-F$0R=3 zmbr78!s;L2Dkr3|4R~2^v56B3*bb2Ymb=)tXwA(x=S6Tk`L*{?DQ7W_6NC|%el%jX znVSl6LfVIKcH`lpF1D>J*5u{e?Z$7@=&J7)Gcw{)-~<;#6Lb1-!v3wPj-(xrhhug) zW-VUX6%Q{WsRb8g&Za+Mzv{fxOqb#0^7S$WPs$wpozHVUbGNr-o|LGJ z5AirF6aO$a0X!>5GMl44KEjRc_c5a%CJ#!3ykz7`d4XfwMR^IcmiIYE`WX8xmypcm zU1-}+ABY?$o@A7Bh%LyU`yix65pK!q^`qf1}MS`X0$4 z@(}xc-q_d3PRgwLXg|1|nf7f)Kc4wx12bjShxk{e{a51TL+R}fFFlWZcMO^PjTD(Rh#GTw}*ij~$`V)*&% zkL_N>w>p<;zL5PXW`#t3c>}8nb6LeD4-~NN>$joy@ER+fKlrUXAh^Te*qd(y9=7Q? zVNL;CKTa6Z9?!8c7R%{w|-lpu`RbKHFE!0SHfps zO_p!d$m(Yn+dmYr&4+F1xbWF=JJxAWvW{)_pUbu~+A5-#nh1;js(Y4tW82_yLT1kr z`QcJ#<9aB^*2}fnu3;MWx@T#Gn|Gs{^_}6|KcMkgJ>P+C%G> zqd7+b+r7Xx*u-?qNhI^u6A<*nR`)i$^Lv34Of2NLKcQ@)2Dag3#EA{YZ|4`V9hei! z+nu;>wrk<`@jQ8%pWikVupJm%cR!fYZQeC>KWue>LV*(on9BkSYH49rK}dwZ%x!TXcMdF( zBcOkiGzy=HB}d3oSH@1tb(HJyG}^F|lFHk-2jO%|!oQSw%IxuX3qRwUrovJsc7fmu}#+#3fT68?T}XfHDqfzGRXKg zT~8=r+Yh!Ooy+=PFY7axvEJv+Wm&#uO^kb~%$hIfxGdjN&hV|uX}+bL;akcc-<6>j!X44Qj&F&@0-a&_nVHK9*t+!@Q;YU$HKnaigfrQoVlZOr O&1D5_y|~49P3OOUw@+LE literal 0 HcmV?d00001 diff --git a/Houses/Demo House.mov b/Houses/Demo House.mov new file mode 100755 index 0000000000000000000000000000000000000000..e2fbd0e2f91a100b30c6b244a0f37dbc0addcffb GIT binary patch literal 119789 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 z z{#S9r*I2r$MIhOhdMY1ch!g#0z_hT`4;o`8mXk0UO@H9b`C~>VI4wwOIQ>0AALaaq z*(9RVRXA-t52HUi`qV9`87xhB6w9vGd-%OXdJn()$Mx&3p z)PVoc736O;SoX zoEEkl4M!{QrFxHw>MW``>B6Jp>&KjrT&_jgv@K)t(p$0%g13Mx<9onqin1x2J{DLC zy;-x2W+A0C=z0%+!I(h2R@8g!+vcK=CB2P!56@-O;K>Ix`ndb=luZYiK0kZF=}2m< zfxEJ7RC~ziN%2fgN7?k7qnm)~jW66hTc*X`;!2m$y9%Zec)I2G)=@TX@!Dh^SUf*a z5Z_at+2z?2+FLKLrYl`6UDnl!M41JoZo8;#`hTsG(@{4e%&S-Uj(khc3591amWm*x ze2$I7ss&5#%>;KT`*b%^u4r8ZS}5V}y!4B&!E{Blk1eit+w=X1h)>e3hLw?TjK2Eh z3l3pJP7f>1KD6KR@M<5CcXgj$U$gIp=y*Sw@qB`HQl}3tN2JroOLd=qx(*#dGlOEd zofDi+Tnr?Af2r5L+UcXBxc0yx>F$t#-l9p~y~Vrg^sxmq{cxKg>WyNS&N1Rt@WHqH zH}`FIr;0#1L|w1SG(4E;8uy{q+uY~!73~0S@m(NNi^(w=JvXS(f%JMD7~Bz({w>F5 zw56=wRzf|}$l8K`SPVdBa(1(M$Lra?u}f4sSH;}&CEj{VZ2TK)vsJFEWQGR!<)6;bN*tk_! zV+h5WdFc~+afq1)f77~yCV4dDxZ8QSw)t3HO0MWm;L?%78UTZj(9}#Le2GRP@Wu@+ z=~;E6&8unJJvl$!<(72NNUO(9TjC+;^s#d1K_Q)-l7_z#cl?@O92gX4n$}M0mmy|) zZ7+$h?2kAEPMPf)sfB`%eYN0|@RjKFVI(NK7t*~G(Jkrv>O`lHCl=0GluD?(>jp&tv?7zIBQ9(iP7x7 z^7n=h1X5mcWN>gGTlV;Px3v0$G`W^!>#Jjlqt#K5JrZW5YUwM~)=)VvPtv^H1BjO< zA-p-(`hb@%l%|}#klrk$Q}A&DjjeKTeN4QK?D%{u*>*4N0-#8C!PP0^J7c-_G<;pN z?!c97!i!dR80yDCZKj8^i?n0rnix*IFjle%^SVa+2sjUF=?> z##uN6OhyH@FnZ#r-#1Dxl=gKoEYnl8fIU5qo_W^=5T?YjLhl*02EI|s(oA3*6@oG+?M&WGHx#Li}0VObRQwx;t|dxh?>m^f|BYe|89+h z94{Vv>lEg6;|tQI4G7~HYQ{Y2K2Ef7M65cAHvBCt;~*v<_+f3r={}sJ&xWZ8Ps*5? z0W=y8aOAH{_mPl$l8)i6{nPtpx(^p*v=L*|A&45yBOk}v*$X1ouEuCos8BdPBxMqC z&&pW(`MDz1!79uL_Yv46uhB2lS-byur^9a6ZAn6j{HlG}jp z{7p1|<9rAv3HX(d$`~8yme!;(?M@Oi`s_LGDAIhuKU}#->?W$Z>XtaPKim>mX8Jh)_rP`}~DY7;=P~I*E@u5UF>&2L=v#iE-C>WD=h`KYhL%L~2)c z2_m&3)Fp7xl!bA5!0j~>X#I-2h}%?kfk?e?BK7X=h<|5Xt;^lrC+uIgHYf)8)yfJH z>QpCjo(MIt6*g}1szSc&4MLw>Lu;LW^UJF?xfcO@N-tovPL3K_O+bnZ;EVHXK-0l> zj2?^+yKDPa3D0m)c#5d4;-Ms;e!=qiilXC%bR%C8sadE5!#UOYjf{_gvgl6yLN#N| zQ!wKrAdJGc{9Up5nx<_c_4+n6ZC7=H@u9Uny=(3uIdQl!t@i_|0aH*HJj4`VL_e?5o+OZh2P+09G0zfze|pABGgXwQCLzj=K4R;p)=4^8006m5!F0Z**BL$rB!|7i z3aPLr1g4Nqj=NP?VZ2!a-)SfMNU{4AIr4zlF>S3NAvFp zTw!xI2Euzgu{eXUQUdBiuF}_O0TX`#{JRqkF7wrbklH_pik(gr)`qFTM zcD~5jAAAX@RzP2mGzQ<}maF#@B^^|%OP_#ha_D7Dt=A3d^^tCo0h!AOB2pJQ^g_1R zT8-2ZWe_iv+`sRVi2-`iJghPb?gU0KqYfvOm|9e7X>aLXKa%hS9o-zu(4nNaRSv!9 zdQmC7(Q4q}G`K%YXAt6d_m8g-5cbc>zo%UYI&1rWS=F3a^B8rU9*scy*FK z96Wp%lnk$1xa|cw^ekNQYDwoJNenMTcEmd|wVDU0?l(jELU=PZ5AnlDOs%>xNJl+Y zIR|fK%?sTFRDTtPVBUl7tkxPBaUmcyC#syJV?mt6L*g_}OkG9QVrz%$m54PZ0Eb^) ze@hfXMXZx_f5D)&>+w=e^zl*-JrxK#SL|uW5Ko)@G{a-&x;sKQy{E#yP$*7SCtV(? z3|5CXaBoL*$@N3*>1=RUU}`bZKh_1V>xx)Qd~Pnuf&_=pPKS@)e@N|>1ttU~uQ zk}wb&LOs%FF*s8Z^6fV1sqt6&mSUEUJYB`ZcZo+kd~_q-Qe@UH3S8dcXD1(kAV2$@_~1f;em#H-aE&SJjrK8K7JSMcXd)FM zFZVzd=d|s5Z=mnIC_+y4LAerI* zvXtSi54k8(WYJ6gG&00c88}N`nB$@1z9%=0ew9TJ%g8jM@06B-pkaKvcc9U;_ncD~ zpbcw&GL?0St zqtgSVVd+c}21dI{bv-=O%ZWbnwnHFKoZ)2+gmx3eY4rPRvgm28AHL8a269kE)c`fq zKRjqgO3MR(m7`Cil8tkh<^dryxRz6`!e5#zwe~JcB?GN_J+SrEwZ#$oM}~Qd`(pcc zlTivlrFlrld6-U(aHR8upCRIQ$imcrf?Z(t)CGUTW#=qsn0qaqlQ+)tc z+(87a^@z`*D~|XLQzSPKXPLhQ7Nu15SJeVcPH|Pz)xC5!Bo;$PNKiBB}qSe zSU#4>jK)AKWsVDS+5u5WxWCT~V%bO!|LLO{T*LD9rNdCa@>_W9Aw<|$;416sho0e*XrKYSj@T6&;~n~qXJ^qzwg z(XjiSoA00PNO+)AW|E(a&|1*<_;_%#!yUzn_-O2rih~N9DBg3=H!Y#HF&BQ^)yThb(L^j0s?>RCJOX|-091|K_Y_?; zG1vUBn#k+R0R055$y03U7vt4Ttc-pc z*N?9&`9~2&kT1}K5prP8z2I(U&y}FH9Fsf(-oqPhcSxG$Y#-PsFxSPayoU&{{6|(R+s0)%4V)t@Gw6NtbX|NqqIe5NPcLAXEFqt#`z%COtLSK?5Y3 z!%Oe>_8EXc>t_YDhFN`F@9wWFhn|WiqJ1=HeKEA=^WaCIH97R|JBJ>XUz9`d)=1o1 zH(p+X)}%OFq4JBE)f7#PeO*ZJ8=Y$Qv9_O|i3V7K*5R-{wxc-*^}0)lcl1@l46Vxu zj*$tDgLweR-1X)3AQ9_&R?IXbNgt4#U)~}Gxv_2ki1k@62 zYf-#UIIIe-!!0G<&p?opjw@wg2wDq3R-tulI%(@k)#XA zaHU+(njDjY)($L-SsgbO8QQXY+R_lJ6tw1&ClkKWGPKslIVY&r zXdTRIOqmV>N2C|fdY5QO#@5cECzoA;*67a8eE`H_IyKsY)_PT;-`Qo2NJ|G)B)7!4 z%Fvp=0$MxzEAE4bFT#P5MMR(2sdx{VM$o#GSrrv%ZSHdh?iFawT|%I>G!eAcBeNjg zLA6k3NV+sOg*e+5oQ-A)u7Rr_G6CEZ`*~c_b@w}gYnj|)i(M*M4M>@wyAyyo9i8qU zv;$tJ+AO0R0#+}UFQGVe0a{DdU~4QUokyh-MIvGyz}nL?8Z+G-SgmX|LNZ;%W*}ho zVhO8-*xiu{gA>kGiXIHYlnYorcac*)9!o8_he6eQ%6d`YY8H=RRabc0+6H)!A#D!? zt23?+P-vK1vM z0#tkX#^)sTnCxQl2=7)wwL*H{ZDiqDx(W3H)jI;!aa}P$bx5y|N(WRMv3Hz0+G(k= zYc*aiE0)o4iysJ7!+|EXh@mDNLfoi8b<(_GZzCSNbZ01a_-hkW3-`vW4%lQ0RA0@> zKQfZN5U)<4TH9hk^+E>K-_YE)MaFLi)f3YhRP*wFe}igipHhnmRIgST)|sV@e8F;i zIfVra7ix5r78ffb-OrGH5-}n9=Rga%3_&YB@!F30d;5W#dGRU2XUQlr#|WA+q7Ehq z-Is=&Us7>xcH6@*-V+mKMu-|Fh;x5jC=?#Mrepj^|Lp85A!-Gy=RPtMBnrNG%T-7p z`0@rJvuEdnBQZg4zP)cIh=SD@%aC)kip0)q>r^Zw-t#;mY6q*?sdsj712YBfLOS(q zx!K~`w6*t_=bt-RJ$Y;EMzxk=iPv?R(0AYhQ9~{$mzP+(v>PZ4$)Xk6IdHOMrQI`T`&NZNUpB#yU5%RAGV`Ocj=44KS(Mi2Aeh!A&ti?ooyu_4B|PmEKwxqGoj! zi-kC)O1`L;Vpd+3$xINGd7b83p`G4ub!AJJJ}FB1o0uSy-e8$o=Z;d7ozHzBGE9(( zYYT-XH9hkE0G-Z)s5v|V^HSSJB`;Nmypr@f=0}VfoOWOM@{qU!BxR^@PENQm1<{0l zl5srwG7wa-T8R1tnAH6lhE(nk>IGgCLQ36KPQFvp6_6ZhTQ?lry~7vio|quQG10s- z#9rWX&YrI}Sa?`4_Xg7ad*D2nAd}NCb2W%L9-f}mH$KxM-)x`U7gxhf5D<0N9q|R` z)rCA}9?*nve(x?!UvhtJEzVIV{1sdcSjx|a%`GuOsDtuU7Z5U{E~N9SNjj*mJAA=G z6z7j?D~%@7A^KixY;spoV_t@oVUi(?|Q_GCNCmA@(9zoq9Ft4l3xLo*lutSz20Yv|HNA2(ir0WO(z=(JS9pD+Nqi8@YpzCe9o5_)IpmA#AZnnBAO^dEt3Yam>!FsSo)NAF!&Zpe z*M5*ru0h?lQR{L&pii@OBWglnyZjNc?YrD1P+L7IUOf^DC;V~j1kbES#3YEbM_ZGX z)knSwkw)qIbaOrHV zlTT7KoMk`l26S6d(%YPkf~&~}2wEr5K08aGUBc-+0Txeep>w zH)2fy3Cylg^&^YoR3Onn6pgOlRD=bBTt)CZ0=280*wBEl&MXj?c`E=5L`BmDIYHJ( zt0fCW3zTh~@uS1vVr;8IjqXhgXYz}FS5VPbk9dtzc>(2(KsWcKg(qpwwZ2YJ*>z3bQekvYiz%4aCkZ zVv_0Y$Z$nCIUq|FRZF}u^+A8|WHeNrBH@|?CGHgJx=B<-ZmFB4aIOgZthRXo5-ejH+1=QGM_wSv|n)R8q8b zNf=>)6qp^39%oK>ClKz7h`}+@>l;@+g~7L!rG&RJO9MzUJ5Lxc zfwh;`-o!9b>c#;4o`1moCXdAP&en_veF(VKE8qJw2s+Xc~R8npgqB`Z8GA$h_fCcwH7Y9Tus=G-+$2Gf=PuDcVc7HIDiq-Zrm`Ygp>icHnc zX`Jki*X`3>v|U!Ec9Q`t3^uoQZ??=-jqt2HP6Nj)&|YWy?du{ZUe(23HbZyQh*NX6 zF@3fK5bZT;+AZzEgi66n>jJ*EOeq~GVTK8?8gg1U%CW@ED~i3yGD$l7JT@Gike;Kx zfl8IB+F(S6$;z-LP>`JD2?mvPubr>fML7OLiK*sm+L_ zb(Y>wpq)Qr$S>F~SVlb>v#FX(dYnKtD4ci&i(PU3&rSVH(!G$5*`Eotx5O}k)hwHb z#!C4L|D*>u*LUbQzv5=tMKgMV>OL|db)e~Cs zz%jA9#=x4<%y2zwoto>wl^-)c4f?E&A~@BZkCUIDtKm9q+Kb(}%A5K(Wv6OD$*2LKE#lG= zk98H7mLU;dkUj2KFm&Z|;`tdxd41>^INB4R#Y*EN7L)RF;%}XwLamP=2hL|E1L--R zDtHO6RC(cE=FPVz$@xK0nu|2ci!8OT%=w`%_MmIr{{cBaCO+&B(D*-kq zoQCwyEvm?jr2Uw=CgFv2Z%hZnBb5n1eSU+q9}5#Vw&rI?(tc!Uqn#56Lv8Z>HNdyO zydtYd_{T9c?5?nJj&{QSZ?=2&IuY^>g3^PlL=3OZq$thHsWZ6E*wDE#8}IeT@S7JO z5HWPx53g4#+F9zZBW!Lb>MKqE*7kG;@w8UJ&}#*gKI=Xp@&OEBHJGjVNZ={i|Oq>EsP2SH&-)_QisxQa%DQGo6# z?T1gmUm+dw1Ph5@>GC7W)NTN8Bkc!<!4I(s42|SI>lm zdTZOqY)HFDtpUxMAf|cT)u0T^u-K;NCn{#L**Jh(&W53PPtu+CV^WtZ)vb)xVgPf8 zjZ!J~^^ci?NA<@314}0%^#VcZDH2D9-Lo?I7Vz!vR-=E+VnfKAtCjTWbV~aXcGsGc z{mihhfI1AA{mr%3{(UDEVQX=Zgw#@A(zT={-G$AO&g3SH)^0KRBz=-*>#&17`Mf$u zb8d`)Z<~!Rkz2`8Pq_v5E%qE`+7H?%=|<0IkVv!&i=Qpwo_Ui>`{4m!kxp|mjCa)B z*j#Q&(zOA=51^BDFQlK)-U0PGe*{-Thp4e0=sjaLRip!^gv~c_AG)4+C&~8iLbFMm zqKb53a|P77M=E~y_0Sv15-wGEWcGSkhS}tRdXsfsR|s{^C(%6WB0izye?_Q9A@2${ zkC3+-vy>&_%u6O_l0N7Qn|BC$5Keg#f*nnF|6><)FTx#gv{f9e2iE37JA`h_Tb)Jw-0F+f)KwClN&#R!H0JTM<3P>wA*GBiKBSMxq+Ij%|!sYtWc8l7xnApv~ ztHX04EJ4|BZ&Q&L8tA8*pE_id`$K^~I9Y6R54!af&BjH=gVe0E?kKWhL1mRp6e#3h z|3cG%!5rolI=^mnFeLw;2wZoRr`%_K(0f0K)f5}&2(1H`}So(zFO8NlEE0o~L8vi8n7$weF{hg<6%qp^ionj2sHqT=_J{bSYA?aD*8 zv1CXuLe#^!s0hG*?u(E%p_(I{2~z-UUKWrvc#c1h>>s|UxMZYb>4D%wy4ci?GE!i? zHZ{*xLRnTZ@X$PDm(mphXC*+DYW5E^OKe8jTu+v6@k88mZLG?s_C>|4d9krkh#Kin zuh9I`^o0<$+{y*%0@$Ym#lM~XBXsxMtE`OX8=3&I`TKu2MmEn*Qz2@i>yiC~Ly^|U zypNDvnf)Vl7xCkE1z=Z*A7@I#Pdp-d4MwTPo@aNO-q;H1EX}!p{Q_A9?>M@mdn~*ibdQwy!^6Iq+z4fNV`~81 zKL`8XFYYE1mnJnenlo4ohvBn)GPvTrF3Cys$da`z)#-9RpY1aB~#Fl!NACjenoLy z^^xM2Vt*^P3*AGDbTTGY~8)OIT@{*KN)O0q0A+lsSJoF)6wSwOC4JGzPLV!oDCL zl%ZVR5M}b+L@D!9kQ^)^D!QdN=%=p$13{op(o;7j=|a{`(Q-ifN-Lr=;fhOh*1H$8b(~&!x+_>*Tn#4YN%Wh**tXA)5YX8uf(Ml zA=LoR(*rPoOW!_bN89apj+Hzb!bFjpTHZ*))ATS(da>JpxK5&;)?t(hPXua>NlVYp zXdGlsP#xwvWor8SjY<*nndN)5mUIcv(#0}8d$QGHa`(8hw`uT5Tsl`!9C3Bytivz^ zIt`-U98;1fBv=hmK~c&eUc&QIiA9b{T0%PIR(*Y&=CNVUacM;{H6T-Sp_$`TN}O{} z1+vaX$TeP;mB~Z8uawet>6HV4hK3EBz0QK8CI*kLpon3Ro@;rG3z|GbIvY6djZi^R zkWdQ&u$mhn5^l>RWrVDe9`zZC1$&1l;W4o#T$G8tR5Dk!VPZTs1%A2a7s5T-V~Iic zys}b+oU4y#Cyg$xLDmm4=nZs=Xk_QcP0yMS&16ibCYH)f3=1 zMWw5eQN}t)+{V@2?o(PC{9?R}-y|Kg*b6v0HMp90)I6~D@j;{Sn=E0V7)Vsxn@X6P`N*5`FWj4h z{(~R5ZemE6+Ip1BGV847dO6J2?LWVABPu6mjBAf($d$3Eq{GCZ^}+GyWAA)@zHiwf zSo1c4#b)?$zzTiCh6LyE!?F3(Z(i)UTcZ8Tf$9(s>Lz39DrxYjE_*ZbG>zBDY|$Si#Y<3>@MsW7EpfM?%VG-YR%<$u1=s18sy_T#%e)ab$A-V%<_|tP3h_a#@>q)`hvGL<$D-P2vavJh?^|e1$ zs2yJv(#a)KNXM`7Ae113oFUKp+MmJ5Al}0l_z#Lu^4K^Ar;At*@jaX{>Z#X16W;^i zNE9R+Ch0EGS`K|`mBepJx(tvCk}FPK1gbA2{75GTB70Df1)p0$>F`CYUgg?|Oo2xp zY&(4FJ$~UswNqv?$i_wFMoQ@66T=g@B>7h2;&LGBR}~JIbcXe?Wl%l&aW|7ao@@ji zBTM&jf#$bnWKr*B=_76>g24$_8&v1WjkKnreoXe*z5S8uz07{t=T>6WPpn4Fq(M9< zq$^=@_pQWSKe4;7TZzp3{Hh_G4={JRJ@R}7vd4mMC9-?atwcdqLH0s-i5CmZpqkrp z(=1#8rLx^Mb26yLC2)J281&W#z+`YUKy@XwGIHmUYz9Cn9oj(=r8$A2T<^vHT}y98 zI@PGzggTp^!_^OnB#J`~UokHmV>FHIe&YQy3 zxZC#WkfP@o5`HX#2MWu;9x!B=g2J(1DB(xb+4PcqMs$D8<|t!O4ch}{o{IoyUX-gZbExwSA2Fn!+4RU#ty_tC6wtf`rtBO6)k7QyOUkh#o00Hi zEz@kOx-&Ug*HrWzuhi@Gb%sX3x03L~x|h=cp6k8fn523d zz{D5!APTN?*R;dkV^soI_;IDKvgC~57{Dw+u@GwR9V=XoV}@4O(h(xfquz^xvPpVE zD4Nz>2W=<^HvI2>(_oky#jQm5Y9U=7qd(lIpTMSstF>Q7dRgyfRCmSA1lggT7*yYl zShcz|-%8|F3+Y-NC~d=4Z2nMGl928VZFwt^nHI0Ag-6m`tZbr^Tz8~e!Zoo4P1!0T zJXuD_BZ2C5!qvMe<|}}jV6~P5PFO;^P}s8}kX>t8i!Cvhc(O!}{v?$@akhMY-S|$s~J}#aI_pyjl2% z&=GG{*yT;Hb_C7^tJ~dOfB8#kKVtP7fIRz0DxnyU!pXv)IwNB?3rpD6QASY^KqG)* zo2tH~5{d>X(J8SkswY9fQT2tzO(Ok^W?2PRkH2PfEzX+oAR3&|hhJh=DVp)Mg!4^w zu$B3)U;;17oB&=wxjj<aS6C(7*eGQ}0Ji7?)Tc#%ZNf3_-95okH#K z1g-))ST4uEn(|G*V_iQDy0~PDS>;Io}hKemvkARPbozih75AHj6&3ZPzh026G^|I za(IfEdc(}i@%R8G24~3uVaNKE*hF|Zoj*A{`z7~*hfak7!j?(f`$ar+eYu{3)EnU| z!b6X-YslHG&xh?t%AhyBckpq4^Rp*=U8Seix|l+UIil^T|H&7(x3?cao&LDJ(-U?2 z-~hZU6U6{VuJ!`_3^XF1=MeRehRq%x{^+QE&!W@hb91fgTI`gY`lIdkgJ~vLtFzzk zc8~T+I8uopYO|wFHmB8)KhB@uTDdiUZ~9hiWoiB13We9X%`_tYjH2azAswo0oSy%3 zCRrQHC_ExBQgNW;N=d?Es}UvV zQ7mXwx%Adg6VlCIH`qz70>I>j5h@GY*2Iz2PDK$J``I=U#1GpdE{ z|EA5sjApus(FwVkyPc*^lTd+0x-?`C2wJ+RC^97Ek1wuXop$;>8K)AmOG6A?iFAc? z#JM;n5#i+2dy7b3Rdc;6qj%(06{D6Pgq2D095%CabE}IpvVA%g!i*VR*jbCft65F} z{4vruL=T=1=@$n9PKmpt3GafY6+`aqt}d=>AQ%}{hZv(5x7a)&upl>oM&gsnYwgzR zQX(I#{HI)NWqN>jF`-URx}0f&FmH8s7uUsYE(UP!RZTqbF1h?pS>W5l9ih5w?dH<_ zmX(+8$S$Q1pg2(|^x*h}88z6sf;*bMwZFME{}AcA09Nruocg2=$M zIWpMIO1!6smxSaAxRLnmtku{i97a&SV_!EjyAD`iL42MbrS2RLo$WU{^Xj(99<3WA zpxwFFz1caq&@uVci6Q-ztDw(Fp9efV zV==4d8pNCh>#8(cX!D|Hka-4Q-spB7gm4)Vhnl9gmYh(At}!BQZE9{S4Tn_s#<8GI zm!VjPsKw?;^bGjNA>Jbf>FTD6?m`bVPk8r0*ZM5lU7CWiW%D-`Js{3|km`k7^&IGx zWR4RHyFhI=Ib(1nC)tf4ax`Y1s`ZlE=Fte>28W%{ZjUua8v7B=A>3)%T-4@s2z6Rj zxhGJfU6859)=Sb^Fcd^4Gc`eEiT16*2qjB;Xddw`XOCtoiHr=kQju}Q(w$MY1leYj zhvrV7r+}zJv)$ffX&a1-H*jgTM~a$hdC?lfb$wdzgpxFgCtzM_KJFyyb{D8ZptrXZ zMB_JcOZi`#x_tG8%GeZm3^FGD?w@e0O$trsec8b z{1hPP^_sJapPgMkb9DMoh)(N`)*>5C=mHviyE2@p8(Db)z{GG->ll~H~gE9rwd8CTK^M$xHt$^8%93PR*+N8N4dL(aD z0tDE2gX|kuGL71hA;OFo zq>BInyo8E;CX#kZqZa!Y?XgR?jL~K2zNRYY@I;pj8nqT`-c=4UDP!F!P=kiVrOzN~ z7c^?2DM_#P>T5PvR&3E)A})PO8Oqw<=|7&hlxWmme@93~3tmL=72M zhgO@@!jeYK42Q_0I}CXL7-G;qNkqN2z75T>x8E4Rbt`DpjA6PddMPzO8$N9hPwJGY z!S|8d!$fD%sL6AUbl#Rhpk+R!3jjPL5%mU7%+Ua?CYB zyIv{~LUd++z;h<=$uhEIhzUa^=>tw?Av&|_G3;8qcM#5_>WOoAEq#PwE*8x21$#}< z%kp|_x1>=|x_Y70N(tYf`^40I(5N*#JhjvA3#zU1l5FiR($~tx zXQx`wsLh`mk*-{PO3&t?Wom9o#Qu<;?_VI@RAdqoM{W;j)LdVX$;s^z z$!_ONU>rjz9KMo$~ysVMt~mM|(&US+MZ;uap#+51!D2mzE1oZc;Dvy|zvCm4|)xjpDzq(2G*4|3!2o5~;NunoIQW%Cke z0O_K&Xhx`eqeXS5o1`BV`ZK%7Y>vr4pW+YkwxlenOx* zQK#Xw=}pz2Xd=x8YD4!NmsWNUsMF*Q;o}4R3-aCAiZf$VbE1$)C+1zt8TnApUywH* zh^|N{$jP)pmD<=$${nJCv9D#*MiE{vV(MBG$xCvD=9i{#r6MdEc)favx8{ZJ%rI`| z7u0EV=jCnQL1z=~WtCDo=k;qFeNm@50TwY^@Rxz17r>3xF^rmrbV2JsuEeFsjlgNk zKWAr8z`b@Ap0OIJ>Oe=bk}tI?8b=~poJ7RK&Vo0A`2J}>rI+i0!wBf+SPD{`lZU?> zA5)XN_^UfPNX88e*+jQNx!gIaqy zk6X=6@_VSc#B2N}=^z+Y-)8&Clmecb9Y7SBAa#V;M+59wPt~_u^=0NOG~K%a9XC>b zkBhp~IizoFwv_9MFmgy&evd^q1}H(qFeF%I;+CTo%mGeSOKAmZ6^PWTyU6Il2Wjv2G^%t#jU{#5(gxANB%QB_| zD}CagTH@z4s_0YL=rXyNa9c%X$yp(JQyTY<9Q{sV>MS=R$_zTsB?-0vU=W8_{2O?lA(N>9ocmL!G?;Q6VlNxoN$`BHwpqIIe!M=z@AFCKs zmDAVQ`0P6!jp7(&l`uwJZDgq2elYw+k%6zu6$ zMLm*(4i_!Q;o+B>duZzH`G6oB#Tll`NcG}!8L3{*(%Ii1;Xj+(ho{54?|sU(#OssW zq|3Ya@uPMtN2&{Dh+?#{pK@4{x?$UOT~eev7}PTtV#!-@FP3nt)CGJ>8fmgnlkg)& zs`s6RTGJ<#p{Sw4u{0;uvhIPDk?I|+sYvxT{xZj7g&9+{m#h}UPj9T;m|K{Zrsng|sS(zD$oILw`_W$L;d zpM6C>$}&>lV2Pa~{T(9JljOt(-?6;wRrRiE5a703b;puf?5Mor zNHv)Hx)2yB7G>tkZo+F1CsI$T6q!5SFKH4 zn_VPQeO>6$+YJd%-E_i5nc==-$=oJyeJ0C{B>b3FEV=9^&N>e`%3CMy(>-eLoqT}w z8%?M=i=jK>eU6h}72kC*d|t0Ba@Sn{m{(Osj;*EHWzTR~X09^CI7r(&KEeGn7wT*6 zuQ;wyMvl#yC54h-(w#KXs=R`C#NVxKlc$0aJgrEzLdnVQ@*H7zTtb1&W=ry>a9)I;-&TW7Udo>`ZXfe(@OZEPL=L?07E>5LEUWB1%xQo z?W7rqC*cR;(S1}pebXKeb{$JzX|%VlOLvK1V3UgY3j-MYaUR1k6Ko<<{cc2ibHa}# zorxT;3ZUU2jKyJ9j)^?c7H$q*CE-V*dx|A@wj4|D>|RkA+}i<80L!VJrDGXLTs_}r zh4ZnglpIVvjddmb@YL3ln+-|Q3`KhzPRT(jb?Z)Jo`_VlOJeTjZOjQ!j3|Yuhzx|Q zGK*!?oC7o&1}9NSr&k$^NN;GZqa+QQPeoFWxRMRvRP&Iogm!)Y1@ZycTgr$%IrXhH zznr4rBXMftv8+qPp~Q}(@D-B%2(e=q!Pzn)2MHFLtK{QDHqWE1wByO@As#u;WEUdI zNJn*V1-J@|WaXfCu}8JF-f43O!x`ZklH_xW8;{eoDeTOq0jX&_t*mmo%fs>rsO>Dw z7|*|nI7hMszbjkywD2Mqp(2v#TLYv6(-F)b0Ee7n-`_DNbeS6_^kasi8qg%gs8`mL zw#2A~dt`_9!NKm@awOl=zI-bNsMc_Yr`xbcI%MhcBPZ!Nw)_*{oaK$bUUP0)0vH`Z z?jH0yAMR+&VIAK<1+8}#HNc7yJMQef|5dPVcriVW9g|`eEz;1GTy=zE$E};cKitGr z(N=4=9ho|!*fF8DO~w_yof<$|U0}%wPxYl= z$gW1F5#HUYMy8o*b&XCxBhrsGYgNROFN2S594+JO3y?3_(!7y$$07%e7DuKhr{8m} zn0WglGHvjkHZX+3R`57?$2dmKwPKQSh19LP+NUkX$^Pc-N`F79kLSpA?z>84+R_!7 zzE^?LV}jD(GA4$oy3rnm37x5o!x!KKv=|J6|YaA^sTum#kP|h@P zv9Nnc=LQ{P9jFVCuDv}aoUT<%D2IW-cW2$nxz9~R?!O5rkT-%U!=g#TH?QX*z0#{l zZ}R>+{M}mr>{RG7GUsX4Wi8jpk+;el7{%04Zk<~{0@7gDk2rgtzV5Zr(l1axUZ=S@ z8BL5LtP4EqT_JN`|M6R6vs$H#S1ksxa#6etq(%AALLJIffiw%~k$^NLnl^YB=}xz_ZAo?0bY=1>)x`iHEkbbs>ByW1@S!WM97p?qv2f|@8>xMcw2+opWXNcq@eWXte|AY&%1f|~$oHUR>R^Yw*^pnQO&Dwfgl zIzW1TQ>2Wo7Se^&5x+1wy@+r{9Ax&SJL8uNw;eL6%mt9v7DM8L@_}W%3CMN_o9qco zJVAAU^wt#%C*U$WEg)^Ii(N9*RnHTe>vFe9XEF6FCc_vuLiv#Jke*?BH-I#bPcVIR zA~pf?+N#7Sd9SEGE4Rv z(WmsPR?ldjfHbi;kTZ#cu(P1NiUj%?}VaR4q6FF7pqM&jL*vo>A);4%VKr4 zxV(Bbi}riUFrzSCSeiEgLN0z=-AvNDFnhTBO2{hxx22?Nze6V*tT% zctosK@U*MrTTh5^jTOR2Xdb0vw5YZ_JQg`qC42yc!hnnunju)X76VNCyLmPJyQp}% zz;v>Rks$+y2QUqEa~xg21gJJtUjeOHx*)Y8#MT)|y;MNz1kM5eW?882IIq^&{8mW% zP0cxe*M#AhLfY#zcB*Ivr+EkheP})gOXE`T&6!(<)b+4}L8%ZmLGpmq+IfI`1Nur6 z7BT=>GMX;K2~m?wOOX1Z210?VHE}sKUaRNBLQ6Mn5u|sXRgo%3H-CAv)TUH5D)10=BSxWT`dIc)!ai#$Tzwdv2 ze)bfv;zw_pq!-%(=`P4+NIe0SBtvQm4=M?=OX+}0ji(NfS{EFNO$+hz1$s+QTU&n*R1#}mG{^4R3sfMr1ei^dr8|#yNaq9?#d`s%r*1g#t(Q-b z8n0l@vvhFc9%gxbg->5fkUCzTF9_YM+X2F1%hX6nWRLf44M|7z$btrSPzdCc{ z;K_CVFOxlNTYrNgb?ju^T#&k6fz;!KyrVVd8d4WMyP|Y88c#H`0?3RsWRM;MsuiXI zc-d#zoqLAUfq7QP#(@v$(hXTA&da=TzPAhK=Ad@}d3O*`8_4cpfQ7iriB?ElQ zt(z|rsE%~hj!pxrJwC!v#Avn}yDT89%c@w?$?2#ws7^fU4DQTyUKJNvg#fvBBgp>i zK{a{j1bdm+;!!&~ozhV+EzB1@YDRV_L+l$+?W>0Z)t`n9?W*Oai?uOXMzGf#0;WHq zbtNJuXR)CahWD}#CILc+bc1RJt~P{Q$FQ`E=(N~8u{L_*M05OT!tBe-8;9p#@u!YX z8&oTPY*1b5F33(5!)pQ!hl(G+1*l%Vu0>31W1)OVKM{;wTm*QaJD~dAf=7-1=&nV{ z9wnNy2sG9?R;Kk9ENwO422{Tt;=L{zu4O~MUh@G<47qmKfdH&`!vT<8JZhz*Ru_0d z(*Q0IKBla%Y!gMsEVRV$#HVLs>pstKyGJRD1UH99TvRrsYjM=s9oIG#TK z70nH*=~~Sc49U(){w*vsI6|aBHR4;JDO8@L(;7HVS!m~(n)eS5hexZ8gF|!&RR0jz ztLSu2M~(Dr5}u@!939vj(dlk;`$WJrr=zxM1RdqZLprb#*bAs;b3zu2=Mdj2JZf|w zWjenQ1_$=a?)Bvc(P>67JnETi!K0SvsOSzdg79XhGZU8Rw4@VTzc=gXw4#%S>`57= z*26SJr+Eyjfp_LnPnA4sEi0irorClampOSLMw^RFVVuoZ^Qg7`I;KXVLA7Gv0jjU9 zFGO_O1Gt2}2q(2mbA!mcLG=exovAUu=ycREJ6N2PGDN4zdUDj-XSGyxI>o+oI_itD zZ+f0vpu;|g{c65@rIL<%sf?@_(!21e&tE`B*JXfqof^G{kBoM zJOQigs-~kXDDR1#VXxM=G{gYajCcj7wY$2WKy`Lz>eLH7>I2qfqSJf;rgH+-2-om+ zYxQcDPRO3nwD7lJZ_{|)vsBHsGV!2GUTgq-3g5If!&?q!TW`yj(-W2|LEpH6uVx?+ zH9)mm^0-oBm>u_7N@vA$m=@64`cxKSI@@7{<_WT=UPZdlui64Z?@Fwn6nT>Ba?bVC z9I%1zJ(|M3AWki(n8d27Kp^W7s3PnxkcfC7Ft6KD3m)NWhpPnw<@)P|bVb4W3OS|j zlLV>#Tf(7&QGzU%?szq{T7&EElgz1RDGZ^Zg5U+#*83S?6DnZ-(nS9e*b``*WsbjQ zb74t&Tr*LKS=$6sARbNSSHWyvkIp|GQ^8+H+vTznI zAE#|5n5=kJp-FmZ&CT0XXz52HBaLEU1-dpWy3hm{>F=%@{DDA zyJA!qAREK@9o1e|DVh_v)~M>dicy`VBRor&c!XC#wmx5tTUTT5o^A|T;b7v{;%ocu z4YEUXb_a!Yrh+(@j$2Pe1@*++QQTUm9M(K5quRuW1;{RI$w))$)p)KUyNHUzVszY^ zWs9hI!KfB?4o39_kiGcpK=wcs6;PPGho`w_E{|}1ID_x_Jq5BgE+~{9K5u&3hgWat zoWByN;3d_JApxIyAisp?h%)5M_sWVd*^O!ByEWV@0Dme&9t04VA>Z&ioSUnEd$fROdNIqejBzN#qY85(K4!Ofwrf(BPp z5L*>r?oT;x{RF?#fdC@uc`bvo7$7(x_9N9xR0_TMREAuIwLN)5y67beiz_M)#Qv#L zCfI2kafZv3@T5#YYLs2IuGgGG zFT{s3)pb}9o4vCXtP5h_Ol8P<+q4WDU1iI>W^*aCg&jFtYHaNd2REq`-Y35W@kf?c zFRaygmDdm)5y=?L0^r)&)ZS08UcII%k_}l70(OTkL(U!O$Ru-h*r!0h-(#1{HLhrmiZsnrquf3qpFzaW_|F=o^ua{S>!eXQpxW)1|zx z1_4C(xQL!=5LBe2yaLheTh~@xC>*~;8FFI3j5AsCCFztQ$E~RhIad`OnI(mu%aE&e z)iR2w5kBEuiU}2E$cb?(g&rHr7&F!80kPToYm`9%xoLo1DMN0!#NrmS$q-vt6<3+t zg4l+@8Z%UUaf}li=}FB2@LUrm>4z^9(mVh#?s|UJFB+D~(&-)0O8@Dq=61Wz3CASe z&%>dGnkUQD^VAl^R&rV^K&sk~>aHdN%XClMo-?lL7X}oBRZB;!O#*YO1kVe7#w%+jNLdr+mU!2gJdV^7362> zwjLa6nk%m~PiQVhBzsi4TGJt2lMi zJqvG!bS@F_w}EoS&`t>2mlDyX5T3{xI(86**1bWMV-!I(Ft z1Nu-cCP`POZVN=pywTSu=I2 znxOL{PKvR_(DwE!O@_tVv0CG^c0e*_yg6|M_|Dr>wxonx`pN*uv7XCc;+P9@9WjBG zN;e6dD_*BHvHk4q?${)SRO(B*n5s@<7_jECGQ{*?J&+S=9||b+j$ix*jzl^0RMv%U zsCsE$b1w}s9Vnl4;9HSQpx-|nkT@}wb#Vp3kY3Dd?gBGAy6iw$d=GjDDmM;7L83WnJ(|lr(IT z-14BqRm$dq5olaTG-Aa`$}m~_sd7ZaU1|u=r*h+LwpLc1GY>CG^suzMKq9wH*;Mdn zmBK3kqb*-{B#MaiY#E()i&R1kSpb(D(S^T`>xfuJ!jm$BMoO_qMp@;|YYKyEq%&ZC z%~eWEcSb(d1x(U4_s~NqN7D1F3VEHLJ#BRyp>97!da)QV9=-Bc?vjz1LGkYcniKve z4PN2$G}a;F*9#JWpcsYf9MnV)7B$ihdI=V!Gd7 zgEfPy_%CB#1I`#FZ))wzIJ$p?!{Z@?b5T-7UvH=4+m7gJTuz-wYP657!5%@30Gohi!SgY z!VUR`%4j_$H0sjh(nU*xHLu{sp_&6G2S<-U(#EALrx?>aI~!0D;^@YMH_tc+t|=fg0(?62e9=3u-<#<0Hj4a*SY3 z!@JTvaJ{Vi71tf1QD3dlsBc6_Hyt{ojNVdhQRrmj{tfOUUb;x5MtrGEY#N+F^N4I9 z6d-Q~jk+B)YLD>TT!Jl~Q9XRRtJ{v{eZ)?tQ77qWpm*fw1m`$>{wf-^r%yl`2HeM3Vl0=bwI|Pt4Qa<5{{9g63sdV z$cN9_lZ~12q1aMpO$cr$>HQX|0#=vibt-%;)W^m zYDE}heV0eCD8t5trO?Vy4ZSu&=DfGkeMF;&%JdLg=Us&)EM3f;cNAZo9g&^~0fbNT ziYsG@r~w>Gz-wUrR{?TaGP+5YOm+{nz6vB~XA)$3g`+2~p*-zP=T#gjSq4iQt;0ue zvG0-elsQiwW#Chp9xP~`KY*93lx z0i2`@PoJG^ZXBF+0bY%s_#|VKrcs+v;sLCcF)V{yJUl(wQ~~ln_q+GaR(Wdz#z&@6 z2d6069q>YGlAW#X0hI=pH%Ntt?!J#0ne%io;gvC@GqC|iyIUK3eNHnQYOdKGj1L>$ z=PB7Tcy&VQPk`RKq1=efd35O8iAJqpdPTZ?2K8dLwjz|i|E`5!mCKIId5NT*UR8Kn zY!!x?27L3XRM*57jark>(piN;)c) zPJ(m~c6~yR5kN>+=#}i;8`{0I7tjd?id%PSVy9PWE{FverorwVK1rK-B-zN-laG!B zNK&tYFjXkAqt(6DdAC@|)ZEhJkRk0K*|NcfAt_9KonSY4`LbxNlGd_CWEaw-yt#5d zk!&x8(vcga554G!bnu}A^~^kixKFIHXIx47sNAMZL~0*1k(%Ul3(Z7oEUp`6e#y&1 z>VP2CU4kF-F!Gmhg;8MLG-|pT1Qm_7#4yCEjiQ`A4;Q~x+~rO06}-Q|Aq#*e$->l; zI-BE-#%rd@D76TicZ0eomK{0?2k|K{H8x9E-ii5rXe0YKPoAk7Dz@oZc_*RSkp4 zzfW_Dftx|CK$RM52FjZSV)r`+aYPOcwLi`2@}xJ9n`&$_(i5H*Q~^xW9lfI~LGDnv z(vNU8!s(1+Cu|_ZwH(0u=Vnl!AHfN;c-b1!lFm>MWekL5#v!MgV{@nAX)Yy(^3pvE zPt7ATjonY4)O6)BF{q_Xyk-)fn=5LG;rmZm?8{4u_oz~*V`@ECJvX=b;Xo`y-C-;u z(-QC27`@b8n?H5yHD{9-(<{2rM>4W6F% z;121wALC!~BYp)>|3(J2`k%JcqvFI0={M%*^R>jppbk8pbyqy1-yxLJ)Sb$&ph%Fd zRwzn7T9|YMPvhr^Mv2+8x*~vlMR;0EfR-2IX{2NJB%Qz^E*M-VpmuD4T*1=;M?7=l zRpCIw{s!^lx?xZcfg^9s=+^NNTT(M?%8Bp>j!vZR6A52Sl-zQ{yv@z*r> z3h5k)Hc9URYCP!fjpAtyOH5O-jAsV1;6oinf~N()ji+@j5$zel-t{Eu#sNnZ20!Vd zPrDDE7C{>Z^|I4wPc!%`XdPCX5buUi1Ii0eGeK_bE(%Y}G^6}%^1&T|c-Pw$d!Xc@ zSa*1)xRz*E0B{GZXI?zvt^TnpBp%~6HrEs4y}B$sy%4?XPR+Ut9MOD>D^pGIw9z`* zNyMNoFAgF;x=C@&!{I)`X3i=KJbm@58Pv8+VA3RA_EUw#x@K(PX+z$Orv=qy_at4b zJ*=H|kw=vI5bx71C{08;TbZA&;aFZvWVjc2x@~TGL*YK~^c6{` zKh>kc)7s{1$fV}XCN^qC{l%TPtU0m+^$M(ylBGCS86F8wE4F?=V|9;q>`rT>vl@mW zg@Z^7rHZM>)8$&D5fEtIxFVWsr$JD5&{7QXVxDXDYLXsU>rMG}7PF%!E2;4`=PPk7 zG0CprU6@tc&Awpllxnrh(JDnmp2ekEm$f21E%^!^LLqKxPK8OOYhJkUn@BQ0wDnOM7tIECq%g0n{0; z>+KVlB-thF&X!UzRF{0Xl2`!h_<|5$Lf$B7&bN!XodGqU=HcyiB~fz#%`;rb?Q|fm zjsR)~hR253(&|-OhcW`xH!lEc<5ELj*dDsFmRtm9S?QEa30I<%70(W3B!7ps5I-SD z=qV8UEo_zMpu*qQ1nG3(a{;p;e5|GVh%4T&l+yi{{)GT_{-X6)gPC>{d%v;EWkBzOPj`B}Sd~VK#M{&ej zWE~MHkdot>@WBk~G=uO__&M$*k}`l-U)!KO-d8K|rSDGNO8KYPHg#JO*;#k^9xM}@ zc&uBeGL2R&yJj8t>Ac+Oos#Y(84pT^f!euK4_62u>Z+=Ap-kU+gpJL8$`{0@P55xn zhIBi>B>f~&GSFt7GKQjLi11cxw)$R(@8wi zi>WOTaC%bT*gG7au*wd}s{rAH;+GIUq`SnUOd)-E0_5EVMjdnxKw**&p?OP$4?i9R zg>)(}InPJqKs%rYyf>uJh>o2IACOhFdKbDw+6t=jY)bnHt0>C!TS zytdvDIN3Ce4lJJ999zKedz5=mGGefT+en_uUfjsG=z@_ zf}>a*!pBzRpPs8uKA{K~NnB-qfb1TGbS|ULZJE&=mdVl;J#*P^8JEq5T($w&%&bd} zWA53J_5X0;cK3J4kjle8-@p&4GX}yuttI|n=lA*%gTqS20HX~G8 zjceq5Gu^; z3M^{LV@7h49xP|gXa<4^ACZlts;w|Ic_iBWb+5N+qKB~~(1-O+$d{>8YU@>z-35IK z6-R@XC!rn!IK*)I$<0lPHnu>x7#~qj(To&Z_TSs!yIS7)SNao<{*f6T!f^Q5<){~i{wj{bc$t2G|MqjNpGeMd9!M z{?!}j&sS|IUf4iD1HB5hjC>q27Q^Gl*J5}`dWe?nz;Q_#V;_x!lug2C0r@bRPI4YFv??3%K+jzFXl+M?z~9u??&I5hxz&SIVG_nGhnN$PwcR!$aaj zcUC5}&kT>EfQ!P0wv1FU#UnL0fF6iGGBK^XieDB5Q!uRBsx!DK$4_*2E`}&XCwfg3c;$pv7|K!n*|D>i*B)OJ#>Hqxk z=EwS;D?i>W-hF=L-Q$D*$@b9x2n;&o1@Bfp3^2rDKgG;sF{SR*PKlLl? z{P9n&{DV3YuiU=>=bN9@`NXBpk3ar%O`z{Jf9!7)%B`O%+o zG(P?#e*TD`e~^BsyZvW3`CXs=Px<+fAGQ49|2LHNN`|tn5TJ3+t4&VGw zwc5Y^Uaj`OZ`Nx6_rI*w{@=e<8@v3lHukswhuYZReH&^>qc(Q^v^Mq!zf&8#y;>W) z_utmW{^9>s8~f8+wXxl&wXuKtztzV6*<5Yxs9ziV7ynCb?7w-ZHuj=f8~dOC)&B>{ CoXE)l literal 0 HcmV?d00001 diff --git a/Houses/Empty House b/Houses/Empty House new file mode 100755 index 0000000000000000000000000000000000000000..31099892460a9e79b1c7e88da9a611260c191f5f GIT binary patch literal 13046 zcmeI2U1(fI6vxlm-Q-GigILfY(T)h>M?Tz2DN0Gw)|4VtY}$$yQ`v6rcGqn7F8A(M zQ^X1u{6Yj@tZyxS^TkI&MYJz{lURdd+cbWaiiiq|6l{&>%-qk}o2E(L%*^fXo|&C{ zoBP{y|8wTdWB{PA@ZhiX0Wbo)-`Z2DdV>BH>%yLDG^a(yX?ga55c`~#C{b&NUyphoC997SgP4x-f>04tsb^LI(uhvl6r`e)0h@cna-g9 zLS8vvtWSutZP!HEwQbRKM7dh4@s(SR0r^+0=&kdyYW=yEyX_w;e>y>V3j=<>E}{KJap9d~lz=HqX}PamAh6}tNq zrCY0?(&`zl4qAPkR-e=AU0VGWt*&4Hx8(y^{uxN8yg&YK4|K!c)Uz|(%Dt%Eo!?t; zR+}|@LX0`i)D_uieYgJd@RcL~$_iRD^oiOrLTx$NMX&GaxdcSmL@iY0PmfrDU6@BI z^i=_0ls5mAy^vRZ78a<_=AfPW%)lIXr#`R2qw-Qn_80IG%;JxH4!na;0Cdp>*@jAJ ze~h1n_AH;N`d|;<3YYkAqyD`x0ayL@+wl>Y_w7ME2}1S3K|B=M@K4Mhj@j!X8*hnh zn2FgZlzm-nb+QOs=oYdGw#?Is@oXwvGMt64eQt)W?zio1w-Vc=-!j{MF}8<&djt8* zoq?|!zircmBwLI0VOuKOai3=adT}_?2W-f8qX`5}V|zZKwK-t6M2B%#(E>&;*Wo3|qt{V=%D3B#ue1&2UWX#|dZs_?E}7 z$7AEyQ8j*%EEM29GnS>!9hhyBERx4Y@om7C=LoO*aRT#vI^ap|MibKYHk~cUw`%SX zXX_faG`3(aG-*SB0A?IZQTb?7Vk2C?EResBw5cn;yZfsY5Wc;wE=Db9V ziWY-?MNLUn$j0>cqOZ5i_O2M){V}$Kfj+F|c^Q*UVVfjtks3sL`;E_*HTIzx&;EdC zvL zRD9d1_7;{G-46!VIno3*g5^kQX@3IwEBkF0#^5&ilPQz4@|tfAPP5-aAMM@h;&zaJ z8|21i3~X|Y@f;(w<+%fMWyTgUQ|r7s+rQwf(gd^4%l?*}^QP=$1nUg3jUUXGW3Vhd z2{*w}xGepabK{dTf2eY~6=h3bHT%I9TZ=ry&vxPfnH$d~*z#J~4%XlWMqR+yBhGLv z$l0#tHJuc{#f07}-31xnvfhSqg4|bAq5K8wEo-j_-;!6W`*01xH0B literal 0 HcmV?d00001 diff --git a/Houses/Fun House b/Houses/Fun House new file mode 100755 index 0000000000000000000000000000000000000000..7cdaa651ddf1196f1c59ed8e5fc716f253ebb539 GIT binary patch literal 15830 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 literal 0 HcmV?d00001 diff --git a/Houses/Grand Prix b/Houses/Grand Prix new file mode 100755 index 0000000000000000000000000000000000000000..7ef1328521ac68ed19c0e6e7613479308eb418de GIT binary patch literal 61766 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 TWdR`wt}*KL4Pcxb0~r55EVvpqiAIyy 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 literal 0 HcmV?d00001 diff --git a/Houses/ImagineHouse PRO II.mov b/Houses/ImagineHouse PRO II.mov new file mode 100755 index 0000000000000000000000000000000000000000..9ba10f64e99bbb57015fd7323fbac2c465fc2e16 GIT binary patch literal 30707 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 Sf1&qT`dKUrMP)zo8U7z_+DhmE literal 0 HcmV?d00001 diff --git a/Houses/In The Mirror b/Houses/In The Mirror new file mode 100755 index 0000000000000000000000000000000000000000..9ce0f87f8c7db83ce1080afb47d8f029faf6c2bf GIT binary patch literal 34622 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 literal 0 HcmV?d00001 diff --git a/Houses/Land of Illusion b/Houses/Land of Illusion new file mode 100755 index 0000000000000000000000000000000000000000..751b199d8f43f219bada8d158a2d95dce59a6f72 GIT binary patch literal 106310 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 SxsAqU+0qGlk$pQ5x&8lGzSD64 literal 0 HcmV?d00001 diff --git a/Houses/Land of Illusion.mov b/Houses/Land of Illusion.mov new file mode 100755 index 0000000000000000000000000000000000000000..7c35d47268d7a71956fa88d00fa527df83612549 GIT binary patch literal 16016 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�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
    #S~9_S>C! z4f?X^PI`ujR{if>*#jI?cF5m?9m3xNEkcb0bJ%0rPpw<6KgzxC@ITGb*bh5JZ;F;z z$~#~QaF#tk^2@~AqTFr=54J-(p|r@`{^;9*%iB6Lt5R$>zs*?96NqSU+<1xcR$;3i z-1wgE=j@&_$Niq!&_r+N_zxL;F9$Le6ni(5`6NA z9^A6>Y&Kqp#Y+@S&%Wu6Pv!i$o!565c2qW#rc`=qs<~xlcBB2%$1jubAnwLL@!oLK z36=N``zzKr=_)?GjVZbOj%@q)*uF*b9Y*?jzLuD*?EjJeP0&k?9z&OLbH2>^44c^}^;2%}uD=#l#bUh(=46^o@h{jWH^7rikJ|!{ie)G@nB8-dG~< z)MRW7lKLZLn0OiZ@d@n7waj9+qsfmwiuXk*NKN_6Kwt6#bPzo zoHn;dZD1H9-WNBwZfz%Q9S18j-o~+-LNP|I_3v=^+Vj4g48sp&{^(hz+99qzxyZfX zzl?lKhrE{z&d2fZK=SWSv6_J=q}tOnTi5|=oBFm;-a&F(WpS`=@%CtUoAGu9QhsZ| z=Zm+e2HsY?)5(ji7C(tE)Pa3I-DLPu_o%;}IX|)S&(JyG8S)U0x|27Pr#RhhG5QX$ zkk9yfqqn#T#4D7?8AIpd@AHgEw@;#;ns|;qI~k&IkJYV>X)^KGC-e*MLosb@(`#HS zJ-n|@*jjG4)(Ius(FvnmEj0_>tZcg89-UByh59sVTY8|8tT}ZvcD<7GLOLOX)_AV& zG|kx+bwbs$<_<&O&TC(l&U7?qGnu~nRx!q&PM2|vQF1$|SBz2mmb9PgTjd(+Li|wq zg=y|wli?~Ni08Qv%1m&ph$DW4clbuF*`HM7Jh8b_E96OFNWN-$%(2w%eVFy`S*C5I zAHe6_Q6!mTKJNmt@xk-c9bM^kCX;S&&#o_sSt?{FC;>d6mu+yM_!M|6oJ@nb3EyNh oT;VH?R=?10DHF!EXWSq1_K3VN?4zMQGLU!ese$g@rF*pge_5ZSBLDyZ literal 0 HcmV?d00001 diff --git a/Houses/Leviathan.mov b/Houses/Leviathan.mov new file mode 100755 index 0000000000000000000000000000000000000000..3696a07901b60ea20b00de2377326fc9cb6adf2b GIT binary patch literal 65920 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 kYp7?ndH|(6=m}SIWsC0qhfIpYC>0<0k|bx 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 Y4y@y%;IOcB7x$$0yd@(D|5=&%|KL266#xJL literal 0 HcmV?d00001 diff --git a/Houses/Metropolis b/Houses/Metropolis new file mode 100755 index 0000000000000000000000000000000000000000..c07b589797a6308c806af46773d2b17b9456f931 GIT binary patch literal 45062 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 LIhpUF_o4rPIGtUY literal 0 HcmV?d00001 diff --git a/Houses/Nemo's Market b/Houses/Nemo's Market new file mode 100755 index 0000000000000000000000000000000000000000..0be74e7b381f318e434fc25137cc214859de4779 GIT binary patch literal 44018 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 literal 0 HcmV?d00001 diff --git a/Houses/Nemo's Market.mov b/Houses/Nemo's Market.mov new file mode 100755 index 0000000000000000000000000000000000000000..388576550060ade80106eda3e13f1c9820eaa92a GIT binary patch literal 28541 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 literal 0 HcmV?d00001 diff --git a/Houses/Rainbow's End b/Houses/Rainbow's End new file mode 100755 index 0000000000000000000000000000000000000000..c58fafc87c0b0730a82cf5b111c77c7a4bd0fbee GIT binary patch literal 78470 zcmeI531C#!_5bfp0!c{1zDkrAK!YqQxK^!!fC1|csMy+SAOnen3{Cq0@v)yxZ zoO7c`pYKaN)rq{+2 zv7lPNGvf=I#*W)0m|tJrTs^Zs79`^Fd5s$dB|*lks*aJGYGXk(c3G=W)p2q>UK7+W zm^C-p$bJ}l?AWbV9kp%0k`cA>1&y)xPIE&$0lw)=x+E`Y!vl4CiC9H2VbhY5ovWMe zY-h#mUY7RM#)6Zf-1#B^o!3tD&6pZiqM0zq%=CoFAK2 zS6#nR;GB0o!FMgbzTmZ%hU?W%N>7^+fO}sm-*Ax<+&g7L9ScGI3xWQ-JJKL-TQtEpQM-j&GVpj`~0}D zkKM|T!#+k|o}~T8{$lqB&x`iA-BtQt2kkd@uety-q*r9nXJycbWYD{3&^Z}&U7Ge& zGU(rD&!zirg#RX+c~f5=BA?sfkZxI6D$i`&JY<__>T@GYa<&i*1kula8B zZMW(11+!{v;)@!}m@h+Y8(U$U{|uMhg3(xfs_mQ4! z@cE}Z)c12sIj+V1+nwdtbvKLlMQ&F=$nDQqMfBOo-4Mxv>z(-Y%r9~oDx|*<{oR%c zz4m4zuCEVvi6I6Mw~hQsW4qH{Kq+k}L>6Jnk8s|Owr=i7SMJyMef*Dk2kp-HecV&f zTk^}xF!z2e_uvyj4(pEfm-rIHznA+HvUG(XNXK$_o_j|}&`D#qFy@WCJ=~Z2dA{6B zmN)nje(&I44I_=@tL5#7~o6@C}(F8{?VZO@^#W^992E>zd1YOpGTIbv2sK;)%Ki^IBu8>&kyL zg=!Mt94BnMxpA&k*OkQ6y^N+HfOdCz{+DjNVWPS0%t$6{F5AhW+|WnuOPuQ-(QY5z zEZX5!H^i5Ny>nY|SD7D?6;5OFtv06dLwZ^S05mPainzes_yTfj=Kiwcp|6eiJ)Zvf`eoeHfg0 zJbi`pUdW&Q{S2eG5w6krh3;`*>8{Xir1y=Q1qM9Z)pI^~xF((veHY{SBXtCwO5F3z zyKsDgcsq~tDF|s~dy^{^ZTD*}=v~OA6`aFHI*0C)v3MplG^2nu)HGJKk8NvY^SPGs zoOCb4D$g*{wJe9@!fQDYS^By=#PkQ@bF{nEu5kjo7V=|Ix8fYPxgYH>fG+IskPeG{ zgO24j!TmVw(^cPam9J*LyPWoc?im+Dx>rH3=PritpD{gH^yScR&_2g~ZhiB>vjMLE zO(>JWuLgaOhk$l;50gpg9`w1?pO}>4$mg|#ZR)%7tKu+jO+|d(R0QrSe2W%u)=r3S zmz3N^vSM-eaof9(+_Sz1?~Zia_+Pkx`4!NT6@$_|><9aea#a&~I`s?=LL$879`W_i>$s==Pq>m}jeg4A$Futhbg}R5mvJw6xtU1n58bZ~ ztC8*|o@8FMxA+a+Eq=Uvl9{u`k8)!ee~Qt=-6eh;PkkQkn=$iMqLbt?W)GLc{nD5% zei%rPb^E!zZ-bstG*#ZAiS_YWa~tFJ^|4t^b@7HT+`7eP8S8rUp9a$|rYq!eE&6eW zZGSg{`MN5U1n2{gxDm+DqxiJM^>eqmVJ6e^-I;Er-_H9S@5Q~- zx*Pq7h*lqF`eZw@C8X)^9*AiAXb!bLQ(X^czK|~APc`xdk%|=U<*#+e8Rk`t32zTL zuuBf|`8M=MUCrp8Fd=yll(`8T}Vz^gn?9 z3$1@0PtYsY-?{buK%SBC*eZ9Xze%#ax8(V6q&p8P>?65-h+ofL<9|lCS?)98Z?9VT zLC>OIF*n>v!`JI5x22zi&3G{MFt5k=6)m3>@ujJm&@N{K03l8EZq!w z+nR5geNxB@VcBI9Xe(g!pSZt6>Dr~=j)`QfRwd^8eZjSz)WYFTQQyDY~Z|&IP!`+~)31cbf0cCoM?GXWgF6 zb9uDigH5%ryP9_4k7jK8ux#YXUU)kCjK}A2fOK5wL)`}M2J3$eckd}Qvd^r216R-8 z(Kt)69>$=1TxRVT@Vzg=e>(Oaw1d}doEB!e*W7N*E68W}AX4mQbUI|Xn~a{kKeTM~ zZQb+kN6ZE4vyAh74vSoN`Z6r?=X_2?-{+oVtS)XER?>ldkFIwVv&CbO(l?I6dT(;I z9HncY2%qncEX(UvSzlc{I!OP&5q4Q?zI~c+&ioO!^3@bbx5uyI`d@+YndZ*LXTXc^ z8th(jSNhGFksQ)+xIfnqGM*gHamjOApLtJ`Tm2WgUcT1%!kG5zkDh9N3HUIB{_gQ@ zx1HjM*@^Xa^JccEgK_PVKOre^#kV=exB140%tywDk^@0R7rMv%e0R0+q~!4HCKEi~ zw>~_-uch?fkWkLxK#aQg18196Iy4WiEEtj7E z2s2rzfrbCee=C_#0=JbgGxWpLWjd|jI>J`EWjT60u$is;pll7^^l@cK+=R{jqukl{ zeAn=7E_4^6|KqQukM6}t_nIBMfx80PqL)WbT;WcP=xx(HY&LQe-}XyBi{TwU$+}Ap zU(NIG2E~g*`s5^yEc%*!xB03+-ur zG)?(w9rB77_-L-wTwH{#klgqqn9C=i_8rw;Y_!`!G+!pa0n_%NqTI0kP|;n({)cC@ zBiRQP6@~qO6pg84>2KrfyE19|SpO3DfZq!ZPB*LsnK_hS(N)|nbgDr`7(Z3$Q`Vme z<5;%~GW%$gpGQLva+lckHQ-y`GqUwYxmtfJmkV#$9NJFYp=4sBxv{CbKA4!OKBzh3 zTP`=U$Mp9J)4=2d%Y}a>-*e4ZBa>>Zn-l2(GhDHJuu0y-S0LTMW5*Y&)#QNe_~j8j z#{D1M%8Nc@@Ozz?rX>@seH2=k+BIK5Tf68n=ocGAeYjuDJ8s|w1;`NW)^CxXP*|0S zHP!|b>Jo`y+`M-6+qUtt9I)M1SH^R9vh;0?H9dDH%eIo;YVFLKh!D}Im~YnZFNmRk zhQ1NE4)i(^Jq|jE=pFsPQgke%{h*BYQ!?6@WwfvGFQ<-uI)h%Brm+oE--WK%KD}0a z3xyNwW7Q2Iwqw64wt0qaj^bhfRf%Uo-UYqNvA>pPv2}rf>AFi?z}6+qc4(Jxp9eEV zb8=x&*}nPwFTS;yBY!G$cmtk#ZpZr1BYw{EtuL5>iZDOk*wikzkG#)Q{yfmN#a8-l zw~$x$c14aETZQz&VTIQeJ5l>!89U};@nusv--b{KVemQo2Tf(DtvoCajSphy%7&T zjE(drc8%!2xoh3Kc&= z(Z^ElXjsX1PKCRN8bY5x<2n1g?0M*$@OL~VUoG@Y%>BrA8}oTT%k>NC&Xu?Qr&ib0 z#e-?J)wAYq9gKy4tLo$NWPU;rz_;?2q&2Y6pD>ZO{8ll?t>`pg*TF?%+qR1JJRJF8 z>wGtFI*6w;e0>W35vF}tMy#@w5ozS`Oxnro1J=UFaZgV5izE6ycWNk$zCL}Gb4cYL zK>ykQ)cwUDD1Ro=lvoLmEHf1pE!wj&E=RR`qoC!IwC}oe|Rb z5Bs=Z5lKD6{8@eQn2y4;xC_IM;JF(v4UzHt5ZyS){Uz$N3-ta*55=d-nAT?)&tp=b zT%V|GB5d#ATqeG4JC{l6+Qffme08$)?*DZitb^E2%3_NwT0=fq!5$4Yu|!RLj_C=? zSW0Dn1d&X5S{$DF`r>o^cf61@r@4 zzufEjGn(`K9_HHh*mXfuuJ83D7A$0Xn58VDG2&1n88WAUdfh7#-;et@OYpX+424Q+fjZQ+fh) zN>9LYzm-n{`69U2i_jeZ;HQaa)=tc~+g`CcvaAU@%-&P3@#e<1I#|&SkjbRgLnBeLAnt3TD@z;*Rdp`SGuEpvC;ech0wWYovRtq` z34hTQWC!4J1ew8#&2cTG@V%Tu8-A6vOfWg{Kjly8p61*7SW{yxR+h=Py6y0-WJ2bz zvWJK$wBp;4uU0xVH$2_ID z-fO;dUGEt5(toSb=qE$JH*^J&rw3eMzSf~&P!RPgCQ|e~&$eOWzH@%CUK4BU=8Z}I zmuSPcLEs$N%0H9DHpF=XSKqZ2-)73&5qK8z$X3>C81bF1BEWD%+Fz8{ftUFc%oi~b zx$%MvtW`4Pd*fs5GP$~Oe%Y7!!F>MnTyPc-Z9d_XbaRV^Q+iEUBt*R?^4B>co6P>Fwoyw1@3@ z(CG}>3+{iG0%Z)b7k4IKq$MY}id42BCi~JRD zm$-fL8{DIO6{9cApr@qhT725QnCop0h2AKlJ@m+sc27c&i|Fe!+K+>_W0Ad`>KpH% zT_yzE+Pv~PjP;*pZC>=lKz!0cY-N|V#Ww3t08g_!B5eD}YLFi+*r9=SI@L{0*bgqb zzAOlcp+5(TZP%9x+dO;52a+SJhkOWmCd43!NJ?LN-@i*%J~4SoW;d;HEq}K!M9pprZtf1ALZ4EZwtWIVT1G1b#X0s;;DrUF$A|Bd^7~hp$8dP z(k#H%za6dV(;Bqp;DdZ7U!Yl67>(22{}%n8$qYlH|RC`#=Gqdvj#iI5_4kYEVZjAJOih;^^FVLqE*(HT?Zcs+)dr7iq8ysxQio> zwvWS>8uW0EtwD2JL_YJ)$TJ_M_HeEzD|5Z**kAZ+a$Ni6ImYSgE`5pcc%jwWYk1tLK;1+WK%&WzGcwp_{*op^&agg!6eX zKUiO4VjqyL_^IEPcXNrw0HyI>EnbwHA{rb#x#j*A-YW+N-nAT@D@xx1f`dCH4>q%r>-(eucvPv-K)$a4XI>%%$t!#D?`rg%1Q_AR_uzjEZqI#C}T zdw)ceKgn|vt}!g-{P*J6ZTM_Gce}riW8Z_O-5(x}+2DTer-ZqhCO6v2pW*(dj)hJg zTfB4KtONpKL2O~XabCOrTVWfnFcZ4^b@qf8w#vybA(wvN=$xk_8UIBu;j=$$bMbHG zi{2i)bs!j?M{W`{_XV0;rS?-J8vD;zxF<}%RUYZh(rLZ;v&tKLMN#hECM0?gl!e)HyQg;Z~qU)T&c(2=sA-4Cr%Q*eK zaGi9dKWygqQ~vvaekckpJlB6>mU@hFTUfvFXZ&4S8`46q{*^q#_Zj^#J)Xnj%R}~7 zD{?>RVR*j9J&)(?4R^Qoc?FN=`|cW}U+1%r-8n{o#M6+Ed}d7k{)&9d-&*@M=qlilYBLyNBp z?Ru3j{Rf`SJN%|DuOl%X5EQn0PO~u`_;Yn~xVwCelktBwSRIu_b1VOC5Ww{EXNA^7 zE@IO}r*UI3F`RTxLU*3EQul%$HT;Vk^L(x}dH{F%V)#L$978<%D&9W|-Qs@Fb9WVd zARhQX=DrJwJ%~OXj=msV>%^+vYvC&O8HGH!p5v6q*v$I77oa5v$Z1r*iD>Tiw@PQ| zAm47StI6^$a_~#|wjy!inR zWHvv>ooe~vnX#U<|F!_V;wmKf+vqj2f1knf53LZzfX>ru31N$dP();VIDLv4vx+sq z!n}yPi2Wgw7_uU8BvM-Y&2G81tIw@kLudUPnBDI#=bPvQ?e9v`-18&L`=;8j3fq~F zGJUygCAYbCuHB}D)7#CpBlwc~5z-U6@*?b;9sLndI{&HsH$I{>*Lq~G%~uZpMALzF z$XI{2Yy_~<8lPCCr&XcDfZIA}(B2L1&&SuJKE0{vk?-pKZ~2ZoeBoi7NHRZ3+kE|X z`C<6pHTn};V>^z#ns%`jvWiFQSH2oy+YLN(QtL;wE^lmvk8oR`yp1Go_Dp{vDe@oe z#OZ&a);CjPX0r?r!Zu|AY8TvrB--20l=-SEBt zov&tlYU{C3hehc4YTC7VwRR7aHT9dv#R}WL*b8|`#PHgO@aG-;29lGbu&g%YZ@BJb zAHM~(czX<}q6wR1MYhB4Y z@cd@o!ZkkYi^dnE^+DH(#%58U^F$ZP&ZEw))bVQpZW zYd*#-wrlW>caU!t)5&7H25dW+BdWMVTWquS6WYiG#d*p37_-ZQSrh3=Uz0rzx$~_n)+;a(>{?H z?mi?rRN$vskKCj@{DATR&GS8-@`f~K1M9R-4Pyl6Yg!T7=|+DS@@gg}>gETPY+k|& zsP=s|ZELS7zfgABK>S?2@LT;$^=d@>eca2InWUj%ygVH9C5zoG;yxbZUeY?&=(}FRVV|Ot?dqcyD$%*U zM2eMirD`}gH{fY}wkaCFZi?pIQZ&Bb6pbS{MdSNT(VS{LlEFkP#w{*qDquo1Gdt^x^uPnz`GAx-AQosC$Z*> z;VtKRZ?~D@wxO-t{nYqyed3CJIa1dl8=M-r+o|eAJeNfPCa!)ls~HR>&ZZY<{B6K{b*w#i}`l$ zx~F~Ek>)Pdm*acyB(rU-=;GvcfT^(UYI_i1R~pZBV@=+5ZmIDkv^zgqTT$b7q@H!yrw%WS<}r+D z`0)hG8DpJ`$;0nq4XY0E?PpoOHGWuw4%Q)TKh0v>iP&ashp({SA*q8+sIN}UTb< z=H5z2kgkyb#b+r!p(iVrLRnhk%kYuTlnRj26V5?T$kYL3Up!^@g<|OH$GUaaN=Rpz zkIrxce~0-#)AZj{^eooQc2yr9-Ras_Wx(R-=Q3*rs)`PYv5*^xK~7GRF%XRD10y7jK2_*=?|uk2mI~*nC&w z`}&!_XGk-|=6+-f=f+4k8;aGF#C9mF&eQb2QuJKbv27Wi1K0JAt!=fr8-M#P$##70 z-vG|tBWx$t&8cH6g7#xNZTU8=hS1%xl|3YE<%=E$|NO3t`NrYlnBm-(Z=Y?&x8*53 z4~Y1-jB3uCL}Qj=kECd-<|gSHR)`Wdu`nI6RT&lUt~tzk06NR4oNL6v>iS+zSUkuv;EJay^4+^4p!tI z_7l0}b*OcD5xL7xK+6xXkKw7<$2`A3ZHgmgVxGJ&=klN{?lX_w;dEm{xiP}~7VXcC!u7>!vXFiOu&mh)srrKFWoTN2sNRMXa z?~4&##hT5>DA}NWv!OLkM7PMNVKg|nc@Yj=BP;Cf8at#Xd}20l)^_L&9qi*Qww;>#$7N0#k z7HdzxO~xH8zXn}ge4B6j7>7v+GKchwuq{YtmjC5M*w|`_ko<10i)_4W+FCD#* z9e47mccWuxvo`&(a2&?Yps}aE!*Pdh)8^OLH3i$Vr}XO9?uGeas-^-E^5Am)6QIMm z!=ct3>g}=%gq8dQSFvt!7yedYF>FRn=DFQOk09p@I$T$4wU6eKPj!Op>Hm*?(66IE zG&=f^-AriN6xg$a=90%%0mV2Lo2a0I8{wZYJjP- z^%d5q8+D2HwRPySxgPUB;aB`DAI?;2=Zc<-ujBk^9BAT;$uZv`18t?3t+$x!NI&NZ zINRvku&v&7E1{2JFZ&$w&(=5kdMvXy$%)gN);zy1F;H)CZ~rF`Cl?|WQx z2e$B9uFcpXyX*^Fhn}6w)-ab9Q)8*RNxMZh#aJudX7A%5Ncj^&iEHwfJ1)L0R!k@5 zGm*UgiOE$(fN!8;S|B!rKX1_v*v6Cn;lmC580{g%PM+_&L!oaq`bNfDNrYGJhf)XZ zPt;RU4b1(CkMm+6#w73bH#R26`kTlNAUo3J&(Fy$B?8Iwcp02{J9|yZKXVFM$9)_+Ew65jeIhKBnX0h21Sh&*FZB?IZA$ zC&$^)<*@&peHRgtcU@&v%l)@_Jn6$a!4hWdG!3D(Yi@gFM} zqF^cgr;*#UyZJdQkTF4|pV+;#dA*0@L%WU05y$|>{W=Gd zKCgo6N7x6VPo(DX$Ns@^j{Y{)t>Sr1om;nw_3>GAty&FsS$p+rtloIqdI)P+3EP42 z(jNXycYxUsqD!GS;1g(~A_u6R5%ey+JAg=s=U$}ilN;s{&d|a$!cg_eKk{#LYzZ~i zrbl~ALHkqLGf{kAK(*y{OuiZI?=_mb{q#S@_T~ubzqv8iU&r=$n@04n{T|UcEj%xe zvMbl?oZC=#Xa6hT$<5a}vnSF4{s814?Vj_t_Mz{bZ{aG*l$_AUHTczm-g2iBTjMBo(wvyZi}y_E*4T%2p5`KE`v- zSApcoT5Hoo-wUmpx7s}2Xuh{l^e9%9$u?5#Y>3|kt+Z0t#(jTJ*P^vc(7y@u=xkq@ zt5}<+m)all=cMSLWc2w~?IGJkHClJ8uWk;*kyH%KoXeD?7}XY*)e!y)+sS;;hZ(kC zxQ{IOs2=k1{6Zq@`lDTqQ>}Gqb|poIzK?8F4c-l-KEvG9RQ_QDdC)tS_cq?BAf`Fq z1%vNE=9J<4N%D;N{1C=ObHP@lbhhcOud9iT4kp$&*TnYYOY{O;XzorBKvlyWgEj`2L6^Y z>JPXj$k$)M$*7#rw^CCrFnS^Rc>7RoS$&4GUNU-i?7obS_UbJK=Oy?G{>)GfNRpx? z<|t5kZe;1(Jbl7>JUE9K)-c}Y+zG>nwuCzbdI&qHQBxX?NayeZ+9EX^bUtK_JQAHx z2^QkHqVv>$spsBB_rh^6HnV$CLfze4qdq0rn=fgf1^Sn;$8wRb5qgX-^y~0Fx~?72 z;csLz`r{X_|73hM)xl);DVkneO);xQbxpHs%f=t%_M>mWFW8D>!k1(FgJF!S|wZQ+09{Mirko~RBf zxL-d;11(>754f=c8GeWx2A)O2*&iF>EXb3WfP@ zjKn(79N&LZyrCRO#jwGYSOTt{#Jb)HTY(FKo^Nu!?E1n-s#7Y=!ai}H@d;_(qrdLU5NxbN zpf#5GXE}R)-UnUE`5fcsm}~)m{EzqWY|F=ckj~kBzsDf0PQgn11MLm&;MDmy_))$j z1J8;yp8pNDgDTlWcEZAVU5z2TbBx3#RNX{lS#`oma3rx6y27;!|0_F4>v=24!9OzP zqn;@r_29esq%F2vMc58uH_7EZ{knGHx!g~PaHs~)Ig%-c&v-np!fGfQ@`wBtwxzBb zU2Bd#ccoTG|6bi9Fj<(A6&lkqW)bZR;kQRMFPOfO+C!H4D7A+yyq9S^WYTM;{%zsT z)p%-@Fs_<`ZEarNFZfn?rZrrNPRbt6_ z0>3}(JCcJNT#+v-?`QW&^sylg&d0#pyzCiY>(~~Dw!`%JB5dDPvE_TgR>%s`Pzw{^ z3fqCL_){1ru@#2SjV>LPD-3@Q$0xC3)&ZXoD+kVtqi6hRp7%{E*691Nn_uwC(^6gNzY@38 z^B@^@8gfC;h3LWPTcU@dJv_nZqN&{K1HN)}7p>nvICYIx$Xm6K>ZLv#`QM4|sbhbi z)Efs(j+@yaQ5(6$OeBOdA>imp-b&`Gs<8GU$TOLc-wIpV4qGuf>OlpQ6b@W3*Z4wo zjrVemFPaQh|0$l;4)jm^aJs@vsePrPQ~OGbCKALEJTu>CntLsC{V0Aop#YhFvrXJNP;d_tKVPw8^RJ5oABDR*>7WaT0BEntQ4GcG`! zNN&H$aqszxsC^ywt5bUcv5X&MXX;G}_j*tFGou^u@h8u-fn(G3!O3ee9eAk=bYJqP zQ?6!ue115Ywbc^>`oOoLL`eUiXV_}5`Ls-s91#D6*WP*#0tcJZHP;Md*Vz$V%Mkqh zy^$4L8m&3##b^$?m%QZ{u|Cx28vKVZ_>02+Y?nvBdmmv z_IJP+kps;$`*1Q>-{|3CALwsf-WIY1y_OBp8*9I0F4O5sKS=)M8n)UmGL3DBr+kba zEFJ)pv(3*RVjJ?a^s61g_E5$f0&gat>qWHh=cZWy;bd!!OX2gK))NL#!XlI1D{swa zEIh>|3-*pRRq%2y*f&EaB$1V#@FT8%6&(y-EsS{eMffWzA0!9<8OeeB$i{iW;y+Dp zf?po`X)~VFF7VqcdcyNQ$(2s^DeESnbD;5m;or^s#ETxSxNY7irgvQv_E$STwo8)z zSvB;4XdCBEJRi`?W%~N;vYr#!ch5vYRrt4+o)82;_;+xWmLMSHO8_>Ls`wq5H;=Zs zs%M_+2|wDr!}&jqbbC`SJ?Ot-A-$`$yU-62Z+(M3xeW)uF1r0$M&IS;q9?s(^!G-; z?NwDr=sd%6$lOoI8Mev#x5*uP^;a{N@Jaa+q3?HFu`=e5)}F@XXvVRW#n z>08#YT5R(S+ksg1g?RrrvAJ7xfmZV~m(3)*<#|a}qr1Y(+#~2E*u=wpfL^6KDlf4o z7sv9_J=z%EBDB9&Qm>}BVr-Jb{$=tQl!K9>J7J@}&fXl|OlMxgIL_xv=4u>2T(w7{ z`}<}F{pS?z{ep-Gmf%&`1`SSr{3S@M-w~T%&*(Ss`4-z6OU~I%_W?dN_4x?j{s7w_ zQ`fRD*Ycd&*&FBzcx+>%OXxMqH{+I`Qr$2|n%AxinpX9LiEk~=D_blbM^|=`Wbh2v zjR*!Wa8um8fJ%PLd0WPno||gd=MxA?TyggBKq_U`cH0Vs{Oe%jbA6#&iBp=`*1Jx`d0eEI#^p+d>iK8 z!+TQ8>>6{(srbz3lO-!6yXh474jpPNufX|NBtZ&fPkrz6!8(ZTlf6oagupxm3Kp&i-{x9#j;x9a(^M0>GFU}Y_dcr=M?NN-OYd5j=^F_i4G z0<1owUf5ioT%e21r>J&liyMe$EeZ8`-uAb1h}M<-kW~>AjlKgv2c z&ti5(evcIsqOZiC_5t}xqH8TPFW2a&Tn~<&Z}eYT<*?G%8GWZe-@PC0FZsAX0b04! zoF{RJz|OOTwU~q452O>)wgYD~-mWFXzP1=m2lHzBOp3=7%E#Y2NNs#vA6po!4>sjQ zWS8YX20`d4^`n(K!nWA0Zja;rv8Yjc31M;+^-3p`zbMSLZ*QYJ(`fB?JW0AR%KuC} z2>q#dk0n7Qv6Q%NIWZfpKXrbn`;q1MHjpzjrd%Ed@&x<{e^HoIgiY7v@q8$D!%(xl zW?A|`KaDRUh;-?dY5MD1r;~wgYUAS&+i}ECSA%ViVcU%i(Y(~X7H-=ZhT%TZN!+w2 zGF}_QP&gkM;apCfS4M}h>QB`5E&l`a-1H|u>n(1>CVbSNyo|S~|0NpC@#mDgADC_O zuKP!LEPR#Oz9Nm`H;--i$_0rA`D!W`G}gu%S@F=k>N@mvzEVhO=LpAIMD1tsjyt@& z@KKGUhr;Wns%m#6&OgPf&?V&AhI9+QtBuGP+<|-2LWFf9Pvp-;gYCA|$K1>4&)LbW z*i~Ae0&>&);}^F6{uV#TKN+_Bi^(;;-RNR}GId`sGdjngNzUXSM7uBi^?dikM!)Yb zz&UoS(eIJbkV`Z<&kb-7vd8fzzLN81FLzc{JgD_)(RCeWF{YvHAwE31E@=6uqvs-% ze$bw+@Oin-C&+6*&gB(XCfJ}iR-*`dqTTfl?41!Js(DPS9rTjT+edhU4KF|hLwA3~ zw@10>$oL!tdh)}(L}Vg{F9V;Ks3htHS?E4c>>m3E_tGJRa z*fwUreC5{uHiKT6K~KdmlZ_m-n*oZJ_4!gAqN7Jl+fVe#M1H z;jMToq)px~g;PS@{;NH^Tdz57Z!HPfuKJSAYd!=j{P8mRb~0;oK4RsF+D|50{-OIz zNc&C6&1DW!yQkfU?XNSheB_Ch)2`R4TFYbfBJ$1`NAw4*d5GGH1)b`ncK@C`RU$># z{&m$-@rv1qf{u8D64Oqf4E5wE76 z3U+Ts>Qb~WGFVMs%}zjTxvbdlmYac`m_uEx70SDS&gLv(Po?(fO)ey9CWp}_*P#ci z!&aWYw*K2}KA733Y5#2xt?OUJKC-beXZ$PWgXK_ViWmGz{*Qcy#;aLu+hE&s*M+e} zrZ9;3_e*6$4qhbES(WdRlnIuL^{aHQ9re3Xd3SzFD(~)pDn~RW6OyaTR?WX%HIFez z9+|96SkqeR3~bwr=>+Z0WqHQ8ZRPEz#3GaN$Lw5|IhUhc7MTST>0r5r?G&=(1!yyCnMbN4 zbc}4;lR_E{`)gg2+M)labg-g{)ztn8rpIb(npdrLdDr~}YF`#GpqkFB@iv$BB>#Uo zdHv5S=0zSzy4I!i-c+qfB95O>DOUVkLSDfrvQ>j{)7MJ`l>eY0uj5V{f7J=UO)?;d+$A~!FE~}+pn;e6ZQfDjp2w`VUIp3JgWPt(lRbp(1lGci z2j{lf7LfJ4oH(HB1}r4MwR`wo)c5>^{VXg#xMrC!U@wb9Dtf+Cbt8pvDOeNi&{$^i zvL114-gdFos__9}`y78ibBDBp?LUQ^_MR|*!mWZK@+WMQqW5MOtz`QV)T~QmyIn*J z+wGx43|spXGO^t^)u(-b!Zj{nXM!1=X9Yfnby9qL71)h0TiUlRwo|E5z#dh26iVRb zJKe3q6Z&y#i`{N(PfA#gaTz;xP)33F+wuJUM092@bO(Lok_l~fu&i&qjSkj9Y}?as zv)Ha3Y$b2Ae7lAx0L)m)b4+s@(J_Uy7O->x0LrM7jJZ#yNgCZ}DS zH_Nwe`F0P2Wr>>j9E+EI<+Xd#Z?pc}HTZ8k7%!84o5i+su$6wB#kO;>m42JWwsWwR zew)R%bFh_uo5i+su$6wB#kO;>RZJ&~?HaJ{Hhn=oJ3J^EjDLw(EHkF#f`C}0DqwWs zM-@N9zn&^5;XbEFu-EN{>=K~8L636F$yj{C=tJ4#^gMO}P`f_4$enHUk?c=;F?I0O zei$oP&v*M8eKc*CQXyV@{VXO%!wY{neaO2zpS`t0dOheZj6U4gxC{KjMlYsj#WLzB zsn6l;2Yvx{oopP{$%)1}f_fMi`j=?0=e*91+M#_WZ5+e*s=YYf$1EkCkB&{YD<}3^ zx2yT&l`A{PYMyxIcCsU#)jlfPHNm>QFw^c!uubC%*qq@H_~u?*%MtkSFZA1zi~U~U(`@uHRGGSr)qiR~ zl$s&uvFB@!+laoyqw8&9f0ARl7x?|@bCTcEUCTboIflv53``!6XkG6z)olhJ(OXc@ zO0=+2JSwuM*saqrvDm@+Nt!+bl6|00OVd81o&BVuap-egNDthFeW2=UYU-_aa|5fP z>Ketxv)z8w;S%3cA56OrhH@Vgy8t)FFj`S1MBKsh0 zrw-5ioRiMyKF;wy>gy`*~3@0vWwjHZbR;w=q^-*8O9E!pM=_~KxJtzwR_#%^ggEVDAxe;D5~C8NUr_M9sV0amW1jE58q) zodUg>jQ&@cgT%uv;Ps&pxCx<;?objnO;^UuDwY zNL{-kc09J_=dkZ8eCvd5e&+fz?O)cFtKJ+Gid$i;+T&-k=LnY`yQQoX(2_hOqDJ+rGm1c?p`v4|r;C;3LK87ZIbE3@mXYskwMeBp-HUKbM6O zJ=bp}{1v}u9elb@;5S|~u!Hfk%>)XV=udJj~8z=s(Ogj&5#Mm-rnp~#49TklC_08e3%E+C+W9WEeZ!oqL;V=-sgbAl^ZhQ$AvF3g)XN=ibcN5w z#vR%BX68!mHJ{wOll{}#?{6#HbJONcSHYO)xY6vBa%yxwCDb*2mp#z+T@_T*JkkYy zZ>DnvRc4{1y*}B$p1GFc(ceCnF4OmB%k??{?U4OyjXr~Mf{4BqTHocVi@HpEh!y>j z>#CxaW7nOLlT$o#L6a>wl}Dkie(S`y=1&l!p>1ZZ6`UJ=FtgI1c^lHSFkN(2LO>HiA|p!hYymGS*b90r(DkQ%3VLSNLD7*Mn_-Ma9qKd|#JWv}aws zo-OyxS+lCI=B^BEll~g{6Li%B!Q^y*H?^=|Fg$;a@8S~wpwXvrj+gp*M*jv|aGBpd zqD!H-H2P%Ug?ib6(Wl~9xD35t_vP2vzL&VahyAf1mtk$G{WN?#my<6m`edG*i`l0~ z^r>!LJPTWe{aOFG%wKQxNz~K62%ZbayvXiruK5rKaQ4DnKAF=p=%HyEA5^Ljx?o7l z7qMx^eW{7)&HY9mJF;I318+gz<4y3xnQZRXD$dIa$)Iu7+QJ&T^-KN)`4~^*=|Nw$ z{ah-j8vKFInf9Z&?klu6F?3WX-{{L&*{PS>FE{=&nsdGw-s464+f>Jn`oJ@l|$5Pss9Z=U^)xEQ@XDU@O}pi|v}QRb9JaLS4eNuyBD+vs+`$K*`&z&D%NHN(akg z+d0@u2g_o+25h@euWktUC5gwIY8%_P9jJ$7SVsS&-zz#jki9c{dik(r<5ajk-19Ez ze+5C63b!|&1ZW%$6~s*f(Pqo{3j5@$y_fn79FO0CaV#nyj&nhHY&Z3Jk2oR65|F6C zF8POOFZ%p&9FDEPk6xzsE~59qe+12mGCuYibfLz-Fg5;EB21>8bI#iP%h0T2@C@l7%&VGg3~2o$N-fK z81euv;N65Ubid%>@S=_V8^qKJrISdj{a#hqOjD~>=!U47?tWce^{TqMd!i_c{_@=) z|N3Rrd>yq>iK5>|QT(40#r^*t_na@oZ!pMxK}A|!yk%ztzg#-M_+mg5|3W~sH9 z;&MD1c6xw60%M|HcR0FS{P=z{nG}Wpn*%R!FZsVzf_4Jm0en800{Nh=9J5@EA%6hz zrC?obL-IkdGdi79xOJw*bh7+@G!%RYPeE00I9@EL0Gr{EK8Nsrz9%`QBIEgVN~v2a zk`&YBDREw+XeY!$=IL7ih4!>G9L5O7#Rlcj#m}bWc-VUc$p@X$07|f$mOK~TN=2cym@G!hIJ;e30sEbi zXeQzaoG!;hnjobDQsDO!T3|rVJnD)Q(duH7hXSTY%jqp&IS0%fXC^KH4KF9f4MA`( zG?T!rrQ~^MG%qF!D4`LFVlfGrWxSjycga~@D-S}4AWl~6>+AJub^T$@vRXf^uh-Wd zd3`Pa(YV43P}lfr`S25_;j4?Ad|<|(RKWUNk!uJ-X|JJ_6dCW|*Xs}07>_1skXAjb z^=e1N0bcm5I#>;qls*?z$#7=T4`bNKfB3zY{|``ooyluBGxw8UV_)gwnPOjwX9yh^ z#~VEHxVXZDn6H63z_TTojdb44t}a}hY*2I*U+;D@60djnKck(1*$&7n$`c&rO}#wG zjAMo|aJw0RvkhL;JCu9Mm!1bs;Z;iSSV7@LKyI}zld&pwoe(0otgAv-7hW8v{}-l* zDbb;rBY=2=JWR{I(yYqtDJB!msGLjE`#?Fw4r`{9j?FNu>f!ZtaYLFyT}8BS4s@30 z2clyt4vT~pue`Wo<8?o-sWS#eO%Wkpp#_jYEl2{3OT8wkqo*Qe51E*%$_5 zr06(_S{!uH&6z!!1k?=Sa092!&{l;-&m|cwR;z`k&XA!Ie+QPhl3(CGJZ|_yir*2< zNQj`r85X;WDU14Kc5yYM#t|Y0)_KyKc>kLkDMJ*Fty4qfo<=HZHp>PlKIueX)ft4B z7{8IuCuzktwv%q1^&@I=+ybN|K{CNp6w5LwElxnQP${VdBr-RZE{!QeIR^bRmu4Ih zkSv)n{yR8E6q4gaIra}dz*c80vmY{iTTGgvPy@(|}0Bi3B znI`E%Y_c2Zkyks*89GV3vRc3fDca82dVnNKhy^aY?4bv zeK-%iAqz^v8EJFp9kSW^dx0ogd&E0rGm}HTno*YK5oL)xg)R^BAbhGz=r<`gJNCBZ zKp^H6Ltp^2Nww!C>X|286&Eupen zJjSJNbzWv}zOr6;OPxjbcnz}!Q~_-M4O4(z)M{_(Dhqw(Qg~D@Nlz>zlZiwNm|l>c z^_Xk4pY;|QZnU5E79p+u4Fe62HVk0kpLhXB_3?5PMU9LXO}p`uS=VUTjn*ikOI(JV zd~ka;8$m3(C}ceU*e5P)>Fx9he{ilW^EcAU9Z`}|v`xLieN6I!T=^=Gs6&F)Q@HGa z*HBvUoJU+kR^qeXz%|jso=hVl1)H{OWd0LD#k}STt_5`J1-{B#x|2wE4rL%P0ka$0Oa8Fi{6r2>K=(b5*D08!98^1 zP0dxPC$bCmigO&4Tub&_*$*&<(7y%s2VT{^4WV!cay}HEU)6iUVUp*JErjNgUc10N z2?p~~8t1(DpvCiwmO+l(f~6wG!W7sf#kYtmK~#vE)+pUSyqkzetJd_ekMvv2@{HSkE9JC5s5yT@_;4VN4>!4WS%_#God8beqW$Ixk~HY37} z9U%vGBSq`oCJ3Y_>OIE?m+Lm|Q-8JDSl3}gKaB2YLooOF5KJ;3yNv+R+{ZU43xg*gov7`iunPx^K=J+96uS+k~82_M6yw=jD4s7zBFikC}OjGTvs%ld#sv!#aHAl|cxDQAn4mis-uCPH&g0%W=gXZ607-pmjSX;< z=1<(RrcB4SWWkZc_GIRCUZ#xc=?5~!!MJVQkIVDPWSu!-ru)G?ysCnAhGv5Q(pM7XG7)GFKtqed~<8X(0`ON@EN zWNtzzraH$cDH-M&C`v}1Wy~oSa|>09rOq&Bl`-aH>Wn|vAAX`kQ~m(#huIPBCxEt5!a5j9YTT%2~2wUj-RdfiClMUCmx!_776NKhe5+ zAH#LseQ5UD!ao03Ht_tI|NNTD@Lo={zb=&f`?lfbORjj2T141>@bV3}onr3yyeXcy zSw{*&D<)b%s6OiFuNk(LxXUp;=z9u9yAG`RkdKfrLVh@ZBb0v;^7A1-1vICDrZ1JL z4`++|a{Z#d^w<00?-V?Bc(D!#LPNbO`!0X|1@g?w3cS6d`bxHtGqR>7M;ym4@6$fE zZ}#n!b^+N6(%x~DpnBB|;unD6T}KVqIl2y=(}bS#UOpNJIMF%0Btcw)B*oc7OR@^M zh$EErdjh(VAbz8czZKkLkkc`AQa9&0PVH!=0p{F4+VB~CcgW)%0p5nyK)k}e5&FGO zxn9R7+@Vqb%mh7yET2OOx>w=Y4)DGJZ>n%=tZ=*u@TX<2?fqM24%b$)wyVCPp0b{* z+z5XL*s8e1&c>cT5jsf^@yOS(8wMu!;%D)Sb@UeNKxZ(-`iw$heu19T0KJCFJj&^Q T?x>3SDfDnnzd!qbtu4_n#`uoB literal 0 HcmV?d00001 diff --git a/Houses/Slumberland b/Houses/Slumberland new file mode 100755 index 0000000000000000000000000000000000000000..98c824c531519a661f51f77082ba77fbe67aeb10 GIT binary patch literal 134150 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

    d0EL)&B)9BdLGv5#ck6eGZ?FXvG%4 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 z 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 literal 0 HcmV?d00001 diff --git a/Houses/SpacePods b/Houses/SpacePods new file mode 100755 index 0000000000000000000000000000000000000000..2b8d5913e16ba3e7349a36d82fd25283a4a82696 GIT binary patch literal 140762 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 i;$`^^+cL_87W`lt-x;p literal 0 HcmV?d00001 diff --git a/Houses/SpacePods.mov b/Houses/SpacePods.mov new file mode 100755 index 0000000000000000000000000000000000000000..e069d1b3c21a9142bdbfdc400f7c115c7cecdac4 GIT binary patch literal 51291 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 bk7b3E+gRTgirbP{ClpNI_KCU8hui-TIn15u literal 0 HcmV?d00001 diff --git a/Houses/Teddy World.mov b/Houses/Teddy World.mov new file mode 100755 index 0000000000000000000000000000000000000000..238dd8a450718a855501b5e4d5839b0cd33b65b4 GIT binary patch literal 28587 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 DIpSiK literal 0 HcmV?d00001 diff --git a/Houses/The Asylum Pro b/Houses/The Asylum Pro new file mode 100755 index 0000000000000000000000000000000000000000..708f8114fec7d95d85aa8bed0663cbb8a4caf58e GIT binary patch literal 49586 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 Lxg literal 0 HcmV?d00001 diff --git a/Houses/Titanic b/Houses/Titanic new file mode 100755 index 0000000000000000000000000000000000000000..efcebe192c8d01c3e87c3f4950b7801affaa75f7 GIT binary patch literal 73250 zcmeI531C#!_5aUJ0ttjAfh25EUf2RCySr8(0TdOXf?G?~AsI*{nZe0Kp#9ZSx2jFu zx~Q#xE7hvi+S=-`Vyl)~wJtxGT5ZwV>d(FIRomLS@c*29-+S}25y(%FW!@0x%$@t* zy!UZjKZToscu=pm6t85i+hXe)3HQ-jaT2~#g-(S(_T91HN<15#=T^s zZ(Tg)HOA^|;|cH74|>#(mRj(-%qyRe<&ZB!_5(2*(g)=d!L>r zAIU~D*BriJ_NtnALqnYNYl_DjV+lRI3cZp_E6I&6l)eC5}R}vzXu-5`;%eh!D zUEc^S$JWJHR@nbISbbu7#R~I`q|AlCmT}Z}RsS{+^LD zpwEE*I`3cSy@l^vpj#~cjGWK@=hJpRea~nA%lUjcpD*Y0<$S&Z`U?7ALH{dg`#$vd zp|9orTHdeY`|F^uv-C3q_5L3fPdBF$dLi?_*chu2xpJgAcEd?xMDny{=!gRQx%k>= zdx1>KJ2KW7-*A!{I$(Xj39YuP+kDPx^Lb61&*?5c-`D2*cE=Mr@NVvRZO8?k5I^2) z>U&8*Y4IUwK=O78$U()wgwg%F!01J1&+-3#wyF>J#47D(|Rd zveEU;e|Gr$(?9&m$6`EBq|Xbq=133eX?MzzeBNi!)=!L?B58TYuqkbBGJP$*4}EzI zHg4P~0&Q*(8T>C=(AAHkTTwNn5GiORyCm+vB8~u#L2D6Ktn+!MCOj-%jW3`)&!IgRh2H13U|$PnSKpyVuAnj&usV z`d1N)8?>3~^Kh}e2m`+%4fI(k-v>Ll`PdHrA$&Vn{wTi%+iJcV37;RKT`ZnqJ9tLh zXUKDMf?1-^)waQQ3;EVz+g-j@Y<-*uUjyHsD<4XQ87H%W$Xn09gH89czDwwg$c}m3N^641F679HyAXA0n&5)jKd>aax`D>Xh_s9?VPU-jM9;3dE zk#ZF@8~ZAKUWT^*18rB|MMdyjw4%pGyXX-pDQys z*a1mXGQpS znUlA&hkQ}M%DiXsd<^^aDYGAYkCa=X0}O99R^NLRk4BFaQ^?hsj_N- z>Q|RxN_~+}eGOKGIoYU!&=(11Ox)3U0|jo?_LVZgTrGd{{at0|Ao;yd_r=Tgv`?3S z^i!7BV}4EsTKh}sN7P#89H8+^xb}n`Y;LVA(sKiUJ;!Y>6M7w;sEw!6$(0oy=wMDJ zylqhpJYkBk$Y=O-*aq@&H?yZyqXXQ@H_!&!C|!gfnXwNHhg{gRA4m<~%+vSN~ zdS6ybq4}b`=3`hW8{}0r`e-jjRzFs#bdf1Q&g>0@yIBlh;eIHd>?`}3!B!tG!d|ey zWqMn`@os?}&a{Jb*dI9)_J{t&{kO$48&dID?P_mMLo!(l|1wI2zHv8}DK=5QHGDpZ zzy9!TiCG1u*ACzEUPY_*hfAfqF2<(+Msoa04x_!dTqJwTOd!csoZ;d(9p>=4rNPAB z3j=NiivIvS-;ewF_b~^{ix%gVGRXWy9xKq_osGoVhi7Cp4vPf)A5gi#o=-v!H0vDS zqSd^JFGvd4Sv_#P`IQXT`vRU}e=raGL&xPx&X)txC)$6DY_wk0saQJR5KGi{z_=>puy4n0#9vho5R~ z`}L+qULd|AaLkwRi@B{vz97%~bcsyIA8@_-F`vui3#J&K&Sx!M1&{rg?RT<_!0X_) z<=D}`QW9)?vF|}xb&z=U=RnU3gBot}EyJMP_e{b2)9_ zfxgDJe`KD3ei3@4G>3dxCjXMX(4o_`tIu~J(qbWWLT1Rmz8px%2=j7fvExa;`xM5q zz6fU>BCbRh~Ym2QpN3ak=zWs;Ab0xCl7*iJNsOwCzjXBb8%1w#&A1d8o zhS=Dy-j_4w2D`7`mqL5L6t^hPKaBMz)^2Gnb1pLX@{CygBRH$f0dsdRpr7#NOu1~7 z$IZU@(X7mg-U}z^{bwO_Uz#~S8|?|XT+WW%iwf16COr_Pk6`u)aoOz7z9X&qaXC31{ z3BK*MAeCI9=|rgxbTH>*d_{j8u8rDdhtM_%z8xqp2j?aW&FLY%2s?{S&tK}$MFYCg zw1o5-p*);G%r=mX6Xbv4|DgYC=K6p(J((EMSi(HSK{+f{bM-a z7s!{f1CpAFQuOpFZ!gw?j6ggK0#tFW6@E+hTOm zd(Z=pKYnN5ZPe6gq_nCjnzVTiQ)3N&0N;tOzzBLwG zl}3h_@~ysW&XRgtTI;v!R}B0!>bD8}jZ=9#ZER|zkcU^Uenp$hvvf z{R7`lDRTWRc@^!yFZ_@L{gEj)C1y{4`z)T)H?h}xS^8D^E4d5*-~CGINhK)}!rP!(QN+;W-REdc}%(%9|ChS-z*YfV9e{ctw7Y4>rW- zTOGrqFC)sgJzMdu>a|`;W{&CLTXv%oU9i?2UzHy^o zSj(R(W9yKU3aHB7RhG8;kBmX7Se2s;`zYGk2E%7Ne%-+M^%}J5NFzy0s)jyKF2U>Y zs2L1>7FO+t_zg<Ztp3}9Tzf6?uS<}YJ=)8R&Sx^(K(fae{DGIrsdn#M zh%i(Jv^fvG^8wpF2A|nwmIibA39g?NW7H<}vn`D=nwHc-eJU_f!m(|Iekr z-WQcK{mfW@-=-tYUeS7k*a#P)Zx9y?(%yA;Sb z(6>(jt30K#sE&p1Aw%VlaMOq8c=|xoj&}`O^^MbfomS~`b;JR>j)VBatbV%$Pv$?d zM*D9c`fbS~Ca6?4c}FI_BkGsNo0!^?st9zjOblJI)tBSn9IM}|A1q@#D25NBVJeR) zzun=>Ue#}x`Z$;4gELD9=p7jT+WxUGl(pP)g-@;ze`=UAgr^#6Oc>(*5#1Ax)cf~(}%{aGmn9}g`HuHm( zRx`N==WQY#Yw)TF?<`*m@A~r{oFDAPkY^QL7kg0swy+(xOYF5fY{yw_^RSHn3WAf( z7uZ9ifmh<>IWj*7yl)Hh4VGZ{mlGM#e8rQ=LqN~xAu;UxZ;6}9c-jT8_p>&CT-(Qx z1$i%R4y)}p&RbHQOr`2;lPR5>Q(2u{k&dUD0=~^)n~?~LZ;sV(RZnQex03dGReAVI zpH_PTtJ&HMN~5P)-5evF^8c-nTDoXQ`6l9b2ES^XA3%j3d}OoA*tc6y3lRrXCyBZ}Y&mkMf?y zWE8V#`uMbO|5`g@I?==WQ`~=NoEC2$9 zNA>y8KcjTuw`oJ~Qg&HERji>Qg}KWFSe>gHe6%{4vw7cyLmj3;UQLeGZ`EEXls`Lc zZLS5rR?DmKu#JuDGp>5+K>4Qf8$wse_t*!ui=5jiy>t3%%Bo^D%XMb40*jx#F`kIk z#w%PtnA5>j)6eAOJDFQWTR);Yw@D3=m8Xw4bhz`NqCvhj$_ zcqgw}+W8*wTH5=f#~HxBN7>`thGc!$=IxisSI9HC&BiOwVMKg^Ie6H~=vp;43Zlm! zfeb&}|E-boC%Mki+()0b@@JdrVEvDpJ@bf+YTHCea`w`t$yB7bUs&9!6vVsp4L&V>F1<7feod(0@m&lvd)vlCo@&B1${JzWmoQ=syk{GP9h$;BH< zu7mo_wNJ|L1FiE;wEvDGZ?PTX-XX|^_-fCoy5uv4I@qyTU40Z=#nbr{9N*63$~C5w zALi2zB;(^!MsVd(rT@-jdh*|)m&l)p?;J0^xu;4mj?m*XG`YL3PnBG$_jl-Jg~C{RBi0@p z`<{=#;x;qG=IWeF)a1MT#+`hnbThQ-F-k9h#`fcUl4wWGXfJ|(KFQiBdK{(4(gw|a z59!_+Y}@-73y&%41l!phs2`T<^=MDGn|wa$v#%P3{?<5IYcAE7 z`208B6#p{LlNf-d7ek}ha-O>}6V+{s`9v^JxIWC&ZMOLdmGVO~N4s#$=sg-h9?lQ2 z@ANvWn4=0FLqE#b>(#z$xv1{3&1AyRph$x+a_808;$EykTw=cl6>Pt{9Ou1Hl zHF{+Q%D3i8d)`i#4v5HvAf}`G?R;OB4wCg!kDc`{`wjP=Occg!{9j=sc^ z%J3Cj!)HgI2EERw-!YB!xzWnWD7{0>FY9q+a!Es+qBw0;T&?>N_-dS-b#g)J9IJyV zw!OkJSFz3W^T8BP=VNr^)CqV7t^mV{c)NbUyYl%Uc>wS2WJVm-0UnTN8RIIT2Qpjw zSv-^;^hnu1xOZ0eUQ2u$#bQU%!TQcjtVRcG@{WivO;6`~*h0ST+*hMISi5;Tc&t>v zRp_S3XiFQLlQ7ZeVbxbB^R?=(l9YJjB+;&|iXU)t8_zmAg7G@?fyl`3}Fu@6G1R+e&}@;u$B~ zKsQ%I2^&-evW>}pPEdJ$8XMQfcQjV}a3&XyI6FT4X~Hb1om&2BEQ`)&KtWC}Ft&(f!k|Id~+`W&^Qx0%h`^U!2+MMEs!VUDQF{fJ`g zd^Wk(H?DEs9$_p-@jTIDt58oN>(=?iG%j|XkD=22e4I6QcBYS~#>*D_m}?vdoGs=` zGxqs74`PP)-ee*uZc}ABo)VQ-Ekx4R%4}0%X)5f=X*NfpMUFDZ$O@x=nHGFDf2XE{ z%VF4N*pjn^a=RdwO0RA&Z(YukYV^vt%CiBsSO%7FGxAokof5%zh>z`b?6sR^dD+dm zmWK_vaS+SHY7+;1t8;uUhRVZlW_Vcfw>;khr>4m^dCy{X3^T3MCT8h#%vTr}H(I*V z)Pu8H=`Hwe)?uq~T=@2SW|bXiJWFpgZ2KRQT!QgX%ajMEMaG*rD+y&npeHzap#QtP znp_);)ZCB4a1NAW8~A6GZQP$*iD1@k)N~)6c63;tp#2?&;00 z!+r>{&FHtPCuA}|a;=uy-gY=M!nZ;F1l6e~`PdGY$FM0z+d2umW08&Jvr5I$XmYE3 z3{NG0d7@Ui17~8pHV@olwd3hvedjQbgd(xltEe)IEyT9{Sf(;T$FlwD)-FGxLwP#{ zPJIN6b{c!6$&p#_=Om10^!X2Mis34v=8ww?J8!oI5AJ(JhtwC{f=vAaSuuaH^lW_C zHHI+@p4=hqvO+4;Hc*i^T~D4uqh4zS+ty=QRNf-RkO#-{TtBFLfRD%+$Hb z2x%u*p+`mN!G3?TmfU#f_qX#GT4V+iA` z?BDGwKcSCi<9nKMcLcYvy%oJf*RU$mNe)!sM&34&gj=g3Hz(r*3~>w9-|Vr!&&F!Fm_wt*I*>b&&_B%K8==Nz{z%Ba1Q%myX`c- znxf1+9dG6`%Byg-A+~LGFqgTcd^=0K!M8ohs%CRM*`W@$2YH(%KDMfl5q-D%n8w7X z`t2oTHM~VGHzOoChwb3JL-TDvEfDX`JZiQ_z<2d@MSJs@Pe*yR zBfD%mk@ah3`OuG%r8)-P>E|IUeRjrP(D@CT#|XARm6w>)x0~X;V`JNMVI$JEV(C(6 zo2f{UkZ)V-3C?y<-$JhSF}BxlJHi$W$)uD1%G*k#cQG}@=?~ZxLA%<*mjAWSeVIN% zEhaF(RP{HVBMIiCs5>!3crL#Y=grIJd!c`F zU-QE-b~zDxKeb^w=SUxpK9gGiCI`Q|Tp6M7h|uBjxfh)s^DT27vIu>T<3wmA-6t@| zzxa>_7L`bO^NH-bWh5ee>vHX01Q@+KUI+2ZH4dDTnS9kinnm*M`(b2@3G>Lus3l4eABdcv&xGJ{#DU zn@Zj-5A%%Y8!*qC805K0k@EJg#%0;Zx_g4Mwy)>%ZL;w#CNx8G>_h;Ez>0 zsJRL~-n`;!CxW?dKK?t8UA9>=A;YhVv5sXLcj$>6c$Mlf1zLNZXMdQiG5Z@usfDP_ z_42w=&rA#1+b27}HuOErr+wbfDIIEvl`GGKb9O8X;^=ucUZ&XIVGfr+GaphhyqOr{ z@730Vz5xvHw-~C79Y^f^N7|0;_&h#tog=}$FvoK*$T8g|u?@yDwaB8jL!OQEf-Q6H zPavX8lmI+m!B*{QmRj6$@Pd0-tlIvrOhOj?)Y9+CEyNY@=OU|n263F772C~{x2IrD2n;Ofqb@El#Z5Fn{7#6(e$&4(v*vbR2cHDT;pQr)NC3F1a zP3aX4^-I%$7W!)3oYS^8ugZifx~c8ZC#=QMf`pyVx;QQe=9|nQ|Cw1$uNLAs^YA}B zWa%orL?=1hfn#Loun+oJq#aG;Pt4l4{x0YrMQF|Q58CHN+P#n#S6$5d%EEKw_~E%h zclNuVh_9yf2$r)XqC;wPEHll_pW{Dlo!5!&fQQ>+o3S0nl2P=!W@exZR6E;Y*pi-V zQ;ealN^J+KtmG)Jg@3X2lf(9%bu25k`3bs+DD%v$aTeiQrzdn|I|Olu47TG~L*QAe zN9Z;hPmOOoSUSk%pgpi1bS^5kgUuR?;t$SI%y;OxL;lSAR0FFIbQp_tKE}2(L9GXu z+pKeSsRXFcCeQwG@?}0_-lU~PCZJy(ZtF9)5I(sII_CJzi^PbM)L7wynX*T=J zhV4A3k@g)s?yyO_Ow{J>&<{38Q2~cA9}IrWu2mH13~QbK&`oR)$zt2Jp3qHf56xoR zHMTwHHK!VzsY}t(x+KHq9f_Xsvf>!skOewAX>E$j$eK}7{ViFU&_*V76War`*lsnx zRUc!PZ@aL0dsf#qr{fhJ%Y;%Z6W+BrM*LvNgwN2XwS_~Op!0T#%h%dmWN7B%$F04f z?YaWI<|w0c;V08NKWoXYtu&|dS?BR-e*XJfo&dTpKA<#yVGXbqu^+SbiIpEo)KibM z3c7;!I5{M=7bM6a{jxk45>A`CYCl{9WkqccH`Ig${ogI{aPe@OPoZ-z}(aPNhhsB6UQ$-VD7{<}CG_UlWfd z>TAfyUy-h}Q>7)0^A7U)Ho(+>=iaFQR_ivm;@bej49@rsCNQt@UV1yeI>p@O^VJ@# zrL{PuS7>#3%c~Q}7dyf4&%V~1>GnNYYc=?N8p8F^BhSJn_%l2Q&OJN_=N2a$)rx1WbUOxBb0Im5<(SDFTe)Q|PJIySpp-gq~$Rhu^#Y)egp znP%%TFAuxEA#6ZldQbWV%uH^6VK}~KcR=6&#TxDGfTkpIg2ORw(#&8 zOZOoQWW3yw#kRgPJ)v`K)#lCSesnRGbyFs&&6~w`>tL(C@hrAoVB0zt*~Tt&bwAqK zyc<8ZcA44^`&~LzTy6!WHxU=W$HlIlTZ8xzE^xH$S*miC^bQ4?kgDKyB&ODyw+s^E= zZepurnPR)pkagjnBmU3I1ZV%Qb+V;3wu)0EZ``PUORim8KiJ21ewkuhX6K4Ic^d=W zDrWfV7*}Kd8P=DWLI#bk3q<=aH4nX;*arDvS!|tM-=VK&*j#T;Jl?=GlI3yluvpD0 z&2b9hHaDf?v1Tdlly8H4Fw@F6E>x;BIg|0+T&Euyo$ZK7IM9oneSCHE5*|Hn};h8_vr)7&noBn z^yxCf&jCxY+TZz=L_z33m#D`2?I0h_MDlNqUY337Gq3d%R3?PEcGhq3a_IZY`f9k3 zy{eKc-Ta&m;$_Y^{<_66lE=tg60M}7bNq+stQyM?t?DOa=bS1gedi~Wb$fcV>X+5C ziY&_;dQ~w3Xbr8_K6d=-{?B1#%eB~QOs9t_^RcBCt69dHxgHFzwG%5$p6dKc<12GD z?nbfN19_qLUW{Tj`g=pV+Klk&3hK4~(WghU;=_N1^ai^&7YAfbgZHSnKM|Wm6H6bW z4(T7{Uv>=LuIgE_hHPVFyfK-wl|;P-4KXBcuzs1V8AxU<&wrF}b1b%6AFNQG^{-tq z{I-(`7TXyp*Q2$Kumb7bETiDgQ)V1OC zrL}MMl@G4Uw_3Nkf4Kggt^vmgXX{w1d?@y1!T@xhfz-EsnLP$mpSjeGmSdq+Rt)v~ z4-}8OcNg0Abb3mRs`kgDcL~}16NUNKR)&ve=JU_l&&r4Gu1?^1a$wGq^R3Ju&w7Ms z=^XOjhs9Z3E6qaajg84h>I+Yg*k!%Ode~(za6tjCifvCmE8prG1Owa*Ud9*2wlae4 zadMR%%bLM~&DLP_=>i>(eA?D(_Gw#lSntcttVgfo;6UnQKSqVNe{z6o=8xY3&S&=F z92hGnQw@tQjAiS%D|eDdg7C&?w!~)KxIS-C^-Viz|MMJebw$73(p|Stq7sMa%lt{4 zQ%H9u6N+`s7h5b4^I=IUmV!^h+>h3LtGMcmWdkg>1MFC)8k%CI=f5m7mYFkH;X$um z>$2iCv-~`Obuf&4!Tg?GcE>MxKA#`<>CZx6>d` zY0{eKV7?W6jCzg{Y&*9dc=|y&Ydd%$KR=q`XV&tt?HSu)+O&4^Hn1Jq_-e2n_6A$E z9eU$+W`iHHwu8mf^1P4jCgWv6-49*cA*$cz*&IZz$2fp$6O-*+{^NLR-}Z5CAz$%( z<{+Z#8c#2i-OXN%W@;<%Qhu<~qvGl2RKoMCQ&cx3YnC@v_;o)r^~M8P>uS2^TE11= zp(x11wB!Er%veUXFtx>W?ZTU+!c68l(S-~OY2?;~POX|I}vwkq1^Cj@I}=xRF3yNaxnAjBu)Z<)O8@+QL1|GBeVs z&DA1Lu@db2Hh$J3AEHwZwd;|z&?@MeYj(Y{teY}n3V4wZCXW)+f77Vl)Iy&Buh1K` zvO){h@QYbh09ycgyUWJQHi@m12_J)2YaJ{X3)f#)I;<_sYE5QjC0UG&YpgTKnoV`UGKgv8+D9YUpkJ32t5KH>|YHLE0+9swb$YMO_5=YDE3hii!HhCn%pHNPA#2 zzK9m4pp?tQW(I1+m*`f``n{i}Vs5>qA3{!SlwVo;V=ULbZ5`KgT(`fMiL8ID{U_i} zIMJ@fHG-OX2h*m%wUT(;U2>vxft@^JRyGnlTuFL#{wHfF_yx?Qwv0lST z>{3ZKQh-&t{D##X_hZ#Uz4rC2_O!3{o0YTL^so8uKeqh>nE~zY(Ioi_nEcYV7a@Bl z+xxPL`5+tQFdR!7uRO@~cbGswE`O^mcKC3V=UBsQiIrDdwKhfBOxTvCism%vnue@) zY8Ta+{=SXrIBcDdQT5x5H%$3feT*g6N2S+-erqns_-d#d=xm3TQfN+=e_MaoN@`#a zmET%^TZzZzI=S2DlR{R_EVX^@mC?s7t6caheu`V%x>Cd^u6^RZ3pS|N_6KC{ENnELrYkatat zZgJKzT&w-r>WGS|B-gE;>=2iqqdu<1&`Z=mg(i0!TJvd^=f}vM;o6bQm=*Xa->Z*n zHqX!)o{>B9cxJ%-Y3{kh|5INtvfo^cvV_Y~n47*|uT(<)*7+D;^zn4aYAiCx$^^wW zoCC$>Ou@IQ^YR=IpCKD8t#WvzFDot}zV^SYrS}m(Qi4r45&m2SJs8jIRc5sI6K1Cv zjj6p2JwT3<6Zn;@q4SZLr!nT?z+mjVjI4j2YJO`3@%$6`-r>1jVOzLpWqrb1lw284 zHMR4DIe)?%dg6>>x+=QkU$MR#tp!xf%o}@McD&f18rh1i#uU&bN?++=#}U@6NozAB z)LV9qQ^lm5Piq*H+!*vAa`mH7u5Ogy*xLH#a-o^d8tOXMAcv6(`x^Z3(7!RrXN@aE zXXI@;$9NRK&?~g-*mSl0&dQlG#?WQV9k`bE1Z$|31hSX7%vIvK`vUz5=ZN;Lj;%-| z6}c(F%N({Za7KYF2;SA7pnO|sa4YM%@o$Pb#g_v*mQ4iP*ZAtI%;~vXuCTty z)1m9|h+RiJv^kXabD#&Yg6|FRYBjX3b;!PUeJHKJ^b+rQWMev8G~Yp=vxuJ1IkqZqv)KM$uyygWe_0$OF&&VeAw-RDoZYr|aT0A?5^KKGb<9VoB>cwu2 zZI1PWDc|-E;*ZvsnC076e4AI*&>Zh<&Z)!p-yL8Z$b|lQvh?e$p3ni`=91go>3m)% z6VwaUmTxugpzB4BFd8cZTU-C^$pAFVuBT-7>PIHZNE48QKnREc<|_*4XCSm`(xMX5wX?#mMlP<4`0g z4E*td<9EHw(tV9*u9VlTO;L{3_O!pgM!8z7c){MXKENG%eTU7csnSv159M2xx7oTM zPDko+o=!Kh)tF8e+b;Cm&A_(Z+&ys3^6h5S0@@56tR1!+KeFpZD&J=3?rlOQ44UgQ zKUfE9N!*KhM>0z%mQJQ@OsBKCdmq_a?iw$XHgorad3n#l+b6mCdU&rhbNWt)_UG}j z@0F3cd%+yNBK)+`xqHE!zPRj(J;=tGm>?P~;oQAmvUgC+9sgK$P|Mv6GT-uRxz8o{ zWI!-qPqtaStebqRQN%3Yb|G)Oh3$vgxzcLq@+^4z9Cc>%_MR1Qs);9R$q3v0`Me*7 z>pN`A`Mh3(NBMU2V?yS?Z>hY zvt!xj@NKtb!UtJwHwW9kM<HivIFDHB{Cqh@MoR&$=@;=*En*~b4^Z1bYF z0~u)*a!}8>@Gq+nq@wv=43R7Y#W^?wo_qmN?S$`1y% zpP_AFTic4Cs^;Ws6tE80-Ru7(QGbhVTfRLAP}D99ZC=jVGb@AZHJV_(k9gJ==aH&w|%>8uDq&VOO>T^ z3OOOCYN`{q8#LLwEQm{?;trxZSpJ{&ilW=be_K64^AJL8 zp<`Tkw$4%{7THZ~RVHMy?ZPhWCbl*!Im@@3wt2gW?SWao?b@HvO>7UyV!PF_-9L-% zR>O9`EVf$>+kLaxZZ&Lmo=#Q=>p}wsNTTpS1Sdl$*t&d>F@kSl?%5#+l)v-)4gJ z3w<@OngzZu3;95d?@jBEit`(Gl@1#>FOpe-f5r&&ais7a{4+D;J-K2`(SVcqi6Yif z??;}W!4p1Qekxx>w)}xJog>A}N|n;n3JvuedNb#ARq1K{a*;nD#KRtuAL2oL+qi>b+m>&4kNC!?NNLEEADBh$buH#i=Tc!Y z;K^M1R>+gD>D+(o>mG(YUv8$^`WHp=Cz&S?B1?x*+vD5zLVkG z(g%**4$nblcyJEgKQAGsbs@9-3vG;MEOUE}XeA@-zmduKs8ei=lmQ2K(Dm_~=FrEtPjdw0@72CFaJ6tM4z8xe-h4duit%KcI zZ>E}KeAyVWbCJDMw1%+jqjZK>%_^T)&!v7qDYb4?(vOrks2^hcBj2Jtyj}5azi=#D zluDjz7tE4yE{Tgp@+88enOFYC52>Z26(x#nOmY_E%Na_W+r_7;wzi+SkaiCoRuWrh zLysCM>l7=We!|u{aP6_MPUA>)ew8?`{Tb>}1oY*GtXseR;>a4`XQQ75Ykc1=*N60V z@_I-=Y_J{tdG6mZ!94dpsGo7E-#&_U#nb-rN6BR literal 0 HcmV?d00001 diff --git a/Houses/Titanic.mov b/Houses/Titanic.mov new file mode 100755 index 0000000000000000000000000000000000000000..db4d2839bb1c4e498a28cc2ca56d366564a80d17 GIT binary patch literal 6534 zcmeHLyN=Z`5Vh|v62C!92L&~v<1>(`5Ht}b6@RwXE%Pgg_jAL{nKOa{J+myQ?mqwfph@Xu8Y!iOzk3>~qjovV{ z0*lfxVt!U_KbpBZM&>p{x;o9CBn*1=?-&G4xAZ7m5KPEQjt`ct1|ThvOyQAktFosI zbWU*F5F{TWh`lrnk$>b#)X*KWnf=O|hZ|V~y_f1&z3S2~( zY!Ed%HhXf)S{aRq5#LZLzH3Bs6*zc_&BY?&ktqU_qJ*pnNQ@$A)<$knRv?;k14M83 zzA0ngRE%-U*huCqyFkdH-bnt*j9CCLTS2qbUK?+Y3#j*{Ykbl~PZ^-@3$zmX)zo`? zrT1P7L>j}wE?RAuG6P{;3RHQ$evB2?M%nr%8m#01J`KOjt2x0|(q~%0Y%8&5I)$^Z>>+Ps25kpjeMo(|QTz@#xi} z70?R`Y#A@l0dy}2c4J5o390WY4RG!3vZL!9hl;W24^EcYA2?%YJ%HOI zEbGJ~c)eHFCBQGT18t)Qx{KiKU0h@TFwhwvLAnz`bwT(PKzD&)SNnDln^2i+kDLV< z8n6sEsQC&t1Yy>LgWaH%SDkt0lYTCs@Jeml4PF_k417^B5K3{msf!EBJuWx1v$Tt> z(t{rjZk7NEkbUrA$_=n$AjzafGLWeP;%u_W+Qi6=^W365&;Uzx8-WGBBOsxCMtA*a z!k@k&a=4N+l!&nqN~|uQ@5*@rLLt;}K|)CmfK9oG{I))e8XbRX?B03Gw5Ju*&>yso z;7m z_bMWBH9Ny7n^1;%WyNKgKver)vnD+gcUG|!9|EP&l?qW~g#n9kIJiuCxmMJ)`wjN? pKF!5CzzS{EG}eKosHy|?8K>5<+se~Vzz!-U0=sejBfgoGegmhV$ZP-r literal 0 HcmV?d00001 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