Mercurial > sdl-ios-xcode
comparison src/video/windx5/SDL_dx5video.c @ 809:dba98fb391e7
Date: Tue, 13 Jan 2004 19:25:37 +0300
From: Dmitry Yakimov
Subject: [SDL] [PATCH] SDL bug patch
Let me introduce 2 fixes to SDL.
1. Preventing great slowdown on fast machines while hardware
flipping (it's obviously bug).
2. Setting up 85 Hz of monitor if supported. The reason is that
Win98 by default sets lowest frequency 60 Hz.
And we can't set up maximum frequency because some users can have
wrong monitor drivers.
This is important for shareware and commercial programs.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Wed, 11 Feb 2004 16:10:16 +0000 |
parents | b8d311d90021 |
children | 6176f9a0d61a |
comparison
equal
deleted
inserted
replaced
808:0defd90ef27c | 809:dba98fb391e7 |
---|---|
69 HRESULT (WINAPI *DInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT *ppDI, LPUNKNOWN punkOuter); | 69 HRESULT (WINAPI *DInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT *ppDI, LPUNKNOWN punkOuter); |
70 | 70 |
71 /* This is the rect EnumModes2 uses */ | 71 /* This is the rect EnumModes2 uses */ |
72 struct DX5EnumRect { | 72 struct DX5EnumRect { |
73 SDL_Rect r; | 73 SDL_Rect r; |
74 int refreshRate; | |
74 struct DX5EnumRect* next; | 75 struct DX5EnumRect* next; |
75 }; | 76 }; |
76 static struct DX5EnumRect *enumlists[NUM_MODELISTS]; | 77 static struct DX5EnumRect *enumlists[NUM_MODELISTS]; |
77 | 78 |
78 /* | 79 /* |
648 { | 649 { |
649 SDL_VideoDevice *this = (SDL_VideoDevice *)udata; | 650 SDL_VideoDevice *this = (SDL_VideoDevice *)udata; |
650 struct DX5EnumRect *enumrect; | 651 struct DX5EnumRect *enumrect; |
651 #if defined(NONAMELESSUNION) | 652 #if defined(NONAMELESSUNION) |
652 int bpp = desc->ddpfPixelFormat.u1.dwRGBBitCount; | 653 int bpp = desc->ddpfPixelFormat.u1.dwRGBBitCount; |
654 int refreshRate = desc->u2.dwRefreshRate; | |
653 #else | 655 #else |
654 int bpp = desc->ddpfPixelFormat.dwRGBBitCount; | 656 int bpp = desc->ddpfPixelFormat.dwRGBBitCount; |
657 int refreshRate = desc->dwRefreshRate; | |
655 #endif | 658 #endif |
656 | 659 |
657 switch (bpp) { | 660 switch (bpp) { |
658 case 8: | 661 case 8: |
659 case 16: | 662 case 16: |
660 case 24: | 663 case 24: |
661 case 32: | 664 case 32: |
662 bpp /= 8; --bpp; | 665 bpp /= 8; --bpp; |
666 if ( enumlists[bpp] && | |
667 enumlists[bpp]->r.w == (Uint16)desc->dwWidth && | |
668 enumlists[bpp]->r.h == (Uint16)desc->dwHeight ) { | |
669 if ( refreshRate > enumlists[bpp]->refreshRate && | |
670 refreshRate <= 85 /* safe value? */ ) { | |
671 enumlists[bpp]->refreshRate = refreshRate; | |
672 printf("New refresh rate for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate); | |
673 } | |
674 break; | |
675 } | |
663 ++SDL_nummodes[bpp]; | 676 ++SDL_nummodes[bpp]; |
664 enumrect = (struct DX5EnumRect*)malloc(sizeof(struct DX5EnumRect)); | 677 enumrect = (struct DX5EnumRect*)malloc(sizeof(struct DX5EnumRect)); |
665 if ( !enumrect ) { | 678 if ( !enumrect ) { |
666 SDL_OutOfMemory(); | 679 SDL_OutOfMemory(); |
667 return(DDENUMRET_CANCEL); | 680 return(DDENUMRET_CANCEL); |
668 } | 681 } |
682 enumrect->refreshRate = refreshRate; | |
669 enumrect->r.x = 0; | 683 enumrect->r.x = 0; |
670 enumrect->r.y = 0; | 684 enumrect->r.y = 0; |
671 enumrect->r.w = (Uint16)desc->dwWidth; | 685 enumrect->r.w = (Uint16)desc->dwWidth; |
672 enumrect->r.h = (Uint16)desc->dwHeight; | 686 enumrect->r.h = (Uint16)desc->dwHeight; |
673 enumrect->next = enumlists[bpp]; | 687 enumrect->next = enumlists[bpp]; |
674 enumlists[bpp] = enumrect; | 688 enumlists[bpp] = enumrect; |
675 break; | 689 printf("New mode for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate); |
676 } | 690 break; |
677 | 691 } |
678 | 692 |
679 return(DDENUMRET_OK); | 693 return(DDENUMRET_OK); |
680 } | 694 } |
681 | 695 |
682 void SetDDerror(const char *function, int code) | 696 void SetDDerror(const char *function, int code) |
910 | 924 |
911 /* Enumerate the available fullscreen modes */ | 925 /* Enumerate the available fullscreen modes */ |
912 for ( i=0; i<NUM_MODELISTS; ++i ) | 926 for ( i=0; i<NUM_MODELISTS; ++i ) |
913 enumlists[i] = NULL; | 927 enumlists[i] = NULL; |
914 | 928 |
915 result = IDirectDraw2_EnumDisplayModes(ddraw2,0,NULL,this,EnumModes2); | 929 result = IDirectDraw2_EnumDisplayModes(ddraw2,DDEDM_REFRESHRATES,NULL,this,EnumModes2); |
916 if ( result != DD_OK ) { | 930 if ( result != DD_OK ) { |
917 SetDDerror("DirectDraw2::EnumDisplayModes", result); | 931 SetDDerror("DirectDraw2::EnumDisplayModes", result); |
918 return(-1); | 932 return(-1); |
919 } | 933 } |
920 for ( i=0; i<NUM_MODELISTS; ++i ) { | 934 for ( i=0; i<NUM_MODELISTS; ++i ) { |
924 if ( SDL_modelist[i] == NULL ) { | 938 if ( SDL_modelist[i] == NULL ) { |
925 SDL_OutOfMemory(); | 939 SDL_OutOfMemory(); |
926 return(-1); | 940 return(-1); |
927 } | 941 } |
928 for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next ) { | 942 for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next ) { |
929 SDL_modelist[i][j]=(SDL_Rect *)rect; | 943 SDL_modelist[i][j] = &rect->r; |
930 } | 944 } |
931 SDL_modelist[i][j] = NULL; | 945 SDL_modelist[i][j] = NULL; |
932 } | 946 } |
933 | 947 |
934 /* Fill in some window manager capabilities */ | 948 /* Fill in some window manager capabilities */ |
1193 return(NULL); | 1207 return(NULL); |
1194 } | 1208 } |
1195 | 1209 |
1196 /* Set the display mode, if we are in fullscreen mode */ | 1210 /* Set the display mode, if we are in fullscreen mode */ |
1197 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { | 1211 if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) { |
1212 struct DX5EnumRect *rect; | |
1213 int maxRefreshRate; | |
1214 | |
1198 /* Cover up desktop during mode change */ | 1215 /* Cover up desktop during mode change */ |
1199 SDL_resizing = 1; | 1216 SDL_resizing = 1; |
1200 SetWindowPos(SDL_Window, NULL, 0, 0, | 1217 SetWindowPos(SDL_Window, NULL, 0, 0, |
1201 GetSystemMetrics(SM_CXSCREEN), | 1218 GetSystemMetrics(SM_CXSCREEN), |
1202 GetSystemMetrics(SM_CYSCREEN), | 1219 GetSystemMetrics(SM_CYSCREEN), |
1205 ShowWindow(SDL_Window, SW_SHOW); | 1222 ShowWindow(SDL_Window, SW_SHOW); |
1206 while ( GetForegroundWindow() != SDL_Window ) { | 1223 while ( GetForegroundWindow() != SDL_Window ) { |
1207 SetForegroundWindow(SDL_Window); | 1224 SetForegroundWindow(SDL_Window); |
1208 SDL_Delay(100); | 1225 SDL_Delay(100); |
1209 } | 1226 } |
1210 result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, | 1227 |
1211 bpp, 0, 0); | 1228 /* find maximum monitor refresh rate for this resolution */ |
1229 /* Dmitry Yakimov ftech@tula.net */ | |
1230 maxRefreshRate = 0; /* system default */ | |
1231 for ( rect = enumlists[bpp / 8 - 1]; rect; rect = rect->next ) { | |
1232 if ( (width == rect->r.w) && (height == rect->r.h) ) { | |
1233 maxRefreshRate = rect->refreshRate; | |
1234 break; | |
1235 } | |
1236 } | |
1237 printf("refresh rate = %d Hz\n", maxRefreshRate); | |
1238 | |
1239 result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, maxRefreshRate, 0); | |
1212 if ( result != DD_OK ) { | 1240 if ( result != DD_OK ) { |
1213 /* We couldn't set fullscreen mode, try window */ | 1241 result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, 0, 0); |
1214 return(DX5_SetVideoMode(this, current, | 1242 if ( result != DD_OK ) { |
1215 width, height, bpp, flags & ~SDL_FULLSCREEN)); | 1243 /* We couldn't set fullscreen mode, try window */ |
1244 return(DX5_SetVideoMode(this, current, width, height, bpp, flags & ~SDL_FULLSCREEN)); | |
1245 } | |
1216 } | 1246 } |
1217 DX5_DInputReset(this, 1); | 1247 DX5_DInputReset(this, 1); |
1218 } else { | 1248 } else { |
1219 DX5_DInputReset(this, 0); | 1249 DX5_DInputReset(this, 0); |
1220 } | 1250 } |
1951 { | 1981 { |
1952 HRESULT result; | 1982 HRESULT result; |
1953 LPDIRECTDRAWSURFACE3 dd_surface; | 1983 LPDIRECTDRAWSURFACE3 dd_surface; |
1954 | 1984 |
1955 dd_surface = surface->hwdata->dd_surface; | 1985 dd_surface = surface->hwdata->dd_surface; |
1956 result = IDirectDrawSurface3_Flip(dd_surface, NULL, 0); | 1986 |
1987 /* to prevent big slowdown on fast computers, wait here instead of driver ring 0 code */ | |
1988 /* Dmitry Yakimov (ftech@tula.net) */ | |
1989 while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING); | |
1990 | |
1991 result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT); | |
1957 if ( result == DDERR_SURFACELOST ) { | 1992 if ( result == DDERR_SURFACELOST ) { |
1958 result = IDirectDrawSurface3_Restore( | 1993 result = IDirectDrawSurface3_Restore( |
1959 surface->hwdata->dd_surface); | 1994 surface->hwdata->dd_surface); |
1960 result = IDirectDrawSurface3_Flip(dd_surface, NULL, 0); | 1995 while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING); |
1996 result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT); | |
1961 } | 1997 } |
1962 if ( result != DD_OK ) { | 1998 if ( result != DD_OK ) { |
1963 SetDDerror("DirectDrawSurface3::Flip", result); | 1999 SetDDerror("DirectDrawSurface3::Flip", result); |
1964 return(-1); | 2000 return(-1); |
1965 } | 2001 } |