implement EnumDisplayModes and BltFast - Fixes DDBLT_COLORFILL with NULL rect - support resolution changes during runtime (AoE2)
This commit is contained in:
parent
25627134e7
commit
cbc66c3bc2
5 changed files with 132 additions and 58 deletions
|
@ -102,6 +102,7 @@ typedef struct IDirectDrawImpl
|
||||||
BOOL maintas;
|
BOOL maintas;
|
||||||
BOOL fakecursorpos;
|
BOOL fakecursorpos;
|
||||||
BOOL noactivateapp;
|
BOOL noactivateapp;
|
||||||
|
BOOL hidemouse;
|
||||||
char shader[MAX_PATH];
|
char shader[MAX_PATH];
|
||||||
BOOL wine;
|
BOOL wine;
|
||||||
int sleep;
|
int sleep;
|
||||||
|
|
56
src/main.c
56
src/main.c
|
@ -145,9 +145,41 @@ HRESULT __stdcall ddraw_DuplicateSurface(IDirectDrawImpl *This, LPDIRECTDRAWSURF
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT __stdcall ddraw_EnumDisplayModes(IDirectDrawImpl *This, DWORD a, LPDDSURFACEDESC b, LPVOID c, LPDDENUMMODESCALLBACK d)
|
HRESULT __stdcall ddraw_EnumDisplayModes(IDirectDrawImpl *This, DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback)
|
||||||
{
|
{
|
||||||
printf("DirectDraw::EnumDisplayModes(This=%p, ...)\n", This);
|
DWORD i = 0;
|
||||||
|
DEVMODE m;
|
||||||
|
DDSURFACEDESC s;
|
||||||
|
|
||||||
|
printf("DirectDraw::EnumDisplayModes(This=%p, dwFlags=%d, lpDDSurfaceDesc=%p, lpContext=%p, lpEnumModesCallback=%p)\n", This, (unsigned int)dwFlags, lpDDSurfaceDesc, lpContext, lpEnumModesCallback);
|
||||||
|
|
||||||
|
if (lpDDSurfaceDesc != NULL)
|
||||||
|
{
|
||||||
|
return DDERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (EnumDisplaySettings(NULL, i, &m))
|
||||||
|
{
|
||||||
|
printf(" %d: %dx%d@%d %d bpp\n", (int)i, (int)m.dmPelsWidth, (int)m.dmPelsHeight, (int)m.dmDisplayFrequency, (int)m.dmBitsPerPel);
|
||||||
|
|
||||||
|
memset(&s, 0, sizeof(DDSURFACEDESC));
|
||||||
|
s.dwSize = sizeof(DDSURFACEDESC);
|
||||||
|
s.dwFlags = DDSD_HEIGHT | DDSD_REFRESHRATE | DDSD_WIDTH | DDSD_PIXELFORMAT;
|
||||||
|
s.dwHeight = m.dmPelsHeight;
|
||||||
|
s.dwWidth = m.dmPelsWidth;
|
||||||
|
s.dwRefreshRate = m.dmDisplayFrequency;
|
||||||
|
s.ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||||
|
s.ddpfPixelFormat.dwFlags = m.dmBitsPerPel == 8 ? DDPF_PALETTEINDEXED8 : DDPF_RGB;
|
||||||
|
s.ddpfPixelFormat.dwRGBBitCount = m.dmBitsPerPel;
|
||||||
|
|
||||||
|
if (lpEnumModesCallback(&s, lpContext) == DDENUMRET_CANCEL)
|
||||||
|
{
|
||||||
|
printf(" DDENUMRET_CANCEL returned, stopping\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,13 +315,21 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD
|
||||||
{
|
{
|
||||||
printf("DirectDraw::SetDisplayMode(This=%p, width=%d, height=%d, bpp=%d)\n", This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp);
|
printf("DirectDraw::SetDisplayMode(This=%p, width=%d, height=%d, bpp=%d)\n", This, (unsigned int)width, (unsigned int)height, (unsigned int)bpp);
|
||||||
|
|
||||||
This->mode.dmSize = sizeof(DEVMODE);
|
if (!This->mode.dmPelsWidth)
|
||||||
This->mode.dmDriverExtra = 0;
|
|
||||||
|
|
||||||
if(EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &This->mode) == FALSE)
|
|
||||||
{
|
{
|
||||||
/* not expected */
|
This->mode.dmSize = sizeof(DEVMODE);
|
||||||
return DDERR_UNSUPPORTED;
|
This->mode.dmDriverExtra = 0;
|
||||||
|
|
||||||
|
if (EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &This->mode) == FALSE)
|
||||||
|
{
|
||||||
|
/* not expected */
|
||||||
|
return DDERR_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else //resolution changed twice during runtime, disable stretching for these cases for now
|
||||||
|
{
|
||||||
|
This->render.width = 0;
|
||||||
|
This->render.height = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
This->width = width;
|
This->width = width;
|
||||||
|
|
25
src/mouse.c
25
src/mouse.c
|
@ -134,11 +134,17 @@ BOOL WINAPI fake_ClipCursor(const RECT *lpRect)
|
||||||
|
|
||||||
int WINAPI fake_ShowCursor(BOOL bShow)
|
int WINAPI fake_ShowCursor(BOOL bShow)
|
||||||
{
|
{
|
||||||
|
if (ddraw && !ddraw->hidemouse)
|
||||||
|
return ShowCursor(bShow);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor)
|
HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor)
|
||||||
{
|
{
|
||||||
|
if (ddraw && !ddraw->hidemouse)
|
||||||
|
return SetCursor(hCursor);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +217,9 @@ void mouse_lock()
|
||||||
|
|
||||||
if (ddraw->devmode)
|
if (ddraw->devmode)
|
||||||
{
|
{
|
||||||
while(ShowCursor(FALSE) > 0);
|
if (ddraw->hidemouse)
|
||||||
|
while(ShowCursor(FALSE) > 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +263,9 @@ void mouse_lock()
|
||||||
SetCapture(ddraw->hWnd);
|
SetCapture(ddraw->hWnd);
|
||||||
ClipCursor(&rc);
|
ClipCursor(&rc);
|
||||||
|
|
||||||
while(ShowCursor(FALSE) > 0);
|
if (ddraw->hidemouse)
|
||||||
|
while(ShowCursor(FALSE) > 0);
|
||||||
|
|
||||||
ddraw->locked = TRUE;
|
ddraw->locked = TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,7 +276,9 @@ void mouse_unlock()
|
||||||
|
|
||||||
if (ddraw->devmode)
|
if (ddraw->devmode)
|
||||||
{
|
{
|
||||||
while(ShowCursor(TRUE) < 0);
|
if (ddraw->hidemouse)
|
||||||
|
while(ShowCursor(TRUE) < 0);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -289,8 +301,11 @@ void mouse_unlock()
|
||||||
ClientToScreen(ddraw->hWnd, &pt2);
|
ClientToScreen(ddraw->hWnd, &pt2);
|
||||||
SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y);
|
SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y);
|
||||||
|
|
||||||
while(ShowCursor(TRUE) < 0);
|
if (ddraw->hidemouse)
|
||||||
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
{
|
||||||
|
while (ShowCursor(TRUE) < 0);
|
||||||
|
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||||
|
}
|
||||||
|
|
||||||
ClipCursor(NULL);
|
ClipCursor(NULL);
|
||||||
ReleaseCapture();
|
ReleaseCapture();
|
||||||
|
|
|
@ -41,6 +41,7 @@ void Settings_Load()
|
||||||
ddraw->fakecursorpos = GetBool("fakecursorpos", TRUE);
|
ddraw->fakecursorpos = GetBool("fakecursorpos", TRUE);
|
||||||
ddraw->noactivateapp = GetBool("noactivateapp", FALSE);
|
ddraw->noactivateapp = GetBool("noactivateapp", FALSE);
|
||||||
ddraw->vhack = GetBool("vhack", FALSE);
|
ddraw->vhack = GetBool("vhack", FALSE);
|
||||||
|
ddraw->hidemouse = GetBool("hidemouse", TRUE);
|
||||||
|
|
||||||
ddraw->sleep = GetInt("sleep", 0);
|
ddraw->sleep = GetInt("sleep", 0);
|
||||||
ddraw->render.maxfps = GetInt("maxfps", 125);
|
ddraw->render.maxfps = GetInt("maxfps", 125);
|
||||||
|
@ -184,6 +185,8 @@ static void CreateSettingsIni()
|
||||||
"shader=\n"
|
"shader=\n"
|
||||||
"; Sleep for X ms after drawing each frame (Slows down scrollrate on C&C95 / Prevents visual glitches on Carmageddon)\n"
|
"; Sleep for X ms after drawing each frame (Slows down scrollrate on C&C95 / Prevents visual glitches on Carmageddon)\n"
|
||||||
"sleep=0\n"
|
"sleep=0\n"
|
||||||
|
"; Hide/Show the mouse cursor on lock/unlock (Ctrl+Tab)\n"
|
||||||
|
"hidemouse=true\n"
|
||||||
"\n"
|
"\n"
|
||||||
"[CARMA95]\n"
|
"[CARMA95]\n"
|
||||||
"fakecursorpos=false\n"
|
"fakecursorpos=false\n"
|
||||||
|
@ -193,6 +196,11 @@ static void CreateSettingsIni()
|
||||||
"[C&C95]\n"
|
"[C&C95]\n"
|
||||||
"sleep=10\n"
|
"sleep=10\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
"[EMPIRES2]\n"
|
||||||
|
"renderer=gdi\n"
|
||||||
|
"hidemouse=false\n"
|
||||||
|
"border=false\n"
|
||||||
|
"\n"
|
||||||
|
|
||||||
, fh);
|
, fh);
|
||||||
fclose(fh);
|
fclose(fh);
|
||||||
|
|
100
src/surface.c
100
src/surface.c
|
@ -104,68 +104,48 @@ HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestR
|
||||||
|
|
||||||
if (This->surface && (dwFlags & DDBLT_COLORFILL))
|
if (This->surface && (dwFlags & DDBLT_COLORFILL))
|
||||||
{
|
{
|
||||||
int dst_w = lpDestRect->right - lpDestRect->left;
|
int dst_w = lpDestRect ? lpDestRect->right - lpDestRect->left : This->width;
|
||||||
int dst_h = lpDestRect->bottom - lpDestRect->top;
|
int dst_h = lpDestRect ? lpDestRect->bottom - lpDestRect->top : This->height;
|
||||||
|
int dst_x = lpDestRect ? lpDestRect->left : 0;
|
||||||
|
int dst_y = lpDestRect ? lpDestRect->top : 0;
|
||||||
|
|
||||||
int y, x;
|
int y, x;
|
||||||
for (y = 0; y < dst_h; y++)
|
for (y = 0; y < dst_h; y++)
|
||||||
{
|
{
|
||||||
int ydst = This->width * (y + lpDestRect->top);
|
int ydst = This->width * (y + dst_y);
|
||||||
|
|
||||||
for (x = 0; x < dst_w; x++)
|
for (x = 0; x < dst_w; x++)
|
||||||
{
|
{
|
||||||
((unsigned char *)This->surface)[x + lpDestRect->left + ydst] = lpDDBltFx->dwFillColor;
|
((unsigned char *)This->surface)[x + dst_x + ydst] = lpDDBltFx->dwFillColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Source)
|
if (Source)
|
||||||
{
|
{
|
||||||
//BitBlt(This->hDC, lpDestRect->left, lpDestRect->top, lpDestRect->right, lpDestRect->bottom,
|
int dx = 0, dy = 0;
|
||||||
// Source->hDC, lpSrcRect->left, lpSrcRect->top, SRCCOPY);
|
if (lpDestRect)
|
||||||
|
|
||||||
int dst_w = lpDestRect->right - lpDestRect->left;
|
|
||||||
int dst_h = lpDestRect->bottom - lpDestRect->top;
|
|
||||||
int src_w = lpSrcRect->right - lpSrcRect->left;
|
|
||||||
int src_h = lpSrcRect->bottom - lpSrcRect->top;
|
|
||||||
|
|
||||||
if (dst_w != src_w || dst_h != src_h)
|
|
||||||
{
|
{
|
||||||
StretchBlt(This->hDC, lpDestRect->left, lpDestRect->top, lpDestRect->right, lpDestRect->bottom,
|
dx = lpDestRect->left;
|
||||||
Source->hDC, lpSrcRect->left, lpSrcRect->top, lpSrcRect->right, lpSrcRect->bottom, SRCCOPY);
|
dy = lpDestRect->top;
|
||||||
}
|
}
|
||||||
else if (dst_w == This->width && dst_h == This->height &&
|
int x0 = 0, y0 = 0, x1 = Source->width, y1 = Source->height;
|
||||||
src_w == Source->width && src_h == Source->height)
|
if (lpSrcRect)
|
||||||
{
|
{
|
||||||
memcpy(This->surface, Source->surface, This->width * This->height * This->lXPitch);
|
x0 = max(x0, lpSrcRect->left);
|
||||||
|
x1 = min(x1, lpSrcRect->right);
|
||||||
|
y0 = max(y0, lpSrcRect->top);
|
||||||
|
y1 = min(y1, lpSrcRect->bottom);
|
||||||
}
|
}
|
||||||
else
|
unsigned char* to = (unsigned char *)This->surface + dy*This->width + dx;
|
||||||
|
unsigned char* from = (unsigned char *)Source->surface + y0*Source->width + x0;
|
||||||
|
int s = x1 - x0;
|
||||||
|
|
||||||
|
int y;
|
||||||
|
for (y = y0; y < y1; ++y, to += This->width, from += Source->width)
|
||||||
{
|
{
|
||||||
int dx=0,dy=0;
|
memcpy(to, from, s);
|
||||||
if (lpDestRect)
|
|
||||||
{
|
|
||||||
dx=lpDestRect->left;
|
|
||||||
dy=lpDestRect->top;
|
|
||||||
}
|
|
||||||
int x0=0,y0=0,x1=Source->width,y1=Source->height;
|
|
||||||
if (lpSrcRect)
|
|
||||||
{
|
|
||||||
x0 = max(x0, lpSrcRect->left);
|
|
||||||
x1 = min(x1, lpSrcRect->right);
|
|
||||||
y0 = max(y0, lpSrcRect->top);
|
|
||||||
y1 = min(y1, lpSrcRect->bottom);
|
|
||||||
}
|
|
||||||
unsigned char* to = (unsigned char *)This->surface + dy*This->width + dx;
|
|
||||||
unsigned char* from = (unsigned char *)Source->surface + y0*Source->width + x0;
|
|
||||||
int s = x1-x0;
|
|
||||||
|
|
||||||
int y;
|
|
||||||
for(y=y0; y<y1; ++y, to+=This->width, from+=Source->width)
|
|
||||||
{
|
|
||||||
memcpy(to, from, s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(This->caps & DDSCAPS_PRIMARYSURFACE && !(This->flags & DDSD_BACKBUFFERCOUNT) && ddraw->render.run)
|
if(This->caps & DDSCAPS_PRIMARYSURFACE && !(This->flags & DDSD_BACKBUFFERCOUNT) && ddraw->render.run)
|
||||||
|
@ -195,9 +175,38 @@ HRESULT __stdcall ddraw_surface_BltBatch(IDirectDrawSurfaceImpl *This, LPDDBLTBA
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT __stdcall ddraw_surface_BltFast(IDirectDrawSurfaceImpl *This, DWORD a, DWORD b, LPDIRECTDRAWSURFACE c, LPRECT d, DWORD e)
|
HRESULT __stdcall ddraw_surface_BltFast(IDirectDrawSurfaceImpl *This, DWORD x, DWORD y, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD flags)
|
||||||
{
|
{
|
||||||
printf("IDirectDrawSurface::BltFast(This=%p, ...)\n", This);
|
printf("IDirectDrawSurface::BltFast(This=%p, ...)\n", This);
|
||||||
|
IDirectDrawSurfaceImpl *Source = (IDirectDrawSurfaceImpl *)lpDDSrcSurface;
|
||||||
|
|
||||||
|
if (Source)
|
||||||
|
{
|
||||||
|
int x0 = 0, y0 = 0, x1 = Source->width, y1 = Source->height;
|
||||||
|
if (lpSrcRect)
|
||||||
|
{
|
||||||
|
x0 = max(x0, lpSrcRect->left);
|
||||||
|
x1 = min(x1, lpSrcRect->right);
|
||||||
|
y0 = max(y0, lpSrcRect->top);
|
||||||
|
y1 = min(y1, lpSrcRect->bottom);
|
||||||
|
}
|
||||||
|
unsigned char* to = (unsigned char *)This->surface + y*This->width + x;
|
||||||
|
unsigned char* from = (unsigned char *)Source->surface + y0*Source->width + x0;
|
||||||
|
int s = x1 - x0;
|
||||||
|
|
||||||
|
int y;
|
||||||
|
for (y = y0; y < y1; ++y, to += This->width, from += Source->width)
|
||||||
|
{
|
||||||
|
memcpy(to, from, s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (This->caps & DDSCAPS_PRIMARYSURFACE && !(This->flags & DDSD_BACKBUFFERCOUNT) && ddraw->render.run)
|
||||||
|
{
|
||||||
|
InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE);
|
||||||
|
ReleaseSemaphore(ddraw->render.sem, 1, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -317,6 +326,7 @@ HRESULT __stdcall ddraw_surface_GetColorKey(IDirectDrawSurfaceImpl *This, DWORD
|
||||||
HRESULT __stdcall ddraw_surface_GetDC(IDirectDrawSurfaceImpl *This, HDC FAR *a)
|
HRESULT __stdcall ddraw_surface_GetDC(IDirectDrawSurfaceImpl *This, HDC FAR *a)
|
||||||
{
|
{
|
||||||
printf("IDirectDrawSurface::GetDC(This=%p, ...)\n", This);
|
printf("IDirectDrawSurface::GetDC(This=%p, ...)\n", This);
|
||||||
|
*a = This->hDC;
|
||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue