mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Partial workaround for black D3DTA_DIFFUSE color on some drivers when RHW=0
Fixes black screen issues under some circumstances (e.g. underwater) in Might and Magic 9 (issue #48).
This commit is contained in:
parent
7068d282ff
commit
bb6092e0bd
@ -7,7 +7,7 @@
|
||||
|
||||
struct _D3DDDI_ADAPTERCALLBACKS;
|
||||
struct _D3DDDI_ADAPTERFUNCS;
|
||||
struct _D3DDDI_DEVICEALLBACKS;
|
||||
struct _D3DDDI_DEVICECALLBACKS;
|
||||
struct _D3DDDI_DEVICEFUNCS;
|
||||
|
||||
template <typename Vtable>
|
||||
@ -20,7 +20,7 @@ template <>
|
||||
class ScopedVtableFuncLock<_D3DDDI_ADAPTERFUNCS> : public D3dDdi::ScopedCriticalSection {};
|
||||
|
||||
template <>
|
||||
class ScopedVtableFuncLock<_D3DDDI_DEVICEALLBACKS> : public D3dDdi::ScopedCriticalSection {};
|
||||
class ScopedVtableFuncLock<_D3DDDI_DEVICECALLBACKS> : public D3dDdi::ScopedCriticalSection {};
|
||||
|
||||
template <>
|
||||
class ScopedVtableFuncLock<_D3DDDI_DEVICEFUNCS> : public D3dDdi::ScopedCriticalSection {};
|
||||
@ -42,9 +42,7 @@ public:
|
||||
m_origVtable.*ptr = m_srcVtable.*ptr;
|
||||
if (m_origVtable.*ptr && s_compatVtable.*ptr)
|
||||
{
|
||||
#ifdef DEBUGLOGS
|
||||
Compat::Log() << "Hooking function: " << FuncNameVisitor<Vtable>::getFuncName<MemberDataPtr, ptr>();
|
||||
#endif
|
||||
Compat::LogDebug() << "Hooking function: " << FuncNameVisitor<Vtable>::getFuncName<MemberDataPtr, ptr>();
|
||||
Compat::hookFunction(reinterpret_cast<void*&>(m_origVtable.*ptr),
|
||||
getThreadSafeFuncPtr<MemberDataPtr, ptr>(s_compatVtable.*ptr));
|
||||
}
|
||||
|
@ -38,6 +38,8 @@ namespace D3dDdi
|
||||
, m_adapter(Adapter::get(adapter))
|
||||
, m_device(device)
|
||||
, m_sharedPrimary(nullptr)
|
||||
, m_streamSourceData{}
|
||||
, m_streamSource(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
@ -135,6 +137,10 @@ namespace D3dDdi
|
||||
g_gdiResourceHandle = nullptr;
|
||||
g_gdiResource = nullptr;
|
||||
}
|
||||
if (resource == m_streamSource)
|
||||
{
|
||||
m_streamSource = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
@ -155,6 +161,11 @@ namespace D3dDdi
|
||||
|
||||
HRESULT Device::drawPrimitive(const D3DDDIARG_DRAWPRIMITIVE& data, const UINT* flagBuffer)
|
||||
{
|
||||
if (m_streamSource && 0 != m_streamSourceData.Stride)
|
||||
{
|
||||
m_streamSource->fixVertexData(m_streamSourceData.Offset + data.VStart * m_streamSourceData.Stride,
|
||||
data.PrimitiveCount, m_streamSourceData.Stride);
|
||||
}
|
||||
prepareForRendering();
|
||||
return m_origVtable.pfnDrawPrimitive(m_device, &data, flagBuffer);
|
||||
}
|
||||
@ -214,6 +225,28 @@ namespace D3dDdi
|
||||
return m_origVtable.pfnPresent1(m_device, &data);
|
||||
}
|
||||
|
||||
HRESULT Device::setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& data)
|
||||
{
|
||||
HRESULT result = m_origVtable.pfnSetStreamSource(m_device, &data);
|
||||
if (SUCCEEDED(result) && 0 == data.Stream)
|
||||
{
|
||||
m_streamSourceData = data;
|
||||
m_streamSource = getResource(data.hVertexBuffer);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT Device::setStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& data, const void* umBuffer)
|
||||
{
|
||||
HRESULT result = m_origVtable.pfnSetStreamSourceUm(m_device, &data, umBuffer);
|
||||
if (SUCCEEDED(result) && 0 == data.Stream)
|
||||
{
|
||||
m_streamSourceData = {};
|
||||
m_streamSource = nullptr;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT Device::texBlt(const D3DDDIARG_TEXBLT& data)
|
||||
{
|
||||
prepareForRendering(data.hDstResource, UINT_MAX, false);
|
||||
|
@ -36,6 +36,8 @@ namespace D3dDdi
|
||||
HRESULT openResource(D3DDDIARG_OPENRESOURCE& data);
|
||||
HRESULT present(const D3DDDIARG_PRESENT& data);
|
||||
HRESULT present1(D3DDDIARG_PRESENT1& data);
|
||||
HRESULT setStreamSource(const D3DDDIARG_SETSTREAMSOURCE& data);
|
||||
HRESULT setStreamSourceUm(const D3DDDIARG_SETSTREAMSOURCEUM& data, const void* umBuffer);
|
||||
HRESULT texBlt(const D3DDDIARG_TEXBLT& data);
|
||||
HRESULT texBlt1(const D3DDDIARG_TEXBLT1& data);
|
||||
HRESULT unlock(const D3DDDIARG_UNLOCK& data);
|
||||
@ -76,6 +78,8 @@ namespace D3dDdi
|
||||
std::map<std::pair<HANDLE, UINT>, Resource&> m_dirtyRenderTargets;
|
||||
std::map<std::pair<HANDLE, UINT>, Resource&> m_dirtyTextures;
|
||||
HANDLE m_sharedPrimary;
|
||||
D3DDDIARG_SETSTREAMSOURCE m_streamSourceData;
|
||||
Resource* m_streamSource;
|
||||
|
||||
static std::map<HANDLE, Device> s_devices;
|
||||
};
|
||||
|
@ -54,6 +54,8 @@ namespace D3dDdi
|
||||
vtable.pfnOpenResource = &DEVICE_FUNC(openResource);
|
||||
vtable.pfnPresent = &DEVICE_FUNC(present);
|
||||
vtable.pfnPresent1 = &DEVICE_FUNC(present1);
|
||||
vtable.pfnSetStreamSource = &DEVICE_FUNC(setStreamSource);
|
||||
vtable.pfnSetStreamSourceUm = &DEVICE_FUNC(setStreamSourceUm);
|
||||
vtable.pfnTexBlt = &DEVICE_FUNC(texBlt);
|
||||
vtable.pfnTexBlt1 = &DEVICE_FUNC(texBlt1);
|
||||
vtable.pfnUnlock = &DEVICE_FUNC(unlock);
|
||||
|
@ -88,6 +88,44 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATERESOURCE2& val)
|
||||
<< Compat::hex(val.Flags2.Value);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.PrimitiveType
|
||||
<< val.BaseVertexIndex
|
||||
<< val.MinIndex
|
||||
<< val.NumVertices
|
||||
<< val.StartIndex
|
||||
<< val.PrimitiveCount;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE2& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.PrimitiveType
|
||||
<< val.BaseVertexOffset
|
||||
<< val.MinIndex
|
||||
<< val.NumVertices
|
||||
<< val.StartIndexOffset
|
||||
<< val.PrimitiveCount;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWPRIMITIVE& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.PrimitiveType
|
||||
<< val.VStart
|
||||
<< val.PrimitiveCount;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWPRIMITIVE2& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.PrimitiveType
|
||||
<< val.FirstVertexOffset
|
||||
<< val.PrimitiveCount;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_LOCK& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
@ -152,6 +190,38 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_RENDERSTATE& val)
|
||||
<< val.Value;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETRENDERTARGET& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.RenderTargetIndex
|
||||
<< val.hRenderTarget
|
||||
<< val.SubResourceIndex;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETSTREAMSOURCE& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.Stream
|
||||
<< val.hVertexBuffer
|
||||
<< val.Offset
|
||||
<< val.Stride;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETSTREAMSOURCEUM& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.Stream
|
||||
<< val.Stride;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_TEXTURESTAGESTATE& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< val.Stage
|
||||
<< val.State
|
||||
<< val.Value;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_UNLOCK& val)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
|
@ -12,12 +12,20 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CLEAR& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_COLORFILL& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATERESOURCE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_CREATERESOURCE2& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWINDEXEDPRIMITIVE2& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWPRIMITIVE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_DRAWPRIMITIVE2& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_LOCK& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_OPENRESOURCE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_PRESENT& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_PRESENT1& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_PRESENTSURFACE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_RENDERSTATE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETRENDERTARGET& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETSTREAMSOURCE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETSTREAMSOURCEUM& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_TEXTURESTAGESTATE& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_UNLOCK& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_WINFO& val);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_ZRANGE& val);
|
||||
|
@ -334,6 +334,15 @@ namespace D3dDdi
|
||||
template <typename Arg>
|
||||
Resource Resource::create(Device& device, Arg& data, HRESULT(APIENTRY *createResourceFunc)(HANDLE, Arg*))
|
||||
{
|
||||
if (D3DDDIFMT_VERTEXDATA == data.Format &&
|
||||
data.Flags.VertexBuffer &&
|
||||
data.Flags.MightDrawFromLocked &&
|
||||
D3DDDIPOOL_SYSTEMMEM != data.Pool)
|
||||
{
|
||||
const HRESULT D3DERR_NOTAVAILABLE = 0x8876086A;
|
||||
throw HResultException(D3DERR_NOTAVAILABLE);
|
||||
}
|
||||
|
||||
Resource resource(device, data);
|
||||
Arg origData = data;
|
||||
fixResourceData(device, reinterpret_cast<D3DDDIARG_CREATERESOURCE&>(data));
|
||||
@ -371,6 +380,31 @@ namespace D3dDdi
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::fixVertexData(UINT offset, UINT count, UINT stride)
|
||||
{
|
||||
if (!m_fixedData.Flags.MightDrawFromLocked ||
|
||||
!m_fixedData.pSurfList[0].pSysMem ||
|
||||
!(m_fixedData.Fvf & D3DFVF_XYZRHW))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned char* data = static_cast<unsigned char*>(const_cast<void*>(m_fixedData.pSurfList[0].pSysMem)) + offset;
|
||||
if (0.0f != reinterpret_cast<D3DTLVERTEX*>(data)->rhw)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (UINT i = 0; i < count; ++i)
|
||||
{
|
||||
if (0.0f == reinterpret_cast<D3DTLVERTEX*>(data)->rhw)
|
||||
{
|
||||
reinterpret_cast<D3DTLVERTEX*>(data)->rhw = 1.0f;
|
||||
}
|
||||
data += stride;
|
||||
}
|
||||
}
|
||||
|
||||
void* Resource::getLockPtr(UINT subResourceIndex)
|
||||
{
|
||||
if (subResourceIndex < m_lockData.size())
|
||||
|
@ -28,6 +28,7 @@ namespace D3dDdi
|
||||
HRESULT blt(D3DDDIARG_BLT data);
|
||||
HRESULT colorFill(const D3DDDIARG_COLORFILL& data);
|
||||
void destroy();
|
||||
void fixVertexData(UINT offset, UINT count, UINT stride);
|
||||
void* getLockPtr(UINT subResourceIndex);
|
||||
HRESULT lock(D3DDDIARG_LOCK& data);
|
||||
void prepareForRendering(UINT subResourceIndex, bool isReadOnly);
|
||||
|
@ -198,6 +198,7 @@
|
||||
<ClInclude Include="Direct3d\Direct3dVertexBuffer.h" />
|
||||
<ClInclude Include="Direct3d\Direct3dViewport.h" />
|
||||
<ClInclude Include="Direct3d\Hooks.h" />
|
||||
<ClInclude Include="Direct3d\Log.h" />
|
||||
<ClInclude Include="Direct3d\Types.h" />
|
||||
<ClInclude Include="Direct3d\Visitors\Direct3dDeviceVtblVisitor.h" />
|
||||
<ClInclude Include="Direct3d\Visitors\Direct3dTextureVtblVisitor.h" />
|
||||
@ -265,6 +266,7 @@
|
||||
<ClCompile Include="Direct3d\Direct3dVertexBuffer.cpp" />
|
||||
<ClCompile Include="Direct3d\Direct3dViewport.cpp" />
|
||||
<ClCompile Include="Direct3d\Hooks.cpp" />
|
||||
<ClCompile Include="Direct3d\Log.cpp" />
|
||||
<ClCompile Include="Dll\Procs.cpp" />
|
||||
<ClCompile Include="Dll\DllMain.cpp" />
|
||||
<ClCompile Include="Dll\UnmodifiedProcs.cpp" />
|
||||
|
@ -354,6 +354,9 @@
|
||||
<ClInclude Include="D3dDdi\FormatInfo.h">
|
||||
<Filter>Header Files\D3dDdi</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Direct3d\Log.h">
|
||||
<Filter>Header Files\Direct3d</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -539,6 +542,9 @@
|
||||
<ClCompile Include="D3dDdi\FormatInfo.cpp">
|
||||
<Filter>Source Files\D3dDdi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Direct3d\Log.cpp">
|
||||
<Filter>Source Files\Direct3d</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Dll\DDrawCompat.def">
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/CompatVtable.h"
|
||||
#include "Direct3d/Visitors/Direct3dVtblVisitor.h"
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <Direct3d/Log.h>
|
||||
#include <Direct3d/Visitors/Direct3dVtblVisitor.h>
|
||||
|
||||
namespace Direct3d
|
||||
{
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/CompatVtable.h"
|
||||
#include "Direct3d/Visitors/Direct3dDeviceVtblVisitor.h"
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <Direct3d/Log.h>
|
||||
#include <Direct3d/Visitors/Direct3dDeviceVtblVisitor.h>
|
||||
|
||||
namespace Direct3d
|
||||
{
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/CompatVtable.h"
|
||||
#include "Direct3d/Visitors/Direct3dTextureVtblVisitor.h"
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <Direct3d/Log.h>
|
||||
#include <Direct3d/Visitors/Direct3dTextureVtblVisitor.h>
|
||||
|
||||
namespace Direct3d
|
||||
{
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/CompatVtable.h"
|
||||
#include "Direct3d/Visitors/Direct3dVertexBufferVtblVisitor.h"
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <Direct3d/Log.h>
|
||||
#include <Direct3d/Visitors/Direct3dVertexBufferVtblVisitor.h>
|
||||
|
||||
namespace Direct3d
|
||||
{
|
||||
|
@ -1,7 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "Common/CompatVtable.h"
|
||||
#include "Direct3d/Visitors/Direct3dViewportVtblVisitor.h"
|
||||
#include <Common/CompatVtable.h>
|
||||
#include <Direct3d/Log.h>
|
||||
#include <Direct3d/Visitors/Direct3dViewportVtblVisitor.h>
|
||||
|
||||
namespace Direct3d
|
||||
{
|
||||
|
26
DDrawCompat/Direct3d/Log.cpp
Normal file
26
DDrawCompat/Direct3d/Log.cpp
Normal file
@ -0,0 +1,26 @@
|
||||
#include <Direct3d/Log.h>
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDP_PTRSTRIDE& data)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< data.lpvData
|
||||
<< data.dwStride;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDRAWPRIMITIVESTRIDEDDATA& data)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< data.position
|
||||
<< data.normal
|
||||
<< data.diffuse
|
||||
<< data.specular
|
||||
<< Compat::array(data.textureCoords, D3DDP_MAXTEXCOORD);
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DVERTEXBUFFERDESC& data)
|
||||
{
|
||||
return Compat::LogStruct(os)
|
||||
<< Compat::hex(data.dwCaps)
|
||||
<< Compat::hex(data.dwFVF)
|
||||
<< data.dwNumVertices;
|
||||
}
|
9
DDrawCompat/Direct3d/Log.h
Normal file
9
DDrawCompat/Direct3d/Log.h
Normal file
@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <d3d.h>
|
||||
|
||||
#include <Common/Log.h>
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDP_PTRSTRIDE& data);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DDRAWPRIMITIVESTRIDEDDATA& data);
|
||||
std::ostream& operator<<(std::ostream& os, const D3DVERTEXBUFFERDESC& data);
|
Loading…
x
Reference in New Issue
Block a user