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 }