diff --git a/GpApp/AppleEvents.cpp b/GpApp/AppleEvents.cpp index 5b55609..812728f 100644 --- a/GpApp/AppleEvents.cpp +++ b/GpApp/AppleEvents.cpp @@ -7,6 +7,7 @@ #include "PLAppleEvents.h" +#include "DialogManager.h" #include "Externs.h" #include "House.h" @@ -131,7 +132,7 @@ PLError_t DoPrintDocAE (const AppleEvent *theAE, AppleEvent *reply, UInt32 ref) short hitWhat; // CenterAlert(kNoPrintingAlert); - hitWhat = Alert(kNoPrintingAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNoPrintingAlert); return PLErrors::kInvalidParameter; } diff --git a/GpApp/Events.cpp b/GpApp/Events.cpp index d4ae019..4b40d0e 100644 --- a/GpApp/Events.cpp +++ b/GpApp/Events.cpp @@ -11,6 +11,7 @@ #include "PLTimeTaggedVOSEvent.h" #include "PLToolUtils.h" #include "PLQDraw.h" +#include "DialogManager.h" #include "Externs.h" #include "Environ.h" #include "House.h" @@ -53,7 +54,7 @@ short BitchAboutColorDepth (void) short sheSaid; // CenterAlert(kColorSwitchedAlert); - sheSaid = Alert(kColorSwitchedAlert, nil); + sheSaid = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kColorSwitchedAlert); return (sheSaid); } diff --git a/GpApp/FileError.cpp b/GpApp/FileError.cpp index 68dc0bc..22efc2c 100644 --- a/GpApp/FileError.cpp +++ b/GpApp/FileError.cpp @@ -9,6 +9,7 @@ #include "PLNumberFormatting.h" #include "PLTextUtils.h" #include "PLPasStr.h" +#include "DialogManager.h" #include "Externs.h" @@ -59,7 +60,7 @@ Boolean CheckFileError (short resultCode, const PLPasStr &fileName) ParamText(errMessage, errNumString, fileName, PSTR("")); // CenterAlert(rFileErrorAlert); - dummyInt = Alert(rFileErrorAlert, 0L); + dummyInt = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(rFileErrorAlert); return(false); } diff --git a/GpApp/HouseIO.cpp b/GpApp/HouseIO.cpp index 51212f4..89ea86e 100644 --- a/GpApp/HouseIO.cpp +++ b/GpApp/HouseIO.cpp @@ -11,6 +11,7 @@ #include "PLStringCompare.h" #include "PLTextUtils.h" #include "PLPasStr.h" +#include "DialogManager.h" #include "Externs.h" #include "Environ.h" #include "FileManager.h" @@ -935,7 +936,7 @@ Boolean QuerySaveChanges (void) InitCursor(); // CenterAlert(kSaveChangesAlert); ParamText(thisHouseName, PSTR(""), PSTR(""), PSTR("")); - hitWhat = Alert(kSaveChangesAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kSaveChangesAlert); if (hitWhat == kSaveChanges) { if (wasHouseVersion < kHouseVersion) @@ -982,7 +983,7 @@ void YellowAlert (short whichAlert, short identifier) // CenterAlert(kYellowAlert); ParamText(errStr, errNumStr, PSTR(""), PSTR("")); - whoCares = Alert(kYellowAlert, nil); + whoCares = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kYellowAlert); } //-------------------------------------------------------------- IsFileReadOnly diff --git a/GpApp/HouseInfo.cpp b/GpApp/HouseInfo.cpp index 18cee23..98eeb46 100644 --- a/GpApp/HouseInfo.cpp +++ b/GpApp/HouseInfo.cpp @@ -297,7 +297,7 @@ Boolean WarnLockingHouse (void) short hitWhat; // CenterAlert(kLockHouseAlert); - hitWhat = Alert(kLockHouseAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kLockHouseAlert); return (hitWhat == 1); } @@ -309,7 +309,7 @@ void HowToZeroScores (void) short hitWhat; // CenterAlert(kZeroScoresAlert); - hitWhat = Alert(kZeroScoresAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kZeroScoresAlert); switch (hitWhat) { diff --git a/GpApp/Input.cpp b/GpApp/Input.cpp index a358cc6..a7c5720 100644 --- a/GpApp/Input.cpp +++ b/GpApp/Input.cpp @@ -8,6 +8,7 @@ #include "PLToolUtils.h" #include "PLDialogs.h" #include "PLKeyEncoding.h" +#include "DialogManager.h" #include "Externs.h" #include "InputManager.h" #include "MainWindow.h" @@ -468,7 +469,7 @@ Boolean QuerySaveGame (void) InitCursor(); FlushEvents(everyEvent, 0); // CenterAlert(kSaveGameAlert); - hitWhat = Alert(kSaveGameAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kSaveGameAlert); if (hitWhat == kYesSaveGameButton) return (true); else diff --git a/GpApp/Map.cpp b/GpApp/Map.cpp index bc867e0..6d42fd0 100644 --- a/GpApp/Map.cpp +++ b/GpApp/Map.cpp @@ -9,6 +9,7 @@ #include "PLResources.h" #include "PLPasStr.h" #include "PLStandardColors.h" +#include "DialogManager.h" #include "Externs.h" #include "Environ.h" #include "House.h" @@ -726,7 +727,7 @@ Boolean QueryNewRoom (void) short hitWhat; // CenterAlert(kNewRoomAlert); - hitWhat = Alert(kNewRoomAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNewRoomAlert); if (hitWhat == kYesDoNewRoom) return (true); else diff --git a/GpApp/Menu.cpp b/GpApp/Menu.cpp index 0de6bb7..5edb9b5 100644 --- a/GpApp/Menu.cpp +++ b/GpApp/Menu.cpp @@ -773,7 +773,7 @@ void DoNotInDemo (void) short whoCares; // CenterAlert(kNotInDemoAlert); - whoCares = Alert(kNotInDemoAlert, nil); + whoCares = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNotInDemoAlert); } #endif @@ -786,7 +786,7 @@ void HeyYourPissingAHighScore (void) // CenterAlert(kNoHighScoreAlert); - whoCares = Alert(kNoHighScoreAlert, nil); + whoCares = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNoHighScoreAlert); } //-------------------------------------------------------------- OpenCloseEditWindows diff --git a/GpApp/Music.cpp b/GpApp/Music.cpp index dd8eb3b..1067bc6 100644 --- a/GpApp/Music.cpp +++ b/GpApp/Music.cpp @@ -1,5 +1,3 @@ - -#define _CRT_SECURE_NO_WARNINGS //============================================================================ //---------------------------------------------------------------------------- // Music.c @@ -9,6 +7,7 @@ #include "PLResources.h" #include "PLSound.h" +#include "DialogManager.h" #include "Environ.h" #include "Externs.h" #include "SoundSync.h" @@ -388,6 +387,6 @@ void TellHerNoMusic (void) short hitWhat; // CenterAlert(kNoMemForMusicAlert); - hitWhat = Alert(kNoMemForMusicAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNoMemForMusicAlert); } diff --git a/GpApp/ObjectAdd.cpp b/GpApp/ObjectAdd.cpp index a859ae9..a67d312 100644 --- a/GpApp/ObjectAdd.cpp +++ b/GpApp/ObjectAdd.cpp @@ -8,6 +8,7 @@ #include "PLToolUtils.h" #include "PLKeyEncoding.h" +#include "DialogManager.h" #include "Externs.h" #include "InputManager.h" #include "ObjectEdit.h" @@ -874,7 +875,7 @@ void ShoutNoMoreObjects (void) short hitWhat; // CenterAlert(kNoMoreObjectsAlert); - hitWhat = Alert(kNoMoreObjectsAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNoMoreObjectsAlert); } //-------------------------------------------------------------- HowManyCandleObjects @@ -1071,7 +1072,7 @@ void ShoutNoMoreSpecialObjects (void) short hitWhat; // CenterAlert(kNoMoreSpecialAlert); - hitWhat = Alert(kNoMoreSpecialAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNoMoreSpecialAlert); } #endif diff --git a/GpApp/Prefs.cpp b/GpApp/Prefs.cpp index 491a69a..cf79a88 100644 --- a/GpApp/Prefs.cpp +++ b/GpApp/Prefs.cpp @@ -6,6 +6,7 @@ //============================================================================ #include "PLPasStr.h" +#include "DialogManager.h" #include "Externs.h" #include "Environ.h" #include "FileManager.h" @@ -183,6 +184,6 @@ void BringUpDeletePrefsAlert (void) InitCursor(); // CenterAlert(kNewPrefsAlertID); - whoCares = Alert(kNewPrefsAlertID, nil); + whoCares = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNewPrefsAlertID); } diff --git a/GpApp/Room.cpp b/GpApp/Room.cpp index 294a07b..bfb4f4a 100644 --- a/GpApp/Room.cpp +++ b/GpApp/Room.cpp @@ -10,6 +10,7 @@ #include "PLPasStr.h" #include "PLStandardColors.h" #include "BitmapImage.h" +#include "DialogManager.h" #include "Externs.h" #include "FontFamily.h" #include "House.h" @@ -477,7 +478,7 @@ Boolean QueryDeleteRoom (void) short hitWhat; // CenterAlert(kDeleteRoomAlert); - hitWhat = Alert(kDeleteRoomAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kDeleteRoomAlert); if (hitWhat == kYesDoDeleteRoom) return (true); else diff --git a/GpApp/RoomInfo.cpp b/GpApp/RoomInfo.cpp index d8b3512..6b45653 100644 --- a/GpApp/RoomInfo.cpp +++ b/GpApp/RoomInfo.cpp @@ -930,7 +930,7 @@ void BitchAboutPICTNotFound (void) short hitWhat; // CenterAlert(kNoPICTFoundAlert); - hitWhat = Alert(kNoPICTFoundAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNoPICTFoundAlert); } #endif diff --git a/GpApp/SavedGames.cpp b/GpApp/SavedGames.cpp index 8f02634..dff4256 100644 --- a/GpApp/SavedGames.cpp +++ b/GpApp/SavedGames.cpp @@ -7,6 +7,7 @@ #include "PLStringCompare.h" +#include "DialogManager.h" #include "Externs.h" #include "FileManager.h" #include "House.h" @@ -165,7 +166,7 @@ void SavedGameMismatchError (StringPtr gameName) // CenterAlert(kSavedGameErrorAlert); ParamText(gameName, thisHouseName, PSTR(""), PSTR("")); - whoCares = Alert(kSavedGameErrorAlert, nil); + whoCares = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kSavedGameErrorAlert); } //-------------------------------------------------------------- OpenSavedGame diff --git a/GpApp/Settings.cpp b/GpApp/Settings.cpp index 4033c05..f786689 100644 --- a/GpApp/Settings.cpp +++ b/GpApp/Settings.cpp @@ -1373,6 +1373,6 @@ void BitchAboutChanges (void) short hitWhat; // CenterAlert(kChangesEffectAlert); - hitWhat = Alert(kChangesEffectAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kChangesEffectAlert); } diff --git a/GpApp/Sound.cpp b/GpApp/Sound.cpp index 26b56a5..73da180 100644 --- a/GpApp/Sound.cpp +++ b/GpApp/Sound.cpp @@ -8,6 +8,7 @@ #include "PLResources.h" #include "PLSound.h" +#include "DialogManager.h" #include "Externs.h" #include "MemoryManager.h" #include "ResourceManager.h" @@ -395,7 +396,7 @@ void TellHerNoSounds (void) short hitWhat; // CenterAlert(kNoMemForSoundsAlert); - hitWhat = Alert(kNoMemForSoundsAlert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNoMemForSoundsAlert); } //-------------------------------------------------------------- BitchAboutSM3 @@ -406,7 +407,7 @@ void BitchAboutSM3 (void) short hitWhat; // CenterAlert(kNoSoundManager3Alert); - hitWhat = Alert(kNoSoundManager3Alert, nil); + hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNoSoundManager3Alert); } diff --git a/GpApp/Utilities.cpp b/GpApp/Utilities.cpp index 257b480..30f16c6 100644 --- a/GpApp/Utilities.cpp +++ b/GpApp/Utilities.cpp @@ -13,6 +13,7 @@ #include "PLTimeTaggedVOSEvent.h" #include "QDPixMap.h" #include "BitmapImage.h" +#include "DialogManager.h" #include "Externs.h" #include "IconLoader.h" #include "InputManager.h" @@ -108,7 +109,7 @@ void RedAlert (short errorNumber) ParamText(errTitle, errMessage, errNumberString, PSTR("")); // CenterAlert(rDeathAlertID); - dummyInt = Alert(rDeathAlertID, nil); + dummyInt = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(rDeathAlertID); ExitToShell(); } diff --git a/PortabilityLayer/DialogManager.cpp b/PortabilityLayer/DialogManager.cpp index 5748bcd..25808f7 100644 --- a/PortabilityLayer/DialogManager.cpp +++ b/PortabilityLayer/DialogManager.cpp @@ -392,11 +392,15 @@ namespace PortabilityLayer { public: Dialog *LoadDialog(int16_t resID, Window *behindWindow) override; + int16_t DisplayAlert(int16_t alertResID) override; + DialogTemplate *LoadDialogTemplate(int16_t resID); static DialogManagerImpl *GetInstance(); private: + void PositionWindow(Window *window, const Rect &rect); + static DialogManagerImpl ms_instance; }; @@ -444,33 +448,7 @@ namespace PortabilityLayer wm->PutWindowBehind(window, behindWindow); - unsigned int displayWidth, displayHeight; - PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(&displayWidth, &displayHeight, nullptr); - - const unsigned int halfDisplayHeight = displayHeight / 2; - const unsigned int quarterDisplayWidth = displayHeight / 4; - const unsigned int halfDisplayWidth = displayWidth; - - const uint16_t dialogWidth = rect.Width(); - const uint16_t dialogHeight = rect.Height(); - - window->m_wmX = (static_cast(displayWidth) - static_cast(dialogWidth)) / 2; - - // We center dialogs vertically in one of 3 ways in this priority: - // - Centered at 1/3 until the top edge is at the 1/4 mark - // - Top edge aligned to 1/4 mark until bottom edge is at 3/4 mark - // - Centered on screen - - //if (displayHeight / 3 - dialogHeight / 2 >= displayHeight / 4) - if (displayHeight * 4 - dialogHeight * 6 >= displayHeight * 3) - { - //window->m_wmY = displayHeight / 3 - dialogHeight / 2; - window->m_wmY = (static_cast(displayHeight * 2) - static_cast(dialogHeight * 3)) / 6; - } - else if (dialogHeight * 2U <= displayHeight) - window->m_wmY = displayHeight / 4; - else - window->m_wmY = (static_cast(displayHeight) - static_cast(dialogHeight)) / 2; + PositionWindow(window, rect); DialogImpl *dialog = DialogImpl::Create(window, numItems); @@ -495,6 +473,61 @@ namespace PortabilityLayer return dialog; } + int16_t DialogManagerImpl::DisplayAlert(int16_t alertResID) + { + enum AlertStageBits + { + }; + + struct AlertResourceData + { + BERect m_rect; + BEInt16_t m_dialogTemplateResID; + + // Stages are supposed to correspond to how to behave when the alert is displayed multiple times. + // We just treat all alerts as stage 1. + BEUInt16_t m_stageData; + }; + + BEUInt16_t autoPosition; + autoPosition = static_cast(0); + + THandle alertResource = PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('ALRT', alertResID); + if (!alertResource) + return 0; + + GP_STATIC_ASSERT(sizeof(AlertResourceData) == 12); + + const size_t resSize = alertResource.MMBlock()->m_rmSelfRef->m_size; + if (resSize < 12) + { + alertResource.Dispose(); + return 0; + } + + AlertResourceData alertResData; + memcpy(&alertResData, *alertResource, 12); + + if (resSize == 14) + memcpy(&autoPosition, static_cast(*alertResource) + 12, 2); + + const uint16_t stageData = alertResData.m_stageData; + uint8_t boldIndexes[4]; + uint8_t soundIndexes[4]; + bool isVisible[4]; + for (int i = 0; i < 4; i++) + { + boldIndexes[i] = static_cast((stageData >> (i * 4)) & 0x1); + isVisible[i] = (((stageData >> (i * 4)) & 0x3) != 0); + soundIndexes[i] = static_cast((stageData >> (i * 4 + 2)) & 0x1); + } + + // If sound index is 0, play no sound + + PL_NotYetImplemented(); + return 0; + } + DialogTemplate *DialogManagerImpl::LoadDialogTemplate(int16_t resID) { ResourceManager *rm = ResourceManager::GetInstance(); @@ -535,6 +568,37 @@ namespace PortabilityLayer return dtemplate; } + void DialogManagerImpl::PositionWindow(Window *window, const Rect &rect) + { + unsigned int displayWidth, displayHeight; + PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(&displayWidth, &displayHeight, nullptr); + + const unsigned int halfDisplayHeight = displayHeight / 2; + const unsigned int quarterDisplayWidth = displayHeight / 4; + const unsigned int halfDisplayWidth = displayWidth; + + const uint16_t dialogWidth = rect.Width(); + const uint16_t dialogHeight = rect.Height(); + + window->m_wmX = (static_cast(displayWidth) - static_cast(dialogWidth)) / 2; + + // We center dialogs vertically in one of 3 ways in this priority: + // - Centered at 1/3 until the top edge is at the 1/4 mark + // - Top edge aligned to 1/4 mark until bottom edge is at 3/4 mark + // - Centered on screen + + //if (displayHeight / 3 - dialogHeight / 2 >= displayHeight / 4) + if (displayHeight * 4 - dialogHeight * 6 >= displayHeight * 3) + { + //window->m_wmY = displayHeight / 3 - dialogHeight / 2; + window->m_wmY = (static_cast(displayHeight * 2) - static_cast(dialogHeight * 3)) / 6; + } + else if (dialogHeight * 2U <= displayHeight) + window->m_wmY = displayHeight / 4; + else + window->m_wmY = (static_cast(displayHeight) - static_cast(dialogHeight)) / 2; + } + DialogManagerImpl *DialogManagerImpl::GetInstance() { return &ms_instance; diff --git a/PortabilityLayer/DialogManager.h b/PortabilityLayer/DialogManager.h index f487634..80cc160 100644 --- a/PortabilityLayer/DialogManager.h +++ b/PortabilityLayer/DialogManager.h @@ -14,6 +14,7 @@ namespace PortabilityLayer { public: virtual Dialog *LoadDialog(int16_t resID, Window *behindWindow) = 0; + virtual int16_t DisplayAlert(int16_t alertResID) = 0; static DialogManager *GetInstance(); }; diff --git a/PortabilityLayer/PLCore.cpp b/PortabilityLayer/PLCore.cpp index 14268a5..3d76eaa 100644 --- a/PortabilityLayer/PLCore.cpp +++ b/PortabilityLayer/PLCore.cpp @@ -113,12 +113,6 @@ void Delay(int ticks, UInt32 *endTickCount) *endTickCount = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetTickCount(); } -short Alert(int dialogID, void *unknown) -{ - PL_NotYetImplemented(); - return 0; -} - short FindWindow(Point point, WindowPtr *window) { short part = 0; diff --git a/PortabilityLayer/PLCore.h b/PortabilityLayer/PLCore.h index 3b850dc..d67908c 100644 --- a/PortabilityLayer/PLCore.h +++ b/PortabilityLayer/PLCore.h @@ -244,7 +244,6 @@ void SetCursor(CursPtr cursor); void SetBuiltinCursor(int builtinCursor); void Delay(int ticks, UInt32 *endTickCount); -short Alert(int dialogID, void *unknown); short FindWindow(Point point, WindowPtr *window); // Translates global coordinates to window coordinates, returns a region ID void DragWindow(WindowPtr window, Point start, Rect *bounds); // Drags the window (probably not implemented)