1
0
mirror of https://github.com/FunkyFr3sh/cnc-ddraw.git synced 2025-03-23 00:52:18 +01:00
cnc-ddraw/src/ddsurface.c

1150 lines
32 KiB
C
Raw Normal View History

2020-10-13 09:20:52 +02:00
#include <windows.h>
#include <stdio.h>
2020-10-13 11:29:52 +02:00
#include "dllmain.h"
2020-10-13 09:20:52 +02:00
#include "dd.h"
#include "hook.h"
#include "ddsurface.h"
#include "mouse.h"
#include "IDirectDrawSurface.h"
#include "winapi_hooks.h"
#include "debug.h"
#include "utils.h"
#include "blt.h"
2020-10-13 09:20:52 +02:00
2021-06-11 20:30:43 +02:00
HRESULT dds_AddAttachedSurface(IDirectDrawSurfaceImpl* This, IDirectDrawSurfaceImpl* lpDDSurface)
2020-10-13 09:20:52 +02:00
{
if (lpDDSurface)
{
IDirectDrawSurface_AddRef(lpDDSurface);
2021-06-11 20:30:43 +02:00
if (!This->backbuffer)
{
2021-06-11 20:30:43 +02:00
lpDDSurface->caps |= DDSCAPS_BACKBUFFER;
This->backbuffer = lpDDSurface;
}
}
2020-10-13 09:20:52 +02:00
return DD_OK;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_Blt(
IDirectDrawSurfaceImpl* This,
LPRECT lpDestRect,
IDirectDrawSurfaceImpl* lpDDSrcSurface,
LPRECT lpSrcRect,
DWORD dwFlags,
2021-06-11 20:30:43 +02:00
LPDDBLTFX lpDDBltFx)
2020-10-13 09:20:52 +02:00
{
dbg_dump_dds_blt_flags(dwFlags);
2021-06-11 20:30:43 +02:00
dbg_dump_dds_blt_fx_flags((dwFlags & DDBLT_DDFX) && lpDDBltFx ? lpDDBltFx->dwDDFX : 0);
2020-10-13 09:20:52 +02:00
2021-06-11 20:30:43 +02:00
if (g_ddraw->iskkndx &&
(dwFlags & DDBLT_COLORFILL) &&
lpDestRect &&
lpDestRect->right == 640 &&
2021-06-05 22:15:52 +02:00
lpDestRect->bottom == 480)
{
if (This->backbuffer)
{
dds_Blt(This->backbuffer, lpDestRect, NULL, NULL, dwFlags, lpDDBltFx);
}
lpDestRect = NULL;
2021-06-05 22:15:52 +02:00
}
2021-06-11 20:30:43 +02:00
IDirectDrawSurfaceImpl* src_surface = lpDDSrcSurface;
2020-10-13 09:20:52 +02:00
RECT src_rect = { 0, 0, src_surface ? src_surface->width : 0, src_surface ? src_surface->height : 0 };
RECT dst_rect = { 0, 0, This->width, This->height };
if (lpSrcRect && src_surface)
memcpy(&src_rect, lpSrcRect, sizeof(src_rect));
if (lpDestRect)
memcpy(&dst_rect, lpDestRect, sizeof(dst_rect));
2021-06-11 20:30:43 +02:00
/* stretch or clip? */
BOOL is_stretch_blt =
2020-10-13 09:20:52 +02:00
((src_rect.right - src_rect.left) != (dst_rect.right - dst_rect.left)) ||
((src_rect.bottom - src_rect.top) != (dst_rect.bottom - dst_rect.top));
if (src_surface)
{
2021-05-06 05:09:27 +02:00
if (src_rect.left < 0)
src_rect.left = 0;
if (src_rect.top < 0)
src_rect.top = 0;
2020-10-13 09:20:52 +02:00
if (src_rect.right > src_surface->width)
src_rect.right = src_surface->width;
if (src_rect.left > src_rect.right)
src_rect.left = src_rect.right;
2020-10-13 09:20:52 +02:00
if (src_rect.bottom > src_surface->height)
src_rect.bottom = src_surface->height;
2020-10-20 18:49:58 +02:00
if (src_rect.top > src_rect.bottom)
src_rect.top = src_rect.bottom;
2020-10-13 09:20:52 +02:00
}
2021-05-06 05:09:27 +02:00
if (dst_rect.left < 0)
dst_rect.left = 0;
if (dst_rect.top < 0)
dst_rect.top = 0;
2020-10-13 09:20:52 +02:00
if (dst_rect.right > This->width)
dst_rect.right = This->width;
if (dst_rect.left > dst_rect.right)
dst_rect.left = dst_rect.right;
2020-10-13 09:20:52 +02:00
if (dst_rect.bottom > This->height)
dst_rect.bottom = This->height;
2020-10-20 18:49:58 +02:00
if (dst_rect.top > dst_rect.bottom)
dst_rect.top = dst_rect.bottom;
2020-10-13 09:20:52 +02:00
int src_w = src_rect.right - src_rect.left;
int src_h = src_rect.bottom - src_rect.top;
int src_x = src_rect.left;
int src_y = src_rect.top;
int dst_w = dst_rect.right - dst_rect.left;
int dst_h = dst_rect.bottom - dst_rect.top;
int dst_x = dst_rect.left;
int dst_y = dst_rect.top;
2021-05-04 22:49:22 +02:00
void* dst_buf = dds_GetBuffer(This);
void* src_buf = dds_GetBuffer(src_surface);
2020-10-13 09:20:52 +02:00
if (dst_buf && (dwFlags & DDBLT_COLORFILL) && lpDDBltFx && dst_w > 0 && dst_h > 0)
2020-10-13 09:20:52 +02:00
{
blt_colorfill(
dst_buf,
dst_x,
dst_y,
dst_w,
dst_h,
This->l_pitch,
lpDDBltFx->dwFillColor,
This->bpp);
2020-10-13 09:20:52 +02:00
}
if (src_surface && src_w > 0 && src_h > 0 && dst_w > 0 && dst_h > 0)
2020-10-13 09:20:52 +02:00
{
BOOL got_fx = (dwFlags & DDBLT_DDFX) && lpDDBltFx;
BOOL mirror_left_right = got_fx && (lpDDBltFx->dwDDFX & DDBLTFX_MIRRORLEFTRIGHT);
BOOL mirror_up_down = got_fx && (lpDDBltFx->dwDDFX & DDBLTFX_MIRRORUPDOWN);
2021-06-06 05:25:33 +02:00
if (This->bpp != src_surface->bpp)
{
2021-06-11 20:30:43 +02:00
TRACE_EXT(" NOT_IMPLEMENTED This->bpp=%u, src_surface->bpp=%u\n", This->bpp, src_surface->bpp);
2021-06-06 05:25:33 +02:00
HDC dst_dc;
dds_GetDC(This, &dst_dc);
HDC src_dc;
dds_GetDC(src_surface, &src_dc);
StretchBlt(dst_dc, dst_x, dst_y, dst_w, dst_h, src_dc, src_x, src_y, src_w, src_h, SRCCOPY);
}
else if (
(dwFlags & DDBLT_KEYSRC) ||
(dwFlags & DDBLT_KEYSRCOVERRIDE) ||
mirror_left_right ||
mirror_up_down)
2020-10-13 09:20:52 +02:00
{
DDCOLORKEY color_key = { 0xFFFFFFFF, 0 };
2020-10-13 09:20:52 +02:00
if ((dwFlags & DDBLT_KEYSRC) || (dwFlags & DDBLT_KEYSRCOVERRIDE))
{
color_key.dwColorSpaceLowValue =
(dwFlags & DDBLT_KEYSRCOVERRIDE) ?
lpDDBltFx->ddckSrcColorkey.dwColorSpaceLowValue : src_surface->color_key.dwColorSpaceLowValue;
2020-10-13 09:20:52 +02:00
color_key.dwColorSpaceHighValue =
(dwFlags & DDBLT_KEYSRCOVERRIDE) ?
lpDDBltFx->ddckSrcColorkey.dwColorSpaceHighValue : src_surface->color_key.dwColorSpaceHighValue;
if (color_key.dwColorSpaceHighValue < color_key.dwColorSpaceLowValue)
color_key.dwColorSpaceHighValue = color_key.dwColorSpaceLowValue;
}
2021-05-10 23:40:42 +02:00
if (src_w == dst_w && src_h == dst_h && !mirror_left_right && !mirror_up_down)
2021-05-06 16:10:09 +02:00
{
blt_colorkey(
dst_buf,
dst_x,
dst_y,
dst_w,
dst_h,
This->l_pitch,
src_buf,
src_x,
src_y,
src_surface->l_pitch,
color_key.dwColorSpaceLowValue,
color_key.dwColorSpaceHighValue,
This->bpp);
2021-06-02 01:52:45 +02:00
}
else
2021-06-02 01:52:45 +02:00
{
blt_colorkey_mirror_stretch(
dst_buf,
dst_x,
dst_y,
dst_w,
dst_h,
This->l_pitch,
src_buf,
src_x,
src_y,
src_w,
src_h,
src_surface->l_pitch,
color_key.dwColorSpaceLowValue,
color_key.dwColorSpaceHighValue,
mirror_up_down,
mirror_left_right,
This->bpp);
2020-10-13 09:20:52 +02:00
}
}
else if (is_stretch_blt)
{
blt_stretch(
dst_buf,
dst_x,
dst_y,
dst_w,
dst_h,
This->l_pitch,
src_buf,
src_x,
src_y,
src_w,
src_h,
src_surface->l_pitch,
This->bpp);
}
else if (This == src_surface)
{
blt_overlap(
dst_buf,
dst_x,
dst_y,
min(dst_w, src_w),
min(dst_h, src_h),
This->l_pitch,
src_buf,
src_x,
src_y,
src_surface->l_pitch,
This->bpp);
}
2020-10-13 09:20:52 +02:00
else
{
blt_clean(
dst_buf,
dst_x,
dst_y,
min(dst_w, src_w),
min(dst_h, src_h),
This->l_pitch,
src_buf,
src_x,
src_y,
src_surface->l_pitch,
This->bpp);
2020-10-13 09:20:52 +02:00
}
}
2021-06-11 20:30:43 +02:00
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw->render.run)
2020-10-13 09:20:52 +02:00
{
InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
if (!(This->flags & DDSD_BACKBUFFERCOUNT) || This->last_flip_tick + FLIP_REDRAW_TIMEOUT < timeGetTime())
{
This->last_blt_tick = timeGetTime();
ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
SwitchToThread();
if (g_ddraw->ticks_limiter.tick_length > 0)
{
g_ddraw->ticks_limiter.use_blt_or_flip = TRUE;
util_limit_game_ticks();
}
}
}
return DD_OK;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_BltFast(
IDirectDrawSurfaceImpl* This,
DWORD dwX,
DWORD dwY,
IDirectDrawSurfaceImpl* lpDDSrcSurface,
LPRECT lpSrcRect,
2021-06-11 20:30:43 +02:00
DWORD dwFlags)
2020-10-13 09:20:52 +02:00
{
2021-06-11 20:30:43 +02:00
dbg_dump_dds_blt_fast_flags(dwFlags);
2020-10-13 09:20:52 +02:00
2021-06-11 20:30:43 +02:00
IDirectDrawSurfaceImpl* src_surface = lpDDSrcSurface;
2020-10-13 09:20:52 +02:00
RECT src_rect = { 0, 0, src_surface ? src_surface->width : 0, src_surface ? src_surface->height : 0 };
if (lpSrcRect && src_surface)
{
memcpy(&src_rect, lpSrcRect, sizeof(src_rect));
2021-05-06 05:09:27 +02:00
if (src_rect.left < 0)
src_rect.left = 0;
if (src_rect.top < 0)
src_rect.top = 0;
2020-10-13 09:20:52 +02:00
if (src_rect.right > src_surface->width)
src_rect.right = src_surface->width;
if (src_rect.left > src_rect.right)
src_rect.left = src_rect.right;
2020-10-13 09:20:52 +02:00
if (src_rect.bottom > src_surface->height)
src_rect.bottom = src_surface->height;
2020-10-20 18:49:58 +02:00
if (src_rect.top > src_rect.bottom)
src_rect.top = src_rect.bottom;
2020-10-13 09:20:52 +02:00
}
2021-06-11 20:30:43 +02:00
int dst_x = dwX;
int dst_y = dwY;
2020-10-13 09:20:52 +02:00
2022-02-06 15:40:25 +01:00
if (dst_x < 0)
2022-02-07 12:22:26 +01:00
{
src_rect.left += abs(dst_x);
if (src_rect.left > src_rect.right)
src_rect.left = src_rect.right;
2022-02-06 15:40:25 +01:00
dst_x = 0;
2022-02-07 12:22:26 +01:00
}
2022-02-06 15:40:25 +01:00
if (dst_y < 0)
2022-02-07 12:22:26 +01:00
{
src_rect.top += abs(dst_y);
if (src_rect.top > src_rect.bottom)
src_rect.top = src_rect.bottom;
2022-02-06 15:40:25 +01:00
dst_y = 0;
2022-02-07 12:22:26 +01:00
}
int src_x = src_rect.left;
int src_y = src_rect.top;
2022-02-06 15:40:25 +01:00
2020-10-13 09:20:52 +02:00
RECT dst_rect = { dst_x, dst_y, (src_rect.right - src_rect.left) + dst_x, (src_rect.bottom - src_rect.top) + dst_y };
2021-05-06 05:09:27 +02:00
if (dst_rect.left < 0)
dst_rect.left = 0;
if (dst_rect.top < 0)
dst_rect.top = 0;
2020-10-13 09:20:52 +02:00
if (dst_rect.right > This->width)
dst_rect.right = This->width;
if (dst_rect.left > dst_rect.right)
dst_rect.left = dst_rect.right;
2020-10-13 09:20:52 +02:00
if (dst_rect.bottom > This->height)
dst_rect.bottom = This->height;
2020-10-20 18:49:58 +02:00
if (dst_rect.top > dst_rect.bottom)
dst_rect.top = dst_rect.bottom;
2021-05-06 05:09:27 +02:00
dst_x = dst_rect.left;
dst_y = dst_rect.top;
2020-10-13 09:20:52 +02:00
int dst_w = dst_rect.right - dst_rect.left;
int dst_h = dst_rect.bottom - dst_rect.top;
2021-05-04 22:49:22 +02:00
void* dst_buf = dds_GetBuffer(This);
void* src_buf = dds_GetBuffer(src_surface);
if (src_surface && dst_w > 0 && dst_h > 0)
2020-10-13 09:20:52 +02:00
{
2021-06-06 05:25:33 +02:00
if (This->bpp != src_surface->bpp)
{
2021-06-11 20:30:43 +02:00
TRACE_EXT(" NOT_IMPLEMENTED This->bpp=%u, src_surface->bpp=%u\n", This->bpp, src_surface->bpp);
2021-06-06 05:25:33 +02:00
HDC dst_dc;
dds_GetDC(This, &dst_dc);
HDC src_dc;
dds_GetDC(src_surface, &src_dc);
BitBlt(dst_dc, dst_x, dst_y, dst_w, dst_h, src_dc, src_x, src_y, SRCCOPY);
}
2021-06-11 20:30:43 +02:00
else if (dwFlags & DDBLTFAST_SRCCOLORKEY)
2020-10-13 09:20:52 +02:00
{
blt_colorkey(
dst_buf,
dst_x,
dst_y,
dst_w,
dst_h,
This->l_pitch,
src_buf,
src_x,
src_y,
src_surface->l_pitch,
src_surface->color_key.dwColorSpaceLowValue,
src_surface->color_key.dwColorSpaceHighValue,
This->bpp);
}
else if (This == src_surface)
{
blt_overlap(
dst_buf,
dst_x,
dst_y,
dst_w,
dst_h,
This->l_pitch,
src_buf,
src_x,
src_y,
src_surface->l_pitch,
This->bpp);
2020-10-13 09:20:52 +02:00
}
else
{
blt_clean(
dst_buf,
dst_x,
dst_y,
dst_w,
dst_h,
This->l_pitch,
src_buf,
src_x,
src_y,
src_surface->l_pitch,
This->bpp);
2020-10-13 09:20:52 +02:00
}
}
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw->render.run)
{
InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
DWORD time = timeGetTime();
2021-06-11 20:30:43 +02:00
if (!(This->flags & DDSD_BACKBUFFERCOUNT) ||
2020-10-13 09:20:52 +02:00
(This->last_flip_tick + FLIP_REDRAW_TIMEOUT < time && This->last_blt_tick + FLIP_REDRAW_TIMEOUT < time))
{
ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
}
}
return DD_OK;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_DeleteAttachedSurface(IDirectDrawSurfaceImpl* This, DWORD dwFlags, IDirectDrawSurfaceImpl* lpDDSurface)
2020-10-13 09:20:52 +02:00
{
if (lpDDSurface)
{
IDirectDrawSurface_Release(lpDDSurface);
2021-06-11 20:30:43 +02:00
if (lpDDSurface == This->backbuffer)
This->backbuffer = NULL;
}
2020-10-13 09:20:52 +02:00
return DD_OK;
}
HRESULT dds_GetSurfaceDesc(IDirectDrawSurfaceImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc)
2020-10-13 09:20:52 +02:00
{
if (lpDDSurfaceDesc)
2020-10-13 09:20:52 +02:00
{
2021-06-11 20:30:43 +02:00
int size = lpDDSurfaceDesc->dwSize == sizeof(DDSURFACEDESC2) ? sizeof(DDSURFACEDESC2) : sizeof(DDSURFACEDESC);
2021-06-11 20:30:43 +02:00
memset(lpDDSurfaceDesc, 0, size);
lpDDSurfaceDesc->dwSize = size;
lpDDSurfaceDesc->dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT | DDSD_LPSURFACE;
lpDDSurfaceDesc->dwWidth = This->width;
lpDDSurfaceDesc->dwHeight = This->height;
lpDDSurfaceDesc->lPitch = This->l_pitch;
2021-05-04 22:49:22 +02:00
lpDDSurfaceDesc->lpSurface = dds_GetBuffer(This);
lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB;
lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = This->bpp;
lpDDSurfaceDesc->ddsCaps.dwCaps = This->caps;
if (!g_ddraw->novidmem || (This->caps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER)))
{
lpDDSurfaceDesc->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
}
if (This->bpp == 8)
{
lpDDSurfaceDesc->ddpfPixelFormat.dwFlags |= DDPF_PALETTEINDEXED8;
}
else if (This->bpp == 16)
{
lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0xF800;
lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x07E0;
lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x001F;
}
2021-06-02 01:52:45 +02:00
else if (This->bpp == 32)
{
lpDDSurfaceDesc->ddpfPixelFormat.dwRBitMask = 0xFF0000;
lpDDSurfaceDesc->ddpfPixelFormat.dwGBitMask = 0x00FF00;
lpDDSurfaceDesc->ddpfPixelFormat.dwBBitMask = 0x0000FF;
}
2020-10-13 09:20:52 +02:00
}
return DD_OK;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_EnumAttachedSurfaces(
IDirectDrawSurfaceImpl* This,
LPVOID lpContext,
LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
2020-10-13 09:20:52 +02:00
{
2021-06-11 20:30:43 +02:00
static DDSURFACEDESC2 desc;
memset(&desc, 0, sizeof(desc));
2020-10-13 09:20:52 +02:00
2021-05-04 23:52:52 +02:00
if (This->backbuffer)
{
dds_GetSurfaceDesc(This->backbuffer, (LPDDSURFACEDESC)&desc);
2021-05-04 23:52:52 +02:00
IDirectDrawSurface_AddRef(This->backbuffer);
lpEnumSurfacesCallback((LPDIRECTDRAWSURFACE)This->backbuffer, (LPDDSURFACEDESC)&desc, lpContext);
2021-05-04 23:52:52 +02:00
}
2020-10-13 09:20:52 +02:00
return DD_OK;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_Flip(IDirectDrawSurfaceImpl* This, IDirectDrawSurfaceImpl* lpDDSurfaceTargetOverride, DWORD dwFlags)
2020-10-13 09:20:52 +02:00
{
if (This->backbuffer)
2020-10-13 09:20:52 +02:00
{
EnterCriticalSection(&g_ddraw->cs);
2021-06-11 20:30:43 +02:00
IDirectDrawSurfaceImpl* backbuffer = lpDDSurfaceTargetOverride ? lpDDSurfaceTargetOverride : This->backbuffer;
2021-05-31 18:54:32 +02:00
void* buf = InterlockedExchangePointer(&This->surface, backbuffer->surface);
HBITMAP bitmap = (HBITMAP)InterlockedExchangePointer(&This->bitmap, backbuffer->bitmap);
HDC dc = (HDC)InterlockedExchangePointer(&This->hdc, backbuffer->hdc);
InterlockedExchangePointer(&backbuffer->surface, buf);
InterlockedExchangePointer(&backbuffer->bitmap, bitmap);
InterlockedExchangePointer(&backbuffer->hdc, dc);
2022-09-13 07:41:01 +02:00
if (g_ddraw->flipclear)
{
2022-09-15 02:12:27 +02:00
blt_clear(buf, backbuffer->size);
2022-09-13 07:41:01 +02:00
}
LeaveCriticalSection(&g_ddraw->cs);
2021-06-04 02:44:04 +02:00
2021-06-11 20:30:43 +02:00
if (!lpDDSurfaceTargetOverride && This->backbuffer->backbuffer)
2021-06-04 02:44:04 +02:00
{
dds_Flip(This->backbuffer, NULL, 0);
}
}
2021-05-04 22:49:22 +02:00
if (This->caps & DDSCAPS_PRIMARYSURFACE && g_ddraw->render.run)
{
2020-10-13 09:20:52 +02:00
This->last_flip_tick = timeGetTime();
InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
SwitchToThread();
2021-06-11 20:30:43 +02:00
if ((dwFlags & DDFLIP_WAIT) || g_ddraw->maxgameticks == -2)
2020-10-13 09:20:52 +02:00
{
dd_WaitForVerticalBlank(DDWAITVB_BLOCKEND, NULL);
}
if (g_ddraw->ticks_limiter.tick_length > 0)
{
g_ddraw->ticks_limiter.use_blt_or_flip = TRUE;
util_limit_game_ticks();
}
}
return DD_OK;
}
HRESULT dds_GetAttachedSurface(IDirectDrawSurfaceImpl* This, LPDDSCAPS lpDdsCaps, IDirectDrawSurfaceImpl** lpDDsurface)
2020-10-13 09:20:52 +02:00
{
2022-09-15 09:57:36 +02:00
if (lpDdsCaps->dwCaps & DDSCAPS_BACKBUFFER)
2020-10-13 09:20:52 +02:00
{
2021-05-04 22:49:22 +02:00
if (This->backbuffer)
{
IDirectDrawSurface_AddRef(This->backbuffer);
2021-06-11 20:30:43 +02:00
*lpDDsurface = This->backbuffer;
2021-05-04 22:49:22 +02:00
}
else
{
IDirectDrawSurface_AddRef(This);
2021-06-11 20:30:43 +02:00
*lpDDsurface = This;
2021-05-04 22:49:22 +02:00
}
2020-10-13 09:20:52 +02:00
}
return DD_OK;
}
2022-09-15 09:57:36 +02:00
return DDERR_NOTFOUND;
}
HRESULT dds_GetCaps(IDirectDrawSurfaceImpl* This, LPDDSCAPS lpDDSCaps)
2020-10-13 09:20:52 +02:00
{
lpDDSCaps->dwCaps = This->caps;
return DD_OK;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_GetClipper(IDirectDrawSurfaceImpl* This, IDirectDrawClipperImpl** lpClipper)
{
if (!lpClipper)
return DDERR_INVALIDPARAMS;
2021-06-11 20:30:43 +02:00
*lpClipper = This->clipper;
2021-05-26 19:21:40 +02:00
if (This->clipper)
{
IDirectDrawClipper_AddRef(This->clipper);
return DD_OK;
}
else
{
return DDERR_NOCLIPPERATTACHED;
}
}
2021-06-11 20:30:43 +02:00
HRESULT dds_GetColorKey(IDirectDrawSurfaceImpl* This, DWORD dwFlags, LPDDCOLORKEY lpColorKey)
2020-10-13 09:20:52 +02:00
{
2021-06-11 20:30:43 +02:00
if (lpColorKey)
2020-10-13 09:20:52 +02:00
{
2021-06-11 20:30:43 +02:00
lpColorKey->dwColorSpaceHighValue = This->color_key.dwColorSpaceHighValue;
lpColorKey->dwColorSpaceLowValue = This->color_key.dwColorSpaceLowValue;
2020-10-13 09:20:52 +02:00
}
return DD_OK;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_GetDC(IDirectDrawSurfaceImpl* This, HDC FAR* lpHDC)
2020-10-13 09:20:52 +02:00
{
2021-05-22 12:23:25 +02:00
if (!This)
{
if (lpHDC)
*lpHDC = NULL;
return DDERR_INVALIDPARAMS;
}
2020-10-22 22:37:57 +02:00
if ((This->l_pitch % 4))
2020-10-13 09:20:52 +02:00
{
2021-06-11 20:30:43 +02:00
TRACE("NOT_IMPLEMENTED GetDC: width=%d height=%d\n", This->width, This->height);
2020-10-13 09:20:52 +02:00
}
2021-06-11 20:30:43 +02:00
RGBQUAD* data =
2021-05-22 12:23:25 +02:00
This->palette ? This->palette->data_rgb :
2020-10-13 09:20:52 +02:00
g_ddraw->primary && g_ddraw->primary->palette ? g_ddraw->primary->palette->data_rgb :
NULL;
2021-05-22 12:23:25 +02:00
HDC dc = This->hdc;
if (This->backbuffer || (This->caps & DDSCAPS_BACKBUFFER))
dc = (HDC)InterlockedExchangeAdd((LONG*)&This->hdc, 0);
2021-06-15 03:20:41 +02:00
if (This->bpp == 8 && data)
2021-05-22 12:23:25 +02:00
SetDIBColorTable(dc, 0, 256, data);
2020-10-13 09:20:52 +02:00
if (lpHDC)
2021-05-22 12:23:25 +02:00
*lpHDC = dc;
2020-10-13 09:20:52 +02:00
return DD_OK;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_GetPalette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl** lplpDDPalette)
2020-10-13 09:20:52 +02:00
{
if (!lplpDDPalette)
return DDERR_INVALIDPARAMS;
2021-06-11 20:30:43 +02:00
*lplpDDPalette = This->palette;
2020-10-13 09:20:52 +02:00
if (This->palette)
{
2021-05-26 19:21:40 +02:00
IDirectDrawPalette_AddRef(This->palette);
2020-10-13 09:20:52 +02:00
return DD_OK;
}
else
{
return DDERR_NOPALETTEATTACHED;
}
}
2021-06-11 20:30:43 +02:00
HRESULT dds_GetPixelFormat(IDirectDrawSurfaceImpl* This, LPDDPIXELFORMAT ddpfPixelFormat)
2020-10-13 09:20:52 +02:00
{
if (ddpfPixelFormat)
2020-10-13 09:20:52 +02:00
{
memset(ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT));
ddpfPixelFormat->dwSize = sizeof(DDPIXELFORMAT);
2020-10-13 09:20:52 +02:00
ddpfPixelFormat->dwFlags = DDPF_RGB;
ddpfPixelFormat->dwRGBBitCount = This->bpp;
if (This->bpp == 8)
{
ddpfPixelFormat->dwFlags |= DDPF_PALETTEINDEXED8;
}
else if (This->bpp == 16)
{
ddpfPixelFormat->dwRBitMask = 0xF800;
ddpfPixelFormat->dwGBitMask = 0x07E0;
ddpfPixelFormat->dwBBitMask = 0x001F;
}
2021-06-02 01:52:45 +02:00
else if (This->bpp == 32)
{
ddpfPixelFormat->dwRBitMask = 0xFF0000;
ddpfPixelFormat->dwGBitMask = 0x00FF00;
ddpfPixelFormat->dwBBitMask = 0x0000FF;
}
2020-10-13 09:20:52 +02:00
return DD_OK;
}
return DDERR_INVALIDPARAMS;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_Lock(
IDirectDrawSurfaceImpl* This,
LPRECT lpDestRect,
LPDDSURFACEDESC lpDDSurfaceDesc,
DWORD dwFlags,
2021-06-11 20:30:43 +02:00
HANDLE hEvent)
2020-10-13 09:20:52 +02:00
{
dbg_dump_dds_lock_flags(dwFlags);
if (g_ddraw && g_ddraw->fixnotresponding)
{
MSG msg; /* workaround for "Not Responding" window problem */
PeekMessage(&msg, g_ddraw->hwnd, 0, 0, PM_NOREMOVE);
}
2021-04-24 08:14:48 +02:00
HRESULT ret = dds_GetSurfaceDesc(This, lpDDSurfaceDesc);
if (lpDestRect && lpDDSurfaceDesc)
2021-04-24 08:14:48 +02:00
{
2021-06-11 20:30:43 +02:00
if (lpDestRect->left < 0 ||
lpDestRect->top < 0 ||
lpDestRect->left > lpDestRect->right ||
lpDestRect->top > lpDestRect->bottom ||
lpDestRect->right > This->width ||
lpDestRect->bottom > This->height)
{
return DDERR_INVALIDPARAMS;
}
2021-06-11 20:30:43 +02:00
lpDDSurfaceDesc->lpSurface =
2021-05-04 22:49:22 +02:00
(char*)dds_GetBuffer(This) + (lpDestRect->left * This->lx_pitch) + (lpDestRect->top * This->l_pitch);
2021-04-24 08:14:48 +02:00
}
return ret;
2020-10-13 09:20:52 +02:00
}
2021-06-11 20:30:43 +02:00
HRESULT dds_ReleaseDC(IDirectDrawSurfaceImpl* This, HDC hDC)
2020-10-13 09:20:52 +02:00
{
2021-06-11 20:30:43 +02:00
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw->render.run)
2020-10-13 09:20:52 +02:00
{
2021-06-11 20:30:43 +02:00
InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
DWORD time = timeGetTime();
2020-10-13 09:20:52 +02:00
2021-06-11 20:30:43 +02:00
if (!(This->flags & DDSD_BACKBUFFERCOUNT) ||
(This->last_flip_tick + FLIP_REDRAW_TIMEOUT < time && This->last_blt_tick + FLIP_REDRAW_TIMEOUT < time))
{
ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
}
2020-10-13 09:20:52 +02:00
}
return DD_OK;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_SetClipper(IDirectDrawSurfaceImpl* This, IDirectDrawClipperImpl* lpClipper)
{
2021-05-09 00:51:02 +02:00
if (lpClipper)
IDirectDrawClipper_AddRef(lpClipper);
if (This->clipper)
IDirectDrawClipper_Release(This->clipper);
2021-06-11 20:30:43 +02:00
This->clipper = lpClipper;
2021-05-09 00:51:02 +02:00
return DD_OK;
}
2021-06-11 20:30:43 +02:00
HRESULT dds_SetColorKey(IDirectDrawSurfaceImpl* This, DWORD dwFlags, LPDDCOLORKEY lpColorKey)
{
if (lpColorKey)
{
TRACE_EXT(" dwColorSpaceHighValue=%d\n", lpColorKey->dwColorSpaceHighValue);
TRACE_EXT(" dwColorSpaceLowValue=%d\n", lpColorKey->dwColorSpaceLowValue);
This->color_key.dwColorSpaceHighValue = lpColorKey->dwColorSpaceHighValue;
This->color_key.dwColorSpaceLowValue = lpColorKey->dwColorSpaceLowValue;
}
return DD_OK;
}
HRESULT dds_SetPalette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* lpDDPalette)
2020-10-13 09:20:52 +02:00
{
2021-05-26 19:21:40 +02:00
if (lpDDPalette)
IDirectDrawPalette_AddRef(lpDDPalette);
2020-10-13 09:20:52 +02:00
if (This->palette)
IDirectDrawPalette_Release(This->palette);
2021-06-04 01:21:07 +02:00
if (This->caps & DDSCAPS_PRIMARYSURFACE)
{
EnterCriticalSection(&g_ddraw->cs);
2021-06-11 20:30:43 +02:00
This->palette = lpDDPalette;
2021-06-04 01:21:07 +02:00
LeaveCriticalSection(&g_ddraw->cs);
if (g_ddraw->render.run)
{
InterlockedExchange(&g_ddraw->render.palette_updated, TRUE);
ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
}
}
else
{
2021-06-11 20:30:43 +02:00
This->palette = lpDDPalette;
2021-06-04 01:21:07 +02:00
}
2020-10-13 09:20:52 +02:00
return DD_OK;
}
2021-06-13 05:17:46 +02:00
HRESULT dds_Unlock(IDirectDrawSurfaceImpl* This, LPRECT lpRect)
2020-10-13 09:20:52 +02:00
{
2021-06-11 20:30:43 +02:00
/* Hack for Warcraft II BNE and Diablo */
2020-10-13 09:20:52 +02:00
HWND hwnd = g_ddraw->bnet_active ? FindWindowEx(HWND_DESKTOP, NULL, "SDlgDialog", NULL) : NULL;
2020-10-13 11:29:52 +02:00
2020-10-13 09:20:52 +02:00
if (hwnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
{
2021-05-22 12:23:25 +02:00
HDC primary_dc;
2021-06-15 03:20:41 +02:00
dds_GetDC(This, &primary_dc);
2020-10-13 09:20:52 +02:00
2021-06-11 20:30:43 +02:00
/* GdiTransparentBlt idea taken from Aqrit's war2 ddraw */
2020-10-13 09:20:52 +02:00
RGBQUAD quad;
2021-05-22 12:23:25 +02:00
GetDIBColorTable(primary_dc, 0xFE, 1, &quad);
2020-10-13 09:20:52 +02:00
COLORREF color = RGB(quad.rgbRed, quad.rgbGreen, quad.rgbBlue);
BOOL erase = FALSE;
do
{
RECT rc;
if (fake_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,
2021-05-22 12:23:25 +02:00
primary_dc,
2020-10-13 09:20:52 +02:00
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)
{
BOOL x = g_ddraw->ticks_limiter.use_blt_or_flip;
DDBLTFX fx = { .dwFillColor = 0xFE };
IDirectDrawSurface_Blt(This, NULL, NULL, NULL, DDBLT_COLORFILL, &fx);
g_ddraw->ticks_limiter.use_blt_or_flip = x;
}
}
2021-06-11 20:30:43 +02:00
/* Hack for Star Trek Armada */
2021-06-09 07:24:17 +02:00
hwnd = g_ddraw->armadahack ? FindWindowEx(HWND_DESKTOP, NULL, "#32770", NULL) : NULL;
if (hwnd && (This->caps & DDSCAPS_PRIMARYSURFACE))
{
HDC primary_dc;
2021-06-15 03:20:41 +02:00
dds_GetDC(This, &primary_dc);
2021-06-09 07:24:17 +02:00
RECT rc;
if (fake_GetWindowRect(hwnd, &rc))
{
HDC hdc = GetDC(hwnd);
GdiTransparentBlt(
hdc,
0,
0,
rc.right - rc.left,
rc.bottom - rc.top,
primary_dc,
rc.left,
rc.top,
rc.right - rc.left,
rc.bottom - rc.top,
0
);
ReleaseDC(hwnd, hdc);
}
BOOL x = g_ddraw->ticks_limiter.use_blt_or_flip;
DDBLTFX fx = { .dwFillColor = 0 };
IDirectDrawSurface_Blt(This, NULL, NULL, NULL, DDBLT_COLORFILL, &fx);
g_ddraw->ticks_limiter.use_blt_or_flip = x;
}
2020-10-13 09:20:52 +02:00
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw->render.run)
{
InterlockedExchange(&g_ddraw->render.surface_updated, TRUE);
DWORD time = timeGetTime();
if (!(This->flags & DDSD_BACKBUFFERCOUNT) ||
(This->last_flip_tick + FLIP_REDRAW_TIMEOUT < time && This->last_blt_tick + FLIP_REDRAW_TIMEOUT < time))
{
ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
if (g_ddraw->ticks_limiter.tick_length > 0 && !g_ddraw->ticks_limiter.use_blt_or_flip)
util_limit_game_ticks();
}
}
return DD_OK;
}
2021-05-29 20:51:19 +02:00
HRESULT dds_GetDDInterface(IDirectDrawSurfaceImpl* This, LPVOID* lplpDD)
{
if (!lplpDD)
return DDERR_INVALIDPARAMS;
*lplpDD = This->ddraw;
IDirectDraw_AddRef(This->ddraw);
return DD_OK;
}
2021-05-04 22:49:22 +02:00
void* dds_GetBuffer(IDirectDrawSurfaceImpl* This)
{
if (!This)
return NULL;
if (This->backbuffer || (This->caps & DDSCAPS_BACKBUFFER))
2021-05-10 01:00:55 +02:00
return (void*)InterlockedExchangeAdd((LONG*)&This->surface, 0);
2021-05-04 22:49:22 +02:00
return This->surface;
}
2021-06-11 20:30:43 +02:00
HRESULT dd_CreateSurface(
IDirectDrawImpl* This,
LPDDSURFACEDESC lpDDSurfaceDesc,
IDirectDrawSurfaceImpl** lpDDSurface,
2021-06-11 20:30:43 +02:00
IUnknown FAR* unkOuter)
2020-10-13 09:20:52 +02:00
{
dbg_dump_dds_flags(lpDDSurfaceDesc->dwFlags);
dbg_dump_dds_caps(lpDDSurfaceDesc->ddsCaps.dwCaps);
2021-06-11 20:30:43 +02:00
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
g_ddraw->primary &&
g_ddraw->primary->width == g_ddraw->width &&
g_ddraw->primary->height == g_ddraw->height &&
g_ddraw->primary->bpp == g_ddraw->bpp)
{
2021-06-11 20:30:43 +02:00
*lpDDSurface = g_ddraw->primary;
IDirectDrawSurface_AddRef(g_ddraw->primary);
return DD_OK;
}
2020-10-13 09:20:52 +02:00
IDirectDrawSurfaceImpl* dst_surface =
2021-06-11 20:30:43 +02:00
(IDirectDrawSurfaceImpl*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl));
2020-10-13 09:20:52 +02:00
dst_surface->lpVtbl = &g_dds_vtbl;
lpDDSurfaceDesc->dwFlags |= DDSD_CAPS;
dst_surface->bpp = g_ddraw->bpp == 0 ? 16 : g_ddraw->bpp;
2020-10-13 09:20:52 +02:00
dst_surface->flags = lpDDSurfaceDesc->dwFlags;
dst_surface->caps = lpDDSurfaceDesc->ddsCaps.dwCaps;
2021-05-29 20:51:19 +02:00
dst_surface->ddraw = This;
2020-10-13 09:20:52 +02:00
2021-06-06 05:25:33 +02:00
if (dst_surface->flags & DDSD_PIXELFORMAT)
{
switch (lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount)
{
case 8:
dst_surface->bpp = 8;
break;
case 15:
2021-06-11 20:30:43 +02:00
TRACE(" NOT_IMPLEMENTED bpp=%u\n", lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount);
2021-06-06 05:25:33 +02:00
case 16:
dst_surface->bpp = 16;
break;
case 24:
2021-06-11 20:30:43 +02:00
TRACE(" NOT_IMPLEMENTED bpp=%u\n", lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount);
2021-06-06 05:25:33 +02:00
case 32:
dst_surface->bpp = 32;
break;
default:
2021-06-11 20:30:43 +02:00
TRACE(" NOT_IMPLEMENTED bpp=%u\n", lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount);
2021-06-06 05:25:33 +02:00
break;
}
}
2021-05-23 06:16:58 +02:00
if (dst_surface->caps & DDSCAPS_PRIMARYSURFACE)
2020-10-13 09:20:52 +02:00
{
dst_surface->width = g_ddraw->width;
dst_surface->height = g_ddraw->height;
2020-10-13 09:20:52 +02:00
}
else
2020-10-13 09:20:52 +02:00
{
dst_surface->width = lpDDSurfaceDesc->dwWidth;
dst_surface->height = lpDDSurfaceDesc->dwHeight;
}
if (dst_surface->width && dst_surface->height)
2020-10-13 09:20:52 +02:00
{
2021-05-23 06:16:58 +02:00
dst_surface->lx_pitch = dst_surface->bpp / 8;
2022-09-13 09:34:48 +02:00
dst_surface->l_pitch = ((dst_surface->width * dst_surface->bpp + 31) & ~31) >> 3;
2022-09-13 17:16:20 +02:00
dst_surface->size = dst_surface->l_pitch * dst_surface->height;
2021-05-23 06:16:58 +02:00
2022-09-13 09:51:19 +02:00
DWORD aligned_width = dst_surface->l_pitch / dst_surface->lx_pitch;
2021-06-11 20:30:43 +02:00
dst_surface->bmi =
2021-06-11 20:30:43 +02:00
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
2021-05-23 06:16:58 +02:00
2020-10-13 09:20:52 +02:00
dst_surface->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
2022-09-13 09:51:19 +02:00
dst_surface->bmi->bmiHeader.biWidth = aligned_width;
dst_surface->bmi->bmiHeader.biHeight = -((int)dst_surface->height + 200);
2020-10-13 09:20:52 +02:00
dst_surface->bmi->bmiHeader.biPlanes = 1;
dst_surface->bmi->bmiHeader.biBitCount = dst_surface->bpp;
2021-06-02 01:52:45 +02:00
dst_surface->bmi->bmiHeader.biCompression = dst_surface->bpp == 8 ? BI_RGB : BI_BITFIELDS;
2020-10-13 09:20:52 +02:00
2020-10-13 11:29:52 +02:00
WORD clr_bits = (WORD)(dst_surface->bmi->bmiHeader.biPlanes * dst_surface->bmi->bmiHeader.biBitCount);
2020-10-13 21:58:04 +02:00
2020-10-13 11:29:52 +02:00
if (clr_bits < 24)
2020-10-13 21:58:04 +02:00
{
2020-10-13 11:29:52 +02:00
dst_surface->bmi->bmiHeader.biClrUsed = (1 << clr_bits);
2020-10-13 21:58:04 +02:00
}
2020-10-13 09:20:52 +02:00
dst_surface->bmi->bmiHeader.biSizeImage =
2022-09-13 09:51:19 +02:00
((aligned_width * clr_bits + 31) & ~31) / 8 * dst_surface->height;
2020-10-13 09:20:52 +02:00
if (dst_surface->bpp == 8)
{
2021-05-22 12:23:25 +02:00
for (int i = 0; i < 256; i++)
2020-10-13 09:20:52 +02:00
{
dst_surface->bmi->bmiColors[i].rgbRed = i;
dst_surface->bmi->bmiColors[i].rgbGreen = i;
dst_surface->bmi->bmiColors[i].rgbBlue = i;
dst_surface->bmi->bmiColors[i].rgbReserved = 0;
}
}
else if (dst_surface->bpp == 16)
{
2021-06-02 01:52:45 +02:00
((DWORD*)dst_surface->bmi->bmiColors)[0] = 0xF800;
((DWORD*)dst_surface->bmi->bmiColors)[1] = 0x07E0;
((DWORD*)dst_surface->bmi->bmiColors)[2] = 0x001F;
}
else if (dst_surface->bpp == 32)
{
((DWORD*)dst_surface->bmi->bmiColors)[0] = 0xFF0000;
((DWORD*)dst_surface->bmi->bmiColors)[1] = 0x00FF00;
((DWORD*)dst_surface->bmi->bmiColors)[2] = 0x0000FF;
2020-10-13 09:20:52 +02:00
}
dst_surface->hdc = CreateCompatibleDC(g_ddraw->render.hdc);
dst_surface->bitmap =
2021-06-11 20:30:43 +02:00
CreateDIBSection(dst_surface->hdc, dst_surface->bmi, DIB_RGB_COLORS, (void**)&dst_surface->surface, NULL, 0);
2022-09-13 09:51:19 +02:00
dst_surface->bmi->bmiHeader.biHeight = -((int)dst_surface->height);
2020-10-13 09:20:52 +02:00
if (!dst_surface->bitmap)
2020-10-13 21:58:04 +02:00
{
2021-06-11 20:30:43 +02:00
dst_surface->surface =
2020-10-13 21:58:04 +02:00
HeapAlloc(
2021-06-11 20:30:43 +02:00
GetProcessHeap(),
HEAP_ZERO_MEMORY,
2022-09-13 17:16:20 +02:00
dst_surface->l_pitch * (dst_surface->height + 200));
2020-10-13 21:58:04 +02:00
}
2020-10-13 09:20:52 +02:00
2021-05-23 06:16:58 +02:00
if (dst_surface->caps & DDSCAPS_PRIMARYSURFACE)
2020-10-13 21:58:04 +02:00
{
g_ddraw->primary = dst_surface;
2020-10-15 05:13:37 +02:00
FakePrimarySurface = dst_surface->surface;
2020-10-13 21:58:04 +02:00
}
2020-10-13 09:20:52 +02:00
SelectObject(dst_surface->hdc, dst_surface->bitmap);
}
2021-05-23 06:16:58 +02:00
if (dst_surface->flags & DDSD_BACKBUFFERCOUNT)
2020-10-13 09:20:52 +02:00
{
2021-06-11 20:30:43 +02:00
TRACE(" dwBackBufferCount=%d\n", lpDDSurfaceDesc->dwBackBufferCount);
2021-05-04 22:49:22 +02:00
DDSURFACEDESC desc;
2021-06-11 20:30:43 +02:00
memset(&desc, 0, sizeof(desc));
2021-05-04 22:49:22 +02:00
2021-06-11 20:30:43 +02:00
if (lpDDSurfaceDesc->dwBackBufferCount > 1)
{
desc.dwBackBufferCount = lpDDSurfaceDesc->dwBackBufferCount - 1;
desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
}
2021-05-31 18:54:32 +02:00
2021-06-11 20:30:43 +02:00
desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
2021-05-04 22:49:22 +02:00
2021-06-11 20:30:43 +02:00
desc.dwWidth = dst_surface->width;
desc.dwHeight = dst_surface->height;
2021-05-04 22:49:22 +02:00
2021-06-11 20:30:43 +02:00
dd_CreateSurface(This, &desc, &dst_surface->backbuffer, unkOuter);
2020-10-13 09:20:52 +02:00
}
2021-06-11 20:30:43 +02:00
TRACE(
" surface = %p (%ux%u@%u)\n",
dst_surface,
dst_surface->width,
dst_surface->height,
2021-06-11 20:30:43 +02:00
dst_surface->bpp);
2020-10-13 09:20:52 +02:00
2021-06-11 20:30:43 +02:00
*lpDDSurface = dst_surface;
2020-10-13 09:20:52 +02:00
dst_surface->ref = 0;
IDirectDrawSurface_AddRef(dst_surface);
2021-06-11 20:30:43 +02:00
2020-10-13 09:20:52 +02:00
return DD_OK;
}