mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added AlignSysMemSurfaces setting
This commit is contained in:
parent
641df63f14
commit
fa99142587
@ -2,6 +2,7 @@
|
||||
|
||||
namespace Config
|
||||
{
|
||||
Settings::AlignSysMemSurfaces alignSysMemSurfaces;
|
||||
Settings::AlternatePixelCenter alternatePixelCenter;
|
||||
Settings::AltTabFix altTabFix;
|
||||
Settings::Antialiasing antialiasing;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/Settings/AlignSysMemSurfaces.h>
|
||||
#include <Config/Settings/AlternatePixelCenter.h>
|
||||
#include <Config/Settings/AltTabFix.h>
|
||||
#include <Config/Settings/Antialiasing.h>
|
||||
@ -27,6 +28,7 @@
|
||||
|
||||
namespace Config
|
||||
{
|
||||
extern Settings::AlignSysMemSurfaces alignSysMemSurfaces;
|
||||
extern Settings::AlternatePixelCenter alternatePixelCenter;
|
||||
extern Settings::AltTabFix altTabFix;
|
||||
extern Settings::Antialiasing antialiasing;
|
||||
|
18
DDrawCompat/Config/Settings/AlignSysMemSurfaces.h
Normal file
18
DDrawCompat/Config/Settings/AlignSysMemSurfaces.h
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/MappedSetting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
class AlignSysMemSurfaces : public MappedSetting<UINT>
|
||||
{
|
||||
public:
|
||||
AlignSysMemSurfaces()
|
||||
: MappedSetting("AlignSysMemSurfaces", "on", { {"off", 8}, {"on", 0} })
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -566,6 +566,7 @@ namespace D3dDdi
|
||||
return;
|
||||
}
|
||||
|
||||
const auto ALIGNMENT = DDraw::Surface::ALIGNMENT;
|
||||
std::vector<D3DDDI_SURFACEINFO> surfaceInfo(m_fixedData.SurfCount);
|
||||
for (UINT i = 0; i < m_fixedData.SurfCount; ++i)
|
||||
{
|
||||
@ -575,21 +576,16 @@ namespace D3dDdi
|
||||
if (i != 0)
|
||||
{
|
||||
std::uintptr_t offset = reinterpret_cast<std::uintptr_t>(surfaceInfo[i - 1].pSysMem) +
|
||||
((surfaceInfo[i - 1].SysMemPitch * surfaceInfo[i - 1].Height + 15) & ~15);
|
||||
((surfaceInfo[i - 1].SysMemPitch * surfaceInfo[i - 1].Height + ALIGNMENT - 1) / ALIGNMENT * ALIGNMENT);
|
||||
surfaceInfo[i].pSysMem = reinterpret_cast<void*>(offset);
|
||||
}
|
||||
}
|
||||
|
||||
std::uintptr_t bufferSize = reinterpret_cast<std::uintptr_t>(surfaceInfo.back().pSysMem) +
|
||||
surfaceInfo.back().SysMemPitch * surfaceInfo.back().Height + 8;
|
||||
surfaceInfo.back().SysMemPitch * surfaceInfo.back().Height + ALIGNMENT;
|
||||
m_lockBuffer.reset(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bufferSize));
|
||||
|
||||
BYTE* bufferStart = static_cast<BYTE*>(m_lockBuffer.get());
|
||||
if (0 == reinterpret_cast<std::uintptr_t>(bufferStart) % 16)
|
||||
{
|
||||
bufferStart += 8;
|
||||
}
|
||||
|
||||
BYTE* bufferStart = static_cast<BYTE*>(DDraw::Surface::alignBuffer(m_lockBuffer.get()));
|
||||
for (UINT i = 0; i < m_fixedData.SurfCount; ++i)
|
||||
{
|
||||
surfaceInfo[i].pSysMem = bufferStart + reinterpret_cast<uintptr_t>(surfaceInfo[i].pSysMem);
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <DDraw/DirectDrawSurface.h>
|
||||
#include <DDraw/ScopedThreadLock.h>
|
||||
@ -69,6 +71,11 @@ namespace
|
||||
SET_COMPAT_METHOD(SetClipper);
|
||||
SET_COMPAT_METHOD(SetPalette);
|
||||
SET_COMPAT_METHOD(Unlock);
|
||||
|
||||
if constexpr (!std::is_same_v<Vtable, IDirectDrawSurfaceVtbl> && !std::is_same_v<Vtable, IDirectDrawSurface2Vtbl>)
|
||||
{
|
||||
SET_COMPAT_METHOD(SetSurfaceDesc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <initguid.h>
|
||||
|
||||
#include <Common/CompatPtr.h>
|
||||
#include <Config/Config.h>
|
||||
#include <DDraw/DirectDrawClipper.h>
|
||||
#include <DDraw/DirectDrawSurface.h>
|
||||
#include <DDraw/Surfaces/Surface.h>
|
||||
@ -11,6 +12,14 @@
|
||||
DEFINE_GUID(IID_CompatSurfacePrivateData,
|
||||
0xc62d8849, 0xdfac, 0x4454, 0xa1, 0xe8, 0xda, 0x67, 0x44, 0x64, 0x26, 0xba);
|
||||
|
||||
namespace
|
||||
{
|
||||
void heapFree(void* p)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, p);
|
||||
}
|
||||
}
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
HRESULT STDMETHODCALLTYPE Surface::QueryInterface(REFIID, LPVOID*)
|
||||
@ -37,6 +46,7 @@ namespace DDraw
|
||||
: m_origCaps(origCaps)
|
||||
, m_refCount(0)
|
||||
, m_sizeOverride{}
|
||||
, m_sysMemBuffer(nullptr, &heapFree)
|
||||
{
|
||||
}
|
||||
|
||||
@ -45,6 +55,19 @@ namespace DDraw
|
||||
DirectDrawClipper::setClipper(*this, nullptr);
|
||||
}
|
||||
|
||||
void* Surface::alignBuffer(void* buffer)
|
||||
{
|
||||
auto p = static_cast<BYTE*>(buffer);
|
||||
const DWORD alignmentOffset = Config::alignSysMemSurfaces.get();
|
||||
const DWORD mod = reinterpret_cast<DWORD>(p) % ALIGNMENT;
|
||||
p = p - mod + alignmentOffset;
|
||||
if (mod > alignmentOffset)
|
||||
{
|
||||
p += ALIGNMENT;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
void Surface::attach(CompatRef<IDirectDrawSurface7> dds, std::unique_ptr<Surface> privateData)
|
||||
{
|
||||
if (SUCCEEDED(dds->SetPrivateData(&dds, IID_CompatSurfacePrivateData,
|
||||
@ -82,6 +105,10 @@ namespace DDraw
|
||||
attach(*attachedSurfaces[i], std::make_unique<Surface>(privateData->m_origCaps));
|
||||
}
|
||||
}
|
||||
else if ((desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) && !(desc.dwFlags & DDSD_LPSURFACE))
|
||||
{
|
||||
privateData->fixAlignment(*surface7);
|
||||
}
|
||||
|
||||
attach(*surface7, std::move(privateData));
|
||||
|
||||
@ -106,6 +133,39 @@ namespace DDraw
|
||||
m_impl7.reset(new SurfaceImpl<IDirectDrawSurface7>(this));
|
||||
}
|
||||
|
||||
void Surface::fixAlignment(CompatRef<IDirectDrawSurface7> surface)
|
||||
{
|
||||
DDSURFACEDESC2 desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
if (FAILED(surface->Lock(&surface, nullptr, &desc, DDLOCK_WAIT, nullptr)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
surface->Unlock(&surface, nullptr);
|
||||
|
||||
const DWORD alignmentOffset = Config::alignSysMemSurfaces.get();
|
||||
const DWORD size = desc.lPitch * desc.dwHeight;
|
||||
if (0 == size || alignmentOffset == reinterpret_cast<DWORD>(desc.lpSurface) % ALIGNMENT)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_sysMemBuffer.reset(HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size + ALIGNMENT));
|
||||
if (!m_sysMemBuffer)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_LPSURFACE;
|
||||
desc.lpSurface = alignBuffer(m_sysMemBuffer.get());
|
||||
if (FAILED(surface->SetSurfaceDesc(&surface, &desc, 0)))
|
||||
{
|
||||
m_sysMemBuffer.reset();
|
||||
}
|
||||
}
|
||||
|
||||
template <>
|
||||
SurfaceImpl<IDirectDrawSurface>* Surface::getImpl<IDirectDrawSurface>() const { return m_impl.get(); }
|
||||
template <>
|
||||
|
@ -16,6 +16,8 @@ namespace DDraw
|
||||
class Surface
|
||||
{
|
||||
public:
|
||||
static const DWORD ALIGNMENT = 32;
|
||||
|
||||
virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, LPVOID*);
|
||||
virtual ULONG STDMETHODCALLTYPE AddRef();
|
||||
virtual ULONG STDMETHODCALLTYPE Release();
|
||||
@ -23,6 +25,8 @@ namespace DDraw
|
||||
Surface(DWORD origCaps);
|
||||
virtual ~Surface();
|
||||
|
||||
static void* alignBuffer(void* buffer);
|
||||
|
||||
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
|
||||
static HRESULT create(
|
||||
CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface, std::unique_ptr<Surface> privateData);
|
||||
@ -44,6 +48,8 @@ namespace DDraw
|
||||
|
||||
virtual void createImpl();
|
||||
|
||||
void fixAlignment(CompatRef<IDirectDrawSurface7> surface);
|
||||
|
||||
std::unique_ptr<SurfaceImpl<IDirectDrawSurface>> m_impl;
|
||||
std::unique_ptr<SurfaceImpl<IDirectDrawSurface2>> m_impl2;
|
||||
std::unique_ptr<SurfaceImpl<IDirectDrawSurface3>> m_impl3;
|
||||
@ -59,5 +65,6 @@ namespace DDraw
|
||||
DWORD m_origCaps;
|
||||
DWORD m_refCount;
|
||||
SIZE m_sizeOverride;
|
||||
std::unique_ptr<void, void(*)(void*)> m_sysMemBuffer;
|
||||
};
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include <set>
|
||||
#include <type_traits>
|
||||
|
||||
#include <d3d.h>
|
||||
#include <d3dumddi.h>
|
||||
@ -255,6 +256,24 @@ namespace DDraw
|
||||
return getOrigVtable(This).SetPalette(This, lpDDPalette);
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT SurfaceImpl<TSurface>::SetSurfaceDesc(TSurface* This, TSurfaceDesc* lpddsd, DWORD dwFlags)
|
||||
{
|
||||
if constexpr (!std::is_same_v<TSurface, IDirectDrawSurface> && !std::is_same_v<TSurface, IDirectDrawSurface2>)
|
||||
{
|
||||
HRESULT result = getOrigVtable(This).SetSurfaceDesc(This, lpddsd, dwFlags);
|
||||
if (SUCCEEDED(result) && (lpddsd->dwFlags & DDSD_LPSURFACE))
|
||||
{
|
||||
m_data->m_sysMemBuffer.reset();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DD_OK;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HRESULT SurfaceImpl<TSurface>::Unlock(TSurface* This, TUnlockParam lpRect)
|
||||
{
|
||||
|
@ -40,6 +40,7 @@ namespace DDraw
|
||||
virtual HRESULT Restore(TSurface* This);
|
||||
virtual HRESULT SetClipper(TSurface* This, LPDIRECTDRAWCLIPPER lpDDClipper);
|
||||
virtual HRESULT SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette);
|
||||
virtual HRESULT SetSurfaceDesc(TSurface* This, TSurfaceDesc* lpddsd, DWORD dwFlags);
|
||||
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect);
|
||||
|
||||
protected:
|
||||
|
@ -158,6 +158,7 @@
|
||||
<ClInclude Include="Config\MappedSetting.h" />
|
||||
<ClInclude Include="Config\Parser.h" />
|
||||
<ClInclude Include="Config\Setting.h" />
|
||||
<ClInclude Include="Config\Settings\AlignSysMemSurfaces.h" />
|
||||
<ClInclude Include="Config\Settings\AlternatePixelCenter.h" />
|
||||
<ClInclude Include="Config\Settings\AltTabFix.h" />
|
||||
<ClInclude Include="Config\Settings\Antialiasing.h" />
|
||||
|
@ -570,6 +570,9 @@
|
||||
<ClInclude Include="Overlay\ButtonControl.h">
|
||||
<Filter>Header Files\Overlay</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Settings\AlignSysMemSurfaces.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
|
@ -90,7 +90,7 @@ namespace
|
||||
}
|
||||
|
||||
void* bits = nullptr;
|
||||
return CreateDIBSection(nullptr, &bmi, DIB_RGB_COLORS, &bits, section, 8);
|
||||
return CreateDIBSection(nullptr, &bmi, DIB_RGB_COLORS, &bits, section, Config::alignSysMemSurfaces.get());
|
||||
}
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ namespace Gdi
|
||||
desc.ddpfPixelFormat = DDraw::DirectDraw::getRgbPixelFormat(g_bpp);
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
desc.lPitch = g_pitch;
|
||||
desc.lpSurface = static_cast<unsigned char*>(g_surfaceView) + 8 +
|
||||
desc.lpSurface = static_cast<unsigned char*>(g_surfaceView) + Config::alignSysMemSurfaces.get() +
|
||||
(rect.top - g_bounds.top) * g_pitch +
|
||||
(rect.left - g_bounds.left) * g_bpp / 8;
|
||||
return desc;
|
||||
|
Loading…
x
Reference in New Issue
Block a user