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:
parent
ee14204ced
commit
0f58746515
@ -1,6 +1,6 @@
|
|||||||
LIBRARY ddraw.dll
|
LIBRARY ddraw.dll
|
||||||
|
|
||||||
EXPORTS
|
EXPORTS
|
||||||
DirectDrawCreate @1
|
DirectDrawCreate @1
|
||||||
DirectDrawEnumerateA @2
|
DirectDrawEnumerateA @2
|
||||||
GameHandlesClose DATA
|
GameHandlesClose DATA
|
||||||
|
2
ddraw.rc
2
ddraw.rc
@ -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"
|
||||||
|
@ -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;
|
||||||
|
136
src/main.c
136
src/main.c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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()))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user