1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-24 17:49:52 +01:00

stop drawing and release d3d9 on alt+tab

This commit is contained in:
FunkyFr3sh 2018-10-07 13:42:32 +02:00
parent 36c14bd857
commit 12655fa5a3
4 changed files with 57 additions and 32 deletions

View File

@ -2,7 +2,7 @@
#define vxstr(a,b,c,d) str(a##.##b##.##c##.##d) #define vxstr(a,b,c,d) str(a##.##b##.##c##.##d)
#define str(s) #s #define str(s) #s
#define VERSION 1,2,0,2 #define VERSION 1,2,0,3
1 VERSIONINFO 1 VERSIONINFO
FILEVERSION VERSION FILEVERSION VERSION

View File

@ -99,6 +99,7 @@ typedef struct IDirectDrawImpl
BOOL wine; BOOL wine;
int sleep; int sleep;
LONG resetDirect3D9; LONG resetDirect3D9;
LONG minimized;
} IDirectDrawImpl; } IDirectDrawImpl;

View File

@ -40,6 +40,7 @@ BOOL screenshot(struct IDirectDrawSurfaceImpl *);
extern HMODULE hD3D9; extern HMODULE hD3D9;
extern D3DPRESENT_PARAMETERS D3dpp; extern D3DPRESENT_PARAMETERS D3dpp;
extern BOOL UseDirect3D9;
IDirectDrawImpl *ddraw = NULL; IDirectDrawImpl *ddraw = NULL;
@ -631,8 +632,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN); ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN);
D3dpp.Windowed = FALSE; InterlockedExchange(&ddraw->minimized, FALSE);
InterlockedExchange(&ddraw->resetDirect3D9, TRUE);
if (wParam == WA_ACTIVE) if (wParam == WA_ACTIVE)
{ {
@ -650,11 +650,12 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
/* minimize our window on defocus when in fullscreen */ /* minimize our window on defocus when in fullscreen */
if (!ddraw->windowed) if (!ddraw->windowed)
{ {
ShowWindow(ddraw->hWnd, SW_MINIMIZE); if (!UseDirect3D9)
ShowWindow(ddraw->hWnd, SW_MINIMIZE);
ChangeDisplaySettings(&ddraw->mode, 0); ChangeDisplaySettings(&ddraw->mode, 0);
D3dpp.Windowed = TRUE; InterlockedExchange(&ddraw->minimized, TRUE);
InterlockedExchange(&ddraw->resetDirect3D9, TRUE);
} }
} }
return 0; return 0;
@ -1254,8 +1255,8 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk
DWORD minor = (DWORD)(HIBYTE(LOWORD(version))); DWORD minor = (DWORD)(HIBYTE(LOWORD(version)));
LPDIRECT3D9 d3d = NULL; LPDIRECT3D9 d3d = NULL;
// Win Vista/XP use Direct3D 9 - Win 7/8/10 and wine use OpenGL // Win XP/Vista/7 use Direct3D 9 - Win 8/10 and wine use OpenGL
if (!This->wine && (major < 6 || (major == 6 && minor == 0)) && (hD3D9 = LoadLibrary("d3d9.dll"))) if (!This->wine && (major < 6 || (major == 6 && minor == 1)) && (hD3D9 = LoadLibrary("d3d9.dll")))
{ {
IDirect3D9 *(WINAPI *D3DCreate9)(UINT) = IDirect3D9 *(WINAPI *D3DCreate9)(UINT) =
(IDirect3D9 *(WINAPI *)(UINT))GetProcAddress(hD3D9, "Direct3DCreate9"); (IDirect3D9 *(WINAPI *)(UINT))GetProcAddress(hD3D9, "Direct3DCreate9");

View File

@ -9,6 +9,8 @@ typedef struct CUSTOMVERTEX { float x, y, z, rhw, u, v; } CUSTOMVERTEX;
HMODULE hD3D9; HMODULE hD3D9;
D3DPRESENT_PARAMETERS D3dpp; D3DPRESENT_PARAMETERS D3dpp;
BOOL UseDirect3D9;
static LPDIRECT3D9 D3d; static LPDIRECT3D9 D3d;
static LPDIRECT3DDEVICE9 D3ddev; static LPDIRECT3DDEVICE9 D3ddev;
static LPDIRECT3DVERTEXBUFFER9 D3dvb; static LPDIRECT3DVERTEXBUFFER9 D3dvb;
@ -22,10 +24,10 @@ static DWORD FrameLength;
static BOOL CreateDirect3D(); static BOOL CreateDirect3D();
static BOOL CreateResources(); static BOOL CreateResources();
static void SetStates(); static BOOL SetStates();
static void UpdateVertices(BOOL inCutscene); static void UpdateVertices(BOOL inCutscene);
static BOOL Reset(); static BOOL Reset();
static void SetMaxFPS(int baseMaxFPS); static void SetMaxFPS();
static void Render(); static void Render();
static BOOL ReleaseDirect3D(); static BOOL ReleaseDirect3D();
@ -36,18 +38,17 @@ DWORD WINAPI render_d3d9_main(void)
{ {
Sleep(500); Sleep(500);
BOOL useDirect3D = CreateDirect3D() && CreateResources(); UseDirect3D9 = CreateDirect3D();
if (useDirect3D) if (UseDirect3D9)
{ {
SetMaxFPS(ddraw->render.maxfps); SetMaxFPS();
SetStates();
Render(); Render();
} }
ReleaseDirect3D(); ReleaseDirect3D();
if (!useDirect3D) if (!UseDirect3D9)
{ {
ShowDriverWarning = TRUE; ShowDriverWarning = TRUE;
ddraw->renderer = render_soft_main; ddraw->renderer = render_soft_main;
@ -76,8 +77,8 @@ static BOOL CreateDirect3D()
D3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; D3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
D3dpp.hDeviceWindow = ddraw->hWnd; D3dpp.hDeviceWindow = ddraw->hWnd;
D3dpp.PresentationInterval = ddraw->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; D3dpp.PresentationInterval = ddraw->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
D3dpp.BackBufferWidth = ddraw->render.width; D3dpp.BackBufferWidth = D3dpp.Windowed ? 0 : ddraw->render.width;
D3dpp.BackBufferHeight = ddraw->render.height; D3dpp.BackBufferHeight = D3dpp.Windowed ? 0 : ddraw->render.height;
D3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; D3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
D3dpp.BackBufferCount = 1; D3dpp.BackBufferCount = 1;
@ -105,7 +106,7 @@ static BOOL CreateDirect3D()
} }
} }
return D3d && D3ddev; return D3d && D3ddev && CreateResources() && SetStates();
} }
static BOOL CreateResources() static BOOL CreateResources()
@ -135,13 +136,15 @@ static BOOL CreateResources()
return SurfaceTex && PaletteTex && D3dvb && PixelShader; return SurfaceTex && PaletteTex && D3dvb && PixelShader;
} }
static void SetStates() static BOOL SetStates()
{ {
D3ddev->lpVtbl->SetFVF(D3ddev, D3DFVF_XYZRHW | D3DFVF_TEX1); BOOL err = FALSE;
D3ddev->lpVtbl->SetStreamSource(D3ddev, 0, D3dvb, 0, sizeof(CUSTOMVERTEX));
D3ddev->lpVtbl->SetTexture(D3ddev, 0, (IDirect3DBaseTexture9 *)SurfaceTex); err = err || FAILED(D3ddev->lpVtbl->SetFVF(D3ddev, D3DFVF_XYZRHW | D3DFVF_TEX1));
D3ddev->lpVtbl->SetTexture(D3ddev, 1, (IDirect3DBaseTexture9 *)PaletteTex); err = err || FAILED(D3ddev->lpVtbl->SetStreamSource(D3ddev, 0, D3dvb, 0, sizeof(CUSTOMVERTEX)));
D3ddev->lpVtbl->SetPixelShader(D3ddev, PixelShader); err = err || FAILED(D3ddev->lpVtbl->SetTexture(D3ddev, 0, (IDirect3DBaseTexture9 *)SurfaceTex));
err = err || FAILED(D3ddev->lpVtbl->SetTexture(D3ddev, 1, (IDirect3DBaseTexture9 *)PaletteTex));
err = err || FAILED(D3ddev->lpVtbl->SetPixelShader(D3ddev, PixelShader));
D3DVIEWPORT9 viewData = { D3DVIEWPORT9 viewData = {
ddraw->render.viewport.x, ddraw->render.viewport.x,
@ -151,7 +154,9 @@ static void SetStates()
0.0f, 0.0f,
1.0f }; 1.0f };
D3ddev->lpVtbl->SetViewport(D3ddev, &viewData); err = err || FAILED(D3ddev->lpVtbl->SetViewport(D3ddev, &viewData));
return !err;
} }
static void UpdateVertices(BOOL inCutscene) static void UpdateVertices(BOOL inCutscene)
@ -183,18 +188,19 @@ static void UpdateVertices(BOOL inCutscene)
static BOOL Reset() static BOOL Reset()
{ {
D3dpp.BackBufferWidth = D3dpp.Windowed ? 0 : ddraw->render.width;
D3dpp.BackBufferHeight = D3dpp.Windowed ? 0 : ddraw->render.height;
D3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
if (SUCCEEDED(D3ddev->lpVtbl->Reset(D3ddev, &D3dpp))) if (SUCCEEDED(D3ddev->lpVtbl->Reset(D3ddev, &D3dpp)))
{ return SetStates();
SetStates();
return TRUE;
}
return FALSE; return FALSE;
} }
static void SetMaxFPS(int baseMaxFPS) static void SetMaxFPS()
{ {
MaxFPS = baseMaxFPS; MaxFPS = ddraw->render.maxfps;
if (MaxFPS < 0) if (MaxFPS < 0)
MaxFPS = ddraw->mode.dmDisplayFrequency; MaxFPS = ddraw->mode.dmDisplayFrequency;
@ -213,9 +219,19 @@ static void Render()
{ {
DWORD tick_start = 0; DWORD tick_start = 0;
DWORD tick_end = 0; DWORD tick_end = 0;
BOOL active = TRUE;
while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, 200) != WAIT_FAILED) while (ddraw->render.run && WaitForSingleObject(ddraw->render.sem, 200) != WAIT_FAILED)
{ {
if (!active)
{
if (!InterlockedExchangeAdd(&ddraw->minimized, 0) && CreateDirect3D())
active = TRUE;
Sleep(500);
continue;
}
#if _DEBUG #if _DEBUG
DrawFrameInfoStart(); DrawFrameInfoStart();
#endif #endif
@ -282,7 +298,14 @@ static void Render()
HRESULT hr = D3ddev->lpVtbl->TestCooperativeLevel(D3ddev); HRESULT hr = D3ddev->lpVtbl->TestCooperativeLevel(D3ddev);
if (InterlockedExchange(&ddraw->resetDirect3D9, FALSE)) if (InterlockedExchangeAdd(&ddraw->minimized, 0))
{
active = FALSE;
ReleaseDirect3D();
Sleep(200);
ShowWindow(ddraw->hWnd, SW_SHOWMINNOACTIVE);
}
else if (InterlockedExchange(&ddraw->resetDirect3D9, FALSE))
{ {
Reset(); Reset();
} }