mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-15 06:04:49 +01:00
add OBS game capture support for bnet lobby
This commit is contained in:
parent
b4cb502f6a
commit
6a241ca0ae
@ -30,6 +30,10 @@ typedef struct IDirectDrawSurfaceImpl
|
||||
DWORD l_pitch;
|
||||
DWORD lx_pitch;
|
||||
|
||||
void* bnet_surface;
|
||||
HDC bnet_dc;
|
||||
HBITMAP bnet_bitmap;
|
||||
|
||||
PBITMAPINFO bmi;
|
||||
HBITMAP bitmap;
|
||||
HDC hdc;
|
||||
|
@ -33,6 +33,6 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect);
|
||||
HRESULT dds_GetDDInterface(IDirectDrawSurfaceImpl* This, LPVOID* lplpDD);
|
||||
void* dds_GetBuffer(IDirectDrawSurfaceImpl* This);
|
||||
HRESULT dd_CreateSurface(IDirectDrawImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc, IDirectDrawSurfaceImpl** lpDDSurface, IUnknown FAR* unkOuter);
|
||||
|
||||
void dds_RedrawBnet(IDirectDrawSurfaceImpl* This);
|
||||
|
||||
#endif
|
||||
|
@ -9,6 +9,7 @@
|
||||
#define WM_DISPLAYCHANGE_DDRAW WM_APP+116
|
||||
|
||||
#define IDT_TIMER_LEAVE_BNET 541287654
|
||||
#define IDT_TIMER_REDRAW_BNET 541287655
|
||||
|
||||
LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
|
@ -90,9 +90,21 @@ ULONG __stdcall IDirectDrawSurface__Release(IDirectDrawSurfaceImpl* This)
|
||||
HeapFree(GetProcessHeap(), 0, This->surface);
|
||||
}
|
||||
|
||||
if (This->bnet_bitmap)
|
||||
{
|
||||
DeleteObject(This->bnet_bitmap);
|
||||
}
|
||||
else if (This->bnet_surface)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This->bnet_surface);
|
||||
}
|
||||
|
||||
if (This->hdc)
|
||||
DeleteDC(This->hdc);
|
||||
|
||||
if (This->bnet_dc)
|
||||
DeleteDC(This->bnet_dc);
|
||||
|
||||
if (This->bmi)
|
||||
HeapFree(GetProcessHeap(), 0, This->bmi);
|
||||
|
||||
|
@ -1190,28 +1190,39 @@ HRESULT dds_SetPalette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* lpD
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect)
|
||||
void dds_RedrawBnet(IDirectDrawSurfaceImpl* This)
|
||||
{
|
||||
/* Hack for Warcraft II BNE and Diablo */
|
||||
HWND hwnd = g_ddraw->bnet_active ? FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL) : NULL;
|
||||
|
||||
if (hwnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
|
||||
if (hwnd)
|
||||
{
|
||||
HDC primary_dc;
|
||||
dds_GetDC(This, &primary_dc);
|
||||
|
||||
if (g_ddraw->primary->palette)
|
||||
{
|
||||
SetDIBColorTable(g_ddraw->primary->bnet_dc, 0, 256, g_ddraw->primary->palette->data_rgb);
|
||||
}
|
||||
|
||||
/* GdiTransparentBlt idea taken from Aqrit's war2 ddraw */
|
||||
|
||||
RGBQUAD quad;
|
||||
GetDIBColorTable(primary_dc, 0xFE, 1, &quad);
|
||||
COLORREF color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
|
||||
BOOL erase = FALSE;
|
||||
HWND hwnd_bnet[20];
|
||||
int i = 0;
|
||||
|
||||
memset(&hwnd_bnet[0], 0, sizeof(hwnd_bnet));
|
||||
|
||||
do
|
||||
{
|
||||
RECT rc;
|
||||
if (fake_GetWindowRect(hwnd, &rc))
|
||||
{
|
||||
hwnd_bnet[i++] = hwnd;
|
||||
|
||||
if (rc.bottom - rc.top == 479)
|
||||
erase = TRUE;
|
||||
|
||||
@ -1236,6 +1247,36 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect)
|
||||
|
||||
} while ((hwnd = FindWindowEx(HWND_DESKTOP, hwnd, "SDlgDialog", NULL)));
|
||||
|
||||
/* hack for windows 8/10 fullscreen exclusive mode */
|
||||
EnterCriticalSection(&g_ddraw->cs);
|
||||
|
||||
for (i = sizeof(hwnd_bnet) / sizeof(hwnd_bnet[0]); i--; )
|
||||
{
|
||||
if (hwnd_bnet[i])
|
||||
{
|
||||
RECT rc;
|
||||
if (fake_GetWindowRect(hwnd_bnet[i], &rc))
|
||||
{
|
||||
HDC dc = GetDC(hwnd_bnet[i]);
|
||||
|
||||
BitBlt(
|
||||
g_ddraw->primary->bnet_dc,
|
||||
rc.left,
|
||||
rc.top,
|
||||
rc.right - rc.left,
|
||||
rc.bottom - rc.top,
|
||||
dc,
|
||||
0,
|
||||
0,
|
||||
SRCCOPY);
|
||||
|
||||
ReleaseDC(hwnd_bnet[i], dc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&g_ddraw->cs);
|
||||
|
||||
if (erase)
|
||||
{
|
||||
BOOL x = g_ddraw->ticks_limiter.use_blt_or_flip;
|
||||
@ -1245,10 +1286,21 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect)
|
||||
|
||||
g_ddraw->ticks_limiter.use_blt_or_flip = x;
|
||||
}
|
||||
|
||||
if (g_ddraw->render.run)
|
||||
ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect)
|
||||
{
|
||||
if ((This->caps & DDSCAPS_PRIMARYSURFACE))
|
||||
{
|
||||
dds_RedrawBnet(This);
|
||||
}
|
||||
|
||||
/* Hack for Star Trek Armada */
|
||||
hwnd = g_ddraw->armadahack ? FindWindowEx(HWND_DESKTOP, NULL, "#32770", NULL) : NULL;
|
||||
HWND hwnd = g_ddraw->armadahack ? FindWindowEx(HWND_DESKTOP, NULL, "#32770", NULL) : NULL;
|
||||
|
||||
if (hwnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
|
||||
{
|
||||
@ -1471,6 +1523,26 @@ HRESULT dd_CreateSurface(
|
||||
{
|
||||
g_ddraw->primary = dst_surface;
|
||||
FakePrimarySurface = dst_surface->surface;
|
||||
|
||||
dst_surface->bnet_dc = CreateCompatibleDC(g_ddraw->render.hdc);
|
||||
|
||||
dst_surface->bnet_bitmap =
|
||||
CreateDIBSection(
|
||||
dst_surface->bnet_dc,
|
||||
dst_surface->bmi,
|
||||
DIB_RGB_COLORS,
|
||||
(void**)&dst_surface->bnet_surface, NULL, 0);
|
||||
|
||||
if (!dst_surface->bnet_bitmap)
|
||||
{
|
||||
dst_surface->bnet_surface =
|
||||
HeapAlloc(
|
||||
GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
dst_surface->l_pitch * (dst_surface->height + 200) * dst_surface->lx_pitch);
|
||||
}
|
||||
|
||||
SelectObject(dst_surface->bnet_dc, dst_surface->bnet_bitmap);
|
||||
}
|
||||
|
||||
SelectObject(dst_surface->hdc, dst_surface->bitmap);
|
||||
|
@ -442,6 +442,27 @@ DWORD WINAPI d3d9_render_main(void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ddraw->bnet_active)
|
||||
{
|
||||
RECT rc = { 0,0,g_ddraw->width,g_ddraw->height };
|
||||
|
||||
if (SUCCEEDED(IDirect3DTexture9_LockRect(g_d3d9.surface_tex[tex_index], 0, &lock_rc, &rc, 0)))
|
||||
{
|
||||
unsigned char* src = (unsigned char*)g_ddraw->primary->bnet_surface;
|
||||
unsigned char* dst = (unsigned char*)lock_rc.pBits;
|
||||
|
||||
for (int i = 0; i < g_ddraw->height; i++)
|
||||
{
|
||||
memcpy(dst, src, g_ddraw->primary->l_pitch);
|
||||
|
||||
src += g_ddraw->primary->l_pitch;
|
||||
dst += lock_rc.Pitch;
|
||||
}
|
||||
|
||||
IDirect3DTexture9_UnlockRect(g_d3d9.surface_tex[tex_index], 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&g_ddraw->cs);
|
||||
@ -456,11 +477,6 @@ DWORD WINAPI d3d9_render_main(void)
|
||||
IDirect3DDevice9_DrawPrimitive(g_d3d9.device, D3DPT_TRIANGLESTRIP, 0, 2);
|
||||
IDirect3DDevice9_EndScene(g_d3d9.device);
|
||||
|
||||
if (g_ddraw->bnet_active)
|
||||
{
|
||||
IDirect3DDevice9_Clear(g_d3d9.device, 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
|
||||
}
|
||||
|
||||
if (FAILED(IDirect3DDevice9_Present(g_d3d9.device, NULL, NULL, NULL, NULL)))
|
||||
{
|
||||
DWORD_PTR result;
|
||||
|
@ -97,8 +97,20 @@ DWORD WINAPI gdi_render_main(void)
|
||||
|
||||
if (g_ddraw->bnet_active)
|
||||
{
|
||||
RECT rc = { 0, 0, g_ddraw->render.width, g_ddraw->render.height };
|
||||
FillRect(g_ddraw->render.hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
||||
StretchDIBits(
|
||||
g_ddraw->render.hdc,
|
||||
g_ddraw->render.viewport.x,
|
||||
g_ddraw->render.viewport.y,
|
||||
g_ddraw->render.viewport.width,
|
||||
g_ddraw->render.viewport.height,
|
||||
0,
|
||||
0,
|
||||
g_ddraw->width,
|
||||
g_ddraw->height,
|
||||
g_ddraw->primary->bnet_surface,
|
||||
g_ddraw->primary->bmi,
|
||||
DIB_RGB_COLORS,
|
||||
SRCCOPY);
|
||||
}
|
||||
else if (upscale_hack)
|
||||
{
|
||||
|
@ -701,6 +701,28 @@ static void ogl_render()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (g_ddraw->bnet_active)
|
||||
{
|
||||
glBindTexture(GL_TEXTURE_2D, g_ogl.surface_tex_ids[tex_index]);
|
||||
|
||||
if (g_ogl.adjust_alignment)
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
|
||||
glTexSubImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
g_ddraw->width,
|
||||
g_ddraw->height,
|
||||
g_ogl.surface_format,
|
||||
g_ogl.surface_type,
|
||||
g_ddraw->primary->bnet_surface);
|
||||
|
||||
if (g_ogl.adjust_alignment)
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
||||
}
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&g_ddraw->cs);
|
||||
@ -823,9 +845,6 @@ static void ogl_render()
|
||||
glEnd();
|
||||
}
|
||||
|
||||
if (g_ddraw->bnet_active)
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
SwapBuffers(g_ddraw->render.hdc);
|
||||
|
||||
#if _DEBUG
|
||||
|
@ -591,6 +591,7 @@ BOOL WINAPI fake_DestroyWindow(HWND hWnd)
|
||||
|
||||
if (!FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL))
|
||||
{
|
||||
KillTimer(g_ddraw->hwnd, IDT_TIMER_REDRAW_BNET);
|
||||
g_ddraw->bnet_active = FALSE;
|
||||
SetFocus(g_ddraw->hwnd);
|
||||
mouse_lock();
|
||||
@ -680,6 +681,7 @@ HWND WINAPI fake_CreateWindowExA(
|
||||
g_ddraw->resizable = FALSE;
|
||||
|
||||
g_ddraw->bnet_active = TRUE;
|
||||
SetTimer(g_ddraw->hwnd, IDT_TIMER_REDRAW_BNET, 200, (TIMERPROC)NULL);
|
||||
mouse_unlock();
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "dllmain.h"
|
||||
#include "dd.h"
|
||||
#include "hook.h"
|
||||
#include "ddsurface.h"
|
||||
#include "mouse.h"
|
||||
#include "render_d3d9.h"
|
||||
#include "config.h"
|
||||
@ -162,6 +163,13 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
||||
|
||||
return 0;
|
||||
}
|
||||
case IDT_TIMER_REDRAW_BNET:
|
||||
{
|
||||
if (g_ddraw->primary)
|
||||
dds_RedrawBnet(g_ddraw->primary);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user