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 fakecursorpos;
|
||||
BOOL noactivateapp;
|
||||
BOOL hidemouse;
|
||||
char shader[MAX_PATH];
|
||||
BOOL wine;
|
||||
int sleep;
|
||||
|
|
44
src/main.c
44
src/main.c
|
@ -145,9 +145,41 @@ HRESULT __stdcall ddraw_DuplicateSurface(IDirectDrawImpl *This, LPDIRECTDRAWSURF
|
|||
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;
|
||||
}
|
||||
|
||||
|
@ -283,6 +315,8 @@ 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);
|
||||
|
||||
if (!This->mode.dmPelsWidth)
|
||||
{
|
||||
This->mode.dmSize = sizeof(DEVMODE);
|
||||
This->mode.dmDriverExtra = 0;
|
||||
|
||||
|
@ -291,6 +325,12 @@ HRESULT __stdcall ddraw_SetDisplayMode(IDirectDrawImpl *This, DWORD width, DWORD
|
|||
/* 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->height = height;
|
||||
|
|
15
src/mouse.c
15
src/mouse.c
|
@ -134,11 +134,17 @@ BOOL WINAPI fake_ClipCursor(const RECT *lpRect)
|
|||
|
||||
int WINAPI fake_ShowCursor(BOOL bShow)
|
||||
{
|
||||
if (ddraw && !ddraw->hidemouse)
|
||||
return ShowCursor(bShow);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HCURSOR WINAPI fake_SetCursor(HCURSOR hCursor)
|
||||
{
|
||||
if (ddraw && !ddraw->hidemouse)
|
||||
return SetCursor(hCursor);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -211,7 +217,9 @@ void mouse_lock()
|
|||
|
||||
if (ddraw->devmode)
|
||||
{
|
||||
if (ddraw->hidemouse)
|
||||
while(ShowCursor(FALSE) > 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -255,7 +263,9 @@ void mouse_lock()
|
|||
SetCapture(ddraw->hWnd);
|
||||
ClipCursor(&rc);
|
||||
|
||||
if (ddraw->hidemouse)
|
||||
while(ShowCursor(FALSE) > 0);
|
||||
|
||||
ddraw->locked = TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +276,9 @@ void mouse_unlock()
|
|||
|
||||
if (ddraw->devmode)
|
||||
{
|
||||
if (ddraw->hidemouse)
|
||||
while(ShowCursor(TRUE) < 0);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -289,8 +301,11 @@ void mouse_unlock()
|
|||
ClientToScreen(ddraw->hWnd, &pt2);
|
||||
SetRect(&rc, pt.x, pt.y, pt2.x, pt2.y);
|
||||
|
||||
if (ddraw->hidemouse)
|
||||
{
|
||||
while (ShowCursor(TRUE) < 0);
|
||||
SetCursor(LoadCursor(NULL, IDC_ARROW));
|
||||
}
|
||||
|
||||
ClipCursor(NULL);
|
||||
ReleaseCapture();
|
||||
|
|
|
@ -41,6 +41,7 @@ void Settings_Load()
|
|||
ddraw->fakecursorpos = GetBool("fakecursorpos", TRUE);
|
||||
ddraw->noactivateapp = GetBool("noactivateapp", FALSE);
|
||||
ddraw->vhack = GetBool("vhack", FALSE);
|
||||
ddraw->hidemouse = GetBool("hidemouse", TRUE);
|
||||
|
||||
ddraw->sleep = GetInt("sleep", 0);
|
||||
ddraw->render.maxfps = GetInt("maxfps", 125);
|
||||
|
@ -184,6 +185,8 @@ static void CreateSettingsIni()
|
|||
"shader=\n"
|
||||
"; Sleep for X ms after drawing each frame (Slows down scrollrate on C&C95 / Prevents visual glitches on Carmageddon)\n"
|
||||
"sleep=0\n"
|
||||
"; Hide/Show the mouse cursor on lock/unlock (Ctrl+Tab)\n"
|
||||
"hidemouse=true\n"
|
||||
"\n"
|
||||
"[CARMA95]\n"
|
||||
"fakecursorpos=false\n"
|
||||
|
@ -193,6 +196,11 @@ static void CreateSettingsIni()
|
|||
"[C&C95]\n"
|
||||
"sleep=10\n"
|
||||
"\n"
|
||||
"[EMPIRES2]\n"
|
||||
"renderer=gdi\n"
|
||||
"hidemouse=false\n"
|
||||
"border=false\n"
|
||||
"\n"
|
||||
|
||||
, fh);
|
||||
fclose(fh);
|
||||
|
|
|
@ -104,42 +104,24 @@ HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestR
|
|||
|
||||
if (This->surface && (dwFlags & DDBLT_COLORFILL))
|
||||
{
|
||||
int dst_w = lpDestRect->right - lpDestRect->left;
|
||||
int dst_h = lpDestRect->bottom - lpDestRect->top;
|
||||
int dst_w = lpDestRect ? lpDestRect->right - lpDestRect->left : This->width;
|
||||
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;
|
||||
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++)
|
||||
{
|
||||
((unsigned char *)This->surface)[x + lpDestRect->left + ydst] = lpDDBltFx->dwFillColor;
|
||||
((unsigned char *)This->surface)[x + dst_x + ydst] = lpDDBltFx->dwFillColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Source)
|
||||
{
|
||||
//BitBlt(This->hDC, lpDestRect->left, lpDestRect->top, lpDestRect->right, lpDestRect->bottom,
|
||||
// Source->hDC, lpSrcRect->left, lpSrcRect->top, SRCCOPY);
|
||||
|
||||
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,
|
||||
Source->hDC, lpSrcRect->left, lpSrcRect->top, lpSrcRect->right, lpSrcRect->bottom, SRCCOPY);
|
||||
}
|
||||
else if (dst_w == This->width && dst_h == This->height &&
|
||||
src_w == Source->width && src_h == Source->height)
|
||||
{
|
||||
memcpy(This->surface, Source->surface, This->width * This->height * This->lXPitch);
|
||||
}
|
||||
else
|
||||
{
|
||||
int dx = 0, dy = 0;
|
||||
if (lpDestRect)
|
||||
|
@ -166,8 +148,6 @@ HRESULT __stdcall ddraw_surface_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestR
|
|||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(This->caps & DDSCAPS_PRIMARYSURFACE && !(This->flags & DDSD_BACKBUFFERCOUNT) && ddraw->render.run)
|
||||
{
|
||||
InterlockedExchange(&ddraw->render.surfaceUpdated, TRUE);
|
||||
|
@ -195,9 +175,38 @@ HRESULT __stdcall ddraw_surface_BltBatch(IDirectDrawSurfaceImpl *This, LPDDBLTBA
|
|||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -317,6 +326,7 @@ HRESULT __stdcall ddraw_surface_GetColorKey(IDirectDrawSurfaceImpl *This, DWORD
|
|||
HRESULT __stdcall ddraw_surface_GetDC(IDirectDrawSurfaceImpl *This, HDC FAR *a)
|
||||
{
|
||||
printf("IDirectDrawSurface::GetDC(This=%p, ...)\n", This);
|
||||
*a = This->hDC;
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue