implement EnumDisplayModes and BltFast - Fixes DDBLT_COLORFILL with NULL rect - support resolution changes during runtime (AoE2)

This commit is contained in:
FunkyFr3sh 2018-10-26 05:27:10 +02:00
parent 25627134e7
commit cbc66c3bc2
5 changed files with 132 additions and 58 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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();

View file

@ -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);

View file

@ -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;
} }