Alexander Dorofeyev : ddraw: Do not return modes differing only by refresh rate without DDEDM_REFRESHRATES .

Alexandre Julliard julliard at winehq.org
Thu May 29 06:52:20 CDT 2008


Module: wine
Branch: master
Commit: 940ef7a9ff86adbca7cae4f825f5911e41470a81
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=940ef7a9ff86adbca7cae4f825f5911e41470a81

Author: Alexander Dorofeyev <alexd4 at inbox.lv>
Date:   Thu May 29 01:13:00 2008 +0300

ddraw: Do not return modes differing only by refresh rate without DDEDM_REFRESHRATES.

---

 dlls/ddraw/ddraw.c |   61 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 230533f..ab78c4b 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1243,6 +1243,8 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
     WINED3DFORMAT pixelformat = WINED3DFMT_UNKNOWN;
     WINED3DDISPLAYMODE mode;
     DDSURFACEDESC2 callback_sd;
+    WINED3DDISPLAYMODE *enum_modes = NULL;
+    unsigned enum_mode_count = 0, enum_mode_array_size = 0;
 
     WINED3DFORMAT checkFormatList[] =
     {
@@ -1280,6 +1282,18 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
             pixelformat = PixelFormat_DD2WineD3D(&DDSD->u4.ddpfPixelFormat);
     }
 
+    if(!(Flags & DDEDM_REFRESHRATES))
+    {
+        enum_mode_array_size = 16;
+        enum_modes = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DDISPLAYMODE) * enum_mode_array_size);
+        if (!enum_modes)
+        {
+            ERR("Out of memory\n");
+            LeaveCriticalSection(&ddraw_cs);
+            return DDERR_OUTOFMEMORY;
+        }
+    }
+
     for(fmt = 0; fmt < (sizeof(checkFormatList) / sizeof(checkFormatList[0])); fmt++)
     {
         if(pixelformat != WINED3DFMT_UNKNOWN && checkFormatList[fmt] != pixelformat)
@@ -1300,6 +1314,28 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
                 if(DDSD->dwFlags & DDSD_HEIGHT && mode.Height != DDSD->dwHeight) continue;
             }
 
+            if(!(Flags & DDEDM_REFRESHRATES))
+            {
+                /* DX docs state EnumDisplayMode should return only unique modes. If DDEDM_REFRESHRATES is not set, refresh
+                 * rate doesn't matter when determining if the mode is unique. So modes only differing in refresh rate have
+                 * to be reduced to a single unique result in such case.
+                 */
+                BOOL found = FALSE;
+                unsigned i;
+
+                for (i = 0; i < enum_mode_count; i++)
+                {
+                    if(enum_modes[i].Width == mode.Width && enum_modes[i].Height == mode.Height &&
+                       enum_modes[i].Format == mode.Format)
+                    {
+                        found = TRUE;
+                        break;
+                    }
+                }
+
+                if(found) continue;
+            }
+
             memset(&callback_sd, 0, sizeof(callback_sd));
             callback_sd.dwSize = sizeof(callback_sd);
             callback_sd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
@@ -1326,13 +1362,38 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
             if(cb(&callback_sd, Context) == DDENUMRET_CANCEL)
             {
                 TRACE("Application asked to terminate the enumeration\n");
+                HeapFree(GetProcessHeap(), 0, enum_modes);
                 LeaveCriticalSection(&ddraw_cs);
                 return DD_OK;
             }
+
+            if(!(Flags & DDEDM_REFRESHRATES))
+            {
+                if (enum_mode_count == enum_mode_array_size)
+                {
+                    WINED3DDISPLAYMODE *new_enum_modes;
+
+                    enum_mode_array_size *= 2;
+                    new_enum_modes = HeapReAlloc(GetProcessHeap(), 0, enum_modes, sizeof(WINED3DDISPLAYMODE) * enum_mode_array_size);
+
+                    if (!new_enum_modes)
+                    {
+                        ERR("Out of memory\n");
+                        HeapFree(GetProcessHeap(), 0, enum_modes);
+                        LeaveCriticalSection(&ddraw_cs);
+                        return DDERR_OUTOFMEMORY;
+                    }
+
+                    enum_modes = new_enum_modes;
+                }
+
+                enum_modes[enum_mode_count++] = mode;
+            }
         }
     }
 
     TRACE("End of enumeration\n");
+    HeapFree(GetProcessHeap(), 0, enum_modes);
     LeaveCriticalSection(&ddraw_cs);
     return DD_OK;
 }




More information about the wine-cvs mailing list