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

Remove mipmap caps from textures with single mip level

Fixes texture creation errors in Extreme-G 2 (see issue #159).
This commit is contained in:
narzoul 2022-10-31 18:05:48 +01:00
parent 113da37945
commit ab443a1ac2
10 changed files with 36 additions and 23 deletions

View File

@ -69,7 +69,7 @@ namespace
} }
return DDraw::Surface::create<TDirectDraw>( return DDraw::Surface::create<TDirectDraw>(
*This, desc, *lplpDDSurface, std::make_unique<DDraw::Surface>(desc.ddsCaps.dwCaps)); *This, desc, *lplpDDSurface, std::make_unique<DDraw::Surface>(desc.dwFlags, desc.ddsCaps.dwCaps));
} }
template <typename TDirectDraw> template <typename TDirectDraw>

View File

@ -22,21 +22,22 @@ namespace DDraw
auto dd1(CompatPtr<IDirectDraw>::from(&dd)); auto dd1(CompatPtr<IDirectDraw>::from(&dd));
CompatPtr<IDirectDrawSurface> palettizedSurface; CompatPtr<IDirectDrawSurface> palettizedSurface;
HRESULT result = Surface::create<IDirectDraw>(*dd1, d, palettizedSurface.getRef(), HRESULT result = Surface::create<IDirectDraw>(*dd1, d, palettizedSurface.getRef(),
std::make_unique<DDraw::Surface>(desc.ddsCaps.dwCaps)); std::make_unique<DDraw::Surface>(desc.dwFlags, desc.ddsCaps.dwCaps));
if (FAILED(result)) if (FAILED(result))
{ {
return LOG_RESULT(result); return LOG_RESULT(result);
} }
auto privateData(std::make_unique<PalettizedTexture>(desc.ddsCaps.dwCaps));
auto data = privateData.get();
data->m_palettizedSurface = palettizedSurface;
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS |
(desc.dwFlags & (DDSD_CKSRCBLT | DDSD_CKDESTBLT)); (desc.dwFlags & (DDSD_CKSRCBLT | DDSD_CKDESTBLT));
desc.ddpfPixelFormat = D3dDdi::getPixelFormat(D3DDDIFMT_A8R8G8B8); desc.ddpfPixelFormat = D3dDdi::getPixelFormat(D3DDDIFMT_A8R8G8B8);
desc.ddsCaps = {}; desc.ddsCaps = {};
desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY; desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY;
auto privateData(std::make_unique<PalettizedTexture>(desc.dwFlags, desc.ddsCaps.dwCaps));
auto data = privateData.get();
data->m_palettizedSurface = palettizedSurface;
result = Surface::create(dd, desc, surface, std::move(privateData)); result = Surface::create(dd, desc, surface, std::move(privateData));
if (FAILED(result)) if (FAILED(result))
{ {

View File

@ -11,7 +11,7 @@ namespace DDraw
class PalettizedTexture : public Surface class PalettizedTexture : public Surface
{ {
public: public:
PalettizedTexture(DWORD origCaps) : Surface(origCaps) {} PalettizedTexture(DWORD origFlags, DWORD origCaps) : Surface(origFlags, origCaps) {}
virtual ~PalettizedTexture() override; virtual ~PalettizedTexture() override;
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc> template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>

View File

@ -106,6 +106,8 @@ namespace DDraw
} }
const DWORD origCaps = desc.ddsCaps.dwCaps; const DWORD origCaps = desc.ddsCaps.dwCaps;
auto privateData(std::make_unique<PrimarySurface>(desc.dwFlags, origCaps));
auto data = privateData.get();
desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT; desc.dwFlags |= DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
desc.dwWidth = dm.dwWidth; desc.dwWidth = dm.dwWidth;
@ -115,8 +117,6 @@ namespace DDraw
desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN; desc.ddsCaps.dwCaps |= DDSCAPS_OFFSCREENPLAIN;
desc.ddpfPixelFormat = dm.ddpfPixelFormat; desc.ddpfPixelFormat = dm.ddpfPixelFormat;
auto privateData(std::make_unique<PrimarySurface>(origCaps));
auto data = privateData.get();
result = Surface::create(dd, desc, surface, std::move(privateData)); result = Surface::create(dd, desc, surface, std::move(privateData));
if (FAILED(result)) if (FAILED(result))
{ {

View File

@ -11,7 +11,7 @@ namespace DDraw
class PrimarySurface : public Surface class PrimarySurface : public Surface
{ {
public: public:
PrimarySurface(DWORD origCaps) : Surface(origCaps) {} PrimarySurface(DWORD origFlags, DWORD origCaps) : Surface(origFlags, origCaps) {}
virtual ~PrimarySurface(); virtual ~PrimarySurface();
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc> template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>

View File

@ -46,8 +46,9 @@ namespace DDraw
return refCount; return refCount;
} }
Surface::Surface(DWORD origCaps) Surface::Surface(DWORD origFlags, DWORD origCaps)
: m_origCaps(origCaps) : m_origFlags(origFlags)
, m_origCaps(origCaps)
, m_refCount(0) , m_refCount(0)
, m_sizeOverride{} , m_sizeOverride{}
, m_sysMemBuffer(nullptr, &heapFree) , m_sysMemBuffer(nullptr, &heapFree)
@ -96,6 +97,12 @@ namespace DDraw
desc.ddsCaps.dwCaps &= ~DDSCAPS_3DDEVICE; desc.ddsCaps.dwCaps &= ~DDSCAPS_3DDEVICE;
} }
if ((desc.dwFlags & DDSD_MIPMAPCOUNT) && 1 == desc.dwMipMapCount)
{
desc.dwFlags &= ~DDSD_MIPMAPCOUNT;
desc.ddsCaps.dwCaps &= ~(DDSCAPS_COMPLEX | DDSCAPS_MIPMAP);
}
HRESULT result = dd->CreateSurface(&dd, &desc, &surface, nullptr); HRESULT result = dd->CreateSurface(&dd, &desc, &surface, nullptr);
if (FAILED(result)) if (FAILED(result))
{ {
@ -108,7 +115,7 @@ namespace DDraw
auto attachedSurfaces(DirectDrawSurface::getAllAttachedSurfaces(*surface7)); auto attachedSurfaces(DirectDrawSurface::getAllAttachedSurfaces(*surface7));
for (DWORD i = 0; i < attachedSurfaces.size(); ++i) for (DWORD i = 0; i < attachedSurfaces.size(); ++i)
{ {
attach(*attachedSurfaces[i], std::make_unique<Surface>(privateData->m_origCaps)); attach(*attachedSurfaces[i], std::make_unique<Surface>(privateData->m_origFlags, privateData->m_origCaps));
} }
} }
else if ((desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) && !(desc.dwFlags & DDSD_LPSURFACE)) else if ((desc.ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) && !(desc.dwFlags & DDSD_LPSURFACE))

View File

@ -23,7 +23,7 @@ namespace DDraw
virtual ULONG STDMETHODCALLTYPE AddRef(); virtual ULONG STDMETHODCALLTYPE AddRef();
virtual ULONG STDMETHODCALLTYPE Release(); virtual ULONG STDMETHODCALLTYPE Release();
Surface(DWORD origCaps); Surface(DWORD origFlags, DWORD origCaps);
virtual ~Surface(); virtual ~Surface();
static void* alignBuffer(void* buffer); static void* alignBuffer(void* buffer);
@ -65,6 +65,7 @@ namespace DDraw
template <typename TDirectDrawSurface> template <typename TDirectDrawSurface>
friend class SurfaceImpl; friend class SurfaceImpl;
DWORD m_origFlags;
DWORD m_origCaps; DWORD m_origCaps;
DWORD m_refCount; DWORD m_refCount;
SIZE m_sizeOverride; SIZE m_sizeOverride;

View File

@ -189,7 +189,14 @@ namespace DDraw
lpDDSurfaceDesc->dwHeight = m_data->m_sizeOverride.cy; lpDDSurfaceDesc->dwHeight = m_data->m_sizeOverride.cy;
m_data->m_sizeOverride = {}; m_data->m_sizeOverride = {};
} }
restoreOrigCaps(lpDDSurfaceDesc->ddsCaps.dwCaps); restoreOrigCaps(lpDDSurfaceDesc->ddsCaps.dwCaps);
if ((m_data->m_origFlags & DDSD_MIPMAPCOUNT) && !(lpDDSurfaceDesc->dwFlags & DDSD_MIPMAPCOUNT))
{
lpDDSurfaceDesc->dwFlags |= DDSD_MIPMAPCOUNT;
lpDDSurfaceDesc->dwMipMapCount = 1;
}
} }
return result; return result;
} }
@ -299,10 +306,7 @@ namespace DDraw
template <typename TSurface> template <typename TSurface>
void SurfaceImpl<TSurface>::restoreOrigCaps(DWORD& caps) void SurfaceImpl<TSurface>::restoreOrigCaps(DWORD& caps)
{ {
if (m_data->m_origCaps & DDSCAPS_3DDEVICE) caps |= m_data->m_origCaps & (DDSCAPS_3DDEVICE | DDSCAPS_MIPMAP | DDSCAPS_COMPLEX);
{
caps |= DDSCAPS_3DDEVICE;
}
} }
template SurfaceImpl<IDirectDrawSurface>; template SurfaceImpl<IDirectDrawSurface>;

