mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Tagged all DirectDraw objects for tracking lifetime
This commit is contained in:
parent
3746362528
commit
7220b80999
@ -4,7 +4,6 @@
|
|||||||
#include "DDraw/ActivateAppHandler.h"
|
#include "DDraw/ActivateAppHandler.h"
|
||||||
#include "DDraw/DirectDraw.h"
|
#include "DDraw/DirectDraw.h"
|
||||||
#include "DDraw/DisplayMode.h"
|
#include "DDraw/DisplayMode.h"
|
||||||
#include "DDraw/Surfaces/FullScreenTagSurface.h"
|
|
||||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||||
#include "DDraw/Surfaces/SurfaceImpl.h"
|
#include "DDraw/Surfaces/SurfaceImpl.h"
|
||||||
#include "Gdi/Gdi.h"
|
#include "Gdi/Gdi.h"
|
||||||
@ -93,7 +92,7 @@ namespace
|
|||||||
Gdi::disableEmulation();
|
Gdi::disableEmulation();
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dd(DDraw::FullScreenTagSurface::getFullScreenDirectDraw());
|
auto dd(DDraw::getFullScreenDirectDraw());
|
||||||
if (dd)
|
if (dd)
|
||||||
{
|
{
|
||||||
if (isActivated)
|
if (isActivated)
|
||||||
|
@ -4,12 +4,38 @@
|
|||||||
#include "DDraw/DirectDraw.h"
|
#include "DDraw/DirectDraw.h"
|
||||||
#include "DDraw/DirectDrawSurface.h"
|
#include "DDraw/DirectDrawSurface.h"
|
||||||
#include "DDraw/DisplayMode.h"
|
#include "DDraw/DisplayMode.h"
|
||||||
#include "DDraw/Surfaces/FullScreenTagSurface.h"
|
#include "DDraw/Surfaces/TagSurface.h"
|
||||||
#include "DDraw/Surfaces/PrimarySurface.h"
|
#include "DDraw/Surfaces/PrimarySurface.h"
|
||||||
#include "DDraw/Surfaces/Surface.h"
|
#include "DDraw/Surfaces/Surface.h"
|
||||||
|
|
||||||
namespace DDraw
|
namespace DDraw
|
||||||
{
|
{
|
||||||
|
TagSurface* g_fullScreenTagSurface = nullptr;
|
||||||
|
|
||||||
|
template <typename TDirectDraw>
|
||||||
|
void* getDdObject(TDirectDraw& dd)
|
||||||
|
{
|
||||||
|
return reinterpret_cast<void**>(&dd)[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
template void* getDdObject(IDirectDraw&);
|
||||||
|
template void* getDdObject(IDirectDraw2&);
|
||||||
|
template void* getDdObject(IDirectDraw4&);
|
||||||
|
template void* getDdObject(IDirectDraw7&);
|
||||||
|
|
||||||
|
CompatPtr<IDirectDraw7> getFullScreenDirectDraw()
|
||||||
|
{
|
||||||
|
return g_fullScreenTagSurface ? g_fullScreenTagSurface->getDirectDraw() : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void onRelease(TagSurface& dd)
|
||||||
|
{
|
||||||
|
if (&dd == g_fullScreenTagSurface)
|
||||||
|
{
|
||||||
|
g_fullScreenTagSurface = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TDirectDraw>
|
template <typename TDirectDraw>
|
||||||
void DirectDraw<TDirectDraw>::setCompatVtable(Vtable<TDirectDraw>& vtable)
|
void DirectDraw<TDirectDraw>::setCompatVtable(Vtable<TDirectDraw>& vtable)
|
||||||
{
|
{
|
||||||
@ -85,16 +111,26 @@ namespace DDraw
|
|||||||
HRESULT result = s_origVtable.SetCooperativeLevel(This, hWnd, dwFlags);
|
HRESULT result = s_origVtable.SetCooperativeLevel(This, hWnd, dwFlags);
|
||||||
if (SUCCEEDED(result))
|
if (SUCCEEDED(result))
|
||||||
{
|
{
|
||||||
if (dwFlags & DDSCL_FULLSCREEN)
|
void* ddObject = getDdObject(*This);
|
||||||
|
TagSurface* tagSurface = TagSurface::get(ddObject);
|
||||||
|
if (!tagSurface)
|
||||||
{
|
{
|
||||||
CompatPtr<IDirectDraw> dd(Compat::queryInterface<IDirectDraw>(This));
|
CompatPtr<IDirectDraw> dd(Compat::queryInterface<IDirectDraw>(This));
|
||||||
DDraw::FullScreenTagSurface::create(*dd);
|
TagSurface::create(*dd);
|
||||||
ActivateAppHandler::setFullScreenCooperativeLevel(hWnd, dwFlags);
|
tagSurface = TagSurface::get(ddObject);
|
||||||
}
|
}
|
||||||
else if (CompatPtr<IDirectDraw7>(Compat::queryInterface<IDirectDraw7>(This)).get() ==
|
|
||||||
DDraw::FullScreenTagSurface::getFullScreenDirectDraw().get())
|
if (tagSurface)
|
||||||
{
|
{
|
||||||
DDraw::FullScreenTagSurface::destroy();
|
if (dwFlags & DDSCL_FULLSCREEN)
|
||||||
|
{
|
||||||
|
g_fullScreenTagSurface = tagSurface;
|
||||||
|
ActivateAppHandler::setFullScreenCooperativeLevel(hWnd, dwFlags);
|
||||||
|
}
|
||||||
|
else if ((dwFlags & DDSCL_NORMAL) && tagSurface == g_fullScreenTagSurface)
|
||||||
|
{
|
||||||
|
g_fullScreenTagSurface = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "Common/CompatPtr.h"
|
||||||
#include "Common/CompatVtable.h"
|
#include "Common/CompatVtable.h"
|
||||||
#include "DDraw/Visitors/DirectDrawVtblVisitor.h"
|
#include "DDraw/Visitors/DirectDrawVtblVisitor.h"
|
||||||
#include "DDraw/Types.h"
|
#include "DDraw/Types.h"
|
||||||
|
|
||||||
namespace DDraw
|
namespace DDraw
|
||||||
{
|
{
|
||||||
|
class TagSurface;
|
||||||
|
|
||||||
|
template <typename TDirectDraw>
|
||||||
|
void* getDdObject(TDirectDraw& dd);
|
||||||
|
|
||||||
|
CompatPtr<IDirectDraw7> getFullScreenDirectDraw();
|
||||||
|
void onRelease(TagSurface& dd);
|
||||||
|
|
||||||
template <typename TDirectDraw>
|
template <typename TDirectDraw>
|
||||||
class DirectDraw: public CompatVtable<Vtable<TDirectDraw>>
|
class DirectDraw: public CompatVtable<Vtable<TDirectDraw>>
|
||||||
{
|
{
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
#include "DDraw/Surfaces/SurfaceImpl.h"
|
|
||||||
#include "DDraw/Surfaces/FullScreenTagSurface.h"
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
CompatWeakPtr<IDirectDrawSurface> g_surface = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace DDraw
|
|
||||||
{
|
|
||||||
FullScreenTagSurface::~FullScreenTagSurface()
|
|
||||||
{
|
|
||||||
g_surface = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
HRESULT FullScreenTagSurface::create(CompatRef<IDirectDraw> dd)
|
|
||||||
{
|
|
||||||
destroy();
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
IDirectDrawSurface* surface = nullptr;
|
|
||||||
HRESULT result = Surface::create(dd, desc, surface);
|
|
||||||
if (SUCCEEDED(result))
|
|
||||||
{
|
|
||||||
CompatPtr<IDirectDrawSurface7> surface7(Compat::queryInterface<IDirectDrawSurface7>(surface));
|
|
||||||
std::unique_ptr<Surface> privateData(new FullScreenTagSurface());
|
|
||||||
attach(*surface7, privateData);
|
|
||||||
g_surface = surface;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FullScreenTagSurface::destroy()
|
|
||||||
{
|
|
||||||
g_surface.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
CompatPtr<IDirectDraw7> FullScreenTagSurface::getFullScreenDirectDraw()
|
|
||||||
{
|
|
||||||
if (!g_surface)
|
|
||||||
{
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CompatPtr<IUnknown> dd = nullptr;
|
|
||||||
auto tagSurface(getFullScreenTagSurface());
|
|
||||||
tagSurface.get()->lpVtbl->GetDDInterface(tagSurface, reinterpret_cast<void**>(&dd.getRef()));
|
|
||||||
return CompatPtr<IDirectDraw7>(Compat::queryInterface<IDirectDraw7>(dd.get()));
|
|
||||||
}
|
|
||||||
|
|
||||||
CompatPtr<IDirectDrawSurface7> FullScreenTagSurface::getFullScreenTagSurface()
|
|
||||||
{
|
|
||||||
return CompatPtr<IDirectDrawSurface7>(
|
|
||||||
Compat::queryInterface<IDirectDrawSurface7>(g_surface.get()));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "DDraw/Surfaces/Surface.h"
|
|
||||||
|
|
||||||
namespace DDraw
|
|
||||||
{
|
|
||||||
class FullScreenTagSurface : public Surface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~FullScreenTagSurface();
|
|
||||||
|
|
||||||
static HRESULT create(CompatRef<IDirectDraw> dd);
|
|
||||||
static void destroy();
|
|
||||||
static CompatPtr<IDirectDraw7> getFullScreenDirectDraw();
|
|
||||||
static CompatPtr<IDirectDrawSurface7> getFullScreenTagSurface();
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
#include <initguid.h>
|
#include <initguid.h>
|
||||||
|
|
||||||
#include "Common/CompatPtr.h"
|
#include "Common/CompatPtr.h"
|
||||||
|
#include "DDraw/DirectDraw.h"
|
||||||
#include "DDraw/DisplayMode.h"
|
#include "DDraw/DisplayMode.h"
|
||||||
#include "DDraw/Surfaces/Surface.h"
|
#include "DDraw/Surfaces/Surface.h"
|
||||||
#include "DDraw/Surfaces/SurfaceImpl.h"
|
#include "DDraw/Surfaces/SurfaceImpl.h"
|
||||||
@ -78,7 +79,8 @@ namespace DDraw
|
|||||||
}
|
}
|
||||||
|
|
||||||
Surface::Surface()
|
Surface::Surface()
|
||||||
: m_ddId()
|
: m_dds(nullptr)
|
||||||
|
, m_ddId()
|
||||||
, m_ddObject(nullptr)
|
, m_ddObject(nullptr)
|
||||||
, m_refCount(0)
|
, m_refCount(0)
|
||||||
{
|
{
|
||||||
@ -104,8 +106,10 @@ namespace DDraw
|
|||||||
privateData->m_impl4->m_data = privateData.get();
|
privateData->m_impl4->m_data = privateData.get();
|
||||||
privateData->m_impl7->m_data = privateData.get();
|
privateData->m_impl7->m_data = privateData.get();
|
||||||
|
|
||||||
|
privateData->m_dds = CompatPtr<IDirectDrawSurface>(
|
||||||
|
Compat::queryInterface<IDirectDrawSurface>(&dds));
|
||||||
privateData->m_ddId = getDdIidFromVtablePtr(reinterpret_cast<void**>(dd.get())[0]);
|
privateData->m_ddId = getDdIidFromVtablePtr(reinterpret_cast<void**>(dd.get())[0]);
|
||||||
privateData->m_ddObject = reinterpret_cast<void**>(dd.get())[1];
|
privateData->m_ddObject = DDraw::getDdObject(*CompatPtr<IDirectDraw>(dd));
|
||||||
|
|
||||||
privateData.release();
|
privateData.release();
|
||||||
}
|
}
|
||||||
@ -181,6 +185,19 @@ namespace DDraw
|
|||||||
template <>
|
template <>
|
||||||
SurfaceImpl<IDirectDrawSurface7>* Surface::getImpl<IDirectDrawSurface7>() const { return m_impl7.get(); }
|
SurfaceImpl<IDirectDrawSurface7>* Surface::getImpl<IDirectDrawSurface7>() const { return m_impl7.get(); }
|
||||||
|
|
||||||
|
CompatPtr<IDirectDraw7> Surface::getDirectDraw() const
|
||||||
|
{
|
||||||
|
auto dds(getDirectDrawSurface());
|
||||||
|
CompatPtr<IUnknown> dd;
|
||||||
|
m_impl7->GetDDInterface(dds, reinterpret_cast<void**>(&dd.getRef()));
|
||||||
|
return CompatPtr<IDirectDraw7>(dd);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompatPtr<IDirectDrawSurface7> Surface::getDirectDrawSurface() const
|
||||||
|
{
|
||||||
|
return CompatPtr<IDirectDrawSurface7>(Compat::queryInterface<IDirectDrawSurface7>(m_dds));
|
||||||
|
}
|
||||||
|
|
||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
Surface* Surface::getSurface(TSurface& dds)
|
Surface* Surface::getSurface(TSurface& dds)
|
||||||
{
|
{
|
||||||
|
@ -29,6 +29,9 @@ namespace DDraw
|
|||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
static Surface* getSurface(TSurface& dds);
|
static Surface* getSurface(TSurface& dds);
|
||||||
|
|
||||||
|
CompatPtr<IDirectDraw7> getDirectDraw() const;
|
||||||
|
CompatPtr<IDirectDrawSurface7> getDirectDrawSurface() const;
|
||||||
|
|
||||||
template <typename TSurface>
|
template <typename TSurface>
|
||||||
SurfaceImpl<TSurface>* getImpl() const;
|
SurfaceImpl<TSurface>* getImpl() const;
|
||||||
|
|
||||||
@ -51,6 +54,7 @@ namespace DDraw
|
|||||||
IDirectDrawSurface7* surface, DDSURFACEDESC2* desc, void* rootSurface);
|
IDirectDrawSurface7* surface, DDSURFACEDESC2* desc, void* rootSurface);
|
||||||
virtual void createImpl();
|
virtual void createImpl();
|
||||||
|
|
||||||
|
IDirectDrawSurface* m_dds;
|
||||||
IID m_ddId;
|
IID m_ddId;
|
||||||
void* m_ddObject;
|
void* m_ddObject;
|
||||||
DWORD m_refCount;
|
DWORD m_refCount;
|
||||||
|
50
DDrawCompat/DDraw/Surfaces/TagSurface.cpp
Normal file
50
DDrawCompat/DDraw/Surfaces/TagSurface.cpp
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
#include <algorithm>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#include "DDraw/DirectDraw.h"
|
||||||
|
#include "DDraw/Surfaces/SurfaceImpl.h"
|
||||||
|
#include "DDraw/Surfaces/TagSurface.h"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
std::map<void*, DDraw::TagSurface*> g_tagSurfaces;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace DDraw
|
||||||
|
{
|
||||||
|
TagSurface::~TagSurface()
|
||||||
|
{
|
||||||
|
std::find_if(g_tagSurfaces.begin(), g_tagSurfaces.end(),
|
||||||
|
[=](auto& i) { return i.second == this; })->second;
|
||||||
|
DDraw::onRelease(*this);
|
||||||
|
g_tagSurfaces.erase(std::find_if(g_tagSurfaces.begin(), g_tagSurfaces.end(),
|
||||||
|
[=](auto& i) { return i.second == this; }));
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT TagSurface::create(CompatRef<IDirectDraw> dd)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
IDirectDrawSurface* surface = nullptr;
|
||||||
|
HRESULT result = Surface::create(dd, desc, surface);
|
||||||
|
if (SUCCEEDED(result))
|
||||||
|
{
|
||||||
|
std::unique_ptr<Surface> privateData(new TagSurface());
|
||||||
|
g_tagSurfaces[getDdObject(dd.get())] = static_cast<TagSurface*>(privateData.get());
|
||||||
|
CompatPtr<IDirectDrawSurface7> surface7(Compat::queryInterface<IDirectDrawSurface7>(surface));
|
||||||
|
attach(*surface7, privateData);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
TagSurface* TagSurface::get(void* ddObject)
|
||||||
|
{
|
||||||
|
auto it = g_tagSurfaces.find(ddObject);
|
||||||
|
return it != g_tagSurfaces.end() ? it->second : nullptr;
|
||||||
|
}
|
||||||
|
}
|
15
DDrawCompat/DDraw/Surfaces/TagSurface.h
Normal file
15
DDrawCompat/DDraw/Surfaces/TagSurface.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "DDraw/Surfaces/Surface.h"
|
||||||
|
|
||||||
|
namespace DDraw
|
||||||
|
{
|
||||||
|
class TagSurface : public Surface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~TagSurface();
|
||||||
|
|
||||||
|
static HRESULT create(CompatRef<IDirectDraw> dd);
|
||||||
|
static TagSurface* get(void* ddObject);
|
||||||
|
};
|
||||||
|
}
|
@ -182,7 +182,7 @@
|
|||||||
<ClInclude Include="DDraw\Hooks.h" />
|
<ClInclude Include="DDraw\Hooks.h" />
|
||||||
<ClInclude Include="DDraw\Repository.h" />
|
<ClInclude Include="DDraw\Repository.h" />
|
||||||
<ClInclude Include="DDraw\ScopedThreadLock.h" />
|
<ClInclude Include="DDraw\ScopedThreadLock.h" />
|
||||||
<ClInclude Include="DDraw\Surfaces\FullScreenTagSurface.h" />
|
<ClInclude Include="DDraw\Surfaces\TagSurface.h" />
|
||||||
<ClInclude Include="DDraw\Surfaces\PrimarySurface.h" />
|
<ClInclude Include="DDraw\Surfaces\PrimarySurface.h" />
|
||||||
<ClInclude Include="DDraw\Surfaces\PrimarySurfaceImpl.h" />
|
<ClInclude Include="DDraw\Surfaces\PrimarySurfaceImpl.h" />
|
||||||
<ClInclude Include="DDraw\Surfaces\Surface.h" />
|
<ClInclude Include="DDraw\Surfaces\Surface.h" />
|
||||||
@ -234,7 +234,7 @@
|
|||||||
<ClCompile Include="DDraw\Repository.cpp" />
|
<ClCompile Include="DDraw\Repository.cpp" />
|
||||||
<ClCompile Include="DDraw\IReleaseNotifier.cpp" />
|
<ClCompile Include="DDraw\IReleaseNotifier.cpp" />
|
||||||
<ClCompile Include="DDraw\RealPrimarySurface.cpp" />
|
<ClCompile Include="DDraw\RealPrimarySurface.cpp" />
|
||||||
<ClCompile Include="DDraw\Surfaces\FullScreenTagSurface.cpp" />
|
<ClCompile Include="DDraw\Surfaces\TagSurface.cpp" />
|
||||||
<ClCompile Include="DDraw\Surfaces\PrimarySurface.cpp" />
|
<ClCompile Include="DDraw\Surfaces\PrimarySurface.cpp" />
|
||||||
<ClCompile Include="DDraw\Surfaces\PrimarySurfaceImpl.cpp" />
|
<ClCompile Include="DDraw\Surfaces\PrimarySurfaceImpl.cpp" />
|
||||||
<ClCompile Include="DDraw\Surfaces\Surface.cpp" />
|
<ClCompile Include="DDraw\Surfaces\Surface.cpp" />
|
||||||
|
@ -255,7 +255,7 @@
|
|||||||
<ClInclude Include="DDraw\Surfaces\PrimarySurfaceImpl.h">
|
<ClInclude Include="DDraw\Surfaces\PrimarySurfaceImpl.h">
|
||||||
<Filter>Header Files\DDraw\Surfaces</Filter>
|
<Filter>Header Files\DDraw\Surfaces</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="DDraw\Surfaces\FullScreenTagSurface.h">
|
<ClInclude Include="DDraw\Surfaces\TagSurface.h">
|
||||||
<Filter>Header Files\DDraw\Surfaces</Filter>
|
<Filter>Header Files\DDraw\Surfaces</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@ -386,7 +386,7 @@
|
|||||||
<ClCompile Include="DDraw\Surfaces\PrimarySurfaceImpl.cpp">
|
<ClCompile Include="DDraw\Surfaces\PrimarySurfaceImpl.cpp">
|
||||||
<Filter>Source Files\DDraw\Surfaces</Filter>
|
<Filter>Source Files\DDraw\Surfaces</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="DDraw\Surfaces\FullScreenTagSurface.cpp">
|
<ClCompile Include="DDraw\Surfaces\TagSurface.cpp">
|
||||||
<Filter>Source Files\DDraw\Surfaces</Filter>
|
<Filter>Source Files\DDraw\Surfaces</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user