mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Implement GDI system palette emulation
This commit is contained in:
parent
12e78aab84
commit
727be63db1
@ -225,7 +225,7 @@ namespace
|
|||||||
{
|
{
|
||||||
g_gdiAdapterInfo = getAdapterInfo(data);
|
g_gdiAdapterInfo = getAdapterInfo(data);
|
||||||
}
|
}
|
||||||
ReleaseDC(nullptr, data.hDc);
|
CALL_ORIG_FUNC(ReleaseDC)(nullptr, data.hDc);
|
||||||
|
|
||||||
lastDisplaySettingsUniqueness = currentDisplaySettingsUniqueness;
|
lastDisplaySettingsUniqueness = currentDisplaySettingsUniqueness;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ namespace
|
|||||||
{
|
{
|
||||||
Win32::DisplayMode::setDDrawBpp(bpp);
|
Win32::DisplayMode::setDDrawBpp(bpp);
|
||||||
HRESULT result = DDraw::DirectDraw<TDirectDraw>::s_origVtable.SetDisplayMode(
|
HRESULT result = DDraw::DirectDraw<TDirectDraw>::s_origVtable.SetDisplayMode(
|
||||||
This, width, height, bpp, refreshRate, flags);
|
This, width, height, 32, refreshRate, flags);
|
||||||
Win32::DisplayMode::setDDrawBpp(0);
|
Win32::DisplayMode::setDDrawBpp(0);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -59,7 +59,7 @@ namespace DDraw
|
|||||||
{
|
{
|
||||||
DDSURFACEDESC2 dm = {};
|
DDSURFACEDESC2 dm = {};
|
||||||
dm.dwSize = sizeof(dm);
|
dm.dwSize = sizeof(dm);
|
||||||
dd->GetDisplayMode(&dd, &dm);
|
dd.get().lpVtbl->GetDisplayMode(&dd, &dm);
|
||||||
return dm;
|
return dm;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,6 +114,7 @@ namespace DDraw
|
|||||||
{
|
{
|
||||||
vtable.CreateSurface = &CreateSurface;
|
vtable.CreateSurface = &CreateSurface;
|
||||||
vtable.FlipToGDISurface = &FlipToGDISurface;
|
vtable.FlipToGDISurface = &FlipToGDISurface;
|
||||||
|
vtable.GetDisplayMode = &GetDisplayMode;
|
||||||
vtable.GetGDISurface = &GetGDISurface;
|
vtable.GetGDISurface = &GetGDISurface;
|
||||||
vtable.SetCooperativeLevel = &SetCooperativeLevel;
|
vtable.SetCooperativeLevel = &SetCooperativeLevel;
|
||||||
vtable.SetDisplayMode = &SetDisplayMode;
|
vtable.SetDisplayMode = &SetDisplayMode;
|
||||||
@ -148,6 +149,18 @@ namespace DDraw
|
|||||||
return PrimarySurface::flipToGdiSurface();
|
return PrimarySurface::flipToGdiSurface();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename TDirectDraw>
|
||||||
|
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetDisplayMode(
|
||||||
|
TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc)
|
||||||
|
{
|
||||||
|
HRESULT result = s_origVtable.GetDisplayMode(This, lpDDSurfaceDesc);
|
||||||
|
if (SUCCEEDED(result) && lpDDSurfaceDesc)
|
||||||
|
{
|
||||||
|
lpDDSurfaceDesc->ddpfPixelFormat = getRgbPixelFormat(Win32::DisplayMode::getBpp());
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TDirectDraw>
|
template <typename TDirectDraw>
|
||||||
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetGDISurface(
|
HRESULT STDMETHODCALLTYPE DirectDraw<TDirectDraw>::GetGDISurface(
|
||||||
TDirectDraw* /*This*/, TSurface** lplpGDIDDSSurface)
|
TDirectDraw* /*This*/, TSurface** lplpGDIDDSSurface)
|
||||||
|
@ -35,6 +35,7 @@ namespace DDraw
|
|||||||
IUnknown* pUnkOuter);
|
IUnknown* pUnkOuter);
|
||||||
|
|
||||||
static HRESULT STDMETHODCALLTYPE FlipToGDISurface(TDirectDraw* This);
|
static HRESULT STDMETHODCALLTYPE FlipToGDISurface(TDirectDraw* This);
|
||||||
|
static HRESULT STDMETHODCALLTYPE GetDisplayMode(TDirectDraw* This, TSurfaceDesc* lpDDSurfaceDesc);
|
||||||
static HRESULT STDMETHODCALLTYPE GetGDISurface(TDirectDraw* This, TSurface** lplpGDIDDSSurface);
|
static HRESULT STDMETHODCALLTYPE GetGDISurface(TDirectDraw* This, TSurface** lplpGDIDDSSurface);
|
||||||
static HRESULT STDMETHODCALLTYPE Initialize(TDirectDraw* This, GUID* lpGUID);
|
static HRESULT STDMETHODCALLTYPE Initialize(TDirectDraw* This, GUID* lpGUID);
|
||||||
static HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags);
|
static HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags);
|
||||||
|
@ -42,7 +42,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
DeleteObject(rgn);
|
DeleteObject(rgn);
|
||||||
ReleaseDC(data.hwnd, dc);
|
CALL_ORIG_FUNC(ReleaseDC)(data.hwnd, dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT STDMETHODCALLTYPE GetHWnd(IDirectDrawClipper* This, HWND* lphWnd)
|
HRESULT STDMETHODCALLTYPE GetHWnd(IDirectDrawClipper* This, HWND* lphWnd)
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "Common/Time.h"
|
#include "Common/Time.h"
|
||||||
#include "Config/Config.h"
|
#include "Config/Config.h"
|
||||||
#include "DDraw/DirectDrawPalette.h"
|
#include "DDraw/DirectDrawPalette.h"
|
||||||
#include "DDraw/RealPrimarySurface.h"
|
|
||||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||||
#include "Gdi/AccessGuard.h"
|
#include "Gdi/AccessGuard.h"
|
||||||
|
|
||||||
@ -36,9 +35,7 @@ namespace DDraw
|
|||||||
HRESULT result = s_origVtable.SetEntries(This, dwFlags, dwStartingEntry, dwCount, lpEntries);
|
HRESULT result = s_origVtable.SetEntries(This, dwFlags, dwStartingEntry, dwCount, lpEntries);
|
||||||
if (This == PrimarySurface::s_palette && SUCCEEDED(result))
|
if (This == PrimarySurface::s_palette && SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
std::memcpy(&PrimarySurface::s_paletteEntries[dwStartingEntry], lpEntries,
|
PrimarySurface::updatePalette();
|
||||||
dwCount * sizeof(PALETTEENTRY));
|
|
||||||
RealPrimarySurface::updatePalette();
|
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +116,7 @@ namespace
|
|||||||
RECT rect = windowPair.second->getWindowRect();
|
RECT rect = windowPair.second->getWindowRect();
|
||||||
CALL_ORIG_FUNC(BitBlt)(dc, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
|
CALL_ORIG_FUNC(BitBlt)(dc, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
|
||||||
virtualScreenDc.get(), rect.left, rect.top, SRCCOPY);
|
virtualScreenDc.get(), rect.left, rect.top, SRCCOPY);
|
||||||
ReleaseDC(presentationWindow, dc);
|
CALL_ORIG_FUNC(ReleaseDC)(presentationWindow, dc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,7 +152,7 @@ namespace
|
|||||||
SelectClipRgn(backBufferDc, nullptr);
|
SelectClipRgn(backBufferDc, nullptr);
|
||||||
|
|
||||||
DeleteObject(rgn);
|
DeleteObject(rgn);
|
||||||
ReleaseDC(*it, windowDc);
|
CALL_ORIG_FUNC(ReleaseDC)(*it, windowDc);
|
||||||
}
|
}
|
||||||
|
|
||||||
backBuffer->ReleaseDC(backBuffer, backBufferDc);
|
backBuffer->ReleaseDC(backBuffer, backBufferDc);
|
||||||
@ -667,17 +667,6 @@ namespace DDraw
|
|||||||
return gammaControl->SetGammaRamp(gammaControl, 0, rampData);
|
return gammaControl->SetGammaRamp(gammaControl, 0, rampData);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RealPrimarySurface::setPalette()
|
|
||||||
{
|
|
||||||
DDraw::ScopedThreadLock lock;
|
|
||||||
if (g_surfaceDesc.ddpfPixelFormat.dwRGBBitCount <= 8)
|
|
||||||
{
|
|
||||||
g_frontBuffer->SetPalette(g_frontBuffer, PrimarySurface::s_palette);
|
|
||||||
}
|
|
||||||
|
|
||||||
updatePalette();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RealPrimarySurface::update()
|
void RealPrimarySurface::update()
|
||||||
{
|
{
|
||||||
DDraw::ScopedThreadLock lock;
|
DDraw::ScopedThreadLock lock;
|
||||||
@ -689,15 +678,6 @@ namespace DDraw
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RealPrimarySurface::updatePalette()
|
|
||||||
{
|
|
||||||
DDraw::ScopedThreadLock lock;
|
|
||||||
if (PrimarySurface::s_palette)
|
|
||||||
{
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RealPrimarySurface::waitForFlip(Surface* surface, bool wait)
|
bool RealPrimarySurface::waitForFlip(Surface* surface, bool wait)
|
||||||
{
|
{
|
||||||
auto primary(DDraw::PrimarySurface::getPrimary());
|
auto primary(DDraw::PrimarySurface::getPrimary());
|
||||||
|
@ -27,9 +27,7 @@ namespace DDraw
|
|||||||
static void removeUpdateThread();
|
static void removeUpdateThread();
|
||||||
static HRESULT restore();
|
static HRESULT restore();
|
||||||
static HRESULT setGammaRamp(DDGAMMARAMP* rampData);
|
static HRESULT setGammaRamp(DDGAMMARAMP* rampData);
|
||||||
static void setPalette();
|
|
||||||
static void update();
|
static void update();
|
||||||
static void updatePalette();
|
|
||||||
static bool waitForFlip(Surface* surface, bool wait = true);
|
static bool waitForFlip(Surface* surface, bool wait = true);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -231,6 +231,15 @@ namespace DDraw
|
|||||||
} while (surfacePtr && surfacePtr != g_primarySurface.get());
|
} while (surfacePtr && surfacePtr != g_primarySurface.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrimarySurface::updatePalette()
|
||||||
|
{
|
||||||
|
if (s_palette)
|
||||||
|
{
|
||||||
|
PrimarySurface::s_palette->GetEntries(s_palette, 0, 0, 256, s_paletteEntries);
|
||||||
|
RealPrimarySurface::update();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette;
|
CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette;
|
||||||
PALETTEENTRY PrimarySurface::s_paletteEntries[256] = {};
|
PALETTEENTRY PrimarySurface::s_paletteEntries[256] = {};
|
||||||
std::vector<std::vector<unsigned char>> PrimarySurface::s_surfaceBuffers;
|
std::vector<std::vector<unsigned char>> PrimarySurface::s_surfaceBuffers;
|
||||||
|
@ -26,6 +26,7 @@ namespace DDraw
|
|||||||
static CompatWeakPtr<IDirectDrawSurface7> getPrimary();
|
static CompatWeakPtr<IDirectDrawSurface7> getPrimary();
|
||||||
static DWORD getOrigCaps();
|
static DWORD getOrigCaps();
|
||||||
static void onRestore();
|
static void onRestore();
|
||||||
|
static void updatePalette();
|
||||||
|
|
||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
static bool isGdiSurface(TSurface* surface);
|
static bool isGdiSurface(TSurface* surface);
|
||||||
|
@ -173,7 +173,7 @@ namespace DDraw
|
|||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
PrimarySurface::s_palette = lpDDPalette;
|
PrimarySurface::s_palette = lpDDPalette;
|
||||||
RealPrimarySurface::setPalette();
|
PrimarySurface::updatePalette();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "DDraw/DirectDrawSurface.h"
|
#include "DDraw/DirectDrawSurface.h"
|
||||||
#include "DDraw/Surfaces/Surface.h"
|
#include "DDraw/Surfaces/Surface.h"
|
||||||
#include "DDraw/Surfaces/SurfaceImpl.h"
|
#include "DDraw/Surfaces/SurfaceImpl.h"
|
||||||
|
#include "Win32/DisplayMode.h"
|
||||||
|
|
||||||
// {C62D8849-DFAC-4454-A1E8-DA67446426BA}
|
// {C62D8849-DFAC-4454-A1E8-DA67446426BA}
|
||||||
DEFINE_GUID(IID_CompatSurfacePrivateData,
|
DEFINE_GUID(IID_CompatSurfacePrivateData,
|
||||||
@ -15,8 +16,7 @@ namespace
|
|||||||
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
||||||
HRESULT createSurface(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface)
|
HRESULT createSurface(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface)
|
||||||
{
|
{
|
||||||
auto dd7(CompatPtr<IDirectDraw7>::from(&dd));
|
fixSurfaceDesc(desc.dwFlags, desc.ddsCaps.dwCaps, desc.ddpfPixelFormat);
|
||||||
fixSurfaceDesc(*dd7, desc.dwFlags, desc.ddsCaps.dwCaps, desc.ddpfPixelFormat);
|
|
||||||
|
|
||||||
if ((desc.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) &&
|
if ((desc.ddsCaps.dwCaps & DDSCAPS_OFFSCREENPLAIN) &&
|
||||||
!(desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY | DDSCAPS_3DDEVICE)))
|
!(desc.ddsCaps.dwCaps & (DDSCAPS_SYSTEMMEMORY | DDSCAPS_3DDEVICE)))
|
||||||
@ -35,7 +35,7 @@ namespace
|
|||||||
return dd->CreateSurface(&dd, &desc, &surface, nullptr);
|
return dd->CreateSurface(&dd, &desc, &surface, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fixSurfaceDesc(CompatRef<IDirectDraw7> dd, DWORD& flags, DWORD& caps, DDPIXELFORMAT& pf)
|
void fixSurfaceDesc(DWORD& flags, DWORD& caps, DDPIXELFORMAT& pf)
|
||||||
{
|
{
|
||||||
if ((flags & DDSD_WIDTH) &&
|
if ((flags & DDSD_WIDTH) &&
|
||||||
(flags & DDSD_HEIGHT) &&
|
(flags & DDSD_HEIGHT) &&
|
||||||
@ -43,9 +43,8 @@ namespace
|
|||||||
{
|
{
|
||||||
if (!(flags & DDSD_PIXELFORMAT))
|
if (!(flags & DDSD_PIXELFORMAT))
|
||||||
{
|
{
|
||||||
auto dm = DDraw::getDisplayMode(dd);
|
|
||||||
flags |= DDSD_PIXELFORMAT;
|
flags |= DDSD_PIXELFORMAT;
|
||||||
pf = dm.ddpfPixelFormat;
|
pf = DDraw::getRgbPixelFormat(Win32::DisplayMode::getBpp());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((pf.dwFlags & DDPF_RGB) && pf.dwRGBBitCount <= 8)
|
if ((pf.dwFlags & DDPF_RGB) && pf.dwRGBBitCount <= 8)
|
||||||
|
@ -290,6 +290,7 @@
|
|||||||
<ClInclude Include="Gdi\DcCache.h" />
|
<ClInclude Include="Gdi\DcCache.h" />
|
||||||
<ClInclude Include="Gdi\DcFunctions.h" />
|
<ClInclude Include="Gdi\DcFunctions.h" />
|
||||||
<ClInclude Include="Gdi\PaintHandlers.h" />
|
<ClInclude Include="Gdi\PaintHandlers.h" />
|
||||||
|
<ClInclude Include="Gdi\Palette.h" />
|
||||||
<ClInclude Include="Gdi\Region.h" />
|
<ClInclude Include="Gdi\Region.h" />
|
||||||
<ClInclude Include="Gdi\ScrollBar.h" />
|
<ClInclude Include="Gdi\ScrollBar.h" />
|
||||||
<ClInclude Include="Gdi\ScrollFunctions.h" />
|
<ClInclude Include="Gdi\ScrollFunctions.h" />
|
||||||
@ -350,6 +351,7 @@
|
|||||||
<ClCompile Include="Gdi\DcCache.cpp" />
|
<ClCompile Include="Gdi\DcCache.cpp" />
|
||||||
<ClCompile Include="Gdi\DcFunctions.cpp" />
|
<ClCompile Include="Gdi\DcFunctions.cpp" />
|
||||||
<ClCompile Include="Gdi\PaintHandlers.cpp" />
|
<ClCompile Include="Gdi\PaintHandlers.cpp" />
|
||||||
|
<ClCompile Include="Gdi\Palette.cpp" />
|
||||||
<ClCompile Include="Gdi\Region.cpp" />
|
<ClCompile Include="Gdi\Region.cpp" />
|
||||||
<ClCompile Include="Gdi\ScrollBar.cpp" />
|
<ClCompile Include="Gdi\ScrollBar.cpp" />
|
||||||
<ClCompile Include="Gdi\ScrollFunctions.cpp" />
|
<ClCompile Include="Gdi\ScrollFunctions.cpp" />
|
||||||
|
@ -324,6 +324,9 @@
|
|||||||
<ClInclude Include="Gdi\AccessGuard.h">
|
<ClInclude Include="Gdi\AccessGuard.h">
|
||||||
<Filter>Header Files\Gdi</Filter>
|
<Filter>Header Files\Gdi</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Gdi\Palette.h">
|
||||||
|
<Filter>Header Files\Gdi</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Gdi\Gdi.cpp">
|
<ClCompile Include="Gdi\Gdi.cpp">
|
||||||
@ -500,6 +503,9 @@
|
|||||||
<ClCompile Include="Gdi\AccessGuard.cpp">
|
<ClCompile Include="Gdi\AccessGuard.cpp">
|
||||||
<Filter>Source Files\Gdi</Filter>
|
<Filter>Source Files\Gdi</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Gdi\Palette.cpp">
|
||||||
|
<Filter>Source Files\Gdi</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="Dll\DDrawCompat.def">
|
<None Include="Dll\DDrawCompat.def">
|
||||||
|
@ -43,7 +43,7 @@ namespace
|
|||||||
{
|
{
|
||||||
HDC dc = GetDC(g_caret.hwnd);
|
HDC dc = GetDC(g_caret.hwnd);
|
||||||
PatBlt(dc, g_caret.left, g_caret.top, g_caret.width, g_caret.height, PATINVERT);
|
PatBlt(dc, g_caret.left, g_caret.top, g_caret.width, g_caret.height, PATINVERT);
|
||||||
ReleaseDC(g_caret.hwnd, dc);
|
CALL_ORIG_FUNC(ReleaseDC)(g_caret.hwnd, dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
CaretData getCaretData(DWORD threadId)
|
CaretData getCaretData(DWORD threadId)
|
||||||
|
@ -24,6 +24,7 @@ namespace
|
|||||||
HGDIOBJ savedFont;
|
HGDIOBJ savedFont;
|
||||||
HGDIOBJ savedBrush;
|
HGDIOBJ savedBrush;
|
||||||
HGDIOBJ savedPen;
|
HGDIOBJ savedPen;
|
||||||
|
HPALETTE savedPalette;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::unordered_map<HDC, CompatDc> CompatDcMap;
|
typedef std::unordered_map<HDC, CompatDc> CompatDcMap;
|
||||||
@ -37,6 +38,8 @@ namespace
|
|||||||
SelectObject(compatDc.dc, compatDc.savedFont = GetCurrentObject(origDc, OBJ_FONT));
|
SelectObject(compatDc.dc, compatDc.savedFont = GetCurrentObject(origDc, OBJ_FONT));
|
||||||
SelectObject(compatDc.dc, compatDc.savedBrush = GetCurrentObject(origDc, OBJ_BRUSH));
|
SelectObject(compatDc.dc, compatDc.savedBrush = GetCurrentObject(origDc, OBJ_BRUSH));
|
||||||
SelectObject(compatDc.dc, compatDc.savedPen = GetCurrentObject(origDc, OBJ_PEN));
|
SelectObject(compatDc.dc, compatDc.savedPen = GetCurrentObject(origDc, OBJ_PEN));
|
||||||
|
CALL_ORIG_FUNC(SelectPalette)(
|
||||||
|
compatDc.dc, compatDc.savedPalette = static_cast<HPALETTE>(GetCurrentObject(origDc, OBJ_PAL)), FALSE);
|
||||||
|
|
||||||
const int graphicsMode = GetGraphicsMode(origDc);
|
const int graphicsMode = GetGraphicsMode(origDc);
|
||||||
SetGraphicsMode(compatDc.dc, graphicsMode);
|
SetGraphicsMode(compatDc.dc, graphicsMode);
|
||||||
@ -104,6 +107,7 @@ namespace
|
|||||||
SelectObject(compatDc.dc, compatDc.savedFont);
|
SelectObject(compatDc.dc, compatDc.savedFont);
|
||||||
SelectObject(compatDc.dc, compatDc.savedBrush);
|
SelectObject(compatDc.dc, compatDc.savedBrush);
|
||||||
SelectObject(compatDc.dc, compatDc.savedPen);
|
SelectObject(compatDc.dc, compatDc.savedPen);
|
||||||
|
CALL_ORIG_FUNC(SelectPalette)(compatDc.dc, compatDc.savedPalette, FALSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +67,7 @@ namespace
|
|||||||
|
|
||||||
bool hasDisplayDcArg(HDC dc)
|
bool hasDisplayDcArg(HDC dc)
|
||||||
{
|
{
|
||||||
return dc && OBJ_DC == GetObjectType(dc) && DT_RASDISPLAY == GetDeviceCaps(dc, TECHNOLOGY) &&
|
return Gdi::isDisplayDc(dc);
|
||||||
!(GetWindowLongPtr(CALL_ORIG_FUNC(WindowFromDC)(dc), GWL_EXSTYLE) & WS_EX_LAYERED);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -153,6 +152,42 @@ namespace
|
|||||||
return LOG_RESULT(TRUE);
|
return LOG_RESULT(TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy)
|
||||||
|
{
|
||||||
|
LOG_FUNC("CreateCompatibleBitmap", hdc, cx, cy);
|
||||||
|
if (Gdi::isDisplayDc(hdc))
|
||||||
|
{
|
||||||
|
return LOG_RESULT(Gdi::VirtualScreen::createOffScreenDib(cx, cy));
|
||||||
|
}
|
||||||
|
return LOG_RESULT(CALL_ORIG_FUNC(CreateCompatibleBitmap)(hdc, cx, cy));
|
||||||
|
}
|
||||||
|
|
||||||
|
HBITMAP WINAPI createDIBitmap(HDC hdc, const BITMAPINFOHEADER* lpbmih, DWORD fdwInit,
|
||||||
|
const void* lpbInit, const BITMAPINFO* lpbmi, UINT fuUsage)
|
||||||
|
{
|
||||||
|
LOG_FUNC("CreateDIBitmap", hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
|
||||||
|
if (lpbmih && (!(fdwInit & CBM_INIT) || lpbInit && lpbmi))
|
||||||
|
{
|
||||||
|
HBITMAP bitmap = Gdi::VirtualScreen::createOffScreenDib(lpbmih->biWidth, std::abs(lpbmih->biHeight));
|
||||||
|
if (bitmap && (fdwInit & CBM_INIT))
|
||||||
|
{
|
||||||
|
SetDIBits(hdc, bitmap, 0, std::abs(lpbmih->biHeight), lpbInit, lpbmi, fuUsage);
|
||||||
|
}
|
||||||
|
return LOG_RESULT(bitmap);
|
||||||
|
}
|
||||||
|
return LOG_RESULT(CALL_ORIG_FUNC(CreateDIBitmap)(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage));
|
||||||
|
}
|
||||||
|
|
||||||
|
HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight)
|
||||||
|
{
|
||||||
|
LOG_FUNC("CreateDiscardableBitmap", hdc, nWidth, nHeight);
|
||||||
|
if (Gdi::isDisplayDc(hdc))
|
||||||
|
{
|
||||||
|
return LOG_RESULT(Gdi::VirtualScreen::createOffScreenDib(nWidth, nHeight));
|
||||||
|
}
|
||||||
|
return LOG_RESULT(CALL_ORIG_FUNC(createDiscardableBitmap)(hdc, nWidth, nHeight));
|
||||||
|
}
|
||||||
|
|
||||||
BOOL CALLBACK excludeRgnForOverlappingWindow(HWND hwnd, LPARAM lParam)
|
BOOL CALLBACK excludeRgnForOverlappingWindow(HWND hwnd, LPARAM lParam)
|
||||||
{
|
{
|
||||||
auto& args = *reinterpret_cast<ExcludeRgnForOverlappingWindowArgs*>(lParam);
|
auto& args = *reinterpret_cast<ExcludeRgnForOverlappingWindowArgs*>(lParam);
|
||||||
@ -262,13 +297,6 @@ namespace
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI realizePalette(HDC hdc)
|
|
||||||
{
|
|
||||||
UINT result = CALL_ORIG_FUNC(RealizePalette)(hdc);
|
|
||||||
Gdi::VirtualScreen::updatePalette();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
HWND WINAPI windowFromDc(HDC dc)
|
HWND WINAPI windowFromDc(HDC dc)
|
||||||
{
|
{
|
||||||
return CALL_ORIG_FUNC(WindowFromDC)(Gdi::Dc::getOrigDc(dc));
|
return CALL_ORIG_FUNC(WindowFromDC)(Gdi::Dc::getOrigDc(dc));
|
||||||
@ -299,9 +327,9 @@ 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, CreateCompatibleBitmap, Win32::DisplayMode::createCompatibleBitmap);
|
HOOK_FUNCTION(gdi32, CreateCompatibleBitmap, createCompatibleBitmap);
|
||||||
HOOK_FUNCTION(gdi32, CreateDIBitmap, Win32::DisplayMode::createDIBitmap);
|
HOOK_FUNCTION(gdi32, CreateDIBitmap, createDIBitmap);
|
||||||
HOOK_FUNCTION(gdi32, CreateDiscardableBitmap, Win32::DisplayMode::createDiscardableBitmap);
|
HOOK_FUNCTION(gdi32, CreateDiscardableBitmap, createDiscardableBitmap);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, ExtFloodFill);
|
HOOK_GDI_DC_FUNCTION(gdi32, ExtFloodFill);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, GdiAlphaBlend);
|
HOOK_GDI_DC_FUNCTION(gdi32, GdiAlphaBlend);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, GdiGradientFill);
|
HOOK_GDI_DC_FUNCTION(gdi32, GdiGradientFill);
|
||||||
@ -325,9 +353,6 @@ namespace Gdi
|
|||||||
// Clipping functions
|
// Clipping functions
|
||||||
HOOK_FUNCTION(gdi32, GetRandomRgn, getRandomRgn);
|
HOOK_FUNCTION(gdi32, GetRandomRgn, getRandomRgn);
|
||||||
|
|
||||||
// Color functions
|
|
||||||
HOOK_SHIM_FUNCTION(RealizePalette, realizePalette);
|
|
||||||
|
|
||||||
// Device context functions
|
// Device context functions
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, DrawEscape);
|
HOOK_GDI_DC_FUNCTION(gdi32, DrawEscape);
|
||||||
HOOK_FUNCTION(user32, WindowFromDC, windowFromDc);
|
HOOK_FUNCTION(user32, WindowFromDC, windowFromDc);
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "Gdi/DcFunctions.h"
|
#include "Gdi/DcFunctions.h"
|
||||||
#include "Gdi/Gdi.h"
|
#include "Gdi/Gdi.h"
|
||||||
#include "Gdi/PaintHandlers.h"
|
#include "Gdi/PaintHandlers.h"
|
||||||
|
#include "Gdi/Palette.h"
|
||||||
#include "Gdi/ScrollFunctions.h"
|
#include "Gdi/ScrollFunctions.h"
|
||||||
#include "Gdi/Window.h"
|
#include "Gdi/Window.h"
|
||||||
#include "Gdi/WinProc.h"
|
#include "Gdi/WinProc.h"
|
||||||
@ -50,12 +51,19 @@ namespace Gdi
|
|||||||
|
|
||||||
DcFunctions::installHooks();
|
DcFunctions::installHooks();
|
||||||
PaintHandlers::installHooks();
|
PaintHandlers::installHooks();
|
||||||
|
Palette::installHooks();
|
||||||
ScrollFunctions::installHooks();
|
ScrollFunctions::installHooks();
|
||||||
Window::installHooks();
|
Window::installHooks();
|
||||||
WinProc::installHooks();
|
WinProc::installHooks();
|
||||||
Caret::installHooks();
|
Caret::installHooks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isDisplayDc(HDC dc)
|
||||||
|
{
|
||||||
|
return dc && OBJ_DC == GetObjectType(dc) && DT_RASDISPLAY == GetDeviceCaps(dc, TECHNOLOGY) &&
|
||||||
|
!(GetWindowLongPtr(CALL_ORIG_FUNC(WindowFromDC)(dc), GWL_EXSTYLE) & WS_EX_LAYERED);
|
||||||
|
}
|
||||||
|
|
||||||
void redraw(HRGN rgn)
|
void redraw(HRGN rgn)
|
||||||
{
|
{
|
||||||
EnumWindows(&redrawWindowCallback, reinterpret_cast<LPARAM>(rgn));
|
EnumWindows(&redrawWindowCallback, reinterpret_cast<LPARAM>(rgn));
|
||||||
@ -97,7 +105,7 @@ namespace Gdi
|
|||||||
Window::uninstallHooks();
|
Window::uninstallHooks();
|
||||||
Dc::dllProcessDetach();
|
Dc::dllProcessDetach();
|
||||||
DcCache::dllProcessDetach();
|
DcCache::dllProcessDetach();
|
||||||
ReleaseDC(nullptr, g_screenDc);
|
CALL_ORIG_FUNC(ReleaseDC)(nullptr, g_screenDc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc)
|
void watchWindowPosChanges(WindowPosChangeNotifyFunc notifyFunc)
|
||||||
|
@ -14,6 +14,7 @@ namespace Gdi
|
|||||||
HDC getScreenDc();
|
HDC getScreenDc();
|
||||||
HRGN getVisibleWindowRgn(HWND hwnd);
|
HRGN getVisibleWindowRgn(HWND hwnd);
|
||||||
void installHooks();
|
void installHooks();
|
||||||
|
bool isDisplayDc(HDC dc);
|
||||||
void redraw(HRGN rgn);
|
void redraw(HRGN rgn);
|
||||||
void redrawWindow(HWND hwnd, HRGN rgn);
|
void redrawWindow(HWND hwnd, HRGN rgn);
|
||||||
void unhookWndProc(LPCSTR className, WNDPROC oldWndProc);
|
void unhookWndProc(LPCSTR className, WNDPROC oldWndProc);
|
||||||
|
@ -299,7 +299,7 @@ namespace
|
|||||||
Gdi::Dc::releaseDc(windowDc);
|
Gdi::Dc::releaseDc(windowDc);
|
||||||
}
|
}
|
||||||
|
|
||||||
ReleaseDC(hwnd, windowDc);
|
CALL_ORIG_FUNC(ReleaseDC)(hwnd, windowDc);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
224
DDrawCompat/Gdi/Palette.cpp
Normal file
224
DDrawCompat/Gdi/Palette.cpp
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#include "Common/Hook.h"
|
||||||
|
#include "Common/Log.h"
|
||||||
|
#include "DDraw/ScopedThreadLock.h"
|
||||||
|
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||||
|
#include "Gdi/Gdi.h"
|
||||||
|
#include "Gdi/Palette.h"
|
||||||
|
#include "VirtualScreen.h"
|
||||||
|
#include "Win32/DisplayMode.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
PALETTEENTRY g_systemPalette[256] = {};
|
||||||
|
UINT g_systemPaletteUse = SYSPAL_STATIC;
|
||||||
|
UINT g_systemPaletteFirstUnusedIndex = 10;
|
||||||
|
UINT g_systemPaletteFirstNonReservedIndex = 10;
|
||||||
|
UINT g_systemPaletteLastNonReservedIndex = 245;
|
||||||
|
|
||||||
|
std::set<HDC> g_foregroundPaletteDcs;
|
||||||
|
|
||||||
|
bool isSameColor(PALETTEENTRY entry1, PALETTEENTRY entry2)
|
||||||
|
{
|
||||||
|
return entry1.peRed == entry2.peRed &&
|
||||||
|
entry1.peGreen == entry2.peGreen &&
|
||||||
|
entry1.peBlue == entry2.peBlue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool exactMatch(PALETTEENTRY entry)
|
||||||
|
{
|
||||||
|
for (UINT i = 0; i < g_systemPaletteFirstUnusedIndex; ++i)
|
||||||
|
{
|
||||||
|
if (isSameColor(entry, g_systemPalette[i]))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (UINT i = g_systemPaletteLastNonReservedIndex + 1; i < 256; ++i)
|
||||||
|
{
|
||||||
|
if (isSameColor(entry, g_systemPalette[i]))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT fillSystemPalette(HDC dc)
|
||||||
|
{
|
||||||
|
HPALETTE palette = reinterpret_cast<HPALETTE>(GetCurrentObject(dc, OBJ_PAL));
|
||||||
|
if (!palette || GetStockObject(DEFAULT_PALETTE) == palette)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PALETTEENTRY entries[256] = {};
|
||||||
|
UINT count = GetPaletteEntries(palette, 0, 256, entries);
|
||||||
|
for (UINT i = 0;
|
||||||
|
i < count && g_systemPaletteFirstUnusedIndex <= g_systemPaletteLastNonReservedIndex;
|
||||||
|
++i)
|
||||||
|
{
|
||||||
|
if ((entries[i].peFlags & PC_EXPLICIT) ||
|
||||||
|
0 == (entries[i].peFlags & (PC_NOCOLLAPSE | PC_RESERVED)) && exactMatch(entries[i]))
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_systemPalette[g_systemPaletteFirstUnusedIndex] = entries[i];
|
||||||
|
g_systemPalette[g_systemPaletteFirstUnusedIndex].peFlags = 0;
|
||||||
|
++g_systemPaletteFirstUnusedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Gdi::VirtualScreen::updatePalette();
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI getSystemPaletteEntries(HDC hdc, UINT iStartIndex, UINT nEntries, LPPALETTEENTRY lppe)
|
||||||
|
{
|
||||||
|
LOG_FUNC("GetSystemPaletteEntries", hdc, iStartIndex, nEntries, lppe);
|
||||||
|
if (!Gdi::isDisplayDc(hdc))
|
||||||
|
{
|
||||||
|
return LOG_RESULT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lppe)
|
||||||
|
{
|
||||||
|
return LOG_RESULT(256);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iStartIndex >= 256)
|
||||||
|
{
|
||||||
|
return LOG_RESULT(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nEntries > 256 - iStartIndex)
|
||||||
|
{
|
||||||
|
nEntries = 256 - iStartIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
DDraw::ScopedThreadLock lock;
|
||||||
|
std::memcpy(lppe, &DDraw::PrimarySurface::s_paletteEntries[iStartIndex], nEntries * sizeof(PALETTEENTRY));
|
||||||
|
|
||||||
|
return LOG_RESULT(nEntries);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI getSystemPaletteUse(HDC hdc)
|
||||||
|
{
|
||||||
|
LOG_FUNC("GetSystemPaletteUse", hdc);
|
||||||
|
if (!Gdi::isDisplayDc(hdc))
|
||||||
|
{
|
||||||
|
return LOG_RESULT(SYSPAL_ERROR);
|
||||||
|
}
|
||||||
|
DDraw::ScopedThreadLock lock;
|
||||||
|
return g_systemPaletteUse;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI realizePalette(HDC hdc)
|
||||||
|
{
|
||||||
|
LOG_FUNC("RealizePalette", hdc);
|
||||||
|
if (Gdi::isDisplayDc(hdc))
|
||||||
|
{
|
||||||
|
DDraw::ScopedThreadLock lock;
|
||||||
|
if (g_foregroundPaletteDcs.find(hdc) != g_foregroundPaletteDcs.end())
|
||||||
|
{
|
||||||
|
g_systemPaletteFirstUnusedIndex = g_systemPaletteFirstNonReservedIndex;
|
||||||
|
}
|
||||||
|
return LOG_RESULT(fillSystemPalette(hdc));
|
||||||
|
}
|
||||||
|
return LOG_RESULT(CALL_ORIG_FUNC(RealizePalette)(hdc));
|
||||||
|
}
|
||||||
|
|
||||||
|
int WINAPI releaseDc(HWND hWnd, HDC hDC)
|
||||||
|
{
|
||||||
|
LOG_FUNC("ReleaseDC", hWnd, hDC);
|
||||||
|
DDraw::ScopedThreadLock lock;
|
||||||
|
g_foregroundPaletteDcs.erase(hDC);
|
||||||
|
return LOG_RESULT(CALL_ORIG_FUNC(ReleaseDC)(hWnd, hDC));
|
||||||
|
}
|
||||||
|
|
||||||
|
HPALETTE WINAPI selectPalette(HDC hdc, HPALETTE hpal, BOOL bForceBackground)
|
||||||
|
{
|
||||||
|
LOG_FUNC("SelectPalette", hdc, hpal, bForceBackground);
|
||||||
|
HPALETTE result = CALL_ORIG_FUNC(SelectPalette)(hdc, hpal, bForceBackground);
|
||||||
|
if (result && Gdi::isDisplayDc(hdc))
|
||||||
|
{
|
||||||
|
HWND wnd = CALL_ORIG_FUNC(WindowFromDC)(hdc);
|
||||||
|
if (wnd && GetDesktopWindow() != wnd)
|
||||||
|
{
|
||||||
|
DDraw::ScopedThreadLock lock;
|
||||||
|
if (bForceBackground || GetStockObject(DEFAULT_PALETTE) == hpal)
|
||||||
|
{
|
||||||
|
g_foregroundPaletteDcs.erase(hdc);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_foregroundPaletteDcs.insert(hdc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return LOG_RESULT(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT WINAPI setSystemPaletteUse(HDC hdc, UINT uUsage)
|
||||||
|
{
|
||||||
|
LOG_FUNC("SetSystemPaletteUse", hdc, uUsage);
|
||||||
|
if (!Gdi::isDisplayDc(hdc))
|
||||||
|
{
|
||||||
|
return LOG_RESULT(SYSPAL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
DDraw::ScopedThreadLock lock;
|
||||||
|
const UINT prevUsage = g_systemPaletteUse;
|
||||||
|
switch (uUsage)
|
||||||
|
{
|
||||||
|
case SYSPAL_STATIC:
|
||||||
|
g_systemPaletteFirstNonReservedIndex = 10;
|
||||||
|
g_systemPaletteLastNonReservedIndex = 245;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSPAL_NOSTATIC:
|
||||||
|
g_systemPaletteFirstNonReservedIndex = 1;
|
||||||
|
g_systemPaletteLastNonReservedIndex = 254;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SYSPAL_NOSTATIC256:
|
||||||
|
g_systemPaletteFirstNonReservedIndex = 0;
|
||||||
|
g_systemPaletteLastNonReservedIndex = 255;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return LOG_RESULT(SYSPAL_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_systemPaletteUse = uUsage;
|
||||||
|
return LOG_RESULT(prevUsage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Gdi
|
||||||
|
{
|
||||||
|
namespace Palette
|
||||||
|
{
|
||||||
|
void installHooks()
|
||||||
|
{
|
||||||
|
HPALETTE defaultPalette = reinterpret_cast<HPALETTE>(GetStockObject(DEFAULT_PALETTE));
|
||||||
|
GetPaletteEntries(defaultPalette, 0, 10, g_systemPalette);
|
||||||
|
GetPaletteEntries(defaultPalette, 246, 10, &g_systemPalette[246]);
|
||||||
|
Gdi::VirtualScreen::updatePalette();
|
||||||
|
|
||||||
|
HOOK_FUNCTION(gdi32, GetSystemPaletteEntries, getSystemPaletteEntries);
|
||||||
|
HOOK_FUNCTION(gdi32, GetSystemPaletteUse, getSystemPaletteUse);
|
||||||
|
HOOK_FUNCTION(gdi32, RealizePalette, realizePalette);
|
||||||
|
HOOK_FUNCTION(user32, ReleaseDC, releaseDc);
|
||||||
|
HOOK_FUNCTION(gdi32, SelectPalette, selectPalette);
|
||||||
|
HOOK_FUNCTION(gdi32, SetSystemPaletteUse, setSystemPaletteUse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
9
DDrawCompat/Gdi/Palette.h
Normal file
9
DDrawCompat/Gdi/Palette.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Gdi
|
||||||
|
{
|
||||||
|
namespace Palette
|
||||||
|
{
|
||||||
|
void installHooks();
|
||||||
|
}
|
||||||
|
}
|
@ -168,7 +168,6 @@ namespace Gdi
|
|||||||
void init()
|
void init()
|
||||||
{
|
{
|
||||||
update();
|
update();
|
||||||
updatePalette();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool update()
|
bool update()
|
||||||
@ -220,13 +219,9 @@ namespace Gdi
|
|||||||
void updatePalette()
|
void updatePalette()
|
||||||
{
|
{
|
||||||
DDraw::ScopedThreadLock lock;
|
DDraw::ScopedThreadLock lock;
|
||||||
if (8 != g_bpp)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
PALETTEENTRY pal[256] = {};
|
PALETTEENTRY pal[256] = {};
|
||||||
GetSystemPaletteEntries(nullptr, 0, 256, pal);
|
GetSystemPaletteEntries(Gdi::getScreenDc(), 0, 256, pal);
|
||||||
|
|
||||||
RGBQUAD systemPalette[256] = {};
|
RGBQUAD systemPalette[256] = {};
|
||||||
for (int i = 0; i < 256; ++i)
|
for (int i = 0; i < 256; ++i)
|
||||||
|
@ -6,10 +6,12 @@
|
|||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#include "Common/Hook.h"
|
||||||
#include "Common/Log.h"
|
#include "Common/Log.h"
|
||||||
#include "Common/ScopedCriticalSection.h"
|
#include "Common/ScopedCriticalSection.h"
|
||||||
#include "Gdi/AccessGuard.h"
|
#include "Gdi/AccessGuard.h"
|
||||||
#include "Gdi/Dc.h"
|
#include "Gdi/Dc.h"
|
||||||
|
#include "Win32/DisplayMode.h"
|
||||||
#include "Gdi/PaintHandlers.h"
|
#include "Gdi/PaintHandlers.h"
|
||||||
#include "Gdi/ScrollBar.h"
|
#include "Gdi/ScrollBar.h"
|
||||||
#include "Gdi/ScrollFunctions.h"
|
#include "Gdi/ScrollFunctions.h"
|
||||||
@ -94,6 +96,10 @@ namespace
|
|||||||
if (GetCurrentProcessId() == windowPid)
|
if (GetCurrentProcessId() == windowPid)
|
||||||
{
|
{
|
||||||
onCreateWindow(hwnd);
|
onCreateWindow(hwnd);
|
||||||
|
if (8 == Win32::DisplayMode::getBpp())
|
||||||
|
{
|
||||||
|
PostMessage(hwnd, WM_PALETTECHANGED, reinterpret_cast<WPARAM>(GetDesktopWindow()), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -148,7 +154,7 @@ namespace
|
|||||||
}
|
}
|
||||||
Gdi::Dc::releaseDc(windowDc);
|
Gdi::Dc::releaseDc(windowDc);
|
||||||
}
|
}
|
||||||
ReleaseDC(hwnd, windowDc);
|
CALL_ORIG_FUNC(ReleaseDC)(hwnd, windowDc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,7 +248,7 @@ namespace Gdi
|
|||||||
{
|
{
|
||||||
HDC windowDc = GetWindowDC(m_hwnd);
|
HDC windowDc = GetWindowDC(m_hwnd);
|
||||||
GetRandomRgn(windowDc, newVisibleRegion, SYSRGN);
|
GetRandomRgn(windowDc, newVisibleRegion, SYSRGN);
|
||||||
ReleaseDC(m_hwnd, windowDc);
|
CALL_ORIG_FUNC(ReleaseDC)(m_hwnd, windowDc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_presentationWindow && GetCurrentThreadId() == GetWindowThreadProcessId(m_hwnd, nullptr))
|
if (m_presentationWindow && GetCurrentThreadId() == GetWindowThreadProcessId(m_hwnd, nullptr))
|
||||||
|
@ -28,8 +28,6 @@ namespace
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
CompatWeakPtr<IDirectDrawSurface7> g_compatibleSurface = {};
|
|
||||||
HDC g_compatibleDc = nullptr;
|
|
||||||
DWORD g_origBpp = 0;
|
DWORD g_origBpp = 0;
|
||||||
DWORD g_currentBpp = 0;
|
DWORD g_currentBpp = 0;
|
||||||
DWORD g_lastBpp = 0;
|
DWORD g_lastBpp = 0;
|
||||||
@ -39,7 +37,6 @@ namespace
|
|||||||
LPCSTR lpszDeviceName, DWORD iModeNum, DEVMODEA* lpDevMode, DWORD dwFlags);
|
LPCSTR lpszDeviceName, DWORD iModeNum, DEVMODEA* lpDevMode, DWORD dwFlags);
|
||||||
BOOL WINAPI enumDisplaySettingsExW(
|
BOOL WINAPI enumDisplaySettingsExW(
|
||||||
LPCWSTR lpszDeviceName, DWORD iModeNum, DEVMODEW* lpDevMode, DWORD dwFlags);
|
LPCWSTR lpszDeviceName, DWORD iModeNum, DEVMODEW* lpDevMode, DWORD dwFlags);
|
||||||
void updateCompatibleDc();
|
|
||||||
|
|
||||||
template <typename CStr, typename DevMode, typename ChangeDisplaySettingsExFunc,
|
template <typename CStr, typename DevMode, typename ChangeDisplaySettingsExFunc,
|
||||||
typename EnumDisplaySettingsExFunc>
|
typename EnumDisplaySettingsExFunc>
|
||||||
@ -80,7 +77,6 @@ namespace
|
|||||||
{
|
{
|
||||||
g_currentBpp = g_origBpp;
|
g_currentBpp = g_origBpp;
|
||||||
}
|
}
|
||||||
updateCompatibleDc();
|
|
||||||
|
|
||||||
DevMode currDevMode = {};
|
DevMode currDevMode = {};
|
||||||
currDevMode.dmSize = sizeof(currDevMode);
|
currDevMode.dmSize = sizeof(currDevMode);
|
||||||
@ -290,65 +286,12 @@ namespace
|
|||||||
}
|
}
|
||||||
return LOG_RESULT(CALL_ORIG_FUNC(GetDeviceCaps)(hdc, nIndex));
|
return LOG_RESULT(CALL_ORIG_FUNC(GetDeviceCaps)(hdc, nIndex));
|
||||||
}
|
}
|
||||||
|
|
||||||
void releaseCompatibleDc()
|
|
||||||
{
|
|
||||||
if (g_compatibleDc)
|
|
||||||
{
|
|
||||||
Dll::g_origProcs.AcquireDDThreadLock();
|
|
||||||
g_compatibleSurface->ReleaseDC(g_compatibleSurface, g_compatibleDc);
|
|
||||||
g_compatibleDc = nullptr;
|
|
||||||
g_compatibleSurface.release();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void replaceDc(HDC& hdc)
|
|
||||||
{
|
|
||||||
if (g_compatibleDc && hdc &&
|
|
||||||
OBJ_DC == GetObjectType(hdc) && DT_RASDISPLAY == GetDeviceCaps(hdc, TECHNOLOGY))
|
|
||||||
{
|
|
||||||
hdc = g_compatibleDc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void updateCompatibleDc()
|
|
||||||
{
|
|
||||||
releaseCompatibleDc();
|
|
||||||
g_compatibleSurface = DDraw::createCompatibleSurface(g_currentBpp).detach();
|
|
||||||
if (g_compatibleSurface &&
|
|
||||||
SUCCEEDED(g_compatibleSurface->GetDC(g_compatibleSurface, &g_compatibleDc)))
|
|
||||||
{
|
|
||||||
Dll::g_origProcs.ReleaseDDThreadLock();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Win32
|
namespace Win32
|
||||||
{
|
{
|
||||||
namespace DisplayMode
|
namespace DisplayMode
|
||||||
{
|
{
|
||||||
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy)
|
|
||||||
{
|
|
||||||
LOG_FUNC("CreateCompatibleBitmap", hdc, cx, cy);
|
|
||||||
replaceDc(hdc);
|
|
||||||
return LOG_RESULT(CALL_ORIG_FUNC(CreateCompatibleBitmap)(hdc, cx, cy));
|
|
||||||
}
|
|
||||||
|
|
||||||
HBITMAP WINAPI createDIBitmap(HDC hdc, const BITMAPINFOHEADER* lpbmih, DWORD fdwInit,
|
|
||||||
const void* lpbInit, const BITMAPINFO* lpbmi, UINT fuUsage)
|
|
||||||
{
|
|
||||||
LOG_FUNC("CreateDIBitmap", hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage);
|
|
||||||
replaceDc(hdc);
|
|
||||||
return LOG_RESULT(CALL_ORIG_FUNC(CreateDIBitmap)(hdc, lpbmih, fdwInit, lpbInit, lpbmi, fuUsage));
|
|
||||||
}
|
|
||||||
|
|
||||||
HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight)
|
|
||||||
{
|
|
||||||
LOG_FUNC("CreateDiscardableBitmap", hdc, nWidth, nHeight);
|
|
||||||
replaceDc(hdc);
|
|
||||||
return LOG_RESULT(CALL_ORIG_FUNC(createDiscardableBitmap)(hdc, nWidth, nHeight));
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD getBpp()
|
DWORD getBpp()
|
||||||
{
|
{
|
||||||
return g_currentBpp;
|
return g_currentBpp;
|
||||||
@ -380,6 +323,12 @@ namespace Win32
|
|||||||
g_currentBpp = g_origBpp;
|
g_currentBpp = g_origBpp;
|
||||||
g_lastBpp = g_origBpp;
|
g_lastBpp = g_origBpp;
|
||||||
|
|
||||||
|
if (32 != devMode.dmBitsPerPel)
|
||||||
|
{
|
||||||
|
devMode.dmBitsPerPel = 32;
|
||||||
|
ChangeDisplaySettings(&devMode, 0);
|
||||||
|
}
|
||||||
|
|
||||||
HOOK_FUNCTION(user32, ChangeDisplaySettingsExA, changeDisplaySettingsExA);
|
HOOK_FUNCTION(user32, ChangeDisplaySettingsExA, changeDisplaySettingsExA);
|
||||||
HOOK_FUNCTION(user32, ChangeDisplaySettingsExW, changeDisplaySettingsExW);
|
HOOK_FUNCTION(user32, ChangeDisplaySettingsExW, changeDisplaySettingsExW);
|
||||||
HOOK_FUNCTION(user32, EnumDisplaySettingsExA, enumDisplaySettingsExA);
|
HOOK_FUNCTION(user32, EnumDisplaySettingsExA, enumDisplaySettingsExA);
|
||||||
@ -402,8 +351,6 @@ namespace Win32
|
|||||||
&ddrawEnumDisplaySettingsExA);
|
&ddrawEnumDisplaySettingsExA);
|
||||||
Compat::hookIatFunction(origDDrawModule, "user32.dll", "EnumDisplaySettingsExW",
|
Compat::hookIatFunction(origDDrawModule, "user32.dll", "EnumDisplaySettingsExW",
|
||||||
&ddrawEnumDisplaySettingsExW);
|
&ddrawEnumDisplaySettingsExW);
|
||||||
|
|
||||||
updateCompatibleDc();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,11 +8,6 @@ namespace Win32
|
|||||||
{
|
{
|
||||||
namespace DisplayMode
|
namespace DisplayMode
|
||||||
{
|
{
|
||||||
HBITMAP WINAPI createCompatibleBitmap(HDC hdc, int cx, int cy);
|
|
||||||
HBITMAP WINAPI createDIBitmap(HDC hdc, const BITMAPINFOHEADER* lpbmih, DWORD fdwInit,
|
|
||||||
const void* lpbInit, const BITMAPINFO* lpbmi, UINT fuUsage);
|
|
||||||
HBITMAP WINAPI createDiscardableBitmap(HDC hdc, int nWidth, int nHeight);
|
|
||||||
|
|
||||||
DWORD getBpp();
|
DWORD getBpp();
|
||||||
ULONG queryDisplaySettingsUniqueness();
|
ULONG queryDisplaySettingsUniqueness();
|
||||||
void setDDrawBpp(DWORD bpp);
|
void setDDrawBpp(DWORD bpp);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user