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...); 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) HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy)
{ {
LOG_FUNC("CreateCompatibleBitmap", hdc, cx, 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, Win32::DisplayMode::getBpp()));
return LOG_RESULT(Gdi::VirtualScreen::createOffScreenDib(cx, cy, useDefaultPalette));
} }
return LOG_RESULT(CALL_ORIG_FUNC(CreateCompatibleBitmap)(hdc, cx, cy)); return LOG_RESULT(CALL_ORIG_FUNC(CreateCompatibleBitmap)(hdc, cx, cy));
} }
@ -287,9 +307,8 @@ namespace
const DWORD CBM_CREATDIB = 2; const DWORD CBM_CREATDIB = 2;
if (!g_disableDibRedirection && !(fdwInit & CBM_CREATDIB) && lpbmih && Gdi::isDisplayDc(hdc)) if (!g_disableDibRedirection && !(fdwInit & CBM_CREATDIB) && lpbmih && Gdi::isDisplayDc(hdc))
{ {
const bool useDefaultPalette = false;
HBITMAP bitmap = Gdi::VirtualScreen::createOffScreenDib( 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) if (bitmap && lpbInit && lpbmi)
{ {
SetDIBits(hdc, bitmap, 0, std::abs(lpbmi->bmiHeader.biHeight), lpbInit, lpbmi, fuUsage); 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) HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight)
{ {
LOG_FUNC("CreateDiscardableBitmap", hdc, nWidth, nHeight); LOG_FUNC("CreateDiscardableBitmap", hdc, nWidth, nHeight);
if (!g_disableDibRedirection && Gdi::isDisplayDc(hdc)) return LOG_RESULT(CALL_ORIG_FUNC(createCompatibleBitmap)(hdc, nWidth, nHeight));
{
const bool useDefaultPalette = false;
return LOG_RESULT(Gdi::VirtualScreen::createOffScreenDib(nWidth, nHeight, useDefaultPalette));
}
return LOG_RESULT(CALL_ORIG_FUNC(createDiscardableBitmap)(hdc, nWidth, nHeight));
} }
BOOL WINAPI drawCaption(HWND hwnd, HDC hdc, const RECT* lprect, UINT flags) BOOL WINAPI drawCaption(HWND hwnd, HDC hdc, const RECT* lprect, UINT flags)
@ -361,6 +375,8 @@ namespace Gdi
// Bitmap functions // Bitmap functions
HOOK_GDI_DC_FUNCTION(msimg32, AlphaBlend); HOOK_GDI_DC_FUNCTION(msimg32, AlphaBlend);
HOOK_GDI_DC_FUNCTION(gdi32, BitBlt); HOOK_GDI_DC_FUNCTION(gdi32, BitBlt);
HOOK_FUNCTION(gdi32, CreateBitmap, createBitmap);
HOOK_FUNCTION(gdi32, CreateBitmapIndirect, createBitmapIndirect);
HOOK_FUNCTION(gdi32, CreateCompatibleBitmap, createCompatibleBitmap); HOOK_FUNCTION(gdi32, CreateCompatibleBitmap, createCompatibleBitmap);
HOOK_FUNCTION(gdi32, CreateDIBitmap, createDIBitmap); HOOK_FUNCTION(gdi32, CreateDIBitmap, createDIBitmap);
HOOK_FUNCTION(gdi32, CreateDiscardableBitmap, createDiscardableBitmap); HOOK_FUNCTION(gdi32, CreateDiscardableBitmap, createDiscardableBitmap);

View File

@ -71,7 +71,7 @@ namespace
return quad; 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 struct BITMAPINFO256 : public BITMAPINFO
{ {
@ -83,10 +83,10 @@ namespace
bmi.bmiHeader.biWidth = width; bmi.bmiHeader.biWidth = width;
bmi.bmiHeader.biHeight = height; bmi.bmiHeader.biHeight = height;
bmi.bmiHeader.biPlanes = 1; bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = static_cast<WORD>(g_bpp); bmi.bmiHeader.biBitCount = static_cast<WORD>(bpp);
bmi.bmiHeader.biCompression = 8 == g_bpp ? BI_RGB : BI_BITFIELDS; bmi.bmiHeader.biCompression = 8 == bpp ? BI_RGB : BI_BITFIELDS;
if (8 == g_bpp) if (8 == bpp)
{ {
if (useDefaultPalette) if (useDefaultPalette)
{ {
@ -99,7 +99,7 @@ namespace
} }
else 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[0]) = pf.dwRBitMask;
reinterpret_cast<DWORD&>(bmi.bmiColors[1]) = pf.dwGBitMask; reinterpret_cast<DWORD&>(bmi.bmiColors[1]) = pf.dwGBitMask;
reinterpret_cast<DWORD&>(bmi.bmiColors[2]) = pf.dwBBitMask; reinterpret_cast<DWORD&>(bmi.bmiColors[2]) = pf.dwBBitMask;
@ -149,13 +149,14 @@ namespace Gdi
{ {
return nullptr; 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); 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) CompatPtr<IDirectDrawSurface7> createSurface(const RECT& rect)

View File

@ -12,7 +12,7 @@ namespace Gdi
{ {
HDC createDc(bool useDefaultPalette); HDC createDc(bool useDefaultPalette);
HBITMAP createDib(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); CompatPtr<IDirectDrawSurface7> createSurface(const RECT& rect);
void deleteDc(HDC dc); 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) std::ostream& operator<<(std::ostream& os, const COMPAREITEMSTRUCT& cis)
{ {
return Compat::LogStruct(os) return Compat::LogStruct(os)

View File

@ -4,6 +4,7 @@
#include <Windows.h> #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 COMPAREITEMSTRUCT& cis);
std::ostream& operator<<(std::ostream& os, const COPYDATASTRUCT& cds); std::ostream& operator<<(std::ostream& os, const COPYDATASTRUCT& cds);
std::ostream& operator<<(std::ostream& os, const CREATESTRUCTA& cs); std::ostream& operator<<(std::ostream& os, const CREATESTRUCTA& cs);