Skip to content

Commit

Permalink
Date: Tue, 13 Jan 2004 19:25:37 +0300
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
slouken committed Feb 11, 2004
1 parent 8de0afc commit ea2b9bf
Showing 1 changed file with 46 additions and 10 deletions.
56 changes: 46 additions & 10 deletions src/video/windx5/SDL_dx5video.c
Expand Up @@ -71,6 +71,7 @@ HRESULT (WINAPI *DInputCreate)(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUT *
/* This is the rect EnumModes2 uses */
struct DX5EnumRect {
SDL_Rect r;
int refreshRate;
struct DX5EnumRect* next;
};
static struct DX5EnumRect *enumlists[NUM_MODELISTS];
Expand Down Expand Up @@ -650,8 +651,10 @@ static HRESULT WINAPI EnumModes2(DDSURFACEDESC *desc, VOID *udata)
struct DX5EnumRect *enumrect;
#if defined(NONAMELESSUNION)
int bpp = desc->ddpfPixelFormat.u1.dwRGBBitCount;
int refreshRate = desc->u2.dwRefreshRate;
#else
int bpp = desc->ddpfPixelFormat.dwRGBBitCount;
int refreshRate = desc->dwRefreshRate;
#endif

switch (bpp) {
Expand All @@ -660,22 +663,33 @@ static HRESULT WINAPI EnumModes2(DDSURFACEDESC *desc, VOID *udata)
case 24:
case 32:
bpp /= 8; --bpp;
if ( enumlists[bpp] &&
enumlists[bpp]->r.w == (Uint16)desc->dwWidth &&
enumlists[bpp]->r.h == (Uint16)desc->dwHeight ) {
if ( refreshRate > enumlists[bpp]->refreshRate &&
refreshRate <= 85 /* safe value? */ ) {
enumlists[bpp]->refreshRate = refreshRate;
printf("New refresh rate for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate);
}
break;
}
++SDL_nummodes[bpp];
enumrect = (struct DX5EnumRect*)malloc(sizeof(struct DX5EnumRect));
if ( !enumrect ) {
SDL_OutOfMemory();
return(DDENUMRET_CANCEL);
}
enumrect->refreshRate = refreshRate;
enumrect->r.x = 0;
enumrect->r.y = 0;
enumrect->r.w = (Uint16)desc->dwWidth;
enumrect->r.h = (Uint16)desc->dwHeight;
enumrect->next = enumlists[bpp];
enumlists[bpp] = enumrect;
printf("New mode for %d bpp: %dx%d at %d Hz\n", (bpp+1)*8, (int)desc->dwWidth, (int)desc->dwHeight, refreshRate);
break;
}


return(DDENUMRET_OK);
}

Expand Down Expand Up @@ -912,7 +926,7 @@ int DX5_VideoInit(_THIS, SDL_PixelFormat *vformat)
for ( i=0; i<NUM_MODELISTS; ++i )
enumlists[i] = NULL;

result = IDirectDraw2_EnumDisplayModes(ddraw2,0,NULL,this,EnumModes2);
result = IDirectDraw2_EnumDisplayModes(ddraw2,DDEDM_REFRESHRATES,NULL,this,EnumModes2);
if ( result != DD_OK ) {
SetDDerror("DirectDraw2::EnumDisplayModes", result);
return(-1);
Expand All @@ -926,7 +940,7 @@ int DX5_VideoInit(_THIS, SDL_PixelFormat *vformat)
return(-1);
}
for ( j = 0, rect = enumlists[i]; rect; ++j, rect = rect->next ) {
SDL_modelist[i][j]=(SDL_Rect *)rect;
SDL_modelist[i][j] = &rect->r;
}
SDL_modelist[i][j] = NULL;
}
Expand Down Expand Up @@ -1195,6 +1209,9 @@ SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current,

/* Set the display mode, if we are in fullscreen mode */
if ( (flags & SDL_FULLSCREEN) == SDL_FULLSCREEN ) {
struct DX5EnumRect *rect;
int maxRefreshRate;

/* Cover up desktop during mode change */
SDL_resizing = 1;
SetWindowPos(SDL_Window, NULL, 0, 0,
Expand All @@ -1207,12 +1224,25 @@ SDL_Surface *DX5_SetVideoMode(_THIS, SDL_Surface *current,
SetForegroundWindow(SDL_Window);
SDL_Delay(100);
}
result = IDirectDraw2_SetDisplayMode(ddraw2, width, height,
bpp, 0, 0);

/* find maximum monitor refresh rate for this resolution */
/* Dmitry Yakimov ftech@tula.net */
maxRefreshRate = 0; /* system default */
for ( rect = enumlists[bpp / 8 - 1]; rect; rect = rect->next ) {
if ( (width == rect->r.w) && (height == rect->r.h) ) {
maxRefreshRate = rect->refreshRate;
break;
}
}
printf("refresh rate = %d Hz\n", maxRefreshRate);

result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, maxRefreshRate, 0);
if ( result != DD_OK ) {
/* We couldn't set fullscreen mode, try window */
return(DX5_SetVideoMode(this, current,
width, height, bpp, flags & ~SDL_FULLSCREEN));
result = IDirectDraw2_SetDisplayMode(ddraw2, width, height, bpp, 0, 0);
if ( result != DD_OK ) {
/* We couldn't set fullscreen mode, try window */
return(DX5_SetVideoMode(this, current, width, height, bpp, flags & ~SDL_FULLSCREEN));
}
}
DX5_DInputReset(this, 1);
} else {
Expand Down Expand Up @@ -1953,11 +1983,17 @@ static int DX5_FlipHWSurface(_THIS, SDL_Surface *surface)
LPDIRECTDRAWSURFACE3 dd_surface;

dd_surface = surface->hwdata->dd_surface;
result = IDirectDrawSurface3_Flip(dd_surface, NULL, 0);

/* to prevent big slowdown on fast computers, wait here instead of driver ring 0 code */
/* Dmitry Yakimov (ftech@tula.net) */
while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);

result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);
if ( result == DDERR_SURFACELOST ) {
result = IDirectDrawSurface3_Restore(
surface->hwdata->dd_surface);
result = IDirectDrawSurface3_Flip(dd_surface, NULL, 0);
while(IDirectDrawSurface3_GetFlipStatus(dd_surface, DDGBS_ISBLTDONE) == DDERR_WASSTILLDRAWING);
result = IDirectDrawSurface3_Flip(dd_surface, NULL, DDFLIP_WAIT);
}
if ( result != DD_OK ) {
SetDDerror("DirectDrawSurface3::Flip", result);
Expand Down

0 comments on commit ea2b9bf

Please sign in to comment.