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>(
*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>

View File

@ -22,21 +22,22 @@ namespace DDraw
auto dd1(CompatPtr<IDirectDraw>::from(&dd));
CompatPtr<IDirectDrawSurface> palettizedSurface;
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))
{
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_CKSRCBLT | DDSD_CKDESTBLT));
desc.ddpfPixelFormat = D3dDdi::getPixelFormat(D3DDDIFMT_A8R8G8B8);
desc.ddsCaps = {};
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));
if (FAILED(result))
{

View File

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

View File

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

View File

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

View File

@ -46,8 +46,9 @@ namespace DDraw
return refCount;
}
Surface::Surface(DWORD origCaps)
: m_origCaps(origCaps)
Surface::Surface(DWORD origFlags, DWORD origCaps)
: m_origFlags(origFlags)
, m_origCaps(origCaps)
, m_refCount(0)
, m_sizeOverride{}
, m_sysMemBuffer(nullptr, &heapFree)
@ -96,6 +97,12 @@ namespace DDraw
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);
if (FAILED(result))
{
@ -108,7 +115,7 @@ namespace DDraw
auto attachedSurfaces(DirectDrawSurface::getAllAttachedSurfaces(*surface7));
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))

View File

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

View File

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

View File

@ -11,14 +11,14 @@ namespace
namespace DDraw
{
TagSurface::TagSurface(DWORD origCaps, DDRAWI_DIRECTDRAW_LCL* ddLcl)
: Surface(origCaps)
TagSurface::TagSurface(DWORD origFlags, DWORD origCaps, DDRAWI_DIRECTDRAW_LCL* ddLcl)
: Surface(origFlags, origCaps)
, m_ddInt{}
, m_fullscreenWindow(nullptr)
, m_fullscreenWindowStyle(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.lpLcl = ddLcl;
m_ddInt.dwIntRefCnt = 1;
@ -41,7 +41,7 @@ namespace DDraw
desc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
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();
IDirectDrawSurface* surface = nullptr;

View File

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