mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Improved palette handling
Fixes windowed-mode palette issues in SimCopter (issue #46)
This commit is contained in:
parent
b747448330
commit
7068d282ff
@ -10,10 +10,15 @@
|
|||||||
#include "Common/Hook.h"
|
#include "Common/Hook.h"
|
||||||
#include "Common/ScopedCriticalSection.h"
|
#include "Common/ScopedCriticalSection.h"
|
||||||
#include "Common/Time.h"
|
#include "Common/Time.h"
|
||||||
|
#include "D3dDdi/Device.h"
|
||||||
#include "D3dDdi/Hooks.h"
|
#include "D3dDdi/Hooks.h"
|
||||||
#include "D3dDdi/KernelModeThunks.h"
|
#include "D3dDdi/KernelModeThunks.h"
|
||||||
#include "D3dDdi/Log/KernelModeThunksLog.h"
|
#include "D3dDdi/Log/KernelModeThunksLog.h"
|
||||||
|
#include "D3dDdi/Resource.h"
|
||||||
|
#include "D3dDdi/ScopedCriticalSection.h"
|
||||||
|
#include "DDraw/ScopedThreadLock.h"
|
||||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||||
|
#include "Gdi/Palette.h"
|
||||||
#include "Win32/DisplayMode.h"
|
#include "Win32/DisplayMode.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -34,6 +39,7 @@ namespace
|
|||||||
|
|
||||||
std::map<D3DKMT_HANDLE, ContextInfo> g_contexts;
|
std::map<D3DKMT_HANDLE, ContextInfo> g_contexts;
|
||||||
D3DDDIFORMAT g_dcFormatOverride = D3DDDIFMT_UNKNOWN;
|
D3DDDIFORMAT g_dcFormatOverride = D3DDDIFMT_UNKNOWN;
|
||||||
|
bool g_dcPaletteOverride = false;
|
||||||
AdapterInfo g_gdiAdapterInfo = {};
|
AdapterInfo g_gdiAdapterInfo = {};
|
||||||
AdapterInfo g_lastOpenAdapterInfo = {};
|
AdapterInfo g_lastOpenAdapterInfo = {};
|
||||||
std::string g_lastDDrawCreateDcDevice;
|
std::string g_lastDDrawCreateDcDevice;
|
||||||
@ -88,20 +94,50 @@ namespace
|
|||||||
pData->Format = g_dcFormatOverride;
|
pData->Format = g_dcFormatOverride;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS result = 0;
|
std::vector<PALETTEENTRY> palette;
|
||||||
if (D3DDDIFMT_P8 == pData->Format && !pData->pColorTable &&
|
auto origColorTable = pData->pColorTable;
|
||||||
DDraw::PrimarySurface::s_palette)
|
|
||||||
|
if (D3DDDIFMT_P8 == pData->Format)
|
||||||
{
|
{
|
||||||
pData->pColorTable = DDraw::PrimarySurface::s_paletteEntries;
|
if (g_dcPaletteOverride)
|
||||||
result = CALL_ORIG_FUNC(D3DKMTCreateDCFromMemory)(pData);
|
{
|
||||||
pData->pColorTable = nullptr;
|
palette = Gdi::Palette::getHardwarePalette();
|
||||||
}
|
pData->pColorTable = palette.data();
|
||||||
else
|
}
|
||||||
{
|
else
|
||||||
result = CALL_ORIG_FUNC(D3DKMTCreateDCFromMemory)(pData);
|
{
|
||||||
|
DDraw::ScopedThreadLock ddLock;
|
||||||
|
D3dDdi::ScopedCriticalSection driverLock;
|
||||||
|
auto primaryResource = D3dDdi::Device::getResource(DDraw::PrimarySurface::getFrontResource());
|
||||||
|
if (primaryResource && pData->pMemory == primaryResource->getLockPtr(0) &&
|
||||||
|
(DDraw::PrimarySurface::getOrigCaps() & DDSCAPS_COMPLEX))
|
||||||
|
{
|
||||||
|
pData->pColorTable = Gdi::Palette::getDefaultPalette();
|
||||||
|
}
|
||||||
|
else if (pData->pColorTable)
|
||||||
|
{
|
||||||
|
palette.assign(pData->pColorTable, pData->pColorTable + 256);
|
||||||
|
auto sysPal = Gdi::Palette::getSystemPalette();
|
||||||
|
for (UINT i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
if (palette[i].peFlags & PC_EXPLICIT)
|
||||||
|
{
|
||||||
|
palette[i] = sysPal[palette[i].peRed];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pData->pColorTable = palette.data();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
palette = Gdi::Palette::getHardwarePalette();
|
||||||
|
pData->pColorTable = palette.data();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto result = CALL_ORIG_FUNC(D3DKMTCreateDCFromMemory)(pData);
|
||||||
pData->Format = origFormat;
|
pData->Format = origFormat;
|
||||||
|
pData->pColorTable = origColorTable;
|
||||||
return LOG_RESULT(result);
|
return LOG_RESULT(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -391,6 +427,11 @@ namespace D3dDdi
|
|||||||
g_dcFormatOverride = static_cast<D3DDDIFORMAT>(format);
|
g_dcFormatOverride = static_cast<D3DDDIFORMAT>(format);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setDcPaletteOverride(bool enable)
|
||||||
|
{
|
||||||
|
g_dcPaletteOverride = enable;
|
||||||
|
}
|
||||||
|
|
||||||
void waitForVerticalBlank()
|
void waitForVerticalBlank()
|
||||||
{
|
{
|
||||||
D3DKMT_WAITFORVERTICALBLANKEVENT data = {};
|
D3DKMT_WAITFORVERTICALBLANKEVENT data = {};
|
||||||
|
@ -16,6 +16,7 @@ namespace D3dDdi
|
|||||||
void installHooks(HMODULE origDDrawModule);
|
void installHooks(HMODULE origDDrawModule);
|
||||||
void setFlipIntervalOverride(UINT flipInterval);
|
void setFlipIntervalOverride(UINT flipInterval);
|
||||||
void setDcFormatOverride(UINT format);
|
void setDcFormatOverride(UINT format);
|
||||||
|
void setDcPaletteOverride(bool enable);
|
||||||
void waitForVerticalBlank();
|
void waitForVerticalBlank();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -371,6 +371,19 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* Resource::getLockPtr(UINT subResourceIndex)
|
||||||
|
{
|
||||||
|
if (subResourceIndex < m_lockData.size())
|
||||||
|
{
|
||||||
|
return m_lockData[subResourceIndex].data;
|
||||||
|
}
|
||||||
|
else if (subResourceIndex < m_fixedData.SurfCount)
|
||||||
|
{
|
||||||
|
return const_cast<void*>(m_fixedData.pSurfList[subResourceIndex].pSysMem);
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
bool Resource::isOversized() const
|
bool Resource::isOversized() const
|
||||||
{
|
{
|
||||||
return m_fixedData.SurfCount != m_origData.SurfCount;
|
return m_fixedData.SurfCount != m_origData.SurfCount;
|
||||||
|
@ -28,6 +28,7 @@ namespace D3dDdi
|
|||||||
HRESULT blt(D3DDDIARG_BLT data);
|
HRESULT blt(D3DDDIARG_BLT data);
|
||||||
HRESULT colorFill(const D3DDDIARG_COLORFILL& data);
|
HRESULT colorFill(const D3DDDIARG_COLORFILL& data);
|
||||||
void destroy();
|
void destroy();
|
||||||
|
void* getLockPtr(UINT subResourceIndex);
|
||||||
HRESULT lock(D3DDDIARG_LOCK& data);
|
HRESULT lock(D3DDDIARG_LOCK& data);
|
||||||
void prepareForRendering(UINT subResourceIndex, bool isReadOnly);
|
void prepareForRendering(UINT subResourceIndex, bool isReadOnly);
|
||||||
void resync();
|
void resync();
|
||||||
|
@ -24,16 +24,10 @@ namespace DDraw
|
|||||||
if (This == PrimarySurface::s_palette)
|
if (This == PrimarySurface::s_palette)
|
||||||
{
|
{
|
||||||
waitForNextUpdate();
|
waitForNextUpdate();
|
||||||
if (lpEntries && dwStartingEntry + dwCount <= 256 &&
|
|
||||||
0 == std::memcmp(&PrimarySurface::s_paletteEntries[dwStartingEntry],
|
|
||||||
lpEntries, dwCount * sizeof(PALETTEENTRY)))
|
|
||||||
{
|
|
||||||
return DD_OK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (SUCCEEDED(result) && This == PrimarySurface::s_palette)
|
||||||
{
|
{
|
||||||
PrimarySurface::updatePalette();
|
PrimarySurface::updatePalette();
|
||||||
}
|
}
|
||||||
|
@ -375,7 +375,9 @@ namespace
|
|||||||
g_paletteConverter->GetDC(g_paletteConverter, &paletteConverterDc);
|
g_paletteConverter->GetDC(g_paletteConverter, &paletteConverterDc);
|
||||||
HDC srcDc = nullptr;
|
HDC srcDc = nullptr;
|
||||||
D3dDdi::Device::setReadOnlyGdiLock(true);
|
D3dDdi::Device::setReadOnlyGdiLock(true);
|
||||||
|
D3dDdi::KernelModeThunks::setDcPaletteOverride(true);
|
||||||
src->GetDC(src, &srcDc);
|
src->GetDC(src, &srcDc);
|
||||||
|
D3dDdi::KernelModeThunks::setDcPaletteOverride(false);
|
||||||
D3dDdi::Device::setReadOnlyGdiLock(false);
|
D3dDdi::Device::setReadOnlyGdiLock(false);
|
||||||
|
|
||||||
if (paletteConverterDc && srcDc)
|
if (paletteConverterDc && srcDc)
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#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/VirtualScreen.h"
|
#include "Gdi/VirtualScreen.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -30,7 +31,6 @@ namespace DDraw
|
|||||||
g_primarySurface = nullptr;
|
g_primarySurface = nullptr;
|
||||||
g_origCaps = 0;
|
g_origCaps = 0;
|
||||||
s_palette = nullptr;
|
s_palette = nullptr;
|
||||||
ZeroMemory(&s_paletteEntries, sizeof(s_paletteEntries));
|
|
||||||
|
|
||||||
for (auto& lockBuffer : g_lockBackBuffers)
|
for (auto& lockBuffer : g_lockBackBuffers)
|
||||||
{
|
{
|
||||||
@ -233,13 +233,28 @@ 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, s_paletteEntries);
|
PrimarySurface::s_palette->GetEntries(s_palette, 0, 0, 256, entries);
|
||||||
RealPrimarySurface::update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Gdi::Palette::setSystemPalette(entries, 256, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
RealPrimarySurface::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette;
|
CompatWeakPtr<IDirectDrawPalette> PrimarySurface::s_palette;
|
||||||
PALETTEENTRY PrimarySurface::s_paletteEntries[256] = {};
|
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@ namespace DDraw
|
|||||||
virtual void restore();
|
virtual void restore();
|
||||||
|
|
||||||
static CompatWeakPtr<IDirectDrawPalette> s_palette;
|
static CompatWeakPtr<IDirectDrawPalette> s_palette;
|
||||||
static PALETTEENTRY s_paletteEntries[256];
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void createImpl() override;
|
virtual void createImpl() override;
|
||||||
|
@ -222,10 +222,6 @@ namespace DDraw
|
|||||||
{
|
{
|
||||||
DirectDrawPalette::waitForNextUpdate();
|
DirectDrawPalette::waitForNextUpdate();
|
||||||
}
|
}
|
||||||
if (lpDDPalette == PrimarySurface::s_palette)
|
|
||||||
{
|
|
||||||
return DD_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT result = SurfaceImpl::SetPalette(This, lpDDPalette);
|
HRESULT result = SurfaceImpl::SetPalette(This, lpDDPalette);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
|
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
#include <Windows.h>
|
|
||||||
|
|
||||||
#include "Common/Hook.h"
|
#include "Common/Hook.h"
|
||||||
#include "Common/Log.h"
|
#include "Common/Log.h"
|
||||||
#include "Common/ScopedCriticalSection.h"
|
#include "Common/ScopedCriticalSection.h"
|
||||||
@ -15,6 +11,8 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
Compat::CriticalSection g_cs;
|
Compat::CriticalSection g_cs;
|
||||||
|
PALETTEENTRY g_defaultPalette[256] = {};
|
||||||
|
PALETTEENTRY g_hardwarePalette[256] = {};
|
||||||
PALETTEENTRY g_systemPalette[256] = {};
|
PALETTEENTRY g_systemPalette[256] = {};
|
||||||
UINT g_systemPaletteUse = SYSPAL_STATIC;
|
UINT g_systemPaletteUse = SYSPAL_STATIC;
|
||||||
UINT g_systemPaletteFirstUnusedIndex = 10;
|
UINT g_systemPaletteFirstUnusedIndex = 10;
|
||||||
@ -51,33 +49,18 @@ namespace
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT fillSystemPalette(HDC dc)
|
void updateStaticSysPalEntries()
|
||||||
{
|
{
|
||||||
HPALETTE palette = reinterpret_cast<HPALETTE>(GetCurrentObject(dc, OBJ_PAL));
|
const UINT count = g_systemPaletteFirstNonReservedIndex;
|
||||||
if (!palette || GetStockObject(DEFAULT_PALETTE) == palette)
|
if (0 == count)
|
||||||
{
|
{
|
||||||
return 0;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memcpy(g_systemPalette, g_defaultPalette, count * sizeof(g_systemPalette[0]));
|
||||||
|
memcpy(&g_systemPalette[256 - count], &g_defaultPalette[256 - count], count * sizeof(g_systemPalette[0]));
|
||||||
|
Gdi::Palette::setHardwarePalette(g_systemPalette);
|
||||||
Gdi::VirtualScreen::updatePalette(g_systemPalette);
|
Gdi::VirtualScreen::updatePalette(g_systemPalette);
|
||||||
return count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI getSystemPaletteEntries(HDC hdc, UINT iStartIndex, UINT nEntries, LPPALETTEENTRY lppe)
|
UINT WINAPI getSystemPaletteEntries(HDC hdc, UINT iStartIndex, UINT nEntries, LPPALETTEENTRY lppe)
|
||||||
@ -117,7 +100,7 @@ namespace
|
|||||||
return LOG_RESULT(SYSPAL_ERROR);
|
return LOG_RESULT(SYSPAL_ERROR);
|
||||||
}
|
}
|
||||||
Compat::ScopedCriticalSection lock(g_cs);
|
Compat::ScopedCriticalSection lock(g_cs);
|
||||||
return g_systemPaletteUse;
|
return LOG_RESULT(g_systemPaletteUse);
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT WINAPI realizePalette(HDC hdc)
|
UINT WINAPI realizePalette(HDC hdc)
|
||||||
@ -126,11 +109,18 @@ namespace
|
|||||||
if (Gdi::isDisplayDc(hdc))
|
if (Gdi::isDisplayDc(hdc))
|
||||||
{
|
{
|
||||||
Compat::ScopedCriticalSection lock(g_cs);
|
Compat::ScopedCriticalSection lock(g_cs);
|
||||||
if (g_foregroundPaletteDcs.find(hdc) != g_foregroundPaletteDcs.end())
|
|
||||||
|
HPALETTE palette = reinterpret_cast<HPALETTE>(GetCurrentObject(hdc, OBJ_PAL));
|
||||||
|
if (!palette || GetStockObject(DEFAULT_PALETTE) == palette)
|
||||||
{
|
{
|
||||||
g_systemPaletteFirstUnusedIndex = g_systemPaletteFirstNonReservedIndex;
|
return 0;
|
||||||
}
|
}
|
||||||
return LOG_RESULT(fillSystemPalette(hdc));
|
|
||||||
|
PALETTEENTRY entries[256] = {};
|
||||||
|
UINT count = GetPaletteEntries(palette, 0, 256, entries);
|
||||||
|
Gdi::Palette::setSystemPalette(entries, count,
|
||||||
|
g_foregroundPaletteDcs.find(hdc) == g_foregroundPaletteDcs.end());
|
||||||
|
return LOG_RESULT(count);
|
||||||
}
|
}
|
||||||
return LOG_RESULT(CALL_ORIG_FUNC(RealizePalette)(hdc));
|
return LOG_RESULT(CALL_ORIG_FUNC(RealizePalette)(hdc));
|
||||||
}
|
}
|
||||||
@ -175,6 +165,11 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
Compat::ScopedCriticalSection lock(g_cs);
|
Compat::ScopedCriticalSection lock(g_cs);
|
||||||
|
if (uUsage == g_systemPaletteUse)
|
||||||
|
{
|
||||||
|
return LOG_RESULT(g_systemPaletteUse);
|
||||||
|
}
|
||||||
|
|
||||||
const UINT prevUsage = g_systemPaletteUse;
|
const UINT prevUsage = g_systemPaletteUse;
|
||||||
switch (uUsage)
|
switch (uUsage)
|
||||||
{
|
{
|
||||||
@ -198,6 +193,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
g_systemPaletteUse = uUsage;
|
g_systemPaletteUse = uUsage;
|
||||||
|
updateStaticSysPalEntries();
|
||||||
return LOG_RESULT(prevUsage);
|
return LOG_RESULT(prevUsage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -206,12 +202,30 @@ namespace Gdi
|
|||||||
{
|
{
|
||||||
namespace Palette
|
namespace Palette
|
||||||
{
|
{
|
||||||
|
PALETTEENTRY* getDefaultPalette()
|
||||||
|
{
|
||||||
|
return g_defaultPalette;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PALETTEENTRY> getHardwarePalette()
|
||||||
|
{
|
||||||
|
Compat::ScopedCriticalSection lock(g_cs);
|
||||||
|
return std::vector<PALETTEENTRY>(g_hardwarePalette, g_hardwarePalette + 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<PALETTEENTRY> getSystemPalette()
|
||||||
|
{
|
||||||
|
Compat::ScopedCriticalSection lock(g_cs);
|
||||||
|
return std::vector<PALETTEENTRY>(g_systemPalette, g_systemPalette + 256);
|
||||||
|
}
|
||||||
|
|
||||||
void installHooks()
|
void installHooks()
|
||||||
{
|
{
|
||||||
HPALETTE defaultPalette = reinterpret_cast<HPALETTE>(GetStockObject(DEFAULT_PALETTE));
|
HPALETTE defaultPalette = reinterpret_cast<HPALETTE>(GetStockObject(DEFAULT_PALETTE));
|
||||||
GetPaletteEntries(defaultPalette, 0, 10, g_systemPalette);
|
GetPaletteEntries(defaultPalette, 0, 10, g_defaultPalette);
|
||||||
GetPaletteEntries(defaultPalette, 10, 10, &g_systemPalette[246]);
|
GetPaletteEntries(defaultPalette, 10, 10, &g_defaultPalette[246]);
|
||||||
Gdi::VirtualScreen::updatePalette(g_systemPalette);
|
|
||||||
|
updateStaticSysPalEntries();
|
||||||
|
|
||||||
HOOK_FUNCTION(gdi32, GetSystemPaletteEntries, getSystemPaletteEntries);
|
HOOK_FUNCTION(gdi32, GetSystemPaletteEntries, getSystemPaletteEntries);
|
||||||
HOOK_FUNCTION(gdi32, GetSystemPaletteUse, getSystemPaletteUse);
|
HOOK_FUNCTION(gdi32, GetSystemPaletteUse, getSystemPaletteUse);
|
||||||
@ -220,5 +234,36 @@ namespace Gdi
|
|||||||
HOOK_FUNCTION(gdi32, SelectPalette, selectPalette);
|
HOOK_FUNCTION(gdi32, SelectPalette, selectPalette);
|
||||||
HOOK_FUNCTION(gdi32, SetSystemPaletteUse, setSystemPaletteUse);
|
HOOK_FUNCTION(gdi32, SetSystemPaletteUse, setSystemPaletteUse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setHardwarePalette(PALETTEENTRY* entries)
|
||||||
|
{
|
||||||
|
Compat::ScopedCriticalSection lock(g_cs);
|
||||||
|
std::memcpy(g_hardwarePalette, entries, sizeof(g_hardwarePalette));
|
||||||
|
}
|
||||||
|
|
||||||
|
void setSystemPalette(PALETTEENTRY* entries, DWORD count, bool forceBackground)
|
||||||
|
{
|
||||||
|
Compat::ScopedCriticalSection lock(g_cs);
|
||||||
|
if (!forceBackground)
|
||||||
|
{
|
||||||
|
g_systemPaletteFirstUnusedIndex = g_systemPaletteFirstNonReservedIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
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::Palette::setHardwarePalette(g_systemPalette);
|
||||||
|
Gdi::VirtualScreen::updatePalette(g_systemPalette);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
namespace Gdi
|
namespace Gdi
|
||||||
{
|
{
|
||||||
namespace Palette
|
namespace Palette
|
||||||
{
|
{
|
||||||
|
PALETTEENTRY* getDefaultPalette();
|
||||||
|
std::vector<PALETTEENTRY> getHardwarePalette();
|
||||||
|
std::vector<PALETTEENTRY> getSystemPalette();
|
||||||
void installHooks();
|
void installHooks();
|
||||||
|
void setHardwarePalette(PALETTEENTRY* entries);
|
||||||
|
void setSystemPalette(PALETTEENTRY* entries, DWORD count, bool forceBackground);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "D3dDdi/Device.h"
|
#include "D3dDdi/Device.h"
|
||||||
#include "D3dDdi/ScopedCriticalSection.h"
|
#include "D3dDdi/ScopedCriticalSection.h"
|
||||||
#include "DDraw/DirectDraw.h"
|
#include "DDraw/DirectDraw.h"
|
||||||
|
#include "DDraw/RealPrimarySurface.h"
|
||||||
#include "DDraw/ScopedThreadLock.h"
|
#include "DDraw/ScopedThreadLock.h"
|
||||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||||
#include "Gdi/Gdi.h"
|
#include "Gdi/Gdi.h"
|
||||||
@ -263,6 +264,8 @@ namespace Gdi
|
|||||||
SetDIBColorTable(dc, 0, 256, systemPalette);
|
SetDIBColorTable(dc, 0, 256, systemPalette);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DDraw::RealPrimarySurface::gdiUpdate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,9 +203,21 @@ namespace
|
|||||||
int WINAPI getDeviceCaps(HDC hdc, int nIndex)
|
int WINAPI getDeviceCaps(HDC hdc, int nIndex)
|
||||||
{
|
{
|
||||||
LOG_FUNC("GetDeviceCaps", hdc, nIndex);
|
LOG_FUNC("GetDeviceCaps", hdc, nIndex);
|
||||||
if (BITSPIXEL == nIndex && Gdi::isDisplayDc(hdc))
|
switch (nIndex)
|
||||||
{
|
{
|
||||||
return LOG_RESULT(g_currentBpp);
|
case BITSPIXEL:
|
||||||
|
if (Gdi::isDisplayDc(hdc))
|
||||||
|
{
|
||||||
|
return LOG_RESULT(g_currentBpp);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RASTERCAPS:
|
||||||
|
if (8 == g_currentBpp && Gdi::isDisplayDc(hdc))
|
||||||
|
{
|
||||||
|
return LOG_RESULT(CALL_ORIG_FUNC(GetDeviceCaps)(hdc, nIndex) | RC_PALETTE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return LOG_RESULT(CALL_ORIG_FUNC(GetDeviceCaps)(hdc, nIndex));
|
return LOG_RESULT(CALL_ORIG_FUNC(GetDeviceCaps)(hdc, nIndex));
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user