From 1da2851d3a003627e134695349f0becd764c50fd Mon Sep 17 00:00:00 2001 From: elasota Date: Thu, 2 Jan 2020 01:32:00 -0500 Subject: [PATCH] Scaled blit, plus fix some level editor things --- GpApp/About.cpp | 201 +++++++++--------- GpApp/DialogUtils.cpp | 15 +- GpApp/HouseIO.cpp | 50 +---- GpApp/InterfaceInit.cpp | 3 +- GpApp/MainWindow.cpp | 12 +- GpApp/Map.cpp | 2 +- GpApp/Menu.cpp | 12 +- GpApp/ObjectDraw2.cpp | 6 +- GpApp/ObjectEdit.cpp | 2 +- GpApp/ObjectRects.cpp | 2 +- GpApp/Play.cpp | 4 +- GpApp/Room.cpp | 14 +- GpApp/RoomGraphics.cpp | 2 +- GpApp/RoomInfo.cpp | 2 +- GpApp/Settings.cpp | 2 +- GpApp/StructuresInit.cpp | 2 +- GpApp/Utilities.cpp | 4 +- GpD3D/GpFileSystem_Win32.cpp | 20 ++ GpD3D/GpFileSystem_Win32.h | 1 + GpD3D/GpSystemServices_Win32.cpp | 4 + PortabilityLayer/DialogManager.cpp | 7 +- PortabilityLayer/FileManager.cpp | 19 ++ PortabilityLayer/FileManager.h | 5 +- PortabilityLayer/HostFileSystem.h | 5 +- PortabilityLayer/MenuManager.cpp | 95 ++++++--- PortabilityLayer/MenuManager.h | 25 ++- PortabilityLayer/PLCore.cpp | 2 +- PortabilityLayer/PLHandle.cpp | 4 +- PortabilityLayer/PLHandle.h | 2 +- PortabilityLayer/PLImageWidget.cpp | 31 +++ PortabilityLayer/PLImageWidget.h | 22 ++ PortabilityLayer/PLMenus.cpp | 15 -- PortabilityLayer/PLMenus.h | 3 - PortabilityLayer/PLQDOffscreen.cpp | 2 +- PortabilityLayer/PLQDOffscreen.h | 10 +- PortabilityLayer/PLQDraw.cpp | 28 ++- PortabilityLayer/PLWidgets.cpp | 5 + PortabilityLayer/PLWidgets.h | 1 + PortabilityLayer/PortabilityLayer.vcxproj | 2 + .../PortabilityLayer.vcxproj.filters | 6 + PortabilityLayer/QDPixMap.cpp | 193 +++++++++++++++++ PortabilityLayer/QDPixMap.h | 2 + 42 files changed, 571 insertions(+), 273 deletions(-) create mode 100644 PortabilityLayer/PLImageWidget.cpp create mode 100644 PortabilityLayer/PLImageWidget.h diff --git a/GpApp/About.cpp b/GpApp/About.cpp index 4301a1a..367aaa9 100644 --- a/GpApp/About.cpp +++ b/GpApp/About.cpp @@ -4,12 +4,15 @@ //---------------------------------------------------------------------------- //============================================================================ +#include "PLArrayView.h" #include "PLKeyEncoding.h" #include "PLControlDefinitions.h" #include "PLNumberFormatting.h" #include "PLResources.h" #include "PLSound.h" #include "PLPasStr.h" +#include "PLSysCalls.h" +#include "PLWidgets.h" #include "About.h" #include "DialogManager.h" #include "DialogUtils.h" @@ -17,15 +20,16 @@ #include "Externs.h" #include "HostSystemServices.h" #include "ScanlineMask.h" +#include "PLTimeTaggedVOSEvent.h" static void HiLiteOkayButton (DrawSurface *surface); static void UnHiLiteOkayButton (DrawSurface *surface); static void UpdateMainPict (Dialog *); -static Boolean AboutFilter (Dialog *, EventRecord *theEvent, short *hit); +static int16_t AboutFilter(Dialog *, const TimeTaggedVOSEvent &evt); -static PortabilityLayer::ScanlineMask *okayButtScanlineMask; +static Point okayButtLowerV, okayButtUpperV; static Rect okayButtonBounds, mainPICTBounds; static Boolean okayButtIsHiLit, clickedDownInOkay; @@ -45,7 +49,7 @@ void DoAbout (void) StringPtr messagePtr; VersRecHndl version; ControlHandle itemHandle; - short itemType, hit, wasResFile; + short hit, wasResFile; wasResFile = CurResFile(); UseResFile(thisMac.thisResFile); @@ -62,31 +66,25 @@ void DoAbout (void) BlockMove((Ptr)messagePtr, &longVersion, ((UInt8)*messagePtr) + 1); SetDialogString(aboutDialog, kTextItemVers, longVersion); } - - GetDialogItem(aboutDialog, kOkayButton, &itemType, &itemHandle, &okayButtonBounds); -#if 0 - PL_NotYetImplemented_TODO("Misc"); - okayButtRgn = NewRgn(); // Create diagonal button region - OpenRgn(); - MoveTo(okayButtonBounds.left + 1, okayButtonBounds.top + 45); - Line(44, -44); // These lines define the region - Line(16, 16); - Line(-44, 44); - Line(-16, -16); - CloseRgn(okayButtRgn); -#endif + + okayButtonBounds = aboutDialog->GetItems()[kOkayButton - 1].GetWidget()->GetRect(); + + okayButtUpperV = Point::Create(okayButtonBounds.left + 45, okayButtonBounds.top + 1); + okayButtLowerV = Point::Create(okayButtUpperV.h - 28, okayButtUpperV.v + 60); + okayButtIsHiLit = false; // Initially, button is not hilit clickedDownInOkay = false; // Initially, didn't click in okay button - GetDialogItem(aboutDialog, kPictItemMain, &itemType, &itemHandle, &mainPICTBounds); + + mainPICTBounds = aboutDialog->GetItems()[kPictItemMain - 1].GetWidget()->GetRect(); + + UpdateMainPict(aboutDialog); do // Loop until user wants to exit { - ModalDialog(AboutFilter, &hit); + hit = aboutDialog->ExecuteModal(AboutFilter); } - while ((hit != kOkayButton) && (okayButtScanlineMask != nil)); - - if (okayButtScanlineMask != nil) - okayButtScanlineMask->Destroy(); // Clean up! + while (hit != kOkayButton); + aboutDialog->Destroy(); UseResFile(wasResFile); @@ -99,7 +97,7 @@ void DoAbout (void) static void HiLiteOkayButton (DrawSurface *surface) { #define kOkayButtPICTHiLit 151 // res ID of unhilit button PICT - PicHandle thePict; + THandle thePict; if (!okayButtIsHiLit) { @@ -121,7 +119,7 @@ static void HiLiteOkayButton (DrawSurface *surface) static void UnHiLiteOkayButton (DrawSurface *surface) { #define kOkayButtPICTNotHiLit 150 // res ID of hilit button PICT - PicHandle thePict; + THandle thePict; if (okayButtIsHiLit) { @@ -143,8 +141,6 @@ static void UpdateMainPict (Dialog *theDial) { Str255 theStr, theStr2; uint64_t freeMemory; - - DrawDialog(theDial); freeMemory = PortabilityLayer::HostSystemServices::GetInstance()->GetFreeMemoryCosmetic(); @@ -168,96 +164,93 @@ static void UpdateMainPict (Dialog *theDial) DrawDialogUserText2(theDial, 8, theStr); } +static bool PointIsInDiagonalOkayButton(const Point &pt) +{ + const Point upperVPt = pt - okayButtUpperV; + const Point lowerVPt = pt - okayButtLowerV; + + const bool edge1 = (upperVPt.h + upperVPt.v) >= 0; + const bool edge2 = (-upperVPt.h + upperVPt.v) >= 0; + const bool edge3 = (lowerVPt.h - lowerVPt.v) >= 0; + const bool edge4 = (-lowerVPt.h - lowerVPt.v) >= 0; + + return edge1 && edge2 && edge3 && edge4; +} + //-------------------------------------------------------------- AboutFilter // Dialog filter for the About dialog. -static Boolean AboutFilter (Dialog *theDial, EventRecord *theEvent, short *hit) +static int16_t AboutFilter(Dialog *dialog, const TimeTaggedVOSEvent &evt) { - Point mousePt; - UInt32 dummyLong; - Boolean handledIt; + bool handledIt = false; + int16_t hit = -1; - DrawSurface *surface = theDial->GetWindow()->GetDrawSurface(); - - if (Button() && clickedDownInOkay) + Window *window = dialog->GetWindow(); + DrawSurface *surface = window->GetDrawSurface(); + + if (evt.IsKeyDownEvent()) { - GetMouse(&mousePt); - if(PointInScanlineMask(mousePt, okayButtScanlineMask)) - HiLiteOkayButton(surface); - else - UnHiLiteOkayButton(surface); - } - - switch (theEvent->what) - { - case keyDown: - switch (theEvent->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): HiLiteOkayButton(surface); - Delay(8, &dummyLong); + PLSysCalls::Sleep(8); UnHiLiteOkayButton(surface); - *hit = kOkayButton; + hit = kOkayButton; handledIt = true; break; - - default: - handledIt = false; - } - break; - - case mouseDown: - mousePt = theEvent->where; - GlobalToLocal(&mousePt); - if(PointInScanlineMask(mousePt, okayButtScanlineMask)) - { - clickedDownInOkay = true; - handledIt = false; - } - else - handledIt = false; - break; - - case mouseUp: - mousePt = theEvent->where; - GlobalToLocal(&mousePt); - if(PointInScanlineMask(mousePt, okayButtScanlineMask) && clickedDownInOkay) - { - UnHiLiteOkayButton(surface); - *hit = kOkayButton; - handledIt = true; - } - else - { - clickedDownInOkay = false; - handledIt = false; - } - break; - - case updateEvt: - if ((WindowPtr)theEvent->message == mainWindow) - { - SetPort((GrafPtr)mainWindow); - UpdateMainWindow(); - EndUpdate((WindowPtr)theEvent->message); - SetPortDialogPort(theDial); - handledIt = true; - } - else if ((WindowPtr)theEvent->message == (WindowPtr)theDial) - { - SetPortDialogPort(theDial); - UpdateMainPict(theDial); - EndUpdate((WindowPtr)theEvent->message); - handledIt = false; - } - break; - + default: - handledIt = false; - break; + handledIt = false; + break; + } } - - return (handledIt); + else if (evt.m_vosEvent.m_eventType == GpVOSEventTypes::kMouseInput) + { + const GpMouseInputEvent &mouseEvt = evt.m_vosEvent.m_event.m_mouseInputEvent; + const Point mousePt = window->MouseToLocal(mouseEvt); + + if (mouseEvt.m_eventType == GpMouseEventTypes::kDown) + { + if (PointIsInDiagonalOkayButton(mousePt)) + { + HiLiteOkayButton(surface); + clickedDownInOkay = true; + handledIt = false; + } + else + handledIt = false; + } + else if (mouseEvt.m_eventType == GpMouseEventTypes::kUp) + { + if (PointIsInDiagonalOkayButton(mousePt) && clickedDownInOkay) + { + UnHiLiteOkayButton(surface); + hit = kOkayButton; + handledIt = true; + } + else + { + clickedDownInOkay = false; + handledIt = false; + } + } + else if (mouseEvt.m_eventType == GpMouseEventTypes::kMove) + { + if (clickedDownInOkay) + { + if (PointIsInDiagonalOkayButton(mousePt)) + HiLiteOkayButton(surface); + else + UnHiLiteOkayButton(surface); + } + } + } + + if (!handledIt) + return -1; + + return hit; } diff --git a/GpApp/DialogUtils.cpp b/GpApp/DialogUtils.cpp index 3c374c9..5491a64 100644 --- a/GpApp/DialogUtils.cpp +++ b/GpApp/DialogUtils.cpp @@ -394,12 +394,7 @@ void GetDialogString (Dialog *theDialog, short item, StringPtr theString) void SetDialogString (Dialog *theDialog, short item, const PLPasStr &theString) { - Rect itemRect; - ControlHandle itemHandle; - short itemType; - - GetDialogItem(theDialog, item, &itemType, &itemHandle, &itemRect); - SetDialogItemText(itemHandle, theString); + theDialog->GetItems()[item - 1].GetWidget()->SetString(theString); } //-------------------------------------------------------------- GetDialogStringLen @@ -662,8 +657,7 @@ void DrawDialogUserText (Dialog *dial, short item, StringPtr text, Boolean inver void DrawDialogUserText2 (Dialog *dial, short item, StringPtr text) { - Rect iRect; - ControlHandle iHandle; + ; Str255 stringCopy; short iType; @@ -671,7 +665,8 @@ void DrawDialogUserText2 (Dialog *dial, short item, StringPtr text) surface->SetApplicationFont(9, PortabilityLayer::FontFamilyFlag_None); PasStringCopy(text, stringCopy); - GetDialogItem(dial, item, &iType, &iHandle, &iRect); + const 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); @@ -687,7 +682,7 @@ void LoadDialogPICT (Dialog *theDialog, short item, short theID) { Rect iRect; ControlHandle iHandle; - PicHandle thePict; + THandle thePict; short iType; GetDialogItem(theDialog, item, &iType, &iHandle, &iRect); diff --git a/GpApp/HouseIO.cpp b/GpApp/HouseIO.cpp index b390876..705a42a 100644 --- a/GpApp/HouseIO.cpp +++ b/GpApp/HouseIO.cpp @@ -14,6 +14,7 @@ #include "Externs.h" #include "Environ.h" #include "FileManager.h" +#include "HostFileSystem.h" #include "House.h" #include "IOStream.h" #include "ObjectEdit.h" @@ -960,52 +961,7 @@ void YellowAlert (short whichAlert, short identifier) //-------------------------------------------------------------- IsFileReadOnly -Boolean IsFileReadOnly (const VFileSpec &) +Boolean IsFileReadOnly (const VFileSpec &spec) { - PL_NotYetImplemented_TODO("FileSystem"); - return true; - /* - Str255 tempStr; - ParamBlockRec theBlock; - HParamBlockRec hBlock; - VolumeParam *volPtr; - PLError_t theErr; - - volPtr = (VolumeParam *)&theBlock; - volPtr->ioCompletion = nil; - volPtr->ioVolIndex = 0; - volPtr->ioNamePtr = tempStr; - volPtr->ioVRefNum = theSpec->vRefNum; - - theErr = PBGetVInfo(&theBlock, false); - if (CheckFileError(theErr, "\pRead/Write")) - { - if (((volPtr->ioVAtrb & 0x0080) == 0x0080) || - ((volPtr->ioVAtrb & 0x8000) == 0x8000)) - return (true); // soft/hard locked bits - else - { - hBlock.fileParam.ioCompletion = nil; - hBlock.fileParam.ioVRefNum = theSpec->vRefNum; - hBlock.fileParam.ioFVersNum = 0; - hBlock.fileParam.ioFDirIndex = 0; - hBlock.fileParam.ioNamePtr = theSpec->name; - hBlock.fileParam.ioDirID = theSpec->parID; - - theErr = PBHGetFInfo(&hBlock, false); - if (CheckFileError(theErr, "\pRead/Write")) - { - if ((hBlock.fileParam.ioFlAttrib & 0x0001) == 0x0001) - return (true); - else - return (false); - } - else - return (false); - } - } - else - return (false); - */ + return PortabilityLayer::FileManager::GetInstance()->FileLocked(spec.m_dir, spec.m_name); } - diff --git a/GpApp/InterfaceInit.cpp b/GpApp/InterfaceInit.cpp index 7c49eb9..434b86e 100644 --- a/GpApp/InterfaceInit.cpp +++ b/GpApp/InterfaceInit.cpp @@ -9,6 +9,7 @@ #include "Externs.h" #include "Environ.h" #include "Map.h" +#include "MenuManager.h" #include "PLKeyEncoding.h" #include "RectUtils.h" #include "Tools.h" @@ -64,7 +65,7 @@ void InitializeMenus (void) InsertMenu(optionsMenu, 0); menusUp = true; - DrawMenuBar(); + PortabilityLayer::MenuManager::GetInstance()->SetMenuVisible(true); houseMenu = GetMenu(kHouseMenuID); if (houseMenu == nil) diff --git a/GpApp/MainWindow.cpp b/GpApp/MainWindow.cpp index 4958085..9db5326 100644 --- a/GpApp/MainWindow.cpp +++ b/GpApp/MainWindow.cpp @@ -198,7 +198,7 @@ void OpenMainWindow (void) if (theMode == kEditMode) { if (menuWindow != nil) - DisposeWindow(menuWindow); + PortabilityLayer::WindowManager::GetInstance()->DestroyWindow(menuWindow); menuWindow = nil; QSetRect(&mainWindowRect, 0, 0, 512, 322); @@ -289,6 +289,12 @@ void OpenMainWindow (void) SetPortWindowPort(mainWindow); } + + CopyBits((BitMap *)*GetGWorldPixMap(workSrcMap), + GetPortBitMapForCopyBits(GetWindowPort(mainWindow)), + &mainWindowRect, &mainWindowRect, srcCopy); + + mainWindow->m_surface.m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents); } //-------------------------------------------------------------- CloseMainWindow @@ -298,11 +304,11 @@ void OpenMainWindow (void) void CloseMainWindow (void) { if (mainWindow != nil) - DisposeWindow(mainWindow); + PortabilityLayer::WindowManager::GetInstance()->DestroyWindow(mainWindow); mainWindow = nil; if (boardWindow != nil) - DisposeWindow(boardWindow); + PortabilityLayer::WindowManager::GetInstance()->DestroyWindow(boardWindow); boardWindow = nil; } diff --git a/GpApp/Map.cpp b/GpApp/Map.cpp index 0588eac..1ebea12 100644 --- a/GpApp/Map.cpp +++ b/GpApp/Map.cpp @@ -161,7 +161,7 @@ void FindNewActiveRoomRect (void) void LoadGraphicPlus (DrawSurface *surface, short resID, const Rect &theRect) { - PicHandle thePicture; + THandle thePicture; thePicture = GetPicture(resID); if (thePicture == nil) diff --git a/GpApp/Menu.cpp b/GpApp/Menu.cpp index 7d4ea5b..3efcc28 100644 --- a/GpApp/Menu.cpp +++ b/GpApp/Menu.cpp @@ -15,6 +15,7 @@ #include "DialogUtils.h" #include "Externs.h" #include "House.h" +#include "MenuManager.h" #include "ObjectEdit.h" @@ -250,10 +251,15 @@ void UpdateMenus (Boolean newMode) if (newMode) { + PortabilityLayer::MenuManager *mm = PortabilityLayer::MenuManager::GetInstance(); if (theMode == kEditMode) InsertMenu(houseMenu, 0); else - DeleteMenu(kHouseMenuID); + { + THandle houseMenu = mm->GetMenuByID(kHouseMenuID); + if (houseMenu) + mm->RemoveMenu(houseMenu); + } } if (theMode == kEditMode) @@ -270,8 +276,6 @@ void UpdateMenus (Boolean newMode) } else UpdateMenusNonEditMode(); - - DrawMenuBar(); } //-------------------------------------------------------------- DoAppleMenu @@ -619,8 +623,6 @@ void DoMenuChoice (long menuChoice) DoHouseMenu(theItem); break; } - - HiliteMenu(0); } //-------------------------------------------------------------- UpdateMapCheckmark diff --git a/GpApp/ObjectDraw2.cpp b/GpApp/ObjectDraw2.cpp index 598837f..9bee33e 100644 --- a/GpApp/ObjectDraw2.cpp +++ b/GpApp/ObjectDraw2.cpp @@ -1045,7 +1045,7 @@ void DrawCalendar (Rect *theRect) { DateTimeRec timeRec; Rect bounds; - PicHandle thePicture; + THandle thePicture; Str255 monthStr; DrawSurface *wasCPort; @@ -1076,7 +1076,7 @@ void DrawCalendar (Rect *theRect) void DrawBulletin (Rect *theRect) { Rect bounds; - PicHandle thePicture; + THandle thePicture; thePicture = GetPicture(kBulletinPictID); if (thePicture == nil) @@ -1094,7 +1094,7 @@ void DrawBulletin (Rect *theRect) void DrawPictObject (short what, Rect *theRect) { Rect bounds; - PicHandle thePicture; + THandle thePicture; short pictID; switch (what) diff --git a/GpApp/ObjectEdit.cpp b/GpApp/ObjectEdit.cpp index bffe3f8..2ee61a5 100644 --- a/GpApp/ObjectEdit.cpp +++ b/GpApp/ObjectEdit.cpp @@ -2004,7 +2004,7 @@ void SelectPrevObject (void) #ifndef COMPILEDEMO void GetThisRoomsObjRects (void) { - PicHandle thePict; + THandle thePict; short i, wide, tall; isFirstRoom = (GetFirstRoomNumber() == thisRoomNumber); diff --git a/GpApp/ObjectRects.cpp b/GpApp/ObjectRects.cpp index 6fa05d2..ecd3c7c 100644 --- a/GpApp/ObjectRects.cpp +++ b/GpApp/ObjectRects.cpp @@ -31,7 +31,7 @@ extern short nHotSpots, numChimes; void GetObjectRect (objectPtr who, Rect *itsRect) { - PicHandle thePict; + THandle thePict; short wide, tall; switch (who->what) diff --git a/GpApp/Play.cpp b/GpApp/Play.cpp index 0093f2f..0ff3dfd 100644 --- a/GpApp/Play.cpp +++ b/GpApp/Play.cpp @@ -451,7 +451,7 @@ void PlayGame (void) { Rect bounds; - PicHandle thePicture; + THandle thePicture; SInt16 hOffset; if (boardSrcRect.right >= 640) @@ -495,7 +495,7 @@ void PlayGame (void) { Rect bounds; - PicHandle thePicture; + THandle thePicture; SInt16 hOffset; if (boardSrcRect.right >= 640) diff --git a/GpApp/Room.cpp b/GpApp/Room.cpp index 8567f66..92aed83 100644 --- a/GpApp/Room.cpp +++ b/GpApp/Room.cpp @@ -10,6 +10,7 @@ #include "PLPasStr.h" #include "PLStandardColors.h" #include "Externs.h" +#include "FontFamily.h" #include "House.h" #include "MainWindow.h" #include "RectUtils.h" @@ -236,7 +237,7 @@ Boolean CreateNewRoom (short h, short v) void ReadyBackground (short theID, short *theTiles) { Rect src, dest; - PicHandle thePicture; + THandle thePicture; short i; if ((noRoomAtAll) || (!houseUnlocked)) @@ -244,6 +245,7 @@ void ReadyBackground (short theID, short *theTiles) LtGrayForeColor(workSrcMap); workSrcMap->FillRect(workSrcRect); workSrcMap->SetForeColor(StdColors::Black()); + workSrcMap->SetApplicationFont(9, PortabilityLayer::FontFamilyFlag_None); const Point textPoint = Point::Create(10, 20); if (houseUnlocked) @@ -319,11 +321,19 @@ void ReflectCurrentRoom (Boolean forceMapRedraw) } } GenerateRetroLinks(); + DebugPixMap(backSrcMap->m_port.GetPixMap(), "DebugData/EditorSplash1"); UpdateEditWindowTitle(); + DebugPixMap(backSrcMap->m_port.GetPixMap(), "DebugData/EditorSplash2"); ReadyBackground(thisRoom->background, thisRoom->tiles); + DebugPixMap(backSrcMap->m_port.GetPixMap(), "DebugData/EditorSplash3"); GetThisRoomsObjRects(); + DebugPixMap(backSrcMap->m_port.GetPixMap(), "DebugData/EditorSplash4"); DrawThisRoomsObjects(); - InvalWindowRect(mainWindow, &mainWindowRect); + DebugPixMap(backSrcMap->m_port.GetPixMap(), "DebugData/EditorSplash5"); + + PL_NotYetImplemented_TODO("FixMe"); + DebugPixMap(backSrcMap->m_port.GetPixMap(), "DebugData/EditorSplash6"); + //InvalWindowRect(mainWindow, &mainWindowRect); #endif } diff --git a/GpApp/RoomGraphics.cpp b/GpApp/RoomGraphics.cpp index e44caf9..1616380 100644 --- a/GpApp/RoomGraphics.cpp +++ b/GpApp/RoomGraphics.cpp @@ -131,7 +131,7 @@ void DrawLocale (void) void LoadGraphicSpecial (DrawSurface *surface, short resID) { Rect bounds; - PicHandle thePicture; + THandle thePicture; thePicture = GetPicture(resID); if (thePicture == nil) diff --git a/GpApp/RoomInfo.cpp b/GpApp/RoomInfo.cpp index a6da379..d8e168d 100644 --- a/GpApp/RoomInfo.cpp +++ b/GpApp/RoomInfo.cpp @@ -857,7 +857,7 @@ short ChooseOriginalArt (short was) Boolean PictIDExists (short theID) { - PicHandle thePicture; + THandle thePicture; // Handle resHandle; // Str255 resName; // ResType resType; diff --git a/GpApp/Settings.cpp b/GpApp/Settings.cpp index 8b3a20a..9c0423b 100644 --- a/GpApp/Settings.cpp +++ b/GpApp/Settings.cpp @@ -513,7 +513,7 @@ void DoControlPrefs (void) prefDlg = PortabilityLayer::DialogManager::GetInstance()->LoadDialog(kControlPrefsDialID, kPutInFront); if (prefDlg == nil) RedAlert(kErrDialogDidntLoad); - SetPort((GrafPtr)prefDlg); + SetGraphicsPort(&prefDlg->GetWindow()->m_surface); for (i = 0; i < 4; i++) { GetDialogItemRect(prefDlg, i + kRightControl, &controlRects[i]); diff --git a/GpApp/StructuresInit.cpp b/GpApp/StructuresInit.cpp index 130a2ca..d81945b 100644 --- a/GpApp/StructuresInit.cpp +++ b/GpApp/StructuresInit.cpp @@ -61,7 +61,7 @@ extern short wasScoreboardMode; void InitScoreboardMap (void) { Rect bounds; - PicHandle thePicture; + THandle thePicture; DrawSurface *wasCPort; PLError_t theErr; short hOffset; diff --git a/GpApp/Utilities.cpp b/GpApp/Utilities.cpp index 7787d8c..75b04a8 100644 --- a/GpApp/Utilities.cpp +++ b/GpApp/Utilities.cpp @@ -282,7 +282,7 @@ void KillOffScreenBitMap (GrafPtr offScreen) void LoadGraphic (DrawSurface *surface, short resID) { Rect bounds; - PicHandle thePicture; + THandle thePicture; thePicture = GetPicture(resID); if (thePicture == nil) @@ -302,7 +302,7 @@ void LoadGraphic (DrawSurface *surface, short resID) void LoadScaledGraphic (DrawSurface *surface, short resID, Rect *theRect) { - PicHandle thePicture; + THandle thePicture; thePicture = GetPicture(resID); if (thePicture == nil) diff --git a/GpD3D/GpFileSystem_Win32.cpp b/GpD3D/GpFileSystem_Win32.cpp index 05be9f5..55f41ba 100644 --- a/GpD3D/GpFileSystem_Win32.cpp +++ b/GpD3D/GpFileSystem_Win32.cpp @@ -172,6 +172,26 @@ bool GpFileSystem_Win32::FileExists(PortabilityLayer::VirtualDirectory_t virtual return PathFileExistsW(winPath) != 0; } +bool GpFileSystem_Win32::FileLocked(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool *exists) +{ + wchar_t winPath[MAX_PATH + 1]; + + if (!ResolvePath(virtualDirectory, path, winPath)) + { + *exists = false; + return false; + } + + DWORD attribs = GetFileAttributesW(winPath); + if (attribs == INVALID_FILE_ATTRIBUTES) + { + *exists = false; + return false; + } + + return (attribs & FILE_ATTRIBUTE_READONLY) != 0; +} + PortabilityLayer::IOStream *GpFileSystem_Win32::OpenFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool writeAccess, bool create) { wchar_t winPath[MAX_PATH + 1]; diff --git a/GpD3D/GpFileSystem_Win32.h b/GpD3D/GpFileSystem_Win32.h index 53a7e57..bf1febe 100644 --- a/GpD3D/GpFileSystem_Win32.h +++ b/GpD3D/GpFileSystem_Win32.h @@ -13,6 +13,7 @@ public: GpFileSystem_Win32(); bool FileExists(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path) override; + bool FileLocked(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool *exists) override; PortabilityLayer::IOStream *OpenFile(PortabilityLayer::VirtualDirectory_t virtualDirectory, const char *path, bool writeAccess, bool create) override; PortabilityLayer::HostDirectoryCursor *ScanDirectory(PortabilityLayer::VirtualDirectory_t virtualDirectory) override; diff --git a/GpD3D/GpSystemServices_Win32.cpp b/GpD3D/GpSystemServices_Win32.cpp index 6ae2182..bc82fb9 100644 --- a/GpD3D/GpSystemServices_Win32.cpp +++ b/GpD3D/GpSystemServices_Win32.cpp @@ -64,6 +64,10 @@ PortabilityLayer::HostThreadEvent *GpSystemServices_Win32::CreateThreadEvent(boo uint64_t GpSystemServices_Win32::GetFreeMemoryCosmetic() const { MEMORYSTATUSEX memStatus; + memset(&memStatus, 0, sizeof(memStatus)); + + memStatus.dwLength = sizeof(memStatus); + if (!GlobalMemoryStatusEx(&memStatus)) return 0; diff --git a/PortabilityLayer/DialogManager.cpp b/PortabilityLayer/DialogManager.cpp index 6898372..9c041bf 100644 --- a/PortabilityLayer/DialogManager.cpp +++ b/PortabilityLayer/DialogManager.cpp @@ -7,6 +7,7 @@ #include "PLButtonWidget.h" #include "PLDialogs.h" #include "PLIconWidget.h" +#include "PLImageWidget.h" #include "PLInvisibleWidget.h" #include "PLLabelWidget.h" #include "PLPasStr.h" @@ -276,10 +277,12 @@ namespace PortabilityLayer case SerializedDialogItemTypeCodes::kIcon: widget = IconWidget::Create(basicState); break; + case SerializedDialogItemTypeCodes::kImage: + widget = ImageWidget::Create(basicState); + break; case SerializedDialogItemTypeCodes::kCheckBox: case SerializedDialogItemTypeCodes::kRadioButton: case SerializedDialogItemTypeCodes::kEditBox: - case SerializedDialogItemTypeCodes::kImage: default: widget = InvisibleWidget::Create(basicState); break; @@ -443,7 +446,7 @@ namespace PortabilityLayer //window->m_wmY = displayHeight / 3 - dialogHeight / 2; window->m_wmY = (static_cast(displayHeight * 2) - static_cast(dialogHeight * 3)) / 6; } - else if (dialogHeight * 2 <= displayHeight) + else if (dialogHeight * 2U <= displayHeight) window->m_wmY = displayHeight / 4; else window->m_wmY = (static_cast(displayHeight) - static_cast(dialogHeight)) / 2; diff --git a/PortabilityLayer/FileManager.cpp b/PortabilityLayer/FileManager.cpp index 1ed8476..3f6b635 100644 --- a/PortabilityLayer/FileManager.cpp +++ b/PortabilityLayer/FileManager.cpp @@ -19,6 +19,7 @@ namespace PortabilityLayer { public: bool FileExists(VirtualDirectory_t dirID, const PLPasStr &filename) override; + bool FileLocked(VirtualDirectory_t dirID, const PLPasStr &filename) override; bool DeleteFile(VirtualDirectory_t dirID, const PLPasStr &filename) override; PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) override; @@ -53,6 +54,24 @@ namespace PortabilityLayer return HostFileSystem::GetInstance()->FileExists(dirID, extFN); } + bool FileManagerImpl::FileLocked(VirtualDirectory_t dirID, const PLPasStr &filename) + { + const char *exts[3] = { ".gpf", ".gpr", ".gpd" }; + + for (int extIndex = 0; extIndex < sizeof(exts) / sizeof(exts[0]); extIndex++) + { + ExtendedFileName_t extFN; + if (!ConstructFilename(extFN, filename, exts[extIndex])) + return true; + + bool exists = false; + if (HostFileSystem::GetInstance()->FileLocked(dirID, extFN, &exists) && exists) + return true; + } + + return false; + } + bool FileManagerImpl::DeleteFile(VirtualDirectory_t dirID, const PLPasStr &filename) { ExtendedFileName_t extFN; diff --git a/PortabilityLayer/FileManager.h b/PortabilityLayer/FileManager.h index db4e866..ab33a80 100644 --- a/PortabilityLayer/FileManager.h +++ b/PortabilityLayer/FileManager.h @@ -1,6 +1,4 @@ #pragma once -#ifndef __PL_FILE_MANAGER_H__ -#define __PL_FILE_MANAGER_H__ #include "FilePermission.h" #include "CoreDefs.h" @@ -22,6 +20,7 @@ namespace PortabilityLayer { public: virtual bool FileExists(VirtualDirectory_t dirID, const PLPasStr &filename) = 0; + virtual bool FileLocked(VirtualDirectory_t dirID, const PLPasStr &filename) = 0; virtual bool DeleteFile(VirtualDirectory_t dirID, const PLPasStr &filename) = 0; virtual PLError_t CreateFile(VirtualDirectory_t dirID, const PLPasStr &filename, const MacFileProperties &mfp) = 0; @@ -37,5 +36,3 @@ namespace PortabilityLayer static FileManager *GetInstance(); }; } - -#endif diff --git a/PortabilityLayer/HostFileSystem.h b/PortabilityLayer/HostFileSystem.h index 2a22d11..89710a3 100644 --- a/PortabilityLayer/HostFileSystem.h +++ b/PortabilityLayer/HostFileSystem.h @@ -1,6 +1,4 @@ #pragma once -#ifndef __PL_HOST_FILESYSTEM_H__ -#define __PL_HOST_FILESYSTEM_H__ #include "VirtualDirectory.h" @@ -13,6 +11,7 @@ namespace PortabilityLayer { public: virtual bool FileExists(VirtualDirectory_t virtualDirectory, const char *path) = 0; + virtual bool FileLocked(VirtualDirectory_t virtualDirectory, const char *path, bool *exists) = 0; virtual IOStream *OpenFile(VirtualDirectory_t virtualDirectory, const char *path, bool writeAccess, bool create) = 0; virtual HostDirectoryCursor *ScanDirectory(VirtualDirectory_t virtualDirectory) = 0; @@ -23,5 +22,3 @@ namespace PortabilityLayer static HostFileSystem *ms_instance; }; } - -#endif diff --git a/PortabilityLayer/MenuManager.cpp b/PortabilityLayer/MenuManager.cpp index e592f1e..bc19483 100644 --- a/PortabilityLayer/MenuManager.cpp +++ b/PortabilityLayer/MenuManager.cpp @@ -91,8 +91,8 @@ struct Menu PortabilityLayer::MMHandleBlock *stringBlobHandle; - Menu **prevMenu; - Menu **nextMenu; + THandle prevMenu; + THandle nextMenu; // Refreshed on layout size_t cumulativeOffset; @@ -116,15 +116,19 @@ namespace PortabilityLayer virtual void Init() override; virtual void Shutdown() override; - Menu **DeserializeMenu(const void *resData) const override; - Menu **GetMenuByID(int id) const override; - void InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu) override; - void InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu) override; - void InsertMenuAtEnd(Menu **insertingMenu) override; - void InsertMenuAtBeginning(Menu **insertingMenu) override; - void SetMenuEnabled(Menu **menuHandle, bool enabled) override; - void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) override; - void SetItemChecked(Menu **menu, unsigned int index, bool checked) override; + THandle DeserializeMenu(const void *resData) const override; + THandle GetMenuByID(int id) const override; + + void InsertMenuBefore(const THandle &insertingMenu, const THandle &existingMenu) override; + void InsertMenuAfter(const THandle &insertingMenu, const THandle &existingMenu) override; + void InsertMenuAtEnd(const THandle &insertingMenu) override; + void InsertMenuAtBeginning(const THandle &insertingMenu) override; + + void RemoveMenu(const THandle &menu) override; + + void SetMenuEnabled(const THandle &menuHandle, bool enabled) override; + void SetItemEnabled(const THandle &menu, unsigned int index, bool enabled) override; + void SetItemChecked(const THandle &menu, unsigned int index, bool checked) override; bool IsPointInMenuBar(const Vec2i &point) const override; void MenuSelect(const Vec2i &initialPoint, int16_t *outMenu, uint16_t *outItem) override; @@ -146,7 +150,7 @@ namespace PortabilityLayer void HandleSelectionOfMenu(MenuManagerImpl *mm, Menu **menuHdl, bool &outNeedRedraw); void Dismiss(); - Menu **GetSelectedMenu() const; + THandle GetSelectedMenu() const; DrawSurface *GetRenderedMenu() const; const unsigned int *GetSelectedItem() const; @@ -156,7 +160,7 @@ namespace PortabilityLayer private: void RenderMenu(Menu *menu); - Menu **m_currentMenu; + THandle m_currentMenu; DrawSurface *m_menuGraf; unsigned int m_itemIndex; bool m_haveItem; @@ -187,8 +191,8 @@ namespace PortabilityLayer DrawSurface *m_menuBarGraf; - Menu **m_firstMenu; - Menu **m_lastMenu; + THandle m_firstMenu; + THandle m_lastMenu; bool m_haveMenuBarLayout; bool m_haveIcon; bool m_menuBarVisible; @@ -205,12 +209,10 @@ namespace PortabilityLayer MenuManagerImpl::MenuManagerImpl() : m_menuBarGraf(nullptr) - , m_firstMenu(nullptr) - , m_lastMenu(nullptr) , m_haveMenuBarLayout(false) , m_haveIcon(false) , m_iconGraphic(nullptr) - , m_menuBarVisible(true) + , m_menuBarVisible(false) { } @@ -238,7 +240,7 @@ namespace PortabilityLayer // GP TODO: Dispose of menus properly } - Menu **MenuManagerImpl::DeserializeMenu(const void *resData) const + THandle MenuManagerImpl::DeserializeMenu(const void *resData) const { PortabilityLayer::MemoryManager *mm = PortabilityLayer::MemoryManager::GetInstance(); @@ -334,21 +336,21 @@ namespace PortabilityLayer menu->layoutWidth = 0; menu->layoutHeight = 0; - return reinterpret_cast(&menuData->m_contents); + return THandle(menuData); } - Menu **MenuManagerImpl::GetMenuByID(int id) const + THandle MenuManagerImpl::GetMenuByID(int id) const { - for (Menu **menuHandle = m_firstMenu; menuHandle; menuHandle = (*menuHandle)->nextMenu) + for (THandle menuHandle = m_firstMenu; menuHandle; menuHandle = (*menuHandle)->nextMenu) { if ((*menuHandle)->menuID == id) return menuHandle; } - return nullptr; + return THandle(); } - void MenuManagerImpl::InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu) + void MenuManagerImpl::InsertMenuBefore(const THandle &insertingMenu, const THandle &existingMenu) { m_haveMenuBarLayout = false; @@ -366,7 +368,7 @@ namespace PortabilityLayer existingMenuPtr->prevMenu = insertingMenu; } - void MenuManagerImpl::InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu) + void MenuManagerImpl::InsertMenuAfter(const THandle &insertingMenu, const THandle &existingMenu) { m_haveMenuBarLayout = false; @@ -384,7 +386,7 @@ namespace PortabilityLayer existingMenuPtr->nextMenu = insertingMenu; } - void MenuManagerImpl::InsertMenuAtEnd(Menu **insertingMenu) + void MenuManagerImpl::InsertMenuAtEnd(const THandle &insertingMenu) { m_haveMenuBarLayout = false; @@ -399,7 +401,7 @@ namespace PortabilityLayer m_lastMenu = insertingMenu; } - void MenuManagerImpl::InsertMenuAtBeginning(Menu **insertingMenu) + void MenuManagerImpl::InsertMenuAtBeginning(const THandle &insertingMenu) { m_haveMenuBarLayout = false; @@ -414,14 +416,39 @@ namespace PortabilityLayer m_firstMenu = insertingMenu; } - void MenuManagerImpl::SetMenuEnabled(Menu **menuHandle, bool enabled) + void MenuManagerImpl::RemoveMenu(const THandle &menu) + { + DrawMenuBar(); + + Menu *menuPtr = *menu; + if (menuPtr->stringBlobHandle) + PortabilityLayer::MemoryManager::GetInstance()->ReleaseHandle(menuPtr->stringBlobHandle); + + if (menuPtr->prevMenu) + (*menuPtr->prevMenu)->nextMenu = menuPtr->nextMenu; + + if (menuPtr->nextMenu) + (*menuPtr->nextMenu)->prevMenu = menuPtr->prevMenu; + + if (m_firstMenu == menu) + m_firstMenu = menuPtr->nextMenu; + + if (m_lastMenu == menu) + m_lastMenu = menuPtr->prevMenu; + + menu.Dispose(); + + DrawMenuBar(); + } + + void MenuManagerImpl::SetMenuEnabled(const THandle &menuHandle, bool enabled) { Menu *menu = *menuHandle; menu->enabled = enabled; } - void MenuManagerImpl::SetItemEnabled(Menu **menuHandle, unsigned int index, bool enabled) + void MenuManagerImpl::SetItemEnabled(const THandle &menuHandle, unsigned int index, bool enabled) { Menu *menu = *menuHandle; @@ -431,7 +458,7 @@ namespace PortabilityLayer menu->menuItems[index].enabled = enabled; } - void MenuManagerImpl::SetItemChecked(Menu **menuHandle, unsigned int index, bool checked) + void MenuManagerImpl::SetItemChecked(const THandle &menuHandle, unsigned int index, bool checked) { Menu *menu = *menuHandle; @@ -710,6 +737,9 @@ namespace PortabilityLayer void MenuManagerImpl::SetMenuVisible(bool isVisible) { + if (isVisible && !m_menuBarVisible) + DrawMenuBar(); + m_menuBarVisible = isVisible; } @@ -919,8 +949,7 @@ namespace PortabilityLayer MenuManagerImpl MenuManagerImpl::ms_instance; MenuManagerImpl::MenuSelectionState::MenuSelectionState() - : m_currentMenu(nullptr) - , m_menuGraf(nullptr) + : m_menuGraf(nullptr) , m_haveItem(false) , m_itemIndex(0) { @@ -965,7 +994,7 @@ namespace PortabilityLayer m_haveItem = false; } - Menu **MenuManagerImpl::MenuSelectionState::GetSelectedMenu() const + THandle MenuManagerImpl::MenuSelectionState::GetSelectedMenu() const { return m_currentMenu; } diff --git a/PortabilityLayer/MenuManager.h b/PortabilityLayer/MenuManager.h index 725d52c..13bf109 100644 --- a/PortabilityLayer/MenuManager.h +++ b/PortabilityLayer/MenuManager.h @@ -1,5 +1,8 @@ #pragma once +template +class THandle; + #include struct IGpDisplayDriver; @@ -15,15 +18,19 @@ namespace PortabilityLayer virtual void Init() = 0; virtual void Shutdown() = 0; - virtual Menu **DeserializeMenu(const void *resData) const = 0; - virtual Menu **GetMenuByID(int id) const = 0; - virtual void InsertMenuBefore(Menu **insertingMenu, Menu **existingMenu) = 0; - virtual void InsertMenuAfter(Menu **insertingMenu, Menu **existingMenu) = 0; - virtual void InsertMenuAtEnd(Menu **insertingMenu) = 0; - virtual void InsertMenuAtBeginning(Menu **insertingMenu) = 0; - virtual void SetMenuEnabled(Menu **menuHandle, bool enabled) = 0; - virtual void SetItemEnabled(Menu **menu, unsigned int index, bool enabled) = 0; - virtual void SetItemChecked(Menu **menu, unsigned int index, bool checked) = 0; + virtual THandle DeserializeMenu(const void *resData) const = 0; + virtual THandle GetMenuByID(int id) const = 0; + + virtual void InsertMenuBefore(const THandle &insertingMenu, const THandle &existingMenu) = 0; + virtual void InsertMenuAfter(const THandle &insertingMenu, const THandle &existingMenu) = 0; + virtual void InsertMenuAtEnd(const THandle &insertingMenu) = 0; + virtual void InsertMenuAtBeginning(const THandle &insertingMenu) = 0; + + virtual void RemoveMenu(const THandle &menu) = 0; + + virtual void SetMenuEnabled(const THandle &menuHandle, bool enabled) = 0; + virtual void SetItemEnabled(const THandle &menu, unsigned int index, bool enabled) = 0; + virtual void SetItemChecked(const THandle &menu, unsigned int index, bool checked) = 0; virtual bool IsPointInMenuBar(const Vec2i &point) const = 0; diff --git a/PortabilityLayer/PLCore.cpp b/PortabilityLayer/PLCore.cpp index b13a400..93659b5 100644 --- a/PortabilityLayer/PLCore.cpp +++ b/PortabilityLayer/PLCore.cpp @@ -287,7 +287,7 @@ void ShowWindow(WindowPtr window) void SetWTitle(WindowPtr window, const PLPasStr &title) { - PL_NotYetImplemented(); + PL_NotYetImplemented_TODO("Editor"); } long MenuSelect(Point point) diff --git a/PortabilityLayer/PLHandle.cpp b/PortabilityLayer/PLHandle.cpp index 7985766..ea75390 100644 --- a/PortabilityLayer/PLHandle.cpp +++ b/PortabilityLayer/PLHandle.cpp @@ -2,10 +2,8 @@ #include "MemoryManager.h" -void THandleBase::Dispose() +void THandleBase::Dispose() const { if (m_hdl) PortabilityLayer::MemoryManager::GetInstance()->ReleaseHandle(m_hdl); - - m_hdl = nullptr; } diff --git a/PortabilityLayer/PLHandle.h b/PortabilityLayer/PLHandle.h index 47dab83..6485b2b 100644 --- a/PortabilityLayer/PLHandle.h +++ b/PortabilityLayer/PLHandle.h @@ -13,7 +13,7 @@ public: PortabilityLayer::MMHandleBlock *MMBlock() const; - void Dispose(); + void Dispose() const; protected: PortabilityLayer::MMHandleBlock *m_hdl; diff --git a/PortabilityLayer/PLImageWidget.cpp b/PortabilityLayer/PLImageWidget.cpp new file mode 100644 index 0000000..811d5fa --- /dev/null +++ b/PortabilityLayer/PLImageWidget.cpp @@ -0,0 +1,31 @@ +#include "PLImageWidget.h" +#include "PLQDraw.h" +#include "ResourceManager.h" + +namespace PortabilityLayer +{ + ImageWidget::ImageWidget(const WidgetBasicState &state) + : WidgetSpec(state) + { + } + + ImageWidget::~ImageWidget() + { + } + + bool ImageWidget::Init(const WidgetBasicState &state) + { + m_pict = PortabilityLayer::ResourceManager::GetInstance()->GetResource('PICT', state.m_resID).StaticCast(); + + if (!m_pict) + return false; + + return true; + } + + void ImageWidget::DrawControl(DrawSurface *surface) + { + if (m_pict && m_rect.IsValid()) + surface->DrawPicture(m_pict, m_rect); + } +} diff --git a/PortabilityLayer/PLImageWidget.h b/PortabilityLayer/PLImageWidget.h new file mode 100644 index 0000000..9da1979 --- /dev/null +++ b/PortabilityLayer/PLImageWidget.h @@ -0,0 +1,22 @@ +#pragma once + +#include "PLWidgets.h" +#include "PLHandle.h" + +struct Picture; + +namespace PortabilityLayer +{ + class ImageWidget final : public WidgetSpec + { + public: + ImageWidget(const WidgetBasicState &state); + ~ImageWidget(); + + bool Init(const WidgetBasicState &state) override; + void DrawControl(DrawSurface *surface) override; + + private: + THandle m_pict; + }; +} diff --git a/PortabilityLayer/PLMenus.cpp b/PortabilityLayer/PLMenus.cpp index d79c75b..4c966d1 100644 --- a/PortabilityLayer/PLMenus.cpp +++ b/PortabilityLayer/PLMenus.cpp @@ -48,21 +48,6 @@ void InsertMenu(MenuHandle menu, int beforeID) mm->InsertMenuAtEnd(menu); } -void DeleteMenu(int menuID) -{ - PL_NotYetImplemented(); -} - -void DrawMenuBar() -{ - PortabilityLayer::MenuManager::GetInstance()->DrawMenuBar(); -} - -void HiliteMenu(int menu) -{ - // Don't know what this does -} - void EnableMenuItem(MenuHandle menu, int index) { PortabilityLayer::MenuManager *mm = PortabilityLayer::MenuManager::GetInstance(); diff --git a/PortabilityLayer/PLMenus.h b/PortabilityLayer/PLMenus.h index ad026b9..68fdf12 100644 --- a/PortabilityLayer/PLMenus.h +++ b/PortabilityLayer/PLMenus.h @@ -8,9 +8,6 @@ class PLPasStr; MenuHandle GetMenu(int resID); void InsertMenu(MenuHandle menu, int beforeID); -void DeleteMenu(int menuID); // ??? -void DrawMenuBar(); -void HiliteMenu(int menu); void EnableMenuItem(MenuHandle menu, int index); void DisableMenuItem(MenuHandle menu, int index); diff --git a/PortabilityLayer/PLQDOffscreen.cpp b/PortabilityLayer/PLQDOffscreen.cpp index 01050df..384f5fe 100644 --- a/PortabilityLayer/PLQDOffscreen.cpp +++ b/PortabilityLayer/PLQDOffscreen.cpp @@ -36,7 +36,7 @@ PixMapHandle GetGWorldPixMap(DrawSurface *gworld) return gworld->m_port.GetPixMap(); } -PicHandle GetPicture(short resID) +THandle GetPicture(short resID) { return PortabilityLayer::ResourceManager::GetInstance()->GetResource('PICT', resID).StaticCast(); } diff --git a/PortabilityLayer/PLQDOffscreen.h b/PortabilityLayer/PLQDOffscreen.h index ea2d3e8..1230e55 100644 --- a/PortabilityLayer/PLQDOffscreen.h +++ b/PortabilityLayer/PLQDOffscreen.h @@ -17,20 +17,12 @@ typedef CTabPtr *CTabHandle; typedef PixMap *PixMapPtr; typedef PixMapPtr *PixMapHandle; -typedef Picture *PicPtr; -typedef THandle PicHandle; - -enum QDFlags -{ - useTempMem = 1, -}; - PLError_t NewGWorld(DrawSurface **gworld, GpPixelFormat_t pixelFormat, const Rect *bounds, CTabHandle colorTable); void DisposeGWorld(DrawSurface *gworld); PixMapHandle GetGWorldPixMap(DrawSurface *gworld); -PicHandle GetPicture(short resID); +THandle GetPicture(short resID); void OffsetRect(Rect *rect, int right, int down); diff --git a/PortabilityLayer/PLQDraw.cpp b/PortabilityLayer/PLQDraw.cpp index 85a6390..08e774d 100644 --- a/PortabilityLayer/PLQDraw.cpp +++ b/PortabilityLayer/PLQDraw.cpp @@ -655,6 +655,9 @@ void DrawSurface::DrawPicture(THandle pictHdl, const Rect &bounds) if (!pictHdl) return; + if (!bounds.IsValid() || bounds.Width() == 0 || bounds.Height() == 0) + return; + Picture *picPtr = *pictHdl; if (!picPtr) return; @@ -663,8 +666,27 @@ void DrawSurface::DrawPicture(THandle pictHdl, const Rect &bounds) if (bounds.right - bounds.left != picRect.right - picRect.left || bounds.bottom - bounds.top != picRect.bottom - picRect.top) { - // Scaled pict draw (not supported) - assert(false); + PL_NotYetImplemented_TODO("Palette"); + + DrawSurface *scaleSurface = nullptr; + if (PortabilityLayer::QDManager::GetInstance()->NewGWorld(&scaleSurface, this->m_port.GetPixelFormat(), picRect, nullptr) != PLErrors::kNone) + return; + + scaleSurface->DrawPicture(pictHdl, picRect); + + const uint16_t newWidth = bounds.Width(); + const uint16_t newHeight = bounds.Height(); + + THandle scaled = static_cast(*scaleSurface->m_port.GetPixMap())->ScaleTo(newWidth, newHeight); + PortabilityLayer::QDManager::GetInstance()->DisposeGWorld(scaleSurface); + + if (scaled) + CopyBits(*scaled, *this->m_port.GetPixMap(), &(*scaled)->m_rect, &bounds, srcCopy); + + PortabilityLayer::PixMapImpl::Destroy(scaled); + + m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents); + return; } @@ -697,6 +719,8 @@ void DrawSurface::DrawPicture(THandle pictHdl, const Rect &bounds) assert(false); return; }; + + m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents); } diff --git a/PortabilityLayer/PLWidgets.cpp b/PortabilityLayer/PLWidgets.cpp index ccb05e1..29ef8d5 100644 --- a/PortabilityLayer/PLWidgets.cpp +++ b/PortabilityLayer/PLWidgets.cpp @@ -40,6 +40,11 @@ namespace PortabilityLayer (void)style; } + void Widget::SetString(const PLPasStr &str) + { + (void)str; + } + const Rect &Widget::GetRect() const { return m_rect; diff --git a/PortabilityLayer/PLWidgets.h b/PortabilityLayer/PLWidgets.h index 14a1b5c..b4ff0ff 100644 --- a/PortabilityLayer/PLWidgets.h +++ b/PortabilityLayer/PLWidgets.h @@ -44,6 +44,7 @@ namespace PortabilityLayer void SetEnabled(bool enabled); void SetState(int16_t state); + virtual void SetString(const PLPasStr &str); virtual void SetHighlightStyle(int16_t style); const Rect &GetRect() const; diff --git a/PortabilityLayer/PortabilityLayer.vcxproj b/PortabilityLayer/PortabilityLayer.vcxproj index 4fec850..5b7f44e 100644 --- a/PortabilityLayer/PortabilityLayer.vcxproj +++ b/PortabilityLayer/PortabilityLayer.vcxproj @@ -200,6 +200,7 @@ + @@ -310,6 +311,7 @@ + diff --git a/PortabilityLayer/PortabilityLayer.vcxproj.filters b/PortabilityLayer/PortabilityLayer.vcxproj.filters index f17e071..c56141b 100644 --- a/PortabilityLayer/PortabilityLayer.vcxproj.filters +++ b/PortabilityLayer/PortabilityLayer.vcxproj.filters @@ -435,6 +435,9 @@ Header Files + + Header Files + @@ -671,5 +674,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/PortabilityLayer/QDPixMap.cpp b/PortabilityLayer/QDPixMap.cpp index 22c813f..35f1e00 100644 --- a/PortabilityLayer/QDPixMap.cpp +++ b/PortabilityLayer/QDPixMap.cpp @@ -4,6 +4,175 @@ #include +class PixMapSampler_8BitStandard +{ +public: + inline static uint8_t ReadAs8BitStandard(const void *rowData, size_t index) + { + return static_cast(rowData)[index]; + } +}; + +template +class PixMapCopier_8BitStandard +{ +public: + inline static void Copy(const void *inData, size_t inIndex, void *outData, size_t outIndex) + { + static_cast(outData)[outIndex] = TSampler::ReadAs8BitStandard(inData, inIndex); + } +}; + +template +class PixMapColBlitter +{ +public: + static void BlitRow(const void *inData, size_t inSize, void *outData, size_t outSize) + { + if (inSize == outSize) + { + for (size_t i = 0; i < inSize; i++) + TCopier::Copy(inData, i, outData, i); + } + else if (inSize < outSize) + { + size_t remainder = 0; + size_t inIndex = 0; + for (size_t i = 0; i < outSize; i++) + { + TCopier::Copy(inData, inIndex, outData, i); + + remainder += inSize; + if (remainder >= outSize) + { + remainder -= outSize; + inIndex++; + } + } + } + else //if (outSize < inSize) + { + size_t remainder = 0; + size_t outIndex = 0; + for (size_t i = 0; i < inSize; i++) + { + remainder += outSize; + if (remainder >= inSize) + { + TCopier::Copy(inData, i, outData, outIndex); + + remainder -= inSize; + outIndex++; + } + } + } + } +}; + +template +class PixMapRowBlitter +{ +public: + static void Blit(const void *inData, size_t inPitch, size_t inColCount, size_t inRowCount, void *outData, size_t outPitch, size_t outColCount, size_t outRowCount) + { + if (inRowCount == outRowCount) + { + for (size_t i = 0; i < inRowCount; i++) + { + PixMapColBlitter::BlitRow(inData, inColCount, outData, outColCount); + + inData = static_cast(inData) + inPitch; + outData = static_cast(outData) + outPitch; + } + } + else if (inRowCount < outRowCount) + { + size_t remainder = 0; + size_t inIndex = 0; + for (size_t i = 0; i < outRowCount; i++) + { + PixMapColBlitter::BlitRow(inData, inColCount, outData, outColCount); + + remainder += inRowCount; + if (remainder >= outRowCount) + { + remainder -= outRowCount; + inData = static_cast(inData) + inPitch; + } + + outData = static_cast(outData) + outPitch; + } + } + else //if(outRowCount < inRowCount) + { + size_t remainder = 0; + size_t outIndex = 0; + for (size_t i = 0; i < inRowCount; i++) + { + remainder += outRowCount; + if (remainder >= inRowCount) + { + PixMapColBlitter::BlitRow(inData, inColCount, outData, outColCount); + + remainder -= inRowCount; + outData = static_cast(outData) + outPitch; + } + + inData = static_cast(inData) + inPitch; + } + } + } +}; + +template +class PixMapBlitTargetDisambiguator +{ +public: + static void Blit(const void *inData, size_t inPitch, size_t inColCount, size_t inRowCount, void *outData, size_t outPitch, size_t outColCount, size_t outRowCount, GpPixelFormat_t destFormat) + { + void(*blitFunc)(const void *inData, size_t inPitch, size_t inColCount, size_t inRowCount, void *outData, size_t outPitch, size_t outColCount, size_t outRowCount); + + blitFunc = nullptr; + + switch (destFormat) + { + case GpPixelFormats::k8BitStandard: + blitFunc = PixMapRowBlitter >::Blit; + break; + default: + PL_NotYetImplemented(); + break; + } + + if (blitFunc != nullptr) + blitFunc(inData, inPitch, inColCount, inRowCount, outData, outPitch, outColCount, outRowCount); + } +}; + +class PixMapBlitSourceDisambiguator +{ +public: + static void Blit(const void *inData, size_t inPitch, size_t inColCount, size_t inRowCount, GpPixelFormat_t srcFormat, void *outData, size_t outPitch, size_t outColCount, size_t outRowCount, GpPixelFormat_t destFormat) + { + void(*blitFunc)(const void *inData, size_t inPitch, size_t inColCount, size_t inRowCount, void *outData, size_t outPitch, size_t outColCount, size_t outRowCount, GpPixelFormat_t srcFormat); + + blitFunc = nullptr; + + switch (srcFormat) + { + case GpPixelFormats::k8BitStandard: + blitFunc = PixMapBlitTargetDisambiguator::Blit; + break; + default: + PL_NotYetImplemented(); + break; + } + + if (blitFunc != nullptr) + blitFunc(inData, inPitch, inColCount, inRowCount, outData, outPitch, outColCount, outRowCount, srcFormat); + } +}; + namespace PortabilityLayer { void PixMapImpl::Destroy(THandle &hdl) @@ -102,6 +271,30 @@ namespace PortabilityLayer return THandle(pmBlock); } + + + THandle PixMapImpl::ScaleTo(uint16_t width, uint16_t height) + { + // Stupid stuff to cover the entire numeric range + Rect scaledRect; + scaledRect.right = static_cast(width / 2); + scaledRect.bottom = static_cast(height / 2); + scaledRect.top = static_cast(scaledRect.bottom - height); + scaledRect.left = static_cast(scaledRect.right - width); + + THandle scaled = PixMapImpl::Create(scaledRect, m_pixelFormat); + if (!scaled) + return THandle(); + + PixMapImpl *destPixMap = *scaled; + + const uint16_t oldWidth = m_rect.Width(); + const uint16_t oldHeight = m_rect.Height(); + + PixMapBlitSourceDisambiguator::Blit(GetPixelData(), m_pitch, m_rect.Width(), m_rect.Height(), m_pixelFormat, destPixMap->GetPixelData(), destPixMap->GetPitch(), width, height, m_pixelFormat); + + return scaled; + } } 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 8c9ec55..21978e4 100644 --- a/PortabilityLayer/QDPixMap.h +++ b/PortabilityLayer/QDPixMap.h @@ -24,6 +24,8 @@ namespace PortabilityLayer const void *GetPixelData() const; size_t GetDataCapacity() const; + THandle ScaleTo(uint16_t width, uint16_t height); + static THandle Create(const Rect &rect, GpPixelFormat_t pixelFormat); static size_t SizeForDimensions(uint16_t width, uint16_t height, GpPixelFormat_t pixelFormat);