diff --git a/DDrawCompat/Gdi/DcFunctions.cpp b/DDrawCompat/Gdi/DcFunctions.cpp index 0664cf9..1c3f9d5 100644 --- a/DDrawCompat/Gdi/DcFunctions.cpp +++ b/DDrawCompat/Gdi/DcFunctions.cpp @@ -269,13 +269,33 @@ namespace return compatGdiDcFunc(dc, params...); } + HBITMAP WINAPI createBitmap(int nWidth, int nHeight, UINT nPlanes, UINT nBitCount, const VOID* lpBits) + { + LOG_FUNC("CreateBitmap", nWidth, nHeight, nPlanes, nBitCount, lpBits); + if (!g_disableDibRedirection && nWidth > 0 && nHeight > 0 && 1 == nPlanes && nBitCount >= 8) + { + HBITMAP bmp = Gdi::VirtualScreen::createOffScreenDib(nWidth, -nHeight, nBitCount); + if (bmp && lpBits) + { + SetBitmapBits(bmp, (nWidth * nBitCount + 15) / 16 * 2 * nHeight, lpBits); + } + return LOG_RESULT(bmp); + } + return LOG_RESULT(CALL_ORIG_FUNC(CreateBitmap)(nWidth, nHeight, nPlanes, nBitCount, lpBits)); + } + + HBITMAP WINAPI createBitmapIndirect(const BITMAP* pbm) + { + LOG_FUNC("CreateBitmapIndirect", pbm); + return LOG_RESULT(createBitmap(pbm->bmWidth, pbm->bmHeight, pbm->bmPlanes, pbm->bmBitsPixel, pbm->bmBits)); + } + HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy) { LOG_FUNC("CreateCompatibleBitmap", hdc, cx, cy); - if (!g_disableDibRedirection && Gdi::isDisplayDc(hdc)) + if (!g_disableDibRedirection && cx > 0 && cy > 0 && Gdi::isDisplayDc(hdc)) { - const bool useDefaultPalette = false; - return LOG_RESULT(Gdi::VirtualScreen::createOffScreenDib(cx, cy, useDefaultPalette)); + return LOG_RESULT(Gdi::VirtualScreen::createOffScreenDib(cx, -cy, Win32::DisplayMode::getBpp())); } return LOG_RESULT(CALL_ORIG_FUNC(CreateCompatibleBitmap)(hdc, cx, cy)); } @@ -287,9 +307,8 @@ namespace const DWORD CBM_CREATDIB = 2; if (!g_disableDibRedirection && !(fdwInit & CBM_CREATDIB) && lpbmih && Gdi::isDisplayDc(hdc)) { - const bool useDefaultPalette = false; HBITMAP bitmap = Gdi::VirtualScreen::createOffScreenDib( - lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, useDefaultPalette); + lpbmi->bmiHeader.biWidth, lpbmi->bmiHeader.biHeight, Win32::DisplayMode::getBpp()); if (bitmap && lpbInit && lpbmi) { SetDIBits(hdc, bitmap, 0, std::abs(lpbmi->bmiHeader.biHeight), lpbInit, lpbmi, fuUsage); @@ -302,12 +321,7 @@ namespace HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight) { LOG_FUNC("CreateDiscardableBitmap", hdc, nWidth, nHeight); - if (!g_disableDibRedirection && Gdi::isDisplayDc(hdc)) - { - const bool useDefaultPalette = false; - return LOG_RESULT(Gdi::VirtualScreen::createOffScreenDib(nWidth, nHeight, useDefaultPalette)); - } - return LOG_RESULT(CALL_ORIG_FUNC(createDiscardableBitmap)(hdc, nWidth, nHeight)); + return LOG_RESULT(CALL_ORIG_FUNC(createCompatibleBitmap)(hdc, nWidth, nHeight)); } BOOL WINAPI drawCaption(HWND hwnd, HDC hdc, const RECT* lprect, UINT flags) @@ -361,6 +375,8 @@ namespace Gdi // Bitmap functions HOOK_GDI_DC_FUNCTION(msimg32, AlphaBlend); HOOK_GDI_DC_FUNCTION(gdi32, BitBlt); + HOOK_FUNCTION(gdi32, CreateBitmap, createBitmap); + HOOK_FUNCTION(gdi32, CreateBitmapIndirect, createBitmapIndirect); HOOK_FUNCTION(gdi32, CreateCompatibleBitmap, createCompatibleBitmap); HOOK_FUNCTION(gdi32, CreateDIBitmap, createDIBitmap); HOOK_FUNCTION(gdi32, CreateDiscardableBitmap, createDiscardableBitmap); diff --git a/DDrawCompat/Gdi/VirtualScreen.cpp b/DDrawCompat/Gdi/VirtualScreen.cpp index 2eb417d..e924870 100644 --- a/DDrawCompat/Gdi/VirtualScreen.cpp +++ b/DDrawCompat/Gdi/VirtualScreen.cpp @@ -71,7 +71,7 @@ namespace return quad; } - HBITMAP createDibSection(LONG width, LONG height, HANDLE section, bool useDefaultPalette) + HBITMAP createDibSection(LONG width, LONG height, DWORD bpp, HANDLE section, bool useDefaultPalette) { struct BITMAPINFO256 : public BITMAPINFO { @@ -83,10 +83,10 @@ namespace bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biHeight = height; bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = static_cast(g_bpp); - bmi.bmiHeader.biCompression = 8 == g_bpp ? BI_RGB : BI_BITFIELDS; + bmi.bmiHeader.biBitCount = static_cast(bpp); + bmi.bmiHeader.biCompression = 8 == bpp ? BI_RGB : BI_BITFIELDS; - if (8 == g_bpp) + if (8 == bpp) { if (useDefaultPalette) { @@ -99,7 +99,7 @@ namespace } else { - const auto pf = DDraw::DirectDraw::getRgbPixelFormat(g_bpp); + const auto pf = DDraw::DirectDraw::getRgbPixelFormat(bpp); reinterpret_cast(bmi.bmiColors[0]) = pf.dwRBitMask; reinterpret_cast(bmi.bmiColors[1]) = pf.dwGBitMask; reinterpret_cast(bmi.bmiColors[2]) = pf.dwBBitMask; @@ -149,13 +149,14 @@ namespace Gdi { return nullptr; } - return createDibSection(g_width, -g_height, g_surfaceFileMapping, useDefaultPalette); + return createDibSection(g_width, -g_height, g_bpp, g_surfaceFileMapping, useDefaultPalette); } - HBITMAP createOffScreenDib(LONG width, LONG height, bool useDefaultPalette) + HBITMAP createOffScreenDib(LONG width, LONG height, DWORD bpp) { Compat::ScopedCriticalSection lock(g_cs); - return createDibSection(width, height, nullptr, useDefaultPalette); + const bool useDefaultPalette = true; + return createDibSection(width, height, bpp, nullptr, useDefaultPalette); } CompatPtr createSurface(const RECT& rect) diff --git a/DDrawCompat/Gdi/VirtualScreen.h b/DDrawCompat/Gdi/VirtualScreen.h index 69a4a36..dcac31d 100644 --- a/DDrawCompat/Gdi/VirtualScreen.h +++ b/DDrawCompat/Gdi/VirtualScreen.h @@ -12,7 +12,7 @@ namespace Gdi { HDC createDc(bool useDefaultPalette); HBITMAP createDib(bool useDefaultPalette); - HBITMAP createOffScreenDib(LONG width, LONG height, bool useDefaultPalette); + HBITMAP createOffScreenDib(LONG width, LONG height, DWORD bpp); CompatPtr createSurface(const RECT& rect); void deleteDc(HDC dc); diff --git a/DDrawCompat/Win32/Log.cpp b/DDrawCompat/Win32/Log.cpp index c1299cb..6fa9a3c 100644 --- a/DDrawCompat/Win32/Log.cpp +++ b/DDrawCompat/Win32/Log.cpp @@ -98,6 +98,18 @@ namespace } } +std::ostream& operator<<(std::ostream& os, const BITMAP& bm) +{ + return Compat::LogStruct(os) + << bm.bmType + << bm.bmWidth + << bm.bmHeight + << bm.bmWidthBytes + << bm.bmPlanes + << bm.bmBitsPixel + << bm.bmBits; +} + std::ostream& operator<<(std::ostream& os, const COMPAREITEMSTRUCT& cis) { return Compat::LogStruct(os) diff --git a/DDrawCompat/Win32/Log.h b/DDrawCompat/Win32/Log.h index 177c00d..e4f0064 100644 --- a/DDrawCompat/Win32/Log.h +++ b/DDrawCompat/Win32/Log.h @@ -4,6 +4,7 @@ #include +std::ostream& operator<<(std::ostream& os, const BITMAP& bm); std::ostream& operator<<(std::ostream& os, const COMPAREITEMSTRUCT& cis); std::ostream& operator<<(std::ostream& os, const COPYDATASTRUCT& cds); std::ostream& operator<<(std::ostream& os, const CREATESTRUCTA& cs);