>From 171809b41f47d9d508721885063118a82904fdef Mon Sep 17 00:00:00 2001
From: Peter Dons Tychsen <donpedro@dhcppc4.(none)>
Date: Fri, 4 Jan 2008 01:13:50 +0100
Subject: [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.

---
 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

