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

Bypass restrictions on maximum render target size (2048x2048)

This commit is contained in:
narzoul 2021-01-08 01:17:04 +01:00
parent 050248a552
commit 7b660e1396
5 changed files with 63 additions and 4 deletions

View File

@ -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;
}
}

View File

@ -35,6 +35,8 @@ namespace DDraw
virtual void restore();
void setSizeOverride(DWORD width, DWORD height);
protected:
static void attach(CompatRef<IDirectDrawSurface7> dds, std::unique_ptr<Surface> privateData);
@ -54,5 +56,6 @@ namespace DDraw
friend class SurfaceImpl;
DWORD m_refCount;
SIZE m_sizeOverride;
};
}

View File

@ -100,7 +100,14 @@ namespace DDraw
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::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 <typename TSurface>
@ -138,7 +145,15 @@ namespace DDraw
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::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 <typename TSurface>

View File

@ -1,4 +1,5 @@
#include <Common/CompatPtr.h>
#include <DDraw/Surfaces/Surface.h>
#include <Direct3d/Direct3d.h>
#include <Direct3d/Direct3dDevice.h>
#include <Direct3d/Types.h>
@ -13,8 +14,20 @@ namespace
TDirect3dDevice** lplpD3DDevice,
Params... params)
{
auto iid = (IID_IDirect3DRampDevice == rclsid) ? &IID_IDirect3DRGBDevice : &rclsid;
HRESULT result = CompatVtable<Vtable<TDirect3d>>::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<Vtable<TDirect3d>>::s_origVtable.CreateDevice(
This, *iid, lpDDS, lplpD3DDevice, params...);
surface->setSizeOverride(0, 0);
}
}
if (SUCCEEDED(result))
{
CompatVtable<Vtable<TDirect3dDevice>>::hookVtable((*lplpD3DDevice)->lpVtbl);

View File

@ -1,6 +1,7 @@
#include <Common/CompatPtr.h>
#include <Common/CompatRef.h>
#include <D3dDdi/Device.h>
#include <DDraw/Surfaces/Surface.h>
#include <Direct3d/Direct3dDevice.h>
#include <Direct3d/Types.h>
@ -17,14 +18,34 @@ namespace
return result;
}
template <typename TDirect3DDevice, typename TSurface>
HRESULT STDMETHODCALLTYPE setRenderTarget(TDirect3DDevice* This, TSurface* lpNewRenderTarget, DWORD dwFlags)
{
HRESULT result = CompatVtable<Vtable<TDirect3DDevice>>::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<Vtable<TDirect3DDevice>>::s_origVtable.SetRenderTarget(
This, lpNewRenderTarget, dwFlags);
surface->setSizeOverride(0, 0);
}
}
return result;
}
void setCompatVtable(IDirect3DDeviceVtbl& vtable)
{
vtable.Execute = &execute;
}
template <typename TDirect3dDeviceVtbl>
void setCompatVtable(TDirect3dDeviceVtbl& /*vtable*/)
void setCompatVtable(TDirect3dDeviceVtbl& vtable)
{
vtable.SetRenderTarget = &setRenderTarget;
}
}