1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Fixed handleActivateApp not enumerating some surfaces

This commit is contained in:
narzoul 2022-06-25 14:16:01 +02:00
parent 8fc97386b6
commit 18360643f5
7 changed files with 33 additions and 64 deletions

View File

@ -56,7 +56,7 @@ namespace D3dDdi
} }
s_inCreateSurface = true; s_inCreateSurface = true;
HRESULT result = dd->CreateSurface(dd, &desc, &surface.getRef(), nullptr); HRESULT result = dd.get()->lpVtbl->CreateSurface(dd, &desc, &surface.getRef(), nullptr);
s_inCreateSurface = false; s_inCreateSurface = false;
if (FAILED(result)) if (FAILED(result))
{ {

View File

@ -105,37 +105,6 @@ namespace
return getOrigVtable(This).WaitForVerticalBlank(This, dwFlags, hEvent); return getOrigVtable(This).WaitForVerticalBlank(This, dwFlags, hEvent);
} }
HRESULT WINAPI restoreSurfaceLostFlag(
LPDIRECTDRAWSURFACE7 lpDDSurface, LPDDSURFACEDESC2 /*lpDDSurfaceDesc*/, LPVOID lpContext)
{
auto& surfacesToRestore = *static_cast<std::set<DDRAWI_DDRAWSURFACE_LCL*>*>(lpContext);
auto lcl = DDraw::DirectDrawSurface::getInt(*lpDDSurface).lpLcl;
auto it = surfacesToRestore.find(lcl);
if (it != surfacesToRestore.end())
{
lcl->dwFlags &= ~DDRAWISURF_INVALID;
surfacesToRestore.erase(it);
}
return DDENUMRET_OK;
}
HRESULT WINAPI setSurfaceLostFlag(
LPDIRECTDRAWSURFACE7 lpDDSurface, LPDDSURFACEDESC2 /*lpDDSurfaceDesc*/, LPVOID lpContext)
{
auto& surfacesToRestore = *static_cast<std::set<void*>*>(lpContext);
auto lcl = DDraw::DirectDrawSurface::getInt(*lpDDSurface).lpLcl;
if (!(lcl->dwFlags & DDRAWISURF_INVALID))
{
auto resource = D3dDdi::Device::findResource(DDraw::DirectDrawSurface::getDriverResourceHandle(*lpDDSurface));
if (resource && !resource->getOrigDesc().Flags.MatchGdiPrimary)
{
lcl->dwFlags |= DDRAWISURF_INVALID;
surfacesToRestore.insert(lcl);
}
}
return DDENUMRET_OK;
}
template <typename Vtable> template <typename Vtable>
constexpr void setCompatVtable(Vtable& vtable) constexpr void setCompatVtable(Vtable& vtable)
{ {
@ -211,18 +180,27 @@ namespace DDraw
DDraw::ScopedThreadLock lock; DDraw::ScopedThreadLock lock;
std::set<DDRAWI_DDRAWSURFACE_LCL*> surfacesToRestore; std::set<DDRAWI_DDRAWSURFACE_LCL*> surfacesToRestore;
TagSurface::forEachDirectDraw([&](CompatRef<IDirectDraw7> dd) DDraw::Surface::enumSurfaces([&](const Surface& surface)
{ {
dd->EnumSurfaces(&dd, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, nullptr, auto lcl = DDraw::DirectDrawSurface::getInt(*surface.getDDS()).lpLcl;
&surfacesToRestore, &setSurfaceLostFlag); if (!(lcl->dwFlags & DDRAWISURF_INVALID))
{
lcl->dwFlags |= DDRAWISURF_INVALID;
surfacesToRestore.insert(lcl);
}
}); });
LRESULT result = callOrigWndProc(); LRESULT result = callOrigWndProc();
TagSurface::forEachDirectDraw([&](CompatRef<IDirectDraw7> dd) DDraw::Surface::enumSurfaces([&](const Surface& surface)
{ {
dd->EnumSurfaces(&dd, DDENUMSURFACES_DOESEXIST | DDENUMSURFACES_ALL, nullptr, auto lcl = DDraw::DirectDrawSurface::getInt(*surface.getDDS()).lpLcl;
&surfacesToRestore, &restoreSurfaceLostFlag); auto it = surfacesToRestore.find(lcl);
if (it != surfacesToRestore.end())
{
lcl->dwFlags &= ~DDRAWISURF_INVALID;
surfacesToRestore.erase(it);
}
}); });
if (isActivated) if (isActivated)

View File

@ -1,3 +1,5 @@
#include <set>
#include <initguid.h> #include <initguid.h>
#include <Common/CompatPtr.h> #include <Common/CompatPtr.h>
@ -14,6 +16,8 @@ DEFINE_GUID(IID_CompatSurfacePrivateData,
namespace namespace
{ {
std::set<DDraw::Surface*> g_surfaces;
void heapFree(void* p) void heapFree(void* p)
{ {
HeapFree(GetProcessHeap(), 0, p); HeapFree(GetProcessHeap(), 0, p);
@ -48,11 +52,13 @@ namespace DDraw
, m_sizeOverride{} , m_sizeOverride{}
, m_sysMemBuffer(nullptr, &heapFree) , m_sysMemBuffer(nullptr, &heapFree)
{ {
g_surfaces.insert(this);
} }
Surface::~Surface() Surface::~Surface()
{ {
DirectDrawClipper::setClipper(*this, nullptr); DirectDrawClipper::setClipper(*this, nullptr);
g_surfaces.erase(this);
} }
void* Surface::alignBuffer(void* buffer) void* Surface::alignBuffer(void* buffer)
@ -133,6 +139,14 @@ namespace DDraw
m_impl7.reset(new SurfaceImpl<IDirectDrawSurface7>(this)); m_impl7.reset(new SurfaceImpl<IDirectDrawSurface7>(this));
} }
void Surface::enumSurfaces(const std::function<void(Surface&)>& callback)
{
for (auto surface : g_surfaces)
{
callback(*surface);
}
}
void Surface::fixAlignment(CompatRef<IDirectDrawSurface7> surface) void Surface::fixAlignment(CompatRef<IDirectDrawSurface7> surface)
{ {
DDSURFACEDESC2 desc = {}; DDSURFACEDESC2 desc = {};

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <functional>
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -31,6 +32,8 @@ namespace DDraw
static HRESULT create( static HRESULT create(
CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface, std::unique_ptr<Surface> privateData); CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface, std::unique_ptr<Surface> privateData);
static void enumSurfaces(const std::function<void(Surface&)>& callback);
template <typename TSurface> template <typename TSurface>
static Surface* getSurface(TSurface& dds); static Surface* getSurface(TSurface& dds);

View File

@ -193,18 +193,6 @@ namespace DDraw
{ {
restoreOrigCaps(lpDDSurfaceDesc->ddsCaps.dwCaps); restoreOrigCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
} }
else if (DDERR_SURFACELOST == result)
{
TSurfaceDesc desc = {};
desc.dwSize = sizeof(desc);
if (SUCCEEDED(getOrigVtable(This).GetSurfaceDesc(This, &desc)) && !(desc.dwFlags & DDSD_HEIGHT))
{
// Fixes missing handling for lost vertex buffers in Messiah
getOrigVtable(This).Restore(This);
// Still, pass back DDERR_SURFACELOST to the application in case it handles it
}
}
return result; return result;
} }

View File

@ -67,18 +67,6 @@ namespace DDraw
return nullptr; return nullptr;
} }
void TagSurface::forEachDirectDraw(std::function<void(CompatRef<IDirectDraw7>)> callback)
{
for (auto& ddObj : g_ddObjects)
{
DDRAWI_DIRECTDRAW_INT intf = {};
intf.lpVtbl = &CompatVtable<IDirectDraw7Vtbl>::s_origVtable;
intf.lpLcl = ddObj.first;
intf.dwIntRefCnt = 1;
callback(CompatRef<IDirectDraw7>(reinterpret_cast<IDirectDraw7&>(intf)));
}
}
TagSurface* TagSurface::get(DDRAWI_DIRECTDRAW_LCL* ddLcl) TagSurface* TagSurface::get(DDRAWI_DIRECTDRAW_LCL* ddLcl)
{ {
auto it = g_ddObjects.find(ddLcl); auto it = g_ddObjects.find(ddLcl);

View File

@ -2,7 +2,6 @@
#include <ddraw.h> #include <ddraw.h>
#include <ddrawi.h> #include <ddrawi.h>
#include <functional>
#include <Common/CompatRef.h> #include <Common/CompatRef.h>
#include <DDraw/Surfaces/Surface.h> #include <DDraw/Surfaces/Surface.h>
@ -20,7 +19,6 @@ namespace DDraw
static TagSurface* findFullscreenWindow(HWND hwnd); static TagSurface* findFullscreenWindow(HWND hwnd);
static bool doesFullscreenDirectDrawExist(); static bool doesFullscreenDirectDrawExist();
static void forEachDirectDraw(std::function<void(CompatRef<IDirectDraw7>)> callback);
void setFullscreenWindow(HWND hwnd); void setFullscreenWindow(HWND hwnd);
LONG setWindowStyle(LONG style); LONG setWindowStyle(LONG style);