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