@@ -2252,6 +2252,13 @@ HRESULT m_IDirectDrawX::RestoreAllSurfaces()
22522252 // Check device status
22532253 if (hr == DD_OK || hr == DDERR_NOEXCLUSIVEMODE)
22542254 {
2255+ // Recreate device, if needed
2256+ if (!d3d9Device)
2257+ {
2258+ CreateD9Device (__FUNCTION__);
2259+ }
2260+
2261+ // Restore all surfaces
22552262 for (const auto & pDDraw : DDrawVector)
22562263 {
22572264 for (const auto & pSurface : pDDraw->SurfaceList )
@@ -2622,6 +2629,17 @@ void m_IDirectDrawX::ReleaseInterface()
26222629 DisplayMode.SetBy = Exclusive.SetBy ;
26232630 Device.IsWindowed = false ;
26242631 FullScreenWindowed = false ;
2632+
2633+ if (d3d9Device)
2634+ {
2635+ const HWND hWnd = GetHwnd ();
2636+ if (IsWindow (hWnd) && GetWindowThreadProcessId (hWnd, nullptr ) == GetCurrentThreadId ())
2637+ {
2638+ LOG_LIMIT (100 , __FUNCTION__ << " Warning: creating d3d9Device from ReleaseInterface()!" );
2639+
2640+ Exclusive.SetBy ->CreateD9Device (__FUNCTION__);
2641+ }
2642+ }
26252643 }
26262644
26272645 // Clear SetBy handles
@@ -3275,37 +3293,37 @@ HRESULT m_IDirectDrawX::ResetD9Device()
32753293 LOG_LIMIT (100 , __FUNCTION__ << " Error: Reset failed: " << (D3DERR)hr);
32763294 ReleaseAllD9Resources (false , false ); // Cannot backup surface after a failed Reset
32773295 ReleaseD9Device ();
3296+ return DDERR_GENERIC;
32783297 }
3279- else
3280- {
3281- CreationInterface = this ;
3282- IsDeviceLost = false ;
3283- WndProc::SwitchingResolution = false ;
3284- IsDeviceVerticesSet = false ;
3285- EnableWaitVsync = false ;
32863298
3287- // Copy GDI data to back buffer
3288- if (PrimarySurface && !presParams.Windowed )
3289- {
3290- PrimarySurface->CopyGDIToPrimaryAndBackbuffer ();
3291- }
3292- CopyGDISurface = false ;
3299+ CreationInterface = this ;
3300+ IsDeviceLost = false ;
3301+ WndProc::SwitchingResolution = false ;
3302+ IsDeviceVerticesSet = false ;
3303+ EnableWaitVsync = false ;
32933304
3294- // Create default state block
3295- GetDefaultStates ();
3305+ // Copy GDI data to back buffer
3306+ if (PrimarySurface && !presParams.Windowed )
3307+ {
3308+ PrimarySurface->CopyGDIToPrimaryAndBackbuffer ();
3309+ }
3310+ CopyGDISurface = false ;
32963311
3297- // Set render target
3298- SetCurrentRenderTarget ();
3312+ // Create default state block
3313+ GetDefaultStates ();
32993314
3300- // Reset D3D device settings
3301- RestoreD3DDeviceState ();
3302- }
3315+ // Set render target
3316+ SetCurrentRenderTarget ();
3317+
3318+ // Reset D3D device settings
3319+ RestoreD3DDeviceState ();
33033320 }
33043321 // Release and recreate device
33053322 else
33063323 {
33073324 ReleaseAllD9Resources (true , false );
33083325 ReleaseD9Device ();
3326+ return DDERR_GENERIC;
33093327 }
33103328
33113329 // Return
@@ -5464,6 +5482,8 @@ HRESULT m_IDirectDrawX::Present(RECT* pSourceRect, RECT* pDestRect)
54645482 presentTime = std::chrono::high_resolution_clock::now ();
54655483#endif
54665484
5485+ const HWND hWnd = GetHwnd ();
5486+
54675487 // Test cooperative level
54685488 if (hr == D3DERR_DEVICELOST)
54695489 {
@@ -5475,6 +5495,16 @@ HRESULT m_IDirectDrawX::Present(RECT* pSourceRect, RECT* pDestRect)
54755495 if (hr == D3DERR_DEVICENOTRESET)
54765496 {
54775497 hr = ResetD9Device ();
5498+
5499+ if (!d3d9Device)
5500+ {
5501+ if (IsWindow (hWnd) && GetWindowThreadProcessId (hWnd, nullptr ) == GetCurrentThreadId ())
5502+ {
5503+ LOG_LIMIT (100 , __FUNCTION__ << " Warning: creating d3d9Device from Present()!" );
5504+
5505+ hr = CreateD9Device (__FUNCTION__);
5506+ }
5507+ }
54785508 }
54795509
54805510 // Present failure
@@ -5485,7 +5515,6 @@ HRESULT m_IDirectDrawX::Present(RECT* pSourceRect, RECT* pDestRect)
54855515 }
54865516
54875517 // Redraw window if it has moved from its last location
5488- HWND hWnd = GetHwnd ();
54895518 RECT ClientRect = {};
54905519 if (ReDrawNextPresent || (presParams.Windowed && !ExclusiveMode && !IsIconic (hWnd) && GetWindowRect (hWnd, &ClientRect) && LastWindowRect.right > 0 && LastWindowRect.bottom > 0 ))
54915520 {
0 commit comments