mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Use RealizePalette for windowed mode palette changes
This commit is contained in:
parent
950bde4161
commit
39bb699cf7
@ -13,6 +13,12 @@ namespace DDraw
|
|||||||
DDPIXELFORMAT getRgbPixelFormat(DWORD bpp);
|
DDPIXELFORMAT getRgbPixelFormat(DWORD bpp);
|
||||||
void suppressEmulatedDirectDraw(GUID*& guid);
|
void suppressEmulatedDirectDraw(GUID*& guid);
|
||||||
|
|
||||||
|
template <typename TDirectDraw>
|
||||||
|
HWND getDeviceWindow(TDirectDraw& dd)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<HWND**>(&dd)[1][8];
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TDirectDraw>
|
template <typename TDirectDraw>
|
||||||
class DirectDraw: public CompatVtable<Vtable<TDirectDraw>>
|
class DirectDraw: public CompatVtable<Vtable<TDirectDraw>>
|
||||||
{
|
{
|
||||||
|
@ -1,15 +1,15 @@
|
|||||||
#include "Common/CompatPtr.h"
|
#include <Common/CompatPtr.h>
|
||||||
#include "Common/CompatRef.h"
|
#include <Common/CompatRef.h>
|
||||||
#include "Config/Config.h"
|
#include <Config/Config.h>
|
||||||
#include "D3dDdi/Device.h"
|
#include <D3dDdi/Device.h>
|
||||||
#include "D3dDdi/KernelModeThunks.h"
|
#include <D3dDdi/KernelModeThunks.h>
|
||||||
#include "DDraw/DirectDraw.h"
|
#include <DDraw/DirectDraw.h>
|
||||||
#include "DDraw/DirectDrawSurface.h"
|
#include <DDraw/DirectDrawSurface.h>
|
||||||
#include "DDraw/RealPrimarySurface.h"
|
#include <DDraw/RealPrimarySurface.h>
|
||||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||||
#include "DDraw/Surfaces/PrimarySurfaceImpl.h"
|
#include <DDraw/Surfaces/PrimarySurfaceImpl.h>
|
||||||
#include "Gdi/Palette.h"
|
#include <Gdi/Palette.h>
|
||||||
#include "Gdi/VirtualScreen.h"
|
#include <Gdi/VirtualScreen.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -17,6 +17,8 @@ namespace
|
|||||||
HANDLE g_gdiResourceHandle = nullptr;
|
HANDLE g_gdiResourceHandle = nullptr;
|
||||||
HANDLE g_frontResource = nullptr;
|
HANDLE g_frontResource = nullptr;
|
||||||
DWORD g_origCaps = 0;
|
DWORD g_origCaps = 0;
|
||||||
|
HWND g_deviceWindow = nullptr;
|
||||||
|
HPALETTE g_palette = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace DDraw
|
namespace DDraw
|
||||||
@ -29,6 +31,12 @@ namespace DDraw
|
|||||||
g_frontResource = nullptr;
|
g_frontResource = nullptr;
|
||||||
g_primarySurface = nullptr;
|
g_primarySurface = nullptr;
|
||||||
g_origCaps = 0;
|
g_origCaps = 0;
|
||||||
|
g_deviceWindow = nullptr;
|
||||||
|
if (g_palette)
|
||||||
|
{
|
||||||
|
DeleteObject(g_palette);
|
||||||
|
g_palette = nullptr;
|
||||||
|
}
|
||||||
s_palette = nullptr;
|
s_palette = nullptr;
|
||||||
|
|
||||||
DDraw::RealPrimarySurface::release();
|
DDraw::RealPrimarySurface::release();
|
||||||
@ -70,6 +78,17 @@ namespace DDraw
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_origCaps = origCaps;
|
g_origCaps = origCaps;
|
||||||
|
g_deviceWindow = DDraw::getDeviceWindow(dd.get());
|
||||||
|
|
||||||
|
if (desc.ddpfPixelFormat.dwRGBBitCount <= 8)
|
||||||
|
{
|
||||||
|
LOGPALETTE lp = {};
|
||||||
|
lp.palVersion = 0x300;
|
||||||
|
lp.palNumEntries = 1;
|
||||||
|
g_palette = CreatePalette(&lp);
|
||||||
|
ResizePalette(g_palette, 256);
|
||||||
|
}
|
||||||
|
|
||||||
data->restore();
|
data->restore();
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
@ -215,24 +234,26 @@ namespace DDraw
|
|||||||
|
|
||||||
void PrimarySurface::updatePalette()
|
void PrimarySurface::updatePalette()
|
||||||
{
|
{
|
||||||
PALETTEENTRY entries[256] = {};
|
if (!s_palette)
|
||||||
if (s_palette)
|
|
||||||
{
|
{
|
||||||
PrimarySurface::s_palette->GetEntries(s_palette, 0, 0, 256, entries);
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PALETTEENTRY entries[256] = {};
|
||||||
|
PrimarySurface::s_palette->GetEntries(s_palette, 0, 0, 256, entries);
|
||||||
|
|
||||||
if (RealPrimarySurface::isFullScreen())
|
if (RealPrimarySurface::isFullScreen())
|
||||||
{
|
{
|
||||||
if (!s_palette)
|
|
||||||
{
|
|
||||||
auto sysPalEntries(Gdi::Palette::getSystemPalette());
|
|
||||||
std::memcpy(entries, sysPalEntries.data(), sizeof(entries));
|
|
||||||
}
|
|
||||||
Gdi::Palette::setHardwarePalette(entries);
|
Gdi::Palette::setHardwarePalette(entries);
|
||||||
}
|
}
|
||||||
else if (s_palette)
|
else
|
||||||
{
|
{
|
||||||
Gdi::Palette::setSystemPalette(entries, 256, false);
|
SetPaletteEntries(g_palette, 0, 256, entries);
|
||||||
|
HDC dc = GetDC(g_deviceWindow);
|
||||||
|
HPALETTE oldPal = SelectPalette(dc, g_palette, FALSE);
|
||||||
|
RealizePalette(dc);
|
||||||
|
SelectPalette(dc, oldPal, FALSE);
|
||||||
|
ReleaseDC(g_deviceWindow, dc);
|
||||||
}
|
}
|
||||||
|
|
||||||
RealPrimarySurface::update();
|
RealPrimarySurface::update();
|
||||||
|
@ -42,7 +42,6 @@ namespace DDraw
|
|||||||
|
|
||||||
virtual void createImpl();
|
virtual void createImpl();
|
||||||
|
|
||||||
void* m_ddObject;
|
|
||||||
std::unique_ptr<SurfaceImpl<IDirectDrawSurface>> m_impl;
|
std::unique_ptr<SurfaceImpl<IDirectDrawSurface>> m_impl;
|
||||||
std::unique_ptr<SurfaceImpl<IDirectDrawSurface2>> m_impl2;
|
std::unique_ptr<SurfaceImpl<IDirectDrawSurface2>> m_impl2;
|
||||||
std::unique_ptr<SurfaceImpl<IDirectDrawSurface3>> m_impl3;
|
std::unique_ptr<SurfaceImpl<IDirectDrawSurface3>> m_impl3;
|
||||||
|
@ -429,12 +429,10 @@ namespace Gdi
|
|||||||
HOOK_GDI_DC_FUNCTION(gdi32, GdiAlphaBlend);
|
HOOK_GDI_DC_FUNCTION(gdi32, GdiAlphaBlend);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, GdiGradientFill);
|
HOOK_GDI_DC_FUNCTION(gdi32, GdiGradientFill);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, GdiTransparentBlt);
|
HOOK_GDI_DC_FUNCTION(gdi32, GdiTransparentBlt);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, GetDIBits);
|
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, GetPixel);
|
HOOK_GDI_DC_FUNCTION(gdi32, GetPixel);
|
||||||
HOOK_GDI_DC_FUNCTION(msimg32, GradientFill);
|
HOOK_GDI_DC_FUNCTION(msimg32, GradientFill);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, MaskBlt);
|
HOOK_GDI_DC_FUNCTION(gdi32, MaskBlt);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, PlgBlt);
|
HOOK_GDI_DC_FUNCTION(gdi32, PlgBlt);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, SetDIBits);
|
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, SetDIBitsToDevice);
|
HOOK_GDI_DC_FUNCTION(gdi32, SetDIBitsToDevice);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, SetPixel);
|
HOOK_GDI_DC_FUNCTION(gdi32, SetPixel);
|
||||||
HOOK_GDI_DC_FUNCTION(gdi32, SetPixelV);
|
HOOK_GDI_DC_FUNCTION(gdi32, SetPixelV);
|
||||||
|
@ -19,7 +19,7 @@ namespace
|
|||||||
UINT g_systemPaletteFirstNonReservedIndex = 10;
|
UINT g_systemPaletteFirstNonReservedIndex = 10;
|
||||||
UINT g_systemPaletteLastNonReservedIndex = 245;
|
UINT g_systemPaletteLastNonReservedIndex = 245;
|
||||||
|
|
||||||
std::set<HDC> g_foregroundPaletteDcs;
|
std::set<HPALETTE> g_foregroundPalettes;
|
||||||
|
|
||||||
bool isSameColor(PALETTEENTRY entry1, PALETTEENTRY entry2)
|
bool isSameColor(PALETTEENTRY entry1, PALETTEENTRY entry2)
|
||||||
{
|
{
|
||||||
@ -63,6 +63,17 @@ namespace
|
|||||||
Gdi::VirtualScreen::updatePalette(g_systemPalette);
|
Gdi::VirtualScreen::updatePalette(g_systemPalette);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI deleteObject(HGDIOBJ ho)
|
||||||
|
{
|
||||||
|
BOOL result = CALL_ORIG_FUNC(DeleteObject)(ho);
|
||||||
|
if (result && OBJ_PAL == GetObjectType(ho))
|
||||||
|
{
|
||||||
|
Compat::ScopedCriticalSection lock(g_cs);
|
||||||
|
g_foregroundPalettes.erase(static_cast<HPALETTE>(ho));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
UINT WINAPI getSystemPaletteEntries(HDC hdc, UINT iStartIndex, UINT nEntries, LPPALETTEENTRY lppe)
|
UINT WINAPI getSystemPaletteEntries(HDC hdc, UINT iStartIndex, UINT nEntries, LPPALETTEENTRY lppe)
|
||||||
{
|
{
|
||||||
LOG_FUNC("GetSystemPaletteEntries", hdc, iStartIndex, nEntries, lppe);
|
LOG_FUNC("GetSystemPaletteEntries", hdc, iStartIndex, nEntries, lppe);
|
||||||
@ -108,8 +119,6 @@ namespace
|
|||||||
LOG_FUNC("RealizePalette", hdc);
|
LOG_FUNC("RealizePalette", hdc);
|
||||||
if (Gdi::isDisplayDc(hdc))
|
if (Gdi::isDisplayDc(hdc))
|
||||||
{
|
{
|
||||||
Compat::ScopedCriticalSection lock(g_cs);
|
|
||||||
|
|
||||||
HPALETTE palette = reinterpret_cast<HPALETTE>(GetCurrentObject(hdc, OBJ_PAL));
|
HPALETTE palette = reinterpret_cast<HPALETTE>(GetCurrentObject(hdc, OBJ_PAL));
|
||||||
if (!palette || GetStockObject(DEFAULT_PALETTE) == palette)
|
if (!palette || GetStockObject(DEFAULT_PALETTE) == palette)
|
||||||
{
|
{
|
||||||
@ -118,38 +127,28 @@ namespace
|
|||||||
|
|
||||||
PALETTEENTRY entries[256] = {};
|
PALETTEENTRY entries[256] = {};
|
||||||
UINT count = GetPaletteEntries(palette, 0, 256, entries);
|
UINT count = GetPaletteEntries(palette, 0, 256, entries);
|
||||||
|
Compat::ScopedCriticalSection lock(g_cs);
|
||||||
Gdi::Palette::setSystemPalette(entries, count,
|
Gdi::Palette::setSystemPalette(entries, count,
|
||||||
g_foregroundPaletteDcs.find(hdc) == g_foregroundPaletteDcs.end());
|
g_foregroundPalettes.find(palette) == g_foregroundPalettes.end());
|
||||||
return LOG_RESULT(count);
|
return LOG_RESULT(count);
|
||||||
}
|
}
|
||||||
return LOG_RESULT(CALL_ORIG_FUNC(RealizePalette)(hdc));
|
return LOG_RESULT(CALL_ORIG_FUNC(RealizePalette)(hdc));
|
||||||
}
|
}
|
||||||
|
|
||||||
int WINAPI releaseDc(HWND hWnd, HDC hDC)
|
|
||||||
{
|
|
||||||
LOG_FUNC("ReleaseDC", hWnd, hDC);
|
|
||||||
Compat::ScopedCriticalSection lock(g_cs);
|
|
||||||
g_foregroundPaletteDcs.erase(hDC);
|
|
||||||
return LOG_RESULT(CALL_ORIG_FUNC(ReleaseDC)(hWnd, hDC));
|
|
||||||
}
|
|
||||||
|
|
||||||
HPALETTE WINAPI selectPalette(HDC hdc, HPALETTE hpal, BOOL bForceBackground)
|
HPALETTE WINAPI selectPalette(HDC hdc, HPALETTE hpal, BOOL bForceBackground)
|
||||||
{
|
{
|
||||||
LOG_FUNC("SelectPalette", hdc, hpal, bForceBackground);
|
LOG_FUNC("SelectPalette", hdc, hpal, bForceBackground);
|
||||||
HPALETTE result = CALL_ORIG_FUNC(SelectPalette)(hdc, hpal, bForceBackground);
|
HPALETTE result = CALL_ORIG_FUNC(SelectPalette)(hdc, hpal, bForceBackground);
|
||||||
if (result && Gdi::isDisplayDc(hdc))
|
if (result && !bForceBackground)
|
||||||
{
|
{
|
||||||
HWND wnd = CALL_ORIG_FUNC(WindowFromDC)(hdc);
|
HWND dcWindow = CALL_ORIG_FUNC(WindowFromDC)(hdc);
|
||||||
if (wnd && GetDesktopWindow() != wnd)
|
if (dcWindow && !(GetWindowLong(dcWindow, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
|
||||||
{
|
{
|
||||||
Compat::ScopedCriticalSection lock(g_cs);
|
HWND activeWindow = GetActiveWindow();
|
||||||
if (bForceBackground || GetStockObject(DEFAULT_PALETTE) == hpal)
|
if (activeWindow == dcWindow || IsChild(activeWindow, dcWindow))
|
||||||
{
|
{
|
||||||
g_foregroundPaletteDcs.erase(hdc);
|
Compat::ScopedCriticalSection lock(g_cs);
|
||||||
}
|
g_foregroundPalettes.insert(hpal);
|
||||||
else
|
|
||||||
{
|
|
||||||
g_foregroundPaletteDcs.insert(hdc);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,10 +226,10 @@ namespace Gdi
|
|||||||
|
|
||||||
updateStaticSysPalEntries();
|
updateStaticSysPalEntries();
|
||||||
|
|
||||||
|
HOOK_FUNCTION(gdi32, DeleteObject, deleteObject);
|
||||||
HOOK_FUNCTION(gdi32, GetSystemPaletteEntries, getSystemPaletteEntries);
|
HOOK_FUNCTION(gdi32, GetSystemPaletteEntries, getSystemPaletteEntries);
|
||||||
HOOK_FUNCTION(gdi32, GetSystemPaletteUse, getSystemPaletteUse);
|
HOOK_FUNCTION(gdi32, GetSystemPaletteUse, getSystemPaletteUse);
|
||||||
HOOK_FUNCTION(gdi32, RealizePalette, realizePalette);
|
HOOK_FUNCTION(gdi32, RealizePalette, realizePalette);
|
||||||
HOOK_FUNCTION(user32, ReleaseDC, releaseDc);
|
|
||||||
HOOK_FUNCTION(gdi32, SelectPalette, selectPalette);
|
HOOK_FUNCTION(gdi32, SelectPalette, selectPalette);
|
||||||
HOOK_FUNCTION(gdi32, SetSystemPaletteUse, setSystemPaletteUse);
|
HOOK_FUNCTION(gdi32, SetSystemPaletteUse, setSystemPaletteUse);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user