diff --git a/inc/main.h b/inc/main.h index eb6af74..c19c6fd 100644 --- a/inc/main.h +++ b/inc/main.h @@ -102,6 +102,7 @@ typedef struct IDirectDrawImpl BOOL maintas; BOOL fakecursorpos; BOOL noactivateapp; + BOOL hidemouse; char shader[MAX_PATH]; BOOL wine; int sleep; diff --git a/src/main.c b/src/main.c index 07c4a28..ef285cf 100644 --- a/src/main.c +++ b/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,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); - This->mode.dmSize = sizeof(DEVMODE); - This->mode.dmDriverExtra = 0; - - if(EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &This->mode) == FALSE) + if (!This->mode.dmPelsWidth) { - /* not expected */ - return DDERR_UNSUPPORTED; + This->mode.dmSize = sizeof(DEVMODE); + 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; diff --git a/src/mouse.c b/src/mouse.c index e2e2a13..595f5d4 100644 --- a/src/mouse.c +++ b/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) { - while(ShowCursor(FALSE) > 0); + if (ddraw->hidemouse) + while(ShowCursor(FALSE) > 0); + return; } @@ -255,7 +263,9 @@ void mouse_lock() SetCapture(ddraw->hWnd); ClipCursor(&rc); - while(ShowCursor(FALSE) > 0); + if (ddraw->hidemouse) + while(ShowCursor(FALSE) > 0); + ddraw->locked = TRUE; } } @@ -266,7 +276,9 @@ void mouse_unlock() if (ddraw->devmode) { - while(ShowCursor(TRUE) < 0); + 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); - while(ShowCursor(TRUE) < 0); - SetCursor(LoadCursor(NULL, IDC_ARROW)); + if (ddraw->hidemouse) + { + while (ShowCursor(TRUE) < 0); + SetCursor(LoadCursor(NULL, IDC_ARROW)); + } ClipCursor(NULL); ReleaseCapture(); diff --git a/src/settings.c b/src/settings.c index 5959427..2f83a5e 100644 --- a/src/settings.c +++ b/src/settings.c @@ -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); diff --git a/src/surface.c b/src/surface.c index 0488767..73eea25 100644 --- a/src/surface.c +++ b/src/surface.c @@ -104,68 +104,48 @@ 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) + 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) + int dx = 0, dy = 0; + if (lpDestRect) { - StretchBlt(This->hDC, lpDestRect->left, lpDestRect->top, lpDestRect->right, lpDestRect->bottom, - Source->hDC, lpSrcRect->left, lpSrcRect->top, lpSrcRect->right, lpSrcRect->bottom, SRCCOPY); + dx = lpDestRect->left; + dy = lpDestRect->top; } - else if (dst_w == This->width && dst_h == This->height && - src_w == Source->width && src_h == Source->height) + int x0 = 0, y0 = 0, x1 = Source->width, y1 = 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; - 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; ywidth, from+=Source->width) - { - memcpy(to, from, s); - } + memcpy(to, from, s); } - } 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; } -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; }