//============================================================================ //---------------------------------------------------------------------------- // 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; }