1
0
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:
narzoul 2021-01-24 21:49:16 +01:00
parent 950bde4161
commit 39bb699cf7
5 changed files with 71 additions and 48 deletions

View File

@ -13,6 +13,12 @@ namespace DDraw
DDPIXELFORMAT getRgbPixelFormat(DWORD bpp);
void suppressEmulatedDirectDraw(GUID*& guid);
template <typename TDirectDraw>
HWND getDeviceWindow(TDirectDraw& dd)
{
return reinterpret_cast<HWND**>(&dd)[1][8];
}
template <typename TDirectDraw>
class DirectDraw: public CompatVtable<Vtable<TDirectDraw>>
{

View File

@ -1,15 +1,15 @@
#include "Common/CompatPtr.h"
#include "Common/CompatRef.h"
#include "Config/Config.h"
#include "D3dDdi/Device.h"
#include "D3dDdi/KernelModeThunks.h"
#include "DDraw/DirectDraw.h"
#include "DDraw/DirectDrawSurface.h"
#include "DDraw/RealPrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurface.h"
#include "DDraw/Surfaces/PrimarySurfaceImpl.h"
#include "Gdi/Palette.h"
#include "Gdi/VirtualScreen.h"
#include <Common/CompatPtr.h>
#include <Common/CompatRef.h>
#include <Config/Config.h>
#include <D3dDdi/Device.h>
#include <D3dDdi/KernelModeThunks.h>
#include <DDraw/DirectDraw.h>
#include <DDraw/DirectDrawSurface.h>
#include <DDraw/RealPrimarySurface.h>
#include <DDraw/Surfaces/PrimarySurface.h>
#include <DDraw/Surfaces/PrimarySurfaceImpl.h>
#include <Gdi/Palette.h>
#include <Gdi/VirtualScreen.h>
namespace
{
@ -17,6 +17,8 @@ namespace
HANDLE g_gdiResourceHandle = nullptr;
HANDLE g_frontResource = nullptr;
DWORD g_origCaps = 0;
HWND g_deviceWindow = nullptr;
HPALETTE g_palette = nullptr;
}
namespace DDraw
@ -29,6 +31,12 @@ namespace DDraw
g_frontResource = nullptr;
g_primarySurface = nullptr;
g_origCaps = 0;
g_deviceWindow = nullptr;
if (g_palette)
{
DeleteObject(g_palette);
g_palette = nullptr;
}
s_palette = nullptr;
DDraw::RealPrimarySurface::release();
@ -70,6 +78,17 @@ namespace DDraw
}
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();
return DD_OK;
}
@ -215,24 +234,26 @@ namespace DDraw
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 (!s_palette)
{
auto sysPalEntries(Gdi::Palette::getSystemPalette());
std::memcpy(entries, sysPalEntries.data(), sizeof(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();

View File

@ -42,7 +42,6 @@ namespace DDraw
virtual void createImpl();
void* m_ddObject;
std::unique_ptr<SurfaceImpl<IDirectDrawSurface>> m_impl;
std::unique_ptr<SurfaceImpl<IDirectDrawSurface2>> m_impl2;
std::unique_ptr<SurfaceImpl<IDirectDrawSurface3>> m_impl3;

View File

@ -429,12 +429,10 @@ namespace Gdi
HOOK_GDI_DC_FUNCTION(gdi32, GdiAlphaBlend);
HOOK_GDI_DC_FUNCTION(gdi32, GdiGradientFill);
HOOK_GDI_DC_FUNCTION(gdi32, GdiTransparentBlt);
HOOK_GDI_DC_FUNCTION(gdi32, GetDIBits);
HOOK_GDI_DC_FUNCTION(gdi32, GetPixel);
HOOK_GDI_DC_FUNCTION(msimg32, GradientFill);
HOOK_GDI_DC_FUNCTION(gdi32, MaskBlt);
HOOK_GDI_DC_FUNCTION(gdi32, PlgBlt);
HOOK_GDI_DC_FUNCTION(gdi32, SetDIBits);
HOOK_GDI_DC_FUNCTION(gdi32, SetDIBitsToDevice);
HOOK_GDI_DC_FUNCTION(gdi32, SetPixel);
HOOK_GDI_DC_FUNCTION(gdi32, SetPixelV);

View File

@ -19,7 +19,7 @@ namespace
UINT g_systemPaletteFirstNonReservedIndex = 10;
UINT g_systemPaletteLastNonReservedIndex = 245;
std::set<HDC> g_foregroundPaletteDcs;
std::set<HPALETTE> g_foregroundPalettes;
bool isSameColor(PALETTEENTRY entry1, PALETTEENTRY entry2)
{
@ -63,6 +63,17 @@ namespace
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)
{
LOG_FUNC("GetSystemPaletteEntries", hdc, iStartIndex, nEntries, lppe);
@ -108,8 +119,6 @@ namespace
LOG_FUNC("RealizePalette", hdc);
if (Gdi::isDisplayDc(hdc))
{
Compat::ScopedCriticalSection lock(g_cs);
HPALETTE palette = reinterpret_cast<HPALETTE>(GetCurrentObject(hdc, OBJ_PAL));
if (!palette || GetStockObject(DEFAULT_PALETTE) == palette)
{
@ -118,38 +127,28 @@ namespace
PALETTEENTRY entries[256] = {};
UINT count = GetPaletteEntries(palette, 0, 256, entries);
Compat::ScopedCriticalSection lock(g_cs);
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(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)
{
LOG_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);
if (wnd && GetDesktopWindow() != wnd)
HWND dcWindow = CALL_ORIG_FUNC(WindowFromDC)(hdc);
if (dcWindow && !(GetWindowLong(dcWindow, GWL_EXSTYLE) & WS_EX_TOOLWINDOW))
{
Compat::ScopedCriticalSection lock(g_cs);
if (bForceBackground || GetStockObject(DEFAULT_PALETTE) == hpal)
HWND activeWindow = GetActiveWindow();
if (activeWindow == dcWindow || IsChild(activeWindow, dcWindow))
{
g_foregroundPaletteDcs.erase(hdc);
}
else
{
g_foregroundPaletteDcs.insert(hdc);
Compat::ScopedCriticalSection lock(g_cs);
g_foregroundPalettes.insert(hpal);
}
}
}
@ -227,10 +226,10 @@ namespace Gdi
updateStaticSysPalEntries();
HOOK_FUNCTION(gdi32, DeleteObject, deleteObject);
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);
}