diff --git a/build/win32/Cxbx.vcxproj b/build/win32/Cxbx.vcxproj
index 322a89925..94b4394ee 100644
--- a/build/win32/Cxbx.vcxproj
+++ b/build/win32/Cxbx.vcxproj
@@ -179,9 +179,9 @@
Include\Win32\Cxbx;%(AdditionalIncludeDirectories)
- legacy_stdio_definitions.lib;d3d8.lib;dinput8.lib;dxguid.lib;odbc32.lib;odbccp32.lib;Shlwapi.lib;dxerr8.lib;ws2_32.lib;dsound.lib;winmm.lib;ddraw.lib;d3dx8.lib;dbghelp.lib;comctl32.lib;XINPUT9_1_0.LIB;%(AdditionalDependencies)
+ legacy_stdio_definitions.lib;d3d9.lib;dinput8.lib;dxguid.lib;odbc32.lib;odbccp32.lib;Shlwapi.lib;dxerr9.lib;ws2_32.lib;dsound.lib;winmm.lib;ddraw.lib;d3dx9.lib;dbghelp.lib;comctl32.lib;XINPUT9_1_0.LIB;%(AdditionalDependencies)
true
- $(Configuration)\;..\..\import\distorm\lib\Win32\;..\..\import\glew-2.0.0\lib\Release\Win32\;%(AdditionalLibraryDirectories)
+ $(Configuration)\;..\..\import\distorm\lib\Win32\;..\..\import\glew-2.0.0\lib\Release\Win32\;..\..\import\DirectX9\lib\;%(AdditionalLibraryDirectories)
libcmt;%(IgnoreSpecificDefaultLibraries)
true
true
@@ -740,6 +740,9 @@
+
+ {b8d9afc2-b38f-4714-846d-8a2754f076c9}
+
{cd2dde93-b45e-4d11-876d-d0056c3dd407}
diff --git a/build/win32/Cxbx.vcxproj.filters b/build/win32/Cxbx.vcxproj.filters
index 7c335b606..d5b56ec69 100644
--- a/build/win32/Cxbx.vcxproj.filters
+++ b/build/win32/Cxbx.vcxproj.filters
@@ -571,7 +571,6 @@
Emulator
-
diff --git a/import/DirectX9/include/dxerr9.h b/import/DirectX9/include/dxerr9.h
new file mode 100644
index 000000000..3fc6fba30
--- /dev/null
+++ b/import/DirectX9/include/dxerr9.h
@@ -0,0 +1,100 @@
+/*==========================================================================;
+ *
+ *
+ * File: dxerr9.h
+ * Content: DirectX Error Library Include File
+ *
+ ****************************************************************************/
+
+#ifndef _DXERR9_H_
+#define _DXERR9_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif //__cplusplus
+
+//
+// DXGetErrorString9
+//
+// Desc: Converts a DirectX 9 or earlier HRESULT to a string
+//
+// Args: HRESULT hr Can be any error code from
+// D3D9 D3DX9 D3D8 D3DX8 DDRAW DPLAY8 DMUSIC DSOUND DINPUT DSHOW
+//
+// Return: Converted string
+//
+const char* WINAPI DXGetErrorString9A(HRESULT hr);
+const WCHAR* WINAPI DXGetErrorString9W(HRESULT hr);
+
+#ifdef UNICODE
+#define DXGetErrorString9 DXGetErrorString9W
+#else
+#define DXGetErrorString9 DXGetErrorString9A
+#endif
+
+
+//
+// DXGetErrorDescription9
+//
+// Desc: Returns a string description of a DirectX 9 or earlier HRESULT
+//
+// Args: HRESULT hr Can be any error code from
+// D3D9 D3DX9 D3D8 D3DX8 DDRAW DPLAY8 DMUSIC DSOUND DINPUT DSHOW
+//
+// Return: String description
+//
+const char* WINAPI DXGetErrorDescription9A(HRESULT hr);
+const WCHAR* WINAPI DXGetErrorDescription9W(HRESULT hr);
+
+#ifdef UNICODE
+ #define DXGetErrorDescription9 DXGetErrorDescription9W
+#else
+ #define DXGetErrorDescription9 DXGetErrorDescription9A
+#endif
+
+
+//
+// DXTrace
+//
+// Desc: Outputs a formatted error message to the debug stream
+//
+// Args: CHAR* strFile The current file, typically passed in using the
+// __FILE__ macro.
+// DWORD dwLine The current line number, typically passed in using the
+// __LINE__ macro.
+// HRESULT hr An HRESULT that will be traced to the debug stream.
+// CHAR* strMsg A string that will be traced to the debug stream (may be NULL)
+// BOOL bPopMsgBox If TRUE, then a message box will popup also containing the passed info.
+//
+// Return: The hr that was passed in.
+//
+HRESULT WINAPI DXTraceA( const char* strFile, DWORD dwLine, HRESULT hr, const char* strMsg, BOOL bPopMsgBox );
+HRESULT WINAPI DXTraceW( const char* strFile, DWORD dwLine, HRESULT hr, const WCHAR* strMsg, BOOL bPopMsgBox );
+
+#ifdef UNICODE
+#define DXTrace DXTraceW
+#else
+#define DXTrace DXTraceA
+#endif
+
+
+//
+// Helper macros
+//
+#if defined(DEBUG) | defined(_DEBUG)
+#define DXTRACE_MSG(str) DXTrace( __FILE__, (DWORD)__LINE__, 0, str, FALSE )
+#define DXTRACE_ERR(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, FALSE )
+#define DXTRACE_ERR_MSGBOX(str,hr) DXTrace( __FILE__, (DWORD)__LINE__, hr, str, TRUE )
+#else
+#define DXTRACE_MSG(str) (0L)
+#define DXTRACE_ERR(str,hr) (hr)
+#define DXTRACE_ERR_MSGBOX(str,hr) (hr)
+#endif
+
+
+#ifdef __cplusplus
+}
+#endif //__cplusplus
+
+#endif // _DXERR9_H_
+
diff --git a/import/DirectX9/lib/DxErr9.lib b/import/DirectX9/lib/DxErr9.lib
new file mode 100644
index 000000000..b08af851e
Binary files /dev/null and b/import/DirectX9/lib/DxErr9.lib differ
diff --git a/import/DirectX9/lib/d3dx9.lib b/import/DirectX9/lib/d3dx9.lib
new file mode 100644
index 000000000..b2397bcbd
Binary files /dev/null and b/import/DirectX9/lib/d3dx9.lib differ
diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp
index c4e10b239..a26f541c6 100644
--- a/src/CxbxKrnl/EmuD3D8.cpp
+++ b/src/CxbxKrnl/EmuD3D8.cpp
@@ -130,7 +130,7 @@ struct {
// D3D based variables
static GUID g_ddguid; // DirectDraw driver GUID
static XTL::IDirect3D *g_pDirect3D = nullptr;
-static XTL::D3DCAPS g_D3DCaps = {}; // Direct3D Caps
+XTL::D3DCAPS g_D3DCaps = {}; // Direct3D Caps
// wireframe toggle
static int g_iWireframe = 0;
@@ -1971,6 +1971,10 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID)
// NOTE: It is possible to fix multisampling by having the host backbuffer normal size, the Xbox backbuffer being multisamples
// and scaling that way, but that can be done as a future PR
g_EmuCDPD.HostPresentationParameters.MultiSampleType = XTL::D3DMULTISAMPLE_NONE;
+#ifdef CXBX_USE_D3D9
+ g_EmuCDPD.HostPresentationParameters.MultiSampleQuality = 0;
+#endif
+
/*
if(g_EmuCDPD.XboxPresentationParameters.MultiSampleType != 0) {
// TODO: Check card for multisampling abilities
@@ -2056,17 +2060,22 @@ static DWORD WINAPI EmuCreateDeviceProxy(LPVOID)
// Dxbx addition : Prevent Direct3D from changing the FPU Control word :
g_EmuCDPD.BehaviorFlags |= D3DCREATE_FPU_PRESERVE;
- // Address debug DirectX runtime warning in _DEBUG builds
// Direct3D8: (WARN) :Device that was created without D3DCREATE_MULTITHREADED is being used by a thread other than the creation thread.
- #ifdef _DEBUG
- g_EmuCDPD.BehaviorFlags |= D3DCREATE_MULTITHREADED;
- #endif
+ g_EmuCDPD.BehaviorFlags |= D3DCREATE_MULTITHREADED;
// For some reason, D3DFMT_D16_LOCKABLE as the AudoDepthStencil causes CreateDevice to fail...
+ g_EmuCDPD.HostPresentationParameters.EnableAutoDepthStencil = TRUE;
if (g_EmuCDPD.HostPresentationParameters.AutoDepthStencilFormat == XTL::D3DFMT_D16_LOCKABLE) {
g_EmuCDPD.HostPresentationParameters.AutoDepthStencilFormat = XTL::D3DFMT_D16;
}
+ // DirectX9 doesn't support 0 as a swap effect
+#ifdef CXBX_USE_D3D9
+ if (g_EmuCDPD.HostPresentationParameters.SwapEffect == 0) {
+ g_EmuCDPD.HostPresentationParameters.SwapEffect = XTL::D3DSWAPEFFECT_DISCARD;
+ }
+#endif
+
// redirect to windows Direct3D
g_EmuCDPD.hRet = g_pDirect3D->CreateDevice(
g_EmuCDPD.Adapter,
@@ -2968,9 +2977,15 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader)
if(VshHandleIsVertexShader(Handle))
{
+ #ifndef CXBX_USE_D3D9
+
CxbxVertexShader *pVertexShader = MapXboxVertexShaderHandleToCxbxVertexShader(Handle);
hRet = g_pD3DDevice->SetVertexShader(pVertexShader->Handle);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader(VshHandleIsVertexShader)");
+ #else
+ hRet = D3D_OK;
+ EmuWarning("SetVertexShader (non-FVF) unimplemented for D3D9");
+ #endif
}
else if(Handle == NULL)
{
@@ -2988,8 +3003,13 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SelectVertexShader)
if(pVertexShader != NULL)
{
+#ifndef CXBX_USE_D3D9
hRet = g_pD3DDevice->SetVertexShader(((CxbxVertexShader *)((X_D3DVertexShader *)g_VertexShaderSlots[Address])->Handle)->Handle);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader(pVertexShader)");
+#else
+ hRet = D3D_OK;
+ EmuWarning("SetVertexShader (non-FVF) unimplemented for D3D9");
+#endif
}
else
{
@@ -3471,6 +3491,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader)
DWORD Usage
)
{
+#ifndef CXBX_USE_D3D9
FUNC_EXPORTS
LOG_FUNC_BEGIN
@@ -3555,10 +3576,16 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader)
{
hRet = g_pD3DDevice->CreateVertexShader
(
+#ifndef CXBX_USE_D3D9
pRecompiledDeclaration,
+#endif
pRecompiledFunction,
- &Handle,
- g_dwVertexShaderUsage // TODO: HACK: Xbox has extensions!
+#ifdef CXBX_USE_D3D9
+ (IDirect3DVertexShader9**)&Handle
+#else
+ &Handle,
+ g_dwVertexShaderUsage // TODO: HACK: Xbox has extensions!
+#endif
);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateVertexShader");
@@ -3589,11 +3616,17 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader)
hRet = g_pD3DDevice->CreateVertexShader
(
- pRecompiledDeclaration,
- (DWORD*)pRecompiledBuffer->GetBufferPointer(),
- &Handle,
- g_dwVertexShaderUsage
- );
+#ifndef CXBX_USE_D3D9
+ pRecompiledDeclaration,
+#endif
+ (DWORD*)pRecompiledBuffer->GetBufferPointer(),
+#ifdef CXBX_USE_D3D9
+ (IDirect3DVertexShader9**)&Handle
+#else
+ &Handle,
+ g_dwVertexShaderUsage // TODO: HACK: Xbox has extensions!
+#endif
+ );
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateVertexShader(fallback)");
}
//*/
@@ -3661,6 +3694,9 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateVertexShader)
return hRet;
+#else
+ return D3D_OK;
+#endif
}
// LTCG specific D3DDevice_SetVertexShaderConstant function...
@@ -5044,7 +5080,7 @@ void CreateHostResource(XTL::X_D3DResource *pResource, DWORD D3DUsage, int iText
true, // Lockable
&pNewHostSurface
#ifdef CXBX_USE_D3D9
- , nullptr, // pSharedHandle
+ , nullptr // pSharedHandle
#endif
);
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->CreateRenderTarget");
@@ -6983,7 +7019,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShader)
HRESULT hRet = D3D_OK;
g_CurrentXboxVertexShaderHandle = Handle;
-
// Store viewport offset and scale in constant registers 58 (c-38) and
// 59 (c-37) used for screen space transformation.
if(g_VertexShaderConstantMode != X_D3DSCM_NORESERVEDCONSTANTS)
@@ -7003,6 +7038,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShader)
#endif
}
+#ifndef CXBX_USE_D3D9
DWORD HostVertexShaderHandle;
if(VshHandleIsVertexShader(Handle))
{
@@ -7055,12 +7091,22 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_SetVertexShader)
// TODO : Instead of changing the FVF here, see if (and which) users need to be updated.
}
}
-
-#ifdef CXBX_USE_D3D9
- hRet = g_pD3DDevice->SetVertexShader(nullptr);
- hRet = g_pD3DDevice->SetFVF(HostVertexShaderHandle);
-#else
hRet = g_pD3DDevice->SetVertexShader(HostVertexShaderHandle);
+#else
+ if (VshHandleIsVertexShader(Handle)) {
+#ifndef CXBX_USE_D3D9
+
+ CxbxVertexShader *pVertexShader = MapXboxVertexShaderHandleToCxbxVertexShader(Handle);
+ hRet = g_pD3DDevice->SetVertexShader(pVertexShader->Handle);
+ DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader(VshHandleIsVertexShader)");
+#else
+ hRet = D3D_OK;
+ EmuWarning("SetVertexShader (non-FVF) unimplemented for D3D9");
+#endif
+ } else {
+ hRet = g_pD3DDevice->SetVertexShader(nullptr);
+ hRet = g_pD3DDevice->SetFVF(Handle);
+ }
#endif
DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader");
}
@@ -8354,6 +8400,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_DeleteVertexShader)
DWORD Handle
)
{
+#ifndef CXBX_USE_D3D9
FUNC_EXPORTS
LOG_FUNC_ONE_ARG(Handle);
@@ -8383,7 +8430,8 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_DeleteVertexShader)
}
HRESULT hRet = g_pD3DDevice->DeleteVertexShader(HostVertexShaderHandle);
- DEBUG_D3DRESULT(hRet, "g_pD3DDevice->DeleteVertexShader");
+ DEBUG_D3DRESULT(hRet, "g_pD3DDevice->DeleteVertexShader");
+#endif
}
// ******************************************************************
@@ -8451,6 +8499,7 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderConstant)
DWORD ConstantCount
)
{
+#ifndef CXBX_USE_D3D9
FUNC_EXPORTS
LOG_FUNC_BEGIN
@@ -8466,7 +8515,8 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_GetVertexShaderConstant)
ConstantCount
);
- DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetVertexShaderConstant");
+ DEBUG_D3DRESULT(hRet, "g_pD3DDevice->GetVertexShaderConstant");
+#endif
}
// ******************************************************************
diff --git a/src/CxbxKrnl/EmuD3D8/PixelShader.cpp b/src/CxbxKrnl/EmuD3D8/PixelShader.cpp
index 9818d79c8..dbc230b18 100644
--- a/src/CxbxKrnl/EmuD3D8/PixelShader.cpp
+++ b/src/CxbxKrnl/EmuD3D8/PixelShader.cpp
@@ -4220,7 +4220,11 @@ static const
/*pDefines=*/nullptr,
/*pInclude=*/nullptr,
#endif
- /*Flags=*/D3DXASM_SKIPVALIDATION,
+#ifndef CXBX_USE_D3D9
+ /*Flags=*/D3DXASM_SKIPVALIDATION,
+#else
+ /*Flags=*/0,
+#endif
#ifndef CXBX_USE_D3D9
/*ppConstants=*/NULL,
#endif
diff --git a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp
index 718781dae..2626a7da7 100755
--- a/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp
+++ b/src/CxbxKrnl/EmuD3D8/VertexBuffer.cpp
@@ -990,7 +990,11 @@ VOID XTL::EmuFlushIVB()
CxbxDrawPrimitiveUP(DrawContext);
if (bFVF) {
- hRet = g_pD3DDevice->SetVertexShader(g_CurrentXboxVertexShaderHandle);
+#ifdef CXBX_USE_D3D9
+ hRet = g_pD3DDevice->SetFVF(g_CurrentXboxVertexShaderHandle);
+#else
+ hRet = g_pD3DDevice->SetVertexShader(g_CurrentXboxVertexShaderHandle);
+#endif
//DEBUG_D3DRESULT(hRet, "g_pD3DDevice->SetVertexShader");
}
g_InlineVertexBuffer_TableOffset = 0; // Might not be needed (also cleared in D3DDevice_Begin)
diff --git a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp
index 5cf956acf..fb619e217 100644
--- a/src/CxbxKrnl/EmuD3D8/VertexShader.cpp
+++ b/src/CxbxKrnl/EmuD3D8/VertexShader.cpp
@@ -2394,6 +2394,7 @@ extern HRESULT XTL::EmuRecompileVshFunction
DWORD *pRecompiledDeclaration
)
{
+#ifndef CXBX_USE_D3D9
VSH_SHADER_HEADER *pShaderHeader = (VSH_SHADER_HEADER*)pFunction;
DWORD *pToken;
boolean EOI = false;
@@ -2506,10 +2507,9 @@ extern HRESULT XTL::EmuRecompileVshFunction
}
else
{
-
hRet = D3DXAssembleShader(pShaderDisassembly,
strlen(pShaderDisassembly),
- D3DXASM_SKIPVALIDATION,
+ D3DXASM_SKIPVALIDATION,
NULL,
ppRecompiled,
&pErrors);
@@ -2530,6 +2530,9 @@ extern HRESULT XTL::EmuRecompileVshFunction
free(pShader);
return hRet;
+#else
+ return D3D_OK;
+#endif
}
extern void XTL::FreeVertexDynamicPatch(CxbxVertexShader *pVertexShader)
@@ -2540,6 +2543,7 @@ extern void XTL::FreeVertexDynamicPatch(CxbxVertexShader *pVertexShader)
// Checks for failed vertex shaders, and shaders that would need patching
boolean VshHandleIsValidShader(DWORD Handle)
{
+#ifndef CXBX_USE_D3D9
//printf( "VS = 0x%.08X\n", Handle );
XTL::CxbxVertexShader *pVertexShader = XTL::MapXboxVertexShaderHandleToCxbxVertexShader(Handle);
@@ -2560,6 +2564,7 @@ boolean VshHandleIsValidShader(DWORD Handle)
}
*/
}
+#endif
return TRUE;
}
diff --git a/src/CxbxKrnl/EmuD3D8Types.h b/src/CxbxKrnl/EmuD3D8Types.h
index e15bfb728..cd138e93c 100755
--- a/src/CxbxKrnl/EmuD3D8Types.h
+++ b/src/CxbxKrnl/EmuD3D8Types.h
@@ -48,8 +48,8 @@
#include // for D3DXVECTOR4, etc
#include
-#include
-#pragma comment(lib, "dxerr.lib") // See https://blogs.msdn.microsoft.com/chuckw/2012/04/24/wheres-dxerr-lib/
+#include
+//#pragma comment(lib, "dxerr.lib") // See https://blogs.msdn.microsoft.com/chuckw/2012/04/24/wheres-dxerr-lib/
// If the above doesn't compile, install the June 2010 DirectX SDK
// from https://www.microsoft.com/en-us/download/details.aspx?id=6812
@@ -66,8 +66,10 @@
#define D3DENUM_NO_WHQL_LEVEL 0 // default in Direct3D 9
// Alias all host Direct3D 9 symbols to generic symbols
+#define DXGetErrorString DXGetErrorString9A
+#define DXGetErrorDescription DXGetErrorDescription9A
#define Direct3DCreate Direct3DCreate9
-#define D3DXAssembleShader D3DXCompileShader
+#define D3DXAssembleShader D3DXAssembleShader
#define FullScreen_PresentationInterval PresentationInterval // a field in D3DPRESENT_PARAMETERS
#define D3DLockData void
#define PixelShaderConstantType float