From 5fe6218c28f738b94d6f7f90408a5f6e0df05ae7 Mon Sep 17 00:00:00 2001 From: elasota Date: Wed, 1 Jan 2020 20:24:46 -0500 Subject: [PATCH] Add some initial widget functionality (prefs partly working) --- Common/CoreDefs.h | 91 ++-- GpApp/About.cpp | 6 +- GpApp/Banner.cpp | 2 +- GpApp/DialogUtils.cpp | 92 ++-- GpApp/Externs.h | 4 +- GpApp/HighScores.cpp | 20 +- GpApp/House.cpp | 9 +- GpApp/HouseIO.cpp | 2 +- GpApp/HouseInfo.cpp | 9 +- GpApp/Menu.cpp | 8 +- GpApp/ObjectDraw2.cpp | 2 +- GpApp/ObjectInfo.cpp | 104 ++--- GpApp/RoomInfo.cpp | 16 +- GpApp/SelectHouse.cpp | 21 +- GpApp/Settings.cpp | 433 +++++++----------- GpApp/StringUtils.cpp | 8 +- GpApp/StructuresInit2.cpp | 2 +- GpApp/Tools.cpp | 8 +- GpApp/Utilities.cpp | 25 +- GpD3D/GpFontHandler_FreeType2.cpp | 24 +- GpD3D/GpMemoryBuffer.cpp | 4 +- PictChecker/PictChecker.cpp | 4 +- PortabilityLayer/ByteSwap.cpp | 36 +- PortabilityLayer/CFileStream.h | 2 +- PortabilityLayer/DialogManager.cpp | 322 +++++++------ PortabilityLayer/DialogManager.h | 15 + PortabilityLayer/DisplayDeviceManager.cpp | 4 +- PortabilityLayer/FontRenderer.cpp | 80 +++- PortabilityLayer/HostFont.h | 2 + PortabilityLayer/IconLoader.cpp | 258 +++++++++++ PortabilityLayer/IconLoader.h | 21 + PortabilityLayer/MMBlock.cpp | 4 +- PortabilityLayer/MMBlock.h | 2 +- PortabilityLayer/MMHandleBlock.h | 2 +- PortabilityLayer/MemReaderStream.h | 2 +- PortabilityLayer/MemoryManager.cpp | 100 ++-- PortabilityLayer/PLArrayView.h | 17 + PortabilityLayer/PLArrayViewIterator.h | 152 ++++-- PortabilityLayer/PLButtonWidget.cpp | 54 +++ PortabilityLayer/PLButtonWidget.h | 21 + PortabilityLayer/PLCTabReducer.cpp | 28 ++ PortabilityLayer/PLCTabReducer.h | 17 + PortabilityLayer/PLCore.cpp | 147 +----- PortabilityLayer/PLCore.h | 6 +- PortabilityLayer/PLDialogs.cpp | 5 - PortabilityLayer/PLDialogs.h | 30 +- PortabilityLayer/PLHacks.cpp | 2 +- PortabilityLayer/PLHandle.cpp | 2 + PortabilityLayer/PLHandle.h | 50 +- PortabilityLayer/PLIconWidget.cpp | 49 ++ PortabilityLayer/PLIconWidget.h | 24 + PortabilityLayer/PLInvisibleWidget.cpp | 20 + PortabilityLayer/PLInvisibleWidget.h | 15 + PortabilityLayer/PLLabelWidget.cpp | 32 ++ PortabilityLayer/PLLabelWidget.h | 20 + PortabilityLayer/PLLowMem.h | 1 - PortabilityLayer/PLQDraw.cpp | 76 ++- PortabilityLayer/PLQDraw.h | 7 - PortabilityLayer/PLSound.cpp | 2 +- PortabilityLayer/PLSysCalls.cpp | 135 ++++++ PortabilityLayer/PLSysCalls.h | 8 + PortabilityLayer/PLTimeTaggedVOSEvent.cpp | 10 + PortabilityLayer/PLTimeTaggedVOSEvent.h | 1 + PortabilityLayer/PLWidgets.cpp | 77 ++++ PortabilityLayer/PLWidgets.h | 106 +++++ PortabilityLayer/PortabilityLayer.vcxproj | 19 +- .../PortabilityLayer.vcxproj.filters | 57 ++- PortabilityLayer/QDGraf.h | 3 + PortabilityLayer/QDManager.cpp | 5 + PortabilityLayer/QDPictDecoder.cpp | 30 +- PortabilityLayer/QDPictHeader.cpp | 2 +- PortabilityLayer/QDPixMap.cpp | 46 +- PortabilityLayer/QDPixMap.h | 9 +- PortabilityLayer/QDPort.cpp | 49 +- PortabilityLayer/QDPort.h | 15 +- PortabilityLayer/RenderedFont.h | 11 +- PortabilityLayer/RenderedFontMetrics.h | 13 + PortabilityLayer/ScanlineMask.cpp | 4 +- PortabilityLayer/ScopedArray.h | 4 +- PortabilityLayer/ScopedPtr.h | 4 +- PortabilityLayer/SharedTypes.h | 24 +- PortabilityLayer/SimpleImage.h | 22 + PortabilityLayer/UnsafePascalStr.h | 26 +- PortabilityLayer/WindowDef.cpp | 2 +- PortabilityLayer/WindowManager.cpp | 2 +- 85 files changed, 2131 insertions(+), 1074 deletions(-) create mode 100644 PortabilityLayer/IconLoader.cpp create mode 100644 PortabilityLayer/IconLoader.h create mode 100644 PortabilityLayer/PLButtonWidget.cpp create mode 100644 PortabilityLayer/PLButtonWidget.h create mode 100644 PortabilityLayer/PLCTabReducer.cpp create mode 100644 PortabilityLayer/PLCTabReducer.h create mode 100644 PortabilityLayer/PLIconWidget.cpp create mode 100644 PortabilityLayer/PLIconWidget.h create mode 100644 PortabilityLayer/PLInvisibleWidget.cpp create mode 100644 PortabilityLayer/PLInvisibleWidget.h create mode 100644 PortabilityLayer/PLLabelWidget.cpp create mode 100644 PortabilityLayer/PLLabelWidget.h delete mode 100644 PortabilityLayer/PLLowMem.h create mode 100644 PortabilityLayer/PLSysCalls.cpp create mode 100644 PortabilityLayer/PLSysCalls.h create mode 100644 PortabilityLayer/PLWidgets.cpp create mode 100644 PortabilityLayer/PLWidgets.h create mode 100644 PortabilityLayer/RenderedFontMetrics.h create mode 100644 PortabilityLayer/SimpleImage.h diff --git a/Common/CoreDefs.h b/Common/CoreDefs.h index 5c59708..11e296a 100644 --- a/Common/CoreDefs.h +++ b/Common/CoreDefs.h @@ -1,47 +1,44 @@ -#pragma once - -#ifndef __PL_COREDEFS_H__ -#define __PL_COREDEFS_H__ - -#if __cplusplus >= 199711L -#define PL_IS_CPP11 1 -#else -#define PL_IS_CPP11 0 -#endif - -#if PL_IS_CPP11 -#define PL_DELETED = delete -#define PL_STATIC_ASSERT(n) static_assert((n), "Static assert failed: " #n) -#else -#ifndef nullptr -#define nullptr 0 -#endif - -#ifndef override -#define override -#endif - -#ifndef final -#define final -#endif - -#define PL_DELETED - -template -struct __PL_StaticAssertHelper -{ -}; - -template<> -struct __PL_StaticAssertHelper -{ - int staticAssertFailed; -}; - -#define PL_STATIC_ASSERT(n) ((void)(&static_cast*>(nullptr)->staticAssertFailed)) - -#endif - -static const size_t PL_SYSTEM_MEMORY_ALIGNMENT = 16; - -#endif +#pragma once + +#if __cplusplus >= 199711L +#define GP_IS_CPP11 1 +#else +#define GP_IS_CPP11 0 +#endif + +#if GP_IS_CPP11 +#define GP_DELETED = delete +#define GP_STATIC_ASSERT(n) static_assert((n), "Static assert failed: " #n) +#else +#ifndef nullptr +#define nullptr 0 +#endif + +#ifndef override +#define override +#endif + +#ifndef final +#define final +#endif + +#define GP_DELETED + +template +struct __GpStaticAssertHelper +{ +}; + +template<> +struct __GpStaticAssertHelper +{ + int staticAssertFailed; +}; + +#define GP_STATIC_ASSERT(n) ((void)(&static_cast*>(nullptr)->staticAssertFailed)) + +#endif + +static const size_t GP_SYSTEM_MEMORY_ALIGNMENT = 16; + +#define GP_DEBUG_CONFIG 1 diff --git a/GpApp/About.cpp b/GpApp/About.cpp index db6106c..af61ad4 100644 --- a/GpApp/About.cpp +++ b/GpApp/About.cpp @@ -46,9 +46,6 @@ void DoAbout (void) VersRecHndl version; ControlHandle itemHandle; short itemType, hit, wasResFile; - ModalFilterUPP aboutFilterUPP; - - aboutFilterUPP = NewModalFilterUPP(AboutFilter); wasResFile = CurResFile(); UseResFile(thisMac.thisResFile); @@ -84,14 +81,13 @@ void DoAbout (void) do // Loop until user wants to exit { - ModalDialog(aboutFilterUPP, &hit); + ModalDialog(AboutFilter, &hit); } while ((hit != kOkayButton) && (okayButtScanlineMask != nil)); if (okayButtScanlineMask != nil) okayButtScanlineMask->Destroy(); // Clean up! DisposeDialog(aboutDialog); - DisposeModalFilterUPP(aboutFilterUPP); UseResFile(wasResFile); } diff --git a/GpApp/Banner.cpp b/GpApp/Banner.cpp index 2634418..9585dfa 100644 --- a/GpApp/Banner.cpp +++ b/GpApp/Banner.cpp @@ -217,7 +217,7 @@ void DisplayStarsRemaining (void) else { LoadScaledGraphic(surface, kStarsRemainingPICT, &bounds); - const Point textPoint = Point::Create(bounds.left + 102 - (StringWidth(theStr) / 2), bounds.top + 23); + const Point textPoint = Point::Create(bounds.left + 102 - (surface->MeasureString(theStr) / 2), bounds.top + 23); ColorText(surface, textPoint, theStr, 4L); } diff --git a/GpApp/DialogUtils.cpp b/GpApp/DialogUtils.cpp index 029c92f..6b2eada 100644 --- a/GpApp/DialogUtils.cpp +++ b/GpApp/DialogUtils.cpp @@ -7,10 +7,10 @@ #include "DialogManager.h" #include "PLArrayView.h" #include "PLControlDefinitions.h" -#include "PLLowMem.h" #include "PLNumberFormatting.h" #include "PLPasStr.h" #include "PLStandardColors.h" +#include "PLWidgets.h" #include "QDStandardPalette.h" #include "DialogUtils.h" #include "Externs.h" @@ -33,7 +33,7 @@ void BringUpDialog (Dialog **theDialog, short dialogID) // CenterDialog(dialogID); if (*theDialog == nil) RedAlert(kErrDialogDidntLoad); - SetPort((GrafPtr)*theDialog); + SetGraphicsPort(&(*theDialog)->GetWindow()->m_graf); ShowWindow((*theDialog)->GetWindow()); DrawDefaultButton(*theDialog); } @@ -342,11 +342,12 @@ void FlashDialogButton (Dialog *theDialog, short itemNumber) ControlHandle itemHandle; UInt32 dummyLong; short itemType; - - GetDialogItem(theDialog, itemNumber, &itemType, &itemHandle, &itemRect); - HiliteControl(itemHandle, kControlButtonPart); + + PortabilityLayer::Widget *widget = theDialog->GetItems()[itemNumber - 1].GetWidget(); + + widget->SetHighlightStyle(kControlButtonPart); Delay(8, &dummyLong); - HiliteControl(itemHandle, 0); + widget->SetHighlightStyle(0); } //-------------------------------------------------------------- DrawDefaultButton @@ -355,10 +356,9 @@ void FlashDialogButton (Dialog *theDialog, short itemNumber) void DrawDefaultButton (Dialog *theDialog) { - DialogItem *firstItem = *theDialog->GetItems().begin(); - Rect itemRect = firstItem->GetRect(); - - DrawSurface *surface = theDialog->GetWindow()->GetDrawSurface(); + const PortabilityLayer::DialogItem &firstItem = *theDialog->GetItems().begin(); + Rect itemRect = firstItem.GetWidget()->GetRect(); + DrawSurface *surface = theDialog->GetWindow()->GetDrawSurface(); InsetRect(&itemRect, -4, -4); @@ -369,7 +369,7 @@ void DrawDefaultButton (Dialog *theDialog) for (int yOffset = 0; yOffset < 3; yOffset++) { const Rect offsetRect = itemRect + Point::Create(xOffset, yOffset); - surface->FrameRoundRect(itemRect, 8, 8); + surface->FrameRoundRect(offsetRect, 8, 8); } } @@ -437,12 +437,7 @@ void GetDialogItemValue (Dialog *theDialog, short item, short *theState) void SetDialogItemValue (Dialog *theDialog, short item, short theState) { - Rect itemRect; - ControlHandle itemHandle; - short itemType; - - GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); - SetControlValue(itemHandle, theState); + theDialog->GetItems()[item - 1].GetWidget()->SetState(theState); } //-------------------------------------------------------------- ToggleDialogItemValue @@ -500,7 +495,7 @@ void GetDialogNumFromStr (Dialog *theDialog, short item, long *theNumber) void GetDialogItemRect (Dialog *theDialog, short item, Rect *theRect) { - *theRect = theDialog->GetItems()[item - 1]->GetRect(); + *theRect = theDialog->GetItems()[item - 1].GetWidget()->GetRect(); } //-------------------------------------------------------------- SetDialogItemRect @@ -539,18 +534,10 @@ void OffsetDialogItemRect (Dialog *theDialog, short item, short h, short v) void SelectFromRadioGroup (Dialog *dial, short which, short first, short last) { - Rect iRect; - ControlHandle iHandle; - short iType, i; + for (int i = first; i <= last; i++) + dial->GetItems()[i - 1].GetWidget()->SetState(0); - for (i = first; i <= last; i++) - { - GetDialogItem(dial, i, &iType, &iHandle, &iRect); - SetControlValue(iHandle, (short)false); - } - - GetDialogItem(dial, which, &iType, &iHandle, &iRect); - SetControlValue(iHandle, (short)true); + dial->GetItems()[which - 1].GetWidget()->SetState(1); } //-------------------------------------------------------------- AddMenuToPopUp @@ -614,9 +601,8 @@ void MyDisableControl (Dialog *theDialog, short whichItem) Rect iRect; ControlHandle iHandle; short iType; - - GetDialogItem(theDialog, whichItem, &iType, &iHandle, &iRect); - HiliteControl(iHandle, kInactive); + + theDialog->GetItems()[whichItem - 1].GetWidget()->SetEnabled(false); } //-------------------------------------------------------------- DrawDialogUserText @@ -626,22 +612,20 @@ void MyDisableControl (Dialog *theDialog, short whichItem) void DrawDialogUserText (Dialog *dial, short item, StringPtr text, Boolean invert) { - Rect iRect; ControlHandle iHandle; - Str255 newString, stringCopy; - short iType, textLong, i, inset; + Str255 stringCopy; + short iType, i, inset; DrawSurface *surface = dial->GetWindow()->GetDrawSurface(); surface->SetApplicationFont(9, PortabilityLayer::FontFamilyFlag_None); 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]; + + Rect iRect = dial->GetItems()[item - 1].GetWidget()->GetRect(); + + if ((surface->MeasureString(stringCopy) + 2) > (iRect.right - iRect.left)) + CollapseStringToWidth(surface, stringCopy, iRect.right - iRect.left - 2); OffsetRect(&iRect, 0, 1); @@ -650,12 +634,20 @@ void DrawDialogUserText (Dialog *dial, short item, StringPtr text, Boolean inver surface->SetForeColor(StdColors::Black()); OffsetRect(&iRect, 0, -1); - - inset = ((iRect.right - iRect.left) - (StringWidth(stringCopy) + 2)) / 2; + + short strWidth = surface->MeasureString(stringCopy); + inset = ((iRect.right - iRect.left) - (strWidth + 2)) / 2; iRect.left += inset; iRect.right -= inset; - - TETextBox(newString, textLong, &iRect, teCenter); + + // Draw centered + PL_NotYetImplemented_TODO("Clip to iRect"); + + const int32_t ascender = surface->MeasureFontAscender(); + + const Point centeredDrawPoint = Point::Create((iRect.left + iRect.right - strWidth) / 2, (iRect.top + iRect.bottom + ascender) / 2); + surface->DrawString(centeredDrawPoint, stringCopy); + if (invert) { OffsetRect(&iRect, 0, 1); @@ -680,8 +672,8 @@ void DrawDialogUserText2 (Dialog *dial, short item, StringPtr text) PasStringCopy(text, stringCopy); GetDialogItem(dial, item, &iType, &iHandle, &iRect); - if ((StringWidth(stringCopy) + 2) > (iRect.right - iRect.left)) - CollapseStringToWidth(stringCopy, iRect.right - iRect.left - 2); + if ((surface->MeasureString(stringCopy) + 2) > (iRect.right - iRect.left)) + CollapseStringToWidth(surface, stringCopy, iRect.right - iRect.left - 2); surface->SetForeColor(StdColors::Black()); surface->DrawString(Point::Create(iRect.left, iRect.bottom), stringCopy); @@ -723,12 +715,8 @@ void FrameDialogItem (Dialog *theDialog, short item) void FrameDialogItemC (Dialog *theDialog, short item, long color) { - Rect itemRect; - ControlHandle itemHandle; - short itemType; DrawSurface *surface = theDialog->GetWindow()->GetDrawSurface(); - - GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); + const Rect itemRect = theDialog->GetItems()[item - 1].GetWidget()->GetRect(); const PortabilityLayer::RGBAColor wasColor = surface->GetForeColor(); surface->SetForeColor(PortabilityLayer::StandardPalette::GetInstance()->GetColors()[color]); diff --git a/GpApp/Externs.h b/GpApp/Externs.h index 0ccb0e1..4d16fea 100644 --- a/GpApp/Externs.h +++ b/GpApp/Externs.h @@ -183,7 +183,7 @@ void PasStringConcat (StringPtr, const PLPasStr &); void GetLineOfText (StringPtr, short, StringPtr); void WrapText (StringPtr, short); void GetFirstWordOfString (StringPtr, StringPtr); -void CollapseStringToWidth (StringPtr, short); +void CollapseStringToWidth (DrawSurface *, StringPtr, short); void GetChooserName (StringPtr); StringPtr GetLocalizedString (short, StringPtr); @@ -198,7 +198,7 @@ void RedAlert (short); void LoadGraphic (DrawSurface *, short); void LoadScaledGraphic (DrawSurface *, short, Rect *); void LargeIconPlot (Rect *, short); -void DrawCIcon (short, short, short); +void DrawCIcon (DrawSurface *surface, short, short, short); char KeyMapOffsetFromRawKey (char); long LongSquareRoot (long); Boolean WaitForInputEvent (short); diff --git a/GpApp/HighScores.cpp b/GpApp/HighScores.cpp index 26ec80c..451af40 100644 --- a/GpApp/HighScores.cpp +++ b/GpApp/HighScores.cpp @@ -141,11 +141,11 @@ void DrawHighScores (DrawSurface *surface) PasStringConcat(tempStr, thisHouseName); PasStringConcat(tempStr, PSTR(" ¥")); - const Point scoreShadowPoint = Point::Create(scoreLeft + ((kScoreWide - StringWidth(tempStr)) / 2) - 1, dropIt - 66); + const Point scoreShadowPoint = Point::Create(scoreLeft + ((kScoreWide - surface->MeasureString(tempStr)) / 2) - 1, dropIt - 66); surface->SetForeColor(blackColor); surface->DrawString(scoreShadowPoint, tempStr); - const Point scoreTextPoint = Point::Create(scoreLeft + ((kScoreWide - StringWidth(tempStr)) / 2), dropIt - 65); + const Point scoreTextPoint = Point::Create(scoreLeft + ((kScoreWide - surface->MeasureString(tempStr)) / 2), dropIt - 65); surface->SetForeColor(cyanColor); surface->DrawString(scoreTextPoint, tempStr); @@ -154,7 +154,7 @@ void DrawHighScores (DrawSurface *surface) thisHousePtr = *thisHouse; // message for score #1 PasStringCopy(thisHousePtr->highScores.banner, tempStr); - bannerWidth = StringWidth(tempStr); + bannerWidth = surface->MeasureString(tempStr); surface->SetForeColor(blackColor); const Point topScoreShadowPoint = Point::Create(scoreLeft + (kScoreWide - bannerWidth) / 2, dropIt - kKimsLifted); surface->DrawString(topScoreShadowPoint, tempStr); @@ -490,9 +490,6 @@ void GetHighScoreName (short place) Str255 scoreStr, placeStr, tempStr; short item; Boolean leaving; - ModalFilterUPP nameFilterUPP; - - nameFilterUPP = NewModalFilterUPP(NameFilter); InitCursor(); NumToString(theScore, scoreStr); @@ -507,7 +504,7 @@ void GetHighScoreName (short place) while (!leaving) { - ModalDialog(nameFilterUPP, &item); + ModalDialog(NameFilter, &item); if (item == kOkayButton) { @@ -518,7 +515,6 @@ void GetHighScoreName (short place) } DisposeDialog(theDial); - DisposeModalFilterUPP(nameFilterUPP); } //-------------------------------------------------------------- UpdateBannerDialog @@ -599,9 +595,6 @@ void GetHighScoreBanner (void) Str255 tempStr; short item; Boolean leaving; - ModalFilterUPP bannerFilterUPP; - - bannerFilterUPP = NewModalFilterUPP(BannerFilter); PlayPrioritySound(kEnergizeSound, kEnergizePriority); BringUpDialog(&theDial, kHighBannerDialogID); @@ -611,7 +604,7 @@ void GetHighScoreBanner (void) while (!leaving) { - ModalDialog(bannerFilterUPP, &item); + ModalDialog(BannerFilter, &item); if (item == kOkayButton) { @@ -620,9 +613,6 @@ void GetHighScoreBanner (void) leaving = true; } } - - DisposeDialog(theDial); - DisposeModalFilterUPP(bannerFilterUPP); } //-------------------------------------------------------------- OpenHighScoresFile diff --git a/GpApp/House.cpp b/GpApp/House.cpp index bfa3b8e..b3030a2 100644 --- a/GpApp/House.cpp +++ b/GpApp/House.cpp @@ -623,7 +623,7 @@ Boolean GoToFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateGoToDialog(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -651,9 +651,7 @@ Boolean GoToFilter (Dialog *dial, EventRecord *event, short *item) long tempLong; short item, roomToGoTo; Boolean leaving, canceled; - ModalFilterUPP goToFilterUPP; - - goToFilterUPP = NewModalFilterUPP(GoToFilter); + BringUpDialog(&theDialog, kGoToDialogID); if (GetFirstRoomNumber() == thisRoomNumber) @@ -670,7 +668,7 @@ Boolean GoToFilter (Dialog *dial, EventRecord *event, short *item) while (!leaving) { - ModalDialog(goToFilterUPP, &item); + ModalDialog(GoToFilter, &item); if (item == kOkayButton) { @@ -700,7 +698,6 @@ Boolean GoToFilter (Dialog *dial, EventRecord *event, short *item) } DisposeDialog(theDialog); - DisposeModalFilterUPP(goToFilterUPP); if (!canceled) { diff --git a/GpApp/HouseIO.cpp b/GpApp/HouseIO.cpp index eaa4b88..b390876 100644 --- a/GpApp/HouseIO.cpp +++ b/GpApp/HouseIO.cpp @@ -612,7 +612,7 @@ Boolean ReadHouse (void) short whichRoom; // There should be no padding remaining the house type - PL_STATIC_ASSERT(sizeof(houseType) - sizeof(roomType) == houseType::kBinaryDataSize + 2); + GP_STATIC_ASSERT(sizeof(houseType) - sizeof(roomType) == houseType::kBinaryDataSize + 2); if (!houseOpen) { diff --git a/GpApp/HouseInfo.cpp b/GpApp/HouseInfo.cpp index 255f7e2..6041ebe 100644 --- a/GpApp/HouseInfo.cpp +++ b/GpApp/HouseInfo.cpp @@ -166,7 +166,7 @@ Boolean HouseFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateHouseInfoDialog(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -208,9 +208,7 @@ void DoHouseInfo (void) short item, numRooms, version; char wasState; Boolean leaving; - ModalFilterUPP houseFilterUPP; - - houseFilterUPP = NewModalFilterUPP(HouseFilter); + tempPhoneBit = phoneBitSet; numRooms = RealRoomNumberCount(); @@ -246,7 +244,7 @@ void DoHouseInfo (void) while (!leaving) { - ModalDialog(houseFilterUPP, &item); + ModalDialog(HouseFilter, &item); if (item == kOkayButton) { @@ -290,7 +288,6 @@ void DoHouseInfo (void) } InitCursor(); DisposeDialog(houseInfoDialog); - DisposeModalFilterUPP(houseFilterUPP); } //-------------------------------------------------------------- WarnLockingHouse diff --git a/GpApp/Menu.cpp b/GpApp/Menu.cpp index 6cbd872..b07456c 100644 --- a/GpApp/Menu.cpp +++ b/GpApp/Menu.cpp @@ -690,7 +690,7 @@ Boolean ResumeFilter (Dialog *dial, EventRecord *event, short *item) case updateEvt: if ((WindowPtr)event->message == dial->GetWindow()) { - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateResumeDialog(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -719,9 +719,6 @@ short QueryResumeGame (void) short hitWhat, hadGliders; char wasState; Boolean leaving; - ModalFilterUPP resumeFilterUPP; - - resumeFilterUPP = NewModalFilterUPP(ResumeFilter); // get score & num. gliders thisHousePtr = *thisHouse; @@ -746,14 +743,13 @@ short QueryResumeGame (void) while (!leaving) { - ModalDialog(resumeFilterUPP, &hitWhat); + ModalDialog(ResumeFilter, &hitWhat); if ((hitWhat == kSheWantsNewGame) || (hitWhat == kSheWantsResumeGame)) { leaving = true; } } DisposeDialog(theDial); - DisposeModalFilterUPP(resumeFilterUPP); return (hitWhat); } diff --git a/GpApp/ObjectDraw2.cpp b/GpApp/ObjectDraw2.cpp index 41143f7..598837f 100644 --- a/GpApp/ObjectDraw2.cpp +++ b/GpApp/ObjectDraw2.cpp @@ -1067,7 +1067,7 @@ void DrawCalendar (Rect *theRect) GetTime(&timeRec); GetIndString(monthStr, kMonthStringID, timeRec.month); - const Point textPos = Point::Create(theRect->left + ((64 - StringWidth(monthStr)) / 2), theRect->top + 55); + const Point textPos = Point::Create(theRect->left + ((64 - backSrcMap->MeasureString(monthStr)) / 2), theRect->top + 55); ColorText(backSrcMap, textPos, monthStr, kDarkFleshColor); } diff --git a/GpApp/ObjectInfo.cpp b/GpApp/ObjectInfo.cpp index 30cbe48..331728a 100644 --- a/GpApp/ObjectInfo.cpp +++ b/GpApp/ObjectInfo.cpp @@ -386,7 +386,7 @@ Boolean BlowerFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateBlowerInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -421,7 +421,7 @@ Boolean FurnitureFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateFurnitureInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -456,7 +456,7 @@ Boolean CustPictFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateCustPictInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -497,7 +497,7 @@ Boolean SwitchFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateSwitchInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -543,7 +543,7 @@ Boolean TriggerFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateTriggerInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -592,7 +592,7 @@ Boolean LightFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateLightInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -646,7 +646,7 @@ Boolean ApplianceFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateApplianceInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -695,7 +695,7 @@ Boolean MicrowaveFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateMicrowaveInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -736,7 +736,7 @@ Boolean GreaseFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateGreaseInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -771,7 +771,7 @@ Boolean InvisBonusFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateInvisBonusInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -812,7 +812,7 @@ Boolean TransFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateTransInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -866,7 +866,7 @@ Boolean EnemyFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateEnemyInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -915,7 +915,7 @@ Boolean FlowerFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateFlowerInfo(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -936,9 +936,6 @@ void DoBlowerObjectInfo (short what) 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); @@ -995,7 +992,7 @@ void DoBlowerObjectInfo (short what) while (!leaving) { - ModalDialog(blowerFilterUPP, &item); + ModalDialog(BlowerFilter, &item); if (item == kOkayButton) { @@ -1092,7 +1089,6 @@ void DoBlowerObjectInfo (short what) } DisposeDialog(infoDial); - DisposeModalFilterUPP(blowerFilterUPP); if (doReturn) { @@ -1109,9 +1105,6 @@ void DoFurnitureObjectInfo (void) Str255 numberStr, kindStr; short item; Boolean leaving, doReturn; - ModalFilterUPP furnitureFilterUPP; - - furnitureFilterUPP = NewModalFilterUPP(FurnitureFilter); if (objActive == kInitialGliderSelected) { @@ -1145,7 +1138,7 @@ void DoFurnitureObjectInfo (void) while (!leaving) { - ModalDialog(furnitureFilterUPP, &item); + ModalDialog(FurnitureFilter, &item); if (item == kOkayButton) leaving = true; @@ -1157,7 +1150,6 @@ void DoFurnitureObjectInfo (void) } DisposeDialog(infoDial); - DisposeModalFilterUPP(furnitureFilterUPP); if (doReturn) { @@ -1175,9 +1167,6 @@ void DoCustPictObjectInfo (void) long wasPict; short item; Boolean leaving; - ModalFilterUPP custPictFilterUPP; - - custPictFilterUPP = NewModalFilterUPP(CustPictFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); @@ -1202,7 +1191,7 @@ void DoCustPictObjectInfo (void) while (!leaving) { - ModalDialog(custPictFilterUPP, &item); + ModalDialog(CustPictFilter, &item); if (item == kOkayButton) { @@ -1260,7 +1249,6 @@ void DoCustPictObjectInfo (void) } DisposeDialog(infoDial); - DisposeModalFilterUPP(custPictFilterUPP); } //-------------------------------------------------------------- DoSwitchObjectInfo @@ -1271,9 +1259,6 @@ void DoSwitchObjectInfo (void) 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); @@ -1310,7 +1295,7 @@ void DoSwitchObjectInfo (void) while (!leaving) { - ModalDialog(switchFilterUPP, &item); + ModalDialog(SwitchFilter, &item); if (item == kOkayButton) { @@ -1363,7 +1348,6 @@ void DoSwitchObjectInfo (void) } DisposeDialog(infoDial); - DisposeModalFilterUPP(switchFilterUPP); if (doLink) { @@ -1394,9 +1378,6 @@ void DoTriggerObjectInfo (void) 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); @@ -1437,7 +1418,7 @@ void DoTriggerObjectInfo (void) while (!leaving) { - ModalDialog(triggerFilterUPP, &item); + ModalDialog(TriggerFilter, &item); if (item == kOkayButton) { @@ -1519,7 +1500,6 @@ void DoTriggerObjectInfo (void) } DisposeDialog(infoDial); - DisposeModalFilterUPP(triggerFilterUPP); if (doLink) { @@ -1549,9 +1529,6 @@ void DoLightObjectInfo (void) 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); @@ -1578,7 +1555,7 @@ void DoLightObjectInfo (void) while (!leaving) { - ModalDialog(lightFilterUPP, &item); + ModalDialog(LightFilter, &item); if (item == kOkayButton) { @@ -1618,7 +1595,6 @@ void DoLightObjectInfo (void) } DisposeDialog(infoDial); - DisposeModalFilterUPP(lightFilterUPP); if (doReturn) { @@ -1636,9 +1612,6 @@ void DoApplianceObjectInfo (short what) long delay; short item, initial; Boolean leaving, doReturn; - ModalFilterUPP applianceFilterUPP; - - applianceFilterUPP = NewModalFilterUPP(ApplianceFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); @@ -1670,7 +1643,7 @@ void DoApplianceObjectInfo (short what) while (!leaving) { - ModalDialog(applianceFilterUPP, &item); + ModalDialog(ApplianceFilter, &item); if (item == kOkayButton) { @@ -1734,7 +1707,6 @@ void DoApplianceObjectInfo (short what) } DisposeDialog(infoDial); - DisposeModalFilterUPP(applianceFilterUPP); if (doReturn) { @@ -1751,9 +1723,6 @@ void DoMicrowaveObjectInfo (void) 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); @@ -1788,7 +1757,7 @@ void DoMicrowaveObjectInfo (void) while (!leaving) { - ModalDialog(microwaveFilterUPP, &item); + ModalDialog(MicrowaveFilter, &item); if (item == kOkayButton) { @@ -1858,7 +1827,6 @@ void DoMicrowaveObjectInfo (void) } DisposeDialog(infoDial); - DisposeModalFilterUPP(microwaveFilterUPP); if (doReturn) { @@ -1875,9 +1843,6 @@ void DoGreaseObjectInfo (void) 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); @@ -1895,7 +1860,7 @@ void DoGreaseObjectInfo (void) while (!leaving) { - ModalDialog(greaseFilterUPP, &item); + ModalDialog(GreaseFilter, &item); if (item == kOkayButton) { @@ -1932,7 +1897,6 @@ void DoGreaseObjectInfo (void) } DisposeDialog(infoDial); - DisposeModalFilterUPP(greaseFilterUPP); if (doReturn) { @@ -1949,9 +1913,6 @@ void DoInvisBonusObjectInfo (void) Str255 numberStr, kindStr; short item; Boolean leaving, doReturn; - ModalFilterUPP invisBonusFilterUPP; - - invisBonusFilterUPP = NewModalFilterUPP(InvisBonusFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); @@ -1982,7 +1943,7 @@ void DoInvisBonusObjectInfo (void) while (!leaving) { - ModalDialog(invisBonusFilterUPP, &item); + ModalDialog(InvisBonusFilter, &item); if (item == kOkayButton) { @@ -2045,7 +2006,6 @@ void DoInvisBonusObjectInfo (void) } DisposeDialog(infoDial); - DisposeModalFilterUPP(invisBonusFilterUPP); if (doReturn) { @@ -2062,9 +2022,6 @@ void DoTransObjectInfo (short what) 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); @@ -2108,7 +2065,7 @@ void DoTransObjectInfo (short what) while (!leaving) { - ModalDialog(transFilterUPP, &item); + ModalDialog(TransFilter, &item); if (item == kOkayButton) { @@ -2155,7 +2112,6 @@ void DoTransObjectInfo (short what) } DisposeDialog(infoDial); - DisposeModalFilterUPP(transFilterUPP); if (doLink) { @@ -2186,9 +2142,6 @@ void DoEnemyObjectInfo (short what) long delay; short item, initial; Boolean leaving, doReturn; - ModalFilterUPP enemyFilterUPP; - - enemyFilterUPP = NewModalFilterUPP(EnemyFilter); NumToString(objActive + 1, numberStr); GetIndString(kindStr, kObjectNameStrings, thisRoom->objects[objActive].what); @@ -2220,7 +2173,7 @@ void DoEnemyObjectInfo (short what) while (!leaving) { - ModalDialog(enemyFilterUPP, &item); + ModalDialog(EnemyFilter, &item); if (item == kOkayButton) { @@ -2278,7 +2231,6 @@ void DoEnemyObjectInfo (short what) } DisposeDialog(infoDial); - DisposeModalFilterUPP(enemyFilterUPP); if (doReturn) { @@ -2295,9 +2247,6 @@ void DoFlowerObjectInfo (void) 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); @@ -2316,7 +2265,7 @@ void DoFlowerObjectInfo (void) while (!leaving) { - ModalDialog(flowerFilterUPP, &item); + ModalDialog(FlowerFilter, &item); if (item == kOkayButton) { @@ -2377,7 +2326,6 @@ void DoFlowerObjectInfo (void) } DisposeDialog(infoDial); - DisposeModalFilterUPP(flowerFilterUPP); if (doReturn) { diff --git a/GpApp/RoomInfo.cpp b/GpApp/RoomInfo.cpp index 5f402dd..c4dc59a 100644 --- a/GpApp/RoomInfo.cpp +++ b/GpApp/RoomInfo.cpp @@ -406,7 +406,7 @@ Boolean RoomFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateRoomInfoDialog(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -434,11 +434,8 @@ void DoRoomInfo (void) short item, i, newBack; char wasState; Boolean leaving, wasFirstRoom, forceDraw; - ModalFilterUPP roomFilterUPP; PLError_t theErr; - roomFilterUPP = NewModalFilterUPP(RoomFilter); - tileOver = -1; cursorIs = kArrowCursor; tempBack = thisRoom->background; @@ -503,7 +500,7 @@ void DoRoomInfo (void) while (!leaving) { - ModalDialog(roomFilterUPP, &item); + ModalDialog(RoomFilter, &item); if (item == kOkayButton) { @@ -598,7 +595,6 @@ void DoRoomInfo (void) InitCursor(); DisposeDialog(roomInfoDialog); - DisposeModalFilterUPP(roomFilterUPP); // KillOffScreenPixMap(tileSrcMap); DisposeGWorld(tileSrcMap); @@ -727,7 +723,7 @@ Boolean OriginalArtFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateOriginalArt(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -750,9 +746,6 @@ short ChooseOriginalArt (short was) long longID; short item, newPictID, tempShort, wasPictID; Boolean leaving; - ModalFilterUPP originalArtFilterUPP; - - originalArtFilterUPP = NewModalFilterUPP(OriginalArtFilter); if (was < kUserBackground) was = kUserBackground; @@ -790,7 +783,7 @@ short ChooseOriginalArt (short was) while (!leaving) { - ModalDialog(originalArtFilterUPP, &item); + ModalDialog(OriginalArtFilter, &item); if (item == kOkayButton) { @@ -855,7 +848,6 @@ short ChooseOriginalArt (short was) } DisposeDialog(theDialog); - DisposeModalFilterUPP(originalArtFilterUPP); return (newPictID); } diff --git a/GpApp/SelectHouse.cpp b/GpApp/SelectHouse.cpp index 4571b4c..ed89a64 100644 --- a/GpApp/SelectHouse.cpp +++ b/GpApp/SelectHouse.cpp @@ -157,7 +157,7 @@ void PageUpHouses (Dialog *theDial) { GetDialogItemRect(theDial, kScrollUpItem, &tempRect); HideDialogItem(theDial, kScrollUpItem); - DrawCIcon(kGrayedOutUpArrow, tempRect.left, tempRect.top); + DrawCIcon(surface, kGrayedOutUpArrow, tempRect.left, tempRect.top); } QSetRect(&tempRect, 8, 39, 421, 223); @@ -191,7 +191,7 @@ void PageDownHouses (Dialog *theDial) { GetDialogItemRect(theDial, kScrollDownItem, &tempRect); HideDialogItem(theDial, kScrollDownItem); - DrawCIcon(kGrayedOutDownArrow, tempRect.left, tempRect.top); + DrawCIcon(surface, kGrayedOutDownArrow, tempRect.left, tempRect.top); } QSetRect(&tempRect, 8, 39, 421, 223); @@ -367,20 +367,20 @@ void DoLoadHouse (void) Dialog *theDial; short i, item, wasIndex, screenCount; Boolean leaving, whoCares; - ModalFilterUPP loadFilterUPP; - - loadFilterUPP = NewModalFilterUPP(LoadFilter); BringUpDialog(&theDial, kLoadHouseDialogID); + + DrawSurface *surface = theDial->GetWindow()->GetDrawSurface(); + if (housesFound <= kDispFiles) { GetDialogItemRect(theDial, kScrollUpItem, &tempRect); HideDialogItem(theDial, kScrollUpItem); - DrawCIcon(kGrayedOutUpArrow, tempRect.left, tempRect.top); + DrawCIcon(surface, kGrayedOutUpArrow, tempRect.left, tempRect.top); GetDialogItemRect(theDial, kScrollDownItem, &tempRect); HideDialogItem(theDial, kScrollDownItem); - DrawCIcon(kGrayedOutDownArrow, tempRect.left, tempRect.top); + DrawCIcon(surface, kGrayedOutDownArrow, tempRect.left, tempRect.top); } else { @@ -388,13 +388,13 @@ void DoLoadHouse (void) { GetDialogItemRect(theDial, kScrollUpItem, &tempRect); HideDialogItem(theDial, kScrollUpItem); - DrawCIcon(kGrayedOutUpArrow, tempRect.left, tempRect.top); + DrawCIcon(surface, kGrayedOutUpArrow, tempRect.left, tempRect.top); } else if (thisHouseIndex > (housesFound - kDispFiles)) { GetDialogItemRect(theDial, kScrollDownItem, &tempRect); HideDialogItem(theDial, kScrollDownItem); - DrawCIcon(kGrayedOutDownArrow, tempRect.left, tempRect.top); + DrawCIcon(surface, kGrayedOutDownArrow, tempRect.left, tempRect.top); } } wasIndex = thisHouseIndex; @@ -415,7 +415,7 @@ void DoLoadHouse (void) while (!leaving) { - ModalDialog(loadFilterUPP, &item); + ModalDialog(LoadFilter, &item); if (item == kOkayButton) { @@ -516,7 +516,6 @@ void DoLoadHouse (void) } DisposeDialog(theDial); - DisposeModalFilterUPP(loadFilterUPP); } #endif diff --git a/GpApp/Settings.cpp b/GpApp/Settings.cpp index d080602..658cf7c 100644 --- a/GpApp/Settings.cpp +++ b/GpApp/Settings.cpp @@ -9,6 +9,7 @@ #include "PLSound.h" #include "PLStandardColors.h" #include "PLTextUtils.h" +#include "PLTimeTaggedVOSEvent.h" #include "DialogManager.h" #include "DialogUtils.h" #include "Externs.h" @@ -79,7 +80,7 @@ void DisplayUpdate (Dialog *); Boolean DisplayFilter (Dialog *, EventRecord *, short *); void DoDisplayPrefs (void); void SetAllDefaults (void); -void FlashSettingsButton (short); +void FlashSettingsButton (DrawSurface *, short); void UpdateSettingsMain (Dialog *); Boolean PrefsFilter (Dialog *, EventRecord *, short *); void BitchAboutChanges (void); @@ -204,7 +205,7 @@ Boolean BrainsFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateSettingsBrains(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -225,9 +226,6 @@ void DoBrainsPrefs (void) long tempLong; short itemHit, wasMaxFiles; Boolean leaving; - ModalFilterUPP brainsFilterUPP; - - brainsFilterUPP = NewModalFilterUPP(BrainsFilter); BringUpDialog(&prefDlg, kBrainsPrefsDialID); leaving = false; @@ -251,7 +249,7 @@ void DoBrainsPrefs (void) while (!leaving) { - ModalDialog(brainsFilterUPP, &itemHit); + ModalDialog(BrainsFilter, &itemHit); switch (itemHit) { case kOkayButton: @@ -320,7 +318,6 @@ void DoBrainsPrefs (void) } DisposeDialog(prefDlg); - DisposeModalFilterUPP(brainsFilterUPP); } //-------------------------------------------------------------- SetControlsToDefaults @@ -491,7 +488,7 @@ Boolean ControlFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateSettingsControl(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -511,9 +508,6 @@ void DoControlPrefs (void) Dialog *prefDlg; short i, itemHit; Boolean leaving; - ModalFilterUPP controlFilterUPP; - - controlFilterUPP = NewModalFilterUPP(ControlFilter); // CenterDialog(kControlPrefsDialID); prefDlg = PortabilityLayer::DialogManager::GetInstance()->LoadDialog(kControlPrefsDialID, kPutInFront); @@ -551,7 +545,7 @@ void DoControlPrefs (void) while (!leaving) { - ModalDialog(controlFilterUPP, &itemHit); + ModalDialog(ControlFilter, &itemHit); switch (itemHit) { case kOkayButton: @@ -609,7 +603,6 @@ void DoControlPrefs (void) } DisposeDialog(prefDlg); - DisposeModalFilterUPP(controlFilterUPP); } //-------------------------------------------------------------- SoundDefaults @@ -754,7 +747,7 @@ Boolean SoundFilter (Dialog *dial, EventRecord *event, short *item) break; case updateEvt: - SetPort((GrafPtr)dial); + SetPortDialogPort(dial); UpdateSettingsSound(dial); EndUpdate(dial->GetWindow()); event->what = nullEvent; @@ -777,11 +770,10 @@ void DoSoundPrefs (void) PLError_t theErr; short itemHit; Boolean leaving; - ModalFilterUPP soundFilterUPP; - - soundFilterUPP = NewModalFilterUPP(SoundFilter); BringUpDialog(&prefDlg, kSoundPrefsDialID); + + DrawSurface *surface = prefDlg->GetWindow()->GetDrawSurface(); UnivGetSoundVolume(&wasLoudness, thisMac.hasSM3); @@ -793,7 +785,7 @@ void DoSoundPrefs (void) while (!leaving) { - ModalDialog(soundFilterUPP, &itemHit); + ModalDialog(SoundFilter, &itemHit); switch (itemHit) { case kOkayButton: @@ -832,7 +824,7 @@ void DoSoundPrefs (void) if (tempVolume > 0) { GetDialogItemRect(prefDlg, kSofterItem, &tempRect); - DrawCIcon(1034, tempRect.left, tempRect.top); + DrawCIcon(surface, 1034, tempRect.left, tempRect.top); tempVolume--; SetDialogNumToStr(prefDlg, kVolNumberItem, (long)tempVolume); UnivSetSoundVolume(tempVolume, thisMac.hasSM3); @@ -847,7 +839,7 @@ void DoSoundPrefs (void) if (tempVolume < 7) { GetDialogItemRect(prefDlg, kLouderItem, &tempRect); - DrawCIcon(1033, tempRect.left, tempRect.top); + DrawCIcon(surface, 1033, tempRect.left, tempRect.top); tempVolume++; if (tempVolume == 7) SetDialogNumToStr(prefDlg, kVolNumberItem, 11L); @@ -892,7 +884,6 @@ void DoSoundPrefs (void) } DisposeDialog(prefDlg); - DisposeModalFilterUPP(soundFilterUPP); } //-------------------------------------------------------------- DisplayDefaults @@ -943,7 +934,6 @@ void FrameDisplayIcon (Dialog *theDialog) void DisplayUpdate (Dialog *theDialog) { - DrawDialog(theDialog); DrawDefaultButton(theDialog); SetDialogItemValue(theDialog, kDoColorFadeItem, (short)wasFade); @@ -962,155 +952,114 @@ void DisplayUpdate (Dialog *theDialog) //-------------------------------------------------------------- DisplayFilter -Boolean DisplayFilter (Dialog *dial, EventRecord *event, short *item) -{ - switch (event->what) +int16_t DisplayFilter(Dialog *dial, const TimeTaggedVOSEvent &evt) +{ + if (evt.IsKeyDownEvent()) { - case keyDown: - switch (event->message) + switch (PackVOSKeyCode(evt.m_vosEvent.m_event.m_keyboardInputEvent)) { - case PL_KEY_SPECIAL(kEnter): - case PL_KEY_NUMPAD_SPECIAL(kEnter): + case PL_KEY_SPECIAL(kEnter): + case PL_KEY_NUMPAD_SPECIAL(kEnter): FlashDialogButton(dial, kOkayButton); - *item = kOkayButton; - return(true); - break; - - case PL_KEY_SPECIAL(kEscape): + return kOkayButton; + + case PL_KEY_SPECIAL(kEscape): FlashDialogButton(dial, kCancelButton); - *item = kCancelButton; - return(true); - break; - - case PL_KEY_SPECIAL(kLeftArrow): + return kCancelButton; + + case PL_KEY_SPECIAL(kLeftArrow): switch (numNeighbors) { - case 1: - *item = kDisplay9Item; - break; - - case 3: - *item = kDisplay1Item; - break; - - case 9: - *item = kDisplay3Item; - break; - } - return(true); - break; - - case PL_KEY_SPECIAL(kRightArrow): - switch (numNeighbors) - { - case 1: - *item = kDisplay3Item; - break; - - case 3: - *item = kDisplay9Item; - break; - - case 9: - *item = kDisplay1Item; - break; - } - return(true); - break; - - case PL_KEY_SPECIAL(kUpArrow): - switch (wasDepthPref) - { - case kSwitchIfNeeded: - *item = k16Depth; - break; - - case kSwitchTo256Colors: - *item = kCurrentDepth; - break; - - case kSwitchTo16Grays: - *item = k256Depth; - break; - } - return(true); - break; - - case PL_KEY_SPECIAL(kDownArrow): - switch (wasDepthPref) - { - case kSwitchIfNeeded: - *item = k256Depth; - break; - - case kSwitchTo256Colors: - *item = k16Depth; - break; - - case kSwitchTo16Grays: - *item = kCurrentDepth; - break; - } - return(true); - break; - - case PL_KEY_ASCII('1'): - *item = kDisplay1Item; - return(true); - break; - - case PL_KEY_ASCII('3'): - *item = kDisplay3Item; - return(true); - break; - - case PL_KEY_ASCII('9'): - *item = kDisplay9Item; - return(true); - break; - - case PL_KEY_ASCII('B'): - *item = kDoColorFadeItem; - return(true); - break; - - case PL_KEY_ASCII('D'): - *item = kDispDefault; - FlashDialogButton(dial, kDispDefault); - return(true); - break; - - case PL_KEY_ASCII('R'): - *item = kUseScreen2Item; - FlashDialogButton(dial, kUseQDItem); - return(true); - break; - - case PL_KEY_ASCII('U'): - *item = kUseQDItem; - return(true); - break; - + case 1: + return kDisplay9Item; + + case 3: + return kDisplay1Item; + + case 9: + return kDisplay3Item; + default: + return -1; + } + break; + + case PL_KEY_SPECIAL(kRightArrow): + switch (numNeighbors) + { + case 1: + return kDisplay3Item; + + case 3: + return kDisplay9Item; + + case 9: + return kDisplay1Item; + + default: + return -1; + } + break; + + case PL_KEY_SPECIAL(kUpArrow): + switch (wasDepthPref) + { + case kSwitchIfNeeded: + return k16Depth; + + case kSwitchTo256Colors: + return kCurrentDepth; + + case kSwitchTo16Grays: + return k256Depth; + + default: + return -1; + } + break; + + case PL_KEY_SPECIAL(kDownArrow): + switch (wasDepthPref) + { + case kSwitchIfNeeded: + return k256Depth; + + case kSwitchTo256Colors: + return k16Depth; + + case kSwitchTo16Grays: + return kCurrentDepth; + } + break; + + case PL_KEY_ASCII('1'): + return kDisplay1Item; + + case PL_KEY_ASCII('3'): + return kDisplay3Item; + + case PL_KEY_ASCII('9'): + return kDisplay9Item; + + case PL_KEY_ASCII('B'): + return kDoColorFadeItem; + + case PL_KEY_ASCII('D'): + FlashDialogButton(dial, kDispDefault); + return kDispDefault; + + case PL_KEY_ASCII('R'): + PL_NotYetImplemented_TODO("FixMe"); // GP: This looks like a bug + + FlashDialogButton(dial, kUseQDItem); + return kUseScreen2Item; + + case PL_KEY_ASCII('U'): + return kUseQDItem; + + default: return(false); } - break; - - case mouseDown: - return(false); - break; - - case updateEvt: - SetPort((GrafPtr)dial); - DisplayUpdate(dial); - EndUpdate(dial->GetWindow()); - event->what = nullEvent; - return(false); - break; - - default: - return(false); - break; } } @@ -1119,13 +1068,13 @@ Boolean DisplayFilter (Dialog *dial, EventRecord *event, short *item) void DoDisplayPrefs (void) { Dialog *prefDlg; - short itemHit, wasNeighbors; + short wasNeighbors; Boolean leaving; - ModalFilterUPP displayFilterUPP; - - displayFilterUPP = NewModalFilterUPP(DisplayFilter); BringUpDialog(&prefDlg, kDisplayPrefsDialID); + + DisplayUpdate(prefDlg); + if (!thisMac.can8Bit) { MyDisableControl(prefDlg, kDoColorFadeItem); @@ -1143,7 +1092,7 @@ void DoDisplayPrefs (void) while (!leaving) { - ModalDialog(displayFilterUPP, &itemHit); + int16_t itemHit = prefDlg->ExecuteModal(DisplayFilter); switch (itemHit) { case kOkayButton: @@ -1225,8 +1174,7 @@ void DoDisplayPrefs (void) } } - DisposeDialog(prefDlg); - DisposeModalFilterUPP(displayFilterUPP); + prefDlg->Destroy(); } //-------------------------------------------------------------- SetAllDefaults @@ -1282,17 +1230,17 @@ void SetAllDefaults (void) //-------------------------------------------------------------- FlashSettingsButton -void FlashSettingsButton (short who) +void FlashSettingsButton (DrawSurface *surface, short who) { #define kNormalSettingsIcon 1010 #define kInvertedSettingsIcon 1014 short theID; theID = kInvertedSettingsIcon + who; - DrawCIcon (theID, prefButton[who].left + 4, prefButton[who].top + 4); + DrawCIcon (surface, theID, prefButton[who].left + 4, prefButton[who].top + 4); DelayTicks(8); theID = kNormalSettingsIcon + who; - DrawCIcon (theID, prefButton[who].left + 4, prefButton[who].top + 4); + DrawCIcon (surface, theID, prefButton[who].left + 4, prefButton[who].top + 4); } //-------------------------------------------------------------- UpdateSettingsMain @@ -1302,8 +1250,6 @@ void UpdateSettingsMain (Dialog *theDialog) Str255 theStr; DrawSurface *surface = theDialog->GetWindow()->GetDrawSurface(); - DrawDialog(theDialog); - DrawDefaultButton(theDialog); GetIndString(theStr, 129, 1); @@ -1323,86 +1269,56 @@ void UpdateSettingsMain (Dialog *theDialog) //-------------------------------------------------------------- PrefsFilter -Boolean PrefsFilter (Dialog *dial, EventRecord *event, short *item) +int16_t PrefsFilter (Dialog *dial, const TimeTaggedVOSEvent &evt) { - Point testPt; short i; Boolean foundHit; - - switch (event->what) + + if (evt.IsKeyDownEvent()) { - case keyDown: - switch (event->message) + intptr_t packedKey = PackVOSKeyCode(evt.m_vosEvent.m_event.m_keyboardInputEvent); + + switch (packedKey) { - case PL_KEY_SPECIAL(kEnter): - case PL_KEY_NUMPAD_SPECIAL(kEnter): + case PL_KEY_SPECIAL(kEnter): + case PL_KEY_NUMPAD_SPECIAL(kEnter): FlashDialogButton(dial, kOkayButton); - *item = kOkayButton; - return(true); - break; - - case PL_KEY_ASCII('B'): - *item = kBrainsButton; - return(true); - break; - - case PL_KEY_ASCII('C'): - *item = kControlsButton; - return(true); - break; - - case PL_KEY_ASCII('d'): - *item = kDisplayButton; - return(true); - break; - - case PL_KEY_ASCII('S'): - *item = kSoundButton; - return(true); - break; - - default: - return(false); + return kOkayButton; + + case PL_KEY_ASCII('B'): + return kBrainsButton; + + case PL_KEY_ASCII('C'): + return kControlsButton; + + case PL_KEY_ASCII('d'): + return kDisplayButton; + + case PL_KEY_ASCII('S'): + return kSoundButton; + + default: + return -1; } - break; - - case mouseDown: - testPt = event->where; - GlobalToLocal(&testPt); - foundHit = false; + } + else if (evt.IsLMouseDownEvent()) + { + const Window *window = dial->GetWindow(); + const GpMouseInputEvent &mouseEvent = evt.m_vosEvent.m_event.m_mouseInputEvent; + + const Point testPt = Point::Create(mouseEvent.m_x - window->m_wmX, mouseEvent.m_y - window->m_wmY); + + int16_t hitCode = -1; + for (i = 0; i < 4; i++) { - if (PtInRect(testPt, &prefButton[i])) - { - *item = kDisplayButton + i; - foundHit = true; - } + if (prefButton[i].Contains(testPt)) + hitCode = kDisplayButton + i; } - return(foundHit); - break; - - case updateEvt: - if ((WindowPtr)event->message == (WindowPtr)mainWindow) - { - SetPortWindowPort(mainWindow); - UpdateMainWindow(); - EndUpdate(mainWindow); - SetPort((GrafPtr)dial); - } - else if ((WindowPtr)event->message == dial->GetWindow()) - { - SetPortDialogPort(dial); - UpdateSettingsMain(dial); - EndUpdate(dial->GetWindow()); - } - event->what = nullEvent; - return(false); - break; - - default: - return(false); - break; + return hitCode; } + + return -1; } //-------------------------------------------------------------- DoSettingsMain @@ -1411,13 +1327,12 @@ void DoSettingsMain (void) { #define kAllDefaultsButton 11 Dialog *prefDlg; - short itemHit; + int16_t itemHit; Boolean leaving; - ModalFilterUPP prefsFilterUPP; - - prefsFilterUPP = NewModalFilterUPP(PrefsFilter); BringUpDialog(&prefDlg, kMainPrefsDialID); + + DrawSurface *surface = prefDlg->GetWindow()->GetDrawSurface(); GetDialogItemRect(prefDlg, kDisplayButton, &prefButton[0]); InsetRect(&prefButton[0], -4, -4); @@ -1427,36 +1342,39 @@ void DoSettingsMain (void) InsetRect(&prefButton[2], -4, -4); GetDialogItemRect(prefDlg, 6, &prefButton[3]); InsetRect(&prefButton[3], -4, -4); + + UpdateSettingsMain(prefDlg); leaving = false; nextRestartChange = false; while (!leaving) { - ModalDialog(prefsFilterUPP, &itemHit); - switch (itemHit) + int16_t selectedItem = prefDlg->ExecuteModal(PrefsFilter); + + switch (selectedItem) { case kOkayButton: leaving = true; break; case kDisplayButton: - FlashSettingsButton(0); + FlashSettingsButton(surface, 0); DoDisplayPrefs(); - SetPort((GrafPtr)prefDlg); + SetGraphicsPort(&prefDlg->GetWindow()->m_graf); break; case kSoundButton: - FlashSettingsButton(1); + FlashSettingsButton(surface, 1); DoSoundPrefs(); - SetPort((GrafPtr)prefDlg); + SetGraphicsPort(&prefDlg->GetWindow()->m_graf); FlushEvents(everyEvent, 0); break; case kControlsButton: - FlashSettingsButton(2); + FlashSettingsButton(surface, 2); DoControlPrefs(); - SetPort((GrafPtr)prefDlg); + SetGraphicsPort(&prefDlg->GetWindow()->m_graf); break; case kBrainsButton: @@ -1466,9 +1384,9 @@ void DoSettingsMain (void) changeLockStateOfHouse = true; saveHouseLocked = false; } - FlashSettingsButton(3); + FlashSettingsButton(surface, 3); DoBrainsPrefs(); - SetPort((GrafPtr)prefDlg); + SetGraphicsPort(&prefDlg->GetWindow()->m_graf); break; case kAllDefaultsButton: @@ -1478,7 +1396,6 @@ void DoSettingsMain (void) } DisposeDialog(prefDlg); - DisposeModalFilterUPP(prefsFilterUPP); if (nextRestartChange) BitchAboutChanges(); diff --git a/GpApp/StringUtils.cpp b/GpApp/StringUtils.cpp index 4fa86f1..75d7628 100644 --- a/GpApp/StringUtils.cpp +++ b/GpApp/StringUtils.cpp @@ -275,17 +275,17 @@ void GetFirstWordOfString (StringPtr stringIn, StringPtr stringOut) // 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) +void CollapseStringToWidth (DrawSurface *surface, StringPtr theStr, short wide) { short dotsWide; Boolean tooWide; - dotsWide = StringWidth(PSTR("É")); - tooWide = StringWidth(theStr) > wide; + dotsWide = surface->MeasureString(PSTR("É")); + tooWide = surface->MeasureString(theStr) > wide; while (tooWide) { theStr[0]--; - tooWide = ((StringWidth(theStr) + dotsWide) > wide); + tooWide = ((surface->MeasureString(theStr) + dotsWide) > wide); if (!tooWide) PasStringConcat(theStr, PSTR("É")); } diff --git a/GpApp/StructuresInit2.cpp b/GpApp/StructuresInit2.cpp index 4908196..5852592 100644 --- a/GpApp/StructuresInit2.cpp +++ b/GpApp/StructuresInit2.cpp @@ -265,7 +265,7 @@ void CreatePointers (void) RedAlert(kErrNoMemory); else { - PL_STATIC_ASSERT(sizeof(demoType) == 6); + GP_STATIC_ASSERT(sizeof(demoType) == 6); BlockMove(*tempHandle, demoData, kDemoLength); tempHandle.Dispose(); diff --git a/GpApp/Tools.cpp b/GpApp/Tools.cpp index 8f23bc4..3d71a8c 100644 --- a/GpApp/Tools.cpp +++ b/GpApp/Tools.cpp @@ -54,7 +54,7 @@ void CreateToolsOffscreen (void); void KillToolsOffscreen (void); void FrameSelectedTool (DrawSurface *); void DrawToolName (DrawSurface *); -void DrawToolTiles (void); +void DrawToolTiles (DrawSurface *); void SwitchToolModes (short); @@ -161,12 +161,12 @@ void DrawToolName (DrawSurface *surface) //-------------------------------------------------------------- DrawToolTiles #ifndef COMPILEDEMO -void DrawToolTiles (void) +void DrawToolTiles (DrawSurface *surface) { Rect srcRect, destRect; short i; - DrawCIcon(2000, toolRects[0].left, toolRects[0].top); // Selection Tool + DrawCIcon(surface, 2000, toolRects[0].left, toolRects[0].top); // Selection Tool for (i = 0; i < 15; i++) // Other tools { @@ -271,7 +271,7 @@ void UpdateToolsWindow (void) surface->DrawLine(Point::Create(4, 25), Point::Create(112, 25)); surface->SetForeColor(StdColors::Black()); - DrawToolTiles(); + DrawToolTiles(surface); FrameSelectedTool(surface); DrawToolName(surface); #endif diff --git a/GpApp/Utilities.cpp b/GpApp/Utilities.cpp index fabb484..7787d8c 100644 --- a/GpApp/Utilities.cpp +++ b/GpApp/Utilities.cpp @@ -11,7 +11,9 @@ #include "PLResources.h" #include "PLSound.h" #include "PLTimeTaggedVOSEvent.h" +#include "QDPixMap.h" #include "Externs.h" +#include "IconLoader.h" #include "Utilities.h" @@ -326,18 +328,25 @@ void LargeIconPlot (Rect *theRect, short theID) // Draws a standard color icon (32 x 32) - resource is a 'CICN'. -void DrawCIcon (short theID, short h, short v) +void DrawCIcon (DrawSurface *surface, short theID, short h, short v) { - CIconHandle theIcon; - Rect theRect; - - theIcon = GetCIcon(theID); - if (theIcon != nil) + THandle colorImage; + THandle bwImage; + THandle maskImage; + + if (PortabilityLayer::IconLoader::GetInstance()->LoadColorIcon(theID, colorImage, bwImage, maskImage)) { + Rect theRect; + SetRect(&theRect, 0, 0, 32, 32); OffsetRect(&theRect, h, v); - PlotCIcon(&theRect, theIcon); - DisposeCIcon(theIcon); + + CopyMask(*colorImage, *maskImage, *surface->m_port.GetPixMap(), &(*colorImage)->m_rect, &(*maskImage)->m_rect, &theRect); + surface->m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents); + + bwImage.Dispose(); + colorImage.Dispose(); + maskImage.Dispose(); } } diff --git a/GpD3D/GpFontHandler_FreeType2.cpp b/GpD3D/GpFontHandler_FreeType2.cpp index f1c1324..ce55d41 100644 --- a/GpD3D/GpFontHandler_FreeType2.cpp +++ b/GpD3D/GpFontHandler_FreeType2.cpp @@ -40,6 +40,7 @@ class GpFont_FreeType2 final : public PortabilityLayer::HostFont public: void Destroy() override; GpFontRenderedGlyph_FreeType2 *Render(uint32_t unicodeCodePoint, unsigned int size) override; + bool GetLineSpacing(unsigned int size, int32_t &outSpacing) override; static GpFont_FreeType2 *Create(const FT_StreamRec_ &streamRec, PortabilityLayer::IOStream *stream); @@ -73,8 +74,8 @@ void GpFontRenderedGlyph_FreeType2::Destroy() GpFontRenderedGlyph_FreeType2 *GpFontRenderedGlyph_FreeType2::Create(size_t dataSize, const PortabilityLayer::RenderedGlyphMetrics &metrics) { - size_t alignedPrefixSize = (sizeof(GpFontRenderedGlyph_FreeType2) + PL_SYSTEM_MEMORY_ALIGNMENT - 1); - alignedPrefixSize -= alignedPrefixSize % PL_SYSTEM_MEMORY_ALIGNMENT; + size_t alignedPrefixSize = (sizeof(GpFontRenderedGlyph_FreeType2) + GP_SYSTEM_MEMORY_ALIGNMENT - 1); + alignedPrefixSize -= alignedPrefixSize % GP_SYSTEM_MEMORY_ALIGNMENT; void *storage = malloc(alignedPrefixSize + dataSize); if (!storage) @@ -141,8 +142,8 @@ GpFontRenderedGlyph_FreeType2 *GpFont_FreeType2::Render(uint32_t unicodeCodePoin const size_t numRowsRequired = glyph->bitmap.rows; size_t pitchRequired = (glyph->bitmap.width + 7) / 8; - pitchRequired = pitchRequired + (PL_SYSTEM_MEMORY_ALIGNMENT - 1); - pitchRequired -= pitchRequired % PL_SYSTEM_MEMORY_ALIGNMENT; + pitchRequired = pitchRequired + (GP_SYSTEM_MEMORY_ALIGNMENT - 1); + pitchRequired -= pitchRequired % GP_SYSTEM_MEMORY_ALIGNMENT; const size_t glyphDataSize = numRowsRequired * pitchRequired; @@ -181,6 +182,21 @@ GpFontRenderedGlyph_FreeType2 *GpFont_FreeType2::Render(uint32_t unicodeCodePoin return renderedGlyph; } +bool GpFont_FreeType2::GetLineSpacing(unsigned int size, int32_t &outSpacing) +{ + if (m_currentSize != size) + { + if (FT_Set_Pixel_Sizes(m_face, 0, size) != 0) + return false; + + m_currentSize = size; + } + + outSpacing = m_face->size->metrics.height / 64; + return true; +} + + GpFont_FreeType2 *GpFont_FreeType2::Create(const FT_StreamRec_ &streamRec, PortabilityLayer::IOStream *stream) { void *storage = malloc(sizeof(GpFont_FreeType2)); diff --git a/GpD3D/GpMemoryBuffer.cpp b/GpD3D/GpMemoryBuffer.cpp index 74930f7..fee70c6 100644 --- a/GpD3D/GpMemoryBuffer.cpp +++ b/GpD3D/GpMemoryBuffer.cpp @@ -42,8 +42,8 @@ GpMemoryBuffer::~GpMemoryBuffer() size_t GpMemoryBuffer::AlignedSize() { - const size_t paddedSize = (sizeof(GpMemoryBuffer) + PL_SYSTEM_MEMORY_ALIGNMENT - 1); - const size_t sz = paddedSize - paddedSize % PL_SYSTEM_MEMORY_ALIGNMENT; + const size_t paddedSize = (sizeof(GpMemoryBuffer) + GP_SYSTEM_MEMORY_ALIGNMENT - 1); + const size_t sz = paddedSize - paddedSize % GP_SYSTEM_MEMORY_ALIGNMENT; return sz; } diff --git a/PictChecker/PictChecker.cpp b/PictChecker/PictChecker.cpp index 2c2d92a..e6d154d 100644 --- a/PictChecker/PictChecker.cpp +++ b/PictChecker/PictChecker.cpp @@ -313,7 +313,7 @@ void AuditPackBitsRectOld(MemReaderStream &stream, int pictVersion, bool isPacke // If pack type == 3, 16-bit RLE // If pack type == 4, 8-bit planar component RLE - PL_STATIC_ASSERT(sizeof(BEPixMap) == 44); + GP_STATIC_ASSERT(sizeof(BEPixMap) == 44); BEPixMap pixMap; stream.Read(&pixMap, sizeof(BEPixMap)); @@ -663,7 +663,7 @@ void AuditPackBitsRect(MemReaderStream &stream, int pictVersion, bool isPackedFl // If pack type == 3, 16-bit RLE // If pack type == 4, 8-bit planar component RLE - PL_STATIC_ASSERT(sizeof(BEPixMap) == 44); + GP_STATIC_ASSERT(sizeof(BEPixMap) == 44); stream.Read(&pixMapBE, sizeof(BEPixMap)); diff --git a/PortabilityLayer/ByteSwap.cpp b/PortabilityLayer/ByteSwap.cpp index 1fc559e..b06a8fd 100644 --- a/PortabilityLayer/ByteSwap.cpp +++ b/PortabilityLayer/ByteSwap.cpp @@ -1,28 +1,28 @@ -#include "ByteSwap.h" +#include "ByteSwap.h" #include "CoreDefs.h" namespace PortabilityLayer { namespace ByteSwap - { - template - void SwapArbitrary(TNumberType &v) - { - PL_STATIC_ASSERT(sizeof(TNumberType) == sizeof(TUnsignedType)); - - uint8_t bytes[sizeof(TNumberType)]; - for (size_t i = 0; i < sizeof(TNumberType); i++) - bytes[i] = reinterpret_cast(&v)[i]; - - TUnsignedType result = 0; - for (size_t i = 0; i < sizeof(TNumberType); i++) - result |= static_cast(bytes[i]) << (sizeof(TUnsignedType) * 8 - 8 - (i * 8)); + { + template + void SwapArbitrary(TNumberType &v) + { + GP_STATIC_ASSERT(sizeof(TNumberType) == sizeof(TUnsignedType)); + + uint8_t bytes[sizeof(TNumberType)]; + for (size_t i = 0; i < sizeof(TNumberType); i++) + bytes[i] = reinterpret_cast(&v)[i]; + + TUnsignedType result = 0; + for (size_t i = 0; i < sizeof(TNumberType); i++) + result |= static_cast(bytes[i]) << (sizeof(TUnsignedType) * 8 - 8 - (i * 8)); v = static_cast(result); - } + } void BigInt16(int16_t &v) - { + { SwapArbitrary(v); } @@ -34,10 +34,10 @@ namespace PortabilityLayer void BigInt64(int64_t &v) { SwapArbitrary(v); - } + } void BigUInt16(uint16_t &v) - { + { SwapArbitrary(v); } diff --git a/PortabilityLayer/CFileStream.h b/PortabilityLayer/CFileStream.h index c411515..9a42584 100644 --- a/PortabilityLayer/CFileStream.h +++ b/PortabilityLayer/CFileStream.h @@ -30,7 +30,7 @@ namespace PortabilityLayer void Close() override; private: - CFileStream(const CFileStream &other) PL_DELETED; + CFileStream(const CFileStream &other) GP_DELETED; FILE *m_file; bool m_readOnly; diff --git a/PortabilityLayer/DialogManager.cpp b/PortabilityLayer/DialogManager.cpp index c15b208..6898372 100644 --- a/PortabilityLayer/DialogManager.cpp +++ b/PortabilityLayer/DialogManager.cpp @@ -1,9 +1,19 @@ #include "DialogManager.h" +#include "HostDisplayDriver.h" +#include "IconLoader.h" #include "ResourceManager.h" #include "PLArrayView.h" -#include "PLDialogs.h" #include "PLBigEndian.h" +#include "PLButtonWidget.h" +#include "PLDialogs.h" +#include "PLIconWidget.h" +#include "PLInvisibleWidget.h" +#include "PLLabelWidget.h" #include "PLPasStr.h" +#include "PLSysCalls.h" +#include "PLTimeTaggedVOSEvent.h" +#include "PLWidgets.h" +#include "QDPixMap.h" #include "ResTypeID.h" #include "SharedTypes.h" #include "WindowDef.h" @@ -14,6 +24,9 @@ namespace PortabilityLayer { + class DialogImpl; + class Widget; + namespace SerializedDialogItemTypeCodes { enum SerializedDialogItemTypeCode @@ -32,6 +45,7 @@ namespace PortabilityLayer typedef SerializedDialogItemTypeCodes::SerializedDialogItemTypeCode SerializedDialogItemTypeCode_t; + struct DialogTemplateItem { Rect m_rect; @@ -41,79 +55,6 @@ namespace PortabilityLayer Str255 m_name; }; - class DialogItemImpl : public DialogItem - { - public: - DialogItemImpl(const DialogTemplateItem &templateItem); - virtual ~DialogItemImpl(); - - Rect GetRect() const override; - - virtual bool Init() = 0; - virtual void Destroy() = 0; - - protected: - Rect m_rect; - int16_t m_id; - bool m_enabled; - PascalStr<255> m_name; - }; - - template - class DialogItemSpec : public DialogItemImpl - { - public: - DialogItemSpec(const DialogTemplateItem &tmpl) - : DialogItemImpl(tmpl) - { - } - - void Destroy() override - { - static_cast(this)->~T(); - free(static_cast(this)); - } - - static DialogItemSpec *Create(const DialogTemplateItem &tmpl) - { - void *storage = malloc(sizeof(T)); - if (!storage) - return nullptr; - - T *item = new (storage) T(tmpl); - - DialogItemImpl *dItem = static_cast(item); - if (!dItem->Init()) - { - dItem->Destroy(); - return nullptr; - } - - return item; - } - }; - - class DialogItem_EditBox final : public DialogItemSpec - { - public: - explicit DialogItem_EditBox(const DialogTemplateItem &tmpl); - bool Init() override; - }; - - class DialogItem_Label final : public DialogItemSpec - { - public: - explicit DialogItem_Label(const DialogTemplateItem &tmpl); - bool Init() override; - }; - - class DialogItem_Unknown final : public DialogItemSpec - { - public: - explicit DialogItem_Unknown(const DialogTemplateItem &tmpl); - bool Init() override; - }; - class DialogTemplate final { public: @@ -132,68 +73,45 @@ namespace PortabilityLayer { public: void Destroy() override; + Window *GetWindow() const override; - ArrayView GetItems() const override; + ArrayView GetItems() const override; + + int16_t ExecuteModal(DialogFilterFunc_t filterFunc) override; bool Populate(DialogTemplate *tmpl); + void DrawControls(); + + Point MouseToDialog(const GpMouseInputEvent &evt); + static DialogImpl *Create(Window *window, size_t numItems); private: - explicit DialogImpl(Window *window, DialogItem **items, size_t numItems); + explicit DialogImpl(Window *window, DialogItem *items, size_t numItems); ~DialogImpl(); Window *m_window; - DialogItem **m_items; + DialogItem *m_items; size_t m_numItems; + size_t m_maxItems; }; - DialogItemImpl::DialogItemImpl(const DialogTemplateItem &templateItem) - : m_enabled(templateItem.m_enabled) - , m_id(templateItem.m_id) - , m_name(PLPasStr(templateItem.m_name)) - , m_rect(templateItem.m_rect) + DialogItem::DialogItem(Widget *widget) + : m_widget(widget) { } - DialogItemImpl::~DialogItemImpl() + DialogItem::~DialogItem() { + if (m_widget) + m_widget->Destroy(); } - Rect DialogItemImpl::GetRect() const + Widget *DialogItem::GetWidget() const { - return m_rect; - } - - DialogItem_EditBox::DialogItem_EditBox(const DialogTemplateItem &tmpl) - : DialogItemSpec(tmpl) - { - } - - bool DialogItem_EditBox::Init() - { - return true; - } - - DialogItem_Label::DialogItem_Label(const DialogTemplateItem &tmpl) - : DialogItemSpec(tmpl) - { - } - - bool DialogItem_Label::Init() - { - return true; - } - - DialogItem_Unknown::DialogItem_Unknown(const DialogTemplateItem &tmpl) - : DialogItemSpec(tmpl) - { - } - - bool DialogItem_Unknown::Init() - { - return true; + return m_widget; } DialogTemplate::DialogTemplate(DialogTemplateItem *itemStorage, size_t numItems) @@ -268,14 +186,68 @@ namespace PortabilityLayer return m_window; } - ArrayView DialogImpl::GetItems() const + ArrayView DialogImpl::GetItems() const { - ArrayView iter(m_items, m_numItems); - return ArrayView(m_items, m_numItems); + return ArrayView(m_items, m_numItems); + } + + int16_t DialogImpl::ExecuteModal(DialogFilterFunc_t filterFunc) + { + Window *window = this->GetWindow(); + Widget *capturingWidget = nullptr; + size_t capturingWidgetIndex = 0; + + for (;;) + { + TimeTaggedVOSEvent evt; + if (WaitForEvent(&evt, 1)) + { + const int16_t selection = filterFunc(this, evt); + + if (selection >= 0) + return selection; + + if (capturingWidget != nullptr) + { + const WidgetHandleState_t state = capturingWidget->ProcessEvent(evt); + + if (state != WidgetHandleStates::kDigested) + capturingWidget = nullptr; + + if (state == WidgetHandleStates::kActivated) + return static_cast(capturingWidgetIndex + 1); + } + else + { + const size_t numItems = this->m_numItems; + for (size_t i = 0; i < numItems; i++) + { + Widget *widget = this->m_items[i].GetWidget(); + + const WidgetHandleState_t state = widget->ProcessEvent(evt); + + if (state == WidgetHandleStates::kActivated) + return static_cast(i + 1); + + if (state == WidgetHandleStates::kCaptured) + { + capturingWidget = widget; + capturingWidgetIndex = i; + break; + } + + if (state == WidgetHandleStates::kDigested) + break; + } + } + } + } } bool DialogImpl::Populate(DialogTemplate *tmpl) { + Window *window = this->GetWindow(); + ArrayView templateItems = tmpl->GetItems(); const size_t numItems = templateItems.Count(); @@ -284,61 +256,94 @@ namespace PortabilityLayer { const DialogTemplateItem &templateItem = templateItems[i]; - DialogItem *ditem = nullptr; + Widget *widget = nullptr; + + WidgetBasicState basicState; + basicState.m_enabled = templateItem.m_enabled; + basicState.m_resID = templateItem.m_id; + basicState.m_text = PascalStr<255>(PLPasStr(templateItem.m_name)); + basicState.m_rect = templateItem.m_rect; + basicState.m_window = window; switch (templateItem.m_serializedType) { + case SerializedDialogItemTypeCodes::kButton: + widget = ButtonWidget::Create(basicState); + break; case SerializedDialogItemTypeCodes::kLabel: - ditem = DialogItem_Label::Create(templateItem); + widget = LabelWidget::Create(basicState); break; + case SerializedDialogItemTypeCodes::kIcon: + widget = IconWidget::Create(basicState); + break; + case SerializedDialogItemTypeCodes::kCheckBox: + case SerializedDialogItemTypeCodes::kRadioButton: case SerializedDialogItemTypeCodes::kEditBox: - ditem = DialogItem_EditBox::Create(templateItem); - break; + case SerializedDialogItemTypeCodes::kImage: default: - ditem = DialogItem_Unknown::Create(templateItem); + widget = InvisibleWidget::Create(basicState); break; } - if (!ditem) + if (!widget) return false; - m_items[i] = ditem; + new (&m_items[m_numItems++]) DialogItem(widget); } return true; } + void DialogImpl::DrawControls() + { + DrawSurface *surface = m_window->GetDrawSurface(); + + for (ArrayViewIterator it = GetItems().begin(), itEnd = GetItems().end(); it != itEnd; ++it) + { + const DialogItem &item = *it; + item.GetWidget()->DrawControl(surface); + } + } + + Point DialogImpl::MouseToDialog(const GpMouseInputEvent &evt) + { + const Window *window = m_window; + const int32_t x = evt.m_x - window->m_wmX; + const int32_t y = evt.m_y - window->m_wmY; + + return Point::Create(x, y); + } + DialogImpl *DialogImpl::Create(Window *window, size_t numItems) { - size_t alignedSize = sizeof(DialogImpl) + PL_SYSTEM_MEMORY_ALIGNMENT + 1; - alignedSize -= alignedSize % PL_SYSTEM_MEMORY_ALIGNMENT; + size_t alignedSize = sizeof(DialogImpl) + GP_SYSTEM_MEMORY_ALIGNMENT + 1; + alignedSize -= alignedSize % GP_SYSTEM_MEMORY_ALIGNMENT; - const size_t itemsSize = sizeof(DialogItemImpl) * numItems; + const size_t itemsSize = sizeof(DialogItem) * numItems; void *storage = malloc(alignedSize + itemsSize); if (!storage) return nullptr; - DialogItem **itemsList = reinterpret_cast(static_cast(storage) + alignedSize); - for (size_t i = 0; i < numItems; i++) - itemsList[i] = nullptr; + DialogItem *itemsList = reinterpret_cast(static_cast(storage) + alignedSize); return new (storage) DialogImpl(window, itemsList, numItems); } - DialogImpl::DialogImpl(Window *window, DialogItem **itemsList, size_t numItems) + DialogImpl::DialogImpl(Window *window, DialogItem *itemsList, size_t numItems) : m_window(window) , m_items(itemsList) - , m_numItems(numItems) + , m_numItems(0) + , m_maxItems(numItems) { } DialogImpl::~DialogImpl() { - for (size_t i = 0; i < m_numItems; i++) + while (m_numItems > 0) { - if (DialogItem *item = m_items[i]) - static_cast(item)->Destroy(); + m_numItems--; + m_items[m_numItems].~DialogItem(); } } @@ -415,6 +420,34 @@ 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 * 2 <= displayHeight) + window->m_wmY = displayHeight / 4; + else + window->m_wmY = (static_cast(displayHeight) - static_cast(dialogHeight)) / 2; + DialogImpl *dialog = DialogImpl::Create(window, numItems); if (!dialog) @@ -433,6 +466,8 @@ namespace PortabilityLayer return nullptr; } + dialog->DrawControls(); + return dialog; } @@ -445,12 +480,17 @@ namespace PortabilityLayer if (!dtemplateH) return nullptr; - uint16_t numItems; - memcpy(&numItems, *dtemplateH, 2); - ByteSwap::BigUInt16(numItems); + int16_t numItemsMinusOne; + memcpy(&numItemsMinusOne, *dtemplateH, 2); + ByteSwap::BigInt16(numItemsMinusOne); - size_t dtlAlignedSize = sizeof(DialogTemplate) + PL_SYSTEM_MEMORY_ALIGNMENT - 1; - dtlAlignedSize -= dtlAlignedSize % PL_SYSTEM_MEMORY_ALIGNMENT; + if (numItemsMinusOne < -1) + return nullptr; + + uint16_t numItems = static_cast(numItemsMinusOne + 1); + + size_t dtlAlignedSize = sizeof(DialogTemplate) + GP_SYSTEM_MEMORY_ALIGNMENT - 1; + dtlAlignedSize -= dtlAlignedSize % GP_SYSTEM_MEMORY_ALIGNMENT; const size_t dtlItemSize = sizeof(DialogTemplateItem) * numItems; diff --git a/PortabilityLayer/DialogManager.h b/PortabilityLayer/DialogManager.h index 49dceb1..f487634 100644 --- a/PortabilityLayer/DialogManager.h +++ b/PortabilityLayer/DialogManager.h @@ -4,9 +4,12 @@ struct Dialog; struct Window; +struct TimeTaggedVOSEvent; namespace PortabilityLayer { + class Widget; + class DialogManager { public: @@ -14,4 +17,16 @@ namespace PortabilityLayer static DialogManager *GetInstance(); }; + + class DialogItem + { + public: + explicit DialogItem(Widget *widget); + ~DialogItem(); + + Widget *GetWidget() const; + + private: + Widget *m_widget; + }; } diff --git a/PortabilityLayer/DisplayDeviceManager.cpp b/PortabilityLayer/DisplayDeviceManager.cpp index b31a938..45ea8aa 100644 --- a/PortabilityLayer/DisplayDeviceManager.cpp +++ b/PortabilityLayer/DisplayDeviceManager.cpp @@ -30,7 +30,7 @@ namespace PortabilityLayer bool m_paletteIsDirty; PortabilityLayer::RGBAColor *m_palette; - uint8_t m_paletteStorage[256 * sizeof(PortabilityLayer::RGBAColor) + PL_SYSTEM_MEMORY_ALIGNMENT]; + uint8_t m_paletteStorage[256 * sizeof(PortabilityLayer::RGBAColor) + GP_SYSTEM_MEMORY_ALIGNMENT]; static DisplayDeviceManagerImpl ms_instance; }; @@ -41,7 +41,7 @@ namespace PortabilityLayer , m_pixelFormat(GpPixelFormats::k8BitStandard) { uint8_t *paletteStorage = m_paletteStorage; - while (reinterpret_cast(paletteStorage) % PL_SYSTEM_MEMORY_ALIGNMENT != 0) + while (reinterpret_cast(paletteStorage) % GP_SYSTEM_MEMORY_ALIGNMENT != 0) paletteStorage++; m_palette = reinterpret_cast(paletteStorage); diff --git a/PortabilityLayer/FontRenderer.cpp b/PortabilityLayer/FontRenderer.cpp index 1a21913..9163545 100644 --- a/PortabilityLayer/FontRenderer.cpp +++ b/PortabilityLayer/FontRenderer.cpp @@ -7,6 +7,7 @@ #include "MacRoman.h" #include "PLPasStr.h" #include "RenderedFont.h" +#include "RenderedFontMetrics.h" #include "RenderedGlyphMetrics.h" #include @@ -19,12 +20,14 @@ namespace PortabilityLayer class RenderedFontImpl final : public RenderedFont { public: - bool GetGlyph(unsigned int character, const RenderedGlyphMetrics **outMetricsPtr, const void **outData) const override; + bool GetGlyph(unsigned int character, const RenderedGlyphMetrics *&outMetricsPtr, const void *&outData) const override; + const RenderedFontMetrics &GetMetrics() const override; size_t MeasureString(const uint8_t *chars, size_t len) const override; void Destroy() override; void SetCharData(unsigned int charID, const void *data, size_t dataOffset, const RenderedGlyphMetrics &metrics); + void SetFontMetrics(const RenderedFontMetrics &metrics); static RenderedFontImpl *Create(size_t glyphDataSize); @@ -33,7 +36,9 @@ namespace PortabilityLayer ~RenderedFontImpl(); size_t m_dataOffsets[256]; - RenderedGlyphMetrics m_metrics[256]; + RenderedGlyphMetrics m_glyphMetrics[256]; + + RenderedFontMetrics m_fontMetrics; void *m_data; }; @@ -49,25 +54,31 @@ namespace PortabilityLayer static FontRendererImpl ms_instance; }; - bool RenderedFontImpl::GetGlyph(unsigned int character, const RenderedGlyphMetrics **outMetricsPtr, const void **outData) const + bool RenderedFontImpl::GetGlyph(unsigned int character, const RenderedGlyphMetrics *&outMetricsPtr, const void *&outData) const { const size_t dataOffset = m_dataOffsets[character]; if (!dataOffset) return false; - *outMetricsPtr = m_metrics + character; - *outData = static_cast(m_data) + dataOffset; + outMetricsPtr = m_glyphMetrics + character; + outData = static_cast(m_data) + dataOffset; return true; } + const RenderedFontMetrics &RenderedFontImpl::GetMetrics() const + { + return m_fontMetrics; + } + + size_t RenderedFontImpl::MeasureString(const uint8_t *chars, size_t len) const { size_t measure = 0; for (size_t i = 0; i < len; i++) { - const RenderedGlyphMetrics &metrics = m_metrics[chars[i]]; + const RenderedGlyphMetrics &metrics = m_glyphMetrics[chars[i]]; measure += metrics.m_advanceX; } @@ -83,14 +94,19 @@ namespace PortabilityLayer void RenderedFontImpl::SetCharData(unsigned int charID, const void *data, size_t dataOffset, const RenderedGlyphMetrics &metrics) { m_dataOffsets[charID] = dataOffset; - m_metrics[charID] = metrics; + m_glyphMetrics[charID] = metrics; memcpy(static_cast(m_data) + dataOffset, data, metrics.m_glyphDataPitch * metrics.m_glyphHeight); } + void RenderedFontImpl::SetFontMetrics(const RenderedFontMetrics &metrics) + { + m_fontMetrics = metrics; + } + RenderedFontImpl *RenderedFontImpl::Create(size_t glyphDataSize) { - size_t alignedPrefixSize = sizeof(RenderedFontImpl) + PL_SYSTEM_MEMORY_ALIGNMENT - 1; - alignedPrefixSize -= alignedPrefixSize % PL_SYSTEM_MEMORY_ALIGNMENT; + size_t alignedPrefixSize = sizeof(RenderedFontImpl) + GP_SYSTEM_MEMORY_ALIGNMENT - 1; + alignedPrefixSize -= alignedPrefixSize % GP_SYSTEM_MEMORY_ALIGNMENT; if (SIZE_MAX - alignedPrefixSize < glyphDataSize) return nullptr; @@ -109,7 +125,8 @@ namespace PortabilityLayer RenderedFontImpl::RenderedFontImpl(void *data) : m_data(data) { - memset(m_metrics, 0, sizeof(m_metrics)); + memset(m_glyphMetrics, 0, sizeof(m_glyphMetrics)); + memset(&m_fontMetrics, 0, sizeof(m_fontMetrics)); memset(m_dataOffsets, 0, sizeof(m_dataOffsets)); } @@ -124,6 +141,10 @@ namespace PortabilityLayer if (size < 1) return nullptr; + int32_t lineSpacing; + if (!font->GetLineSpacing(size, lineSpacing)) + return nullptr; + HostFontRenderedGlyph *glyphs[numCharacters]; for (unsigned int i = 0; i < numCharacters; i++) @@ -138,7 +159,7 @@ namespace PortabilityLayer glyphs[i] = font->Render(unicodeCodePoint, size); } - size_t glyphDataSize = PL_SYSTEM_MEMORY_ALIGNMENT; // So we can use 0 to mean no data + size_t glyphDataSize = GP_SYSTEM_MEMORY_ALIGNMENT; // So we can use 0 to mean no data size_t numUsedGlyphs = 0; for (unsigned int i = 0; i < numCharacters; i++) { @@ -152,7 +173,7 @@ namespace PortabilityLayer RenderedFontImpl *rfont = RenderedFontImpl::Create(glyphDataSize); if (rfont) { - size_t fillOffset = PL_SYSTEM_MEMORY_ALIGNMENT; + size_t fillOffset = GP_SYSTEM_MEMORY_ALIGNMENT; size_t numUsedGlyphs = 0; for (unsigned int i = 0; i < numCharacters; i++) @@ -190,6 +211,41 @@ namespace PortabilityLayer } } + // Compute metrics + RenderedFontMetrics fontMetrics; + fontMetrics.m_linegap = lineSpacing; + fontMetrics.m_ascent = 0; + fontMetrics.m_descent = 0; + + bool measuredAnyGlyphs = false; + for (char capChar = 'A'; capChar <= 'Z'; capChar++) + { + const RenderedGlyphMetrics *glyphMetrics; + const void *glyphData; + if (rfont->GetGlyph(static_cast(capChar), glyphMetrics, glyphData) && glyphMetrics != nullptr) + { + const int32_t ascent = glyphMetrics->m_bearingY; + const int32_t descent = static_cast(glyphMetrics->m_glyphHeight) - ascent; + + if (!measuredAnyGlyphs) + { + fontMetrics.m_ascent = ascent; + fontMetrics.m_descent = descent; + measuredAnyGlyphs = true; + } + else + { + if (ascent > fontMetrics.m_ascent) + fontMetrics.m_ascent = ascent; + + if (descent > fontMetrics.m_descent) + fontMetrics.m_descent = descent; + } + } + } + + rfont->SetFontMetrics(fontMetrics); + for (unsigned int i = 0; i < numCharacters; i++) { if (glyphs[i]) diff --git a/PortabilityLayer/HostFont.h b/PortabilityLayer/HostFont.h index 05ef6e5..38d5253 100644 --- a/PortabilityLayer/HostFont.h +++ b/PortabilityLayer/HostFont.h @@ -5,11 +5,13 @@ namespace PortabilityLayer { class HostFontRenderedGlyph; + struct RenderedFontMetrics; class HostFont { public: virtual void Destroy() = 0; virtual HostFontRenderedGlyph *Render(uint32_t unicodeCodePoint, unsigned int size) = 0; + virtual bool GetLineSpacing(unsigned int size, int32_t &outSpacing) = 0; }; } diff --git a/PortabilityLayer/IconLoader.cpp b/PortabilityLayer/IconLoader.cpp new file mode 100644 index 0000000..d2682bf --- /dev/null +++ b/PortabilityLayer/IconLoader.cpp @@ -0,0 +1,258 @@ +#include "IconLoader.h" +#include "PLCore.h" +#include "PLCTabReducer.h" +#include "ResourceManager.h" +#include "QDStandardPalette.h" +#include "QDPixMap.h" + +#include "SharedTypes.h" + +// Color icons (cicn) format: +// ColorIconSerializedData (82 bytes) +// Mask bits +// B&W bits +// BEColorTableHeader (8 bytes) +// BEColorTableItem (8 bytes) +// Color bits + +// ICON format is just a 32x32 bitfield + +struct IconImagePrefix +{ + BEUInt32_t m_unknown; // Seems to always be zero + BEUInt16_t m_pitch; // +0x8000 for color +}; + +struct ColorIconSerializedData +{ + IconImagePrefix m_colorPrefix; + BEPixMap m_colorPixMap; + IconImagePrefix m_maskPrefix; + BEBitMap m_maskBitMap; + IconImagePrefix m_bwPrefix; + BEBitMap m_bwBitMap; + + uint8_t m_unused[4]; +}; + +namespace PortabilityLayer +{ + class IconLoaderImpl final : public IconLoader + { + public: + bool LoadColorIcon(const int16_t id, THandle &outColorImage, THandle &outBWImage, THandle &outMaskImage) override; + THandle LoadBWIcon(const int16_t id) override; + + static IconLoaderImpl *GetInstance(); + + private: + static bool ParseColorImage(const IconImagePrefix &prefix, const BEPixMap &pixMapHeader, THandle &outHandle, const uint8_t *&dataPtr); + static bool ParseBWImage(const IconImagePrefix &prefix, const BEBitMap &bitMapHeader, THandle &outHandle, const uint8_t *&dataPtr); + + static IconLoaderImpl ms_instance; + }; + + + bool IconLoaderImpl::LoadColorIcon(const int16_t id, THandle &outColorImage, THandle &outBWImage, THandle &outMaskImage) + { + THandle data = PortabilityLayer::ResourceManager::GetInstance()->GetResource('cicn', id).StaticCast(); + + if (!data) + return false; + + GP_STATIC_ASSERT(sizeof(ColorIconSerializedData) == 82); + + ColorIconSerializedData header; + memcpy(&header, *data, sizeof(header)); + + const uint8_t *dataPtr = (*data) + sizeof(header); + + THandle maskImage; + if (!ParseBWImage(header.m_maskPrefix, header.m_maskBitMap, maskImage, dataPtr)) + { + data.Dispose(); + return false; + } + + THandle bwImage; + if (!ParseBWImage(header.m_bwPrefix, header.m_bwBitMap, bwImage, dataPtr)) + { + PixMapImpl::Destroy(maskImage); + data.Dispose(); + return false; + } + + THandle colorImage; + if (!ParseColorImage(header.m_colorPrefix, header.m_colorPixMap, colorImage, dataPtr)) + { + PixMapImpl::Destroy(bwImage); + PixMapImpl::Destroy(maskImage); + data.Dispose(); + return false; + } + + outColorImage = colorImage; + outBWImage = bwImage; + outMaskImage = maskImage; + + return true; + } + + bool IconLoaderImpl::ParseColorImage(const IconImagePrefix &prefix, const BEPixMap &pixMapHeader, THandle &outHandle, const uint8_t *&dataPtr) + { + if (pixMapHeader.m_componentCount != 1 || pixMapHeader.m_packType != 0) + { + PL_NotYetImplemented(); + return false; + } + + const uint8_t *inData = dataPtr; + + BEColorTableHeader colorTableHeader; + memcpy(&colorTableHeader, inData, sizeof(BEColorTableHeader)); + + inData += sizeof(BEColorTableHeader); + + const size_t numItems = static_cast(colorTableHeader.m_numItemsMinusOne) + 1; + if (numItems > 256) + return false; + + uint8_t remapping[256]; + for (int i = 0; i < 256; i++) + remapping[i] = 0; + + for (size_t i = 0; i < numItems; i++) + { + BEColorTableItem ctabItem; + memcpy(&ctabItem, inData, sizeof(BEColorTableItem)); + inData += sizeof(BEColorTableItem); + + const uint16_t index = ctabItem.m_index; + if (index >= 256) + return false; + + const PortabilityLayer::RGBAColor remappedColor = CTabReducer::DecodeClutItem(ctabItem); + + remapping[index] = StandardPalette::GetInstance()->MapColorLUT(remappedColor); + } + + const Rect rect = pixMapHeader.m_bounds.ToRect(); + if (!rect.IsValid()) + return false; + + THandle pixMap = PixMapImpl::Create(rect, GpPixelFormats::k8BitStandard); + if (!pixMap) + return false; + + const size_t width = rect.Width(); + const size_t height = rect.Height(); + const size_t inPitch = (prefix.m_pitch & 0x7fff); + + uint8_t *outData = static_cast((*pixMap)->GetPixelData()); + const size_t outPitch = (*pixMap)->GetPitch(); + + for (size_t row = 0; row < height; row++) + { + if (numItems > 16) + { + // 8bpp + for (size_t col = 0; col < width; col++) + { + const unsigned int index = inData[col]; + outData[col] = remapping[index]; + } + } + else if (numItems > 4) + { + // 4bpp + for (size_t col = 0; col < width; col++) + { + const unsigned int index = (inData[col / 2] >> (4 - ((col & 1) * 4))) & 0x0f; + outData[col] = remapping[index]; + } + } + else if (numItems > 2) + { + // 2bpp + for (size_t col = 0; col < width; col++) + { + const unsigned int index = (inData[col / 4] >> (6 - ((col & 3) * 2))) & 0x03; + outData[col] = remapping[index]; + } + } + else + { + // 1bpp + for (size_t col = 0; col < width; col++) + { + const unsigned int index = (inData[col / 4] >> (7 - (col & 7))) & 0x01; + outData[col] = remapping[index]; + } + } + + inData += inPitch; + outData += outPitch; + } + + outHandle = pixMap; + dataPtr = inData; + + return true; + } + + bool IconLoaderImpl::ParseBWImage(const IconImagePrefix &prefix, const BEBitMap &bitMapHeader, THandle &outHandle, const uint8_t *&dataPtr) + { + const Rect rect = bitMapHeader.m_bounds.ToRect(); + if (!rect.IsValid()) + return false; + + THandle pixMap = PixMapImpl::Create(rect, GpPixelFormats::kBW1); + if (!pixMap) + return THandle(); + + const size_t inPitch = prefix.m_pitch; + const size_t height = rect.Height(); + const size_t width = rect.Width(); + + const uint8_t *inData = dataPtr; + uint8_t *outData = static_cast((*pixMap)->GetPixelData()); + const size_t outPitch = (*pixMap)->GetPitch(); + + for (size_t row = 0; row < height; row++) + { + for (size_t col = 0; col < width; col++) + { + if (inData[col / 8] & (0x80 >> (col & 7))) + outData[col] = 0xff; + else + outData[col] = 0x00; + } + + inData += inPitch; + outData += outPitch; + } + + dataPtr = inData; + outHandle = pixMap; + + return true; + } + + THandle IconLoaderImpl::LoadBWIcon(const int16_t id) + { + PL_NotYetImplemented(); + return THandle(); + } + + IconLoaderImpl *IconLoaderImpl::GetInstance() + { + return &ms_instance; + } + + IconLoaderImpl IconLoaderImpl::ms_instance; + + IconLoader *IconLoader::GetInstance() + { + return IconLoaderImpl::GetInstance(); + } +} diff --git a/PortabilityLayer/IconLoader.h b/PortabilityLayer/IconLoader.h new file mode 100644 index 0000000..5eb93b9 --- /dev/null +++ b/PortabilityLayer/IconLoader.h @@ -0,0 +1,21 @@ +#pragma once + +#include + +template +class THandle; + +namespace PortabilityLayer +{ + class PixMapImpl; + class SimpleImage; + + class IconLoader + { + public: + virtual bool LoadColorIcon(const int16_t id, THandle &outColorImage, THandle &outBWImage, THandle &outMaskImage) = 0; + virtual THandle LoadBWIcon(const int16_t id) = 0; + + static IconLoader *GetInstance(); + }; +} diff --git a/PortabilityLayer/MMBlock.cpp b/PortabilityLayer/MMBlock.cpp index 7c34c43..3902d6e 100644 --- a/PortabilityLayer/MMBlock.cpp +++ b/PortabilityLayer/MMBlock.cpp @@ -4,8 +4,8 @@ namespace PortabilityLayer { size_t MMBlock::AlignedSize() { - const size_t paddedSize = sizeof(MMBlock) + PL_SYSTEM_MEMORY_ALIGNMENT - 1; - const size_t paddedSizeTruncated = paddedSize - (paddedSize % PL_SYSTEM_MEMORY_ALIGNMENT); + const size_t paddedSize = sizeof(MMBlock) + GP_SYSTEM_MEMORY_ALIGNMENT - 1; + const size_t paddedSizeTruncated = paddedSize - (paddedSize % GP_SYSTEM_MEMORY_ALIGNMENT); return paddedSizeTruncated; } diff --git a/PortabilityLayer/MMBlock.h b/PortabilityLayer/MMBlock.h index 844094a..7e9ef0c 100644 --- a/PortabilityLayer/MMBlock.h +++ b/PortabilityLayer/MMBlock.h @@ -11,7 +11,7 @@ namespace PortabilityLayer { struct MMBlock { - SmallestUInt::ValueType_t m_offsetFromAllocLocation; + SmallestUInt::ValueType_t m_offsetFromAllocLocation; static size_t AlignedSize(); }; diff --git a/PortabilityLayer/MMHandleBlock.h b/PortabilityLayer/MMHandleBlock.h index bff3801..fa6cffe 100644 --- a/PortabilityLayer/MMHandleBlock.h +++ b/PortabilityLayer/MMHandleBlock.h @@ -22,7 +22,7 @@ namespace PortabilityLayer size_t m_size; private: - MMHandleBlock() PL_DELETED; + MMHandleBlock() GP_DELETED; }; } diff --git a/PortabilityLayer/MemReaderStream.h b/PortabilityLayer/MemReaderStream.h index 4e61b76..da85259 100644 --- a/PortabilityLayer/MemReaderStream.h +++ b/PortabilityLayer/MemReaderStream.h @@ -26,7 +26,7 @@ namespace PortabilityLayer void Close() override; private: - MemReaderStream() PL_DELETED; + MemReaderStream() GP_DELETED; const uint8_t *m_bytes; size_t m_size; diff --git a/PortabilityLayer/MemoryManager.cpp b/PortabilityLayer/MemoryManager.cpp index fcd0206..4d9d17e 100644 --- a/PortabilityLayer/MemoryManager.cpp +++ b/PortabilityLayer/MemoryManager.cpp @@ -1,12 +1,12 @@ #include "MemoryManager.h" #include "MMBlock.h" #include "MMHandleBlock.h" -#include "ResourceCompiledRef.h" +#include "ResourceCompiledRef.h" #include "ResourceManager.h" #include #include -#include +#include #include namespace PortabilityLayer @@ -16,10 +16,10 @@ namespace PortabilityLayer public: void Init() override; void Shutdown() override; - - void *Alloc(size_t size) override; + + void *Alloc(size_t size) override; void *Realloc(void *buf, size_t newSize) override; - void Release(void *buf) override; + void Release(void *buf) override; MMHandleBlock *AllocHandle(size_t size) override; bool ResizeHandle(MMHandleBlock *hdl, size_t newSize) override; @@ -38,40 +38,40 @@ namespace PortabilityLayer void MemoryManagerImpl::Shutdown() { - } + } - void *MemoryManagerImpl::Realloc(void *buf, size_t newSize) - { - assert(buf != nullptr); + void *MemoryManagerImpl::Realloc(void *buf, size_t newSize) + { + assert(buf != nullptr); const size_t mmBlockSize = MMBlock::AlignedSize(); uint8_t *oldBufBytes = static_cast(buf); - const MMBlock *oldBufMMBlock = reinterpret_cast(oldBufBytes - MMBlock::AlignedSize()); - - const size_t oldBufOffsetFromAlignLoc = oldBufMMBlock->m_offsetFromAllocLocation; - uint8_t *oldBufBase = oldBufBytes - MMBlock::AlignedSize() - oldBufOffsetFromAlignLoc; + const MMBlock *oldBufMMBlock = reinterpret_cast(oldBufBytes - MMBlock::AlignedSize()); - const size_t mmBlockSizeWithMaxPadding = MMBlock::AlignedSize() + PL_SYSTEM_MEMORY_ALIGNMENT - 1; + const size_t oldBufOffsetFromAlignLoc = oldBufMMBlock->m_offsetFromAllocLocation; + uint8_t *oldBufBase = oldBufBytes - MMBlock::AlignedSize() - oldBufOffsetFromAlignLoc; + + const size_t mmBlockSizeWithMaxPadding = MMBlock::AlignedSize() + GP_SYSTEM_MEMORY_ALIGNMENT - 1; if (SIZE_MAX - newSize < mmBlockSizeWithMaxPadding) - return nullptr; - - const size_t newBufferSize = newSize + mmBlockSizeWithMaxPadding; - uint8_t *newBuffer = static_cast(realloc(oldBufBase, newSize + mmBlockSizeWithMaxPadding)); - if (!newBuffer) - return nullptr; + return nullptr; - const intptr_t offsetFromAlignPoint = reinterpret_cast(newBuffer) & static_cast(PL_SYSTEM_MEMORY_ALIGNMENT - 1); + const size_t newBufferSize = newSize + mmBlockSizeWithMaxPadding; + uint8_t *newBuffer = static_cast(realloc(oldBufBase, newSize + mmBlockSizeWithMaxPadding)); + if (!newBuffer) + return nullptr; + + const intptr_t offsetFromAlignPoint = reinterpret_cast(newBuffer) & static_cast(GP_SYSTEM_MEMORY_ALIGNMENT - 1); intptr_t alignPadding = 0; if (offsetFromAlignPoint != 0) - alignPadding = static_cast(PL_SYSTEM_MEMORY_ALIGNMENT) - offsetFromAlignPoint; - - // Check if the alignment changed, if so relocate - if (static_cast(alignPadding) != oldBufOffsetFromAlignLoc) - memmove(newBuffer + alignPadding, newBuffer + oldBufOffsetFromAlignLoc, MMBlock::AlignedSize() + newSize); + alignPadding = static_cast(GP_SYSTEM_MEMORY_ALIGNMENT) - offsetFromAlignPoint; + + // Check if the alignment changed, if so relocate + if (static_cast(alignPadding) != oldBufOffsetFromAlignLoc) + memmove(newBuffer + alignPadding, newBuffer + oldBufOffsetFromAlignLoc, MMBlock::AlignedSize() + newSize); + + MMBlock *newMMBlock = reinterpret_cast(newBuffer + alignPadding); + newMMBlock->m_offsetFromAllocLocation = static_cast::ValueType_t>(alignPadding); - MMBlock *newMMBlock = reinterpret_cast(newBuffer + alignPadding); - newMMBlock->m_offsetFromAllocLocation = static_cast::ValueType_t>(alignPadding); - return newBuffer + alignPadding + MMBlock::AlignedSize(); } @@ -80,7 +80,7 @@ namespace PortabilityLayer if (size == 0) return nullptr; - const size_t mmBlockSizeWithMaxPadding = MMBlock::AlignedSize() + PL_SYSTEM_MEMORY_ALIGNMENT - 1; + const size_t mmBlockSizeWithMaxPadding = MMBlock::AlignedSize() + GP_SYSTEM_MEMORY_ALIGNMENT - 1; if (SIZE_MAX - size < mmBlockSizeWithMaxPadding) return nullptr; @@ -88,13 +88,13 @@ namespace PortabilityLayer if (!buffer) return nullptr; - const intptr_t offsetFromAlignPoint = reinterpret_cast(buffer) & static_cast(PL_SYSTEM_MEMORY_ALIGNMENT - 1); + const intptr_t offsetFromAlignPoint = reinterpret_cast(buffer) & static_cast(GP_SYSTEM_MEMORY_ALIGNMENT - 1); intptr_t alignPadding = 0; if (offsetFromAlignPoint != 0) - alignPadding = static_cast(PL_SYSTEM_MEMORY_ALIGNMENT) - offsetFromAlignPoint; + alignPadding = static_cast(GP_SYSTEM_MEMORY_ALIGNMENT) - offsetFromAlignPoint; MMBlock *mmBlock = reinterpret_cast(buffer + alignPadding); - mmBlock->m_offsetFromAllocLocation = static_cast::ValueType_t>(alignPadding); + mmBlock->m_offsetFromAllocLocation = static_cast::ValueType_t>(alignPadding); return buffer + alignPadding + MMBlock::AlignedSize(); } @@ -118,23 +118,23 @@ namespace PortabilityLayer MMHandleBlock *handleBlock = static_cast(Alloc(sizeof(MMHandleBlock))); return new (handleBlock) MMHandleBlock(contents, size); - } + } - bool MemoryManagerImpl::ResizeHandle(MMHandleBlock *hdl, size_t newSize) - { - if (hdl->m_contents == nullptr) - return false; - - if (newSize != hdl->m_size) + bool MemoryManagerImpl::ResizeHandle(MMHandleBlock *hdl, size_t newSize) + { + if (hdl->m_contents == nullptr) + return false; + + if (newSize != hdl->m_size) { - void *newBuf = Realloc(hdl->m_contents, newSize); - if (!newBuf) - return false; - - hdl->m_contents = newBuf; - hdl->m_size = newSize; - } - + void *newBuf = Realloc(hdl->m_contents, newSize); + if (!newBuf) + return false; + + hdl->m_contents = newBuf; + hdl->m_size = newSize; + } + return true; } @@ -142,8 +142,8 @@ namespace PortabilityLayer { if (!hdl) return; - - if (hdl->m_rmSelfRef) + + if (hdl->m_rmSelfRef) PortabilityLayer::ResourceManager::GetInstance()->DissociateHandle(hdl); if (hdl->m_contents) diff --git a/PortabilityLayer/PLArrayView.h b/PortabilityLayer/PLArrayView.h index 67ffb78..172f98d 100644 --- a/PortabilityLayer/PLArrayView.h +++ b/PortabilityLayer/PLArrayView.h @@ -23,8 +23,13 @@ private: size_t m_count; }; +#include "CoreDefs.h" #include "PLArrayViewIterator.h" +#if GP_DEBUG_CONFIG +#include +#endif + template inline ArrayView::ArrayView(const T *items, size_t count) : m_items(items) @@ -48,17 +53,29 @@ inline size_t ArrayView::Count() const template const T &ArrayView::operator[](size_t index) const { +#if GP_DEBUG_CONFIG + assert(index < m_count); +#endif + return m_items[index]; } template inline ArrayViewIterator ArrayView::begin() const { +#if GP_DEBUG_CONFIG + return ArrayViewIterator(m_items, m_count, 0); +#else return ArrayViewIterator(m_items); +#endif } template inline ArrayViewIterator ArrayView::end() const { +#if GP_DEBUG_CONFIG + return ArrayViewIterator(m_items, m_count, m_count); +#else return ArrayViewIterator(m_items + m_count); +#endif } diff --git a/PortabilityLayer/PLArrayViewIterator.h b/PortabilityLayer/PLArrayViewIterator.h index 49951f6..5290c0c 100644 --- a/PortabilityLayer/PLArrayViewIterator.h +++ b/PortabilityLayer/PLArrayViewIterator.h @@ -1,12 +1,18 @@ #pragma once +#include "CoreDefs.h" + #include template class ArrayViewIterator -{ +{ public: +#if GP_DEBUG_CONFIG + ArrayViewIterator(T *items, size_t count, size_t index); +#else ArrayViewIterator(T *item); +#endif ArrayViewIterator(const ArrayViewIterator &other); ArrayViewIterator operator++(int); @@ -24,9 +30,88 @@ public: operator T*() const; private: +#if GP_DEBUG_CONFIG + T *m_items; + size_t m_count; + size_t m_index; +#else T *m_iter; +#endif }; +#if GP_DEBUG_CONFIG + +#include + +template +inline ArrayViewIterator::ArrayViewIterator(T *items, size_t count, size_t index) + : m_items(items) + , m_count(count) + , m_index(index) +{ +} + +template +inline ArrayViewIterator::ArrayViewIterator(const ArrayViewIterator &other) + : m_items(other.m_items) + , m_count(other.m_count) + , m_index(other.m_index) +{ +} + +template +inline ArrayViewIterator &ArrayViewIterator::operator+=(ptrdiff_t delta) +{ + if (delta < 0) + { + assert(-static_cast(m_index) >= delta); + } + else + { + assert(static_cast(m_count) >= delta && static_cast(m_count - m_index) >= delta); + } + + m_index = static_cast(static_cast(m_index) + delta); + return *this; +} + +template +inline ArrayViewIterator &ArrayViewIterator::operator-=(ptrdiff_t delta) +{ + if (delta >= 0) + { + assert(static_cast(m_index) >= delta); + } + else + { + assert(-static_cast(m_count) <= delta && -static_cast(m_count - m_index) <= delta); + } + + m_index = static_cast(static_cast(m_index) - delta); + return *this; +} + +template +inline bool ArrayViewIterator::operator==(const ArrayViewIterator &other) const +{ + return m_index == other.m_index && m_items == other.m_items; +} + +template +inline bool ArrayViewIterator::operator!=(const ArrayViewIterator &other) const +{ + return m_index != other.m_index || m_items != other.m_items; +} + +template +inline ArrayViewIterator::operator T*() const +{ + assert(m_index < m_count); + return m_items + m_index; +} + +#else + template inline ArrayViewIterator::ArrayViewIterator(T *item) : m_iter(item) @@ -39,36 +124,6 @@ inline ArrayViewIterator::ArrayViewIterator(const ArrayViewIterator &other { } -template -inline ArrayViewIterator ArrayViewIterator::operator++(int) -{ - ArrayViewIterator copy = *this; - m_iter++; - return copy; -} - -template -inline ArrayViewIterator &ArrayViewIterator::operator++() -{ - m_iter++; - return *this; -} - -template -inline ArrayViewIterator ArrayViewIterator::operator--(int) -{ - ArrayViewIterator copy = *this; - m_iter--; - return copy; -} - -template -inline ArrayViewIterator &ArrayViewIterator::operator--() -{ - m_iter--; - return *this; -} - template inline ArrayViewIterator &ArrayViewIterator::operator+=(ptrdiff_t delta) { @@ -92,7 +147,7 @@ inline bool ArrayViewIterator::operator==(const ArrayViewIterator &other) template inline bool ArrayViewIterator::operator!=(const ArrayViewIterator &other) const { - return m_iter == other.m_iter; + return m_iter != other.m_iter; } template @@ -100,3 +155,36 @@ inline ArrayViewIterator::operator T*() const { return m_iter; } +#endif + + +template +inline ArrayViewIterator ArrayViewIterator::operator++(int) +{ + ArrayViewIterator copy = *this; + ++(*this); + return copy; +} + + +template +inline ArrayViewIterator ArrayViewIterator::operator--(int) +{ + ArrayViewIterator copy = *this; + --(*this); + return copy; +} + +template +inline ArrayViewIterator &ArrayViewIterator::operator++() +{ + (*this) += 1; + return *this; +} + +template +inline ArrayViewIterator &ArrayViewIterator::operator--() +{ + (*this) -= 1; + return *this; +} diff --git a/PortabilityLayer/PLButtonWidget.cpp b/PortabilityLayer/PLButtonWidget.cpp new file mode 100644 index 0000000..8c83bba --- /dev/null +++ b/PortabilityLayer/PLButtonWidget.cpp @@ -0,0 +1,54 @@ +#include "PLButtonWidget.h" +#include "PLCore.h" +#include "PLTimeTaggedVOSEvent.h" + +namespace PortabilityLayer +{ + ButtonWidget::ButtonWidget(const WidgetBasicState &state) + : WidgetSpec(state) + , m_haveMouseDown(false) + { + } + + WidgetHandleState_t ButtonWidget::ProcessEvent(Window *window, const TimeTaggedVOSEvent &evt) + { + if (m_haveMouseDown) + { + if (evt.IsLMouseUpEvent()) + { + m_haveMouseDown = false; + + const Point pt = window->MouseToLocal(evt.m_vosEvent.m_event.m_mouseInputEvent); + if (m_rect.Contains(pt)) + return WidgetHandleStates::kActivated; + else + return WidgetHandleStates::kIgnored; + } + + return WidgetHandleStates::kCaptured; + } + else + { + if (evt.IsLMouseDownEvent()) + { + const Point pt = window->MouseToLocal(evt.m_vosEvent.m_event.m_mouseInputEvent); + + if (m_rect.Contains(pt)) + { + m_haveMouseDown = true; + return WidgetHandleStates::kCaptured; + } + else + return WidgetHandleStates::kIgnored; + } + } + + return WidgetHandleStates::kIgnored; + } + + bool ButtonWidget::Init(const WidgetBasicState &state) + { + (void)state; + return true; + } +} diff --git a/PortabilityLayer/PLButtonWidget.h b/PortabilityLayer/PLButtonWidget.h new file mode 100644 index 0000000..215cceb --- /dev/null +++ b/PortabilityLayer/PLButtonWidget.h @@ -0,0 +1,21 @@ +#pragma once + +#include "PascalStr.h" +#include "PLWidgets.h" + +namespace PortabilityLayer +{ + class ButtonWidget final : public WidgetSpec + { + public: + explicit ButtonWidget(const WidgetBasicState &state); + + bool Init(const WidgetBasicState &state) override; + + WidgetHandleState_t ProcessEvent(Window *window, const TimeTaggedVOSEvent &evt); + + private: + bool m_haveMouseDown; + PascalStr<255> m_text; + }; +} diff --git a/PortabilityLayer/PLCTabReducer.cpp b/PortabilityLayer/PLCTabReducer.cpp new file mode 100644 index 0000000..f737df7 --- /dev/null +++ b/PortabilityLayer/PLCTabReducer.cpp @@ -0,0 +1,28 @@ +#include "PLCTabReducer.h" +#include "RGBAColor.h" + +#include "SharedTypes.h" + +namespace PortabilityLayer +{ + uint8_t CTabReducer::DecodeClutItemChannel(const uint8_t *color16) + { + const int colorHigh = color16[0]; + const int colorLow = color16[1]; + + const int lowDelta = colorLow - colorHigh; + if (lowDelta < -128) + return static_cast(colorHigh - 1); + else if (lowDelta > 128) + return static_cast(colorHigh + 1); + return static_cast(colorHigh); + } + + RGBAColor CTabReducer::DecodeClutItem(const BEColorTableItem &clutItem) + { + const uint8_t r = DecodeClutItemChannel(clutItem.m_red); + const uint8_t g = DecodeClutItemChannel(clutItem.m_green); + const uint8_t b = DecodeClutItemChannel(clutItem.m_blue); + return RGBAColor::Create(r, g, b, 255); + } +} diff --git a/PortabilityLayer/PLCTabReducer.h b/PortabilityLayer/PLCTabReducer.h new file mode 100644 index 0000000..0f037e3 --- /dev/null +++ b/PortabilityLayer/PLCTabReducer.h @@ -0,0 +1,17 @@ +#pragma once + +#include + +struct BEColorTableItem; + +namespace PortabilityLayer +{ + struct RGBAColor; + + class CTabReducer + { + public: + static uint8_t DecodeClutItemChannel(const uint8_t *color16); + static RGBAColor DecodeClutItem(const BEColorTableItem &clutItem); + }; +} diff --git a/PortabilityLayer/PLCore.cpp b/PortabilityLayer/PLCore.cpp index a729181..32e19b8 100644 --- a/PortabilityLayer/PLCore.cpp +++ b/PortabilityLayer/PLCore.cpp @@ -33,6 +33,7 @@ #include "PLBigEndian.h" #include "PLEventQueue.h" #include "PLKeyEncoding.h" +#include "PLSysCalls.h" #include "PLTimeTaggedVOSEvent.h" #include "QDManager.h" #include "Vec2i.h" @@ -65,113 +66,6 @@ static bool ConvertFilenameToSafePStr(const char *str, uint8_t *pstr) return true; } -static void TranslateMouseInputEvent(const GpVOSEvent &vosEventBase, uint32_t timestamp, PortabilityLayer::EventQueue *queue) -{ - const GpMouseInputEvent &vosEvent = vosEventBase.m_event.m_mouseInputEvent; - - bool requeue = false; - if (vosEvent.m_button == GpMouseButtons::kLeft) - { - if (vosEvent.m_eventType == GpMouseEventTypes::kDown) - requeue = true; - else if (vosEvent.m_eventType == GpMouseEventTypes::kUp) - requeue = true; - } - else if (vosEvent.m_eventType == GpMouseEventTypes::kMove) - requeue = true; - - if (requeue) - { - if (TimeTaggedVOSEvent *evt = queue->Enqueue()) - *evt = TimeTaggedVOSEvent::Create(vosEventBase, timestamp); - } -} - -static void TranslateGamepadInputEvent(const GpGamepadInputEvent &vosEvent, PortabilityLayer::EventQueue *queue) -{ - PortabilityLayer::InputManager *inputManager = PortabilityLayer::InputManager::GetInstance(); - - inputManager->ApplyGamepadEvent(vosEvent); - - PL_DEAD(queue); -} - -static void TranslateKeyboardInputEvent(const GpVOSEvent &vosEventBase, uint32_t timestamp, PortabilityLayer::EventQueue *queue) -{ - const GpKeyboardInputEvent &vosEvent = vosEventBase.m_event.m_keyboardInputEvent; - - PL_STATIC_ASSERT((1 << PL_INPUT_PLAYER_INDEX_BITS) >= PL_INPUT_MAX_PLAYERS); - PL_STATIC_ASSERT((1 << PL_INPUT_TYPE_CODE_BITS) >= KeyEventType_Count); - - PortabilityLayer::InputManager *inputManager = PortabilityLayer::InputManager::GetInstance(); - - if (vosEvent.m_eventType == GpKeyboardInputEventTypes::kUp || vosEvent.m_eventType == GpKeyboardInputEventTypes::kDown) - inputManager->ApplyKeyboardEvent(vosEvent); - - if (TimeTaggedVOSEvent *evt = queue->Enqueue()) - *evt = TimeTaggedVOSEvent::Create(vosEventBase, timestamp); -} - -intptr_t PackVOSKeyCode(const GpKeyboardInputEvent &vosEvent) -{ - switch (vosEvent.m_keyIDSubset) - { - case GpKeyIDSubsets::kASCII: - return PL_KEY_ASCII(vosEvent.m_key.m_asciiChar); - case GpKeyIDSubsets::kFKey: - return PL_KEY_FKEY(vosEvent.m_key.m_fKey); - case GpKeyIDSubsets::kNumPadNumber: - return PL_KEY_NUMPAD_NUMBER(vosEvent.m_key.m_numPadNumber); - case GpKeyIDSubsets::kSpecial: - return PL_KEY_SPECIAL_ENCODE(vosEvent.m_key.m_specialKey); - break; - case GpKeyIDSubsets::kNumPadSpecial: - return PL_KEY_NUMPAD_SPECIAL_ENCODE(vosEvent.m_key.m_numPadSpecialKey); - break; - case GpKeyIDSubsets::kUnicode: - for (int i = 128; i < 256; i++) - { - if (PortabilityLayer::MacRoman::g_toUnicode[i] == vosEvent.m_key.m_unicodeChar) - return PL_KEY_MACROMAN(i); - } - break; - case GpKeyIDSubsets::kGamepadButton: - return PL_KEY_GAMEPAD_BUTTON_ENCODE(vosEvent.m_key.m_gamepadKey.m_button, vosEvent.m_key.m_gamepadKey.m_player); - default: - return 0; - } - - return 0; -} - -static void TranslateVOSEvent(const GpVOSEvent *vosEvent, uint32_t timestamp, PortabilityLayer::EventQueue *queue) -{ - switch (vosEvent->m_eventType) - { - case GpVOSEventTypes::kMouseInput: - TranslateMouseInputEvent(*vosEvent, timestamp, queue); - break; - case GpVOSEventTypes::kKeyboardInput: - TranslateKeyboardInputEvent(*vosEvent, timestamp, queue); - break; - case GpVOSEventTypes::kGamepadInput: - TranslateGamepadInputEvent(vosEvent->m_event.m_gamepadInputEvent, queue); - break; - } -} - -static void ImportVOSEvents(uint32_t timestamp) -{ - PortabilityLayer::EventQueue *plQueue = PortabilityLayer::EventQueue::GetInstance(); - - PortabilityLayer::HostVOSEventQueue *evtQueue = PortabilityLayer::HostVOSEventQueue::GetInstance(); - while (const GpVOSEvent *evt = evtQueue->GetNext()) - { - TranslateVOSEvent(evt, timestamp, plQueue); - evtQueue->DischargeOne(); - } -} - void InitCursor() { PortabilityLayer::HostDisplayDriver::GetInstance()->SetStandardCursor(EGpStandardCursors::kArrow); @@ -244,15 +138,7 @@ void DisposeCCursor(CCrsrHandle handle) void Delay(int ticks, UInt32 *endTickCount) { - if (ticks > 0) - { - PortabilityLayer::HostSuspendCallArgument args[1]; - args[0].m_uint = static_cast(ticks); - - PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_Delay, args, nullptr); - - ImportVOSEvents(PortabilityLayer::DisplayDeviceManager::GetInstance()->GetTickCount()); - } + PLSysCalls::Sleep(ticks); if (endTickCount) *endTickCount = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetTickCount(); @@ -718,30 +604,6 @@ void DisposeDirectoryFiles(DirectoryFileListEntry *firstDFL) } } -short StringWidth(const PLPasStr &str) -{ - const PortabilityLayer::QDState *qdState = PortabilityLayer::QDManager::GetInstance()->GetState(); - PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance(); - - PortabilityLayer::FontFamily *fontFamily = qdState->m_fontFamily; - - if (!fontFamily) - return 0; - - const int variationFlags = qdState->m_fontVariationFlags; - const int fontSize = qdState->m_fontSize; - - PortabilityLayer::RenderedFont *rfont = fontManager->GetRenderedFontFromFamily(fontFamily, fontSize, variationFlags); - if (!rfont) - return 0; - - const size_t width = rfont->MeasureString(str.UChars(), str.Length()); - if (width > SHRT_MAX) - return SHRT_MAX; - - return static_cast(width); -} - void GetMouse(Point *point) { PL_NotYetImplemented(); @@ -965,3 +827,8 @@ DrawSurface *Window::GetDrawSurface() const { return const_cast(&m_graf); } + +Point Window::MouseToLocal(const GpMouseInputEvent &evt) const +{ + return Point::Create(evt.m_x - m_wmX, evt.m_y - m_wmY); +} diff --git a/PortabilityLayer/PLCore.h b/PortabilityLayer/PLCore.h index 2977e6a..f97a1b8 100644 --- a/PortabilityLayer/PLCore.h +++ b/PortabilityLayer/PLCore.h @@ -15,6 +15,7 @@ struct IGpColorCursor; struct GpVOSEvent; +struct GpMouseInputEvent; struct TimeTaggedVOSEvent; namespace PortabilityLayer @@ -104,6 +105,9 @@ struct Window DrawSurface *GetDrawSurface() const; + // Convenience method to convert a mouse event to local point + Point MouseToLocal(const GpMouseInputEvent &evt) const; + DrawSurface m_graf; // Must be the first item // The port is always at 0,0 @@ -308,8 +312,6 @@ PLError_t PBGetCatInfo(CInfoPBPtr paramBlock, Boolean async); DirectoryFileListEntry *GetDirectoryFiles(PortabilityLayer::VirtualDirectory_t dirID); void DisposeDirectoryFiles(DirectoryFileListEntry *firstDFL); -short StringWidth(const PLPasStr &str); - void GetMouse(Point *point); Boolean Button(); // Returns true if there's a mouse down event in the queue Boolean StillDown(); diff --git a/PortabilityLayer/PLDialogs.cpp b/PortabilityLayer/PLDialogs.cpp index 288c57b..d9dd2d9 100644 --- a/PortabilityLayer/PLDialogs.cpp +++ b/PortabilityLayer/PLDialogs.cpp @@ -71,8 +71,3 @@ void HideDialogItem(Dialog *dialog, int item) { PL_NotYetImplemented(); } - -void TETextBox(const PLPasStr &str, short len, const Rect *rect, TEMode teMode) -{ - PL_NotYetImplemented(); -} diff --git a/PortabilityLayer/PLDialogs.h b/PortabilityLayer/PLDialogs.h index 1816834..f1f99ad 100644 --- a/PortabilityLayer/PLDialogs.h +++ b/PortabilityLayer/PLDialogs.h @@ -1,30 +1,29 @@ #pragma once -#ifndef __PL_DIALOGS_H__ -#define __PL_DIALOGS_H__ #include "PLCore.h" +namespace PortabilityLayer +{ + class DialogItem; +} + template class ArrayView; class PLPasStr; struct Control; +struct Dialog; -struct DialogItem -{ - virtual Rect GetRect() const = 0; -}; +typedef int16_t(*DialogFilterFunc_t)(Dialog *dialog, const TimeTaggedVOSEvent &evt); struct Dialog { virtual void Destroy() = 0; - virtual Window *GetWindow() const = 0; - virtual ArrayView GetItems() const = 0; -}; -enum TEMode -{ - teCenter + virtual Window *GetWindow() const = 0; + virtual ArrayView GetItems() const = 0; + + virtual int16_t ExecuteModal(DialogFilterFunc_t filterFunc) = 0; }; typedef Boolean(*ModalFilterUPP)(Dialog *dial, EventRecord *event, short *item); @@ -40,16 +39,9 @@ void SetDialogItemText(THandle handle, const PLPasStr &str); void SelectDialogItemText(Dialog *dialog, int item, int firstSelChar, int lastSelCharExclusive); -ModalFilterUPP NewModalFilterUPP(ModalFilterUPP func); - void ModalDialog(ModalFilterUPP filter, short *item); void DisposeDialog(Dialog *dialog); -void DisposeModalFilterUPP(ModalFilterUPP upp); void ShowDialogItem(Dialog *dialog, int item); void HideDialogItem(Dialog *dialog, int item); - -void TETextBox(const PLPasStr &str, short len, const Rect *rect, TEMode teMode); - -#endif diff --git a/PortabilityLayer/PLHacks.cpp b/PortabilityLayer/PLHacks.cpp index 80eecdc..8b29fea 100644 --- a/PortabilityLayer/PLHacks.cpp +++ b/PortabilityLayer/PLHacks.cpp @@ -14,6 +14,6 @@ bool IsMacPlusSoundBanned() // High scores disabled until dialogs work bool IsHighScoreDisabled() -{ +{ return true; } diff --git a/PortabilityLayer/PLHandle.cpp b/PortabilityLayer/PLHandle.cpp index 8d25b5e..7985766 100644 --- a/PortabilityLayer/PLHandle.cpp +++ b/PortabilityLayer/PLHandle.cpp @@ -6,4 +6,6 @@ void THandleBase::Dispose() { if (m_hdl) PortabilityLayer::MemoryManager::GetInstance()->ReleaseHandle(m_hdl); + + m_hdl = nullptr; } diff --git a/PortabilityLayer/PLHandle.h b/PortabilityLayer/PLHandle.h index b4db377..47dab83 100644 --- a/PortabilityLayer/PLHandle.h +++ b/PortabilityLayer/PLHandle.h @@ -28,7 +28,8 @@ public: explicit THandle(PortabilityLayer::MMHandleBlock *hdl); THandle(const THandle &other); - operator T **() const; + operator T *const*() const; + operator T **(); template THandle StaticCast() const; @@ -36,11 +37,16 @@ public: template THandle ReinterpretCast() const; + template + THandle ImplicitCast() const; + bool operator==(const THandle &other) const; bool operator!=(const THandle &other) const; bool operator==(T** other) const; bool operator!=(T** other) const; + + static THandle NullPtr(); }; typedef THandle Handle; @@ -65,7 +71,7 @@ inline PortabilityLayer::MMHandleBlock *THandleBase::MMBlock() const template inline THandle::THandle() : THandleBase(nullptr) -{ +{ } template @@ -83,37 +89,51 @@ inline THandle::THandle(PortabilityLayer::MMHandleBlock *hdl) template inline THandle::THandle(const THandle &other) : THandleBase(other.m_hdl) -{ +{ } template -bool THandle::operator==(const THandle &other) const +inline bool THandle::operator==(const THandle &other) const { return m_hdl == other.m_hdl; } template -bool THandle::operator!=(const THandle &other) const +inline bool THandle::operator!=(const THandle &other) const { - return m_hdl != other.m_hdl; + return m_hdl != other.m_hdl; } template -bool THandle::operator==(T** other) const +inline bool THandle::operator==(T** other) const { return static_cast(&m_hdl->m_contents) == static_cast(other); } template -bool THandle::operator!=(T** other) const +inline bool THandle::operator!=(T** other) const { return static_cast(&m_hdl->m_contents) != static_cast(other); } template -inline THandle::operator T**() const +THandle THandle::NullPtr() { - return reinterpret_cast(&m_hdl->m_contents); + return THandle(static_cast(nullptr)); +} + +template +inline THandle::operator T*const*() const +{ + // Should use const_cast here but then I'd have to strip qualifiers, blah, do the lazy thing + return (T*const*)(&m_hdl->m_contents); +} + +template +inline THandle::operator T**() +{ + // Should use const_cast here but then I'd have to strip qualifiers, blah, do the lazy thing + return (T**)(&m_hdl->m_contents); } template @@ -131,3 +151,13 @@ THandle THandle::ReinterpretCast() const (void)(reinterpret_cast(static_cast(nullptr))); return THandle(m_hdl); } + +template +template +THandle THandle::ImplicitCast() const +{ + const TOther *target = static_cast(nullptr); + (void)target; + + return THandle(m_hdl); +} diff --git a/PortabilityLayer/PLIconWidget.cpp b/PortabilityLayer/PLIconWidget.cpp new file mode 100644 index 0000000..958603a --- /dev/null +++ b/PortabilityLayer/PLIconWidget.cpp @@ -0,0 +1,49 @@ +#include "PLIconWidget.h" + +#include "IconLoader.h" +#include "QDPixMap.h" + +#include + +namespace PortabilityLayer +{ + IconWidget::IconWidget(const WidgetBasicState &state) + : WidgetSpec(state) + { + } + + IconWidget::~IconWidget() + { + if (m_iconImage) + PixMapImpl::Destroy(m_iconImage); + if (m_iconMask) + PixMapImpl::Destroy(m_iconMask); + } + + bool IconWidget::Init(const WidgetBasicState &state) + { + PL_DEAD(str); + + THandle colorImage; + THandle bwImage; + THandle maskImage; + + if (!PortabilityLayer::IconLoader::GetInstance()->LoadColorIcon(state.m_resID, colorImage, bwImage, maskImage)) + return false; + + PixMapImpl::Destroy(bwImage); + m_iconImage = colorImage; + m_iconMask = maskImage; + + assert(m_iconImage != nullptr); + assert(m_iconMask != nullptr); + + return true; + } + + void IconWidget::DrawControl(DrawSurface *surface) + { + CopyMask(*m_iconImage, *m_iconMask, *surface->m_port.GetPixMap(), &(*m_iconImage)->m_rect, &(*m_iconMask)->m_rect, &m_rect); + surface->m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents); + } +} diff --git a/PortabilityLayer/PLIconWidget.h b/PortabilityLayer/PLIconWidget.h new file mode 100644 index 0000000..2239e2e --- /dev/null +++ b/PortabilityLayer/PLIconWidget.h @@ -0,0 +1,24 @@ +#pragma once + +#include "PLWidgets.h" +#include "PLHandle.h" + +namespace PortabilityLayer +{ + class PixMapImpl; + + class IconWidget final : public WidgetSpec + { + public: + IconWidget(const WidgetBasicState &state); + ~IconWidget() override; + + bool Init(const WidgetBasicState &state) override; + + void DrawControl(DrawSurface *surface) override; + + private: + THandle m_iconImage; + THandle m_iconMask; + }; +} diff --git a/PortabilityLayer/PLInvisibleWidget.cpp b/PortabilityLayer/PLInvisibleWidget.cpp new file mode 100644 index 0000000..7856f4e --- /dev/null +++ b/PortabilityLayer/PLInvisibleWidget.cpp @@ -0,0 +1,20 @@ +#include "PLInvisibleWidget.h" + +namespace PortabilityLayer +{ + InvisibleWidget::InvisibleWidget(const WidgetBasicState &state) + : WidgetSpec(state) + { + } + + InvisibleWidget::~InvisibleWidget() + { + } + + bool InvisibleWidget::Init(const WidgetBasicState &state) + { + (void)state; + + return true; + } +} diff --git a/PortabilityLayer/PLInvisibleWidget.h b/PortabilityLayer/PLInvisibleWidget.h new file mode 100644 index 0000000..dad8a4a --- /dev/null +++ b/PortabilityLayer/PLInvisibleWidget.h @@ -0,0 +1,15 @@ +#pragma once + +#include "PLWidgets.h" + +namespace PortabilityLayer +{ + class InvisibleWidget final : public WidgetSpec + { + public: + InvisibleWidget(const WidgetBasicState &state); + ~InvisibleWidget(); + + bool Init(const WidgetBasicState &state) override; + }; +} diff --git a/PortabilityLayer/PLLabelWidget.cpp b/PortabilityLayer/PLLabelWidget.cpp new file mode 100644 index 0000000..5286049 --- /dev/null +++ b/PortabilityLayer/PLLabelWidget.cpp @@ -0,0 +1,32 @@ +#include "PLLabelWidget.h" +#include "PLQDraw.h" +#include "FontFamily.h" +#include "PLStandardColors.h" + +#include + +namespace PortabilityLayer +{ + LabelWidget::LabelWidget(const WidgetBasicState &state) + : WidgetSpec(state) + , m_text(state.m_text) + { + } + + bool LabelWidget::Init(const WidgetBasicState &state) + { + (void)state; + return true; + } + + void LabelWidget::DrawControl(DrawSurface *surface) + { + surface->SetSystemFont(12, PortabilityLayer::FontFamilyFlag_Bold); + surface->SetForeColor(StdColors::Black()); + + const Point topLeftCorner = Point::Create(m_rect.left, m_rect.top); + const Point textStartPoint = topLeftCorner + Point::Create(0, surface->MeasureFontAscender()); + + surface->DrawString(textStartPoint, m_text.ToShortStr()); + } +} diff --git a/PortabilityLayer/PLLabelWidget.h b/PortabilityLayer/PLLabelWidget.h new file mode 100644 index 0000000..d6827ef --- /dev/null +++ b/PortabilityLayer/PLLabelWidget.h @@ -0,0 +1,20 @@ +#pragma once + +#include "PascalStr.h" +#include "PLWidgets.h" + +namespace PortabilityLayer +{ + class LabelWidget final : public WidgetSpec + { + public: + LabelWidget(const WidgetBasicState &state); + + bool Init(const WidgetBasicState &state) override; + + void DrawControl(DrawSurface *surface) override; + + private: + PascalStr<255> m_text; + }; +} diff --git a/PortabilityLayer/PLLowMem.h b/PortabilityLayer/PLLowMem.h deleted file mode 100644 index 50e9667..0000000 --- a/PortabilityLayer/PLLowMem.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once diff --git a/PortabilityLayer/PLQDraw.cpp b/PortabilityLayer/PLQDraw.cpp index 9cb0214..931251e 100644 --- a/PortabilityLayer/PLQDraw.cpp +++ b/PortabilityLayer/PLQDraw.cpp @@ -11,6 +11,7 @@ #include "HostFontHandler.h" #include "PLPasStr.h" #include "RenderedFont.h" +#include "RenderedFontMetrics.h" #include "RenderedGlyphMetrics.h" #include "Rect2i.h" #include "ResourceManager.h" @@ -274,23 +275,6 @@ PLError_t PlotIconSuite(Rect *rect, Handle iconSuite) return PLErrors::kNone; } -CIconHandle GetCIcon(short resID) -{ - PL_NotYetImplemented(); - return nullptr; -} - -PLError_t PlotCIcon(Rect *rect, CIconHandle icon) -{ - PL_NotYetImplemented(); - return PLErrors::kNone; -} - -void DisposeCIcon(CIconHandle icon) -{ - PL_NotYetImplemented(); -} - void SetRect(Rect *rect, short left, short top, short right, short bottom) { rect->left = left; @@ -523,7 +507,7 @@ static void DrawGlyph(PortabilityLayer::QDState *qdState, PixMap *pixMap, const const PortabilityLayer::RenderedGlyphMetrics *metrics; const void *data; - if (!rfont->GetGlyph(character, &metrics, &data)) + if (!rfont->GetGlyph(character, metrics, data)) return; const Point originalPoint = penPos; @@ -608,10 +592,59 @@ void DrawSurface::DrawString(const Point &point, const PLPasStr &str) if (!rect.IsValid()) return; // ??? + Point paraStartPos = penPos; + for (size_t i = 0; i < len; i++) - DrawGlyph(qdState, pixMap, rect, penPos, rfont, chars[i]); + { + if (chars[i] == static_cast('\r')) + { + paraStartPos.v += rfont->GetMetrics().m_linegap; + penPos = paraStartPos; + } + else + DrawGlyph(qdState, pixMap, rect, penPos, rfont, chars[i]); + } } +size_t DrawSurface::MeasureString(const PLPasStr &str) +{ + const PortabilityLayer::QDState *qdState = m_port.GetState(); + PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance(); + + PortabilityLayer::FontFamily *fontFamily = qdState->m_fontFamily; + + if (!fontFamily) + return 0; + + const int variationFlags = qdState->m_fontVariationFlags; + const int fontSize = qdState->m_fontSize; + + PortabilityLayer::RenderedFont *rfont = fontManager->GetRenderedFontFromFamily(fontFamily, fontSize, variationFlags); + if (!rfont) + return 0; + + return rfont->MeasureString(str.UChars(), str.Length()); +} + +int32_t DrawSurface::MeasureFontAscender() +{ + const PortabilityLayer::QDState *qdState = m_port.GetState(); + PortabilityLayer::FontManager *fontManager = PortabilityLayer::FontManager::GetInstance(); + + PortabilityLayer::FontFamily *fontFamily = qdState->m_fontFamily; + + if (!fontFamily) + return 0; + + const int variationFlags = qdState->m_fontVariationFlags; + const int fontSize = qdState->m_fontSize; + + PortabilityLayer::RenderedFont *rfont = fontManager->GetRenderedFontFromFamily(fontFamily, fontSize, variationFlags); + if (!rfont) + return 0; + + return rfont->GetMetrics().m_ascent; +} void DrawSurface::DrawPicture(THandle pictHdl, const Rect &bounds) { @@ -1056,11 +1089,6 @@ const PortabilityLayer::RGBAColor &DrawSurface::GetBackColor() const return m_port.GetState()->GetBackColor(); } -void FrameRoundRect(const Rect *rect, int w, int h) -{ - PL_NotYetImplemented_TODO("Ovals"); -} - void PenInvertMode(bool invertMode) { PortabilityLayer::QDState *qdState = PortabilityLayer::QDManager::GetInstance()->GetState(); diff --git a/PortabilityLayer/PLQDraw.h b/PortabilityLayer/PLQDraw.h index c987cd7..f9175a6 100644 --- a/PortabilityLayer/PLQDraw.h +++ b/PortabilityLayer/PLQDraw.h @@ -102,10 +102,6 @@ void EndUpdate(WindowPtr graf); PLError_t GetIconSuite(Handle *suite, short resID, IconSuiteFlags flags); PLError_t PlotIconSuite(Rect *rect, Handle iconSuite); -CIconHandle GetCIcon(short resID); -PLError_t PlotCIcon(Rect *rect, CIconHandle icon); -void DisposeCIcon(CIconHandle icon); - void SetRect(Rect *rect, short left, short top, short right, short bottom); int TextWidth(const PLPasStr &str, int firstChar1Based, int length); @@ -113,13 +109,10 @@ void SetOrigin(int x, int y); void ForeColor(SystemColorID color); void BackColor(SystemColorID color); void GetForeColor(RGBColor *color); -void PaintOval(const Rect *rect); void ClipRect(const Rect *rect); void GetClip(Rect *rect); -void FrameOval(const Rect *rect); -void FrameRoundRect(const Rect *rect, int w, int h); void PenInvertMode(bool invertMode); void PenMask(bool maskMode); void PenPat(const Pattern *pattern); diff --git a/PortabilityLayer/PLSound.cpp b/PortabilityLayer/PLSound.cpp index ea4bda0..e6516ad 100644 --- a/PortabilityLayer/PLSound.cpp +++ b/PortabilityLayer/PLSound.cpp @@ -208,7 +208,7 @@ namespace PortabilityLayer BufferHeader bufferHeader; - PL_STATIC_ASSERT(sizeof(BufferHeader) >= 22); + GP_STATIC_ASSERT(sizeof(BufferHeader) >= 22); memcpy(&bufferHeader, dataPointer, 22); diff --git a/PortabilityLayer/PLSysCalls.cpp b/PortabilityLayer/PLSysCalls.cpp new file mode 100644 index 0000000..51f6737 --- /dev/null +++ b/PortabilityLayer/PLSysCalls.cpp @@ -0,0 +1,135 @@ +#include "PLCore.h" +#include "PLEventQueue.h" +#include "PLKeyEncoding.h" +#include "PLSysCalls.h" +#include "PLTimeTaggedVOSEvent.h" +#include "DisplayDeviceManager.h" +#include "GpVOSEvent.h" +#include "InputManager.h" +#include "HostSuspendCallArgument.h" +#include "HostSuspendHook.h" +#include "HostVOSEventQueue.h" +#include "MacRoman.h" + +static void TranslateMouseInputEvent(const GpVOSEvent &vosEventBase, uint32_t timestamp, PortabilityLayer::EventQueue *queue) +{ + const GpMouseInputEvent &vosEvent = vosEventBase.m_event.m_mouseInputEvent; + + bool requeue = false; + if (vosEvent.m_button == GpMouseButtons::kLeft) + { + if (vosEvent.m_eventType == GpMouseEventTypes::kDown) + requeue = true; + else if (vosEvent.m_eventType == GpMouseEventTypes::kUp) + requeue = true; + } + else if (vosEvent.m_eventType == GpMouseEventTypes::kMove) + requeue = true; + + if (requeue) + { + if (TimeTaggedVOSEvent *evt = queue->Enqueue()) + *evt = TimeTaggedVOSEvent::Create(vosEventBase, timestamp); + } +} + +static void TranslateGamepadInputEvent(const GpGamepadInputEvent &vosEvent, PortabilityLayer::EventQueue *queue) +{ + PortabilityLayer::InputManager *inputManager = PortabilityLayer::InputManager::GetInstance(); + + inputManager->ApplyGamepadEvent(vosEvent); + + PL_DEAD(queue); +} + +static void TranslateKeyboardInputEvent(const GpVOSEvent &vosEventBase, uint32_t timestamp, PortabilityLayer::EventQueue *queue) +{ + const GpKeyboardInputEvent &vosEvent = vosEventBase.m_event.m_keyboardInputEvent; + + GP_STATIC_ASSERT((1 << PL_INPUT_PLAYER_INDEX_BITS) >= PL_INPUT_MAX_PLAYERS); + GP_STATIC_ASSERT((1 << PL_INPUT_TYPE_CODE_BITS) >= KeyEventType_Count); + + PortabilityLayer::InputManager *inputManager = PortabilityLayer::InputManager::GetInstance(); + + if (vosEvent.m_eventType == GpKeyboardInputEventTypes::kUp || vosEvent.m_eventType == GpKeyboardInputEventTypes::kDown) + inputManager->ApplyKeyboardEvent(vosEvent); + + if (TimeTaggedVOSEvent *evt = queue->Enqueue()) + *evt = TimeTaggedVOSEvent::Create(vosEventBase, timestamp); +} + +intptr_t PackVOSKeyCode(const GpKeyboardInputEvent &vosEvent) +{ + switch (vosEvent.m_keyIDSubset) + { + case GpKeyIDSubsets::kASCII: + return PL_KEY_ASCII(vosEvent.m_key.m_asciiChar); + case GpKeyIDSubsets::kFKey: + return PL_KEY_FKEY(vosEvent.m_key.m_fKey); + case GpKeyIDSubsets::kNumPadNumber: + return PL_KEY_NUMPAD_NUMBER(vosEvent.m_key.m_numPadNumber); + case GpKeyIDSubsets::kSpecial: + return PL_KEY_SPECIAL_ENCODE(vosEvent.m_key.m_specialKey); + break; + case GpKeyIDSubsets::kNumPadSpecial: + return PL_KEY_NUMPAD_SPECIAL_ENCODE(vosEvent.m_key.m_numPadSpecialKey); + break; + case GpKeyIDSubsets::kUnicode: + for (int i = 128; i < 256; i++) + { + if (PortabilityLayer::MacRoman::g_toUnicode[i] == vosEvent.m_key.m_unicodeChar) + return PL_KEY_MACROMAN(i); + } + break; + case GpKeyIDSubsets::kGamepadButton: + return PL_KEY_GAMEPAD_BUTTON_ENCODE(vosEvent.m_key.m_gamepadKey.m_button, vosEvent.m_key.m_gamepadKey.m_player); + default: + return 0; + } + + return 0; +} + +static void TranslateVOSEvent(const GpVOSEvent *vosEvent, uint32_t timestamp, PortabilityLayer::EventQueue *queue) +{ + switch (vosEvent->m_eventType) + { + case GpVOSEventTypes::kMouseInput: + TranslateMouseInputEvent(*vosEvent, timestamp, queue); + break; + case GpVOSEventTypes::kKeyboardInput: + TranslateKeyboardInputEvent(*vosEvent, timestamp, queue); + break; + case GpVOSEventTypes::kGamepadInput: + TranslateGamepadInputEvent(vosEvent->m_event.m_gamepadInputEvent, queue); + break; + } +} + +static void ImportVOSEvents(uint32_t timestamp) +{ + PortabilityLayer::EventQueue *plQueue = PortabilityLayer::EventQueue::GetInstance(); + + PortabilityLayer::HostVOSEventQueue *evtQueue = PortabilityLayer::HostVOSEventQueue::GetInstance(); + while (const GpVOSEvent *evt = evtQueue->GetNext()) + { + TranslateVOSEvent(evt, timestamp, plQueue); + evtQueue->DischargeOne(); + } +} + +namespace PLSysCalls +{ + void Sleep(uint32_t ticks) + { + if (ticks > 0) + { + PortabilityLayer::HostSuspendCallArgument args[1]; + args[0].m_uint = static_cast(ticks); + + PortabilityLayer::SuspendApplication(PortabilityLayer::HostSuspendCallID_Delay, args, nullptr); + + ImportVOSEvents(PortabilityLayer::DisplayDeviceManager::GetInstance()->GetTickCount()); + } + } +} diff --git a/PortabilityLayer/PLSysCalls.h b/PortabilityLayer/PLSysCalls.h new file mode 100644 index 0000000..c54a0e7 --- /dev/null +++ b/PortabilityLayer/PLSysCalls.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +namespace PLSysCalls +{ + void Sleep(uint32_t ticks); +} diff --git a/PortabilityLayer/PLTimeTaggedVOSEvent.cpp b/PortabilityLayer/PLTimeTaggedVOSEvent.cpp index e573079..ff4fb8c 100644 --- a/PortabilityLayer/PLTimeTaggedVOSEvent.cpp +++ b/PortabilityLayer/PLTimeTaggedVOSEvent.cpp @@ -20,3 +20,13 @@ bool TimeTaggedVOSEvent::IsLMouseDownEvent() const return mouseEvent.m_eventType == GpMouseEventTypes::kDown && mouseEvent.m_button == GpMouseButtons::kLeft; } + +bool TimeTaggedVOSEvent::IsLMouseUpEvent() const +{ + if (m_vosEvent.m_eventType != GpVOSEventTypes::kMouseInput) + return false; + + const GpMouseInputEvent &mouseEvent = m_vosEvent.m_event.m_mouseInputEvent; + + return mouseEvent.m_eventType == GpMouseEventTypes::kUp && mouseEvent.m_button == GpMouseButtons::kLeft; +} diff --git a/PortabilityLayer/PLTimeTaggedVOSEvent.h b/PortabilityLayer/PLTimeTaggedVOSEvent.h index b3fe203..c82e8a8 100644 --- a/PortabilityLayer/PLTimeTaggedVOSEvent.h +++ b/PortabilityLayer/PLTimeTaggedVOSEvent.h @@ -12,6 +12,7 @@ struct TimeTaggedVOSEvent // Helpers for common cases bool IsKeyDownEvent() const; bool IsLMouseDownEvent() const; + bool IsLMouseUpEvent() const; }; inline TimeTaggedVOSEvent TimeTaggedVOSEvent::Create(const GpVOSEvent &vosEvent, uint32_t timestamp) diff --git a/PortabilityLayer/PLWidgets.cpp b/PortabilityLayer/PLWidgets.cpp new file mode 100644 index 0000000..ccb05e1 --- /dev/null +++ b/PortabilityLayer/PLWidgets.cpp @@ -0,0 +1,77 @@ +#include "PLWidgets.h" +#include "MemoryManager.h" + +namespace PortabilityLayer +{ + WidgetBasicState::WidgetBasicState() + : m_resID(0) + , m_rect(Rect::Create(0, 0, 0, 0)) + , m_enabled(true) + , m_window(nullptr) + { + } + + WidgetHandleState_t Widget::ProcessEvent(const TimeTaggedVOSEvent &evt) + { + (void)evt; + + return WidgetHandleStates::kIgnored; + } + + void Widget::DrawControl(DrawSurface *surface) + { + (void)surface; + } + + void Widget::SetEnabled(bool enabled) + { + m_enabled = enabled; + OnEnabledChanged(); + } + + void Widget::SetState(int16_t state) + { + m_state = state; + OnStateChanged(); + } + + void Widget::SetHighlightStyle(int16_t style) + { + (void)style; + } + + const Rect &Widget::GetRect() const + { + return m_rect; + } + + Widget::Widget(const WidgetBasicState &state) + : m_rect(state.m_rect) + , m_window(state.m_window) + , m_enabled(state.m_enabled) + , m_state(0) + { + } + + Widget::~Widget() + { + } + + void Widget::OnEnabledChanged() + { + } + + void Widget::OnStateChanged() + { + } + + void Widget::BaseRelease(void *storage) + { + PortabilityLayer::MemoryManager::GetInstance()->Release(storage); + } + + void *Widget::BaseAlloc(size_t sz) + { + return PortabilityLayer::MemoryManager::GetInstance()->Alloc(sz); + } +} diff --git a/PortabilityLayer/PLWidgets.h b/PortabilityLayer/PLWidgets.h new file mode 100644 index 0000000..14a1b5c --- /dev/null +++ b/PortabilityLayer/PLWidgets.h @@ -0,0 +1,106 @@ +#pragma once + +#include "PascalStr.h" +#include "SharedTypes.h" + +struct DrawSurface; +class PLPasStr; +struct TimeTaggedVOSEvent; +struct Window; + +namespace PortabilityLayer +{ + namespace WidgetHandleStates + { + enum WidgetHandleState + { + kIgnored, // Event was ignored + kDigested, // Event was digested by the control + kCaptured, // Event was digested by the control and only this control should receive events until it returns a different result + kActivated, // Event caused the control to activate + }; + } + + typedef WidgetHandleStates::WidgetHandleState WidgetHandleState_t; + + struct WidgetBasicState + { + WidgetBasicState(); + + Rect m_rect; + int16_t m_resID; + PascalStr<255> m_text; + bool m_enabled; + Window *m_window; + }; + + class Widget + { + public: + virtual bool Init(const WidgetBasicState &state) = 0; + virtual void Destroy() = 0; + virtual WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt); + virtual void DrawControl(DrawSurface *surface); + + void SetEnabled(bool enabled); + void SetState(int16_t state); + virtual void SetHighlightStyle(int16_t style); + + const Rect &GetRect() const; + + protected: + explicit Widget(const WidgetBasicState &state); + virtual ~Widget(); + + virtual void OnEnabledChanged(); + virtual void OnStateChanged(); + + static void BaseRelease(void *storage); + static void *BaseAlloc(size_t sz); + + Window *m_window; + Rect m_rect; + int16_t m_state; + bool m_enabled; + }; +} + +#include +#include + +namespace PortabilityLayer +{ + template + class WidgetSpec : public Widget + { + public: + explicit WidgetSpec(const WidgetBasicState &state) + : Widget(state) + { + } + + void Destroy() override + { + static_cast(this)->~T(); + Widget::BaseRelease(static_cast(this)); + } + + static WidgetSpec *Create(const WidgetBasicState &state) + { + void *storage = Widget::BaseAlloc(sizeof(T)); + if (!storage) + return nullptr; + + T *widgetT = new (storage) T(state); + + Widget *widget = static_cast(widgetT); + if (!widget->Init(state)) + { + widget->Destroy(); + return nullptr; + } + + return widgetT; + } + }; +} diff --git a/PortabilityLayer/PortabilityLayer.vcxproj b/PortabilityLayer/PortabilityLayer.vcxproj index 037081d..4fec850 100644 --- a/PortabilityLayer/PortabilityLayer.vcxproj +++ b/PortabilityLayer/PortabilityLayer.vcxproj @@ -163,6 +163,7 @@ + @@ -189,20 +190,28 @@ + + + + + + + - + + @@ -279,6 +288,7 @@ + @@ -292,11 +302,16 @@ + + + + + @@ -308,7 +323,9 @@ + + diff --git a/PortabilityLayer/PortabilityLayer.vcxproj.filters b/PortabilityLayer/PortabilityLayer.vcxproj.filters index 717c91f..f17e071 100644 --- a/PortabilityLayer/PortabilityLayer.vcxproj.filters +++ b/PortabilityLayer/PortabilityLayer.vcxproj.filters @@ -132,9 +132,6 @@ Header Files - - Header Files - Header Files @@ -408,6 +405,36 @@ Header Files + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + @@ -620,5 +647,29 @@ Source Files + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + \ No newline at end of file diff --git a/PortabilityLayer/QDGraf.h b/PortabilityLayer/QDGraf.h index 3c3114e..243a764 100644 --- a/PortabilityLayer/QDGraf.h +++ b/PortabilityLayer/QDGraf.h @@ -76,6 +76,9 @@ struct DrawSurface final void SetSystemFont(int size, int variationFlags); void DrawString(const Point &point, const PLPasStr &str); + size_t MeasureString(const PLPasStr &str); + int32_t MeasureFontAscender(); + void DrawPicture(THandle pictHandle, const Rect &rect); void SetPattern8x8(const uint8_t *pattern); diff --git a/PortabilityLayer/QDManager.cpp b/PortabilityLayer/QDManager.cpp index 1adfce7..f9c33c2 100644 --- a/PortabilityLayer/QDManager.cpp +++ b/PortabilityLayer/QDManager.cpp @@ -46,6 +46,11 @@ namespace PortabilityLayer void QDManagerImpl::SetPort(QDPort *gw) { +#if GP_DEBUG_CONFIG + if (gw) + gw->CheckPortSentinel(); +#endif + m_port = gw; } diff --git a/PortabilityLayer/QDPictDecoder.cpp b/PortabilityLayer/QDPictDecoder.cpp index 421e367..9f95309 100644 --- a/PortabilityLayer/QDPictDecoder.cpp +++ b/PortabilityLayer/QDPictDecoder.cpp @@ -1,4 +1,5 @@ #include "CoreDefs.h" +#include "PLCTabReducer.h" #include "QDPictDecoder.h" #include "QDPictEmitContext.h" #include "QDPictHeader.h" @@ -11,29 +12,6 @@ #include #include -namespace -{ - static void DecodeClutItemChannel(uint8_t &outChannel, const uint8_t *color16) - { - const int colorHigh = color16[0]; - const int colorLow = color16[1]; - - const int lowDelta = colorLow - colorHigh; - if (lowDelta < -128) - outChannel = static_cast(colorHigh - 1); - else if (lowDelta > 128) - outChannel = static_cast(colorHigh + 1); - outChannel = static_cast(colorHigh); - } - - static void DecodeClutItem(PortabilityLayer::RGBAColor &decoded, const BEColorTableItem &clutItem) - { - DecodeClutItemChannel(decoded.r, clutItem.m_red); - DecodeClutItemChannel(decoded.g, clutItem.m_green); - DecodeClutItemChannel(decoded.b, clutItem.m_blue); - decoded.a = 255; - } -} namespace PortabilityLayer { @@ -88,7 +66,7 @@ namespace PortabilityLayer if (stream->Read(scratchBytes, 10) != 10 || scratchBytes[0] != 0 || scratchBytes[1] != 10) return false; // Unknown format region - PL_STATIC_ASSERT(sizeof(scratchBERect) == 8); + GP_STATIC_ASSERT(sizeof(scratchBERect) == 8); memcpy(&scratchBERect, scratchBytes + 2, 8); scratchRect = scratchBERect.ToRect(); @@ -280,7 +258,7 @@ namespace PortabilityLayer // If pack type == 3, 16-bit RLE // If pack type == 4, 8-bit planar component RLE - PL_STATIC_ASSERT(sizeof(BEPixMap) == 44); + GP_STATIC_ASSERT(sizeof(BEPixMap) == 44); if (stream->Read(&pixMapBE, sizeof(BEPixMap)) != sizeof(BEPixMap)) return 13; @@ -303,7 +281,7 @@ namespace PortabilityLayer return 16; for (size_t i = 0; i < numColors; i++) - DecodeClutItem(colors[i], clutItems[i]); + colors[i] = CTabReducer::DecodeClutItem(clutItems[i]); } BERect srcRectBE; diff --git a/PortabilityLayer/QDPictHeader.cpp b/PortabilityLayer/QDPictHeader.cpp index 9738adb..726e81e 100644 --- a/PortabilityLayer/QDPictHeader.cpp +++ b/PortabilityLayer/QDPictHeader.cpp @@ -15,7 +15,7 @@ namespace PortabilityLayer bool QDPictHeader::Load(IOStream *stream) { - PL_STATIC_ASSERT(sizeof(Picture) == 10); + GP_STATIC_ASSERT(sizeof(Picture) == 10); Picture pictHeader; if (stream->Read(&pictHeader, sizeof(Picture)) != sizeof(Picture)) diff --git a/PortabilityLayer/QDPixMap.cpp b/PortabilityLayer/QDPixMap.cpp index 3d11bec..22c813f 100644 --- a/PortabilityLayer/QDPixMap.cpp +++ b/PortabilityLayer/QDPixMap.cpp @@ -1,10 +1,21 @@ #include "QDPixMap.h" #include "CoreDefs.h" +#include "MemoryManager.h" #include namespace PortabilityLayer { + void PixMapImpl::Destroy(THandle &hdl) + { + if (hdl) + { + (*hdl)->~PixMapImpl(); + } + + hdl.Dispose(); + } + PixMapImpl::PixMapImpl(int16_t left, int16_t top, uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat) : m_left(left) , m_top(top) @@ -22,6 +33,10 @@ namespace PortabilityLayer static_cast(this)->Init(rect, pixelFormat, PitchForWidth(width, pixelFormat), dataPtr); } + PixMapImpl::~PixMapImpl() + { + } + size_t PixMapImpl::SizeForDimensions(uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat) { return AlignedSize() + PitchForWidth(width, pixelFormat) * height; @@ -29,8 +44,8 @@ namespace PortabilityLayer size_t PixMapImpl::AlignedSize() { - const size_t szBase = sizeof(PixMapImpl) + PL_SYSTEM_MEMORY_ALIGNMENT - 1; - const size_t szAdjusted = szBase - szBase % PL_SYSTEM_MEMORY_ALIGNMENT; + const size_t szBase = sizeof(PixMapImpl) + GP_SYSTEM_MEMORY_ALIGNMENT - 1; + const size_t szAdjusted = szBase - szBase % GP_SYSTEM_MEMORY_ALIGNMENT; return szAdjusted; } @@ -59,11 +74,34 @@ namespace PortabilityLayer assert(false); return 0; } - const size_t szBase = rowByteCount + PL_SYSTEM_MEMORY_ALIGNMENT - 1; - const size_t szAdjusted = szBase - szBase % PL_SYSTEM_MEMORY_ALIGNMENT; + const size_t szBase = rowByteCount + GP_SYSTEM_MEMORY_ALIGNMENT - 1; + const size_t szAdjusted = szBase - szBase % GP_SYSTEM_MEMORY_ALIGNMENT; return szAdjusted; } + + THandle PixMapImpl::Create(const Rect &rect, GpPixelFormat_t pixelFormat) + { + if (!rect.IsValid()) + return THandle(); + + const uint16_t width = static_cast(rect.right - rect.left); + const uint16_t height = static_cast(rect.bottom - rect.top); + + const size_t pixMapSize = PixMapImpl::SizeForDimensions(width, height, pixelFormat); + if (pixMapSize == 0) + return THandle(); + + MMHandleBlock *pmBlock = PortabilityLayer::MemoryManager::GetInstance()->AllocHandle(pixMapSize); + if (!pmBlock) + return THandle(); + + memset(pmBlock->m_contents, 0, pixMapSize); + + new (pmBlock->m_contents) PixMapImpl(rect.left, rect.top, width, height, pixelFormat); + + return THandle(pmBlock); + } } void PixMap::Init(const Rect &rect, GpPixelFormat_t pixelFormat, size_t pitch, void *dataPtr) diff --git a/PortabilityLayer/QDPixMap.h b/PortabilityLayer/QDPixMap.h index 9ade7f9..8c9ec55 100644 --- a/PortabilityLayer/QDPixMap.h +++ b/PortabilityLayer/QDPixMap.h @@ -16,17 +16,22 @@ namespace PortabilityLayer class PixMapImpl final : public PixMap { public: - PixMapImpl(int16_t left, int16_t top, uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat); - + static void Destroy(THandle &hdl); + GpPixelFormat_t GetPixelFormat() const; size_t GetPitch() const; void *GetPixelData(); const void *GetPixelData() const; size_t GetDataCapacity() const; + static THandle Create(const Rect &rect, GpPixelFormat_t pixelFormat); + static size_t SizeForDimensions(uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat); private: + PixMapImpl(int16_t left, int16_t top, uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat); + ~PixMapImpl(); + static size_t AlignedSize(); static size_t PitchForWidth(uint16_t width, GpPixelFormat_t pixelFormat); diff --git a/PortabilityLayer/QDPort.cpp b/PortabilityLayer/QDPort.cpp index ea6e702..7314e68 100644 --- a/PortabilityLayer/QDPort.cpp +++ b/PortabilityLayer/QDPort.cpp @@ -1,9 +1,16 @@ #include "QDPort.h" #include "PLErrorCodes.h" +#include "PLHandle.h" #include "MemoryManager.h" #include "MMHandleBlock.h" #include "QDPixMap.h" +#if GP_DEBUG_CONFIG +#include + +static const int32_t kQDPortSentinelValue = 0x222a1877; // Completely arbitrary number +#endif + namespace PortabilityLayer { static uint32_t gs_nextQDPortDebugID = 0; @@ -14,10 +21,12 @@ namespace PortabilityLayer , m_top(0) , m_width(0) , m_height(0) - , m_pixMap(nullptr) , m_pixelFormat(GpPixelFormats::kInvalid) , m_dirtyFlags(0) , m_debugID(gs_nextQDPortDebugID++) +#if GP_DEBUG_CONFIG + , m_portSentinel(kQDPortSentinelValue) +#endif { } @@ -29,11 +38,7 @@ namespace PortabilityLayer void QDPort::DisposePixMap() { if (m_pixMap) - { - if (*m_pixMap) - static_cast(*m_pixMap)->~PixMapImpl(); - MemoryManager::GetInstance()->ReleaseHandle(reinterpret_cast(m_pixMap)); - } + PixMapImpl::Destroy(m_pixMap); } PLError_t QDPort::Init(const Rect &rect, GpPixelFormat_t pixelFormat) @@ -49,31 +54,24 @@ namespace PortabilityLayer bool QDPort::Resize(const Rect &rect) { - const uint16_t width = static_cast(rect.right - rect.left); - const uint16_t height = static_cast(rect.bottom - rect.top); - - size_t pixMapSize = PixMapImpl::SizeForDimensions(width, height, m_pixelFormat); - if (pixMapSize == 0) + if (!rect.IsValid()) return false; - MMHandleBlock *pmBlock = MemoryManager::GetInstance()->AllocHandle(pixMapSize); - if (!pmBlock) - return false; + THandle newPixMap = PixMapImpl::Create(rect, m_pixelFormat); - memset(pmBlock->m_contents, 0, pixMapSize); + if (!newPixMap) + return false; SetDirty(QDPortDirtyFlag_Size | QDPortDirtyFlag_Contents); m_left = rect.left; m_top = rect.top; - m_width = width; - m_height = height; - - new (pmBlock->m_contents) PixMapImpl(m_left, m_top, width, height, m_pixelFormat); + m_width = rect.Width(); + m_height = rect.Height(); DisposePixMap(); - m_pixMap = reinterpret_cast(&pmBlock->m_contents); + m_pixMap = newPixMap; return true; } @@ -93,9 +91,9 @@ namespace PortabilityLayer m_dirtyFlags &= ~flag; } - PixMap **QDPort::GetPixMap() const + THandle QDPort::GetPixMap() const { - return m_pixMap; + return m_pixMap.ImplicitCast(); } const QDState *QDPort::GetState() const @@ -117,4 +115,11 @@ namespace PortabilityLayer { return Rect::Create(m_top, m_left, m_top + m_height, m_left + m_width); } + +#if GP_DEBUG_CONFIG + void QDPort::CheckPortSentinel() const + { + assert(m_portSentinel == kQDPortSentinelValue); + } +#endif } diff --git a/PortabilityLayer/QDPort.h b/PortabilityLayer/QDPort.h index 493224c..d0d02d6 100644 --- a/PortabilityLayer/QDPort.h +++ b/PortabilityLayer/QDPort.h @@ -3,6 +3,7 @@ #include #include "GpPixelFormat.h" #include "PLErrorCodes.h" +#include "PLHandle.h" #include "QDState.h" struct PixMap; @@ -10,6 +11,8 @@ struct Rect; namespace PortabilityLayer { + class PixMapImpl; + enum QDPortType { QDPortType_Invalid, @@ -33,7 +36,7 @@ namespace PortabilityLayer PLError_t Init(const Rect &rect, GpPixelFormat_t pixelFormat); QDPortType GetPortType() const; - PixMap **GetPixMap() const; + THandle GetPixMap() const; const QDState *GetState() const; QDState *GetState(); GpPixelFormat_t GetPixelFormat() const; @@ -45,13 +48,21 @@ namespace PortabilityLayer void SetDirty(uint32_t flag); void ClearDirty(uint32_t flag); +#if GP_DEBUG_CONFIG + void CheckPortSentinel() const; +#endif + private: void DisposePixMap(); +#if GP_DEBUG_CONFIG + int32_t m_portSentinel; +#endif + QDPortType m_portType; QDState m_state; - PixMap **m_pixMap; + THandle m_pixMap; int16_t m_left; int16_t m_top; diff --git a/PortabilityLayer/RenderedFont.h b/PortabilityLayer/RenderedFont.h index 5ff4643..39dfa00 100644 --- a/PortabilityLayer/RenderedFont.h +++ b/PortabilityLayer/RenderedFont.h @@ -1,17 +1,20 @@ #pragma once -#include +#include namespace PortabilityLayer { + struct RenderedFontMetrics; + struct RenderedGlyphMetrics; class RenderedFont - { + { public: - virtual bool GetGlyph(unsigned int character, const RenderedGlyphMetrics **outMetricsPtr, const void **outData) const = 0; + virtual bool GetGlyph(unsigned int character, const RenderedGlyphMetrics *&outMetricsPtr, const void *&outData) const = 0; + virtual const RenderedFontMetrics &GetMetrics() const = 0; virtual size_t MeasureString(const uint8_t *chars, size_t len) const = 0; - virtual void Destroy() = 0; + virtual void Destroy() = 0; }; } diff --git a/PortabilityLayer/RenderedFontMetrics.h b/PortabilityLayer/RenderedFontMetrics.h new file mode 100644 index 0000000..e9d84c3 --- /dev/null +++ b/PortabilityLayer/RenderedFontMetrics.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace PortabilityLayer +{ + struct RenderedFontMetrics + { + int32_t m_ascent; + int32_t m_descent; + int32_t m_linegap; + }; +} diff --git a/PortabilityLayer/ScanlineMask.cpp b/PortabilityLayer/ScanlineMask.cpp index f55dc32..6ff11a9 100644 --- a/PortabilityLayer/ScanlineMask.cpp +++ b/PortabilityLayer/ScanlineMask.cpp @@ -26,8 +26,8 @@ namespace PortabilityLayer ScanlineMask *ScanlineMask::Create(const Rect &rect, const ScanlineMaskBuilder &builder) { - size_t alignedPrefixSize = sizeof(ScanlineMask) + PL_SYSTEM_MEMORY_ALIGNMENT - 1; - alignedPrefixSize -= alignedPrefixSize % PL_SYSTEM_MEMORY_ALIGNMENT; + size_t alignedPrefixSize = sizeof(ScanlineMask) + GP_SYSTEM_MEMORY_ALIGNMENT - 1; + alignedPrefixSize -= alignedPrefixSize % GP_SYSTEM_MEMORY_ALIGNMENT; const size_t longestSpan = builder.GetLongestSpan(); const size_t numSpans = builder.GetNumSpans(); diff --git a/PortabilityLayer/ScopedArray.h b/PortabilityLayer/ScopedArray.h index 3dfc9da..b5f660b 100644 --- a/PortabilityLayer/ScopedArray.h +++ b/PortabilityLayer/ScopedArray.h @@ -23,8 +23,8 @@ namespace PortabilityLayer void Set(T *ref); private: - ScopedArray(const ScopedArray &other) PL_DELETED; - void operator=(const ScopedArray &other) PL_DELETED; + ScopedArray(const ScopedArray &other) GP_DELETED; + void operator=(const ScopedArray &other) GP_DELETED; T *m_ref; }; } diff --git a/PortabilityLayer/ScopedPtr.h b/PortabilityLayer/ScopedPtr.h index 934ef10..33fa271 100644 --- a/PortabilityLayer/ScopedPtr.h +++ b/PortabilityLayer/ScopedPtr.h @@ -25,8 +25,8 @@ namespace PortabilityLayer void Set(T *ref); private: - ScopedPtr(const ScopedPtr &other) PL_DELETED; - void operator=(const ScopedPtr &other) PL_DELETED; + ScopedPtr(const ScopedPtr &other) GP_DELETED; + void operator=(const ScopedPtr &other) GP_DELETED; T *m_ref; }; } diff --git a/PortabilityLayer/SharedTypes.h b/PortabilityLayer/SharedTypes.h index d126438..6011a02 100644 --- a/PortabilityLayer/SharedTypes.h +++ b/PortabilityLayer/SharedTypes.h @@ -29,6 +29,11 @@ struct Rect Rect operator-(const Point &point) const; Rect operator+(const Point &point) const; + uint16_t Height() const; + uint16_t Width() const; + + bool Contains(const Point &point) const; + static Rect Create(int16_t top, int16_t left, int16_t bottom, int16_t right); static Rect CreateFromPoints(const Point &topLeft, const Point &bottomRight); }; @@ -97,7 +102,7 @@ struct GDevice { GpPixelFormat_t pixelFormat; - uint8_t paletteStorage[256 * 4 + PL_SYSTEM_MEMORY_ALIGNMENT]; + uint8_t paletteStorage[256 * 4 + GP_SYSTEM_MEMORY_ALIGNMENT]; uint8_t paletteDataOffset; bool paletteIsDirty; }; @@ -164,6 +169,21 @@ inline Rect Rect::operator+(const Point &point) const return Rect::Create(this->top + point.v, this->left + point.h, this->bottom + point.v, this->right + point.h); } +inline uint16_t Rect::Height() const +{ + return static_cast(static_cast(this->bottom) - static_cast(this->top)); +} + +inline uint16_t Rect::Width() const +{ + return static_cast(static_cast(this->right) - static_cast(this->left)); +} + +inline bool Rect::Contains(const Point &point) const +{ + return point.h >= this->left && point.h < this->right && point.v >= this->top && point.v < this->bottom; +} + inline Rect Rect::Create(int16_t top, int16_t left, int16_t bottom, int16_t right) { Rect result; @@ -177,5 +197,5 @@ inline Rect Rect::Create(int16_t top, int16_t left, int16_t bottom, int16_t righ inline Rect Rect::CreateFromPoints(const Point &topLeft, const Point &bottomRight) { - return Rect::Create(topLeft.v, topLeft.h, bottomRight.v, bottomRight.h); + return Rect::Create(topLeft.v, topLeft.h, bottomRight.v, bottomRight.h); } diff --git a/PortabilityLayer/SimpleImage.h b/PortabilityLayer/SimpleImage.h new file mode 100644 index 0000000..87c38d3 --- /dev/null +++ b/PortabilityLayer/SimpleImage.h @@ -0,0 +1,22 @@ +#pragma once + +#include "GpPixelFormat.h" +#include + +namespace PortabilityLayer +{ + class SimpleImage final + { + public: + void Destroy(); + void *GetData(); + const void *GetData() const; + + static SimpleImage *Create(GpPixelFormat_t pixelFormat, size_t pitch, size_t dataSize); + + private: + GpPixelFormat_t m_pixelFormat; + size_t m_pitch; + void *m_data; + }; +} diff --git a/PortabilityLayer/UnsafePascalStr.h b/PortabilityLayer/UnsafePascalStr.h index bcdab92..6f32553 100644 --- a/PortabilityLayer/UnsafePascalStr.h +++ b/PortabilityLayer/UnsafePascalStr.h @@ -5,6 +5,8 @@ #include "DataTypes.h" #include "SmallestInt.h" + +class PLPasStr; namespace PortabilityLayer { @@ -19,7 +21,10 @@ namespace PortabilityLayer const char &operator[](size_t index) const; void Set(size_t size, const char *str); void SetLength(size_t size); - size_t Length() const; + size_t Length() const; + + const char *UnsafeCharPtr() const; + PLPasStr ToShortStr() const; private: char m_chars[TSize + (TCStr ? 1 : 0)]; @@ -28,7 +33,9 @@ namespace PortabilityLayer } #include -#include +#include + +#include "PLPasStr.h" namespace PortabilityLayer { @@ -84,7 +91,22 @@ namespace PortabilityLayer inline size_t UnsafePascalStr::Length() const { return m_size; + } + + template + inline const char *UnsafePascalStr::UnsafeCharPtr() const + { + return m_chars; } + + template + PLPasStr UnsafePascalStr::ToShortStr() const + { + if (m_size > 255) + return PLPasStr(255, m_chars); + else + return PLPasStr(static_cast(m_size), m_chars); + } } #endif diff --git a/PortabilityLayer/WindowDef.cpp b/PortabilityLayer/WindowDef.cpp index 4b25eb5..dd644fa 100644 --- a/PortabilityLayer/WindowDef.cpp +++ b/PortabilityLayer/WindowDef.cpp @@ -19,7 +19,7 @@ namespace PortabilityLayer uint8_t m_titleLength; }; - PL_STATIC_ASSERT(sizeof(WindowDefPart1) == 19); + GP_STATIC_ASSERT(sizeof(WindowDefPart1) == 19); WindowDefPart1 wdefPart1; diff --git a/PortabilityLayer/WindowManager.cpp b/PortabilityLayer/WindowManager.cpp index 643d967..2abda1b 100644 --- a/PortabilityLayer/WindowManager.cpp +++ b/PortabilityLayer/WindowManager.cpp @@ -86,7 +86,7 @@ namespace PortabilityLayer WindowImpl::~WindowImpl() { - PL_NotYetImplemented(); + assert(m_windowAbove == nullptr && m_windowBelow == nullptr); } bool WindowImpl::Init(const WindowDef &windowDef)