mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added KeepVideoMemory setting
This commit is contained in:
parent
01be996c36
commit
0ee03e4553
@ -3,6 +3,7 @@
|
||||
namespace Config
|
||||
{
|
||||
Settings::AlternatePixelCenter alternatePixelCenter;
|
||||
Settings::AltTabFix altTabFix;
|
||||
Settings::Antialiasing antialiasing;
|
||||
Settings::ConfigHotKey configHotKey;
|
||||
Settings::CpuAffinity cpuAffinity;
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/Settings/AlternatePixelCenter.h>
|
||||
#include <Config/Settings/AltTabFix.h>
|
||||
#include <Config/Settings/Antialiasing.h>
|
||||
#include <Config/Settings/ConfigHotKey.h>
|
||||
#include <Config/Settings/CpuAffinity.h>
|
||||
@ -23,6 +24,7 @@
|
||||
namespace Config
|
||||
{
|
||||
extern Settings::AlternatePixelCenter alternatePixelCenter;
|
||||
extern Settings::AltTabFix altTabFix;
|
||||
extern Settings::Antialiasing antialiasing;
|
||||
extern Settings::ConfigHotKey configHotKey;
|
||||
extern Settings::CpuAffinity cpuAffinity;
|
||||
|
24
DDrawCompat/Config/Settings/AltTabFix.h
Normal file
24
DDrawCompat/Config/Settings/AltTabFix.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/EnumSetting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
class AltTabFix : public MappedSetting<UINT>
|
||||
{
|
||||
public:
|
||||
static const UINT OFF = 0;
|
||||
static const UINT KEEPVIDMEM = 1;
|
||||
|
||||
AltTabFix()
|
||||
: MappedSetting("AltTabFix", "off", {
|
||||
{"off", OFF},
|
||||
{"keepvidmem", KEEPVIDMEM}
|
||||
})
|
||||
{
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -1,19 +1,26 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
|
||||
#include <Common/Comparison.h>
|
||||
#include <Common/CompatPtr.h>
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <Config/Config.h>
|
||||
#include <D3dDdi/Adapter.h>
|
||||
#include <D3dDdi/Device.h>
|
||||
#include <D3dDdi/KernelModeThunks.h>
|
||||
#include <D3dDdi/Resource.h>
|
||||
#include <DDraw/DirectDraw.h>
|
||||
#include <DDraw/DirectDrawSurface.h>
|
||||
#include <DDraw/RealPrimarySurface.h>
|
||||
#include <DDraw/ScopedThreadLock.h>
|
||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||
#include <DDraw/Surfaces/TagSurface.h>
|
||||
#include <DDraw/Visitors/DirectDrawVtblVisitor.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
const DWORD SURFACE_LOST_FLAG = 0x10000000;
|
||||
|
||||
template <typename TDirectDraw, typename TSurfaceDesc, typename TSurface>
|
||||
HRESULT STDMETHODCALLTYPE CreateSurface(
|
||||
@ -70,6 +77,17 @@ namespace
|
||||
return getOrigVtable(This).RestoreAllSurfaces(This);
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE SetCooperativeLevel(TDirectDraw* This, HWND hWnd, DWORD dwFlags)
|
||||
{
|
||||
HRESULT result = getOrigVtable(This).SetCooperativeLevel(This, hWnd, dwFlags);
|
||||
if (SUCCEEDED(result))
|
||||
{
|
||||
DDraw::TagSurface::create(*CompatPtr<IDirectDraw>::from(This));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HRESULT STDMETHODCALLTYPE WaitForVerticalBlank(TDirectDraw* This, DWORD dwFlags, HANDLE hEvent)
|
||||
{
|
||||
@ -78,12 +96,44 @@ namespace
|
||||
return getOrigVtable(This).WaitForVerticalBlank(This, dwFlags, hEvent);
|
||||
}
|
||||
|
||||
HRESULT WINAPI restoreSurfaceLostFlag(
|
||||
LPDIRECTDRAWSURFACE7 lpDDSurface, LPDDSURFACEDESC2 /*lpDDSurfaceDesc*/, LPVOID lpContext)
|
||||
{
|
||||
auto& surfacesToRestore = *static_cast<std::set<void*>*>(lpContext);
|
||||
auto it = surfacesToRestore.find(DDraw::DirectDrawSurface::getSurfaceObject(*lpDDSurface));
|
||||
if (it != surfacesToRestore.end())
|
||||
{
|
||||
DWORD& flags = DDraw::DirectDrawSurface::getFlags(*lpDDSurface);
|
||||
flags &= ~SURFACE_LOST_FLAG;
|
||||
surfacesToRestore.erase(it);
|
||||
}
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
HRESULT WINAPI setSurfaceLostFlag(
|
||||
LPDIRECTDRAWSURFACE7 lpDDSurface, LPDDSURFACEDESC2 /*lpDDSurfaceDesc*/, LPVOID lpContext)
|
||||
{
|
||||
auto& surfacesToRestore = *static_cast<std::set<void*>*>(lpContext);
|
||||
DWORD& flags = DDraw::DirectDrawSurface::getFlags(*lpDDSurface);
|
||||
if (!(flags & SURFACE_LOST_FLAG))
|
||||
{
|
||||
auto resource = D3dDdi::Device::findResource(DDraw::DirectDrawSurface::getDriverResourceHandle(*lpDDSurface));
|
||||
if (resource && !resource->getOrigDesc().Flags.MatchGdiPrimary)
|
||||
{
|
||||
flags |= SURFACE_LOST_FLAG;
|
||||
surfacesToRestore.insert(DDraw::DirectDrawSurface::getSurfaceObject(*lpDDSurface));
|
||||
}
|
||||
}
|
||||
return DDENUMRET_OK;
|
||||
}
|
||||
|
||||
template <typename Vtable>
|
||||
constexpr void setCompatVtable(Vtable& vtable)
|
||||
{
|
||||
vtable.CreateSurface = &CreateSurface;
|
||||
vtable.FlipToGDISurface = &FlipToGDISurface;
|
||||
vtable.GetGDISurface = &GetGDISurface;
|
||||
vtable.SetCooperativeLevel = &SetCooperativeLevel;
|
||||
vtable.WaitForVerticalBlank = &WaitForVerticalBlank;
|
||||
|
||||
if constexpr (std::is_same_v<Vtable, IDirectDraw4Vtbl> || std::is_same_v<Vtable, IDirectDraw7Vtbl>)
|
||||
@ -142,6 +192,42 @@ namespace DDraw
|
||||
return pf;
|
||||
}
|
||||
|
||||
LRESULT handleActivateApp(bool isActivated, std::function<LRESULT()> callOrigWndProc)
|
||||
{
|
||||
LOG_FUNC("handleActivateApp", isActivated, callOrigWndProc);
|
||||
if (Config::Settings::AltTabFix::KEEPVIDMEM != Config::altTabFix.get())
|
||||
{
|
||||
return LOG_RESULT(callOrigWndProc());
|
||||
}
|
||||
|
||||
DDraw::ScopedThreadLock lock;
|
||||
std::set<void*> surfacesToRestore;
|
||||
TagSurface::forEachDirectDraw([&](CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
dd->EnumSurfaces(&dd, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, nullptr,
|
||||
&surfacesToRestore, &setSurfaceLostFlag);
|
||||
});
|
||||
|
||||
LRESULT result = callOrigWndProc();
|
||||
|
||||
TagSurface::forEachDirectDraw([&](CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
dd->EnumSurfaces(&dd, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, nullptr,
|
||||
&surfacesToRestore, &restoreSurfaceLostFlag);
|
||||
});
|
||||
|
||||
if (isActivated)
|
||||
{
|
||||
auto realPrimary(DDraw::RealPrimarySurface::getSurface());
|
||||
if (realPrimary)
|
||||
{
|
||||
realPrimary->Restore(realPrimary);
|
||||
}
|
||||
}
|
||||
|
||||
return LOG_RESULT(result);
|
||||
}
|
||||
|
||||
void onCreate(GUID* guid, CompatRef<IDirectDraw7> dd)
|
||||
{
|
||||
static std::map<LUID, CompatWeakPtr<IDirectDraw7>> repositories;
|
||||
@ -155,7 +241,7 @@ namespace DDraw
|
||||
{
|
||||
return;
|
||||
}
|
||||
repo->SetCooperativeLevel(repo, nullptr, DDSCL_NORMAL);
|
||||
repo.get()->lpVtbl->SetCooperativeLevel(repo, nullptr, DDSCL_NORMAL);
|
||||
it = repositories.insert({ adapterInfo.luid, repo }).first;
|
||||
repo.detach();
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <ddraw.h>
|
||||
|
||||
#include <Common/CompatPtr.h>
|
||||
@ -11,9 +13,16 @@ namespace DDraw
|
||||
{
|
||||
DDSURFACEDESC2 getDisplayMode(CompatRef<IDirectDraw7> dd);
|
||||
DDPIXELFORMAT getRgbPixelFormat(DWORD bpp);
|
||||
LRESULT handleActivateApp(bool isActivated, std::function<LRESULT()> callOrigWndProc);
|
||||
void onCreate(GUID* guid, CompatRef<IDirectDraw7> dd);
|
||||
void suppressEmulatedDirectDraw(GUID*& guid);
|
||||
|
||||
template <typename TDirectDraw>
|
||||
void* getDdObject(TDirectDraw& dd)
|
||||
{
|
||||
return reinterpret_cast<void**>(&dd)[1];
|
||||
}
|
||||
|
||||
template <typename TDirectDraw>
|
||||
HWND* getDeviceWindowPtr(TDirectDraw& dd)
|
||||
{
|
||||
|
@ -13,6 +13,18 @@ namespace DDraw
|
||||
{
|
||||
std::vector<CompatPtr<IDirectDrawSurface7>> getAllAttachedSurfaces(CompatRef<IDirectDrawSurface7> surface);
|
||||
|
||||
template <typename TSurface>
|
||||
void* getSurfaceObject(TSurface& surface)
|
||||
{
|
||||
return reinterpret_cast<void**>(&surface)[1];
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
DWORD& getFlags(TSurface& surface)
|
||||
{
|
||||
return reinterpret_cast<DWORD**>(&surface)[1][7];
|
||||
}
|
||||
|
||||
template <typename TSurface>
|
||||
HANDLE getRuntimeResourceHandle(TSurface& surface)
|
||||
{
|
||||
|
56
DDrawCompat/DDraw/Surfaces/TagSurface.cpp
Normal file
56
DDrawCompat/DDraw/Surfaces/TagSurface.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include <map>
|
||||
|
||||
#include <DDraw/DirectDraw.h>
|
||||
#include <DDraw/Surfaces/TagSurface.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
std::map<void*, DDraw::TagSurface*> g_ddObjects;
|
||||
}
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
HRESULT TagSurface::create(CompatRef<IDirectDraw> dd)
|
||||
{
|
||||
auto ddObject = DDraw::DirectDraw::getDdObject(dd.get());
|
||||
if (g_ddObjects.find(ddObject) != g_ddObjects.end())
|
||||
{
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
DDSURFACEDESC desc = {};
|
||||
desc.dwSize = sizeof(desc);
|
||||
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
|
||||
desc.dwWidth = 1;
|
||||
desc.dwHeight = 1;
|
||||
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
|
||||
|
||||
auto privateData(std::make_unique<TagSurface>(desc.ddsCaps.dwCaps, ddObject));
|
||||
g_ddObjects[ddObject] = privateData.get();
|
||||
|
||||
IDirectDrawSurface* surface = nullptr;
|
||||
return Surface::create(dd, desc, surface, std::move(privateData));
|
||||
}
|
||||
|
||||
void TagSurface::forEachDirectDraw(std::function<void(CompatRef<IDirectDraw7>)> callback)
|
||||
{
|
||||
struct DirectDrawInterface
|
||||
{
|
||||
const void* vtable;
|
||||
void* ddObject;
|
||||
DirectDrawInterface* next;
|
||||
DWORD refCount;
|
||||
};
|
||||
|
||||
for (auto ddObj : g_ddObjects)
|
||||
{
|
||||
DirectDrawInterface intf = { &CompatVtable<IDirectDraw7Vtbl>::s_origVtable, ddObj.first, nullptr, 1 };
|
||||
callback(CompatRef<IDirectDraw7>(reinterpret_cast<IDirectDraw7&>(intf)));
|
||||
}
|
||||
}
|
||||
|
||||
TagSurface::~TagSurface()
|
||||
{
|
||||
g_ddObjects.erase(m_ddObject);
|
||||
}
|
||||
}
|
23
DDrawCompat/DDraw/Surfaces/TagSurface.h
Normal file
23
DDrawCompat/DDraw/Surfaces/TagSurface.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <ddraw.h>
|
||||
#include <functional>
|
||||
|
||||
#include <Common/CompatRef.h>
|
||||
#include <DDraw/Surfaces/Surface.h>
|
||||
|
||||
namespace DDraw
|
||||
{
|
||||
class TagSurface : public Surface
|
||||
{
|
||||
public:
|
||||
TagSurface(DWORD origCaps, void* ddObject) : Surface(origCaps), m_ddObject(ddObject) {}
|
||||
virtual ~TagSurface() override;
|
||||
|
||||
static HRESULT create(CompatRef<IDirectDraw> dd);
|
||||
static void forEachDirectDraw(std::function<void(CompatRef<IDirectDraw7>)> callback);
|
||||
|
||||
private:
|
||||
void* m_ddObject;
|
||||
};
|
||||
}
|
@ -218,6 +218,7 @@
|
||||
<ClInclude Include="Config\Parser.h" />
|
||||
<ClInclude Include="Config\Setting.h" />
|
||||
<ClInclude Include="Config\Settings\AlternatePixelCenter.h" />
|
||||
<ClInclude Include="Config\Settings\AltTabFix.h" />
|
||||
<ClInclude Include="Config\Settings\Antialiasing.h" />
|
||||
<ClInclude Include="Config\Settings\ConfigHotKey.h" />
|
||||
<ClInclude Include="Config\Settings\CpuAffinity.h" />
|
||||
@ -277,6 +278,7 @@
|
||||
<ClInclude Include="DDraw\Surfaces\PrimarySurfaceImpl.h" />
|
||||
<ClInclude Include="DDraw\Surfaces\Surface.h" />
|
||||
<ClInclude Include="DDraw\Surfaces\SurfaceImpl.h" />
|
||||
<ClInclude Include="DDraw\Surfaces\TagSurface.h" />
|
||||
<ClInclude Include="DDraw\Types.h" />
|
||||
<ClInclude Include="DDraw\IReleaseNotifier.h" />
|
||||
<ClInclude Include="DDraw\RealPrimarySurface.h" />
|
||||
@ -399,6 +401,7 @@
|
||||
<ClCompile Include="DDraw\Surfaces\PrimarySurfaceImpl.cpp" />
|
||||
<ClCompile Include="DDraw\Surfaces\Surface.cpp" />
|
||||
<ClCompile Include="DDraw\Surfaces\SurfaceImpl.cpp" />
|
||||
<ClCompile Include="DDraw\Surfaces\TagSurface.cpp" />
|
||||
<ClCompile Include="Direct3d\Direct3d.cpp" />
|
||||
<ClCompile Include="Direct3d\Direct3dDevice.cpp" />
|
||||
<ClCompile Include="Direct3d\Direct3dExecuteBuffer.cpp" />
|
||||
|
@ -546,6 +546,12 @@
|
||||
<ClInclude Include="Config\Settings\VSync.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="DDraw\Surfaces\TagSurface.h">
|
||||
<Filter>Header Files\DDraw\Surfaces</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Settings\AltTabFix.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -863,6 +869,9 @@
|
||||
<ClCompile Include="Config\Settings\VSync.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="DDraw\Surfaces\TagSurface.cpp">
|
||||
<Filter>Source Files\DDraw\Surfaces</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="DDrawCompat.rc">
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <Common/Log.h>
|
||||
#include <Common/ScopedSrwLock.h>
|
||||
#include <Dll/Dll.h>
|
||||
#include <DDraw/DirectDraw.h>
|
||||
#include <DDraw/RealPrimarySurface.h>
|
||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||
#include <Gdi/CompatDc.h>
|
||||
@ -105,7 +106,17 @@ namespace
|
||||
break;
|
||||
}
|
||||
|
||||
LRESULT result = callWindowProc(wndProc, hwnd, uMsg, wParam, lParam);
|
||||
LRESULT result = 0;
|
||||
if (WM_ACTIVATEAPP == uMsg && Dll::g_origDDrawModule == Compat::getModuleHandleFromAddress(
|
||||
reinterpret_cast<void*>(GetWindowLongA(hwnd, GWL_WNDPROC))))
|
||||
{
|
||||
result = DDraw::DirectDraw::handleActivateApp(wParam, [=]() {
|
||||
return callWindowProc(wndProc, hwnd, uMsg, wParam, lParam); });
|
||||
}
|
||||
else
|
||||
{
|
||||
result = callWindowProc(wndProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
switch (uMsg)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user