View File

@ -11,14 +11,14 @@ namespace
namespace DDraw namespace DDraw
{ {
TagSurface::TagSurface(DWORD origCaps, DDRAWI_DIRECTDRAW_LCL* ddLcl) TagSurface::TagSurface(DWORD origFlags, DWORD origCaps, DDRAWI_DIRECTDRAW_LCL* ddLcl)
: Surface(origCaps) : Surface(origFlags, origCaps)
, m_ddInt{} , m_ddInt{}
, m_fullscreenWindow(nullptr) , m_fullscreenWindow(nullptr)
, m_fullscreenWindowStyle(0) , m_fullscreenWindowStyle(0)
, m_fullscreenWindowExStyle(0) , m_fullscreenWindowExStyle(0)
{ {
LOG_FUNC("TagSurface::TagSurface", Compat::hex(origCaps), ddLcl); LOG_FUNC("TagSurface::TagSurface", Compat::hex(origFlags), Compat::hex(origCaps), ddLcl);
m_ddInt.lpVtbl = &CompatVtable<IDirectDraw>::s_origVtable; m_ddInt.lpVtbl = &CompatVtable<IDirectDraw>::s_origVtable;
m_ddInt.lpLcl = ddLcl; m_ddInt.lpLcl = ddLcl;
m_ddInt.dwIntRefCnt = 1; m_ddInt.dwIntRefCnt = 1;
@ -41,7 +41,7 @@ namespace DDraw
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY; desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
auto ddLcl = DDraw::DirectDraw::getInt(dd.get()).lpLcl; auto ddLcl = DDraw::DirectDraw::getInt(dd.get()).lpLcl;
auto privateData(std::make_unique<TagSurface>(desc.ddsCaps.dwCaps, ddLcl)); auto privateData(std::make_unique<TagSurface>(desc.dwFlags, desc.ddsCaps.dwCaps, ddLcl));
g_ddObjects[ddLcl] = privateData.get(); g_ddObjects[ddLcl] = privateData.get();
IDirectDrawSurface* surface = nullptr; IDirectDrawSurface* surface = nullptr;

View File

@ -11,7 +11,7 @@ namespace DDraw
class TagSurface : public Surface class TagSurface : public Surface
{ {
public: public:
TagSurface(DWORD origCaps, DDRAWI_DIRECTDRAW_LCL* ddLcl); TagSurface(DWORD origFlags, DWORD origCaps, DDRAWI_DIRECTDRAW_LCL* ddLcl);
virtual ~TagSurface() override; virtual ~TagSurface() override;
static TagSurface* get(DDRAWI_DIRECTDRAW_LCL* ddLcl); static TagSurface* get(DDRAWI_DIRECTDRAW_LCL* ddLcl);