mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-23 14:53:52 +00:00
481 lines
12 KiB
C++
481 lines
12 KiB
C++
|
|
//============================================================================
|
|
//----------------------------------------------------------------------------
|
|
// Events.c
|
|
//----------------------------------------------------------------------------
|
|
//============================================================================
|
|
|
|
|
|
#include "PLKeyEncoding.h"
|
|
#include "PLTimeTaggedVOSEvent.h"
|
|
#include "PLQDraw.h"
|
|
#include "DialogManager.h"
|
|
#include "Externs.h"
|
|
#include "Environ.h"
|
|
#include "House.h"
|
|
#include "InputManager.h"
|
|
#include "ObjectEdit.h"
|
|
#include "Rect2i.h"
|
|
#include "WindowManager.h"
|
|
|
|
|
|
short BitchAboutColorDepth (void);
|
|
void HandleMouseEvent (const GpMouseInputEvent &, uint32_t);
|
|
void HandleKeyEvent (const KeyDownStates &keyStates, const GpKeyboardInputEvent &);
|
|
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 = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kColorSwitchedAlert, nullptr);
|
|
|
|
return (sheSaid);
|
|
}
|
|
|
|
//-------------------------------------------------------------- HandleMouseEvent
|
|
// Handle a mouse click event.
|
|
|
|
void HandleMouseEvent (const GpMouseInputEvent &theEvent, uint32_t tick)
|
|
{
|
|
WindowPtr whichWindow;
|
|
long menuChoice;
|
|
short thePart, hDelta, vDelta;
|
|
Boolean isDoubleClick;
|
|
Point evtPoint = Point::Create(theEvent.m_x, theEvent.m_y);
|
|
|
|
thePart = FindWindow(evtPoint, &whichWindow);
|
|
|
|
switch (thePart)
|
|
{
|
|
case RegionIDs::kMenuBar:
|
|
menuChoice = MenuSelect(evtPoint);
|
|
DoMenuChoice(menuChoice);
|
|
break;
|
|
|
|
case RegionIDs::kTitleBar:
|
|
PortabilityLayer::WindowManager::GetInstance()->DragWindow(whichWindow, evtPoint, thisMac.fullScreen);
|
|
if (whichWindow == mainWindow)
|
|
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);
|
|
break;
|
|
|
|
case RegionIDs::kClose:
|
|
if (TrackGoAway(whichWindow, evtPoint))
|
|
{
|
|
if (whichWindow == mapWindow)
|
|
ToggleMapWindow();
|
|
else if (whichWindow == toolsWindow)
|
|
ToggleToolsWindow();
|
|
else if (whichWindow == linkWindow)
|
|
CloseLinkWindow();
|
|
else if (whichWindow == coordWindow)
|
|
ToggleCoordinateWindow();
|
|
}
|
|
break;
|
|
|
|
case RegionIDs::kResize:
|
|
if (whichWindow == mapWindow)
|
|
{
|
|
PortabilityLayer::Vec2i newSize = TrackResize(mapWindow, evtPoint, 47, 35, &thisMac.gray);
|
|
ResizeMapWindow(newSize.m_x, newSize.m_y);
|
|
}
|
|
break;
|
|
|
|
case RegionIDs::kContent:
|
|
if (whichWindow == mainWindow)
|
|
{
|
|
hDelta = evtPoint.h - lastWhere.h;
|
|
if (hDelta < 0)
|
|
hDelta = -hDelta;
|
|
vDelta = evtPoint.v - lastWhere.v;
|
|
if (vDelta < 0)
|
|
vDelta = -vDelta;
|
|
if (((tick - lastUp) < doubleTime) && (hDelta < 5) &&
|
|
(vDelta < 5))
|
|
isDoubleClick = true;
|
|
else
|
|
{
|
|
isDoubleClick = false;
|
|
lastUp = tick;
|
|
lastWhere = evtPoint;
|
|
}
|
|
HandleMainClick(evtPoint, isDoubleClick);
|
|
}
|
|
else if (whichWindow == mapWindow)
|
|
HandleMapClick(theEvent);
|
|
else if (whichWindow == toolsWindow)
|
|
HandleToolsClick(evtPoint);
|
|
else if (whichWindow == linkWindow)
|
|
HandleLinkClick(evtPoint);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------- HandleKeyEvent
|
|
// Handle a key-down event.
|
|
|
|
void HandleKeyEvent (const KeyDownStates &keyStates, const GpKeyboardInputEvent &theEvent)
|
|
{
|
|
const intptr_t theChar = PackVOSKeyCode(theEvent);
|
|
const bool shiftDown = keyStates.IsSet(PL_KEY_EITHER_SPECIAL(kShift));
|
|
const bool commandDown = keyStates.IsSet(PL_KEY_EITHER_SPECIAL(kControl));
|
|
const bool optionDown = keyStates.IsSet(PL_KEY_EITHER_SPECIAL(kAlt));
|
|
|
|
if ((commandDown) && (!optionDown))
|
|
DoMenuChoice(MenuKey(theChar));
|
|
else
|
|
{
|
|
switch (theChar)
|
|
{
|
|
case PL_KEY_SPECIAL(kPageUp):
|
|
if (houseUnlocked)
|
|
PrevToolMode();
|
|
break;
|
|
|
|
case PL_KEY_SPECIAL(kPageDown):
|
|
if (houseUnlocked)
|
|
NextToolMode();
|
|
break;
|
|
|
|
#if BUILD_ARCADE_VERSION
|
|
|
|
case PL_KEY_SPECIAL(kLeftArrow):
|
|
DoOptionsMenu(iHighScores);
|
|
break;
|
|
|
|
case PL_KEY_SPECIAL(kRightArrow):
|
|
DoOptionsMenu(iHelp);
|
|
break;
|
|
|
|
case PL_KEY_SPECIAL(kUpArrow):
|
|
DoGameMenu(iNewGame);
|
|
break;
|
|
|
|
case PL_KEY_SPECIAL(kDownArrow):
|
|
DoGameMenu(iNewGame);
|
|
break;
|
|
|
|
#else
|
|
|
|
case PL_KEY_SPECIAL(kLeftArrow):
|
|
if (houseUnlocked)
|
|
{
|
|
if (objActive == kNoObjectSelected)
|
|
SelectNeighborRoom(kRoomToLeft);
|
|
else
|
|
MoveObject(kBumpLeft, shiftDown);
|
|
}
|
|
break;
|
|
|
|
case PL_KEY_SPECIAL(kRightArrow):
|
|
if (houseUnlocked)
|
|
{
|
|
if (objActive == kNoObjectSelected)
|
|
SelectNeighborRoom(kRoomToRight);
|
|
else
|
|
MoveObject(kBumpRight, shiftDown);
|
|
}
|
|
break;
|
|
|
|
case PL_KEY_SPECIAL(kUpArrow):
|
|
if (houseUnlocked)
|
|
{
|
|
if (objActive == kNoObjectSelected)
|
|
SelectNeighborRoom(kRoomAbove);
|
|
else
|
|
MoveObject(kBumpUp, shiftDown);
|
|
}
|
|
break;
|
|
|
|
case PL_KEY_SPECIAL(kDownArrow):
|
|
if (houseUnlocked)
|
|
{
|
|
if (objActive == kNoObjectSelected)
|
|
SelectNeighborRoom(kRoomBelow);
|
|
else
|
|
MoveObject(kBumpDown, shiftDown);
|
|
}
|
|
break;
|
|
|
|
#endif
|
|
|
|
case PL_KEY_SPECIAL(kDelete):
|
|
if (houseUnlocked)
|
|
{
|
|
if (objActive == kNoObjectSelected)
|
|
DeleteRoom(true);
|
|
else
|
|
DeleteObject();
|
|
}
|
|
break;
|
|
|
|
case PL_KEY_SPECIAL(kTab):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
{
|
|
if (shiftDown)
|
|
SelectPrevObject();
|
|
else
|
|
SelectNextObject();
|
|
}
|
|
break;
|
|
|
|
case PL_KEY_SPECIAL(kEscape):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
DeselectObject();
|
|
break;
|
|
|
|
case PL_KEY_ASCII('A'):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
SetSpecificToolMode(kApplianceMode);
|
|
break;
|
|
|
|
case PL_KEY_ASCII('B'):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
SetSpecificToolMode(kBlowerMode);
|
|
break;
|
|
|
|
case PL_KEY_ASCII('C'):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
SetSpecificToolMode(kClutterMode);
|
|
break;
|
|
|
|
case PL_KEY_ASCII('E'):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
SetSpecificToolMode(kEnemyMode);
|
|
break;
|
|
|
|
case PL_KEY_ASCII('F'):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
SetSpecificToolMode(kFurnitureMode);
|
|
break;
|
|
|
|
case PL_KEY_ASCII('L'):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
SetSpecificToolMode(kLightMode);
|
|
break;
|
|
|
|
case PL_KEY_ASCII('P'):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
SetSpecificToolMode(kBonusMode);
|
|
break;
|
|
|
|
case PL_KEY_ASCII('S'):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
SetSpecificToolMode(kSwitchMode);
|
|
break;
|
|
|
|
case PL_KEY_ASCII('T'):
|
|
if ((theMode == kEditMode) && (houseUnlocked))
|
|
SetSpecificToolMode(kTransportMode);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------- HandleSplashResolutionChange
|
|
void HandleSplashResolutionChange(void)
|
|
{
|
|
FlushResolutionChange();
|
|
|
|
RecomputeInterfaceRects();
|
|
RecreateOffscreens();
|
|
CloseMainWindow();
|
|
OpenMainWindow();
|
|
|
|
UpdateMainWindow();
|
|
|
|
//ResetLocale(true);
|
|
InitScoreboardMap();
|
|
//RefreshScoreboard(wasScoreboardTitleMode);
|
|
//DumpScreenOn(&justRoomsRect);
|
|
}
|
|
|
|
void KeepWindowInBounds(Window *window)
|
|
{
|
|
if (!window)
|
|
return;
|
|
|
|
PortabilityLayer::Rect2i windowRect = PortabilityLayer::WindowManager::GetInstance()->GetWindowFullRect(window);
|
|
|
|
int32_t topNudge = std::max<int32_t>(kScoreboardTall - windowRect.Top(), 0);
|
|
int32_t bottomNudge = std::min<int32_t>(thisMac.fullScreen.bottom - windowRect.Bottom(), 0);
|
|
int32_t leftNudge = std::max<int32_t>(-windowRect.Left(), 0);
|
|
int32_t rightNudge = std::min<int32_t>(thisMac.fullScreen.right - windowRect.Right(), 0);
|
|
|
|
window->SetPosition(window->GetPosition() + PortabilityLayer::Vec2i(leftNudge + rightNudge, topNudge + bottomNudge));
|
|
}
|
|
|
|
void HandleEditorResolutionChange(void)
|
|
{
|
|
FlushResolutionChange();
|
|
|
|
RecomputeInterfaceRects();
|
|
RecreateOffscreens();
|
|
CloseMainWindow();
|
|
OpenMainWindow();
|
|
|
|
UpdateMainWindow();
|
|
|
|
//ResetLocale(true);
|
|
InitScoreboardMap();
|
|
//RefreshScoreboard(wasScoreboardTitleMode);
|
|
//DumpScreenOn(&justRoomsRect);
|
|
|
|
if (toolsWindow)
|
|
PortabilityLayer::WindowManager::GetInstance()->PutWindowBehind(toolsWindow, PortabilityLayer::WindowManager::GetInstance()->GetPutInFrontSentinel());
|
|
|
|
if (mapWindow)
|
|
PortabilityLayer::WindowManager::GetInstance()->PutWindowBehind(mapWindow, PortabilityLayer::WindowManager::GetInstance()->GetPutInFrontSentinel());
|
|
|
|
KeepWindowInBounds(mainWindow);
|
|
KeepWindowInBounds(toolsWindow);
|
|
KeepWindowInBounds(mapWindow);
|
|
}
|
|
|
|
//-------------------------------------------------------------- HandleIdleTask
|
|
// Handle some processing during event lulls.
|
|
|
|
void HandleIdleTask (void)
|
|
{
|
|
if (theMode == kEditMode)
|
|
{
|
|
if (thisMac.isResolutionDirty)
|
|
{
|
|
HandleEditorResolutionChange();
|
|
}
|
|
|
|
SetPort(mainWindow->GetDrawSurface());
|
|
DoMarquee();
|
|
|
|
if ((autoRoomEdit) && (newRoomNow))
|
|
{
|
|
if (theMode == kEditMode)
|
|
DoRoomInfo();
|
|
newRoomNow = false;
|
|
}
|
|
}
|
|
|
|
if (theMode == kSplashMode)
|
|
{
|
|
if (thisMac.isResolutionDirty)
|
|
{
|
|
HandleSplashResolutionChange();
|
|
}
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------- 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)
|
|
{
|
|
TimeTaggedVOSEvent theEvent;
|
|
uint32_t sleep = 2;
|
|
bool itHappened = true;
|
|
|
|
const KeyDownStates *eventKeys = PortabilityLayer::InputManager::GetInstance()->GetKeys();
|
|
if ((eventKeys->IsSet(PL_KEY_EITHER_SPECIAL(kControl))) &&
|
|
(eventKeys->IsSet(PL_KEY_EITHER_SPECIAL(kAlt))))
|
|
{
|
|
HiliteAllObjects();
|
|
}
|
|
else if ((eventKeys->IsSet(PL_KEY_EITHER_SPECIAL(kAlt))) && (theMode == kEditMode) &&
|
|
(houseUnlocked))
|
|
{
|
|
EraseSelectedTool();
|
|
SelectTool(kSelectTool);
|
|
}
|
|
|
|
itHappened = WaitForEvent(&theEvent, sleep);
|
|
|
|
if (itHappened)
|
|
{
|
|
if (theEvent.m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput)
|
|
{
|
|
switch (theEvent.m_vosEvent.m_event.m_mouseInputEvent.m_eventType)
|
|
{
|
|
case GpMouseEventTypes::kDown:
|
|
HandleMouseEvent(theEvent.m_vosEvent.m_event.m_mouseInputEvent, theEvent.m_timestamp);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
else if (theEvent.m_vosEvent.m_eventType == GpVOSEventTypes::kKeyboardInput)
|
|
{
|
|
switch (theEvent.m_vosEvent.m_event.m_keyboardInputEvent.m_eventType)
|
|
{
|
|
case GpKeyboardInputEventTypes::kDown:
|
|
case GpKeyboardInputEventTypes::kAuto:
|
|
HandleKeyEvent(*eventKeys, theEvent.m_vosEvent.m_event.m_keyboardInputEvent);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
HandleIdleTask();
|
|
|
|
if ((theMode == kSplashMode) && doAutoDemo && !switchedOut)
|
|
{
|
|
if (TickCount() >= incrementModeTime)
|
|
DoDemoGame();
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------- 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;
|
|
}
|
|
|