1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-15 06:04:49 +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 str(s) #s
#define VERSION 1,2,0,2
#define VERSION 1,2,0,3
1 VERSIONINFO
FILEVERSION VERSION

View File

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

View File

@ -40,6 +40,7 @@ BOOL screenshot(struct IDirectDrawSurfaceImpl *);
extern HMODULE hD3D9;
extern D3DPRESENT_PARAMETERS D3dpp;
extern BOOL UseDirect3D9;
IDirectDrawImpl *ddraw = NULL;
@ -631,8 +632,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN);
D3dpp.Windowed = FALSE;
InterlockedExchange(&ddraw->resetDirect3D9, TRUE);
InterlockedExchange(&ddraw->minimized, FALSE);
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 */
if (!ddraw->windowed)
{
ShowWindow(ddraw->hWnd, SW_MINIMIZE);
if (!UseDirect3D9)
ShowWindow(ddraw->hWnd, SW_MINIMIZE);
ChangeDisplaySettings(&ddraw->mode, 0);
D3dpp.Windowed = TRUE;
InterlockedExchange(&ddraw->resetDirect3D9, TRUE);
InterlockedExchange(&ddraw->minimized, TRUE);
}
}
return 0;
@ -1254,8 +1255,8 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk
DWORD minor = (DWORD)(HIBYTE(LOWORD(version)));
LPDIRECT3D9 d3d = NULL;
// Win Vista/XP use Direct3D 9 - Win 7/8/10 and wine use OpenGL
if (!This->wine && (major < 6 || (major == 6 && minor == 0)) && (hD3D9 = LoadLibrary("d3d9.dll")))
// Win XP/Vista/7 use Direct3D 9 - Win 8/10 and wine use OpenGL
if (!This->wine && (major < 6 || (major == 6 && minor == 1)) && (hD3D9 = LoadLibrary("d3d9.dll")))
{
IDirect3D9 *(WINAPI *D3DCreate9)(UINT) =
(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;
D3DPRESENT_PARAMETERS D3dpp;
BOOL UseDirect3D9;
static LPDIRECT3D9 D3d;
static LPDIRECT3DDEVICE9 D3ddev;
static LPDIRECT3DVERTEXBUFFER9 D3dvb;
@ -22,10 +24,10 @@ static DWORD FrameLength;
static BOOL CreateDirect3D();
static BOOL CreateResources();
static void SetStates();
static BOOL SetStates();
static void UpdateVertices(BOOL inCutscene);
static BOOL Reset();
static void SetMaxFPS(int baseMaxFPS);
static void SetMaxFPS();
static void Render();
static BOOL ReleaseDirect3D();
@ -36,18 +38,17 @@ DWORD WINAPI render_d3d9_main(void)
{
Sleep(500);
BOOL useDirect3D = CreateDirect3D() && CreateResources();
if (useDirect3D)
UseDirect3D9 = CreateDirect3D();
if (UseDirect3D9)
{
SetMaxFPS(ddraw->render.maxfps);
SetStates();
SetMaxFPS();
Render();
}
ReleaseDirect3D();
if (!useDirect3D)
if (!UseDirect3D9)
{
ShowDriverWarning = TRUE;
ddraw->renderer = render_soft_main;
@ -76,8 +77,8 @@ static BOOL CreateDirect3D()
D3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
D3dpp.hDeviceWindow = ddraw->hWnd;
D3dpp.PresentationInterval = ddraw->vsync ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE;
D3dpp.BackBufferWidth = ddraw->render.width;
D3dpp.BackBufferHeight = ddraw->render.height;
D3dpp.BackBufferWidth = D3dpp.Windowed ? 0 : ddraw->render.width;
D3dpp.BackBufferHeight = D3dpp.Windowed ? 0 : ddraw->render.height;
D3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
D3dpp.BackBufferCount = 1;
@ -105,7 +106,7 @@ static BOOL CreateDirect3D()
}
}
return D3d && D3ddev;
return D3d && D3ddev && CreateResources() && SetStates();
}
static BOOL CreateResources()
@ -135,13 +136,15 @@ static BOOL CreateResources()
return SurfaceTex && PaletteTex && D3dvb && PixelShader;
}
static void SetStates()
static BOOL SetStates()
{
D3ddev->lpVtbl->SetFVF(D3ddev, D3DFVF_XYZRHW | D3DFVF_TEX1);
D3ddev->lpVtbl->SetStreamSource(D3ddev, 0, D3dvb, 0, sizeof(CUSTOMVERTEX));
D3ddev->lpVtbl->SetTexture(D3ddev, 0, (IDirect3DBaseTexture9 *)SurfaceTex);
D3ddev->lpVtbl->SetTexture(D3ddev, 1, (IDirect3DBaseTexture9 *)PaletteTex);
D3ddev->lpVtbl->SetPixelShader(D3ddev, PixelShader);
BOOL err = FALSE;
err = err || FAILED(D3ddev->lpVtbl->SetFVF(D3ddev, D3DFVF_XYZRHW | D3DFVF_TEX1));
err = err || FAILED(D3ddev->lpVtbl->SetStreamSource(D3ddev, 0, D3dvb, 0, sizeof(CUSTOMVERTEX)));
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 = {
ddraw->render.viewport.x,
@ -151,7 +154,9 @@ static void SetStates()
0.0f,
1.0f };
D3ddev->lpVtbl->SetViewport(D3ddev, &viewData);
err = err || FAILED(D3ddev->lpVtbl->SetViewport(D3ddev, &viewData));
return !err;
}
static void UpdateVertices(BOOL inCutscene)
@ -183,18 +188,19 @@ static void UpdateVertices(BOOL inCutscene)
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)))
{
SetStates();
return TRUE;
}
return SetStates();
return FALSE;
}
static void SetMaxFPS(int baseMaxFPS)
static void SetMaxFPS()
{
MaxFPS = baseMaxFPS;
MaxFPS = ddraw->render.maxfps;
if (MaxFPS < 0)
MaxFPS = ddraw->mode.dmDisplayFrequency;
@ -213,9 +219,19 @@ static void Render()
{
DWORD tick_start = 0;
DWORD tick_end = 0;
BOOL active = TRUE;
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
DrawFrameInfoStart();
#endif
@ -282,7 +298,14 @@ static void Render()
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();
}