mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-24 17:49:52 +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 l_pitch;
|
||||||
DWORD lx_pitch;
|
DWORD lx_pitch;
|
||||||
|
|
||||||
|
void* bnet_surface;
|
||||||
|
HDC bnet_dc;
|
||||||
|
HBITMAP bnet_bitmap;
|
||||||
|
|
||||||
PBITMAPINFO bmi;
|
PBITMAPINFO bmi;
|
||||||
HBITMAP bitmap;
|
HBITMAP bitmap;
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
|
@ -33,6 +33,6 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect);
|
|||||||
HRESULT dds_GetDDInterface(IDirectDrawSurfaceImpl* This, LPVOID* lplpDD);
|
HRESULT dds_GetDDInterface(IDirectDrawSurfaceImpl* This, LPVOID* lplpDD);
|
||||||
void* dds_GetBuffer(IDirectDrawSurfaceImpl* This);
|
void* dds_GetBuffer(IDirectDrawSurfaceImpl* This);
|
||||||
HRESULT dd_CreateSurface(IDirectDrawImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc, IDirectDrawSurfaceImpl** lpDDSurface, IUnknown FAR* unkOuter);
|
HRESULT dd_CreateSurface(IDirectDrawImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc, IDirectDrawSurfaceImpl** lpDDSurface, IUnknown FAR* unkOuter);
|
||||||
|
void dds_RedrawBnet(IDirectDrawSurfaceImpl* This);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#define WM_DISPLAYCHANGE_DDRAW WM_APP+116
|
#define WM_DISPLAYCHANGE_DDRAW WM_APP+116
|
||||||
|
|
||||||
#define IDT_TIMER_LEAVE_BNET 541287654
|
#define IDT_TIMER_LEAVE_BNET 541287654
|
||||||
|
#define IDT_TIMER_REDRAW_BNET 541287655
|
||||||
|
|
||||||
LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
|
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);
|
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)
|
if (This->hdc)
|
||||||
DeleteDC(This->hdc);
|
DeleteDC(This->hdc);
|
||||||
|
|
||||||
|
if (This->bnet_dc)
|
||||||
|
DeleteDC(This->bnet_dc);
|
||||||
|
|
||||||
if (This->bmi)
|
if (This->bmi)
|
||||||
HeapFree(GetProcessHeap(), 0, This->bmi);
|
HeapFree(GetProcessHeap(), 0, This->bmi);
|
||||||
|
|
||||||
|
@ -1190,28 +1190,39 @@ HRESULT dds_SetPalette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* lpD
|
|||||||
return DD_OK;
|
return DD_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect)
|
void dds_RedrawBnet(IDirectDrawSurfaceImpl* This)
|
||||||
{
|
{
|
||||||
/* Hack for Warcraft II BNE and Diablo */
|
/* Hack for Warcraft II BNE and Diablo */
|
||||||
HWND hwnd = g_ddraw->bnet_active ? FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL) : NULL;
|
HWND hwnd = g_ddraw->bnet_active ? FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL) : NULL;
|
||||||
|
|
||||||
if (hwnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
|
if (hwnd)
|
||||||
{
|
{
|
||||||
HDC primary_dc;
|
HDC primary_dc;
|
||||||
dds_GetDC(This, &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 */
|
/* GdiTransparentBlt idea taken from Aqrit's war2 ddraw */
|
||||||
|
|
||||||
RGBQUAD quad;
|
RGBQUAD quad;
|
||||||
GetDIBColorTable(primary_dc, 0xFE, 1, &quad);
|
GetDIBColorTable(primary_dc, 0xFE, 1, &quad);
|
||||||
COLORREF color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
|
COLORREF color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
|
||||||
BOOL erase = FALSE;
|
BOOL erase = FALSE;
|
||||||
|
HWND hwnd_bnet[20];
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
memset(&hwnd_bnet[0], 0, sizeof(hwnd_bnet));
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
RECT rc;
|
RECT rc;
|
||||||
if (fake_GetWindowRect(hwnd, &rc))
|
if (fake_GetWindowRect(hwnd, &rc))
|
||||||
{
|
{
|
||||||
|
hwnd_bnet[i++] = hwnd;
|
||||||
|
|
||||||
if (rc.bottom - rc.top == 479)
|
if (rc.bottom - rc.top == 479)
|
||||||
erase = TRUE;
|
erase = TRUE;
|
||||||
|
|
||||||
@ -1236,6 +1247,36 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect)
|
|||||||
|
|
||||||
} while ((hwnd = FindWindowEx(HWND_DESKTOP, hwnd, "SDlgDialog", NULL)));
|
} 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)
|
if (erase)
|
||||||
{
|
{
|
||||||
BOOL x = g_ddraw->ticks_limiter.use_blt_or_flip;
|
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;
|
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 */
|
/* 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))
|
if (hwnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
|
||||||
{
|
{
|
||||||
@ -1471,6 +1523,26 @@ HRESULT dd_CreateSurface(
|
|||||||
{
|
{
|
||||||
g_ddraw->primary = dst_surface;
|
g_ddraw->primary = dst_surface;
|
||||||
FakePrimarySurface = dst_surface->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);
|
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);
|
LeaveCriticalSection(&g_ddraw->cs);
|
||||||
@ -456,11 +477,6 @@ DWORD WINAPI d3d9_render_main(void)
|
|||||||
IDirect3DDevice9_DrawPrimitive(g_d3d9.device, D3DPT_TRIANGLESTRIP, 0, 2);
|
IDirect3DDevice9_DrawPrimitive(g_d3d9.device, D3DPT_TRIANGLESTRIP, 0, 2);
|
||||||
IDirect3DDevice9_EndScene(g_d3d9.device);
|
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)))
|
if (FAILED(IDirect3DDevice9_Present(g_d3d9.device, NULL, NULL, NULL, NULL)))
|
||||||
{
|
{
|
||||||
DWORD_PTR result;
|
DWORD_PTR result;
|
||||||
|
@ -97,8 +97,20 @@ DWORD WINAPI gdi_render_main(void)
|
|||||||
|
|
||||||
if (g_ddraw->bnet_active)
|
if (g_ddraw->bnet_active)
|
||||||
{
|
{
|
||||||
RECT rc = { 0, 0, g_ddraw->render.width, g_ddraw->render.height };
|
StretchDIBits(
|
||||||
FillRect(g_ddraw->render.hdc, &rc, (HBRUSH)GetStockObject(BLACK_BRUSH));
|
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)
|
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);
|
LeaveCriticalSection(&g_ddraw->cs);
|
||||||
@ -823,9 +845,6 @@ static void ogl_render()
|
|||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_ddraw->bnet_active)
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
|
|
||||||
SwapBuffers(g_ddraw->render.hdc);
|
SwapBuffers(g_ddraw->render.hdc);
|
||||||
|
|
||||||
#if _DEBUG
|
#if _DEBUG
|
||||||
|
@ -591,6 +591,7 @@ BOOL WINAPI fake_DestroyWindow(HWND hWnd)
|
|||||||
|
|
||||||
if (!FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL))
|
if (!FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL))
|
||||||
{
|
{
|
||||||
|
KillTimer(g_ddraw->hwnd, IDT_TIMER_REDRAW_BNET);
|
||||||
g_ddraw->bnet_active = FALSE;
|
g_ddraw->bnet_active = FALSE;
|
||||||
SetFocus(g_ddraw->hwnd);
|
SetFocus(g_ddraw->hwnd);
|
||||||
mouse_lock();
|
mouse_lock();
|
||||||
@ -680,6 +681,7 @@ HWND WINAPI fake_CreateWindowExA(
|
|||||||
g_ddraw->resizable = FALSE;
|
g_ddraw->resizable = FALSE;
|
||||||
|
|
||||||
g_ddraw->bnet_active = TRUE;
|
g_ddraw->bnet_active = TRUE;
|
||||||
|
SetTimer(g_ddraw->hwnd, IDT_TIMER_REDRAW_BNET, 200, (TIMERPROC)NULL);
|
||||||
mouse_unlock();
|
mouse_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "dllmain.h"
|
#include "dllmain.h"
|
||||||
#include "dd.h"
|
#include "dd.h"
|
||||||
#include "hook.h"
|
#include "hook.h"
|
||||||
|
#include "ddsurface.h"
|
||||||
#include "mouse.h"
|
#include "mouse.h"
|
||||||
#include "render_d3d9.h"
|
#include "render_d3d9.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -162,6 +163,13 @@ LRESULT CALLBACK fake_WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
case IDT_TIMER_REDRAW_BNET:
|
||||||
|
{
|
||||||
|
if (g_ddraw->primary)
|
||||||
|
dds_RedrawBnet(g_ddraw->primary);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user