[PATCH 1/3] ddraw: Thunk to surface1, not surface7 in blt (v2).

Stefan Dösinger stefan at codeweavers.com
Tue Aug 11 06:50:42 CDT 2020


This patch series makes FRAPS work with ddraw games. It hooks only version 1
methods of blt, unlock and flip to detect a front buffer modification.

Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>

---

Version 2: Add a comment explaining why we thunk to ddraw1.

In the past FRAPS wouldn't work in Wine because it assumed that the offset
of the hooked functions inside the library is the same in every process.
This wasn't the case when we used Linux .so's, but it now works with PE
builds of the d3d frontend DLLs.

d3d8 is already working. For d3d9, FRAPS hooks D3DPERF_*. It happens to
work as-is with my build, but I have a patch in my tree that adds
DECLSPEC_HOTPATCH to those. Unfortunately this nowadays runs into bug
47633, so we won't be able to upstream it anytime soon. That means using
fraps with a d3d9 game puts you at the mercy of your compiler.
---
 dlls/ddraw/surface.c | 68 ++++++++++++++++++--------------------------
 1 file changed, 27 insertions(+), 41 deletions(-)

diff --git a/dlls/ddraw/surface.c b/dlls/ddraw/surface.c
index a5f032eabfc..22bebffce64 100644
--- a/dlls/ddraw/surface.c
+++ b/dlls/ddraw/surface.c
@@ -1635,27 +1635,13 @@ static HRESULT ddraw_surface_blt_clipped(struct ddraw_surface *dst_surface, cons
     return hr;
 }
 
-/*****************************************************************************
- * IDirectDrawSurface7::Blt
- *
- * Performs a blit on the surface
- *
- * Params:
- *  DestRect: Destination rectangle, can be NULL
- *  SrcSurface: Source surface, can be NULL
- *  SrcRect: Source rectangle, can be NULL
- *  Flags: Blt flags
- *  DDBltFx: Some extended blt parameters, connected to the flags
- *
- * Returns:
- *  D3D_OK on success, error code otherwise.
- *
- *****************************************************************************/
-static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Blt(IDirectDrawSurface7 *iface, RECT *dst_rect,
-        IDirectDrawSurface7 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
+/* FRAPS hooks IDirectDrawSurface::Blt and expects the version 1 method to be called when the
+ * game uses later interfaces. */
+static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Blt(IDirectDrawSurface *iface, RECT *dst_rect,
+        IDirectDrawSurface *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
 {
-    struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface7(iface);
-    struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface7(src_surface);
+    struct ddraw_surface *dst_impl = impl_from_IDirectDrawSurface(iface);
+    struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface(src_surface);
     struct wined3d_blt_fx wined3d_fx;
     DWORD unsupported_flags;
     DWORD fill_colour = 0;
@@ -1834,6 +1820,19 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Blt(IDirectDrawSurface7 *
     }
 }
 
+static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface7_Blt(IDirectDrawSurface7 *iface, RECT *dst_rect,
+        IDirectDrawSurface7 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
+{
+    struct ddraw_surface *dst = impl_from_IDirectDrawSurface7(iface);
+    struct ddraw_surface *src = unsafe_impl_from_IDirectDrawSurface7(src_surface);
+
+    TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
+            iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
+
+    return ddraw_surface1_Blt(&dst->IDirectDrawSurface_iface, dst_rect,
+            src ? &src->IDirectDrawSurface_iface : NULL, src_rect, flags, fx);
+}
+
 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface4_Blt(IDirectDrawSurface4 *iface, RECT *dst_rect,
         IDirectDrawSurface4 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
 {
@@ -1843,47 +1842,34 @@ static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface4_Blt(IDirectDrawSurface4 *
     TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
             iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
 
-    return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
-            src ? &src->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
+    return ddraw_surface1_Blt(&dst->IDirectDrawSurface_iface, dst_rect,
+            src ? &src->IDirectDrawSurface_iface : NULL, src_rect, flags, fx);
 }
 
 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface3_Blt(IDirectDrawSurface3 *iface, RECT *dst_rect,
         IDirectDrawSurface3 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
 {
     struct ddraw_surface *dst = impl_from_IDirectDrawSurface3(iface);
-    struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface3(src_surface);
+    struct ddraw_surface *src = unsafe_impl_from_IDirectDrawSurface3(src_surface);
 
     TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
             iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
 
-    return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
-            src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
+    return ddraw_surface1_Blt(&dst->IDirectDrawSurface_iface, dst_rect,
+            src ? &src->IDirectDrawSurface_iface : NULL, src_rect, flags, fx);
 }
 
 static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface2_Blt(IDirectDrawSurface2 *iface, RECT *dst_rect,
         IDirectDrawSurface2 *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
 {
     struct ddraw_surface *dst = impl_from_IDirectDrawSurface2(iface);
-    struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface2(src_surface);
-
-    TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
-            iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
-
-    return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
-            src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
-}
-
-static HRESULT WINAPI DECLSPEC_HOTPATCH ddraw_surface1_Blt(IDirectDrawSurface *iface, RECT *dst_rect,
-        IDirectDrawSurface *src_surface, RECT *src_rect, DWORD flags, DDBLTFX *fx)
-{
-    struct ddraw_surface *dst = impl_from_IDirectDrawSurface(iface);
-    struct ddraw_surface *src_impl = unsafe_impl_from_IDirectDrawSurface(src_surface);
+    struct ddraw_surface *src = unsafe_impl_from_IDirectDrawSurface2(src_surface);
 
     TRACE("iface %p, dst_rect %s, src_surface %p, src_rect %s, flags %#x, fx %p.\n",
             iface, wine_dbgstr_rect(dst_rect), src_surface, wine_dbgstr_rect(src_rect), flags, fx);
 
-    return ddraw_surface7_Blt(&dst->IDirectDrawSurface7_iface, dst_rect,
-            src_impl ? &src_impl->IDirectDrawSurface7_iface : NULL, src_rect, flags, fx);
+    return ddraw_surface1_Blt(&dst->IDirectDrawSurface_iface, dst_rect,
+            src ? &src->IDirectDrawSurface_iface : NULL, src_rect, flags, fx);
 }
 
 /*****************************************************************************
-- 
2.26.2




More information about the wine-devel mailing list