[PATCH] Implement correct behavior for the DDEDM_REFRESHRATES flag, as the old implementation was not implemented as specified on MSDN. This fixes some older apps which dont like getting flooded with enumerated copies of modes, even though they did not set the DDEDM_REFRESHRATES flag.

Peter Dons Tychsen (none) donpedro at dhcppc4.
Thu Jan 3 18:13:50 CST 2008


---
 dlls/ddraw/ddraw.c |   50 +++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 43 insertions(+), 7 deletions(-)

diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index 908fb3b..af49dd9 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -1215,6 +1215,8 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
     unsigned int modenum, fmt;
     WINED3DFORMAT pixelformat = WINED3DFMT_UNKNOWN;
     WINED3DDISPLAYMODE mode;
+    WINED3DDISPLAYMODE *prevmodes=NULL;
+    int prevmodecount = 0; 
     DDSURFACEDESC2 callback_sd;
 
     WINED3DFORMAT checkFormatList[] =
@@ -1272,17 +1274,49 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
                 if(DDSD->dwFlags & DDSD_WIDTH && mode.Width != DDSD->dwWidth) continue;
                 if(DDSD->dwFlags & DDSD_HEIGHT && mode.Height != DDSD->dwHeight) continue;
             }
-
+            
+            /* Check if this mode is already is enumerated. If it is, then dont enumerate it again,
+               unless the DDEDM_REFRESHRATES flags is set. MSDN specifies this for all ddraw versions.
+               The maximum number of enumerated modes is not specified, but assume 100 for now, which
+               should be plenty. Some older games break anyway if there are too many modes enumerated */
+            if(!(Flags & DDEDM_REFRESHRATES))
+            {
+                int i;
+                for(i=0; i<prevmodecount; i++)
+                {
+                    if((prevmodes[i].Width == mode.Width) && (prevmodes[i].Height == mode.Height) && (prevmodes[i].Format == mode.Format))
+                    {
+                        break;
+                    }
+                }
+                if(i!=prevmodecount)
+                {
+                    /* Skip this mode, we already have it */
+                    continue;
+                }
+                if(!prevmodes)
+                {
+                     prevmodes = HeapAlloc(GetProcessHeap(), 0, sizeof(WINED3DDISPLAYMODE) * 100);
+                     if(!prevmodes)
+                     {
+                         LeaveCriticalSection(&ddraw_cs);
+                         return DDERR_OUTOFMEMORY;
+                     }
+                }
+                if(prevmodecount == 100)
+                {
+                    FIXME("Out of mode buffer, increase buffer\n");
+                    continue;
+                }
+                prevmodes[prevmodecount++] = mode;
+            }
+            
             memset(&callback_sd, 0, sizeof(callback_sd));
             callback_sd.dwSize = sizeof(callback_sd);
             callback_sd.u4.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
 
-            callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH;
-            if(Flags & DDEDM_REFRESHRATES)
-            {
-                callback_sd.dwFlags |= DDSD_REFRESHRATE;
-                callback_sd.u2.dwRefreshRate = mode.RefreshRate;
-            }
+            callback_sd.dwFlags = DDSD_HEIGHT|DDSD_WIDTH|DDSD_PIXELFORMAT|DDSD_PITCH|DDSD_REFRESHRATE;
+            callback_sd.u2.dwRefreshRate = mode.RefreshRate;
 
             callback_sd.dwWidth = mode.Width;
             callback_sd.dwHeight = mode.Height;
@@ -1299,6 +1333,7 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
             if(cb(&callback_sd, Context) == DDENUMRET_CANCEL)
             {
                 TRACE("Application asked to terminate the enumeration\n");
+                if(prevmodes) HeapFree(GetProcessHeap(), 0, prevmodes);
                 LeaveCriticalSection(&ddraw_cs);
                 return DD_OK;
             }
@@ -1306,6 +1341,7 @@ IDirectDrawImpl_EnumDisplayModes(IDirectDraw7 *iface,
     }
 
     TRACE("End of enumeration\n");
+    if(prevmodes) HeapFree(GetProcessHeap(), 0, prevmodes);
     LeaveCriticalSection(&ddraw_cs);
     return DD_OK;
 }
-- 
1.5.3.6


--=-VIkg25CPq5W8SqHkukuo--




More information about the wine-patches mailing list