src/video/windx5/SDL_dx5video.c
changeset 809 dba98fb391e7
parent 769 b8d311d90021
child 815 6176f9a0d61a
     1.1 --- a/src/video/windx5/SDL_dx5video.c	Wed Feb 11 07:26:29 2004 +0000
     1.2 +++ b/src/video/windx5/SDL_dx5video.c	Wed Feb 11 16:10:16 2004 +0000
     1.3 @@ -71,6 +71,7 @@
     1.4  /* This is the rect EnumModes2 uses */
     1.5  struct DX5EnumRect {
     1.6  	SDL_Rect r;
     1.7 +	int refreshRate;
     1.8  	struct DX5EnumRect* next;
     1.9  };
    1.10  static struct DX5EnumRect *enumlists[NUM_MODELISTS];
    1.11 @@ -650,8 +651,10 @@
    1.12  	struct DX5EnumRect *enumrect;
    1.13  #if defined(NONAMELESSUNION)
    1.14  	int bpp = desc->ddpfPixelFormat.u1.dwRGBBitCount;
    1.15 +	int refreshRate = desc->u2.dwRefreshRate;
    1.16  #else
    1.17  	int bpp = desc->ddpfPixelFormat.dwRGBBitCount;
    1.18 +	int refreshRate = desc->dwRefreshRate;
    1.19  #endif
    1.20  
    1.21  	switch (bpp)  {
    1.22 @@ -660,22 +663,33 @@
    1.23  		case 24:
    1.24  		case 32:
    1.25  			bpp /= 8; --bpp;
    1.26 +			if ( enumlists[bpp] &&
    1.27 +			     enumlists[bpp]->r.w == (Uint16)desc->dwWidth &&
    1.28 +			     enumlists[bpp]->r.h == (Uint16)desc->dwHeight ) {
    1.29 +				if ( refreshRate > enumlists[bpp]->refreshRate &&
    1.30 +				     refreshRate <= 85 /* safe value? */ ) {
    1.31 +					enumlists[bpp]->refreshRate = refreshRate;
    1.32 +printf("New refresh rate for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate);
    1.33 +				}
    1.34 +				break;
    1.35 +			}
    1.36  			++SDL_nummodes[bpp];
    1.37  			enumrect = (struct DX5EnumRect*)malloc(sizeof(struct DX5EnumRect));
    1.38  			if ( !enumrect ) {
    1.39  				SDL_OutOfMemory();
    1.40  				return(DDENUMRET_CANCEL);
    1.41  			}
    1.42 +			enumrect->refreshRate = refreshRate;
    1.43  			enumrect->r.x = 0;
    1.44  			enumrect->r.y = 0;
    1.45  			enumrect->r.w = (Uint16)desc->dwWidth;
    1.46  			enumrect->r.h = (Uint16)desc->dwHeight;
    1.47  			enumrect->next = enumlists[bpp];
    1.48  			enumlists[bpp] = enumrect;
    1.49 +printf("New mode for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate);
    1.50  			break;
    1.51  	}
    1.52  
    1.53 -
    1.54  	return(DDENUMRET_OK);
    1.55  }
    1.56  
    1.57 @@ -912,7 +926,7 @@
    1.58  	for ( i=0; i<NUM_MODELISTS; ++i )
    1.59  		enumlists[i] = NULL;
    1.60  
    1.61 -	result = IDirectDraw2_EnumDisplayModes(ddraw2,0,NULL,this,EnumModes2);
    1.62 +	result = IDirectDraw2_EnumDisplayModes(ddraw2,DDEDM_REFRESHRATES,NULL,this,EnumModes2);
    1.63  	if ( result != DD_OK ) {
    1.64  		SetDDerror("DirectDraw2::EnumDisplayModes", result);
    1.65  		return(-1);
    1.66 @@ -926,7 +940,7 @@
    1.67  			return(-1);
    1.68  		}
    1.69  		for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next ) {
    1.70 -			SDL_modelist[i][j]=(SDL_Rect *)rect;
    1.71 +			SDL_modelist[i][j] = &rect->r;
    1.72  		}
    1.73  		SDL_modelist[i][j] = NULL;
    1.74  	}
    1.75 @@ -1195,6 +1209,9 @@
    1.76  
    1.77  	/* Set the display mode, if we are in fullscreen mode */
    1.78  	if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
    1.79 +		struct DX5EnumRect *rect;
    1.80 +		int maxRefreshRate;
    1.81 +
    1.82  		/* Cover up desktop during mode change */
    1.83  		SDL_resizing = 1;
    1.84  		SetWindowPos(SDL_Window, NULL, 0, 0, 
    1.85 @@ -1207,12 +1224,25 @@
    1.86  			SetForegroundWindow(SDL_Window);
    1.87  			SDL_Delay(100);
    1.88  		}
    1.89 -		result = IDirectDraw2_SetDisplayMode(ddraw2, width, height,
    1.90 -								bpp, 0, 0);
    1.91 +
    1.92 +		/* find maximum monitor refresh rate for this resolution */
    1.93 +		/* Dmitry Yakimov ftech@tula.net */
    1.94 +		maxRefreshRate = 0; /* system default */
    1.95 +		for ( rect = enumlists[bpp / 8 - 1]; rect; rect = rect->next ) {
    1.96 +			if ( (width == rect->r.w) && (height == rect->r.h) ) {
    1.97 +				maxRefreshRate = rect->refreshRate;
    1.98 +				break;
    1.99 +			}
   1.100 +		}
   1.101 +		printf("refresh rate = %d Hz\n", maxRefreshRate);
   1.102 +
   1.103 +		result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, maxRefreshRate, 0);
   1.104  		if ( result != DD_OK ) {
   1.105 -			/* We couldn't set fullscreen mode, try window */
   1.106 -			return(DX5_SetVideoMode(this, current,
   1.107 -				width, height, bpp, flags & ~SDL_FULLSCREEN)); 
   1.108 +			result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, 0, 0);
   1.109 +			if ( result != DD_OK ) {
   1.110 +				/* We couldn't set fullscreen mode, try window */
   1.111 +				return(DX5_SetVideoMode(this, current, width, height, bpp, flags & ~SDL_FULLSCREEN)); 
   1.112 +			}
   1.113  		}
   1.114  		DX5_DInputReset(this, 1);
   1.115  	} else {
   1.116 @@ -1953,11 +1983,17 @@
   1.117  	LPDIRECTDRAWSURFACE3 dd_surface;
   1.118  
   1.119  	dd_surface = surface->hwdata->dd_surface;
   1.120 -	result = IDirectDrawSurface3_Flip(dd_surface, NULL, 0);
   1.121 +
   1.122 +	/* to prevent big slowdown on fast computers, wait here instead of driver ring 0 code */
   1.123 +	/* Dmitry Yakimov (ftech@tula.net) */
   1.124 +	while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
   1.125 +
   1.126 +	result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);
   1.127  	if ( result == DDERR_SURFACELOST ) {
   1.128  		result = IDirectDrawSurface3_Restore(
   1.129  						surface->hwdata->dd_surface);
   1.130 -		result = IDirectDrawSurface3_Flip(dd_surface, NULL, 0);
   1.131 +		while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
   1.132 +		result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);
   1.133  	}
   1.134  	if ( result != DD_OK ) {
   1.135  		SetDDerror("DirectDrawSurface3::Flip", result);