1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-15 06:04:49 +01:00

make clipper threadsafe for TA

This commit is contained in:
FunkyFr3sh 2024-05-27 05:01:54 +02:00
parent 009bc4e2e8
commit 103f78276b
3 changed files with 51 additions and 0 deletions

View File

@ -16,6 +16,7 @@ typedef struct IDirectDrawClipperImpl
ULONG ref; ULONG ref;
HWND hwnd; HWND hwnd;
HRGN region; HRGN region;
CRITICAL_SECTION cs;
} IDirectDrawClipperImpl; } IDirectDrawClipperImpl;

View File

@ -31,6 +31,8 @@ ULONG __stdcall IDirectDrawClipper__Release(IDirectDrawClipperImpl* This)
if (This->region) if (This->region)
DeleteObject(This->region); DeleteObject(This->region);
DeleteCriticalSection(&This->cs);
HeapFree(GetProcessHeap(), 0, This); HeapFree(GetProcessHeap(), 0, This);
} }

View File

@ -7,11 +7,19 @@
HRESULT ddc_GetClipList(IDirectDrawClipperImpl* This, LPRECT lpRect, LPRGNDATA lpClipList, LPDWORD lpdwSiz) HRESULT ddc_GetClipList(IDirectDrawClipperImpl* This, LPRECT lpRect, LPRGNDATA lpClipList, LPDWORD lpdwSiz)
{ {
EnterCriticalSection(&This->cs);
if (!This->region) if (!This->region)
{
LeaveCriticalSection(&This->cs);
return DDERR_NOCLIPLIST; return DDERR_NOCLIPLIST;
}
if (!lpdwSiz) if (!lpdwSiz)
{
LeaveCriticalSection(&This->cs);
return DDERR_INVALIDPARAMS; return DDERR_INVALIDPARAMS;
}
HRGN region = NULL; HRGN region = NULL;
@ -20,11 +28,16 @@ HRESULT ddc_GetClipList(IDirectDrawClipperImpl* This, LPRECT lpRect, LPRGNDATA l
region = CreateRectRgnIndirect(lpRect); region = CreateRectRgnIndirect(lpRect);
if (!region) if (!region)
{
LeaveCriticalSection(&This->cs);
return DDERR_INVALIDPARAMS; return DDERR_INVALIDPARAMS;
}
if (CombineRgn(region, This->region, region, RGN_AND) == ERROR) if (CombineRgn(region, This->region, region, RGN_AND) == ERROR)
{ {
DeleteObject(region); DeleteObject(region);
LeaveCriticalSection(&This->cs);
return DDERR_GENERIC; return DDERR_GENERIC;
} }
} }
@ -39,40 +52,64 @@ HRESULT ddc_GetClipList(IDirectDrawClipperImpl* This, LPRECT lpRect, LPRGNDATA l
DeleteObject(region); DeleteObject(region);
if (*lpdwSiz == 0) if (*lpdwSiz == 0)
{
LeaveCriticalSection(&This->cs);
return DDERR_REGIONTOOSMALL; return DDERR_REGIONTOOSMALL;
}
LeaveCriticalSection(&This->cs);
return DD_OK; return DD_OK;
} }
HRESULT ddc_GetHWnd(IDirectDrawClipperImpl* This, HWND FAR* lphWnd) HRESULT ddc_GetHWnd(IDirectDrawClipperImpl* This, HWND FAR* lphWnd)
{ {
EnterCriticalSection(&This->cs);
if (!lphWnd) if (!lphWnd)
{
LeaveCriticalSection(&This->cs);
return DDERR_INVALIDPARAMS; return DDERR_INVALIDPARAMS;
}
*lphWnd = This->hwnd; *lphWnd = This->hwnd;
LeaveCriticalSection(&This->cs);
return DD_OK; return DD_OK;
} }
HRESULT ddc_IsClipListChanged(IDirectDrawClipperImpl* This, BOOL FAR* lpbChanged) HRESULT ddc_IsClipListChanged(IDirectDrawClipperImpl* This, BOOL FAR* lpbChanged)
{ {
EnterCriticalSection(&This->cs);
if (!lpbChanged) if (!lpbChanged)
{
LeaveCriticalSection(&This->cs);
return DDERR_INVALIDPARAMS; return DDERR_INVALIDPARAMS;
}
*lpbChanged = FALSE; /* Always return FALSE - See ddc_SetHWnd for remarks */ *lpbChanged = FALSE; /* Always return FALSE - See ddc_SetHWnd for remarks */
LeaveCriticalSection(&This->cs);
return DD_OK; return DD_OK;
} }
HRESULT ddc_SetClipList(IDirectDrawClipperImpl* This, LPRGNDATA lpClipList, DWORD dwFlags) HRESULT ddc_SetClipList(IDirectDrawClipperImpl* This, LPRGNDATA lpClipList, DWORD dwFlags)
{ {
EnterCriticalSection(&This->cs);
if (This->hwnd) if (This->hwnd)
{
LeaveCriticalSection(&This->cs);
return DDERR_CLIPPERISUSINGHWND; return DDERR_CLIPPERISUSINGHWND;
}
if (lpClipList) if (lpClipList)
{ {
if (!lpClipList->rdh.nCount) if (!lpClipList->rdh.nCount)
{
LeaveCriticalSection(&This->cs);
return DDERR_INVALIDCLIPLIST; return DDERR_INVALIDCLIPLIST;
}
if (This->region) if (This->region)
DeleteObject(This->region); DeleteObject(This->region);
@ -82,14 +119,20 @@ HRESULT ddc_SetClipList(IDirectDrawClipperImpl* This, LPRGNDATA lpClipList, DWOR
This->region = CreateRectRgnIndirect(&rc[0]); This->region = CreateRectRgnIndirect(&rc[0]);
if (!This->region) if (!This->region)
{
LeaveCriticalSection(&This->cs);
return DDERR_INVALIDCLIPLIST; return DDERR_INVALIDCLIPLIST;
}
for (int i = 1; i < lpClipList->rdh.nCount; ++i) for (int i = 1; i < lpClipList->rdh.nCount; ++i)
{ {
HRGN region = CreateRectRgnIndirect(&rc[i]); HRGN region = CreateRectRgnIndirect(&rc[i]);
if (!region) if (!region)
{
LeaveCriticalSection(&This->cs);
return DDERR_INVALIDCLIPLIST; return DDERR_INVALIDCLIPLIST;
}
if (CombineRgn(This->region, region, This->region, RGN_OR) == ERROR) if (CombineRgn(This->region, region, This->region, RGN_OR) == ERROR)
{ {
@ -97,6 +140,7 @@ HRESULT ddc_SetClipList(IDirectDrawClipperImpl* This, LPRGNDATA lpClipList, DWOR
DeleteObject(This->region); DeleteObject(This->region);
This->region = NULL; This->region = NULL;
LeaveCriticalSection(&This->cs);
return DDERR_INVALIDCLIPLIST; return DDERR_INVALIDCLIPLIST;
} }
@ -111,17 +155,20 @@ HRESULT ddc_SetClipList(IDirectDrawClipperImpl* This, LPRGNDATA lpClipList, DWOR
This->region = NULL; This->region = NULL;
} }
LeaveCriticalSection(&This->cs);
return DD_OK; return DD_OK;
} }
HRESULT ddc_SetHWnd(IDirectDrawClipperImpl* This, DWORD dwFlags, HWND hWnd) HRESULT ddc_SetHWnd(IDirectDrawClipperImpl* This, DWORD dwFlags, HWND hWnd)
{ {
EnterCriticalSection(&This->cs);
/* /*
We don't use the regions from the hwnd here since everything is emulated and we need the entire We don't use the regions from the hwnd here since everything is emulated and we need the entire
emulated surface to be redrawn all the time emulated surface to be redrawn all the time
*/ */
This->hwnd = hWnd; This->hwnd = hWnd;
LeaveCriticalSection(&This->cs);
return DD_OK; return DD_OK;
} }
@ -137,6 +184,7 @@ HRESULT dd_CreateClipper(DWORD dwFlags, IDirectDrawClipperImpl** lplpDDClipper,
c->lpVtbl = &g_ddc_vtbl; c->lpVtbl = &g_ddc_vtbl;
IDirectDrawClipper_AddRef(c); IDirectDrawClipper_AddRef(c);
InitializeCriticalSection(&c->cs);
*lplpDDClipper = c; *lplpDDClipper = c;