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);
|
||||
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>>
|
||||
{
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user