1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-24 17:49:52 +01:00

experimental tweaks for diablo and warcraft 2

This commit is contained in:
FunkyFr3sh 2019-03-17 00:16:09 +01:00
parent ee14204ced
commit 0f58746515
10 changed files with 176 additions and 57 deletions

View File

@ -1,6 +1,6 @@
LIBRARY ddraw.dll LIBRARY ddraw.dll
EXPORTS EXPORTS
DirectDrawCreate @1 DirectDrawCreate @1
DirectDrawEnumerateA @2 DirectDrawEnumerateA @2
GameHandlesClose DATA GameHandlesClose DATA

View File

@ -21,7 +21,7 @@ PRODUCTVERSION VERSION
VALUE "FileDescription", "DirectDraw replacement" VALUE "FileDescription", "DirectDraw replacement"
VALUE "FileVersion", VERSION_STRING VALUE "FileVersion", VERSION_STRING
VALUE "InternalName", "ddraw" VALUE "InternalName", "ddraw"
VALUE "LegalCopyright", "Copyright (c) 2010-2018" VALUE "LegalCopyright", "Copyright (c) 2010-2019"
VALUE "LegalTrademarks", "" VALUE "LegalTrademarks", ""
VALUE "OriginalFileName", "ddraw.dll" VALUE "OriginalFileName", "ddraw.dll"
VALUE "ProductName", "cnc-ddraw" VALUE "ProductName", "cnc-ddraw"

View File

@ -125,6 +125,8 @@ typedef struct IDirectDrawImpl
BOOL altenter; BOOL altenter;
BOOL hidecursor; BOOL hidecursor;
BOOL accurateTimers; BOOL accurateTimers;
int bnetHack;
BOOL bnetActive;
SpeedLimiter ticksLimiter; SpeedLimiter ticksLimiter;
SpeedLimiter flipLimiter; SpeedLimiter flipLimiter;
SpeedLimiter fpsLimiter; SpeedLimiter fpsLimiter;

View File

@ -1161,51 +1161,6 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
break; 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 //workaround for a bug where sometimes a background window steals the focus
case WM_WINDOWPOSCHANGING: case WM_WINDOWPOSCHANGING:
{ {
@ -1228,7 +1183,77 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
mouse_unlock(); mouse_unlock();
return 0; 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: 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 */ /* C&C and RA stop drawing when they receive this with FALSE wParam, disable in windowed mode */
if (ddraw->windowed || ddraw->noactivateapp) if (ddraw->windowed || ddraw->noactivateapp)
{ {
@ -1619,6 +1644,16 @@ HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACK lpCallback, LPVOID lpContex
return DD_OK; 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; int stdout_open = 0;
HRESULT WINAPI DirectDrawCreate(GUID FAR* lpGUID, LPDIRECTDRAW FAR* lplpDD, IUnknown FAR* pUnkOuter) 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(); 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; return DD_OK;
} }

View File

@ -250,7 +250,7 @@ void mouse_lock()
if (ddraw->handlemouse) if (ddraw->handlemouse)
{ {
SetCapture(ddraw->hWnd); //SetCapture(ddraw->hWnd);
ClipCursor(&rc); ClipCursor(&rc);
while (ShowCursor(FALSE) > 0); while (ShowCursor(FALSE) > 0);
} }
@ -315,7 +315,7 @@ void mouse_unlock()
} }
ClipCursor(NULL); ClipCursor(NULL);
ReleaseCapture(); //ReleaseCapture();
SetCursorPos( SetCursorPos(
rc.left + ddraw->render.viewport.x + (ddraw->cursor.x * ddraw->render.scaleW), rc.left + ddraw->render.viewport.x + (ddraw->cursor.x * ddraw->render.scaleW),

View File

@ -787,6 +787,9 @@ static void Render()
glEnd(); glEnd();
} }
if (ddraw->bnetActive)
glClear(GL_COLOR_BUFFER_BIT);
SwapBuffers(ddraw->render.hDC); SwapBuffers(ddraw->render.hDC);
#if _DEBUG #if _DEBUG

View File

@ -410,6 +410,9 @@ DWORD WINAPI render_d3d9_main(void)
IDirect3DDevice9_DrawPrimitive(D3dDev, D3DPT_TRIANGLESTRIP, 0, 2); IDirect3DDevice9_DrawPrimitive(D3dDev, D3DPT_TRIANGLESTRIP, 0, 2);
IDirect3DDevice9_EndScene(D3dDev); 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))) if (FAILED(IDirect3DDevice9_Present(D3dDev, NULL, NULL, NULL, NULL)))
{ {
DWORD_PTR dwResult; DWORD_PTR dwResult;

View File

@ -103,7 +103,12 @@ DWORD WINAPI render_soft_main(void)
EnumChildWindows(ddraw->hWnd, EnumChildProc, (LPARAM)ddraw->primary); 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( StretchDIBits(
ddraw->render.hDC, ddraw->render.hDC,

View File

@ -49,6 +49,8 @@ void Settings_Load()
ddraw->render.maxfps = GetInt("maxfps", 125); ddraw->render.maxfps = GetInt("maxfps", 125);
ddraw->bnetHack = GetBool("bnetHack", TRUE);
if (ddraw->accurateTimers || ddraw->vsync) if (ddraw->accurateTimers || ddraw->vsync)
ddraw->fpsLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL); ddraw->fpsLimiter.hTimer = CreateWaitableTimer(NULL, TRUE, NULL);
//can't fully set it up here due to missing ddraw->mode.dmDisplayFrequency //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)); GetString("renderer", "auto", tmp, sizeof(tmp));
printf("Using %s renderer\n", 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 if (tolower(tmp[0]) == 's' || tolower(tmp[0]) == 'g') //gdi
{ {
ddraw->renderer = render_soft_main; ddraw->renderer = render_soft_main;
@ -274,6 +279,10 @@ static void CreateSettingsIni()
"; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact\n" "; Force CPU0 affinity, avoids crashes/freezing, *might* have a performance impact\n"
"singlecpu=true\n" "singlecpu=true\n"
"\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"
"\n" "\n"
"; ### Game specific settings ###\n" "; ### Game specific settings ###\n"
@ -389,11 +398,13 @@ static void CreateSettingsIni()
"handlemouse=false\n" "handlemouse=false\n"
"maxfps=60\n" "maxfps=60\n"
"\n" "\n"
"; Command & Conquer: Red Alert 2: Yuri's Revenge - XWIS\n" "; Diablo\n"
"[Yuri's Revenge]\n" "[Diablo]\n"
"noactivateapp=true\n" "bnetHack=true\n"
"handlemouse=false\n" "\n"
"maxfps=60\n" "; Warcraft 2 Battle.net Edition\n"
"[Warcraft II BNE]\n"
"bnetHack=true\n"
"\n" "\n"
, fh); , fh);

View File

@ -992,6 +992,55 @@ HRESULT __stdcall ddraw_surface_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRe
printf("DirectDrawSurface::Unlock(This=%p, lpRect=%p)\n", This, lpRect); printf("DirectDrawSurface::Unlock(This=%p, lpRect=%p)\n", This, lpRect);
#endif #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 && if (This->caps & DDSCAPS_PRIMARYSURFACE &&
ddraw->render.run && ddraw->render.run &&
(!(This->flags & DDSD_BACKBUFFERCOUNT) || This->lastFlipTick + FLIP_REDRAW_TIMEOUT < timeGetTime())) (!(This->flags & DDSD_BACKBUFFERCOUNT) || This->lastFlipTick + FLIP_REDRAW_TIMEOUT < timeGetTime()))