diff --git a/DDrawCompat/DDraw/Surfaces/Surface.cpp b/DDrawCompat/DDraw/Surfaces/Surface.cpp index f666388..6b87b04 100644 --- a/DDrawCompat/DDraw/Surfaces/Surface.cpp +++ b/DDrawCompat/DDraw/Surfaces/Surface.cpp @@ -35,6 +35,7 @@ namespace DDraw Surface::Surface() : m_refCount(0) + , m_sizeOverride{} { } @@ -130,4 +131,10 @@ namespace DDraw void Surface::restore() { } + + void Surface::setSizeOverride(DWORD width, DWORD height) + { + m_sizeOverride.cx = width; + m_sizeOverride.cy = height; + } } diff --git a/DDrawCompat/DDraw/Surfaces/Surface.h b/DDrawCompat/DDraw/Surfaces/Surface.h index 17729e1..cf47f0f 100644 --- a/DDrawCompat/DDraw/Surfaces/Surface.h +++ b/DDrawCompat/DDraw/Surfaces/Surface.h @@ -35,6 +35,8 @@ namespace DDraw virtual void restore(); + void setSizeOverride(DWORD width, DWORD height); + protected: static void attach(CompatRef dds, std::unique_ptr privateData); @@ -54,5 +56,6 @@ namespace DDraw friend class SurfaceImpl; DWORD m_refCount; + SIZE m_sizeOverride; }; } diff --git a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp index 66a82d1..45c9101 100644 --- a/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp +++ b/DDrawCompat/DDraw/Surfaces/SurfaceImpl.cpp @@ -100,7 +100,14 @@ namespace DDraw template HRESULT SurfaceImpl::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc) { - return s_origVtable.GetSurfaceDesc(This, lpDDSurfaceDesc); + HRESULT result = s_origVtable.GetSurfaceDesc(This, lpDDSurfaceDesc); + if (SUCCEEDED(result) && 0 != m_data->m_sizeOverride.cx) + { + lpDDSurfaceDesc->dwWidth = m_data->m_sizeOverride.cx; + lpDDSurfaceDesc->dwHeight = m_data->m_sizeOverride.cy; + m_data->m_sizeOverride = {}; + } + return result; } template @@ -138,7 +145,15 @@ namespace DDraw template HRESULT SurfaceImpl::QueryInterface(TSurface* This, REFIID riid, LPVOID* obp) { - return s_origVtable.QueryInterface(This, (IID_IDirect3DRampDevice == riid ? IID_IDirect3DRGBDevice : riid), obp); + auto iid = (IID_IDirect3DRampDevice == riid) ? &IID_IDirect3DRGBDevice : &riid; + HRESULT result = s_origVtable.QueryInterface(This, *iid, obp); + if (DDERR_INVALIDOBJECT == result) + { + m_data->setSizeOverride(1, 1); + result = s_origVtable.QueryInterface(This, *iid, obp); + m_data->setSizeOverride(0, 0); + } + return result; } template diff --git a/DDrawCompat/Direct3d/Direct3d.cpp b/DDrawCompat/Direct3d/Direct3d.cpp index b226713..6b332c9 100644 --- a/DDrawCompat/Direct3d/Direct3d.cpp +++ b/DDrawCompat/Direct3d/Direct3d.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -13,8 +14,20 @@ namespace TDirect3dDevice** lplpD3DDevice, Params... params) { + auto iid = (IID_IDirect3DRampDevice == rclsid) ? &IID_IDirect3DRGBDevice : &rclsid; HRESULT result = CompatVtable>::s_origVtable.CreateDevice( - This, (IID_IDirect3DRampDevice == rclsid) ? IID_IDirect3DRGBDevice : rclsid, lpDDS, lplpD3DDevice, params...); + This, *iid, lpDDS, lplpD3DDevice, params...); + if (DDERR_INVALIDOBJECT == result && lpDDS) + { + auto surface = DDraw::Surface::getSurface(*lpDDS); + if (surface) + { + surface->setSizeOverride(1, 1); + result = CompatVtable>::s_origVtable.CreateDevice( + This, *iid, lpDDS, lplpD3DDevice, params...); + surface->setSizeOverride(0, 0); + } + } if (SUCCEEDED(result)) { CompatVtable>::hookVtable((*lplpD3DDevice)->lpVtbl); diff --git a/DDrawCompat/Direct3d/Direct3dDevice.cpp b/DDrawCompat/Direct3d/Direct3dDevice.cpp index 9c69450..915febe 100644 --- a/DDrawCompat/Direct3d/Direct3dDevice.cpp +++ b/DDrawCompat/Direct3d/Direct3dDevice.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -17,14 +18,34 @@ namespace return result; } + template + HRESULT STDMETHODCALLTYPE setRenderTarget(TDirect3DDevice* This, TSurface* lpNewRenderTarget, DWORD dwFlags) + { + HRESULT result = CompatVtable>::s_origVtable.SetRenderTarget( + This, lpNewRenderTarget, dwFlags); + if (DDERR_INVALIDPARAMS == result && lpNewRenderTarget) + { + auto surface = DDraw::Surface::getSurface(*lpNewRenderTarget); + if (surface) + { + surface->setSizeOverride(1, 1); + result = CompatVtable>::s_origVtable.SetRenderTarget( + This, lpNewRenderTarget, dwFlags); + surface->setSizeOverride(0, 0); + } + } + return result; + } + void setCompatVtable(IDirect3DDeviceVtbl& vtable) { vtable.Execute = &execute; } template - void setCompatVtable(TDirect3dDeviceVtbl& /*vtable*/) + void setCompatVtable(TDirect3dDeviceVtbl& vtable) { + vtable.SetRenderTarget = &setRenderTarget; } }