mirror of
https://github.com/FunkyFr3sh/cnc-ddraw.git
synced 2025-03-15 06:04:49 +01:00
create backbuffer for flip games
This commit is contained in:
parent
9717d7b906
commit
ae4446becb
@ -35,6 +35,8 @@ typedef struct IDirectDrawSurfaceImpl
|
||||
DWORD last_flip_tick;
|
||||
DWORD last_blt_tick;
|
||||
|
||||
struct IDirectDrawSurfaceImpl *backbuffer;
|
||||
|
||||
} IDirectDrawSurfaceImpl;
|
||||
|
||||
typedef struct IDirectDrawSurfaceImplVtbl IDirectDrawSurfaceImplVtbl;
|
||||
|
1
inc/dd.h
1
inc/dd.h
@ -106,6 +106,7 @@ typedef struct cnc_ddraw
|
||||
BOOL nonexclusive;
|
||||
BOOL fixchildwindows;
|
||||
BOOL d3d9linear;
|
||||
BOOL backbuffer;
|
||||
int maxgameticks;
|
||||
BOOL alt_key_down;
|
||||
BOOL bnet_active;
|
||||
|
@ -26,6 +26,8 @@ HRESULT dds_Lock(IDirectDrawSurfaceImpl* This, LPRECT lpDestRect, LPDDSURFACEDES
|
||||
HRESULT dds_SetColorKey(IDirectDrawSurfaceImpl* This, DWORD flags, LPDDCOLORKEY colorKey);
|
||||
HRESULT dds_SetPalette(IDirectDrawSurfaceImpl* This, LPDIRECTDRAWPALETTE lpDDPalette);
|
||||
HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPVOID lpRect);
|
||||
void* dds_GetBuffer(IDirectDrawSurfaceImpl* This);
|
||||
HDC dds_GetHDC(IDirectDrawSurfaceImpl* This);
|
||||
HRESULT dd_CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FAR* lpDDSurface, IUnknown FAR* unkOuter);
|
||||
|
||||
|
||||
|
@ -86,6 +86,9 @@ ULONG __stdcall IDirectDrawSurface__Release(IDirectDrawSurfaceImpl *This)
|
||||
if (This->bmi)
|
||||
HeapFree(GetProcessHeap(), 0, This->bmi);
|
||||
|
||||
if (This->backbuffer)
|
||||
IDirectDrawSurface_Release(This->backbuffer);
|
||||
|
||||
if(This->palette && (!g_ddraw || (void*)This->palette != g_ddraw->last_freed_palette))
|
||||
{
|
||||
IDirectDrawPalette_Release(This->palette);
|
||||
|
@ -50,6 +50,7 @@ void cfg_load()
|
||||
g_ddraw->nonexclusive = cfg_get_bool("nonexclusive", FALSE);
|
||||
g_ddraw->fixchildwindows = cfg_get_bool("fixchildwindows", TRUE);
|
||||
g_ddraw->d3d9linear = cfg_get_bool("d3d9linear", TRUE);
|
||||
g_ddraw->backbuffer = cfg_get_bool("backbuffer", TRUE);
|
||||
g_ddraw->sierrahack = cfg_get_bool("sierrahack", FALSE); // Sierra Caesar III, Pharaoh, and Zeus hack
|
||||
g_ddraw->dk2hack = cfg_get_bool("dk2hack", FALSE); // Dungeon Keeper 2 hack
|
||||
|
||||
@ -552,6 +553,11 @@ static void cfg_create_ini()
|
||||
"renderer=opengl\n"
|
||||
"nonexclusive=true\n"
|
||||
"\n"
|
||||
"; Tzar: The Burden of the Crown\n"
|
||||
"; Note: Must set 'DIRECTXDEVICE=0' in 'Tzar.ini'\n"
|
||||
"[Tzar]\n"
|
||||
"handlemouse=false\n"
|
||||
"\n"
|
||||
|
||||
, fh);
|
||||
fclose(fh);
|
||||
|
115
src/ddsurface.c
115
src/ddsurface.c
@ -75,10 +75,12 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
|
||||
int dst_x = dst_rect.left;
|
||||
int dst_y = dst_rect.top;
|
||||
|
||||
void* dst_buf = dds_GetBuffer(This);
|
||||
void* src_buf = dds_GetBuffer(src_surface);
|
||||
|
||||
if (This->surface && (dwFlags & DDBLT_COLORFILL) && dst_w > 0 && dst_h > 0)
|
||||
if (dst_buf && (dwFlags & DDBLT_COLORFILL) && dst_w > 0 && dst_h > 0)
|
||||
{
|
||||
unsigned char *dst = (unsigned char *)This->surface + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
|
||||
unsigned char *dst = (unsigned char *)dst_buf + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
|
||||
unsigned char *first_row = dst;
|
||||
unsigned int dst_pitch = dst_w * This->lx_pitch;
|
||||
int x, i;
|
||||
@ -151,11 +153,11 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
|
||||
|
||||
for (x1 = 0; x1 < width; x1++)
|
||||
{
|
||||
unsigned char c = ((unsigned char *)src_surface->surface)[x1 + src_x + ysrc];
|
||||
unsigned char c = ((unsigned char *)src_buf)[x1 + src_x + ysrc];
|
||||
|
||||
if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue)
|
||||
{
|
||||
((unsigned char *)This->surface)[x1 + dst_x + ydst] = c;
|
||||
((unsigned char *)dst_buf)[x1 + dst_x + ydst] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -170,11 +172,11 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
|
||||
|
||||
for (x1 = 0; x1 < width; x1++)
|
||||
{
|
||||
unsigned short c = ((unsigned short *)src_surface->surface)[x1 + src_x + ysrc];
|
||||
unsigned short c = ((unsigned short *)src_buf)[x1 + src_x + ysrc];
|
||||
|
||||
if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue)
|
||||
{
|
||||
((unsigned short *)This->surface)[x1 + dst_x + ydst] = c;
|
||||
((unsigned short *)dst_buf)[x1 + dst_x + ydst] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,10 +195,10 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
|
||||
int height = dst_h > src_h ? src_h : dst_h;
|
||||
|
||||
unsigned char *src =
|
||||
(unsigned char *)src_surface->surface + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
|
||||
(unsigned char *)src_buf + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
|
||||
|
||||
unsigned char *dst =
|
||||
(unsigned char *)This->surface + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
|
||||
(unsigned char *)dst_buf + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
|
||||
|
||||
unsigned int dst_pitch = width * This->lx_pitch;
|
||||
|
||||
@ -316,8 +318,8 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
|
||||
if (This->bpp == 8)
|
||||
{
|
||||
unsigned char *d, *s, v;
|
||||
unsigned char *src = (unsigned char *)src_surface->surface;
|
||||
unsigned char *dst = (unsigned char *)This->surface;
|
||||
unsigned char *src = (unsigned char *)src_buf;
|
||||
unsigned char *dst = (unsigned char *)dst_buf;
|
||||
|
||||
do {
|
||||
switch (current->type)
|
||||
@ -355,8 +357,8 @@ HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSUR
|
||||
else if (This->bpp == 16)
|
||||
{
|
||||
unsigned short *d, *s, v;
|
||||
unsigned short *src = (unsigned short *)src_surface->surface;
|
||||
unsigned short *dst = (unsigned short *)This->surface;
|
||||
unsigned short *src = (unsigned short *)src_buf;
|
||||
unsigned short *dst = (unsigned short *)dst_buf;
|
||||
|
||||
do {
|
||||
switch (current->type)
|
||||
@ -466,6 +468,9 @@ HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDI
|
||||
int dst_w = dst_rect.right - dst_rect.left;
|
||||
int dst_h = dst_rect.bottom - dst_rect.top;
|
||||
|
||||
void* dst_buf = dds_GetBuffer(This);
|
||||
void* src_buf = dds_GetBuffer(src_surface);
|
||||
|
||||
if (src_surface && dst_w > 0 && dst_h > 0)
|
||||
{
|
||||
if (flags & DDBLTFAST_SRCCOLORKEY)
|
||||
@ -480,11 +485,11 @@ HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDI
|
||||
|
||||
for (x1 = 0; x1 < dst_w; x1++)
|
||||
{
|
||||
unsigned char c = ((unsigned char *)src_surface->surface)[x1 + src_x + ysrc];
|
||||
unsigned char c = ((unsigned char *)src_buf)[x1 + src_x + ysrc];
|
||||
|
||||
if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue)
|
||||
{
|
||||
((unsigned char *)This->surface)[x1 + dst_x + ydst] = c;
|
||||
((unsigned char *)dst_buf)[x1 + dst_x + ydst] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -499,11 +504,11 @@ HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDI
|
||||
|
||||
for (x1 = 0; x1 < dst_w; x1++)
|
||||
{
|
||||
unsigned short c = ((unsigned short *)src_surface->surface)[x1 + src_x + ysrc];
|
||||
unsigned short c = ((unsigned short *)src_buf)[x1 + src_x + ysrc];
|
||||
|
||||
if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue)
|
||||
{
|
||||
((unsigned short *)This->surface)[x1 + dst_x + ydst] = c;
|
||||
((unsigned short *)dst_buf)[x1 + dst_x + ydst] = c;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -512,10 +517,10 @@ HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDI
|
||||
else
|
||||
{
|
||||
unsigned char *src =
|
||||
(unsigned char *)src_surface->surface + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
|
||||
(unsigned char *)src_buf + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
|
||||
|
||||
unsigned char *dst =
|
||||
(unsigned char *)This->surface + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
|
||||
(unsigned char *)dst_buf + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
|
||||
|
||||
unsigned int dst_pitch = dst_w * This->lx_pitch;
|
||||
|
||||
@ -591,7 +596,7 @@ HRESULT dds_GetSurfaceDesc(IDirectDrawSurfaceImpl *This, LPDDSURFACEDESC lpDDSur
|
||||
lpDDSurfaceDesc->dwWidth = This->width;
|
||||
lpDDSurfaceDesc->dwHeight = This->height;
|
||||
lpDDSurfaceDesc->lPitch = This->l_pitch;
|
||||
lpDDSurfaceDesc->lpSurface = This->surface;
|
||||
lpDDSurfaceDesc->lpSurface = dds_GetBuffer(This);
|
||||
lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
||||
lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB;
|
||||
lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = This->bpp;
|
||||
@ -634,6 +639,19 @@ HRESULT dds_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWSURFACE surface, DWOR
|
||||
{
|
||||
if(This->caps & DDSCAPS_PRIMARYSURFACE && g_ddraw->render.run)
|
||||
{
|
||||
if (This->backbuffer)
|
||||
{
|
||||
EnterCriticalSection(&g_ddraw->cs);
|
||||
void* surface = InterlockedExchangePointer(&This->surface, This->backbuffer->surface);
|
||||
HBITMAP bitmap = (HBITMAP)InterlockedExchangePointer(&This->bitmap, This->backbuffer->bitmap);
|
||||
HDC hdc = (HDC)InterlockedExchangePointer(&This->hdc, This->backbuffer->hdc);
|
||||
|
||||
InterlockedExchangePointer(&This->backbuffer->surface, surface);
|
||||
InterlockedExchangePointer(&This->backbuffer->bitmap, bitmap);
|
||||
InterlockedExchangePointer(&This->backbuffer->hdc, hdc);
|
||||
LeaveCriticalSection(&g_ddraw->cs);
|
||||
}
|
||||
|
||||
This->last_flip_tick = timeGetTime();
|
||||
|
||||
InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
|
||||
@ -659,8 +677,16 @@ HRESULT dds_GetAttachedSurface(IDirectDrawSurfaceImpl *This, LPDDSCAPS lpDdsCaps
|
||||
{
|
||||
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && (This->caps & DDSCAPS_FLIP) && (lpDdsCaps->dwCaps & DDSCAPS_BACKBUFFER))
|
||||
{
|
||||
IDirectDrawSurface_AddRef(This);
|
||||
*surface = (LPDIRECTDRAWSURFACE)This;
|
||||
if (This->backbuffer)
|
||||
{
|
||||
IDirectDrawSurface_AddRef(This->backbuffer);
|
||||
*surface = (LPDIRECTDRAWSURFACE)This->backbuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
IDirectDrawSurface_AddRef(This);
|
||||
*surface = (LPDIRECTDRAWSURFACE)This;
|
||||
}
|
||||
}
|
||||
|
||||
return DD_OK;
|
||||
@ -696,9 +722,9 @@ HRESULT dds_GetDC(IDirectDrawSurfaceImpl *This, HDC FAR *a)
|
||||
NULL;
|
||||
|
||||
if (data)
|
||||
SetDIBColorTable(This->hdc, 0, 256, data);
|
||||
SetDIBColorTable(dds_GetHDC(This), 0, 256, data);
|
||||
|
||||
*a = This->hdc;
|
||||
*a = dds_GetHDC(This);
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
@ -752,7 +778,7 @@ HRESULT dds_Lock(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDDSURFACEDES
|
||||
if (lpDestRect && lpDDSurfaceDesc && lpDestRect->left >= 0 && lpDestRect->top >= 0)
|
||||
{
|
||||
lpDDSurfaceDesc->lpSurface =
|
||||
(char*)This->surface + (lpDestRect->left * This->lx_pitch) + (lpDestRect->top * This->l_pitch);
|
||||
(char*)dds_GetBuffer(This) + (lpDestRect->left * This->lx_pitch) + (lpDestRect->top * This->l_pitch);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -810,12 +836,12 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRect)
|
||||
if (hwnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
|
||||
{
|
||||
if (g_ddraw->primary->palette && g_ddraw->primary->palette->data_rgb)
|
||||
SetDIBColorTable(g_ddraw->primary->hdc, 0, 256, g_ddraw->primary->palette->data_rgb);
|
||||
SetDIBColorTable(dds_GetHDC(g_ddraw->primary), 0, 256, g_ddraw->primary->palette->data_rgb);
|
||||
|
||||
//GdiTransparentBlt idea taken from Aqrit's war2 ddraw
|
||||
|
||||
RGBQUAD quad;
|
||||
GetDIBColorTable(g_ddraw->primary->hdc, 0xFE, 1, &quad);
|
||||
GetDIBColorTable(dds_GetHDC(g_ddraw->primary), 0xFE, 1, &quad);
|
||||
COLORREF color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
|
||||
BOOL erase = FALSE;
|
||||
|
||||
@ -835,7 +861,7 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRect)
|
||||
0,
|
||||
rc.right - rc.left,
|
||||
rc.bottom - rc.top,
|
||||
g_ddraw->primary->hdc,
|
||||
dds_GetHDC(g_ddraw->primary),
|
||||
rc.left,
|
||||
rc.top,
|
||||
rc.right - rc.left,
|
||||
@ -878,6 +904,28 @@ HRESULT dds_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRect)
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
void* dds_GetBuffer(IDirectDrawSurfaceImpl* This)
|
||||
{
|
||||
if (!This)
|
||||
return NULL;
|
||||
|
||||
if (This->backbuffer || (This->caps & DDSCAPS_BACKBUFFER))
|
||||
return (void*)InterlockedExchangeAdd(&This->surface, 0);
|
||||
|
||||
return This->surface;
|
||||
}
|
||||
|
||||
HDC dds_GetHDC(IDirectDrawSurfaceImpl* This)
|
||||
{
|
||||
if (!This)
|
||||
return NULL;
|
||||
|
||||
if (This->backbuffer || (This->caps & DDSCAPS_BACKBUFFER))
|
||||
return (HDC)InterlockedExchangeAdd(&This->hdc, 0);
|
||||
|
||||
return This->hdc;
|
||||
}
|
||||
|
||||
HRESULT dd_CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FAR *lpDDSurface, IUnknown FAR * unkOuter)
|
||||
{
|
||||
dbg_dump_dds_flags(lpDDSurfaceDesc->dwFlags);
|
||||
@ -980,6 +1028,19 @@ HRESULT dd_CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FA
|
||||
if (lpDDSurfaceDesc->dwFlags & DDSD_BACKBUFFERCOUNT)
|
||||
{
|
||||
dprintf(" dwBackBufferCount=%d\n", lpDDSurfaceDesc->dwBackBufferCount);
|
||||
|
||||
if (g_ddraw->backbuffer)
|
||||
{
|
||||
DDSURFACEDESC desc;
|
||||
memset(&desc, 0, sizeof(DDSURFACEDESC));
|
||||
|
||||
desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
|
||||
|
||||
desc.dwWidth = dst_surface->width;
|
||||
desc.dwHeight = dst_surface->height;
|
||||
|
||||
dd_CreateSurface(&desc, &dst_surface->backbuffer, unkOuter);
|
||||
}
|
||||
}
|
||||
|
||||
dprintf(" surface = %p (%dx%d@%d)\n", dst_surface, (int)dst_surface->width, (int)dst_surface->height, (int)dst_surface->bpp);
|
||||
|
@ -146,9 +146,9 @@ void dbg_draw_frame_info_start()
|
||||
if (g_ddraw->primary)
|
||||
{
|
||||
if (g_ddraw->primary->palette && g_ddraw->primary->palette->data_rgb)
|
||||
SetDIBColorTable(g_ddraw->primary->hdc, 0, 256, g_ddraw->primary->palette->data_rgb);
|
||||
|
||||
DrawText(g_ddraw->primary->hdc, debug_text, -1, &debugrc, DT_NOCLIP);
|
||||
SetDIBColorTable(dds_GetHDC(g_ddraw->primary), 0, 256, g_ddraw->primary->palette->data_rgb);
|
||||
|
||||
DrawText(dds_GetHDC(g_ddraw->primary), debug_text, -1, &debugrc, DT_NOCLIP);
|
||||
}
|
||||
|
||||
DWORD tick_start = timeGetTime();
|
||||
|
@ -9,7 +9,7 @@
|
||||
|
||||
BOOL ss_take_screenshot(struct IDirectDrawSurfaceImpl *src)
|
||||
{
|
||||
if (!src || !src->palette || !src->surface)
|
||||
if (!src || !src->palette || !dds_GetBuffer(src))
|
||||
return FALSE;
|
||||
|
||||
int i;
|
||||
@ -54,7 +54,7 @@ BOOL ss_take_screenshot(struct IDirectDrawSurfaceImpl *src)
|
||||
state.info_raw.bitdepth = 8;
|
||||
state.encoder.auto_convert = 0;
|
||||
|
||||
unsigned int error = lodepng_encode(&png, &pngsize, src->surface, src->width, src->height, &state);
|
||||
unsigned int error = lodepng_encode(&png, &pngsize, dds_GetBuffer(src), src->width, src->height, &state);
|
||||
|
||||
if (!error)
|
||||
lodepng_save_file(png, pngsize, filename);
|
||||
|
@ -321,7 +321,7 @@ BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lparam)
|
||||
|
||||
MapWindowPoints(HWND_DESKTOP, g_ddraw->hwnd, (LPPOINT)&pos, 2);
|
||||
|
||||
BitBlt(hdc, 0, 0, size.right, size.bottom, this->hdc, pos.left, pos.top, SRCCOPY);
|
||||
BitBlt(hdc, 0, 0, size.right, size.bottom, dds_GetHDC(this), pos.left, pos.top, SRCCOPY);
|
||||
|
||||
ReleaseDC(hwnd, hdc);
|
||||
}
|
||||
@ -332,7 +332,7 @@ BOOL CALLBACK util_enum_child_proc(HWND hwnd, LPARAM lparam)
|
||||
|
||||
static unsigned char util_get_pixel(int x, int y)
|
||||
{
|
||||
return ((unsigned char*)g_ddraw->primary->surface)[y * g_ddraw->primary->l_pitch + x * g_ddraw->primary->lx_pitch];
|
||||
return ((unsigned char*)dds_GetBuffer(g_ddraw->primary))[y * g_ddraw->primary->l_pitch + x * g_ddraw->primary->lx_pitch];
|
||||
}
|
||||
|
||||
BOOL util_detect_cutscene()
|
||||
|
Loading…
x
Reference in New Issue
Block a user