mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-15 06:04:49 +01:00
experimental tweaks for diablo and warcraft 2
This commit is contained in:
parent
ee14204ced
commit
0f58746515
@ -1,6 +1,6 @@
|
||||
LIBRARY ddraw.dll
|
||||
|
||||
EXPORTS
|
||||
DirectDrawCreate @1
|
||||
DirectDrawEnumerateA @2
|
||||
GameHandlesClose DATA
|
||||
DirectDrawCreate @1
|
||||
DirectDrawEnumerateA @2
|
||||
GameHandlesClose DATA
|
||||
|
2
ddraw.rc
2
ddraw.rc
@ -21,7 +21,7 @@ PRODUCTVERSION VERSION
|
||||
VALUE "FileDescription", "DirectDraw replacement"
|
||||
VALUE "FileVersion", VERSION_STRING
|
||||
VALUE "InternalName", "ddraw"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2010-2018"
|
||||
VALUE "LegalCopyright", "Copyright (c) 2010-2019"
|
||||
VALUE "LegalTrademarks", ""
|
||||
VALUE "OriginalFileName", "ddraw.dll"
|
||||
VALUE "ProductName", "cnc-ddraw"
|
||||
|
@ -125,6 +125,8 @@ typedef struct IDirectDrawImpl
|
||||
BOOL altenter;
|
||||
BOOL hidecursor;
|
||||
BOOL accurateTimers;
|
||||
int bnetHack;
|
||||
BOOL bnetActive;
|
||||
SpeedLimiter ticksLimiter;
|
||||
SpeedLimiter flipLimiter;
|
||||
SpeedLimiter fpsLimiter;
|
||||
|
136
src/main.c
136
src/main.c
@ -1161,51 +1161,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
break;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE)
|
||||
{
|
||||
if (!ddraw->windowed)
|
||||
{
|
||||
if (!Direct3D9Active)
|
||||
{
|
||||
ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN);
|
||||
|
||||
if (wParam == WA_ACTIVE)
|
||||
{
|
||||
mouse_lock();
|
||||
}
|
||||
}
|
||||
|
||||
InterlockedExchange(&ddraw->minimized, FALSE);
|
||||
}
|
||||
|
||||
if (!ddraw->handlemouse)
|
||||
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||
}
|
||||
else if (wParam == WA_INACTIVE)
|
||||
{
|
||||
if (!ddraw->windowed && !ddraw->locked && ddraw->noactivateapp)
|
||||
return 0;
|
||||
|
||||
mouse_unlock();
|
||||
|
||||
if (ddraw->wine && LastSetWindowPosTick + 500 > timeGetTime())
|
||||
return 0;
|
||||
|
||||
/* minimize our window on defocus when in fullscreen */
|
||||
if (!ddraw->windowed)
|
||||
{
|
||||
if (!Direct3D9Active)
|
||||
{
|
||||
ShowWindow(ddraw->hWnd, SW_MINIMIZE);
|
||||
ChangeDisplaySettings(&ddraw->mode, 0);
|
||||
}
|
||||
|
||||
InterlockedExchange(&ddraw->minimized, TRUE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
//workaround for a bug where sometimes a background window steals the focus
|
||||
case WM_WINDOWPOSCHANGING:
|
||||
{
|
||||
@ -1228,7 +1183,77 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
mouse_unlock();
|
||||
return 0;
|
||||
|
||||
|
||||
case WM_ENABLE:
|
||||
{
|
||||
if (ddraw->bnetHack)
|
||||
{
|
||||
if (wParam)
|
||||
mouse_lock();
|
||||
else
|
||||
mouse_unlock();
|
||||
|
||||
HWND hWnd = FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL);
|
||||
if (hWnd)
|
||||
{
|
||||
RECT rc;
|
||||
if (GetWindowRect(hWnd, &rc) && (rc.bottom - rc.top != 479))
|
||||
while (ShowCursor(FALSE) > 0);
|
||||
}
|
||||
|
||||
ddraw->bnetActive = !wParam;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case WM_ACTIVATE:
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_ACTIVATEAPP:
|
||||
|
||||
if (wParam)
|
||||
{
|
||||
if (!ddraw->windowed)
|
||||
{
|
||||
if (!Direct3D9Active)
|
||||
{
|
||||
ChangeDisplaySettings(&ddraw->render.mode, CDS_FULLSCREEN);
|
||||
|
||||
mouse_lock();
|
||||
}
|
||||
|
||||
InterlockedExchange(&ddraw->minimized, FALSE);
|
||||
}
|
||||
|
||||
if (!ddraw->handlemouse)
|
||||
RedrawWindow(hWnd, NULL, NULL, RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ddraw->windowed && !ddraw->locked && ddraw->noactivateapp)
|
||||
goto aapp_end;
|
||||
|
||||
mouse_unlock();
|
||||
|
||||
if (ddraw->wine && LastSetWindowPosTick + 500 > timeGetTime())
|
||||
goto aapp_end;
|
||||
|
||||
/* minimize our window on defocus when in fullscreen */
|
||||
if (!ddraw->windowed)
|
||||
{
|
||||
if (!Direct3D9Active)
|
||||
{
|
||||
ShowWindow(ddraw->hWnd, SW_MINIMIZE);
|
||||
ChangeDisplaySettings(&ddraw->mode, 0);
|
||||
}
|
||||
|
||||
InterlockedExchange(&ddraw->minimized, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
aapp_end:
|
||||
/* C&C and RA stop drawing when they receive this with FALSE wParam, disable in windowed mode */
|
||||
if (ddraw->windowed || ddraw->noactivateapp)
|
||||
{
|
||||
@ -1619,6 +1644,16 @@ HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACK lpCallback, LPVOID lpContex
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
//Force redraw when the "Player Profile" screen exits - Idea taken from Aqrit's war2 ddraw
|
||||
static WNDPROC ButtonWndProc_original;
|
||||
LRESULT __stdcall ButtonWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == WM_DESTROY)
|
||||
RedrawWindow(NULL, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_ALLCHILDREN);
|
||||
|
||||
return ButtonWndProc_original(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
int stdout_open = 0;
|
||||
HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter)
|
||||
{
|
||||
@ -1668,5 +1703,16 @@ HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnk
|
||||
|
||||
Settings_Load();
|
||||
|
||||
if (ddraw->bnetHack)
|
||||
{
|
||||
WNDCLASS wc;
|
||||
HINSTANCE hInst = GetModuleHandle(NULL);
|
||||
GetClassInfo(NULL, "Button", &wc);
|
||||
wc.hInstance = hInst;
|
||||
ButtonWndProc_original = wc.lpfnWndProc;
|
||||
wc.lpfnWndProc = ButtonWndProc;
|
||||
RegisterClass(&wc);
|
||||
}
|
||||
|
||||
return DD_OK;
|
||||
}
|
||||
|
@ -250,7 +250,7 @@ void mouse_lock()
|
||||
|
||||
if (ddraw->handlemouse)
|
||||
{
|
||||
SetCapture(ddraw->hWnd);
|
||||
//SetCapture(ddraw->hWnd);
|
||||
ClipCursor(&rc);
|
||||
while (ShowCursor(FALSE) > 0);
|
||||
}
|
||||
@ -315,7 +315,7 @@ void mouse_unlock()
|
||||
}
|
||||
|
||||
ClipCursor(NULL);
|
||||
ReleaseCapture();
|
||||
//ReleaseCapture();
|
||||
|
||||
SetCursorPos(
|
||||
rc.left + ddraw->render.viewport.x + (ddraw->cursor.x * ddraw->render.scaleW),
|
||||
|
@ -787,6 +787,9 @@ static void Render()
|
||||
glEnd();
|
||||
}
|
||||
|
||||
if (ddraw->bnetActive)
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
SwapBuffers(ddraw->render.hDC);
|
||||
|
||||
#if _DEBUG
|
||||
|
@ -410,6 +410,9 @@ DWORD WINAPI render_d3d9_main(void)
|
||||
IDirect3DDevice9_DrawPrimitive(D3dDev, D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
IDirect3DDevice9_EndScene(D3dDev);
|
||||
|
||||
if (ddraw->bnetActive)
|
||||
IDirect3DDevice9_Clear(D3dDev, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
|
||||
|
||||
if (FAILED(IDirect3DDevice9_Present(D3dDev, NULL, NULL, NULL, NULL)))
|
||||
{
|
||||
DWORD_PTR dwResult;
|
||||
|
@ -103,7 +103,12 @@ DWORD WINAPI render_soft_main(void)
|
||||
EnumChildWindows(ddraw->hWnd, EnumChildProc, (LPARAM)ddraw->primary);
|
||||
}
|
||||
|
||||
if (scaleCutscene)
|
||||
if (ddraw->bnetActive)
|
||||
{
|
||||
RECT rc = { 0, 0, ddraw->render.width, ddraw->render.height };
|
||||
FillRect(ddraw->render.hDC, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
||||
}
|
||||
else if (scaleCutscene)
|
||||
{
|
||||
StretchDIBits(
|
||||
ddraw->render.hDC,
|
||||
|
@ -49,6 +49,8 @@ void Settings_Load()
|
||||
|
||||
ddraw->render.maxfps = GetInt("maxfps", 125);
|
||||
|
||||
ddraw->bnetHack = GetBool("bnetHack", TRUE);
|
||||
|
||||
if (ddraw->accurateTimers || ddraw->vsync)
|
||||
ddraw->fpsLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||
//can't fully set it up here due to missing ddraw->mode.dmDisplayFrequency
|
||||
@ -102,6 +104,9 @@ void Settings_Load()
|
||||
GetString("renderer", "auto", tmp, sizeof(tmp));
|
||||
printf("Using %s renderer\n", tmp);
|
||||
|
||||
if (ddraw->bnetHack && tolower(tmp[0]) != 'g')
|
||||
ddraw->windowed = TRUE;
|
||||
|
||||
if (tolower(tmp[0]) == 's' || tolower(tmp[0]) == 'g') //gdi
|
||||
{
|
||||
ddraw->renderer = render_soft_main;
|
||||
@ -274,6 +279,10 @@ static void CreateSettingsIni()
|
||||
"; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact\n"
|
||||
"singlecpu=true\n"
|
||||
"\n"
|
||||
"; Workaround for battle.net on Diablo and Warcraft 2 BNE\n"
|
||||
"; Note: This hack as a negative side-effect, you can only play fullscreen with 'renderer=gdi' or via 'fullscreen=true'\n"
|
||||
"bnetHack=false\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"\n"
|
||||
"; ### Game specific settings ###\n"
|
||||
@ -389,11 +398,13 @@ static void CreateSettingsIni()
|
||||
"handlemouse=false\n"
|
||||
"maxfps=60\n"
|
||||
"\n"
|
||||
"; Command & Conquer: Red Alert 2: Yuri's Revenge - XWIS\n"
|
||||
"[Yuri's Revenge]\n"
|
||||
"noactivateapp=true\n"
|
||||
"handlemouse=false\n"
|
||||
"maxfps=60\n"
|
||||
"; Diablo\n"
|
||||
"[Diablo]\n"
|
||||
"bnetHack=true\n"
|
||||
"\n"
|
||||
"; Warcraft 2 Battle.net Edition\n"
|
||||
"[Warcraft II BNE]\n"
|
||||
"bnetHack=true\n"
|
||||
"\n"
|
||||
|
||||
, fh);
|
||||
|
@ -992,6 +992,55 @@ HRESULT __stdcall ddraw_surface_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRe
|
||||
printf("DirectDrawSurface::Unlock(This=%p, lpRect=%p)\n", This, lpRect);
|
||||
#endif
|
||||
|
||||
HWND hWnd = ddraw->bnetHack ? FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL) : NULL;
|
||||
if (hWnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
|
||||
{
|
||||
if (ddraw->primary->palette && ddraw->primary->palette->data_rgb)
|
||||
SetDIBColorTable(ddraw->primary->hDC, 0, 256, ddraw->primary->palette->data_rgb);
|
||||
|
||||
//GdiTransparentBlt idea taken from Aqrit's war2 ddraw
|
||||
|
||||
RGBQUAD quad;
|
||||
GetDIBColorTable(ddraw->primary->hDC, 0xFE, 1, &quad);
|
||||
COLORREF color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
|
||||
BOOL erase = FALSE;
|
||||
|
||||
do
|
||||
{
|
||||
RECT rc;
|
||||
if (GetWindowRect(hWnd, &rc))
|
||||
{
|
||||
if (rc.bottom - rc.top == 479)
|
||||
erase = TRUE;
|
||||
|
||||
HDC hDC = GetDCEx(hWnd, NULL, DCX_PARENTCLIP | DCX_CACHE);
|
||||
|
||||
GdiTransparentBlt(
|
||||
hDC,
|
||||
0,
|
||||
0,
|
||||
rc.right - rc.left,
|
||||
rc.bottom - rc.top,
|
||||
ddraw->primary->hDC,
|
||||
rc.left,
|
||||
rc.top,
|
||||
rc.right - rc.left,
|
||||
rc.bottom - rc.top,
|
||||
color
|
||||
);
|
||||
|
||||
ReleaseDC(hWnd, hDC);
|
||||
}
|
||||
|
||||
} while ((hWnd = FindWindowEx(HWND_DESKTOP, hWnd, "SDlgDialog", NULL)));
|
||||
|
||||
if (erase)
|
||||
{
|
||||
DDBLTFX fx = { .dwFillColor = 0xFE };
|
||||
IDirectDrawSurface_Blt(This, NULL, NULL, NULL, DDBLT_COLORFILL, &fx);
|
||||
}
|
||||
}
|
||||
|
||||
if (This->caps & DDSCAPS_PRIMARYSURFACE &&
|
||||
ddraw->render.run &&
|
||||
(!(This->flags & DDSD_BACKBUFFERCOUNT) || This->lastFlipTick + FLIP_REDRAW_TIMEOUT < timeGetTime()))
|
||||
|
Loading…
x
Reference in New Issue
Block a user