diff --git a/Aerofoil/GpMain_Win32.cpp b/Aerofoil/GpMain_Win32.cpp index b37af5e..85e007a 100644 --- a/Aerofoil/GpMain_Win32.cpp +++ b/Aerofoil/GpMain_Win32.cpp @@ -429,6 +429,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine g_gpWindowsGlobals.m_translateWindowsMessageFunc = TranslateWindowsMessage; g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_D3D11; + g_gpGlobalConfig.m_audioDriverType = EGpAudioDriverType_XAudio2; EGpInputDriverType inputDrivers[] = diff --git a/ApplicationResourcePatches/DITL/1017.json b/ApplicationResourcePatches/DITL/1017.json index 5b7acba..bddf945 100644 --- a/ApplicationResourcePatches/DITL/1017.json +++ b/ApplicationResourcePatches/DITL/1017.json @@ -73,6 +73,14 @@ "id" : 0, "enabled" : true }, + { + "name" : "32-bit color (Requires restart)", + "itemType" : "CheckBox", + "pos" : [ 8, 162 ], + "size" : [ 256, 18 ], + "id" : 0, + "enabled" : true + }, { "name" : "", "itemType" : "UserItem", diff --git a/GpApp/Banner.cpp b/GpApp/Banner.cpp index 0a6f813..ff7979a 100644 --- a/GpApp/Banner.cpp +++ b/GpApp/Banner.cpp @@ -68,10 +68,10 @@ void DrawBanner (Point *topLeft) partPage.top = partPage.bottom - 30; mapBounds = partPage; ZeroRectCorner(&mapBounds); - theErr = CreateOffScreenGWorld(&tempMap, &mapBounds, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &mapBounds); LoadGraphicCustom(tempMap, kBannerPageBottomPICT); - theErr = CreateOffScreenGWorld(&tempMask, &mapBounds, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&tempMask, &mapBounds, GpPixelFormats::kBW1); LoadGraphicCustom(tempMask, kBannerPageBottomMask); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), diff --git a/GpApp/DynamicMaps.cpp b/GpApp/DynamicMaps.cpp index 6262cc1..633e9fa 100644 --- a/GpApp/DynamicMaps.cpp +++ b/GpApp/DynamicMaps.cpp @@ -82,7 +82,7 @@ short BackUpToSavedMap (Rect *theRect, SInt16 where, SInt16 who, SInt16 componen ZeroRectCorner(&mapRect); savedMaps[numSavedMaps].dest = *theRect; // CreateOffScreenPixMap(&mapRect, &savedMaps[numSavedMaps].map); - theErr = CreateOffScreenGWorld(&savedMaps[numSavedMaps].map, &mapRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&savedMaps[numSavedMaps].map, &mapRect); CopyBits((BitMap *)*GetGWorldPixMap(backSrcMap), GetPortBitMapForCopyBits(savedMaps[numSavedMaps].map), diff --git a/GpApp/Environ.cpp b/GpApp/Environ.cpp index 656cef5..74119f3 100644 --- a/GpApp/Environ.cpp +++ b/GpApp/Environ.cpp @@ -207,30 +207,6 @@ Boolean DoWeHaveDragManager (void) return true; } -//-------------------------------------------------------------- WhatsOurDepth - -// Determines the pixel bit depth for current device (monitor). - -short WhatsOurDepth (void) -{ - GpPixelFormat_t pixelFormat; - PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(nil, nil, &pixelFormat); - - switch (pixelFormat) - { - case GpPixelFormats::k8BitCustom: - case GpPixelFormats::k8BitStandard: - return 8; - case GpPixelFormats::kRGB555: - return 16; - case GpPixelFormats::kRGB24: - case GpPixelFormats::kRGB32: - return 32; - default: - return 0; - } -} - void SwitchToDepth (short, Boolean) { } @@ -321,9 +297,6 @@ void CheckOurEnvirons (void) thisMac.can4Bit = true; thisMac.can8Bit = true; thisMac.numScreens = HowManyUsableScreens(false, true, true); - - thisMac.wasDepth = WhatsOurDepth(); - thisMac.wasColorOrGray = AreWeColorOrGrayscale(); thisMac.isResolutionDirty = true; FlushResolutionChange(); @@ -417,53 +390,21 @@ void ReflectSecondMonitorEnvirons (Boolean use1Bit, Boolean use4Bit, Boolean use void HandleDepthSwitching (void) { - if (thisMac.hasColor) + switch (isDepthPref) { - switch (isDepthPref) - { - case kSwitchIfNeeded: - if ((thisMac.wasDepth != 8) && - ((thisMac.wasDepth != 4) || (thisMac.wasColorOrGray))) - SwitchDepthOrAbort(); - break; - - case kSwitchTo256Colors: - if (thisMac.wasDepth != 8) - { - if (thisMac.can8Bit) - SwitchToDepth(8, true); - else - SwitchDepthOrAbort(); - } - break; - - case kSwitchTo16Grays: - if ((thisMac.wasDepth != 4) || (thisMac.wasColorOrGray)) - { - if (thisMac.can4Bit) - SwitchToDepth(4, false); - else - SwitchDepthOrAbort(); - } - break; - - default: - break; - } + case 32: + PortabilityLayer::DisplayDeviceManager::GetInstance()->SetPixelFormat(GpPixelFormats::kRGB32); + break; + case 8: + PortabilityLayer::DisplayDeviceManager::GetInstance()->SetPixelFormat(GpPixelFormats::k8BitStandard); + break; + default: + isDepthPref = 8; + PortabilityLayer::DisplayDeviceManager::GetInstance()->SetPixelFormat(GpPixelFormats::k8BitStandard); + break; } - - thisMac.isDepth = WhatsOurDepth(); -} -//-------------------------------------------------------------- RestoreColorDepth - -// Restores a monitor to its previous depth when we quit (if we changed it). - -void RestoreColorDepth (void) -{ - if ((thisMac.hasColor) && ((thisMac.wasDepth != thisMac.isDepth) || - (thisMac.wasColorOrGray != AreWeColorOrGrayscale()))) - SwitchToDepth(thisMac.wasDepth, true); + thisMac.isDepth = isDepthPref; } //-------------------------------------------------------------- CheckMemorySize @@ -574,7 +515,7 @@ void GetDeviceRect(Rect *rect) { unsigned int width; unsigned int height; - PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(&width, &height, nil); + PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(&width, &height); SetRect(rect, 0, 0, static_cast(width), static_cast(height)); } diff --git a/GpApp/Environ.h b/GpApp/Environ.h index 7a40b28..f596c92 100644 --- a/GpApp/Environ.h +++ b/GpApp/Environ.h @@ -12,7 +12,7 @@ typedef struct { Rect fullScreen, constrainedScreen, gray; long dirID; - short wasDepth, isDepth; + short isDepth; short numScreens; short vRefNum; Boolean can1Bit; diff --git a/GpApp/Externs.h b/GpApp/Externs.h index 0c5e33a..721445f 100644 --- a/GpApp/Externs.h +++ b/GpApp/Externs.h @@ -21,10 +21,6 @@ namespace PortabilityLayer class RenderedFont; } -#define kPreferredDepth 8 -#define kPreferredPixelFormat (GpPixelFormats::k8BitStandard) - - #define kNilPointer 0L #define kPutInFront (PL_GetPutInFrontWindowPtr()) #define kNormalUpdates TRUE @@ -168,15 +164,12 @@ void DumpToResEditFile (Ptr, long); void HandleEvent (void); // --- Event.c void IgnoreThisClick (void); -short WhatsOurDepth (void); // --- Environs.c -void SwitchToDepth (short, Boolean); +void SwitchToDepth (short, Boolean); // --- Environs.c void CheckOurEnvirons (void); void InstallResolutionHandler (void); //void ReflectSecondMonitorEnvirons (Boolean, Boolean, Boolean); void HandleDepthSwitching (void); -void RestoreColorDepth (void); void CheckMemorySize (void); -void SetAppMemorySize (long); Boolean CheckFileError (short, const PLPasStr &); // --- File Error.c diff --git a/GpApp/GameOver.cpp b/GpApp/GameOver.cpp index 08e65d3..d93cb45 100644 --- a/GpApp/GameOver.cpp +++ b/GpApp/GameOver.cpp @@ -278,14 +278,14 @@ void InitDiedGameOver (void) PLError_t theErr; QSetRect(&pageSrcRect, 0, 0, 25, 32 * 8); - theErr = CreateOffScreenGWorld(&gameOverSrcMap, &pageSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&gameOverSrcMap, &pageSrcRect); LoadGraphic(gameOverSrcMap, kLettersPictID); QSetRect(&pageSrcRect, 0, 0, 32, 32 * kPageFrames); - theErr = CreateOffScreenGWorld(&pageSrcMap, &pageSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&pageSrcMap, &pageSrcRect); LoadGraphic(pageSrcMap, kPagesPictID); - theErr = CreateOffScreenGWorld(&pageMaskMap, &pageSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&pageMaskMap, &pageSrcRect, GpPixelFormats::kBW1); LoadGraphic(pageMaskMap, kPagesMaskID); for (i = 0; i < kPageFrames; i++) // initialize src page rects diff --git a/GpApp/GliderDefines.h b/GpApp/GliderDefines.h index 3d3dbe3..ce15852 100644 --- a/GpApp/GliderDefines.h +++ b/GpApp/GliderDefines.h @@ -41,8 +41,6 @@ #define kYellowCantOrderLinks 24 #define kSwitchIfNeeded 0 -#define kSwitchTo256Colors 1 -#define kSwitchTo16Grays 2 #define kProdGameScoreMode -4 #define kKickGameScoreMode -3 diff --git a/GpApp/HighScores.cpp b/GpApp/HighScores.cpp index 05ab080..1027187 100644 --- a/GpApp/HighScores.cpp +++ b/GpApp/HighScores.cpp @@ -131,10 +131,10 @@ void DrawHighScores (DrawSurface *surface) dropIt = 129 + splashOriginV; QSetRect(&tempRect, 0, 0, 332, 30); - theErr = CreateOffScreenGWorld(&tempMap, &tempRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &tempRect); LoadGraphic(tempMap, kHighScoresPictID); - theErr = CreateOffScreenGWorld(&tempMask, &tempRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&tempMask, &tempRect, GpPixelFormats::kBW1); LoadGraphic(tempMask, kHighScoresMaskID); tempRect2 = tempRect; diff --git a/GpApp/Main.cpp b/GpApp/Main.cpp index 60cd7c6..41d3373 100644 --- a/GpApp/Main.cpp +++ b/GpApp/Main.cpp @@ -395,7 +395,6 @@ int gpAppMain() } } WriteOutPrefs(); - RestoreColorDepth(); PL_DEAD(FlushEvents()); // theErr = LoadScrap(); diff --git a/GpApp/Map.cpp b/GpApp/Map.cpp index 1db7bf5..cc57f63 100644 --- a/GpApp/Map.cpp +++ b/GpApp/Map.cpp @@ -762,7 +762,7 @@ void CreateNailOffscreen (void) if (nailSrcMap == nil) { QSetRect(&nailSrcRect, 0, 0, kMapRoomWidth, kMapRoomHeight * (kNumBackgrounds + 1)); - theErr = CreateOffScreenGWorld(&nailSrcMap, &nailSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&nailSrcMap, &nailSrcRect); LoadGraphic(nailSrcMap, kThumbnailPictID); } diff --git a/GpApp/ObjectDraw2.cpp b/GpApp/ObjectDraw2.cpp index 8fb55bb..a3d1cd0 100644 --- a/GpApp/ObjectDraw2.cpp +++ b/GpApp/ObjectDraw2.cpp @@ -169,10 +169,10 @@ void DrawMailboxLeft (Rect *theRect, short down) } bounds = srcRects[kMailboxLf]; - theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &bounds); LoadGraphic(tempMap, kMailboxLeftPictID); - theErr = CreateOffScreenGWorld(&tempMask, &bounds, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&tempMask, &bounds, GpPixelFormats::kBW1); LoadGraphic(tempMask, kMailboxLeftMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), @@ -241,10 +241,10 @@ void DrawMailboxRight (Rect *theRect, short down) } bounds = srcRects[kMailboxRt]; - theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &bounds); LoadGraphic(tempMap, kMailboxRightPictID); - theErr = CreateOffScreenGWorld(&tempMask, &bounds, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&tempMask, &bounds, GpPixelFormats::kBW1); LoadGraphic(tempMask, kMailboxRightMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), @@ -604,10 +604,10 @@ void DrawTV (Rect *theRect, Boolean isOn, Boolean isLit) if (isLit) { bounds = srcRects[kTV]; - theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &bounds); LoadGraphic(tempMap, kTVPictID); - theErr = CreateOffScreenGWorld(&tempMask, &bounds, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&tempMask, &bounds, GpPixelFormats::kBW1); LoadGraphic(tempMask, kTVMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), @@ -690,10 +690,10 @@ void DrawVCR (Rect *theRect, Boolean isOn, Boolean isLit) if (isLit) { bounds = srcRects[kVCR]; - theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &bounds); LoadGraphic(tempMap, kVCRPictID); - theErr = CreateOffScreenGWorld(&tempMask, &bounds, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&tempMask, &bounds, GpPixelFormats::kBW1); LoadGraphic(tempMask, kVCRMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), @@ -737,10 +737,10 @@ void DrawStereo (Rect *theRect, Boolean isOn, Boolean isLit) if (isLit) { bounds = srcRects[kStereo]; - theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &bounds); LoadGraphic(tempMap, kStereoPictID); - theErr = CreateOffScreenGWorld(&tempMask, &bounds, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&tempMask, &bounds, GpPixelFormats::kBW1); LoadGraphic(tempMask, kStereoMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), @@ -784,10 +784,10 @@ void DrawMicrowave (Rect *theRect, Boolean isOn, Boolean isLit) if (isLit) { bounds = srcRects[kMicrowave]; - theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &bounds); LoadGraphic(tempMap, kMicrowavePictID); - theErr = CreateOffScreenGWorld(&tempMask, &bounds, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&tempMask, &bounds, GpPixelFormats::kBW1); LoadGraphic(tempMask, kMicrowaveMaskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), @@ -1162,10 +1162,10 @@ void DrawPictWithMaskObject (short what, Rect *theRect) } bounds = srcRects[what]; - theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &bounds); LoadGraphic(tempMap, pictID); - theErr = CreateOffScreenGWorld(&tempMask, &bounds, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&tempMask, &bounds, GpPixelFormats::kBW1); LoadGraphic(tempMask, maskID); CopyMask((BitMap *)*GetGWorldPixMap(tempMap), @@ -1273,7 +1273,7 @@ void DrawPictSansWhiteObject (short what, Rect *theRect) } bounds = srcRects[what]; - theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &bounds); LoadGraphic(tempMap, pictID); CopyBits((BitMap *)*GetGWorldPixMap(tempMap), @@ -1293,7 +1293,7 @@ void DrawCustPictSansWhite (short pictID, Rect *theRect) bounds = *theRect; ZeroRectCorner(&bounds); - theErr = CreateOffScreenGWorld(&tempMap, &bounds, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tempMap, &bounds); LoadGraphicCustom(tempMap, pictID); CopyBits((BitMap *)*GetGWorldPixMap(tempMap), diff --git a/GpApp/RoomInfo.cpp b/GpApp/RoomInfo.cpp index 7e54fc6..e717faf 100644 --- a/GpApp/RoomInfo.cpp +++ b/GpApp/RoomInfo.cpp @@ -436,7 +436,7 @@ void DoRoomInfo(void) NumToString(thisRoom->numObjects, objectsStr); DialogTextSubstitutions substitutions(floorStr, suiteStr, objectsStr); - theErr = CreateOffScreenGWorld(&tileSrcMap, &tileSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&tileSrcMap, &tileSrcRect); // CreateOffScreenPixMap(&tileSrcRect, &tileSrcMap); // SetPort((GrafPtr)tileSrcMap); if ((tempBack > kStars) && (!PictIDExists(tempBack))) diff --git a/GpApp/Settings.cpp b/GpApp/Settings.cpp index 91de993..345a620 100644 --- a/GpApp/Settings.cpp +++ b/GpApp/Settings.cpp @@ -34,12 +34,12 @@ #define kDisplay9Item 5 #define kBorder1Item 8 #define kDoColorFadeItem 9 -//#define kCurrentDepth 10 +#define k32BitColorItem 10 //#define k256Depth 11 //#define k16Depth 12 -#define kBorder2Item 10 -#define kBorder3Item 11 -#define kDispDefault 12 +#define kBorder2Item 11 +#define kBorder3Item 12 +#define kDispDefault 13 //#define kUseQDItem 13 //#define kUseScreen2Item 14 #define kSofterItem 4 @@ -906,6 +906,7 @@ void DisplayUpdate (Dialog *theDialog) DrawDefaultButton(theDialog); SetDialogItemValue(theDialog, kDoColorFadeItem, (short)wasFade); + SetDialogItemValue(theDialog, k32BitColorItem, wasDepthPref == 32); FrameDisplayIcon(theDialog, StdColors::Red()); FrameDialogItemC(theDialog, kBorder1Item, kRedOrangeColor8); @@ -1001,9 +1002,6 @@ void DoDisplayPrefs (void) BringUpDialog(&prefDlg, kDisplayPrefsDialID, nullptr); - if (!thisMac.can8Bit) - MyDisableControl(prefDlg, kDoColorFadeItem); - wasNeighbors = numNeighbors; wasFade = isDoColorFade; wasDepthPref = isDepthPref; @@ -1060,6 +1058,14 @@ void DoDisplayPrefs (void) SetDialogItemValue(prefDlg, kDoColorFadeItem, (short)wasFade); break; + case k32BitColorItem: + if (wasDepthPref == 32) + wasDepthPref = 8; + else + wasDepthPref = 32; + SetDialogItemValue(prefDlg, k32BitColorItem, wasDepthPref == 32); + break; + case kDispDefault: FrameDisplayIcon(prefDlg, StdColors::White()); DisplayDefaults(); diff --git a/GpApp/StructuresInit.cpp b/GpApp/StructuresInit.cpp index f0954a4..42fb6b3 100644 --- a/GpApp/StructuresInit.cpp +++ b/GpApp/StructuresInit.cpp @@ -73,7 +73,7 @@ void InitScoreboardMap(void) boardSrcRect = houseRect; ZeroRectCorner(&boardSrcRect); boardSrcRect.bottom = kScoreboardTall; - theErr = CreateOffScreenGWorld(&boardSrcMap, &boardSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&boardSrcMap, &boardSrcRect); if (boardSrcRect.right >= 640) hOffset = (RectWide(&boardSrcRect) - kMaxViewWidth) / 2; @@ -91,7 +91,7 @@ void InitScoreboardMap(void) QSetRect(&badgeSrcRect, 0, 0, 32, 66); // 2144 pixels if (!badgeSrcMap) { - theErr = CreateOffScreenGWorld(&badgeSrcMap, &badgeSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&badgeSrcMap, &badgeSrcRect); LoadGraphic(badgeSrcMap, kBadgePictID); } @@ -104,7 +104,7 @@ void InitScoreboardMap(void) QSetRect(&boardTSrcRect, 0, 0, 256, 12); // room title if (!boardTSrcMap) { - theErr = CreateOffScreenGWorld(&boardTSrcMap, &boardTSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&boardTSrcMap, &boardTSrcRect); } boardTDestRect = boardTSrcRect; QOffsetRect(&boardTDestRect, 137 + hOffset, 5); @@ -112,7 +112,7 @@ void InitScoreboardMap(void) QSetRect(&boardGSrcRect, 0, 0, 20, 10); // # gliders if (!boardGSrcMap) { - theErr = CreateOffScreenGWorld(&boardGSrcMap, &boardGSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&boardGSrcMap, &boardGSrcRect); } boardGDestRect = boardGSrcRect; QOffsetRect(&boardGDestRect, 526 + hOffset, 5); @@ -121,7 +121,7 @@ void InitScoreboardMap(void) QSetRect(&boardPSrcRect, 0, 0, 64, 10); // points if (!boardPSrcMap) { - theErr = CreateOffScreenGWorld(&boardPSrcMap, &boardPSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&boardPSrcMap, &boardPSrcRect); } boardPDestRect = boardPSrcRect; QOffsetRect(&boardPDestRect, 570 + hOffset, 5); // total = 6396 pixels @@ -166,13 +166,13 @@ void InitGliderMap (void) short i; QSetRect(&glidSrcRect, 0, 0, kGliderWide, 668); // 32112 pixels - theErr = CreateOffScreenGWorld(&glidSrcMap, &glidSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&glidSrcMap, &glidSrcRect); LoadGraphic(glidSrcMap, kGliderPictID); - theErr = CreateOffScreenGWorld(&glid2SrcMap, &glidSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&glid2SrcMap, &glidSrcRect); LoadGraphic(glid2SrcMap, kGlider2PictID); - theErr = CreateOffScreenGWorld(&glidMaskMap, &glidSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&glidMaskMap, &glidSrcRect, GpPixelFormats::kBW1); LoadGraphic(glidMaskMap, kGliderPictID + 1000); for (i = 0; i <= 20; i++) @@ -192,10 +192,10 @@ void InitGliderMap (void) QOffsetRect(&gliderSrc[30], 0, 648); QSetRect(&shadowSrcRect, 0, 0, kGliderWide, kShadowHigh * kNumShadowSrcRects); - theErr = CreateOffScreenGWorld(&shadowSrcMap, &shadowSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&shadowSrcMap, &shadowSrcRect); LoadGraphic(shadowSrcMap, kShadowPictID); - theErr = CreateOffScreenGWorld(&shadowMaskMap, &shadowSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&shadowMaskMap, &shadowSrcRect, GpPixelFormats::kBW1); LoadGraphic(shadowMaskMap, kShadowPictID + 1000); for (i = 0; i < kNumShadowSrcRects; i++) @@ -205,10 +205,10 @@ void InitGliderMap (void) } QSetRect(&bandsSrcRect, 0, 0, 16, 18); // 304 pixels - theErr = CreateOffScreenGWorld(&bandsSrcMap, &bandsSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&bandsSrcMap, &bandsSrcRect); LoadGraphic(bandsSrcMap, kRubberBandsPictID); - theErr = CreateOffScreenGWorld(&bandsMaskMap, &bandsSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&bandsMaskMap, &bandsSrcRect, GpPixelFormats::kBW1); LoadGraphic(bandsMaskMap, kRubberBandsPictID + 1000); for (i = 0; i < 3; i++) @@ -228,10 +228,10 @@ void InitBlowers (void) PLError_t theErr; QSetRect(&blowerSrcRect, 0, 0, 48, 402); // 19344 pixels - theErr = CreateOffScreenGWorld(&blowerSrcMap, &blowerSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&blowerSrcMap, &blowerSrcRect); LoadGraphic(blowerSrcMap, kBlowerPictID); - theErr = CreateOffScreenGWorld(&blowerMaskMap, &blowerSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&blowerMaskMap, &blowerSrcRect, GpPixelFormats::kBW1); LoadGraphic(blowerMaskMap, kBlowerPictID + 1000); for (i = 0; i < kNumCandleFlames; i++) @@ -271,10 +271,10 @@ void InitFurniture (void) wasCPort = GetGraphicsPort(); QSetRect(&furnitureSrcRect, 0, 0, 64, 278); // 17856 pixels - theErr = CreateOffScreenGWorld(&furnitureSrcMap, &furnitureSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&furnitureSrcMap, &furnitureSrcRect); LoadGraphic(furnitureSrcMap, kFurniturePictID); - theErr = CreateOffScreenGWorld(&furnitureMaskMap, &furnitureSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&furnitureMaskMap, &furnitureSrcRect, GpPixelFormats::kBW1); LoadGraphic(furnitureMaskMap, kFurniturePictID + 1000); QSetRect(&tableSrc, 0, 0, 64, 22); @@ -314,10 +314,10 @@ void InitPrizes (void) PLError_t theErr; QSetRect(&bonusSrcRect, 0, 0, 88, 378); // 33264 pixels - theErr = CreateOffScreenGWorld(&bonusSrcMap, &bonusSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&bonusSrcMap, &bonusSrcRect); LoadGraphic(bonusSrcMap, kBonusPictID); - theErr = CreateOffScreenGWorld(&bonusMaskMap, &bonusSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&bonusMaskMap, &bonusSrcRect, GpPixelFormats::kBW1); LoadGraphic(bonusMaskMap, kBonusPictID + 1000); for (i = 0; i < 11; i++) @@ -365,10 +365,10 @@ void InitPrizes (void) sparkleSrc[1] = sparkleSrc[3]; QSetRect(&pointsSrcRect, 0, 0, 24, 120); // 2880 pixels - theErr = CreateOffScreenGWorld(&pointsSrcMap, &pointsSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&pointsSrcMap, &pointsSrcRect); LoadGraphic(pointsSrcMap, kPointsPictID); - theErr = CreateOffScreenGWorld(&pointsMaskMap, &pointsSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&pointsMaskMap, &pointsSrcRect, GpPixelFormats::kBW1); LoadGraphic(pointsMaskMap, kPointsPictID + 1000); for (i = 0; i < 15; i++) @@ -387,10 +387,10 @@ void InitTransports (void) PLError_t theErr; QSetRect(&transSrcRect, 0, 0, 56, 32); // 1848 pixels - theErr = CreateOffScreenGWorld(&transSrcMap, &transSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&transSrcMap, &transSrcRect); LoadGraphic(transSrcMap, kTransportPictID); - theErr = CreateOffScreenGWorld(&transMaskMap, &transSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&transMaskMap, &transSrcRect, GpPixelFormats::kBW1); LoadGraphic(transMaskMap, kTransportPictID + 1000); } @@ -403,7 +403,7 @@ void InitSwitches (void) PLError_t theErr; QSetRect(&switchSrcRect, 0, 0, 32, 104); // 3360 pixels - theErr = CreateOffScreenGWorld(&switchSrcMap, &switchSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&switchSrcMap, &switchSrcRect); LoadGraphic(switchSrcMap, kSwitchPictID); QSetRect(&lightSwitchSrc[0], 0, 0, 15, 24); @@ -442,10 +442,10 @@ void InitLights (void) PLError_t theErr; QSetRect(&lightSrcRect, 0, 0, 72, 126); // 9144 pixels - theErr = CreateOffScreenGWorld(&lightSrcMap, &lightSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&lightSrcMap, &lightSrcRect); LoadGraphic(lightSrcMap, kLightPictID); - theErr = CreateOffScreenGWorld(&lightMaskMap, &lightSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&lightMaskMap, &lightSrcRect, GpPixelFormats::kBW1); LoadGraphic(lightMaskMap, kLightPictID + 1000); QSetRect(&flourescentSrc1, 0, 0, 16, 12); @@ -471,24 +471,24 @@ void InitAppliances (void) PLError_t theErr; QSetRect(&applianceSrcRect, 0, 0, 80, 269); // 21600 pixels - theErr = CreateOffScreenGWorld(&applianceSrcMap, &applianceSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&applianceSrcMap, &applianceSrcRect); LoadGraphic(applianceSrcMap, kAppliancePictID); - theErr = CreateOffScreenGWorld(&applianceMaskMap, &applianceSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&applianceMaskMap, &applianceSrcRect, GpPixelFormats::kBW1); LoadGraphic(applianceMaskMap, kAppliancePictID + 1000); QSetRect(&toastSrcRect, 0, 0, 32, 174); // 5600 pixels - theErr = CreateOffScreenGWorld(&toastSrcMap, &toastSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&toastSrcMap, &toastSrcRect); LoadGraphic(toastSrcMap, kToastPictID); - theErr = CreateOffScreenGWorld(&toastMaskMap, &toastSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&toastMaskMap, &toastSrcRect, GpPixelFormats::kBW1); LoadGraphic(toastMaskMap, kToastPictID + 1000); QSetRect(&shredSrcRect, 0, 0, 40, 35); // 1440 pixels - theErr = CreateOffScreenGWorld(&shredSrcMap, &shredSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&shredSrcMap, &shredSrcRect); LoadGraphic(shredSrcMap, kShreddedPictID); - theErr = CreateOffScreenGWorld(&shredMaskMap, &shredSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&shredMaskMap, &shredSrcRect, GpPixelFormats::kBW1); LoadGraphic(shredMaskMap, kShreddedPictID + 1000); QSetRect(&plusScreen1, 0, 0, 32, 22); @@ -544,52 +544,52 @@ void InitEnemies (void) PLError_t theErr; QSetRect(&balloonSrcRect, 0, 0, 24, 30 * kNumBalloonFrames); - theErr = CreateOffScreenGWorld(&balloonSrcMap, &balloonSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&balloonSrcMap, &balloonSrcRect); LoadGraphic(balloonSrcMap, kBalloonPictID); - theErr = CreateOffScreenGWorld(&balloonMaskMap, &balloonSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&balloonMaskMap, &balloonSrcRect, GpPixelFormats::kBW1); LoadGraphic(balloonMaskMap, kBalloonPictID + 1000); QSetRect(&copterSrcRect, 0, 0, 32, 30 * kNumCopterFrames); - theErr = CreateOffScreenGWorld(&copterSrcMap, &copterSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&copterSrcMap, &copterSrcRect); LoadGraphic(copterSrcMap, kCopterPictID); - theErr = CreateOffScreenGWorld(&copterMaskMap, &copterSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&copterMaskMap, &copterSrcRect, GpPixelFormats::kBW1); LoadGraphic(copterMaskMap, kCopterPictID + 1000); QSetRect(&dartSrcRect, 0, 0, 64, 19 * kNumDartFrames); - theErr = CreateOffScreenGWorld(&dartSrcMap, &dartSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&dartSrcMap, &dartSrcRect); LoadGraphic(dartSrcMap, kDartPictID); - theErr = CreateOffScreenGWorld(&dartMaskMap, &dartSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&dartMaskMap, &dartSrcRect, GpPixelFormats::kBW1); LoadGraphic(dartMaskMap, kDartPictID + 1000); QSetRect(&ballSrcRect, 0, 0, 32, 32 * kNumBallFrames); - theErr = CreateOffScreenGWorld(&ballSrcMap, &ballSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&ballSrcMap, &ballSrcRect); LoadGraphic(ballSrcMap, kBallPictID); - theErr = CreateOffScreenGWorld(&ballMaskMap, &ballSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&ballMaskMap, &ballSrcRect, GpPixelFormats::kBW1); LoadGraphic(ballMaskMap, kBallPictID + 1000); QSetRect(&dripSrcRect, 0, 0, 16, 12 * kNumDripFrames); - theErr = CreateOffScreenGWorld(&dripSrcMap, &dripSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&dripSrcMap, &dripSrcRect); LoadGraphic(dripSrcMap, kDripPictID); - theErr = CreateOffScreenGWorld(&dripMaskMap, &dripSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&dripMaskMap, &dripSrcRect, GpPixelFormats::kBW1); LoadGraphic(dripMaskMap, kDripPictID + 1000); QSetRect(&enemySrcRect, 0, 0, 36, 33); - theErr = CreateOffScreenGWorld(&enemySrcMap, &enemySrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&enemySrcMap, &enemySrcRect); LoadGraphic(enemySrcMap, kEnemyPictID); - theErr = CreateOffScreenGWorld(&enemyMaskMap, &enemySrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&enemyMaskMap, &enemySrcRect, GpPixelFormats::kBW1); LoadGraphic(enemyMaskMap, kEnemyPictID + 1000); QSetRect(&fishSrcRect, 0, 0, 16, 16 * kNumFishFrames); - theErr = CreateOffScreenGWorld(&fishSrcMap, &fishSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&fishSrcMap, &fishSrcRect); LoadGraphic(fishSrcMap, kFishPictID); - theErr = CreateOffScreenGWorld(&fishMaskMap, &fishSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&fishMaskMap, &fishSrcRect, GpPixelFormats::kBW1); LoadGraphic(fishMaskMap, kFishPictID + 1000); for (i = 0; i < kNumBalloonFrames; i++) diff --git a/GpApp/StructuresInit2.cpp b/GpApp/StructuresInit2.cpp index 15de057..4094265 100644 --- a/GpApp/StructuresInit2.cpp +++ b/GpApp/StructuresInit2.cpp @@ -57,10 +57,10 @@ void InitClutter (void) PLError_t theErr; QSetRect(&clutterSrcRect, 0, 0, 128, 69); - theErr = CreateOffScreenGWorld(&clutterSrcMap, &clutterSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&clutterSrcMap, &clutterSrcRect); LoadGraphic(clutterSrcMap, kClutterPictID); - theErr = CreateOffScreenGWorld(&clutterMaskMap, &clutterSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&clutterMaskMap, &clutterSrcRect, GpPixelFormats::kBW1); LoadGraphic(clutterMaskMap, kClutterPictID + 1000); QSetRect(&flowerSrc[0], 0, 0, 10, 28); @@ -92,7 +92,7 @@ void InitSupport (void) PLError_t theErr; QSetRect(&suppSrcRect, 0, 0, kRoomWide, kFloorSupportTall); // 44 - theErr = CreateOffScreenGWorld(&suppSrcMap, &suppSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&suppSrcMap, &suppSrcRect); LoadGraphic(suppSrcMap, kSupportPictID); } @@ -106,10 +106,10 @@ void InitAngel (void) PLError_t theErr; QSetRect(&angelSrcRect, 0, 0, 96, 44); - theErr = CreateOffScreenGWorld(&angelSrcMap, &angelSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&angelSrcMap, &angelSrcRect); LoadGraphic(angelSrcMap, kAngelPictID); - theErr = CreateOffScreenGWorld(&angelMaskMap, &angelSrcRect, GpPixelFormats::kBW1); + theErr = CreateOffScreenGWorldCustomDepth(&angelMaskMap, &angelSrcRect, GpPixelFormats::kBW1); LoadGraphic(angelMaskMap, kAngelPictID + 1); } @@ -132,11 +132,11 @@ PLError_t RecreateOffscreens(void) workSrcRect = houseRect; // Set up work map ZeroRectCorner(&workSrcRect); - theErr = CreateOffScreenGWorld(&workSrcMap, &workSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&workSrcMap, &workSrcRect); backSrcRect = houseRect; // Set up background map ZeroRectCorner(&backSrcRect); - theErr = CreateOffScreenGWorld(&backSrcMap, &backSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&backSrcMap, &backSrcRect); return PLErrors::kNone; } diff --git a/GpApp/Tools.cpp b/GpApp/Tools.cpp index b401c1d..d3dde17 100644 --- a/GpApp/Tools.cpp +++ b/GpApp/Tools.cpp @@ -87,7 +87,7 @@ void CreateToolsOffscreen (void) if (toolSrcMap == nil) { QSetRect(&toolSrcRect, 0, 0, 360, 216); - theErr = CreateOffScreenGWorld(&toolSrcMap, &toolSrcRect, kPreferredPixelFormat); + theErr = CreateOffScreenGWorld(&toolSrcMap, &toolSrcRect); LoadGraphic(toolSrcMap, kToolsPictID); } } diff --git a/GpApp/Utilities.cpp b/GpApp/Utilities.cpp index fbff448..afbd359 100644 --- a/GpApp/Utilities.cpp +++ b/GpApp/Utilities.cpp @@ -15,6 +15,7 @@ #include "QDPixMap.h" #include "BitmapImage.h" #include "DialogManager.h" +#include "DisplayDeviceManager.h" #include "Externs.h" #include "HostSystemServices.h" #include "IconLoader.h" @@ -211,13 +212,17 @@ void CreateOffScreenPixMap (Rect *theRect, CGrafPtr *offScreen) //-------------------------------------------------------------------- CreateOffScreenGWorld // Creates an offscreen GWorldÊusing the depth passed in. -PLError_t CreateOffScreenGWorld (DrawSurface **theGWorld, Rect *bounds, GpPixelFormat_t pixelFormat) +PLError_t CreateOffScreenGWorld (DrawSurface **theGWorld, Rect *bounds) { - PLError_t theErr; + GpPixelFormat_t pixelFormat = PortabilityLayer::DisplayDeviceManager::GetInstance()->GetPixelFormat(); - theErr = NewGWorld(theGWorld, pixelFormat, bounds, nil); - - return theErr; + return NewGWorld(theGWorld, pixelFormat, bounds, nil); +} + + +PLError_t CreateOffScreenGWorldCustomDepth(DrawSurface **theGWorld, Rect *bounds, GpPixelFormat_t pixelFormat) +{ + return NewGWorld(theGWorld, pixelFormat, bounds, nil); } //-------------------------------------------------------------- KillOffScreenPixMap diff --git a/GpApp/Utilities.h b/GpApp/Utilities.h index aabf206..fb62aff 100644 --- a/GpApp/Utilities.h +++ b/GpApp/Utilities.h @@ -9,4 +9,5 @@ #include "GpPixelFormat.h" -PLError_t CreateOffScreenGWorld (DrawSurface **surface, Rect *bounds, GpPixelFormat_t pixelFormat); +PLError_t CreateOffScreenGWorld (DrawSurface **surface, Rect *bounds); +PLError_t CreateOffScreenGWorldCustomDepth (DrawSurface **surface, Rect *bounds, GpPixelFormat_t pixelFormat); diff --git a/GpCommon/GpBuildVersion.h b/GpCommon/GpBuildVersion.h index 9bde46e..522a6cf 100644 --- a/GpCommon/GpBuildVersion.h +++ b/GpCommon/GpBuildVersion.h @@ -2,8 +2,8 @@ #define GP_BUILD_VERSION_MAJOR 1 #define GP_BUILD_VERSION_MINOR 0 -#define GP_BUILD_VERSION_UPDATE 1 +#define GP_BUILD_VERSION_UPDATE 2 -#define GP_APPLICATION_VERSION_STRING "1.0.1" +#define GP_APPLICATION_VERSION_STRING "1.0.2" #define GP_APPLICATION_COPYRIGHT_STRING "2020 Eric Lasota" #define GP_APPLICATION_WEBSITE_STRING "https://github.com/elasota/Aerofoil" diff --git a/GpCommon/IGpDisplayDriver.h b/GpCommon/IGpDisplayDriver.h index 372405a..b9154ee 100644 --- a/GpCommon/IGpDisplayDriver.h +++ b/GpCommon/IGpDisplayDriver.h @@ -5,6 +5,7 @@ struct IGpDisplayDriverSurface; struct IGpCursor; +struct GpDisplayDriverProperties; struct GpDisplayDriverSurfaceEffects { @@ -26,7 +27,7 @@ public: virtual void Run() = 0; virtual void Shutdown() = 0; - virtual void GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *bpp) = 0; + virtual void GetDisplayResolution(unsigned int *width, unsigned int *height) = 0; virtual IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat) = 0; virtual void DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height, const GpDisplayDriverSurfaceEffects *effects) = 0; @@ -40,6 +41,8 @@ public: virtual void SetBackgroundColor(uint8_t r, uint8_t g, uint8_t b, uint8_t a) = 0; virtual void RequestToggleFullScreen(uint32_t timestamp) = 0; + + virtual const GpDisplayDriverProperties &GetProperties() const = 0; }; inline GpDisplayDriverSurfaceEffects::GpDisplayDriverSurfaceEffects() diff --git a/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_D3D11.cpp b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_D3D11.cpp index 6f435e8..bb8da43 100644 --- a/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_D3D11.cpp +++ b/GpDisplayDriver_D3D11/CompiledShaders/DrawQuadRGBP_D3D11.cpp @@ -1,46 +1,132 @@ static unsigned char gs_shaderData[] = { - 68, 88, 66, 67, 196, 70, 6, 103, 19, 68, 64, 241, 205, 255, 73, - 188, 120, 217, 29, 231, 1, 0, 0, 0, 116, 2, 0, 0, 5, 0, - 0, 0, 52, 0, 0, 0, 176, 0, 0, 0, 8, 1, 0, 0, 60, - 1, 0, 0, 248, 1, 0, 0, 82, 68, 69, 70, 116, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, - 0, 0, 4, 255, 255, 0, 137, 0, 0, 75, 0, 0, 0, 60, 0, + 68, 88, 66, 67, 79, 173, 176, 182, 205, 217, 61, 84, 80, 209, 33, + 250, 135, 89, 76, 198, 1, 0, 0, 0, 116, 7, 0, 0, 5, 0, + 0, 0, 52, 0, 0, 0, 124, 2, 0, 0, 212, 2, 0, 0, 8, + 3, 0, 0, 248, 6, 0, 0, 82, 68, 69, 70, 64, 2, 0, 0, + 1, 0, 0, 0, 132, 0, 0, 0, 2, 0, 0, 0, 28, 0, 0, + 0, 0, 4, 255, 255, 0, 137, 0, 0, 24, 2, 0, 0, 92, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 4, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 1, 0, 0, 0, 9, 0, 0, 0, - 115, 117, 114, 102, 97, 99, 101, 84, 101, 120, 116, 117, 114, 101, 0, - 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, - 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, - 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 171, 73, 83, 71, 78, - 80, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, - 0, 0, 15, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, - 83, 86, 95, 80, 79, 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, - 67, 79, 79, 82, 68, 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, - 0, 0, 1, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, - 15, 0, 0, 0, 83, 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, - 171, 83, 72, 68, 82, 180, 0, 0, 0, 64, 0, 0, 0, 45, 0, - 0, 0, 88, 24, 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, - 85, 0, 0, 98, 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, - 101, 0, 0, 3, 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, - 2, 1, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, 0, - 0, 0, 70, 16, 16, 0, 1, 0, 0, 0, 54, 0, 0, 8, 194, - 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, 0, - 7, 242, 0, 16, 0, 0, 0, 0, 0, 70, 14, 16, 0, 0, 0, - 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 54, 0, 0, 5, 114, - 32, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, - 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, 0, 0, 1, 64, 0, - 0, 0, 0, 128, 63, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, - 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 2, + 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 115, 117, 114, 102, 97, 99, 101, 84, 101, 120, 116, 117, 114, + 101, 0, 83, 68, 114, 97, 119, 81, 117, 97, 100, 80, 105, 120, 101, + 108, 67, 111, 110, 115, 116, 97, 110, 116, 115, 0, 171, 107, 0, 0, + 0, 6, 0, 0, 0, 156, 0, 0, 0, 48, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 44, 1, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 0, 2, 0, 0, 0, 68, 1, 0, 0, 0, 0, 0, 0, + 84, 1, 0, 0, 16, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, + 0, 108, 1, 0, 0, 0, 0, 0, 0, 124, 1, 0, 0, 24, 0, + 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 156, 1, 0, 0, 0, + 0, 0, 0, 172, 1, 0, 0, 28, 0, 0, 0, 4, 0, 0, 0, + 2, 0, 0, 0, 156, 1, 0, 0, 0, 0, 0, 0, 202, 1, 0, + 0, 32, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 228, 1, + 0, 0, 0, 0, 0, 0, 244, 1, 0, 0, 36, 0, 0, 0, 12, + 0, 0, 0, 0, 0, 0, 0, 8, 2, 0, 0, 0, 0, 0, 0, + 99, 111, 110, 115, 116, 97, 110, 116, 115, 95, 77, 111, 100, 117, 108, + 97, 116, 105, 111, 110, 0, 171, 171, 171, 1, 0, 3, 0, 1, 0, + 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, + 97, 110, 116, 115, 95, 70, 108, 105, 99, 107, 101, 114, 65, 120, 105, + 115, 0, 171, 171, 1, 0, 2, 0, 1, 0, 2, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, 97, 110, 116, 115, 95, + 70, 108, 105, 99, 107, 101, 114, 83, 116, 97, 114, 116, 84, 104, 114, + 101, 115, 104, 111, 108, 100, 0, 0, 0, 2, 0, 1, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, 97, 110, + 116, 115, 95, 70, 108, 105, 99, 107, 101, 114, 69, 110, 100, 84, 104, + 114, 101, 115, 104, 111, 108, 100, 0, 99, 111, 110, 115, 116, 97, 110, + 116, 115, 95, 68, 101, 115, 97, 116, 117, 114, 97, 116, 105, 111, 110, + 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 99, 111, 110, 115, 116, 97, 110, 116, 115, 95, + 85, 110, 117, 115, 101, 100, 0, 171, 171, 171, 1, 0, 3, 0, 1, + 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, + 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, + 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, + 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 80, 0, 0, 0, 2, + 0, 0, 0, 8, 0, 0, 0, 56, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, + 0, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, + 0, 0, 1, 0, 0, 0, 3, 3, 0, 0, 83, 86, 95, 80, 79, + 83, 73, 84, 73, 79, 78, 0, 84, 69, 88, 67, 79, 79, 82, 68, + 0, 171, 171, 171, 79, 83, 71, 78, 44, 0, 0, 0, 1, 0, 0, + 0, 8, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 83, + 86, 95, 84, 65, 82, 71, 69, 84, 0, 171, 171, 83, 72, 68, 82, + 232, 3, 0, 0, 64, 0, 0, 0, 250, 0, 0, 0, 89, 0, 0, + 4, 70, 142, 32, 0, 0, 0, 0, 0, 3, 0, 0, 0, 88, 24, + 0, 4, 0, 112, 16, 0, 0, 0, 0, 0, 85, 85, 0, 0, 98, + 16, 0, 3, 50, 16, 16, 0, 1, 0, 0, 0, 101, 0, 0, 3, + 242, 32, 16, 0, 0, 0, 0, 0, 104, 0, 0, 2, 3, 0, 0, + 0, 65, 0, 0, 5, 50, 0, 16, 0, 0, 0, 0, 0, 70, 16, + 16, 0, 1, 0, 0, 0, 27, 0, 0, 5, 50, 0, 16, 0, 0, + 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 54, 0, 0, 8, + 194, 0, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 45, 0, + 0, 7, 242, 0, 16, 0, 1, 0, 0, 0, 70, 14, 16, 0, 0, + 0, 0, 0, 70, 126, 16, 0, 0, 0, 0, 0, 56, 0, 0, 9, + 242, 0, 16, 0, 2, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 70, 142, 32, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 54, 0, 0, 5, 130, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 128, 63, 56, 0, 0, 7, 242, 0, 16, 0, + 1, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 70, 14, 16, + 0, 2, 0, 0, 0, 38, 0, 0, 9, 0, 208, 0, 0, 50, 0, + 16, 0, 0, 0, 0, 0, 70, 0, 16, 0, 0, 0, 0, 0, 70, + 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 30, 0, 0, 7, + 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, + 0, 10, 0, 16, 0, 0, 0, 0, 0, 34, 0, 0, 8, 34, 0, + 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 42, + 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 33, 0, 0, 8, + 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, + 0, 58, 128, 32, 0, 0, 0, 0, 0, 1, 0, 0, 0, 55, 0, + 0, 12, 242, 0, 16, 0, 1, 0, 0, 0, 86, 5, 16, 0, 0, + 0, 0, 0, 2, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, + 0, 60, 0, 0, 7, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, + 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 55, + 0, 0, 12, 242, 0, 16, 0, 0, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 70, 14, 16, 0, 1, 0, 0, 0, 2, 64, 0, + 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, + 128, 63, 29, 0, 0, 7, 18, 0, 16, 0, 1, 0, 0, 0, 1, + 64, 0, 0, 0, 0, 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, + 13, 0, 4, 3, 10, 0, 16, 0, 1, 0, 0, 0, 57, 0, 0, + 8, 18, 0, 16, 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0, + 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 0, 16, + 0, 0, 10, 34, 0, 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 154, 153, 153, 62, 154, 153, 25, + 63, 205, 204, 204, 61, 0, 0, 0, 0, 0, 0, 0, 9, 66, 0, + 16, 0, 1, 0, 0, 0, 10, 128, 32, 128, 65, 0, 0, 0, 0, + 0, 0, 0, 2, 0, 0, 0, 1, 64, 0, 0, 0, 0, 128, 63, + 56, 0, 0, 8, 34, 0, 16, 0, 1, 0, 0, 0, 26, 0, 16, + 0, 1, 0, 0, 0, 10, 128, 32, 0, 0, 0, 0, 0, 2, 0, + 0, 0, 50, 0, 0, 9, 226, 0, 16, 0, 1, 0, 0, 0, 6, + 9, 16, 0, 0, 0, 0, 0, 166, 10, 16, 0, 1, 0, 0, 0, + 86, 5, 16, 0, 1, 0, 0, 0, 55, 32, 0, 9, 114, 0, 16, + 0, 0, 0, 0, 0, 6, 0, 16, 0, 1, 0, 0, 0, 150, 7, + 16, 0, 1, 0, 0, 0, 70, 2, 16, 0, 0, 0, 0, 0, 47, + 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 0, 0, 0, + 0, 70, 2, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 102, 102, + 230, 63, 102, 102, 230, 63, 102, 102, 230, 63, 0, 0, 0, 0, 25, + 0, 0, 5, 114, 0, 16, 0, 0, 0, 0, 0, 70, 2, 16, 0, + 0, 0, 0, 0, 56, 0, 0, 10, 114, 0, 16, 0, 1, 0, 0, + 0, 86, 5, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 150, 246, + 160, 189, 43, 199, 117, 63, 40, 177, 243, 60, 0, 0, 0, 0, 50, + 0, 0, 12, 114, 0, 16, 0, 1, 0, 0, 0, 6, 0, 16, 0, + 0, 0, 0, 0, 2, 64, 0, 0, 87, 203, 136, 63, 86, 131, 197, + 60, 225, 104, 227, 58, 0, 0, 0, 0, 70, 2, 16, 0, 1, 0, + 0, 0, 50, 0, 0, 12, 114, 32, 16, 0, 0, 0, 0, 0, 166, + 10, 16, 0, 0, 0, 0, 0, 2, 64, 0, 0, 5, 9, 34, 60, + 158, 151, 129, 60, 194, 240, 119, 63, 0, 0, 0, 0, 70, 2, 16, + 0, 1, 0, 0, 0, 54, 0, 0, 5, 130, 32, 16, 0, 0, 0, + 0, 0, 58, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, + 84, 65, 84, 116, 0, 0, 0, 30, 0, 0, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 0, 0, 15, 0, 0, 0, 4, 0, 0, + 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 3, 0, 0, + 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, }; namespace GpBinarizedShaders diff --git a/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp index b428317..f5fb046 100644 --- a/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp +++ b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.cpp @@ -1205,14 +1205,12 @@ void GpDisplayDriverD3D11::Shutdown() free(this); } -void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *pixelFormat) +void GpDisplayDriverD3D11::GetDisplayResolution(unsigned int *width, unsigned int *height) { if (width) *width = m_windowWidthVirtual; if (height) *height = m_windowHeightVirtual; - if (pixelFormat) - *pixelFormat = GpPixelFormats::k8BitStandard; } IGpDisplayDriverSurface *GpDisplayDriverD3D11::CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat) @@ -1424,6 +1422,11 @@ void GpDisplayDriverD3D11::RequestToggleFullScreen(uint32_t timestamp) } } +const GpDisplayDriverProperties &GpDisplayDriverD3D11::GetProperties() const +{ + return m_properties; +} + GpDisplayDriverD3D11 *GpDisplayDriverD3D11::Create(const GpDisplayDriverProperties &properties) { void *storage = malloc(sizeof(GpDisplayDriverD3D11)); diff --git a/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h index a7d2577..d9cfc15 100644 --- a/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h +++ b/GpDisplayDriver_D3D11/GpDisplayDriverD3D11.h @@ -36,7 +36,7 @@ public: void Run() override; void Shutdown() override; - void GetDisplayResolution(unsigned int *width, unsigned int *height, GpPixelFormat_t *bpp) override; + void GetDisplayResolution(unsigned int *width, unsigned int *height) override; IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, GpPixelFormat_t pixelFormat) override; void DrawSurface(IGpDisplayDriverSurface *surface, int32_t x, int32_t y, size_t width, size_t height, const GpDisplayDriverSurfaceEffects *effects) override; @@ -51,6 +51,8 @@ public: void RequestToggleFullScreen(uint32_t timestamp) override; + const GpDisplayDriverProperties &GetProperties() const override; + static GpDisplayDriverD3D11 *Create(const GpDisplayDriverProperties &properties); private: diff --git a/PortabilityLayer/AntiAliasTable.cpp b/PortabilityLayer/AntiAliasTable.cpp index bfe09f0..7380d92 100644 --- a/PortabilityLayer/AntiAliasTable.cpp +++ b/PortabilityLayer/AntiAliasTable.cpp @@ -1,6 +1,9 @@ #include "AntiAliasTable.h" #include "RGBAColor.h" +#include +#include + // TODO: This is not gamma correct... namespace PortabilityLayer { @@ -116,5 +119,29 @@ namespace PortabilityLayer } } } + + void AntiAliasTable::GenerateForSimpleScale(uint8_t colorChannel) + { + const double gamma = 1.8; + const double rcpGamma = 1.0 / gamma; + const double rcp255 = 1.0 / 255.0; + const double rcp15 = 1.0 / 15.0; + double colorChannelLinear = pow(colorChannel * rcp255, gamma); + + for (size_t baseColor = 0; baseColor < 256; baseColor++) + { + const double baseColorLinear = pow(baseColor * rcp255, gamma); + + for (size_t opacity = 0; opacity < 16; opacity++) + { + const double opacityF = static_cast(opacity) * rcp15; + const double blendedColor = colorChannelLinear * opacityF + (1.0 - opacityF) * baseColorLinear; + + const double blendedColorGammaSpace = pow(std::min(std::max(0.0, blendedColor), 1.0), rcpGamma); + + m_aaTranslate[baseColor][opacity] = static_cast(floor(blendedColorGammaSpace * 255.0 + 0.5)); + } + } + } #endif } diff --git a/PortabilityLayer/AntiAliasTable.h b/PortabilityLayer/AntiAliasTable.h index 800b36d..b5c8f2a 100644 --- a/PortabilityLayer/AntiAliasTable.h +++ b/PortabilityLayer/AntiAliasTable.h @@ -12,5 +12,6 @@ namespace PortabilityLayer uint8_t m_aaTranslate[256][16]; void GenerateForPalette(const RGBAColor &baseColor, const RGBAColor *colors, size_t numColors); + void GenerateForSimpleScale(uint8_t colorChannel); }; } diff --git a/PortabilityLayer/DialogManager.cpp b/PortabilityLayer/DialogManager.cpp index 431eaef..325d45a 100644 --- a/PortabilityLayer/DialogManager.cpp +++ b/PortabilityLayer/DialogManager.cpp @@ -830,7 +830,7 @@ namespace PortabilityLayer void DialogManagerImpl::PositionWindow(Window *window, const Rect &rect) const { unsigned int displayWidth, displayHeight; - PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(&displayWidth, &displayHeight, nullptr); + PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(&displayWidth, &displayHeight); const unsigned int halfDisplayHeight = displayHeight / 2; const unsigned int quarterDisplayWidth = displayHeight / 4; diff --git a/PortabilityLayer/DisplayDeviceManager.cpp b/PortabilityLayer/DisplayDeviceManager.cpp index a2da391..a0b137c 100644 --- a/PortabilityLayer/DisplayDeviceManager.cpp +++ b/PortabilityLayer/DisplayDeviceManager.cpp @@ -16,6 +16,7 @@ namespace PortabilityLayer void Init() override; void Shutdown() override; + void SetPixelFormat(GpPixelFormat_t pixelFormat) override; GpPixelFormat_t GetPixelFormat() const override; void SyncPalette(IGpDisplayDriver *displayDriver) override; @@ -62,8 +63,6 @@ namespace PortabilityLayer void DisplayDeviceManagerImpl::Init() { - HostDisplayDriver::GetInstance()->GetDisplayResolution(nullptr, nullptr, &m_pixelFormat); - const PortabilityLayer::RGBAColor *spColors = StandardPalette::GetInstance()->GetColors(); for (size_t i = 0; i < 256; i++) m_palette[i] = spColors[i]; @@ -75,6 +74,11 @@ namespace PortabilityLayer { } + void DisplayDeviceManagerImpl::SetPixelFormat(GpPixelFormat_t pixelFormat) + { + m_pixelFormat = pixelFormat; + } + GpPixelFormat_t DisplayDeviceManagerImpl::GetPixelFormat() const { return m_pixelFormat; diff --git a/PortabilityLayer/DisplayDeviceManager.h b/PortabilityLayer/DisplayDeviceManager.h index d383c0b..778d439 100644 --- a/PortabilityLayer/DisplayDeviceManager.h +++ b/PortabilityLayer/DisplayDeviceManager.h @@ -21,6 +21,7 @@ namespace PortabilityLayer virtual void Init() = 0; virtual void Shutdown() = 0; + virtual void SetPixelFormat(GpPixelFormat_t pixelFormat) = 0; virtual GpPixelFormat_t GetPixelFormat() const = 0; virtual void SyncPalette(IGpDisplayDriver *displayDriver) = 0; diff --git a/PortabilityLayer/IconLoader.cpp b/PortabilityLayer/IconLoader.cpp index e2cc284..1583819 100644 --- a/PortabilityLayer/IconLoader.cpp +++ b/PortabilityLayer/IconLoader.cpp @@ -1,6 +1,9 @@ #include "IconLoader.h" + +#include "DisplayDeviceManager.h" #include "PLCore.h" #include "PLCTabReducer.h" +#include "PLStandardColors.h" #include "ResourceManager.h" #include "QDStandardPalette.h" #include "QDPixMap.h" @@ -119,8 +122,12 @@ namespace PortabilityLayer return false; uint8_t remapping[256]; + PortabilityLayer::RGBAColor palette[256]; for (int i = 0; i < 256; i++) + { remapping[i] = 0; + palette[i] = StdColors::Black(); + } for (size_t i = 0; i < numItems; i++) { @@ -133,6 +140,7 @@ namespace PortabilityLayer return false; const PortabilityLayer::RGBAColor remappedColor = CTabReducer::DecodeClutItem(ctabItem); + palette[i] = remappedColor; remapping[index] = StandardPalette::GetInstance()->MapColorLUT(remappedColor); } @@ -141,7 +149,9 @@ namespace PortabilityLayer if (!rect.IsValid()) return false; - THandle pixMap = PixMapImpl::Create(rect, GpPixelFormats::k8BitStandard); + GpPixelFormat_t pixelFormat = DisplayDeviceManager::GetInstance()->GetPixelFormat(); + + THandle pixMap = PixMapImpl::Create(rect, pixelFormat); if (!pixMap) return false; @@ -152,49 +162,117 @@ namespace PortabilityLayer uint8_t *outData = static_cast((*pixMap)->GetPixelData()); const size_t outPitch = (*pixMap)->GetPitch(); - for (size_t row = 0; row < height; row++) + if (pixelFormat == GpPixelFormats::k8BitStandard) { - if (numItems > 16) + for (size_t row = 0; row < height; row++) { - // 8bpp - for (size_t col = 0; col < width; col++) + if (numItems > 16) { - const unsigned int index = inData[col]; - outData[col] = remapping[index]; + // 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++) + else if (numItems > 4) { - const unsigned int index = (inData[col / 2] >> (4 - ((col & 1) * 4))) & 0x0f; - outData[col] = remapping[index]; + // 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++) + else if (numItems > 2) { - const unsigned int index = (inData[col / 4] >> (6 - ((col & 3) * 2))) & 0x03; - outData[col] = remapping[index]; + // 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++) + else { - const unsigned int index = (inData[col / 4] >> (7 - (col & 7))) & 0x01; - outData[col] = remapping[index]; + // 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; + inData += inPitch; + outData += outPitch; + } } + else if (pixelFormat == GpPixelFormats::kRGB32) + { + 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]; + const PortabilityLayer::RGBAColor &color = palette[index]; + outData[col * 4 + 0] = color.r; + outData[col * 4 + 1] = color.g; + outData[col * 4 + 2] = color.b; + outData[col * 4 + 3] = 255; + } + } + 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; + const PortabilityLayer::RGBAColor &color = palette[index]; + outData[col * 4 + 0] = color.r; + outData[col * 4 + 1] = color.g; + outData[col * 4 + 2] = color.b; + outData[col * 4 + 3] = 255; + } + } + 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; + const PortabilityLayer::RGBAColor &color = palette[index]; + outData[col * 4 + 0] = color.r; + outData[col * 4 + 1] = color.g; + outData[col * 4 + 2] = color.b; + outData[col * 4 + 3] = 255; + } + } + else + { + // 1bpp + for (size_t col = 0; col < width; col++) + { + const unsigned int index = (inData[col / 4] >> (7 - (col & 7))) & 0x01; + const PortabilityLayer::RGBAColor &color = palette[index]; + outData[col * 4 + 0] = color.r; + outData[col * 4 + 1] = color.g; + outData[col * 4 + 2] = color.b; + outData[col * 4 + 3] = 255; + } + } + inData += inPitch; + outData += outPitch; + } + } + else + { + PL_NotYetImplemented(); + } + outHandle = pixMap; dataPtr = inData; @@ -245,7 +323,10 @@ namespace PortabilityLayer return THandle(); const Rect rect = Rect::Create(0, 0, 32, 32); - THandle pixMap = PixMapImpl::Create(rect, GpPixelFormats::k8BitStandard); + + GpPixelFormat_t pixelFormat = DisplayDeviceManager::GetInstance()->GetPixelFormat(); + + THandle pixMap = PixMapImpl::Create(rect, pixelFormat); if (!pixMap) return THandle(); @@ -253,13 +334,34 @@ namespace PortabilityLayer uint8_t *outData = static_cast((*pixMap)->GetPixelData()); const size_t outPitch = (*pixMap)->GetPitch(); - for (size_t row = 0; row < 32; row++) + if (pixelFormat == GpPixelFormats::kRGB32) { - for (size_t col = 0; col < 32; col++) - outData[col] = inData[col]; + const PortabilityLayer::RGBAColor *palette = StandardPalette::GetInstance()->GetColors(); - inData += 32; - outData += outPitch; + for (size_t row = 0; row < 32; row++) + { + uint32_t *outU32 = reinterpret_cast(outData); + for (size_t col = 0; col < 32; col++) + outU32[col] = palette[inData[col]].AsUInt32(); + + inData += 32; + outData += outPitch; + } + } + else if (pixelFormat == GpPixelFormats::k8BitStandard) + { + for (size_t row = 0; row < 32; row++) + { + for (size_t col = 0; col < 32; col++) + outData[col] = inData[col]; + + inData += 32; + outData += outPitch; + } + } + else + { + PL_NotYetImplemented(); } return pixMap; diff --git a/PortabilityLayer/MenuManager.cpp b/PortabilityLayer/MenuManager.cpp index 0212a2f..c1377f4 100644 --- a/PortabilityLayer/MenuManager.cpp +++ b/PortabilityLayer/MenuManager.cpp @@ -819,8 +819,9 @@ namespace PortabilityLayer } unsigned int width; - GpPixelFormat_t pixelFormat; - PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(&width, nullptr, &pixelFormat); + HostDisplayDriver::GetInstance()->GetDisplayResolution(&width, nullptr); + + GpPixelFormat_t pixelFormat = DisplayDeviceManager::GetInstance()->GetPixelFormat(); PortabilityLayer::QDManager *qdManager = PortabilityLayer::QDManager::GetInstance(); @@ -1310,7 +1311,7 @@ namespace PortabilityLayer int32_t popupBottom = m_popupPosition.m_y + menu->layoutFinalHeight; unsigned int displayHeight = 0; - PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(nullptr, &displayHeight, nullptr); + PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(nullptr, &displayHeight); if (popupBottom > static_cast(displayHeight)) m_popupPosition.m_y -= popupBottom - static_cast(displayHeight); } @@ -1397,8 +1398,7 @@ namespace PortabilityLayer if (m_menuGraf == nullptr) { - GpPixelFormat_t pixelFormat; - PortabilityLayer::HostDisplayDriver::GetInstance()->GetDisplayResolution(nullptr, nullptr, &pixelFormat); + GpPixelFormat_t pixelFormat = DisplayDeviceManager::GetInstance()->GetPixelFormat(); if (qdManager->NewGWorld(&m_menuGraf, pixelFormat, menuRect, nullptr) != 0) return; diff --git a/PortabilityLayer/PLQDraw.cpp b/PortabilityLayer/PLQDraw.cpp index d5bf62f..d00be52 100644 --- a/PortabilityLayer/PLQDraw.cpp +++ b/PortabilityLayer/PLQDraw.cpp @@ -11,6 +11,7 @@ #include "MemReaderStream.h" #include "HostFontHandler.h" #include "PLPasStr.h" +#include "PLStandardColors.h" #include "RenderedFont.h" #include "RenderedFontMetrics.h" #include "RenderedGlyphMetrics.h" @@ -33,11 +34,20 @@ #include #include +const uint32_t kInvertPixelAlphaMask = PortabilityLayer::RGBAColor::Create(0, 0, 0, 255).AsUInt32(); + static inline void InvertPixel8(uint8_t &pixel) { pixel = 255 ^ pixel; } +static inline void InvertPixel32(uint8_t *pixel) +{ + uint32_t &pixel32 = *reinterpret_cast(pixel); + pixel32 = ~pixel32; + pixel[3] = 255; +} + void SetPort(DrawSurface *graf) { PortabilityLayer::QDManager::GetInstance()->SetPort(graf); @@ -113,20 +123,21 @@ static void PlotLine(DrawSurface *surface, const PortabilityLayer::Vec2i &pointA assert(currentPoint.m_y < constrainedRect.bottom); - size_t plotIndex = static_cast(currentPoint.m_y) * pitch + static_cast(currentPoint.m_x); + const size_t plotRowStartOffset = static_cast(currentPoint.m_y) * pitch; const size_t plotLimit = pixMap->GetPitch() * (pixMap->m_rect.bottom - pixMap->m_rect.top); switch (pixelFormat) { case GpPixelFormats::k8BitStandard: { + size_t plotOffset = plotRowStartOffset + static_cast(currentPoint.m_x); const size_t pixelSize = 1; const uint8_t color = foreColor.Resolve8(nullptr, 0); while (currentPoint.m_x >= constrainedRect.left && currentPoint.m_x < constrainedRect.right && currentPoint.m_y < constrainedRect.bottom) { - assert(plotIndex < plotLimit); - pixData[plotIndex] = color; + assert(plotOffset < plotLimit); + pixData[plotOffset] = color; PortabilityLayer::PlotDirection plotDir = plotter.PlotNext(); if (plotDir == PortabilityLayer::PlotDirection_Exhausted) @@ -148,25 +159,80 @@ static void PlotLine(DrawSurface *surface, const PortabilityLayer::Vec2i &pointA case PortabilityLayer::PlotDirection_NegX_PosY: currentPoint.m_x--; currentPoint.m_y++; - plotIndex = plotIndex + pitch - pixelSize; + plotOffset = plotOffset + pitch - pixelSize; break; case PortabilityLayer::PlotDirection_0X_PosY: currentPoint.m_y++; - plotIndex = plotIndex + pitch; + plotOffset = plotOffset + pitch; break; case PortabilityLayer::PlotDirection_PosX_PosY: currentPoint.m_x++; currentPoint.m_y++; - plotIndex = plotIndex + pitch + pixelSize; + plotOffset = plotOffset + pitch + pixelSize; break; case PortabilityLayer::PlotDirection_NegX_0Y: currentPoint.m_x--; - plotIndex = plotIndex - pixelSize; + plotOffset = plotOffset - pixelSize; break; case PortabilityLayer::PlotDirection_PosX_0Y: currentPoint.m_x++; - plotIndex = plotIndex + pixelSize; + plotOffset = plotOffset + pixelSize; + break; + } + } + } + break; + case GpPixelFormats::kRGB32: + { + size_t plotOffset = plotRowStartOffset + static_cast(currentPoint.m_x) * 4; + const size_t pixelSize = 4; + const uint32_t color = foreColor.GetRGBAColor().AsUInt32(); + + while (currentPoint.m_x >= constrainedRect.left && currentPoint.m_x < constrainedRect.right && currentPoint.m_y < constrainedRect.bottom) + { + assert(plotOffset < plotLimit); + reinterpret_cast(pixData[plotOffset]) = color; + + PortabilityLayer::PlotDirection plotDir = plotter.PlotNext(); + if (plotDir == PortabilityLayer::PlotDirection_Exhausted) + return; + + switch (plotDir) + { + default: + case PortabilityLayer::PlotDirection_Exhausted: + return; + + case PortabilityLayer::PlotDirection_NegX_NegY: + case PortabilityLayer::PlotDirection_0X_NegY: + case PortabilityLayer::PlotDirection_PosX_NegY: + // These should never happen, the point order is swapped so that Y is always 0 or positive + assert(false); + return; + + case PortabilityLayer::PlotDirection_NegX_PosY: + currentPoint.m_x--; + currentPoint.m_y++; + plotOffset = plotOffset + pitch - pixelSize; + break; + case PortabilityLayer::PlotDirection_0X_PosY: + currentPoint.m_y++; + plotOffset = plotOffset + pitch; + break; + case PortabilityLayer::PlotDirection_PosX_PosY: + currentPoint.m_x++; + currentPoint.m_y++; + plotOffset = plotOffset + pitch + pixelSize; + break; + + case PortabilityLayer::PlotDirection_NegX_0Y: + currentPoint.m_x--; + plotOffset = plotOffset - pixelSize; + break; + case PortabilityLayer::PlotDirection_PosX_0Y: + currentPoint.m_x++; + plotOffset = plotOffset + pixelSize; break; } } @@ -281,6 +347,91 @@ static void DrawGlyph(PixMap *pixMap, const Rect &rect, const Point &penPos, con } } break; + case GpPixelFormats::kRGB32: + { + uint8_t *firstOutputRowData = static_cast(pixMap->m_data) + firstOutputRow * outputPitch; + + const PortabilityLayer::RGBAColor color = cacheColor.GetRGBAColor(); + uint8_t colorRGB[3] = { color.r, color.g, color.b }; + + const PortabilityLayer::AntiAliasTable *aaTables[3] = { nullptr, nullptr, nullptr }; + + if (isAA) + { + PortabilityLayer::RGBAColor rgbaColor = cacheColor.GetRGBAColor(); + uint8_t rgbColor[3] = { rgbaColor.r, rgbaColor.g, rgbaColor.b }; + uint8_t cacheRGBColor[3] = { cachedAATableColor.r, cachedAATableColor.g, cachedAATableColor.b }; + + for (int ch = 0; ch < 3; ch++) + { + if (rgbColor[ch] == 0) + aaTables[ch] = &PortabilityLayer::StandardPalette::GetInstance()->GetBlackToneAATable(); + else if (rgbColor[ch] == 255) + aaTables[ch] = &PortabilityLayer::StandardPalette::GetInstance()->GetWhiteToneAATable(); + else if (cachedAATable != nullptr && rgbColor[ch] == cacheRGBColor[ch]) + aaTables[ch] = &cachedAATable[ch]; + else + { + if (!cachedAATable) + { + cachedAATable = static_cast(PortabilityLayer::MemoryManager::GetInstance()->Alloc(sizeof(PortabilityLayer::AntiAliasTable) * 3)); + if (!cachedAATable) + return; + + cachedAATableColor = PortabilityLayer::RGBAColor::Create(0, 0, 0, 255); + cachedAATable[0] = cachedAATable[1] = cachedAATable[2] = PortabilityLayer::StandardPalette::GetInstance()->GetBlackToneAATable(); + } + + cacheRGBColor[ch] = rgbColor[ch]; + + cachedAATableColor = PortabilityLayer::RGBAColor::Create(cacheRGBColor[0], cacheRGBColor[1], cacheRGBColor[2], 255); + cachedAATable[ch].GenerateForSimpleScale(rgbColor[ch]); + + aaTables[ch] = &cachedAATable[ch]; + } + } + } + + for (uint32_t row = 0; row < numRows; row++) + { + const uint8_t *inputRowData = firstInputRowData + row * inputPitch; + uint8_t *outputRowData = firstOutputRowData + row * outputPitch; + + // It should be possible to speed this up, if needed. The input is guaranteed to be well-aligned and not mutable within this loop. + if (isAA) + { + for (uint32_t col = 0; col < numCols; col++) + { + const size_t inputOffset = firstInputCol + col; + + const unsigned int grayLevel = (inputRowData[inputOffset / 2] >> ((inputOffset & 1) * 4)) & 0xf; + uint8_t *targetPixel = outputRowData + (firstOutputCol + col) * 4; + + if (grayLevel > 0) + { + for (int ch = 0; ch < 3; ch++) + targetPixel[ch] = aaTables[ch]->m_aaTranslate[targetPixel[ch]][grayLevel]; + } + } + } + else + { + for (uint32_t col = 0; col < numCols; col++) + { + uint8_t *targetPixel = outputRowData + (firstOutputCol + col) * 4; + + const size_t inputOffset = firstInputCol + col; + if (inputRowData[inputOffset / 8] & (1 << (inputOffset & 0x7))) + { + targetPixel[0] = color.r; + targetPixel[1] = color.g; + targetPixel[2] = color.b; + } + } + } + } + } + break; default: PL_NotYetImplemented(); } @@ -317,7 +468,7 @@ void DrawSurface::DrawStringConstrained(const Point &point, const PLPasStr &str, PortabilityLayer::TextPlacer placer(PortabilityLayer::Vec2i(point.h, point.v), -1, rfont, str); - DrawText(placer, pixMap, rect, rfont, m_cachedAATable, m_cachedAAColor, cacheColor); + DrawText(placer, pixMap, rect, rfont, m_cachedAATables, m_cachedAAColor, cacheColor); m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents); } @@ -342,7 +493,7 @@ void DrawSurface::DrawStringWrap(const Point &point, const Rect &constrainRect, PortabilityLayer::TextPlacer placer(PortabilityLayer::Vec2i(point.h, point.v), areaRect.Width(), rfont, str); - DrawText(placer, pixMap, limitRect, rfont, m_cachedAATable, m_cachedAAColor, cacheColor); + DrawText(placer, pixMap, limitRect, rfont, m_cachedAATables, m_cachedAAColor, cacheColor); m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents); } @@ -527,7 +678,7 @@ void DrawSurface::DrawPicture(THandle pictHdl, const Rect &bounds) const PortabilityLayer::RGBAColor &resultColor = PortabilityLayer::StandardPalette::GetInstance()->GetColors()[paletteMapping[i]]; } } - else + else if (pixMap->GetPixelFormat() == GpPixelFormats::k8BitCustom) { PL_NotYetImplemented(); } @@ -574,93 +725,229 @@ void DrawSurface::DrawPicture(THandle pictHdl, const Rect &bounds) { case GpPixelFormats::kBW1: case GpPixelFormats::k8BitStandard: - { - const uint8_t *currentSourceRow = firstSourceRow; - uint8_t *currentDestRow = firstDestRow; - - int16_t *errorDiffusionBuffer = nullptr; - int16_t *errorDiffusionNextRow = nullptr; - int16_t *errorDiffusionCurrentRow = nullptr; - - if (bpp == 16 || bpp == 24) { - errorDiffusionBuffer = static_cast(memManager->Alloc(sizeof(int16_t) * numCopyCols * 2 * 3)); - if (!errorDiffusionBuffer) - return; + const uint8_t *currentSourceRow = firstSourceRow; + uint8_t *currentDestRow = firstDestRow; - errorDiffusionNextRow = errorDiffusionBuffer; - errorDiffusionCurrentRow = errorDiffusionBuffer + numCopyCols * 3; + int16_t *errorDiffusionBuffer = nullptr; + int16_t *errorDiffusionNextRow = nullptr; + int16_t *errorDiffusionCurrentRow = nullptr; - memset(errorDiffusionNextRow, 0, sizeof(int16_t) * numCopyCols * 3); - } - - for (uint32_t row = 0; row < numCopyRows; row++) - { - if (errorDiffusionBuffer) + if (bpp == 16 || bpp == 24) { - std::swap(errorDiffusionCurrentRow, errorDiffusionNextRow); + errorDiffusionBuffer = static_cast(memManager->Alloc(sizeof(int16_t) * numCopyCols * 2 * 3)); + if (!errorDiffusionBuffer) + return; + + errorDiffusionNextRow = errorDiffusionBuffer; + errorDiffusionCurrentRow = errorDiffusionBuffer + numCopyCols * 3; + memset(errorDiffusionNextRow, 0, sizeof(int16_t) * numCopyCols * 3); } - assert(currentSourceRow >= imageDataStart && currentSourceRow <= imageDataStart + inDataSize); - - if (bpp == 1) + for (uint32_t row = 0; row < numCopyRows; row++) { - for (size_t col = 0; col < numCopyCols; col++) + if (errorDiffusionBuffer) { - const size_t srcColIndex = col + firstSourceCol; - const size_t destColIndex = col + firstDestCol; - - const unsigned int srcIndex = (currentSourceRow[srcColIndex / 8] >> (8 - ((srcColIndex & 7) + 1))) & 0x01; - currentDestRow[destColIndex] = paletteMapping[srcIndex]; + std::swap(errorDiffusionCurrentRow, errorDiffusionNextRow); + memset(errorDiffusionNextRow, 0, sizeof(int16_t) * numCopyCols * 3); } - } - else if (bpp == 4) - { - for (size_t col = 0; col < numCopyCols; col++) - { - const size_t srcColIndex = col + firstSourceCol; - const size_t destColIndex = col + firstDestCol; - const unsigned int srcIndex = (currentSourceRow[srcColIndex / 2] >> (8 - ((srcColIndex & 1) + 1) * 4)) & 0x0f; - currentDestRow[destColIndex] = paletteMapping[srcIndex]; - } - } - else if (bpp == 8) - { - for (size_t col = 0; col < numCopyCols; col++) - { - const size_t srcColIndex = col + firstSourceCol; - const size_t destColIndex = col + firstDestCol; + assert(currentSourceRow >= imageDataStart && currentSourceRow <= imageDataStart + inDataSize); - const unsigned int srcIndex = currentSourceRow[srcColIndex]; - currentDestRow[destColIndex] = paletteMapping[srcIndex]; - } - } - else if (bpp == 16) - { - if (destFormat == GpPixelFormats::kBW1) + if (bpp == 1) { for (size_t col = 0; col < numCopyCols; col++) { const size_t srcColIndex = col + firstSourceCol; const size_t destColIndex = col + firstDestCol; - const uint8_t srcLow = currentSourceRow[srcColIndex * 2 + 0]; - const uint8_t srcHigh = currentSourceRow[srcColIndex * 2 + 1]; - - const unsigned int combinedValue = srcLow | (srcHigh << 8); - const unsigned int b = (combinedValue & 0x1f); - const unsigned int g = ((combinedValue >> 5) & 0x1f); - const unsigned int r = ((combinedValue >> 10) & 0x1f); - - if (r + g + b > 46) - currentDestRow[destColIndex] = 0; - else - currentDestRow[destColIndex] = 1; + const unsigned int srcIndex = (currentSourceRow[srcColIndex / 8] >> (8 - ((srcColIndex & 7) + 1))) & 0x01; + currentDestRow[destColIndex] = paletteMapping[srcIndex]; } } - else + else if (bpp == 4) + { + for (size_t col = 0; col < numCopyCols; col++) + { + const size_t srcColIndex = col + firstSourceCol; + const size_t destColIndex = col + firstDestCol; + + const unsigned int srcIndex = (currentSourceRow[srcColIndex / 2] >> (8 - ((srcColIndex & 1) + 1) * 4)) & 0x0f; + currentDestRow[destColIndex] = paletteMapping[srcIndex]; + } + } + else if (bpp == 8) + { + for (size_t col = 0; col < numCopyCols; col++) + { + const size_t srcColIndex = col + firstSourceCol; + const size_t destColIndex = col + firstDestCol; + + const unsigned int srcIndex = currentSourceRow[srcColIndex]; + currentDestRow[destColIndex] = paletteMapping[srcIndex]; + } + } + else if (bpp == 16) + { + if (destFormat == GpPixelFormats::kBW1) + { + for (size_t col = 0; col < numCopyCols; col++) + { + const size_t srcColIndex = col + firstSourceCol; + const size_t destColIndex = col + firstDestCol; + + const uint8_t srcLow = currentSourceRow[srcColIndex * 2 + 0]; + const uint8_t srcHigh = currentSourceRow[srcColIndex * 2 + 1]; + + const unsigned int combinedValue = srcLow | (srcHigh << 8); + const unsigned int b = (combinedValue & 0x1f); + const unsigned int g = ((combinedValue >> 5) & 0x1f); + const unsigned int r = ((combinedValue >> 10) & 0x1f); + + if (r + g + b > 46) + currentDestRow[destColIndex] = 0; + else + currentDestRow[destColIndex] = 1; + } + } + else + { + for (size_t col = 0; col < numCopyCols; col++) + { + const size_t srcColIndex = col + firstSourceCol; + const size_t destColIndex = col + firstDestCol; + + const uint8_t srcLow = currentSourceRow[srcColIndex * 2 + 0]; + const uint8_t srcHigh = currentSourceRow[srcColIndex * 2 + 1]; + + const unsigned int combinedValue = srcLow | (srcHigh << 8); + const unsigned int b = (combinedValue & 0x1f); + const unsigned int g = ((combinedValue >> 5) & 0x1f); + const unsigned int r = ((combinedValue >> 10) & 0x1f); + + const unsigned int xr = (r << 5) | (r >> 2); + const unsigned int xg = (g << 5) | (g >> 2); + const unsigned int xb = (b << 5) | (b >> 2); + + ErrorDiffusionWorkPixel wp = ApplyErrorDiffusion(errorDiffusionCurrentRow, xr, xg, xb, col, numCopyCols); + + uint8_t colorIndex = stdPalette->MapColorLUT(PortabilityLayer::RGBAColor::Create(wp.m_8[0], wp.m_8[1], wp.m_8[2], 255)); + PortabilityLayer::RGBAColor resultColor = stdPalette->GetColors()[colorIndex]; + + RedistributeError(errorDiffusionNextRow, errorDiffusionCurrentRow, wp.m_16[0], wp.m_16[1], wp.m_16[2], resultColor.r, resultColor.g, resultColor.b, col, numCopyCols); + + currentDestRow[destColIndex] = colorIndex; + } + } + } + else if (bpp == 24) + { + if (destFormat == GpPixelFormats::kBW1) + { + for (size_t col = 0; col < numCopyCols; col++) + { + const size_t srcColIndex = col + firstSourceCol; + const size_t destColIndex = col + firstDestCol; + + const uint8_t srcLow = currentSourceRow[srcColIndex * 2 + 0]; + const uint8_t srcHigh = currentSourceRow[srcColIndex * 2 + 1]; + + const unsigned int combinedValue = srcLow | (srcHigh << 8); + const unsigned int b = (combinedValue & 0x1f); + const unsigned int g = ((combinedValue >> 5) & 0x1f); + const unsigned int r = ((combinedValue >> 10) & 0x1f); + + if (r + g + b > 46) + currentDestRow[destColIndex] = 0; + else + currentDestRow[destColIndex] = 1; + } + } + else + { + for (size_t col = 0; col < numCopyCols; col++) + { + const size_t srcColIndex = col + firstSourceCol; + const size_t destColIndex = col + firstDestCol; + + ErrorDiffusionWorkPixel wp = ApplyErrorDiffusion(errorDiffusionCurrentRow, currentSourceRow[srcColIndex * 3 + 2], currentSourceRow[srcColIndex * 3 + 1], currentSourceRow[srcColIndex * 3 + 0], col, numCopyCols); + + uint8_t colorIndex = stdPalette->MapColorLUT(PortabilityLayer::RGBAColor::Create(wp.m_8[0], wp.m_8[1], wp.m_8[2], 255)); + PortabilityLayer::RGBAColor resultColor = stdPalette->GetColors()[colorIndex]; + + RedistributeError(errorDiffusionNextRow, errorDiffusionCurrentRow, wp.m_16[0], wp.m_16[1], wp.m_16[2], resultColor.r, resultColor.g, resultColor.b, col, numCopyCols); + + currentDestRow[destColIndex] = colorIndex; + } + } + } + + currentSourceRow -= sourcePitch; + currentDestRow += destPitch; + } + + if (errorDiffusionBuffer) + memManager->Release(errorDiffusionBuffer); + } + break; + case GpPixelFormats::kRGB32: + { + const uint8_t *currentSourceRow = firstSourceRow; + uint8_t *currentDestRowBytes = firstDestRow; + + uint32_t blackColor32 = StdColors::Black().AsUInt32(); + uint32_t whiteColor32 = StdColors::White().AsUInt32(); + + uint32_t unpackedColors[256]; + + const PortabilityLayer::BitmapColorTableEntry *ctab = reinterpret_cast(ctabLoc); + for (size_t i = 0; i < numColors; i++) + unpackedColors[i] = PortabilityLayer::RGBAColor::Create(ctab[i].m_r, ctab[i].m_g, ctab[i].m_b, 255).AsUInt32(); + + for (size_t i = numColors; i < 256; i++) + unpackedColors[i] = StdColors::Black().AsUInt32(); + + for (uint32_t row = 0; row < numCopyRows; row++) + { + uint32_t *currentDestRow32 = reinterpret_cast(currentDestRowBytes); + + assert(currentSourceRow >= imageDataStart && currentSourceRow <= imageDataStart + inDataSize); + + if (bpp == 1) + { + for (size_t col = 0; col < numCopyCols; col++) + { + const size_t srcColIndex = col + firstSourceCol; + const size_t destColIndex = col + firstDestCol; + + const unsigned int srcIndex = (currentSourceRow[srcColIndex / 8] >> (8 - ((srcColIndex & 7) + 1))) & 0x01; + currentDestRow32[destColIndex] = srcIndex ? blackColor32 : whiteColor32; + } + } + else if (bpp == 4) + { + for (size_t col = 0; col < numCopyCols; col++) + { + const size_t srcColIndex = col + firstSourceCol; + const size_t destColIndex = col + firstDestCol; + + const unsigned int srcIndex = (currentSourceRow[srcColIndex / 2] >> (8 - ((srcColIndex & 1) + 1) * 4)) & 0x0f; + currentDestRow32[destColIndex] = unpackedColors[srcIndex]; + } + } + else if (bpp == 8) + { + for (size_t col = 0; col < numCopyCols; col++) + { + const size_t srcColIndex = col + firstSourceCol; + const size_t destColIndex = col + firstDestCol; + + const unsigned int srcIndex = currentSourceRow[srcColIndex]; + currentDestRow32[destColIndex] = unpackedColors[srcIndex]; + } + } + else if (bpp == 16) { for (size_t col = 0; col < numCopyCols; col++) { @@ -679,67 +966,31 @@ void DrawSurface::DrawPicture(THandle pictHdl, const Rect &bounds) const unsigned int xg = (g << 5) | (g >> 2); const unsigned int xb = (b << 5) | (b >> 2); - ErrorDiffusionWorkPixel wp = ApplyErrorDiffusion(errorDiffusionCurrentRow, xr, xg, xb, col, numCopyCols); - - uint8_t colorIndex = stdPalette->MapColorLUT(PortabilityLayer::RGBAColor::Create(wp.m_8[0], wp.m_8[1], wp.m_8[2], 255)); - PortabilityLayer::RGBAColor resultColor = stdPalette->GetColors()[colorIndex]; - - RedistributeError(errorDiffusionNextRow, errorDiffusionCurrentRow, wp.m_16[0], wp.m_16[1], wp.m_16[2], resultColor.r, resultColor.g, resultColor.b, col, numCopyCols); - - currentDestRow[destColIndex] = colorIndex; + currentDestRowBytes[destColIndex * 4 + 0] = xr; + currentDestRowBytes[destColIndex * 4 + 1] = xg; + currentDestRowBytes[destColIndex * 4 + 2] = xb; + currentDestRowBytes[destColIndex * 4 + 3] = 255; } } - } - else if (bpp == 24) - { - if (destFormat == GpPixelFormats::kBW1) + else if (bpp == 24) { for (size_t col = 0; col < numCopyCols; col++) { const size_t srcColIndex = col + firstSourceCol; const size_t destColIndex = col + firstDestCol; - const uint8_t srcLow = currentSourceRow[srcColIndex * 2 + 0]; - const uint8_t srcHigh = currentSourceRow[srcColIndex * 2 + 1]; - - const unsigned int combinedValue = srcLow | (srcHigh << 8); - const unsigned int b = (combinedValue & 0x1f); - const unsigned int g = ((combinedValue >> 5) & 0x1f); - const unsigned int r = ((combinedValue >> 10) & 0x1f); - - if (r + g + b > 46) - currentDestRow[destColIndex] = 0; - else - currentDestRow[destColIndex] = 1; + currentDestRowBytes[destColIndex * 4 + 0] = currentSourceRow[srcColIndex * 3 + 2]; + currentDestRowBytes[destColIndex * 4 + 1] = currentSourceRow[srcColIndex * 3 + 1]; + currentDestRowBytes[destColIndex * 4 + 2] = currentSourceRow[srcColIndex * 3 + 0]; + currentDestRowBytes[destColIndex * 4 + 3] = 255; } } - else - { - for (size_t col = 0; col < numCopyCols; col++) - { - const size_t srcColIndex = col + firstSourceCol; - const size_t destColIndex = col + firstDestCol; - ErrorDiffusionWorkPixel wp = ApplyErrorDiffusion(errorDiffusionCurrentRow, currentSourceRow[srcColIndex * 3 + 2], currentSourceRow[srcColIndex * 3 + 1], currentSourceRow[srcColIndex * 3 + 0], col, numCopyCols); - - uint8_t colorIndex = stdPalette->MapColorLUT(PortabilityLayer::RGBAColor::Create(wp.m_8[0], wp.m_8[1], wp.m_8[2], 255)); - PortabilityLayer::RGBAColor resultColor = stdPalette->GetColors()[colorIndex]; - - RedistributeError(errorDiffusionNextRow, errorDiffusionCurrentRow, wp.m_16[0], wp.m_16[1], wp.m_16[2], resultColor.r, resultColor.g, resultColor.b, col, numCopyCols); - - currentDestRow[destColIndex] = colorIndex; - } - } + currentSourceRow -= sourcePitch; + currentDestRowBytes += destPitch; } - - currentSourceRow -= sourcePitch; - currentDestRow += destPitch; } - - if (errorDiffusionBuffer) - memManager->Release(errorDiffusionBuffer); - } - break; + break; default: // TODO: Implement higher-resolution pixel blitters assert(false); @@ -767,7 +1018,7 @@ void DrawSurface::FillRect(const Rect &rect, PortabilityLayer::ResolveCachingCol PortabilityLayer::PixMapImpl *pixMap = static_cast(*qdPort->GetPixMap()); const size_t pitch = pixMap->GetPitch(); - const size_t firstIndex = static_cast(constrainedRect.top) * pitch + static_cast(constrainedRect.left); + const size_t firstRowStartIndex = static_cast(constrainedRect.top) * pitch; const size_t numLines = static_cast(constrainedRect.bottom - constrainedRect.top); const size_t numCols = static_cast(constrainedRect.right - constrainedRect.left); uint8_t *pixData = static_cast(pixMap->GetPixelData()); @@ -776,6 +1027,7 @@ void DrawSurface::FillRect(const Rect &rect, PortabilityLayer::ResolveCachingCol { case GpPixelFormats::k8BitStandard: { + const size_t firstIndex = firstRowStartIndex + static_cast(constrainedRect.left); const uint8_t color = cacheColor.Resolve8(nullptr, 0); size_t scanlineIndex = 0; @@ -787,6 +1039,20 @@ void DrawSurface::FillRect(const Rect &rect, PortabilityLayer::ResolveCachingCol } } break; + case GpPixelFormats::kRGB32: + { + const size_t firstIndex = firstRowStartIndex + static_cast(constrainedRect.left) * 4; + const uint32_t color = cacheColor.GetRGBAColor().AsUInt32(); + + size_t scanlineIndex = 0; + for (size_t ln = 0; ln < numLines; ln++) + { + const size_t firstLineIndex = firstIndex + ln * pitch; + for (size_t col = 0; col < numCols; col++) + reinterpret_cast(pixData[firstLineIndex + col * 4]) = color; + } + } + break; default: PL_NotYetImplemented(); return; @@ -816,7 +1082,7 @@ void DrawSurface::FillRectWithMaskPattern8x8(const Rect &rect, const uint8_t *pa PortabilityLayer::PixMapImpl *pixMap = static_cast(*qdPort->GetPixMap()); const size_t pitch = pixMap->GetPitch(); - const size_t firstIndex = static_cast(constrainedRect.top) * pitch + static_cast(constrainedRect.left); + const size_t rowFirstIndex = static_cast(constrainedRect.top) * pitch; const size_t numLines = static_cast(constrainedRect.bottom - constrainedRect.top); const size_t numCols = static_cast(constrainedRect.right - constrainedRect.left); uint8_t *pixData = static_cast(pixMap->GetPixelData()); @@ -827,25 +1093,45 @@ void DrawSurface::FillRectWithMaskPattern8x8(const Rect &rect, const uint8_t *pa switch (pixelFormat) { case GpPixelFormats::k8BitStandard: - { - const uint8_t color = cacheColor.Resolve8(nullptr, 0); - uint8_t backColor = 0; - - size_t scanlineIndex = 0; - for (size_t ln = 0; ln < numLines; ln++) { - const int patternRow = static_cast((patternFirstRow + ln) & 7); - const size_t firstLineIndex = firstIndex + ln * pitch; + const size_t firstIndex = rowFirstIndex + static_cast(constrainedRect.left); + const uint8_t color = cacheColor.Resolve8(nullptr, 0); - for (size_t col = 0; col < numCols; col++) + size_t scanlineIndex = 0; + for (size_t ln = 0; ln < numLines; ln++) { - const int patternCol = static_cast((patternFirstCol + col) & 7); - if ((pattern[patternRow] >> patternCol) & 1) - pixData[firstLineIndex + col] = color; + const int patternRow = static_cast((patternFirstRow + ln) & 7); + const size_t firstLineIndex = firstIndex + ln * pitch; + + for (size_t col = 0; col < numCols; col++) + { + const int patternCol = static_cast((patternFirstCol + col) & 7); + if ((pattern[patternRow] >> patternCol) & 1) + pixData[firstLineIndex + col] = color; + } } } - } - break; + break; + case GpPixelFormats::kRGB32: + { + const size_t firstIndex = rowFirstIndex + static_cast(constrainedRect.left) * 4; + const uint32_t color = cacheColor.GetRGBAColor().AsUInt32(); + + size_t scanlineIndex = 0; + for (size_t ln = 0; ln < numLines; ln++) + { + const int patternRow = static_cast((patternFirstRow + ln) & 7); + const size_t firstLineIndex = firstIndex + ln * pitch; + + for (size_t col = 0; col < numCols; col++) + { + const int patternCol = static_cast((patternFirstCol + col) & 7); + if ((pattern[patternRow] >> patternCol) & 1) + reinterpret_cast(pixData[firstLineIndex + col * 4]) = color; + } + } + } + break; default: PL_NotYetImplemented(); return; @@ -957,7 +1243,7 @@ void DrawSurface::FrameEllipse(const Rect &rect, PortabilityLayer::ResolveCachin m_port.SetDirty(PortabilityLayer::QDPortDirtyFlag_Contents); } -static void FillScanlineSpan(uint8_t *rowStart, size_t startCol, size_t endCol, uint8_t patternByte, uint8_t foreColor) +static void FillScanlineSpan8(uint8_t *rowStart, size_t startCol, size_t endCol, uint8_t patternByte, uint8_t foreColor) { if (patternByte == 0xff) { @@ -974,6 +1260,25 @@ static void FillScanlineSpan(uint8_t *rowStart, size_t startCol, size_t endCol, } } +static void FillScanlineSpan32(uint8_t *rowStartBytes, size_t startCol, size_t endCol, uint8_t patternByte, uint32_t foreColor) +{ + uint32_t *rowStart = reinterpret_cast(rowStartBytes); + + if (patternByte == 0xff) + { + for (size_t col = startCol; col < endCol; col++) + rowStart[col] = foreColor; + } + else + { + for (size_t col = startCol; col < endCol; col++) + { + if (patternByte & (0x80 >> (col & 7))) + rowStart[col] = foreColor; + } + } +} + void DrawSurface::FillScanlineMask(const PortabilityLayer::ScanlineMask *scanlineMask, PortabilityLayer::ResolveCachingColor &cacheColor) { FillScanlineMaskWithMaskPattern(scanlineMask, nullptr, cacheColor); @@ -1011,15 +1316,19 @@ void DrawSurface::FillScanlineMaskWithMaskPattern(const PortabilityLayer::Scanli } uint8_t foreColor8 = 0; + uint32_t foreColor32 = 0; const GpPixelFormat_t pixelFormat = pixMap->m_pixelFormat; size_t pixelSize = 0; - switch (pixMap->m_pixelFormat) + switch (pixelFormat) { case GpPixelFormats::k8BitStandard: foreColor8 = cacheColor.Resolve8(nullptr, 256); break; + case GpPixelFormats::kRGB32: + foreColor32 = cacheColor.GetRGBAColor().AsUInt32(); + break; default: PL_NotYetImplemented(); return; @@ -1088,7 +1397,14 @@ void DrawSurface::FillScanlineMaskWithMaskPattern(const PortabilityLayer::Scanli { const size_t spanEndCol = spanStartCol + currentSpan; if (spanState) - FillScanlineSpan(thisRowStart, spanStartCol, spanEndCol, thisRowPatternRow, foreColor8); + { + if (pixelFormat == GpPixelFormats::k8BitStandard) + FillScanlineSpan8(thisRowStart, spanStartCol, spanEndCol, thisRowPatternRow, foreColor8); + else if (pixelFormat == GpPixelFormats::kRGB32) + FillScanlineSpan32(thisRowStart, spanStartCol, spanEndCol, thisRowPatternRow, foreColor32); + else + PL_NotYetImplemented(); + } spanStartCol = spanEndCol; paintColsRemaining -= currentSpan; @@ -1101,7 +1417,12 @@ void DrawSurface::FillScanlineMaskWithMaskPattern(const PortabilityLayer::Scanli if (spanState) { const size_t spanEndCol = firstPortCol + constrainedRectWidth; - FillScanlineSpan(thisRowStart, spanStartCol, spanEndCol, thisRowPatternRow, foreColor8); + if (pixelFormat == GpPixelFormats::k8BitStandard) + FillScanlineSpan8(thisRowStart, spanStartCol, spanEndCol, thisRowPatternRow, foreColor8); + else if (pixelFormat == GpPixelFormats::kRGB32) + FillScanlineSpan32(thisRowStart, spanStartCol, spanEndCol, thisRowPatternRow, foreColor32); + else + PL_NotYetImplemented(); } if (row != numRows - 1) @@ -1212,7 +1533,7 @@ void DrawSurface::InvertFillRect(const Rect &rect, const uint8_t *pattern) PortabilityLayer::PixMapImpl *pixMap = static_cast(*qdPort->GetPixMap()); const size_t pitch = pixMap->GetPitch(); - const size_t firstIndex = static_cast(constrainedRect.top) * pitch + static_cast(constrainedRect.left); + const size_t rowFirstIndex = static_cast(constrainedRect.top) * pitch; const size_t numLines = static_cast(constrainedRect.bottom - constrainedRect.top); const size_t numCols = static_cast(constrainedRect.right - constrainedRect.left); uint8_t *pixData = static_cast(pixMap->GetPixelData()); @@ -1223,22 +1544,41 @@ void DrawSurface::InvertFillRect(const Rect &rect, const uint8_t *pattern) switch (pixelFormat) { case GpPixelFormats::k8BitStandard: - { - size_t scanlineIndex = 0; - for (size_t ln = 0; ln < numLines; ln++) { - const int patternRow = static_cast((patternFirstRow + ln) & 7); - const size_t firstLineIndex = firstIndex + ln * pitch; - - for (size_t col = 0; col < numCols; col++) + const size_t firstIndex = rowFirstIndex + static_cast(constrainedRect.left); + size_t scanlineIndex = 0; + for (size_t ln = 0; ln < numLines; ln++) { - const int patternCol = static_cast((patternFirstCol + col) & 7); - if ((pattern[patternRow] >> patternCol) & 1) - InvertPixel8(pixData[firstLineIndex + col]); + const int patternRow = static_cast((patternFirstRow + ln) & 7); + const size_t firstLineIndex = firstIndex + ln * pitch; + + for (size_t col = 0; col < numCols; col++) + { + const int patternCol = static_cast((patternFirstCol + col) & 7); + if ((pattern[patternRow] >> patternCol) & 1) + InvertPixel8(pixData[firstLineIndex + col]); + } } } - } - break; + break; + case GpPixelFormats::kRGB32: + { + const size_t firstIndex = rowFirstIndex + static_cast(constrainedRect.left) * 4; + size_t scanlineIndex = 0; + for (size_t ln = 0; ln < numLines; ln++) + { + const int patternRow = static_cast((patternFirstRow + ln) & 7); + const size_t firstLineIndex = firstIndex + ln * pitch; + + for (size_t col = 0; col < numCols; col++) + { + const int patternCol = static_cast((patternFirstCol + col) & 7); + if ((pattern[patternRow] >> patternCol) & 1) + InvertPixel32(pixData + (firstLineIndex + col * 4)); + } + } + } + break; default: PL_NotYetImplemented(); return; @@ -1291,7 +1631,7 @@ void GetIndPattern(Pattern *pattern, int patListID, int index) memcpy(pattern, patternRes + 2 + (index - 1) * 8, 8); } -static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase, const Rect *maskConstraintRect) +static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap8, const BitMap *maskBitmap32, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase, const Rect *maskConstraintRect) { assert(srcBitmap->m_pixelFormat == destBitmap->m_pixelFormat); @@ -1300,7 +1640,23 @@ static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap, const GpPixelFormat_t pixelFormat = srcBitmap->m_pixelFormat; const size_t srcPitch = srcBitmap->m_pitch; const size_t destPitch = destBitmap->m_pitch; - const size_t maskPitch = (maskBitmap != nullptr) ? maskBitmap->m_pitch : 0; + size_t maskPitch = 0; + + const BitMap *maskBitmapSelected = nullptr; + if (maskBitmap8) + { + assert(maskBitmap32 == nullptr); + maskPitch = maskBitmap8->m_pitch; + maskBitmapSelected = maskBitmap8; + } + if (maskBitmap32) + { + assert(maskBitmap8 == nullptr); + maskPitch = maskBitmap32->m_pitch; + maskBitmapSelected = maskBitmap32; + } + + assert((maskBitmapSelected == nullptr) == (maskRectBase == nullptr)); if (srcRectBase->right - srcRectBase->left != destRectBase->right - destRectBase->left || srcRectBase->bottom - srcRectBase->top != destRectBase->bottom - destRectBase->top) @@ -1309,14 +1665,19 @@ static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap, return; } - if (maskBitmap) + if (maskBitmap8) { assert(maskRectBase); assert(maskRectBase->right - maskRectBase->left == srcRectBase->right - srcRectBase->left); - assert(maskBitmap->m_pixelFormat == GpPixelFormats::kBW1 || maskBitmap->m_pixelFormat == GpPixelFormats::k8BitStandard); + assert(maskBitmap8->m_pixelFormat == GpPixelFormats::kBW1 || maskBitmap8->m_pixelFormat == GpPixelFormats::k8BitStandard); } - assert((maskBitmap == nullptr) == (maskRectBase == nullptr)); + if (maskBitmap32) + { + assert(maskRectBase); + assert(maskRectBase->right - maskRectBase->left == srcRectBase->right - srcRectBase->left); + assert(maskBitmap32->m_pixelFormat == GpPixelFormats::kRGB32); + } Rect srcRect; Rect destRect; @@ -1404,8 +1765,8 @@ static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap, const size_t destFirstCol = destRect.left - destBitmap->m_rect.left; const size_t destFirstRow = destRect.top - destBitmap->m_rect.top; - const size_t maskFirstCol = maskBitmap ? constrainedMaskRect.left - maskBitmap->m_rect.left : 0; - const size_t maskFirstRow = maskBitmap ? constrainedMaskRect.top - maskBitmap->m_rect.top : 0; + const size_t maskFirstCol = maskBitmapSelected ? constrainedMaskRect.left - maskBitmapSelected->m_rect.left : 0; + const size_t maskFirstRow = maskBitmapSelected ? constrainedMaskRect.top - maskBitmapSelected->m_rect.top : 0; { size_t pixelSizeBytes = 0; @@ -1429,17 +1790,17 @@ static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap, const uint8_t *srcBytes = static_cast(srcBitmap->m_data); uint8_t *destBytes = static_cast(destBitmap->m_data); - const uint8_t *maskBytes = maskBitmap ? static_cast(maskBitmap->m_data) : nullptr; + const uint8_t *maskBytes = maskBitmapSelected ? static_cast(maskBitmapSelected->m_data) : nullptr; const size_t firstSrcByte = srcFirstRow * srcPitch + srcFirstCol * pixelSizeBytes; const size_t firstDestByte = destFirstRow * destPitch + destFirstCol * pixelSizeBytes; - const size_t firstMaskRowByte = maskBitmap ? maskFirstRow * maskPitch : 0; + const size_t firstMaskRowByte = maskBitmapSelected ? maskFirstRow * maskPitch : 0; const size_t numCopiedRows = srcRect.bottom - srcRect.top; const size_t numCopiedCols = srcRect.right - srcRect.left; const size_t numCopiedBytesPerScanline = numCopiedCols * pixelSizeBytes; - if (maskBitmap) + if (maskBitmap8) { for (size_t i = 0; i < numCopiedRows; i++) { @@ -1469,6 +1830,36 @@ static void CopyBitsComplete(const BitMap *srcBitmap, const BitMap *maskBitmap, memcpy(destRow + numCopiedCols * pixelSizeBytes - span, srcRow + numCopiedCols * pixelSizeBytes - span, span); } } + else if (maskBitmap32) + { + for (size_t i = 0; i < numCopiedRows; i++) + { + uint8_t *destRow = destBytes + firstDestByte + i * destPitch; + const uint8_t *srcRow = srcBytes + firstSrcByte + i * srcPitch; + const uint8_t *rowMaskBytes = maskBytes + firstMaskRowByte + i * maskPitch; + + size_t span = 0; + + for (size_t col = 0; col < numCopiedCols; col++) + { + const size_t maskBitOffset = maskFirstCol + col; + //const bool maskBit = ((maskBytes[maskBitOffset / 8] & (0x80 >> (maskBitOffset & 7))) != 0); + const bool maskBit = (reinterpret_cast(rowMaskBytes)[maskBitOffset] != 0xffffffffU); + if (maskBit) + span += pixelSizeBytes; + else + { + if (span != 0) + memcpy(destRow + col * pixelSizeBytes - span, srcRow + col * pixelSizeBytes - span, span); + + span = 0; + } + } + + if (span != 0) + memcpy(destRow + numCopiedCols * pixelSizeBytes - span, srcRow + numCopiedCols * pixelSizeBytes - span, span); + } + } else { for (size_t i = 0; i < numCopiedRows; i++) @@ -1484,20 +1875,26 @@ void CopyBits(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRectBa void CopyBitsConstrained(const BitMap *srcBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *destRectBase, CopyBitsMode copyMode, const Rect *constrainRect) { - const BitMap *maskBitmap = nullptr; + const BitMap *maskBitmap8 = nullptr; + const BitMap *maskBitmap32 = nullptr; const Rect *maskRect = nullptr; if (copyMode == transparent && srcBitmap->m_pixelFormat == GpPixelFormats::k8BitStandard) { - maskBitmap = srcBitmap; + maskBitmap8 = srcBitmap; + maskRect = srcRectBase; + } + if (copyMode == transparent && srcBitmap->m_pixelFormat == GpPixelFormats::kRGB32) + { + maskBitmap32 = srcBitmap; maskRect = srcRectBase; } - CopyBitsComplete(srcBitmap, maskBitmap, destBitmap, srcRectBase, maskRect, destRectBase, constrainRect); + CopyBitsComplete(srcBitmap, maskBitmap8, maskBitmap32, destBitmap, srcRectBase, maskRect, destRectBase, constrainRect); } void CopyMaskConstrained(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase, const Rect *constrainRect) { - CopyBitsComplete(srcBitmap, maskBitmap, destBitmap, srcRectBase, maskRectBase, destRectBase, constrainRect); + CopyBitsComplete(srcBitmap, maskBitmap, nullptr, destBitmap, srcRectBase, maskRectBase, destRectBase, constrainRect); } // This doesn't bounds-check the source (because it's only used in one place) @@ -1551,6 +1948,15 @@ void ImageInvert(const PixMap *invertMask, PixMap *targetBitmap, const Rect &src InvertPixel8(targetRowStart[destCol]); } break; + case GpPixelFormats::kRGB32: + for (uint16_t c = 0; c < numCols; c++) + { + const int32_t srcCol = c + firstSrcCol; + const int32_t destCol = c + firstDestCol; + if (invertRowStart[srcCol] != 0) + InvertPixel32(targetRowStart + destCol * 4); + } + break; default: PL_NotYetImplemented(); break; @@ -1566,7 +1972,7 @@ bool PointInScanlineMask(Point point, PortabilityLayer::ScanlineMask *scanlineMa void CopyMask(const BitMap *srcBitmap, const BitMap *maskBitmap, BitMap *destBitmap, const Rect *srcRectBase, const Rect *maskRectBase, const Rect *destRectBase) { - CopyBitsComplete(srcBitmap, maskBitmap, destBitmap, srcRectBase, maskRectBase, destRectBase, nullptr); + CopyBitsComplete(srcBitmap, maskBitmap, nullptr, destBitmap, srcRectBase, maskRectBase, destRectBase, nullptr); } PixMap *GetPortBitMapForCopyBits(DrawSurface *grafPtr) diff --git a/PortabilityLayer/QDGraf.cpp b/PortabilityLayer/QDGraf.cpp index 03e24d2..34c51b3 100644 --- a/PortabilityLayer/QDGraf.cpp +++ b/PortabilityLayer/QDGraf.cpp @@ -8,8 +8,8 @@ DrawSurface::~DrawSurface() { - if (m_cachedAATable) - PortabilityLayer::MemoryManager::GetInstance()->Release(m_cachedAATable); + if (m_cachedAATables) + PortabilityLayer::MemoryManager::GetInstance()->Release(m_cachedAATables); } void DrawSurface::PushToDDSurface(IGpDisplayDriver *displayDriver) diff --git a/PortabilityLayer/QDGraf.h b/PortabilityLayer/QDGraf.h index e63ba66..f3b419d 100644 --- a/PortabilityLayer/QDGraf.h +++ b/PortabilityLayer/QDGraf.h @@ -32,7 +32,7 @@ struct DrawSurface : m_port(PortabilityLayer::QDPortType_DrawSurface) , m_ddSurface(nullptr) , m_cachedAAColor(PortabilityLayer::RGBAColor::Create(0, 0, 0, 255)) - , m_cachedAATable(nullptr) + , m_cachedAATables(nullptr) { } @@ -40,7 +40,7 @@ struct DrawSurface : m_port(overridePortType) , m_ddSurface(nullptr) , m_cachedAAColor(PortabilityLayer::RGBAColor::Create(0, 0, 0, 255)) - , m_cachedAATable(nullptr) + , m_cachedAATables(nullptr) { } @@ -85,7 +85,7 @@ struct DrawSurface IGpDisplayDriverSurface *m_ddSurface; - PortabilityLayer::AntiAliasTable *m_cachedAATable; + PortabilityLayer::AntiAliasTable *m_cachedAATables; PortabilityLayer::RGBAColor m_cachedAAColor; PortabilityLayer::QDPort m_port; diff --git a/PortabilityLayer/QDPixMap.cpp b/PortabilityLayer/QDPixMap.cpp index 35f1e00..e26f57d 100644 --- a/PortabilityLayer/QDPixMap.cpp +++ b/PortabilityLayer/QDPixMap.cpp @@ -1,9 +1,12 @@ #include "QDPixMap.h" #include "CoreDefs.h" #include "MemoryManager.h" +#include "QDStandardPalette.h" #include +static const PortabilityLayer::RGBAColor *gs_staticPalette = PortabilityLayer::StandardPalette::GetInstance()->GetColors(); + class PixMapSampler_8BitStandard { public: @@ -11,6 +14,26 @@ public: { return static_cast(rowData)[index]; } + + inline static uint32_t ReadAsRGBA(const void *rowData, size_t index) + { + return gs_staticPalette[static_cast(rowData)[index]].AsUInt32(); + } +}; + +class PixMapSampler_32Bit +{ +public: + inline static uint8_t ReadAs8BitStandard(const void *rowData, size_t index) + { + const uint8_t *pixelData = static_cast(rowData) + index * 4; + return PortabilityLayer::StandardPalette::GetInstance()->MapColorLUT(PortabilityLayer::RGBAColor::Create(pixelData[0], pixelData[1], pixelData[2], 255)); + } + + inline static uint32_t ReadAsRGBA(const void *rowData, size_t index) + { + return static_cast(rowData)[index]; + } }; template @@ -23,6 +46,16 @@ public: } }; +template +class PixMapCopier_32Bit +{ +public: + inline static void Copy(const void *inData, size_t inIndex, void *outData, size_t outIndex) + { + static_cast(outData)[outIndex] = TSampler::ReadAsRGBA(inData, inIndex); + } +}; + template class PixMapColBlitter { @@ -139,6 +172,9 @@ public: case GpPixelFormats::k8BitStandard: blitFunc = PixMapRowBlitter >::Blit; break; + case GpPixelFormats::kRGB32: + blitFunc = PixMapRowBlitter >::Blit; + break; default: PL_NotYetImplemented(); break; @@ -163,6 +199,9 @@ public: case GpPixelFormats::k8BitStandard: blitFunc = PixMapBlitTargetDisambiguator::Blit; break; + case GpPixelFormats::kRGB32: + blitFunc = PixMapBlitTargetDisambiguator::Blit; + break; default: PL_NotYetImplemented(); break; diff --git a/PortabilityLayer/QDStandardPalette.cpp b/PortabilityLayer/QDStandardPalette.cpp index 8e721b1..788a33c 100644 --- a/PortabilityLayer/QDStandardPalette.cpp +++ b/PortabilityLayer/QDStandardPalette.cpp @@ -115,6 +115,9 @@ namespace PortabilityLayer m_blackAATable.GenerateForPalette(RGBAColor::Create(0, 0, 0, 255), m_colors, 256); m_whiteAATable.GenerateForPalette(RGBAColor::Create(255, 255, 255, 255), m_colors, 256); #endif + + m_whiteToneAATable.GenerateForSimpleScale(255); + m_blackToneAATable.GenerateForSimpleScale(0); } const RGBAColor *StandardPalette::GetColors() const @@ -273,5 +276,15 @@ namespace PortabilityLayer return m_blackAATable; } + const AntiAliasTable &StandardPalette::GetWhiteToneAATable() const + { + return m_whiteToneAATable; + } + + const AntiAliasTable &StandardPalette::GetBlackToneAATable() const + { + return m_blackToneAATable; + } + StandardPalette StandardPalette::ms_instance; } diff --git a/PortabilityLayer/QDStandardPalette.h b/PortabilityLayer/QDStandardPalette.h index e081cf2..610b20d 100644 --- a/PortabilityLayer/QDStandardPalette.h +++ b/PortabilityLayer/QDStandardPalette.h @@ -23,6 +23,9 @@ namespace PortabilityLayer const AntiAliasTable &GetWhiteAATable() const; const AntiAliasTable &GetBlackAATable() const; + const AntiAliasTable &GetWhiteToneAATable() const; + const AntiAliasTable &GetBlackToneAATable() const; + static const StandardPalette *GetInstance(); private: @@ -31,6 +34,8 @@ namespace PortabilityLayer RGBAColor m_colors[kSize]; AntiAliasTable m_whiteAATable; AntiAliasTable m_blackAATable; + AntiAliasTable m_whiteToneAATable; + AntiAliasTable m_blackToneAATable; uint8_t m_lut[16 * 16 * 16]; }; } diff --git a/PortabilityLayer/RGBAColor.h b/PortabilityLayer/RGBAColor.h index 402687d..fa907f2 100644 --- a/PortabilityLayer/RGBAColor.h +++ b/PortabilityLayer/RGBAColor.h @@ -10,7 +10,9 @@ namespace PortabilityLayer bool operator==(const RGBAColor &other) const; bool operator!=(const RGBAColor &other) const; - static RGBAColor Create(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + static RGBAColor Create(uint8_t r, uint8_t g, uint8_t b, uint8_t a); + + uint32_t AsUInt32() const; }; inline RGBAColor RGBAColor::Create(uint8_t r, uint8_t g, uint8_t b, uint8_t a) @@ -32,5 +34,16 @@ namespace PortabilityLayer inline bool RGBAColor::operator!=(const RGBAColor &other) const { return !((*this) == other); - } + } + + inline uint32_t RGBAColor::AsUInt32() const + { + uint32_t rgbaColor = 0; + uint8_t *rgbaColorBytes = reinterpret_cast(&rgbaColor); + rgbaColorBytes[0] = r; + rgbaColorBytes[1] = g; + rgbaColorBytes[2] = b; + rgbaColorBytes[3] = a; + return rgbaColor; + } } diff --git a/PortabilityLayer/SimpleGraphic.cpp b/PortabilityLayer/SimpleGraphic.cpp index 86acc4b..db2b3a2 100644 --- a/PortabilityLayer/SimpleGraphic.cpp +++ b/PortabilityLayer/SimpleGraphic.cpp @@ -92,6 +92,42 @@ namespace PortabilityLayer } } break; + case GpPixelFormats::kRGB32: + { + uint8_t *destFirstPixel = static_cast(pixMapData) + destXOffset * 4 + destYOffset * destPitch; + const PortabilityLayer::RGBAColor *srcPixel = m_pixelData; + + for (size_t row = 0; row < srcHeight; row++) + { + uint8_t *destRowFirstPixel = destFirstPixel + row * destPitch; + + if (maskData) + { + for (size_t col = 0; col < srcWidth; col++) + { + if (maskData[maskOffset / 8] & (0x80 >> (maskOffset & 7))) + { + destRowFirstPixel[col * 4 + 0] = srcPixel->r; + destRowFirstPixel[col * 4 + 1] = srcPixel->g; + destRowFirstPixel[col * 4 + 2] = srcPixel->b; + } + srcPixel++; + maskOffset++; + } + } + else + { + for (size_t col = 0; col < srcWidth; col++) + { + destRowFirstPixel[col * 4 + 0] = srcPixel->r; + destRowFirstPixel[col * 4 + 1] = srcPixel->g; + destRowFirstPixel[col * 4 + 2] = srcPixel->b; + srcPixel++; + } + } + } + } + break; default: PL_NotYetImplemented(); break; diff --git a/PortabilityLayer/WindowManager.cpp b/PortabilityLayer/WindowManager.cpp index 7817af2..b60ede1 100644 --- a/PortabilityLayer/WindowManager.cpp +++ b/PortabilityLayer/WindowManager.cpp @@ -839,6 +839,9 @@ namespace PortabilityLayer if (int errorCode = m_surface.Init(adjustedBounds, pixelFormat)) return false; + PortabilityLayer::ResolveCachingColor whiteColor = StdColors::White(); + m_surface.FillRect(adjustedBounds, whiteColor); + m_title.Set(windowDef.m_title[0], reinterpret_cast(windowDef.m_title + 1)); // Resolve chrome diff --git a/ShaderSrc/DrawQuadRGBP.hlsl b/ShaderSrc/DrawQuadRGBP.hlsl index 92177c4..00a98e2 100644 --- a/ShaderSrc/DrawQuadRGBP.hlsl +++ b/ShaderSrc/DrawQuadRGBP.hlsl @@ -1,4 +1,6 @@ #include "DrawQuad.h" +#include "DrawQuadPixelConstants.h" +#include "Functions.h" SamplerState surfaceSampler : register(s0); Texture2D surfaceTexture : register(t0); @@ -8,11 +10,24 @@ struct SDrawQuadPixelOutput float4 color : SV_TARGET; }; +float3 SamplePixel(int2 texCoord) +{ + return surfaceTexture.Load(int3(texCoord, 0)); +} + SDrawQuadPixelOutput PSMain(SDrawQuadPixelInput input) { - float3 surfaceColor = surfaceTexture.Load(int3(input.texCoord.xy, 0)).rgb; - SDrawQuadPixelOutput result; - result.color = float4(surfaceColor, 1.0); + int2 pixelCoordinate = int2(floor(input.texCoord.xy)); + result.color = float4(SamplePixel(int2(floor(input.texCoord.xy))), 1.0); + result.color *= constants_Modulation; + result.color = ApplyFlicker(pixelCoordinate, constants_FlickerStartThreshold, constants_FlickerEndThreshold, result.color * constants_Modulation); + result.color = ApplyDesaturation(constants_Desaturation, result.color); + + if (result.color.a <= 0.0) + discard; + + result.color.rgb = AppleRGBToSRGBLinear(result.color.rgb); + return result; }