http://bugs.winehq.org/show_bug.cgi?id=23621
Summary: DDraw surface reference counting doesn't match Windows (causes Recoil to fail) Product: Wine Version: unspecified Platform: x86 OS/Version: Linux Status: NEW Severity: normal Priority: P2 Component: directx-ddraw AssignedTo: wine-bugs@winehq.org ReportedBy: kazade@gmail.com
I just realized there is no bug report covering this issue.
DirectDraw surfaces (and other COM interfaces) maintain a reference count so that they are destroyed when they are no longer in use. The refcount is returned by the IUnknown_Release function. Unfortunately some games base logic on the value returned by IDirectDrawSurface_Release. Specifically they sometimes (wrongly) expect the return to be zero.
Something like:
if(IDirectDrawSurface_Release(surf)) { //Bail out }
We can test this by forcing DDS_Release to return zero. One game that is affected is Recoil which complains about not being to set the video mode.
The difference between Wine's implementation and the Windows implementation is Windows maintains a refcount for each surface interface version (1, 2, 3, 4 and 7) whereas Wine has one reference count across all versions. There are tests in dlls/ddraw/dsurface.c that confirm the Windows behaviour. To fix this issue the reference counting needs to be split, which requires a lot of changes (as versions 1, 2 and 3 all share the same thunks).