diff --git a/Aerofoil/GpSystemServices_Win32.cpp b/Aerofoil/GpSystemServices_Win32.cpp index bc82fb9..d41c362 100644 --- a/Aerofoil/GpSystemServices_Win32.cpp +++ b/Aerofoil/GpSystemServices_Win32.cpp @@ -74,6 +74,12 @@ uint64_t GpSystemServices_Win32::GetFreeMemoryCosmetic() const return memStatus.ullAvailPhys; } +void GpSystemServices_Win32::Beep() const +{ + MessageBeep(MB_OK); +} + + GpSystemServices_Win32 *GpSystemServices_Win32::GetInstance() { return &ms_instance; diff --git a/Aerofoil/GpSystemServices_Win32.h b/Aerofoil/GpSystemServices_Win32.h index 00c521d..28e5e5f 100644 --- a/Aerofoil/GpSystemServices_Win32.h +++ b/Aerofoil/GpSystemServices_Win32.h @@ -20,6 +20,7 @@ public: PortabilityLayer::HostMutex *CreateMutex() override; PortabilityLayer::HostThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) override; uint64_t GetFreeMemoryCosmetic() const override; + void Beep() const override; static GpSystemServices_Win32 *GetInstance(); diff --git a/ConvertColorCursors/ConvertColorCursors.cpp b/ConvertColorCursors/ConvertColorCursors.cpp index 0ef166e..909adcb 100644 --- a/ConvertColorCursors/ConvertColorCursors.cpp +++ b/ConvertColorCursors/ConvertColorCursors.cpp @@ -94,8 +94,8 @@ void ConvertCursors(PortabilityLayer::ResourceFile *resFile) for (size_t i = 0; i < numRefs; i++) { const int resID = typeList->m_firstRef[i].m_resID; - const PortabilityLayer::MMHandleBlock *hBlock = resFile->GetResource('crsr', resID, true); - const void *cursorDataBase = hBlock->m_contents; + const THandle resHdl = resFile->GetResource('crsr', resID, true); + const void *cursorDataBase = *resHdl; const void *cursorData = cursorDataBase; const CursorHeader *cursorHeader = static_cast(cursorData); @@ -247,16 +247,16 @@ void ConvertIconFamily(PortabilityLayer::ResourceFile *resFile, int32_t iconBitm for (size_t i = 0; i < numRefs; i++) { const int resID = typeList->m_firstRef[i].m_resID; - const PortabilityLayer::MMHandleBlock *bwBlock = resFile->GetResource(iconBitmapType, resID, true); - const PortabilityLayer::MMHandleBlock *colorBlock = resFile->GetResource(iconColorType, resID, true); + const THandle bwBlock = resFile->GetResource(iconBitmapType, resID, true); + const THandle colorBlock = resFile->GetResource(iconColorType, resID, true); if (!bwBlock || !colorBlock) continue; - const uint8_t *bwIconData = static_cast(bwBlock->m_contents); + const uint8_t *bwIconData = static_cast(*bwBlock); const uint8_t *bwMaskData = bwIconData + (dimension * dimension / 8); - const uint8_t *indexedData = static_cast(colorBlock->m_contents); + const uint8_t *indexedData = static_cast(*colorBlock); PortabilityLayer::RGBAColor *pixelData = new PortabilityLayer::RGBAColor[dimension * dimension * 4]; @@ -321,7 +321,7 @@ int main(int argc, const char **argv) PortabilityLayer::CFileStream stream(f); - PortabilityLayer::ResourceFile *resFile = new PortabilityLayer::ResourceFile(); + PortabilityLayer::ResourceFile *resFile = PortabilityLayer::ResourceFile::Create(); if (!resFile->Load(&stream)) return -1; diff --git a/GpApp/DialogUtils.cpp b/GpApp/DialogUtils.cpp index 5491a64..e853510 100644 --- a/GpApp/DialogUtils.cpp +++ b/GpApp/DialogUtils.cpp @@ -364,9 +364,9 @@ void DrawDefaultButton (Dialog *theDialog) surface->SetForeColor(StdColors::Black()); - for (int xOffset = 0; xOffset < 3; xOffset++) + for (int xOffset = -1; xOffset <= 1; xOffset++) { - for (int yOffset = 0; yOffset < 3; yOffset++) + for (int yOffset = -1; yOffset <= 1; yOffset++) { const Rect offsetRect = itemRect + Point::Create(xOffset, yOffset); surface->FrameRoundRect(offsetRect, 8, 8); @@ -646,7 +646,7 @@ void DrawDialogUserText (Dialog *dial, short item, StringPtr text, Boolean inver if (invert) { OffsetRect(&iRect, 0, 1); - InvertRect(&iRect); + surface->InvertFillRect(iRect, nullptr); } } @@ -680,12 +680,10 @@ void DrawDialogUserText2 (Dialog *dial, short item, StringPtr text) void LoadDialogPICT (Dialog *theDialog, short item, short theID) { - Rect iRect; - ControlHandle iHandle; THandle thePict; - short iType; - - GetDialogItem(theDialog, item, &iType, &iHandle, &iRect); + + Rect iRect = theDialog->GetItems()[item - 1].GetWidget()->GetRect();; + thePict = GetPicture(theID); if (thePict) theDialog->GetWindow()->GetDrawSurface()->DrawPicture(thePict, iRect); diff --git a/GpApp/Externs.h b/GpApp/Externs.h index 4d16fea..238cd15 100644 --- a/GpApp/Externs.h +++ b/GpApp/Externs.h @@ -13,6 +13,7 @@ namespace PortabilityLayer { + class ResourceFile; class ScanlineMask; } @@ -197,7 +198,7 @@ UInt32 RandomLongQUS (void); void RedAlert (short); void LoadGraphic (DrawSurface *, short); void LoadScaledGraphic (DrawSurface *, short, Rect *); -void LargeIconPlot (Rect *, short); +bool LargeIconPlot (DrawSurface *, PortabilityLayer::ResourceFile *, short, const Rect &); void DrawCIcon (DrawSurface *surface, short, short, short); char KeyMapOffsetFromRawKey (char); long LongSquareRoot (long); diff --git a/GpApp/Interactions.cpp b/GpApp/Interactions.cpp index 739cd9d..b223995 100644 --- a/GpApp/Interactions.cpp +++ b/GpApp/Interactions.cpp @@ -994,6 +994,10 @@ void HandleSwitches (hotPtr who) roomLinked = masterObjects[whoLinked].roomLink; objectLinked = masterObjects[whoLinked].objectLink; linkIndex = masterObjects[whoLinked].localLink; + + if (roomLinked < 0) + return; // GP: Some objects (like Leviathan) have corrupted switch data + // change state of linked obj. if (SetObjectState(roomLinked, objectLinked, masterObjects[whoLinked].theObject.data.e.type, linkIndex)) diff --git a/GpApp/Menu.cpp b/GpApp/Menu.cpp index 3efcc28..968a9d9 100644 --- a/GpApp/Menu.cpp +++ b/GpApp/Menu.cpp @@ -346,7 +346,7 @@ void DoGameMenu (short theItem) Rect updateRect; SetRect(&updateRect, splashOriginH + 474, splashOriginV + 304, splashOriginH + 474 + 166, splashOriginV + 304 + 12); - InvalWindowRect(mainWindow, &updateRect); + UpdateMainWindow(); } } #endif diff --git a/GpApp/Objects.cpp b/GpApp/Objects.cpp index 99bc8de..e4ea4c9 100644 --- a/GpApp/Objects.cpp +++ b/GpApp/Objects.cpp @@ -355,7 +355,7 @@ void AddTempManholeRect (Rect *manHole) Boolean SetObjectState (short room, short object, short action, short local) { char wasState; - Boolean changed; + Boolean changed = false; switch ((*thisHouse)->rooms[room].objects[object].what) { diff --git a/GpApp/SelectHouse.cpp b/GpApp/SelectHouse.cpp index 540cdc1..4fbabdc 100644 --- a/GpApp/SelectHouse.cpp +++ b/GpApp/SelectHouse.cpp @@ -17,7 +17,9 @@ #include "FileManager.h" #include "House.h" #include "RectUtils.h" +#include "ResourceFile.h" #include "ResourceManager.h" +#include "PLTimeTaggedVOSEvent.h" #include "VirtualDirectory.h" @@ -42,7 +44,7 @@ void UpdateLoadDialog (Dialog *); void PageUpHouses (Dialog *); void PageDownHouses (Dialog *); -Boolean LoadFilter (Dialog *, EventRecord *, short *); +int16_t LoadFilter (Dialog *, const TimeTaggedVOSEvent &); void SortHouseList (void); void DoDirSearch (void); @@ -66,12 +68,14 @@ extern UInt32 doubleTime; void UpdateLoadDialog (Dialog *theDialog) { Rect tempRect, dialogRect, dummyRect; - short houseStart, houseStop, i, wasResFile, isResFile, count; + short houseStart, houseStop, i, wasResFile, count; // char wasState; WindowRef theWindow; // RgnHandle theRegion; - + theWindow = theDialog->GetWindow(); + DrawSurface *surface = theWindow->GetDrawSurface(); + GetWindowBounds(theWindow, kWindowContentRgn, &dialogRect); /* wasState = HGetState((Handle)(((DialogPeek)theDialog)->window).port.visRgn); @@ -79,8 +83,7 @@ void UpdateLoadDialog (Dialog *theDialog) dialogRect = (**((((DialogPeek)theDialog)->window).port.visRgn)).rgnBBox; HSetState((Handle)(((DialogPeek)theDialog)->window).port.visRgn, wasState); */ - - DrawDialog(theDialog); + ColorFrameWHRect(theDialog->GetWindow()->GetDrawSurface(), 8, 39, 413, 184, kRedOrangeColor8); // box around files houseStart = housePage; @@ -88,7 +91,6 @@ void UpdateLoadDialog (Dialog *theDialog) if ((houseStop - houseStart) > kDispFiles) houseStop = houseStart + kDispFiles; - wasResFile = CurResFile(); count = 0; for (i = 0; i < 12; i++) @@ -103,17 +105,16 @@ void UpdateLoadDialog (Dialog *theDialog) if (SectRect(&dialogRect, &tempRect, &dummyRect)) { - isResFile = HOpenResFile(theHousesSpecs[i].m_dir, theHousesSpecs[i].m_name, fsRdPerm); - if (isResFile != -1) + PortabilityLayer::ResourceFile *resFile = PortabilityLayer::ResourceManager::GetInstance()->LoadResFile(theHousesSpecs[i].m_dir, theHousesSpecs[i].m_name); + if (resFile != nullptr) { - if (Get1Resource('icl8', -16455) != nil) + if (!LargeIconPlot(surface, resFile, -16455, tempRect)) { - LargeIconPlot(&tempRect, -16455); + LoadDialogPICT(theDialog, kLoadIconFirstItem + i - housePage, + kDefaultHousePict8); } - else - LoadDialogPICT(theDialog, kLoadIconFirstItem + i - housePage, - kDefaultHousePict8); - PortabilityLayer::ResourceManager::GetInstance()->CloseResFile(isResFile); + + resFile->Destroy(); } else LoadDialogPICT(theDialog, kLoadIconFirstItem + i - housePage, @@ -131,7 +132,6 @@ void UpdateLoadDialog (Dialog *theDialog) } InitCursor(); - UseResFile(wasResFile); } #endif @@ -152,11 +152,11 @@ void PageUpHouses (Dialog *theDial) housePage -= kDispFiles; thisHouseIndex = kDispFiles - 1; - ShowDialogItem(theDial, kScrollDownItem); + theDial->SetItemVisibility(kScrollDownItem - 1, true); if (housePage < kDispFiles) { GetDialogItemRect(theDial, kScrollUpItem, &tempRect); - HideDialogItem(theDial, kScrollUpItem); + theDial->SetItemVisibility(kScrollUpItem - 1, false); DrawCIcon(surface, kGrayedOutUpArrow, tempRect.left, tempRect.top); } @@ -165,7 +165,8 @@ void PageUpHouses (Dialog *theDial) surface->SetForeColor(StdColors::White()); surface->FillRect(tempRect); surface->SetForeColor(StdColors::Black()); - InvalWindowRect(theDial->GetWindow(), &tempRect); + + UpdateLoadDialog(theDial); } #endif @@ -186,11 +187,11 @@ void PageDownHouses (Dialog *theDial) housePage += kDispFiles; thisHouseIndex = 0; - ShowDialogItem(theDial, kScrollUpItem); + theDial->SetItemVisibility(kScrollUpItem - 1, true); if (housePage >= (housesFound - kDispFiles)) { GetDialogItemRect(theDial, kScrollDownItem, &tempRect); - HideDialogItem(theDial, kScrollDownItem); + theDial->SetItemVisibility(kScrollDownItem - 1, false); DrawCIcon(surface, kGrayedOutDownArrow, tempRect.left, tempRect.top); } @@ -198,46 +199,39 @@ void PageDownHouses (Dialog *theDial) surface->SetForeColor(StdColors::White()); surface->FillRect(tempRect); surface->SetForeColor(StdColors::Black()); - InvalWindowRect(theDial->GetWindow(), &tempRect); + + UpdateLoadDialog(theDial); } #endif //-------------------------------------------------------------- LoadFilter #ifndef COMPILEDEMO -Boolean LoadFilter (Dialog *dial, EventRecord *event, short *item) +int16_t LoadFilter(Dialog *dial, const TimeTaggedVOSEvent &evt) { short screenCount, i, wasIndex; - - switch (event->what) + + if (evt.IsKeyDownEvent()) { - case keyDown: - switch (event->message) + const intptr_t keyCode = PackVOSKeyCode(evt.m_vosEvent.m_event.m_keyboardInputEvent); + switch (keyCode) { - 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; + return kOkayButton; - case PL_KEY_SPECIAL(kEscape): + case PL_KEY_SPECIAL(kEscape): FlashDialogButton(dial, kCancelButton); - *item = kCancelButton; - return(true); - break; + return kCancelButton; - case PL_KEY_SPECIAL(kPageUp): - *item = kScrollUpItem; - return (true); - break; + case PL_KEY_SPECIAL(kPageUp): + return kScrollUpItem; - case PL_KEY_SPECIAL(kPageDown): - *item = kScrollDownItem; - return (true); - break; + case PL_KEY_SPECIAL(kPageDown): + return kScrollDownItem; - case PL_KEY_SPECIAL(kUpArrow): + case PL_KEY_SPECIAL(kUpArrow): InvalWindowRect(dial->GetWindow(), &loadHouseRects[thisHouseIndex]); thisHouseIndex -= 4; if (thisHouseIndex < 0) @@ -245,18 +239,17 @@ Boolean LoadFilter (Dialog *dial, EventRecord *event, short *item) screenCount = housesFound - housePage; if (screenCount > kDispFiles) screenCount = kDispFiles; - + thisHouseIndex += 4; - thisHouseIndex = (((screenCount - 1) / 4) * 4) + - (thisHouseIndex % 4); + thisHouseIndex = (((screenCount - 1) / 4) * 4) + + (thisHouseIndex % 4); if (thisHouseIndex >= screenCount) thisHouseIndex -= 4; } InvalWindowRect(dial->GetWindow(), &loadHouseRects[thisHouseIndex]); - return(true); - break; + return 0; - case PL_KEY_SPECIAL(kDownArrow): + case PL_KEY_SPECIAL(kDownArrow): InvalWindowRect(dial->GetWindow(), &loadHouseRects[thisHouseIndex]); thisHouseIndex += 4; screenCount = housesFound - housePage; @@ -265,10 +258,10 @@ Boolean LoadFilter (Dialog *dial, EventRecord *event, short *item) if (thisHouseIndex >= screenCount) thisHouseIndex %= 4; InvalWindowRect(dial->GetWindow(), &loadHouseRects[thisHouseIndex]); - return(true); - break; - case PL_KEY_SPECIAL(kLeftArrow): + return 0; + + case PL_KEY_SPECIAL(kLeftArrow): InvalWindowRect(dial->GetWindow(), &loadHouseRects[thisHouseIndex]); thisHouseIndex--; if (thisHouseIndex < 0) @@ -279,11 +272,10 @@ Boolean LoadFilter (Dialog *dial, EventRecord *event, short *item) thisHouseIndex = screenCount - 1; } InvalWindowRect(dial->GetWindow(), &loadHouseRects[thisHouseIndex]); - return(true); - break; + return 0; - case PL_KEY_SPECIAL(kTab): - case PL_KEY_SPECIAL(kRightArrow): + case PL_KEY_SPECIAL(kTab): + case PL_KEY_SPECIAL(kRightArrow): InvalWindowRect(dial->GetWindow(), &loadHouseRects[thisHouseIndex]); thisHouseIndex++; screenCount = housesFound - housePage; @@ -292,13 +284,12 @@ Boolean LoadFilter (Dialog *dial, EventRecord *event, short *item) if (thisHouseIndex >= screenCount) thisHouseIndex = 0; InvalWindowRect(dial->GetWindow(), &loadHouseRects[thisHouseIndex]); - return(true); - break; - - default: - if (PL_KEY_GET_EVENT_TYPE(event->message) == KeyEventType_ASCII) + return 0; + + default: + if (PL_KEY_GET_EVENT_TYPE(keyCode) == KeyEventType_ASCII) { - char theChar = static_cast(PL_KEY_GET_VALUE(event->message)); + char theChar = static_cast(PL_KEY_GET_VALUE(keyCode)); if (theChar >= 'A' && theChar <= 'Z') { @@ -325,35 +316,29 @@ Boolean LoadFilter (Dialog *dial, EventRecord *event, short *item) InvalWindowRect(dial->GetWindow(), &loadHouseRects[thisHouseIndex]); } } - return(true); + return 0; } else - return(false); + return -1; } - break; - - case mouseDown: - lastWhenClick = event->when - lastWhenClick; - SubPt(event->where, &lastWhereClick); - return(false); - break; - - case mouseUp: - lastWhenClick = event->when; - lastWhereClick = event->where; - return(false); - break; - - case updateEvt: - UpdateLoadDialog(dial); - EndUpdate(dial->GetWindow()); - event->what = nullEvent; - return(false); - break; - - default: - return(false); - break; + } + else if (evt.IsLMouseDownEvent()) + { + const GpMouseInputEvent &mouseEvt = evt.m_vosEvent.m_event.m_mouseInputEvent; + + lastWhenClick = evt.m_timestamp - lastWhenClick; + lastWhereClick -= Point::Create(mouseEvt.m_x, mouseEvt.m_y); + + return -1; + } + else if (evt.IsLMouseUpEvent()) + { + const GpMouseInputEvent &mouseEvt = evt.m_vosEvent.m_event.m_mouseInputEvent; + + lastWhenClick = evt.m_timestamp; + lastWhereClick = Point::Create(mouseEvt.m_x, mouseEvt.m_y); + + return -1; } } #endif @@ -365,7 +350,7 @@ void DoLoadHouse (void) { Rect tempRect; Dialog *theDial; - short i, item, wasIndex, screenCount; + short i, wasIndex, screenCount; Boolean leaving, whoCares; BringUpDialog(&theDial, kLoadHouseDialogID); @@ -375,11 +360,11 @@ void DoLoadHouse (void) if (housesFound <= kDispFiles) { GetDialogItemRect(theDial, kScrollUpItem, &tempRect); - HideDialogItem(theDial, kScrollUpItem); + theDial->SetItemVisibility(kScrollUpItem - 1, false); DrawCIcon(surface, kGrayedOutUpArrow, tempRect.left, tempRect.top); GetDialogItemRect(theDial, kScrollDownItem, &tempRect); - HideDialogItem(theDial, kScrollDownItem); + theDial->SetItemVisibility(kScrollDownItem - 1, false); DrawCIcon(surface, kGrayedOutDownArrow, tempRect.left, tempRect.top); } else @@ -387,13 +372,13 @@ void DoLoadHouse (void) if (thisHouseIndex < kDispFiles) { GetDialogItemRect(theDial, kScrollUpItem, &tempRect); - HideDialogItem(theDial, kScrollUpItem); + theDial->SetItemVisibility(kScrollUpItem - 1, false); DrawCIcon(surface, kGrayedOutUpArrow, tempRect.left, tempRect.top); } else if (thisHouseIndex > (housesFound - kDispFiles)) { GetDialogItemRect(theDial, kScrollDownItem, &tempRect); - HideDialogItem(theDial, kScrollDownItem); + theDial->SetItemVisibility(kScrollDownItem - 1, false); DrawCIcon(surface, kGrayedOutDownArrow, tempRect.left, tempRect.top); } } @@ -412,10 +397,12 @@ void DoLoadHouse (void) } leaving = false; + + UpdateLoadDialog(theDial); while (!leaving) { - ModalDialog(LoadFilter, &item); + int16_t item = theDial->ExecuteModal(LoadFilter); if (item == kOkayButton) { diff --git a/GpApp/Utilities.cpp b/GpApp/Utilities.cpp index 75b04a8..2aaed3d 100644 --- a/GpApp/Utilities.cpp +++ b/GpApp/Utilities.cpp @@ -14,6 +14,7 @@ #include "QDPixMap.h" #include "Externs.h" #include "IconLoader.h" +#include "ResourceFile.h" #include "Utilities.h" @@ -314,14 +315,39 @@ void LoadScaledGraphic (DrawSurface *surface, short resID, Rect *theRect) //-------------------------------------------------------------- LargeIconPlot // Draws a standard b&w icon (32 x 32) - resource is an 'ICON'. -void LargeIconPlot (Rect *theRect, short theID) +bool LargeIconPlot (DrawSurface *surface, PortabilityLayer::ResourceFile *resFile, short resID, const Rect &theRect) { - PLError_t theErr; - Handle theSuite; - - theErr = GetIconSuite(&theSuite, theID, svAllLargeData); - if (theErr == PLErrors::kNone) - theErr = PlotIconSuite(theRect, theSuite); + Handle hdl = resFile->GetResource('icl8', resID, true); + if (hdl) + { + THandle img = PortabilityLayer::IconLoader::GetInstance()->LoadSimpleColorIcon(hdl); + + if (img) + { + CopyBits(*img, *surface->m_port.GetPixMap(), &(*img)->m_rect, &theRect, srcCopy); + img.Dispose(); + } + + hdl.Dispose(); + return true; + } + + hdl = resFile->GetResource('ICN#', resID, true); + if (hdl) + { + THandle img = PortabilityLayer::IconLoader::GetInstance()->LoadBWIcon(hdl); + + if (img) + { + CopyBits(*img, *surface->m_port.GetPixMap(), &(*img)->m_rect, &theRect, srcCopy); + img.Dispose(); + } + + hdl.Dispose(); + return true; + } + + return false; } //-------------------------------------------------------------- DrawCIcon diff --git a/PictChecker/PictChecker.cpp b/PictChecker/PictChecker.cpp index e6d154d..d4e60c2 100644 --- a/PictChecker/PictChecker.cpp +++ b/PictChecker/PictChecker.cpp @@ -1278,7 +1278,7 @@ int main(int argc, const char **argv) FILE *f = fopen(filePath.c_str(), "rb"); CFileStream stream(f); - ResourceFile *resFile = new ResourceFile(); + ResourceFile *resFile = ResourceFile::Create(); if (!resFile->Load(&stream)) { assert(false); @@ -1292,8 +1292,8 @@ int main(int argc, const char **argv) const size_t numRefs = typeList->m_numRefs; for (size_t i = 0; i < numRefs; i++) { - const MMHandleBlock *hBlock = resFile->GetResource('PICT', typeList->m_firstRef[i].m_resID, true); - const void *pictData = hBlock->m_contents; + const THandle hBlock = resFile->GetResource('PICT', typeList->m_firstRef[i].m_resID, true); + const void *pictData = *hBlock; std::string dumpPath = "D:\\Source Code\\GlidePort\\DebugData\\PictDump\\"; @@ -1311,7 +1311,7 @@ int main(int argc, const char **argv) int n = 0; } - AuditPictOps2(static_cast(pictData), hBlock->m_size, dumpPath.c_str()); + AuditPictOps2(static_cast(pictData), hBlock.MMBlock()->m_size, dumpPath.c_str()); } } diff --git a/PortabilityLayer/DialogManager.cpp b/PortabilityLayer/DialogManager.cpp index 9c041bf..a3c7459 100644 --- a/PortabilityLayer/DialogManager.cpp +++ b/PortabilityLayer/DialogManager.cpp @@ -11,6 +11,7 @@ #include "PLInvisibleWidget.h" #include "PLLabelWidget.h" #include "PLPasStr.h" +#include "PLStandardColors.h" #include "PLSysCalls.h" #include "PLTimeTaggedVOSEvent.h" #include "PLWidgets.h" @@ -77,12 +78,13 @@ namespace PortabilityLayer Window *GetWindow() const override; ArrayView GetItems() const override; + void SetItemVisibility(unsigned int itemIndex, bool isVisible) override; int16_t ExecuteModal(DialogFilterFunc_t filterFunc) override; bool Populate(DialogTemplate *tmpl); - void DrawControls(); + void DrawControls(bool redraw); Point MouseToDialog(const GpMouseInputEvent &evt); @@ -192,6 +194,26 @@ namespace PortabilityLayer return ArrayView(m_items, m_numItems); } + void DialogImpl::SetItemVisibility(unsigned int itemIndex, bool isVisible) + { + Widget *widget = m_items[itemIndex].GetWidget(); + + if (widget->IsVisible() != isVisible) + { + widget->SetVisible(isVisible); + + DrawSurface *surface = m_window->GetDrawSurface(); + + if (isVisible) + widget->DrawControl(surface); + else + { + surface->SetForeColor(StdColors::Red()); + surface->FrameRect(surface->m_port.GetRect()); + } + } + } + int16_t DialogImpl::ExecuteModal(DialogFilterFunc_t filterFunc) { Window *window = this->GetWindow(); @@ -297,14 +319,22 @@ namespace PortabilityLayer return true; } - void DialogImpl::DrawControls() + void DialogImpl::DrawControls(bool redraw) { DrawSurface *surface = m_window->GetDrawSurface(); + if (redraw) + { + surface->SetForeColor(StdColors::White()); + surface->FillRect(surface->m_port.GetRect()); + } + for (ArrayViewIterator it = GetItems().begin(), itEnd = GetItems().end(); it != itEnd; ++it) { const DialogItem &item = *it; - item.GetWidget()->DrawControl(surface); + Widget *widget = item.GetWidget(); + if (widget->IsVisible()) + widget->DrawControl(surface); } } @@ -469,7 +499,7 @@ namespace PortabilityLayer return nullptr; } - dialog->DrawControls(); + dialog->DrawControls(true); return dialog; } diff --git a/PortabilityLayer/HostSystemServices.h b/PortabilityLayer/HostSystemServices.h index b9f19d2..9af144a 100644 --- a/PortabilityLayer/HostSystemServices.h +++ b/PortabilityLayer/HostSystemServices.h @@ -21,6 +21,7 @@ namespace PortabilityLayer virtual HostMutex *CreateMutex() = 0; virtual HostThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) = 0; virtual size_t GetFreeMemoryCosmetic() const = 0; // Returns free memory in bytes, does not have to be accurate + virtual void Beep() const = 0; static void SetInstance(HostSystemServices *instance); static HostSystemServices *GetInstance(); diff --git a/PortabilityLayer/IconLoader.cpp b/PortabilityLayer/IconLoader.cpp index d2682bf..4fbdd68 100644 --- a/PortabilityLayer/IconLoader.cpp +++ b/PortabilityLayer/IconLoader.cpp @@ -18,7 +18,7 @@ // 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 }; @@ -36,12 +36,13 @@ struct ColorIconSerializedData }; 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; + THandle LoadSimpleColorIcon(const THandle &hdl) override; + THandle LoadBWIcon(const THandle &hdl) override; static IconLoaderImpl *GetInstance(); @@ -238,10 +239,61 @@ namespace PortabilityLayer return true; } - THandle IconLoaderImpl::LoadBWIcon(const int16_t id) + THandle IconLoaderImpl::LoadSimpleColorIcon(const THandle &hdl) { - PL_NotYetImplemented(); - return THandle(); + if (hdl == nullptr || hdl.MMBlock()->m_size != 1024) + return THandle(); + + const Rect rect = Rect::Create(0, 0, 32, 32); + THandle pixMap = PixMapImpl::Create(rect, GpPixelFormats::k8BitStandard); + if (!pixMap) + return THandle(); + + const uint8_t *inData = static_cast(*hdl); + uint8_t *outData = static_cast((*pixMap)->GetPixelData()); + const size_t outPitch = (*pixMap)->GetPitch(); + + for (size_t row = 0; row < 32; row++) + { + for (size_t col = 0; col < 32; col++) + outData[col] = inData[col]; + + inData += 32; + outData += outPitch; + } + + return pixMap; + } + + THandle IconLoaderImpl::LoadBWIcon(const THandle &hdl) + { + if (hdl == nullptr || hdl.MMBlock()->m_size != 128) + return THandle(); + + const Rect rect = Rect::Create(0, 0, 32, 32); + THandle pixMap = PixMapImpl::Create(rect, GpPixelFormats::kBW1); + if (!pixMap) + return THandle(); + + const uint8_t *inData = static_cast(*hdl); + uint8_t *outData = static_cast((*pixMap)->GetPixelData()); + const size_t outPitch = (*pixMap)->GetPitch(); + + for (size_t row = 0; row < 32; row++) + { + for (size_t col = 0; col < 32; col++) + { + if (inData[col / 8] & (0x80 >> (col & 7))) + outData[col] = 0xff; + else + outData[col] = 0x00; + } + + inData += 4; + outData += outPitch; + } + + return pixMap; } IconLoaderImpl *IconLoaderImpl::GetInstance() diff --git a/PortabilityLayer/IconLoader.h b/PortabilityLayer/IconLoader.h index 5eb93b9..c1ffdc7 100644 --- a/PortabilityLayer/IconLoader.h +++ b/PortabilityLayer/IconLoader.h @@ -14,7 +14,8 @@ namespace PortabilityLayer { public: virtual bool LoadColorIcon(const int16_t id, THandle &outColorImage, THandle &outBWImage, THandle &outMaskImage) = 0; - virtual THandle LoadBWIcon(const int16_t id) = 0; + virtual THandle LoadSimpleColorIcon(const THandle &hdl) = 0; + virtual THandle LoadBWIcon(const THandle &hdl) = 0; static IconLoader *GetInstance(); }; diff --git a/PortabilityLayer/MenuManager.cpp b/PortabilityLayer/MenuManager.cpp index 6d1419b..ad6bc72 100644 --- a/PortabilityLayer/MenuManager.cpp +++ b/PortabilityLayer/MenuManager.cpp @@ -442,8 +442,6 @@ namespace PortabilityLayer if (m_lastMenu == menu) m_lastMenu = menuPtr->prevMenu; - menu.Dispose(); - DrawMenuBar(); } diff --git a/PortabilityLayer/PLApplication.cpp b/PortabilityLayer/PLApplication.cpp index 44fb61b..65504d2 100644 --- a/PortabilityLayer/PLApplication.cpp +++ b/PortabilityLayer/PLApplication.cpp @@ -1,5 +1,6 @@ #include "PLApplication.h" -#include "PLCore.h" +#include "PLCore.h" +#include "HostSystemServices.h" #include #include @@ -18,6 +19,6 @@ namespace PortabilityLayer } void SysBeep(int duration) -{ - PL_NotYetImplemented(); +{ + PortabilityLayer::HostSystemServices::GetInstance()->Beep(); } diff --git a/PortabilityLayer/PLButtonWidget.cpp b/PortabilityLayer/PLButtonWidget.cpp index 59d6582..f07c219 100644 --- a/PortabilityLayer/PLButtonWidget.cpp +++ b/PortabilityLayer/PLButtonWidget.cpp @@ -1,12 +1,15 @@ #include "PLButtonWidget.h" #include "PLCore.h" #include "PLTimeTaggedVOSEvent.h" +#include "PLStandardColors.h" +#include "FontFamily.h" namespace PortabilityLayer { ButtonWidget::ButtonWidget(const WidgetBasicState &state) : WidgetSpec(state) , m_haveMouseDown(false) + , m_text(state.m_text) { } @@ -51,4 +54,14 @@ namespace PortabilityLayer (void)state; return true; } + + void ButtonWidget::DrawControl(DrawSurface *surface) + { + surface->SetForeColor(StdColors::Black()); + surface->FrameRect(this->m_rect); + surface->SetSystemFont(12, PortabilityLayer::FontFamilyFlag_Bold); + int32_t x = (m_rect.left + m_rect.right - static_cast(surface->MeasureString(m_text.ToShortStr()))) / 2; + int32_t y = (m_rect.top + m_rect.bottom + static_cast(surface->MeasureFontAscender())) / 2; + surface->DrawString(Point::Create(x, y), m_text.ToShortStr()); + } } diff --git a/PortabilityLayer/PLButtonWidget.h b/PortabilityLayer/PLButtonWidget.h index 1578fcb..cb7d65a 100644 --- a/PortabilityLayer/PLButtonWidget.h +++ b/PortabilityLayer/PLButtonWidget.h @@ -12,6 +12,8 @@ namespace PortabilityLayer bool Init(const WidgetBasicState &state) override; + void DrawControl(DrawSurface *surface) override; + WidgetHandleState_t ProcessEvent(const TimeTaggedVOSEvent &evt) override; private: diff --git a/PortabilityLayer/PLDialogs.cpp b/PortabilityLayer/PLDialogs.cpp index 7b55933..5517933 100644 --- a/PortabilityLayer/PLDialogs.cpp +++ b/PortabilityLayer/PLDialogs.cpp @@ -52,7 +52,6 @@ void ModalDialog(ModalFilterUPP filter, short *item) PL_NotYetImplemented(); } - void DisposeModalFilterUPP(ModalFilterUPP upp) { PL_NotYetImplemented(); diff --git a/PortabilityLayer/PLDialogs.h b/PortabilityLayer/PLDialogs.h index 00ae005..21d1cfb 100644 --- a/PortabilityLayer/PLDialogs.h +++ b/PortabilityLayer/PLDialogs.h @@ -23,6 +23,8 @@ struct Dialog virtual Window *GetWindow() const = 0; virtual ArrayView GetItems() const = 0; + virtual void SetItemVisibility(unsigned int itemIndex, bool isVisible) = 0; + virtual int16_t ExecuteModal(DialogFilterFunc_t filterFunc) = 0; }; diff --git a/PortabilityLayer/PLQDraw.cpp b/PortabilityLayer/PLQDraw.cpp index 08e774d..d16033b 100644 --- a/PortabilityLayer/PLQDraw.cpp +++ b/PortabilityLayer/PLQDraw.cpp @@ -1101,7 +1101,7 @@ void DrawSurface::InvertFrameRect(const Rect &rect, const uint8_t *pattern) void DrawSurface::InvertFillRect(const Rect &rect, const uint8_t *pattern) { - PL_NotYetImplemented(); + PL_NotYetImplemented_TODO("InvertFillRect"); } void DrawSurface::SetForeColor(const PortabilityLayer::RGBAColor &color) diff --git a/PortabilityLayer/PLResourceManager.cpp b/PortabilityLayer/PLResourceManager.cpp index a3f2d72..ca27081 100644 --- a/PortabilityLayer/PLResourceManager.cpp +++ b/PortabilityLayer/PLResourceManager.cpp @@ -30,6 +30,7 @@ namespace PortabilityLayer void SetResLoad(bool load) override; + ResourceFile *LoadResFile(VirtualDirectory_t virtualDir, const PLPasStr &filename) const override; short OpenResFork(VirtualDirectory_t virtualDir, const PLPasStr &filename) override; void CloseResFile(short ref) override; PLError_t CreateBlankResFile(VirtualDirectory_t virtualDir, const PLPasStr &filename) override; @@ -131,7 +132,7 @@ namespace PortabilityLayer } } - delete rf; + rf->Destroy(); } ResourceManagerImpl *ResourceManagerImpl::GetInstance() @@ -144,6 +145,28 @@ namespace PortabilityLayer m_load = load; } + ResourceFile *ResourceManagerImpl::LoadResFile(VirtualDirectory_t virtualDir, const PLPasStr &filename) const + { + IOStream *fStream = nullptr; + if (FileManager::GetInstance()->RawOpenFileResources(virtualDir, filename, EFilePermission_Read, true, GpFileCreationDispositions::kOpenExisting, fStream) != PLErrors::kNone) + return nullptr; + + ResourceFile *resFile = ResourceFile::Create(); + if (!resFile) + return nullptr; + + bool loaded = resFile->Load(fStream); + fStream->Close(); + + if (!loaded) + { + resFile->Destroy(); + return nullptr; + } + + return resFile; + } + short ResourceManagerImpl::OpenResFork(VirtualDirectory_t virtualDir, const PLPasStr &filename) { const size_t numSlots = m_resFiles.size(); @@ -161,19 +184,11 @@ namespace PortabilityLayer if (resFileIndex == 0x7fff) return -1; - IOStream *fStream = nullptr; - if (FileManager::GetInstance()->RawOpenFileResources(virtualDir, filename, EFilePermission_Read, true, GpFileCreationDispositions::kOpenExisting, fStream) != PLErrors::kNone) - return -1; - ResourceFile *resFile = new ResourceFile(); - bool loaded = resFile->Load(fStream); - fStream->Close(); + ResourceFile *resFile = LoadResFile(virtualDir, filename); - if (!loaded) - { - delete resFile; + if (!resFile) return -1; - } ResFileSlot slot; slot.m_resourceFile = resFile; @@ -202,7 +217,10 @@ namespace PortabilityLayer void ResourceManagerImpl::CloseResFile(short ref) { ResFileSlot &slot = m_resFiles[ref]; - delete slot.m_resourceFile; + + assert(slot.m_resourceFile != nullptr); + + slot.m_resourceFile->Destroy(); slot.m_resourceFile = nullptr; if (m_lastResFile == ref) @@ -256,8 +274,9 @@ namespace PortabilityLayer const ResFileSlot& slot = m_resFiles[searchIndex]; assert(slot.m_resourceFile); - if (MMHandleBlock *block = slot.m_resourceFile->GetResource(resType, id, m_load)) - return THandle(block); + THandle resHdl = slot.m_resourceFile->GetResource(resType, id, m_load); + if (resHdl != nullptr) + return resHdl; searchIndex = slot.m_prevFile; } diff --git a/PortabilityLayer/PLWidgets.cpp b/PortabilityLayer/PLWidgets.cpp index 29ef8d5..ce24317 100644 --- a/PortabilityLayer/PLWidgets.cpp +++ b/PortabilityLayer/PLWidgets.cpp @@ -35,6 +35,16 @@ namespace PortabilityLayer OnStateChanged(); } + void Widget::SetVisible(bool visible) + { + m_visible = visible; + } + + bool Widget::IsVisible() const + { + return m_visible; + } + void Widget::SetHighlightStyle(int16_t style) { (void)style; @@ -54,6 +64,7 @@ namespace PortabilityLayer : m_rect(state.m_rect) , m_window(state.m_window) , m_enabled(state.m_enabled) + , m_visible(true) , m_state(0) { } diff --git a/PortabilityLayer/PLWidgets.h b/PortabilityLayer/PLWidgets.h index b4ff0ff..cb4355f 100644 --- a/PortabilityLayer/PLWidgets.h +++ b/PortabilityLayer/PLWidgets.h @@ -44,6 +44,10 @@ namespace PortabilityLayer void SetEnabled(bool enabled); void SetState(int16_t state); + + void SetVisible(bool visible); + bool IsVisible() const; + virtual void SetString(const PLPasStr &str); virtual void SetHighlightStyle(int16_t style); @@ -63,6 +67,7 @@ namespace PortabilityLayer Rect m_rect; int16_t m_state; bool m_enabled; + bool m_visible; }; } diff --git a/PortabilityLayer/ResourceFile.cpp b/PortabilityLayer/ResourceFile.cpp index 9aab110..908121b 100644 --- a/PortabilityLayer/ResourceFile.cpp +++ b/PortabilityLayer/ResourceFile.cpp @@ -356,18 +356,18 @@ namespace PortabilityLayer return tl; } - MMHandleBlock *ResourceFile::GetResource(const ResTypeID &resType, int id, bool load) + THandle ResourceFile::GetResource(const ResTypeID &resType, int id, bool load) { const ResourceCompiledTypeList *tl = GetResourceTypeList(resType); if (tl == nullptr) - return nullptr; + return THandle(); ResourceCompiledRef *refStart = tl->m_firstRef; ResourceCompiledRef *refEnd = refStart + tl->m_numRefs; ResourceCompiledRef *ref = BinarySearch(refStart, refEnd, id, CompiledRefSearchPredicate); if (ref == refEnd) - return nullptr; + return THandle(); MMHandleBlock *handle = nullptr; if (ref->m_handle != nullptr) @@ -391,6 +391,21 @@ namespace PortabilityLayer } } - return handle; + return THandle(handle); + } + + ResourceFile *ResourceFile::Create() + { + void *storage = PortabilityLayer::MemoryManager::GetInstance()->Alloc(sizeof(ResourceFile)); + if (!storage) + return nullptr; + + return new (storage) ResourceFile(); + } + + void ResourceFile::Destroy() + { + this->~ResourceFile(); + PortabilityLayer::MemoryManager::GetInstance()->Release(this); } } diff --git a/PortabilityLayer/ResourceFile.h b/PortabilityLayer/ResourceFile.h index a02d25d..e92bd79 100644 --- a/PortabilityLayer/ResourceFile.h +++ b/PortabilityLayer/ResourceFile.h @@ -1,7 +1,6 @@ #pragma once -#ifndef __PL_RESOURCE_FILE_H__ -#define __PL_RESOURCE_FILE_H__ +#include "PLHandle.h" #include "ResTypeID.h" #include @@ -17,17 +16,19 @@ namespace PortabilityLayer class ResourceFile { public: - ResourceFile(); - ~ResourceFile(); - bool Load(IOStream *stream); void GetAllResourceTypeLists(ResourceCompiledTypeList *&outTypeLists, size_t &outCount) const; const ResourceCompiledTypeList *GetResourceTypeList(const ResTypeID &resType); - MMHandleBlock *GetResource(const ResTypeID &resType, int id, bool load); + THandle GetResource(const ResTypeID &resType, int id, bool load); + + static ResourceFile *Create(); + void Destroy(); private: + ResourceFile(); + ~ResourceFile(); uint8_t *m_resDataBlob; size_t m_resDataBlobSize; @@ -48,5 +49,3 @@ namespace PortabilityLayer static int CompiledTypeListSearchPredicate(const ResTypeID &resTypeID, const ResourceCompiledTypeList &typeList); }; } - -#endif diff --git a/PortabilityLayer/ResourceManager.h b/PortabilityLayer/ResourceManager.h index 85a4030..e63cc64 100644 --- a/PortabilityLayer/ResourceManager.h +++ b/PortabilityLayer/ResourceManager.h @@ -10,6 +10,7 @@ namespace PortabilityLayer { struct MMHandleBlock; struct ResourceCompiledRef; + class ResourceFile; class ResTypeID; class ResourceManager @@ -20,6 +21,7 @@ namespace PortabilityLayer virtual void SetResLoad(bool load) = 0; + virtual ResourceFile *LoadResFile(VirtualDirectory_t virtualDir, const PLPasStr &filename) const = 0; virtual short OpenResFork(VirtualDirectory_t virtualDir, const PLPasStr &filename) = 0; virtual void CloseResFile(short ref) = 0; virtual PLError_t CreateBlankResFile(VirtualDirectory_t virtualDir, const PLPasStr &filename) = 0; diff --git a/PortabilityLayer/SharedTypes.h b/PortabilityLayer/SharedTypes.h index 6011a02..71db377 100644 --- a/PortabilityLayer/SharedTypes.h +++ b/PortabilityLayer/SharedTypes.h @@ -13,6 +13,9 @@ struct Point Point operator-(const Point &other) const; Point operator+(const Point &other) const; + Point &operator-=(const Point &other); + Point &operator+=(const Point &other); + static Point Create(int16_t h, int16_t v); }; @@ -117,6 +120,20 @@ inline Point Point::operator+(const Point &other) const return Point::Create(this->h + other.h, this->v + other.v); } +inline Point &Point::operator-=(const Point &other) +{ + this->h -= other.h; + this->v -= other.v; + return *this; +} + +inline Point &Point::operator+=(const Point &other) +{ + this->h += other.h; + this->v += other.v; + return *this; +} + inline Point Point::Create(int16_t h, int16_t v) { Point p;