1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Added support for CreateBitmap(Indirect)

Fixes QuickTime videos in Carmen Sandiego series (issue #156)
This commit is contained in:
narzoul 2022-11-13 22:19:20 +01:00
parent ac1eccd79f
commit 483bf5f6dd
5 changed files with 50 additions and 20 deletions

View File

@ -269,13 +269,33 @@ namespace
return compatGdiDcFunc<origFunc, Result>(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);

View File

@ -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<WORD>(g_bpp);
bmi.bmiHeader.biCompression = 8 == g_bpp ? BI_RGB : BI_BITFIELDS;
bmi.bmiHeader.biBitCount = static_cast<WORD>(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<DWORD&>(bmi.bmiColors[0]) = pf.dwRBitMask;
reinterpret_cast<DWORD&>(bmi.bmiColors[1]) = pf.dwGBitMask;
reinterpret_cast<DWORD&>(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<IDirectDrawSurface7> createSurface(const RECT& rect)

View File

@ -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<IDirectDrawSurface7> createSurface(const RECT& rect);
void deleteDc(HDC dc);

View File

@ -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)

View File

@ -4,6 +4,7 @@
#include <Windows.h>
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);