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"
|
2022-09-08 02:19:15 +02:00
|
|
|
#include "blt.h"
|
2023-09-22 00:38:42 +02:00
|
|
|
#include "config.h"
|
2024-05-28 00:33:05 +02:00
|
|
|
#include "ddclipper.h"
|
2024-09-11 18:01:21 +02:00
|
|
|
#include "utils.h"
|
2024-05-06 01:23:59 +02:00
|
|
|
#include "versionhelpers.h"
|
2024-12-15 00:05:51 +01:00
|
|
|
#include "ddpalette.h"
|
2024-12-19 21:28:43 +01:00
|
|
|
#include "palette.h"
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
|
2023-07-31 09:17:57 +02:00
|
|
|
LONG g_dds_gdi_handles;
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
HRESULT dds_AddAttachedSurface(IDirectDrawSurfaceImpl* This, IDirectDrawSurfaceImpl* lpDDSurface)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-05-06 01:24:07 +02:00
|
|
|
if (lpDDSurface)
|
2021-05-06 00:15:47 +02:00
|
|
|
{
|
2021-05-06 01:24:07 +02:00
|
|
|
IDirectDrawSurface_AddRef(lpDDSurface);
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
if (!This->backbuffer)
|
2021-05-06 01:24:07 +02:00
|
|
|
{
|
2023-07-27 06:59:09 +02:00
|
|
|
if (This->caps & DDSCAPS_FRONTBUFFER)
|
|
|
|
{
|
|
|
|
lpDDSurface->caps |= DDSCAPS_BACKBUFFER;
|
|
|
|
}
|
|
|
|
|
|
|
|
lpDDSurface->caps |= DDSCAPS_FLIP;
|
|
|
|
|
2022-09-27 15:31:03 +02:00
|
|
|
This->backbuffer = lpDDSurface;
|
2021-05-06 01:24:07 +02:00
|
|
|
}
|
2021-05-06 00:15:47 +02:00
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
HRESULT dds_Blt(
|
2022-09-08 02:19:15 +02:00
|
|
|
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
|
|
|
{
|
2024-12-26 23:59:05 +01:00
|
|
|
if (lpDDSrcSurface &&
|
|
|
|
lpDDSrcSurface->bpp != 8 &&
|
|
|
|
lpDDSrcSurface->bpp != 16 &&
|
|
|
|
lpDDSrcSurface->bpp != 24 &&
|
|
|
|
lpDDSrcSurface->bpp != 32)
|
|
|
|
{
|
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
|
2024-09-11 18:01:21 +02:00
|
|
|
util_pull_messages();
|
2024-09-02 12:40:39 +02:00
|
|
|
|
2024-03-22 22:27:00 +01:00
|
|
|
if (g_ddraw.ref &&
|
|
|
|
g_ddraw.iskkndx &&
|
2021-06-11 20:30:43 +02:00
|
|
|
(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);
|
|
|
|
}
|
|
|
|
|
2021-05-15 00:41:50 +02:00
|
|
|
lpDestRect = NULL;
|
2021-06-05 22:15:52 +02:00
|
|
|
}
|
2021-05-15 00:41:50 +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)
|
2024-11-04 02:27:34 +01:00
|
|
|
{
|
2024-12-26 23:59:55 +01:00
|
|
|
//dbg_print_rect("lpSrcRect", lpSrcRect);
|
2024-11-04 02:27:34 +01:00
|
|
|
src_rect = *lpSrcRect;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
if (lpDestRect)
|
2024-11-04 02:27:34 +01:00
|
|
|
{
|
2024-12-26 23:59:55 +01:00
|
|
|
//dbg_print_rect("lpDestRect", lpDestRect);
|
2024-11-04 02:27:34 +01:00
|
|
|
dst_rect = *lpDestRect;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2022-09-28 00:52:32 +02:00
|
|
|
int src_w = src_rect.right - src_rect.left;
|
|
|
|
int src_h = src_rect.bottom - src_rect.top;
|
|
|
|
|
|
|
|
int dst_w = dst_rect.right - dst_rect.left;
|
|
|
|
int dst_h = dst_rect.bottom - dst_rect.top;
|
|
|
|
|
2022-09-29 17:21:23 +02:00
|
|
|
float scale_w = (src_w > 0 && dst_w > 0) ? (float)src_w / dst_w : 1.0f;
|
|
|
|
float scale_h = (src_h > 0 && dst_h > 0) ? (float)src_h / dst_h : 1.0f;
|
|
|
|
|
2022-09-28 00:52:32 +02:00
|
|
|
BOOL is_stretch_blt = src_w != dst_w || src_h != dst_h;
|
|
|
|
|
2024-05-28 00:53:50 +02:00
|
|
|
if (This->clipper && !This->clipper->hwnd && !(dwFlags & DDBLT_NO_CLIP) && dst_w > 0 && dst_h > 0)
|
2022-09-28 00:52:32 +02:00
|
|
|
{
|
|
|
|
DWORD size = 0;
|
|
|
|
|
2024-05-28 00:33:05 +02:00
|
|
|
HRESULT result = ddc_GetClipList(This->clipper, &dst_rect, NULL, &size);
|
2024-05-26 09:08:38 +02:00
|
|
|
|
|
|
|
if (SUCCEEDED(result))
|
2022-09-28 00:52:32 +02:00
|
|
|
{
|
|
|
|
RGNDATA* list = (RGNDATA*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
|
|
|
|
|
|
|
|
if (list)
|
|
|
|
{
|
2024-05-28 00:33:05 +02:00
|
|
|
if (SUCCEEDED(ddc_GetClipList(This->clipper, &dst_rect, list, &size)))
|
2022-09-28 00:52:32 +02:00
|
|
|
{
|
|
|
|
RECT* dst_c_rect = (RECT*)list->Buffer;
|
|
|
|
|
|
|
|
for (int i = 0; i < list->rdh.nCount; ++i)
|
|
|
|
{
|
|
|
|
RECT src_c_rect = src_rect;
|
|
|
|
|
2022-09-29 17:21:23 +02:00
|
|
|
if (src_surface)
|
|
|
|
{
|
|
|
|
src_c_rect.left += (LONG)((dst_c_rect[i].left - dst_rect.left) * scale_w);
|
|
|
|
src_c_rect.top += (LONG)((dst_c_rect[i].top - dst_rect.top) * scale_h);
|
|
|
|
src_c_rect.right -= (LONG)((dst_rect.right - dst_c_rect[i].right) * scale_w);
|
|
|
|
src_c_rect.bottom -= (LONG)((dst_rect.bottom - dst_c_rect[i].bottom) * scale_h);
|
|
|
|
}
|
2022-09-29 13:44:25 +02:00
|
|
|
|
2022-09-28 00:52:32 +02:00
|
|
|
dds_Blt(This, &dst_c_rect[i], src_surface, &src_c_rect, dwFlags | DDBLT_NO_CLIP, lpDDBltFx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
HeapFree(GetProcessHeap(), 0, list);
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
}
|
2024-05-26 09:08:38 +02:00
|
|
|
else if (result == DDERR_NOCLIPLIST)
|
|
|
|
{
|
2024-05-28 00:33:05 +02:00
|
|
|
TRACE(" DDERR_NOCLIPLIST\n");
|
|
|
|
//return DDERR_NOCLIPLIST;
|
2024-05-26 09:08:38 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-05-28 00:33:05 +02:00
|
|
|
TRACE(" DDERR_INVALIDCLIPLIST\n");
|
|
|
|
//return DDERR_INVALIDCLIPLIST;
|
2024-05-26 09:08:38 +02:00
|
|
|
}
|
2022-09-28 00:52:32 +02:00
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2022-10-15 05:04:19 +02:00
|
|
|
if (dst_rect.right < 0)
|
|
|
|
dst_rect.right = 0;
|
|
|
|
|
2021-05-06 05:09:27 +02:00
|
|
|
if (dst_rect.left < 0)
|
2022-09-27 22:45:13 +02:00
|
|
|
{
|
2022-09-29 21:27:05 +02:00
|
|
|
src_rect.left += (LONG)(abs(dst_rect.left) * scale_w);
|
2021-05-06 05:09:27 +02:00
|
|
|
dst_rect.left = 0;
|
2022-09-27 22:45:13 +02:00
|
|
|
}
|
2021-05-06 05:09:27 +02:00
|
|
|
|
2022-10-15 05:04:19 +02:00
|
|
|
if (dst_rect.bottom < 0)
|
|
|
|
dst_rect.bottom = 0;
|
|
|
|
|
2021-05-06 05:09:27 +02:00
|
|
|
if (dst_rect.top < 0)
|
2022-09-27 22:45:13 +02:00
|
|
|
{
|
2022-09-29 21:27:05 +02:00
|
|
|
src_rect.top += (LONG)(abs(dst_rect.top) * scale_h);
|
2021-05-06 05:09:27 +02:00
|
|
|
dst_rect.top = 0;
|
2022-09-27 22:45:13 +02:00
|
|
|
}
|
2021-05-06 05:09:27 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (dst_rect.right > This->width)
|
2022-09-29 21:27:05 +02:00
|
|
|
{
|
|
|
|
src_rect.right -= (LONG)((dst_rect.right - This->width) * scale_w);
|
2020-10-13 09:20:52 +02:00
|
|
|
dst_rect.right = This->width;
|
2022-09-29 21:27:05 +02:00
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2020-10-20 15:00:12 +02:00
|
|
|
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)
|
2022-09-29 21:27:05 +02:00
|
|
|
{
|
|
|
|
src_rect.bottom -= (LONG)((dst_rect.bottom - This->height) * scale_h);
|
2020-10-13 09:20:52 +02:00
|
|
|
dst_rect.bottom = This->height;
|
2022-09-29 21:27:05 +02:00
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2020-10-20 18:49:58 +02:00
|
|
|
if (dst_rect.top > dst_rect.bottom)
|
|
|
|
dst_rect.top = dst_rect.bottom;
|
2020-10-20 15:00:12 +02:00
|
|
|
|
2022-09-29 17:21:23 +02:00
|
|
|
if (src_surface)
|
|
|
|
{
|
2022-10-15 05:04:19 +02:00
|
|
|
if (src_rect.right < 0)
|
|
|
|
src_rect.right = 0;
|
|
|
|
|
2022-09-29 17:21:23 +02:00
|
|
|
if (src_rect.left < 0)
|
|
|
|
src_rect.left = 0;
|
|
|
|
|
2022-10-15 05:04:19 +02:00
|
|
|
if (src_rect.bottom < 0)
|
|
|
|
src_rect.bottom = 0;
|
|
|
|
|
2022-09-29 17:21:23 +02:00
|
|
|
if (src_rect.top < 0)
|
|
|
|
src_rect.top = 0;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
if (src_rect.bottom > src_surface->height)
|
|
|
|
src_rect.bottom = src_surface->height;
|
|
|
|
|
|
|
|
if (src_rect.top > src_rect.bottom)
|
|
|
|
src_rect.top = src_rect.bottom;
|
|
|
|
}
|
|
|
|
|
2022-09-28 00:52:32 +02:00
|
|
|
src_w = src_rect.right - src_rect.left;
|
|
|
|
src_h = src_rect.bottom - src_rect.top;
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
int src_x = src_rect.left;
|
|
|
|
int src_y = src_rect.top;
|
|
|
|
|
2022-09-28 00:52:32 +02:00
|
|
|
dst_w = dst_rect.right - dst_rect.left;
|
|
|
|
dst_h = dst_rect.bottom - dst_rect.top;
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
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
|
|
|
|
2022-09-08 02:19:15 +02:00
|
|
|
if (dst_buf && (dwFlags & DDBLT_COLORFILL) && lpDDBltFx && dst_w > 0 && dst_h > 0)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-12-23 04:55:15 +01:00
|
|
|
if (This->bpp == 24)
|
|
|
|
{
|
2024-12-23 05:32:02 +01:00
|
|
|
TRACE_EXT(" NOT_IMPLEMENTED This->bpp=%u, dwFillColor=%08X\n", This->bpp, lpDDBltFx->dwFillColor);
|
2024-12-23 04:55:15 +01:00
|
|
|
}
|
|
|
|
|
2022-09-08 02:19:15 +02:00
|
|
|
blt_colorfill(
|
2022-09-27 15:31:03 +02:00
|
|
|
dst_buf,
|
|
|
|
dst_x,
|
|
|
|
dst_y,
|
|
|
|
dst_w,
|
|
|
|
dst_h,
|
2022-10-19 03:20:31 +02:00
|
|
|
This->pitch,
|
2022-09-27 15:31:03 +02:00
|
|
|
lpDDBltFx->dwFillColor,
|
2022-09-08 02:19:15 +02:00
|
|
|
This->bpp);
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
|
2020-10-20 15:00:12 +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
|
|
|
{
|
2022-09-29 17:21:23 +02:00
|
|
|
if (!is_stretch_blt)
|
|
|
|
{
|
|
|
|
src_w = dst_w = min(src_w, dst_w);
|
|
|
|
src_h = dst_h = min(src_h, dst_h);
|
|
|
|
}
|
|
|
|
|
2021-09-08 22:51:44 +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);
|
|
|
|
|
2024-12-23 04:55:15 +01:00
|
|
|
if (This->bpp != src_surface->bpp ||
|
|
|
|
This->bpp == 24 ||
|
|
|
|
src_surface->bpp == 24 ||
|
|
|
|
(is_stretch_blt && This == src_surface))
|
2021-06-06 05:25:33 +02:00
|
|
|
{
|
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);
|
|
|
|
|
2024-12-26 01:34:52 +01:00
|
|
|
if (((dwFlags & DDBLT_KEYSRC) && (src_surface->flags & DDSD_CKSRCBLT)) || (dwFlags & DDBLT_KEYSRCOVERRIDE))
|
2022-09-29 00:19:48 +02:00
|
|
|
{
|
|
|
|
UINT color =
|
|
|
|
(dwFlags & DDBLT_KEYSRCOVERRIDE) ?
|
|
|
|
lpDDBltFx->ddckSrcColorkey.dwColorSpaceLowValue : src_surface->color_key.dwColorSpaceLowValue;
|
|
|
|
|
2024-12-23 04:55:15 +01:00
|
|
|
if (src_surface->bpp == 32 || src_surface->bpp == 24)
|
2022-09-29 00:19:48 +02:00
|
|
|
{
|
|
|
|
color = color & 0xFFFFFF;
|
|
|
|
}
|
|
|
|
else if (src_surface->bpp == 16)
|
|
|
|
{
|
|
|
|
unsigned short c = (unsigned short)color;
|
|
|
|
|
|
|
|
BYTE r = ((c & 0xF800) >> 11) << 3;
|
|
|
|
BYTE g = ((c & 0x07E0) >> 5) << 2;
|
|
|
|
BYTE b = ((c & 0x001F)) << 3;
|
|
|
|
|
|
|
|
color = RGB(r, g, b);
|
|
|
|
}
|
|
|
|
else if (src_surface->bpp == 8)
|
|
|
|
{
|
|
|
|
RGBQUAD* quad =
|
|
|
|
src_surface->palette ? src_surface->palette->data_rgb :
|
2024-03-22 22:27:00 +01:00
|
|
|
g_ddraw.ref && g_ddraw.primary && g_ddraw.primary->palette ? g_ddraw.primary->palette->data_rgb :
|
2022-09-29 00:19:48 +02:00
|
|
|
NULL;
|
|
|
|
|
|
|
|
if (quad)
|
|
|
|
{
|
|
|
|
unsigned char i = (unsigned char)color;
|
|
|
|
|
|
|
|
color = RGB(quad[i].rgbRed, quad[i].rgbGreen, quad[i].rgbBlue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GdiTransparentBlt(dst_dc, dst_x, dst_y, dst_w, dst_h, src_dc, src_x, src_y, src_w, src_h, color);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-10-02 18:41:06 +02:00
|
|
|
real_StretchBlt(dst_dc, dst_x, dst_y, dst_w, dst_h, src_dc, src_x, src_y, src_w, src_h, SRCCOPY);
|
2022-09-29 00:19:48 +02:00
|
|
|
}
|
|
|
|
|
2022-09-28 01:59:12 +02:00
|
|
|
/*
|
|
|
|
StretchBlt(
|
|
|
|
dst_dc,
|
|
|
|
lpDestRect->left,
|
|
|
|
lpDestRect->top,
|
|
|
|
lpDestRect->right - lpDestRect->left,
|
|
|
|
lpDestRect->bottom - lpDestRect->top,
|
|
|
|
src_dc,
|
|
|
|
lpSrcRect->left,
|
|
|
|
lpSrcRect->top,
|
|
|
|
lpSrcRect->right - lpSrcRect->left,
|
|
|
|
lpSrcRect->bottom - lpSrcRect->top,
|
|
|
|
SRCCOPY);
|
|
|
|
*/
|
2021-06-06 05:25:33 +02:00
|
|
|
}
|
2021-09-08 22:51:44 +02:00
|
|
|
else if (
|
2024-12-26 01:34:52 +01:00
|
|
|
((dwFlags & DDBLT_KEYSRC) && (src_surface->flags & DDSD_CKSRCBLT)) ||
|
2022-09-08 02:19:15 +02:00
|
|
|
(dwFlags & DDBLT_KEYSRCOVERRIDE) ||
|
2021-09-08 22:51:44 +02:00
|
|
|
mirror_left_right ||
|
|
|
|
mirror_up_down)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-09-08 22:51:44 +02:00
|
|
|
DDCOLORKEY color_key = { 0xFFFFFFFF, 0 };
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2021-09-08 22:51:44 +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
|
|
|
|
2021-09-08 22:51:44 +02:00
|
|
|
color_key.dwColorSpaceHighValue =
|
|
|
|
(dwFlags & DDBLT_KEYSRCOVERRIDE) ?
|
|
|
|
lpDDBltFx->ddckSrcColorkey.dwColorSpaceHighValue : src_surface->color_key.dwColorSpaceHighValue;
|
2022-09-06 07:28:17 +02:00
|
|
|
|
|
|
|
if (color_key.dwColorSpaceHighValue < color_key.dwColorSpaceLowValue)
|
|
|
|
color_key.dwColorSpaceHighValue = color_key.dwColorSpaceLowValue;
|
2021-09-08 22:51:44 +02:00
|
|
|
}
|
2021-05-10 23:40:42 +02:00
|
|
|
|
2022-09-27 22:45:13 +02:00
|
|
|
if (!is_stretch_blt && !mirror_left_right && !mirror_up_down)
|
2021-05-06 16:10:09 +02:00
|
|
|
{
|
2022-09-08 02:19:15 +02:00
|
|
|
blt_colorkey(
|
|
|
|
dst_buf,
|
|
|
|
dst_x,
|
|
|
|
dst_y,
|
2022-09-29 12:55:16 +02:00
|
|
|
dst_w,
|
|
|
|
dst_h,
|
2022-10-19 03:20:31 +02:00
|
|
|
This->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
src_buf,
|
|
|
|
src_x,
|
|
|
|
src_y,
|
2022-10-19 03:20:31 +02:00
|
|
|
src_surface->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
color_key.dwColorSpaceLowValue,
|
|
|
|
color_key.dwColorSpaceHighValue,
|
|
|
|
This->bpp);
|
2021-06-02 01:52:45 +02:00
|
|
|
}
|
2022-09-08 02:19:15 +02:00
|
|
|
else
|
2021-06-02 01:52:45 +02:00
|
|
|
{
|
2022-09-08 02:19:15 +02:00
|
|
|
blt_colorkey_mirror_stretch(
|
|
|
|
dst_buf,
|
|
|
|
dst_x,
|
|
|
|
dst_y,
|
|
|
|
dst_w,
|
|
|
|
dst_h,
|
2022-10-19 03:20:31 +02:00
|
|
|
This->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
src_buf,
|
|
|
|
src_x,
|
|
|
|
src_y,
|
|
|
|
src_w,
|
|
|
|
src_h,
|
2022-10-19 03:20:31 +02:00
|
|
|
src_surface->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
color_key.dwColorSpaceLowValue,
|
|
|
|
color_key.dwColorSpaceHighValue,
|
|
|
|
mirror_up_down,
|
|
|
|
mirror_left_right,
|
|
|
|
This->bpp);
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
2022-09-27 22:45:13 +02:00
|
|
|
else if (is_stretch_blt && (src_w != dst_w || src_h != dst_h))
|
2022-09-08 02:19:15 +02:00
|
|
|
{
|
|
|
|
blt_stretch(
|
|
|
|
dst_buf,
|
|
|
|
dst_x,
|
|
|
|
dst_y,
|
|
|
|
dst_w,
|
|
|
|
dst_h,
|
2022-10-19 03:20:31 +02:00
|
|
|
This->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
src_buf,
|
|
|
|
src_x,
|
|
|
|
src_y,
|
|
|
|
src_w,
|
|
|
|
src_h,
|
2022-10-19 03:20:31 +02:00
|
|
|
src_surface->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
This->bpp);
|
|
|
|
}
|
|
|
|
else if (This == src_surface)
|
|
|
|
{
|
|
|
|
blt_overlap(
|
|
|
|
dst_buf,
|
|
|
|
dst_x,
|
|
|
|
dst_y,
|
2022-09-29 12:55:16 +02:00
|
|
|
dst_w,
|
|
|
|
dst_h,
|
2022-10-19 03:20:31 +02:00
|
|
|
This->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
src_buf,
|
|
|
|
src_x,
|
|
|
|
src_y,
|
2022-10-19 03:20:31 +02:00
|
|
|
src_surface->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
This->bpp);
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
else
|
|
|
|
{
|
2022-09-08 02:19:15 +02:00
|
|
|
blt_clean(
|
|
|
|
dst_buf,
|
|
|
|
dst_x,
|
|
|
|
dst_y,
|
2022-09-29 12:55:16 +02:00
|
|
|
dst_w,
|
|
|
|
dst_h,
|
2022-10-19 03:20:31 +02:00
|
|
|
This->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
src_buf,
|
|
|
|
src_x,
|
|
|
|
src_y,
|
2022-10-19 03:20:31 +02:00
|
|
|
src_surface->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
This->bpp);
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-22 22:27:00 +01:00
|
|
|
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw.ref && g_ddraw.render.run)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-03-22 22:27:00 +01:00
|
|
|
InterlockedExchange(&g_ddraw.render.surface_updated, TRUE);
|
2024-12-22 02:21:23 +01:00
|
|
|
InterlockedExchange(&g_ddraw.render.screen_updated, TRUE);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
if (!(This->flags & DDSD_BACKBUFFERCOUNT) || This->last_flip_tick + FLIP_REDRAW_TIMEOUT < timeGetTime())
|
|
|
|
{
|
|
|
|
This->last_blt_tick = timeGetTime();
|
|
|
|
|
2024-06-02 23:57:21 +02:00
|
|
|
ReleaseSemaphore(g_ddraw.render.sem, 1, NULL);
|
2020-10-13 09:20:52 +02:00
|
|
|
SwitchToThread();
|
|
|
|
|
2024-12-22 02:21:23 +01:00
|
|
|
if (g_ddraw.ticks_limiter.tick_length > 0 && g_config.limiter_type != LIMIT_PEEKMESSAGE)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-05-31 21:43:33 +02:00
|
|
|
g_ddraw.ticks_limiter.dds_unlock_limiter_disabled = TRUE;
|
2020-10-13 09:20:52 +02:00
|
|
|
util_limit_game_ticks();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
HRESULT dds_BltFast(
|
2022-09-08 02:19:15 +02:00
|
|
|
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)
|
2024-11-04 02:27:34 +01:00
|
|
|
{
|
|
|
|
//dbg_print_rect("lpSrcRect", lpSrcRect);
|
|
|
|
src_rect = *lpSrcRect;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2022-09-29 21:34:55 +02:00
|
|
|
int dst_x = dwX;
|
|
|
|
int dst_y = dwY;
|
|
|
|
|
|
|
|
if (dst_x < 0)
|
|
|
|
{
|
|
|
|
src_rect.left += abs(dst_x);
|
|
|
|
dst_x = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dst_y < 0)
|
|
|
|
{
|
|
|
|
src_rect.top += abs(dst_y);
|
|
|
|
dst_y = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (src_surface)
|
|
|
|
{
|
2022-10-15 05:04:19 +02:00
|
|
|
if (src_rect.right < 0)
|
|
|
|
src_rect.right = 0;
|
|
|
|
|
2021-05-06 05:09:27 +02:00
|
|
|
if (src_rect.left < 0)
|
|
|
|
src_rect.left = 0;
|
|
|
|
|
2022-10-15 05:04:19 +02:00
|
|
|
if (src_rect.bottom < 0)
|
|
|
|
src_rect.bottom = 0;
|
|
|
|
|
2021-05-06 05:09:27 +02:00
|
|
|
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;
|
|
|
|
|
2020-10-20 15:00:12 +02:00
|
|
|
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 15:00:12 +02:00
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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 };
|
|
|
|
|
2022-10-15 05:04:19 +02:00
|
|
|
if (dst_rect.right < 0)
|
|
|
|
dst_rect.right = 0;
|
|
|
|
|
2021-05-06 05:09:27 +02:00
|
|
|
if (dst_rect.left < 0)
|
|
|
|
dst_rect.left = 0;
|
|
|
|
|
2022-10-15 05:04:19 +02:00
|
|
|
if (dst_rect.bottom < 0)
|
|
|
|
dst_rect.bottom = 0;
|
|
|
|
|
2021-05-06 05:09:27 +02:00
|
|
|
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;
|
|
|
|
|
2020-10-20 15:00:12 +02:00
|
|
|
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-20 15:00:12 +02:00
|
|
|
|
2021-05-06 05:09:27 +02:00
|
|
|
dst_x = dst_rect.left;
|
|
|
|
dst_y = dst_rect.top;
|
2022-09-28 02:25:50 +02:00
|
|
|
|
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);
|
|
|
|
|
2020-10-20 15:00:12 +02:00
|
|
|
if (src_surface && dst_w > 0 && dst_h > 0)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-12-23 04:55:15 +01:00
|
|
|
if (This->bpp != src_surface->bpp ||
|
|
|
|
This->bpp == 24 ||
|
|
|
|
src_surface->bpp == 24)
|
2021-06-06 05:25:33 +02:00
|
|
|
{
|
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);
|
|
|
|
|
2024-12-26 01:34:52 +01:00
|
|
|
if ((dwFlags & DDBLTFAST_SRCCOLORKEY) && (src_surface->flags & DDSD_CKSRCBLT))
|
2022-09-29 00:19:48 +02:00
|
|
|
{
|
|
|
|
UINT color = src_surface->color_key.dwColorSpaceLowValue;
|
|
|
|
|
2024-12-23 04:55:15 +01:00
|
|
|
if (src_surface->bpp == 32 || src_surface->bpp == 24)
|
2022-09-29 00:19:48 +02:00
|
|
|
{
|
|
|
|
color = color & 0xFFFFFF;
|
|
|
|
}
|
|
|
|
else if (src_surface->bpp == 16)
|
|
|
|
{
|
|
|
|
unsigned short c = (unsigned short)color;
|
|
|
|
|
|
|
|
BYTE r = ((c & 0xF800) >> 11) << 3;
|
|
|
|
BYTE g = ((c & 0x07E0) >> 5) << 2;
|
|
|
|
BYTE b = ((c & 0x001F)) << 3;
|
|
|
|
|
|
|
|
color = RGB(r, g, b);
|
|
|
|
}
|
|
|
|
else if (src_surface->bpp == 8)
|
|
|
|
{
|
|
|
|
RGBQUAD* quad =
|
|
|
|
src_surface->palette ? src_surface->palette->data_rgb :
|
2024-03-22 22:27:00 +01:00
|
|
|
g_ddraw.ref && g_ddraw.primary && g_ddraw.primary->palette ? g_ddraw.primary->palette->data_rgb :
|
2022-09-29 00:19:48 +02:00
|
|
|
NULL;
|
|
|
|
|
|
|
|
if (quad)
|
|
|
|
{
|
|
|
|
unsigned char i = (unsigned char)color;
|
|
|
|
|
|
|
|
color = RGB(quad[i].rgbRed, quad[i].rgbGreen, quad[i].rgbBlue);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
GdiTransparentBlt(dst_dc, dst_x, dst_y, dst_w, dst_h, src_dc, src_x, src_y, dst_w, dst_h, color);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2024-05-25 07:29:30 +02:00
|
|
|
real_BitBlt(dst_dc, dst_x, dst_y, dst_w, dst_h, src_dc, src_x, src_y, SRCCOPY);
|
2022-09-29 00:19:48 +02:00
|
|
|
}
|
|
|
|
|
2022-09-28 01:59:12 +02:00
|
|
|
/*
|
2024-05-25 07:29:30 +02:00
|
|
|
real_BitBlt(
|
2022-09-28 01:59:12 +02:00
|
|
|
dst_dc,
|
|
|
|
dwX,
|
|
|
|
dwY,
|
|
|
|
lpSrcRect->right - lpSrcRect->left,
|
|
|
|
lpSrcRect->bottom - lpSrcRect->top,
|
|
|
|
src_dc,
|
|
|
|
lpSrcRect->left,
|
|
|
|
lpSrcRect->top,
|
|
|
|
SRCCOPY);
|
|
|
|
*/
|
2021-06-06 05:25:33 +02:00
|
|
|
}
|
2024-12-26 01:34:52 +01:00
|
|
|
else if ((dwFlags & DDBLTFAST_SRCCOLORKEY) && (src_surface->flags & DDSD_CKSRCBLT))
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2022-09-08 02:19:15 +02:00
|
|
|
blt_colorkey(
|
|
|
|
dst_buf,
|
|
|
|
dst_x,
|
|
|
|
dst_y,
|
|
|
|
dst_w,
|
|
|
|
dst_h,
|
2022-10-19 03:20:31 +02:00
|
|
|
This->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
src_buf,
|
|
|
|
src_x,
|
|
|
|
src_y,
|
2022-10-19 03:20:31 +02:00
|
|
|
src_surface->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
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,
|
2022-10-19 03:20:31 +02:00
|
|
|
This->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
src_buf,
|
|
|
|
src_x,
|
|
|
|
src_y,
|
2022-10-19 03:20:31 +02:00
|
|
|
src_surface->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
This->bpp);
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-09-08 02:19:15 +02:00
|
|
|
blt_clean(
|
|
|
|
dst_buf,
|
|
|
|
dst_x,
|
|
|
|
dst_y,
|
|
|
|
dst_w,
|
|
|
|
dst_h,
|
2022-10-19 03:20:31 +02:00
|
|
|
This->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
src_buf,
|
|
|
|
src_x,
|
|
|
|
src_y,
|
2022-10-19 03:20:31 +02:00
|
|
|
src_surface->pitch,
|
2022-09-08 02:19:15 +02:00
|
|
|
This->bpp);
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-03-22 22:27:00 +01:00
|
|
|
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw.ref && g_ddraw.render.run)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-05-31 21:12:07 +02:00
|
|
|
InterlockedExchange(&g_ddraw.render.surface_updated, TRUE);
|
2024-12-22 02:21:23 +01:00
|
|
|
InterlockedExchange(&g_ddraw.render.screen_updated, TRUE);
|
2024-06-02 23:57:21 +02:00
|
|
|
|
|
|
|
DWORD time = timeGetTime();
|
2024-05-31 21:12:07 +02:00
|
|
|
|
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))
|
|
|
|
{
|
2024-06-02 23:57:21 +02:00
|
|
|
ReleaseSemaphore(g_ddraw.render.sem, 1, NULL);
|
|
|
|
|
2024-05-31 21:43:33 +02:00
|
|
|
if (g_config.limiter_type == LIMIT_BLTFAST && g_ddraw.ticks_limiter.tick_length > 0)
|
2022-10-31 02:54:40 +01:00
|
|
|
{
|
2024-05-31 21:43:33 +02:00
|
|
|
g_ddraw.ticks_limiter.dds_unlock_limiter_disabled = TRUE;
|
2022-10-31 02:54:40 +01:00
|
|
|
util_limit_game_ticks();
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
{
|
2021-05-06 01:24:07 +02:00
|
|
|
if (lpDDSurface)
|
|
|
|
{
|
|
|
|
IDirectDrawSurface_Release(lpDDSurface);
|
2021-06-11 20:30:43 +02:00
|
|
|
|
|
|
|
if (lpDDSurface == This->backbuffer)
|
|
|
|
This->backbuffer = NULL;
|
2021-05-06 01:24:07 +02:00
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-06-14 09:57:26 +02:00
|
|
|
HRESULT dds_GetSurfaceDesc(IDirectDrawSurfaceImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2020-10-14 09:58:59 +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);
|
2020-10-14 09:58:59 +02:00
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
memset(lpDDSurfaceDesc, 0, size);
|
|
|
|
|
|
|
|
lpDDSurfaceDesc->dwSize = size;
|
2023-07-29 03:42:08 +02:00
|
|
|
lpDDSurfaceDesc->dwFlags =
|
|
|
|
DDSD_CAPS |
|
|
|
|
DDSD_WIDTH |
|
|
|
|
DDSD_HEIGHT |
|
|
|
|
DDSD_PITCH |
|
2024-12-27 02:15:01 +01:00
|
|
|
DDSD_PIXELFORMAT;
|
2023-07-29 03:42:08 +02:00
|
|
|
|
2020-10-14 09:58:59 +02:00
|
|
|
lpDDSurfaceDesc->dwWidth = This->width;
|
|
|
|
lpDDSurfaceDesc->dwHeight = This->height;
|
2022-10-19 03:20:31 +02:00
|
|
|
lpDDSurfaceDesc->lPitch = This->pitch;
|
2021-05-04 22:49:22 +02:00
|
|
|
lpDDSurfaceDesc->lpSurface = dds_GetBuffer(This);
|
2020-10-14 09:58:59 +02:00
|
|
|
lpDDSurfaceDesc->ddpfPixelFormat.dwSize = sizeof(DDPIXELFORMAT);
|
|
|
|
lpDDSurfaceDesc->ddpfPixelFormat.dwFlags = DDPF_RGB;
|
|
|
|
lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount = This->bpp;
|
2021-05-05 16:58:40 +02:00
|
|
|
lpDDSurfaceDesc->ddsCaps.dwCaps = This->caps;
|
2023-09-10 02:31:28 +02:00
|
|
|
|
|
|
|
if (This->flags & DDSD_BACKBUFFERCOUNT)
|
|
|
|
{
|
|
|
|
lpDDSurfaceDesc->dwFlags |= DDSD_BACKBUFFERCOUNT;
|
2023-09-13 19:08:31 +02:00
|
|
|
lpDDSurfaceDesc->dwBackBufferCount = This->backbuffer_count;
|
2023-09-10 02:31:28 +02:00
|
|
|
}
|
2024-05-08 01:47:56 +02:00
|
|
|
|
|
|
|
if (This->flags & DDSD_CKSRCBLT)
|
|
|
|
{
|
|
|
|
lpDDSurfaceDesc->dwFlags |= DDSD_CKSRCBLT;
|
|
|
|
lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceHighValue = This->color_key.dwColorSpaceHighValue;
|
|
|
|
lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceLowValue = This->color_key.dwColorSpaceLowValue;
|
|
|
|
}
|
2021-05-05 16:58:40 +02:00
|
|
|
|
2020-10-14 09:58:59 +02:00
|
|
|
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;
|
|
|
|
}
|
2024-12-23 04:55:15 +01:00
|
|
|
else if (This->bpp == 32 || This->bpp == 24)
|
2021-06-02 01:52:45 +02:00
|
|
|
{
|
|
|
|
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(
|
2022-09-08 02:19:15 +02:00
|
|
|
IDirectDrawSurfaceImpl* This,
|
|
|
|
LPVOID lpContext,
|
2021-06-14 09:57:26 +02:00
|
|
|
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)
|
|
|
|
{
|
2024-07-03 05:47:30 +02:00
|
|
|
/* Hack for carmageddon 1 lowres mode */
|
2024-07-03 04:24:27 +02:00
|
|
|
if (g_config.carma95_hack && g_ddraw.height == 200)
|
|
|
|
{
|
|
|
|
dds_GetSurfaceDesc(This, (LPDDSURFACEDESC)&desc);
|
|
|
|
lpEnumSurfacesCallback((LPDIRECTDRAWSURFACE)This, (LPDDSURFACEDESC)&desc, lpContext);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dds_GetSurfaceDesc(This->backbuffer, (LPDDSURFACEDESC)&desc);
|
|
|
|
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
|
|
|
{
|
2022-09-30 14:16:30 +02:00
|
|
|
dbg_dump_dds_flip_flags(dwFlags);
|
|
|
|
|
2024-07-03 04:24:27 +02:00
|
|
|
if (This->backbuffer && !This->skip_flip && !(g_config.carma95_hack && g_ddraw.height == 200))
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-03-22 22:27:00 +01:00
|
|
|
EnterCriticalSection(&g_ddraw.cs);
|
2021-06-11 20:30:43 +02:00
|
|
|
IDirectDrawSurfaceImpl* backbuffer = lpDDSurfaceTargetOverride ? lpDDSurfaceTargetOverride : This->backbuffer;
|
2021-05-06 00:15:47 +02:00
|
|
|
|
2021-05-31 18:54:32 +02:00
|
|
|
void* buf = InterlockedExchangePointer(&This->surface, backbuffer->surface);
|
2023-10-22 11:46:13 +02:00
|
|
|
HBITMAP bitmap = (HBITMAP)InterlockedExchangePointer((void*)&This->bitmap, backbuffer->bitmap);
|
|
|
|
HDC dc = (HDC)InterlockedExchangePointer((void*)&This->hdc, backbuffer->hdc);
|
2022-10-19 03:20:31 +02:00
|
|
|
HANDLE map = (HANDLE)InterlockedExchangePointer(&This->mapping, backbuffer->mapping);
|
2021-05-31 18:54:32 +02:00
|
|
|
|
|
|
|
InterlockedExchangePointer(&backbuffer->surface, buf);
|
2023-10-22 11:46:13 +02:00
|
|
|
InterlockedExchangePointer((void*)&backbuffer->bitmap, bitmap);
|
|
|
|
InterlockedExchangePointer((void*)&backbuffer->hdc, dc);
|
2022-10-19 03:20:31 +02:00
|
|
|
InterlockedExchangePointer(&backbuffer->mapping, map);
|
2022-09-13 07:41:01 +02:00
|
|
|
|
2024-05-02 05:53:29 +02:00
|
|
|
if (g_config.flipclear && (This->caps & DDSCAPS_PRIMARYSURFACE))
|
2022-09-13 07:41:01 +02:00
|
|
|
{
|
2022-09-20 02:27:01 +02:00
|
|
|
blt_clear(buf, 0, backbuffer->size);
|
2022-09-13 07:41:01 +02:00
|
|
|
}
|
|
|
|
|
2024-03-22 22:27:00 +01: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-06 00:15:47 +02:00
|
|
|
}
|
2021-05-04 22:49:22 +02:00
|
|
|
|
2023-12-12 00:39:25 +01:00
|
|
|
This->skip_flip = FALSE;
|
|
|
|
|
2024-03-22 22:27:00 +01:00
|
|
|
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw.ref && g_ddraw.render.run)
|
2021-05-06 00:15:47 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
This->last_flip_tick = timeGetTime();
|
|
|
|
|
2024-03-22 22:27:00 +01:00
|
|
|
InterlockedExchange(&g_ddraw.render.surface_updated, TRUE);
|
2024-12-22 02:21:23 +01:00
|
|
|
InterlockedExchange(&g_ddraw.render.screen_updated, TRUE);
|
2024-03-22 22:27:00 +01:00
|
|
|
ReleaseSemaphore(g_ddraw.render.sem, 1, NULL);
|
2020-10-13 09:20:52 +02:00
|
|
|
SwitchToThread();
|
|
|
|
|
2023-09-22 00:38:42 +02:00
|
|
|
if ((g_config.maxgameticks == 0 && (dwFlags & DDFLIP_WAIT)) || g_config.maxgameticks == -2)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
|
|
|
dd_WaitForVerticalBlank(DDWAITVB_BLOCKEND, NULL);
|
|
|
|
}
|
|
|
|
|
2024-12-22 02:21:23 +01:00
|
|
|
if (g_ddraw.ticks_limiter.tick_length > 0 && g_config.limiter_type != LIMIT_PEEKMESSAGE)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-05-31 21:43:33 +02:00
|
|
|
g_ddraw.ticks_limiter.dds_unlock_limiter_disabled = TRUE;
|
2020-10-13 09:20:52 +02:00
|
|
|
util_limit_game_ticks();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-06-14 09:57:26 +02:00
|
|
|
HRESULT dds_GetAttachedSurface(IDirectDrawSurfaceImpl* This, LPDDSCAPS lpDdsCaps, IDirectDrawSurfaceImpl** lpDDsurface)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-05-24 04:55:55 +02:00
|
|
|
if (!lpDdsCaps || !lpDDsurface)
|
|
|
|
return DDERR_INVALIDPARAMS;
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2024-05-24 04:55:55 +02:00
|
|
|
if (This->backbuffer && (This->backbuffer->caps & lpDdsCaps->dwCaps) == lpDdsCaps->dwCaps)
|
2024-05-23 07:12:33 +02:00
|
|
|
{
|
2024-05-24 04:55:55 +02:00
|
|
|
IDirectDrawSurface_AddRef(This->backbuffer);
|
|
|
|
*lpDDsurface = This->backbuffer;
|
2024-05-23 07:12:33 +02:00
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2022-09-15 09:57:36 +02:00
|
|
|
return DDERR_NOTFOUND;
|
|
|
|
}
|
|
|
|
|
2021-06-14 09:57:26 +02:00
|
|
|
HRESULT dds_GetCaps(IDirectDrawSurfaceImpl* This, LPDDSCAPS lpDDSCaps)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2022-09-29 18:06:51 +02:00
|
|
|
if (!lpDDSCaps)
|
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
lpDDSCaps->dwCaps = This->caps;
|
2022-09-29 18:06:51 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
HRESULT dds_GetClipper(IDirectDrawSurfaceImpl* This, IDirectDrawClipperImpl** lpClipper)
|
2021-05-08 23:42:29 +02:00
|
|
|
{
|
2021-05-26 19:48:48 +02:00
|
|
|
if (!lpClipper)
|
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
*lpClipper = This->clipper;
|
2021-05-08 23:42:29 +02:00
|
|
|
|
2021-05-26 19:21:40 +02:00
|
|
|
if (This->clipper)
|
|
|
|
{
|
|
|
|
IDirectDrawClipper_AddRef(This->clipper);
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return DDERR_NOCLIPPERATTACHED;
|
|
|
|
}
|
2021-05-08 23:42:29 +02:00
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2025-01-16 04:47:38 +01:00
|
|
|
if (!(This->flags & DDSD_CKSRCBLT))
|
|
|
|
{
|
|
|
|
return DDERR_NOCOLORKEY;
|
|
|
|
}
|
|
|
|
|
2023-08-10 14:41:42 +02:00
|
|
|
if (dwFlags != DDCKEY_SRCBLT || !lpColorKey)
|
2022-09-29 18:06:51 +02:00
|
|
|
{
|
2023-08-10 14:41:42 +02:00
|
|
|
TRACE(" NOT_IMPLEMENTED dwFlags=%08X, lpColorKey=%p\n", dwFlags, lpColorKey);
|
2022-09-29 18:06:51 +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;
|
|
|
|
}
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
RGBQUAD* data =
|
2021-05-22 12:23:25 +02:00
|
|
|
This->palette ? This->palette->data_rgb :
|
2024-03-22 22:27:00 +01:00
|
|
|
g_ddraw.ref && g_ddraw.primary && g_ddraw.primary->palette ? g_ddraw.primary->palette->data_rgb :
|
2020-10-13 09:20:52 +02:00
|
|
|
NULL;
|
|
|
|
|
2021-05-22 12:23:25 +02:00
|
|
|
HDC dc = This->hdc;
|
|
|
|
|
2023-07-27 06:59:09 +02:00
|
|
|
if (This->backbuffer || (This->caps & DDSCAPS_FLIP))
|
2021-05-22 12:23:25 +02:00
|
|
|
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
|
|
|
|
2021-05-08 23:42:29 +02:00
|
|
|
if (lpHDC)
|
2021-05-22 12:23:25 +02:00
|
|
|
*lpHDC = dc;
|
2021-05-08 23:42:29 +02:00
|
|
|
|
2024-10-18 18:02:30 +02:00
|
|
|
if (!(This->caps & DDSCAPS_OWNDC))
|
|
|
|
InterlockedExchange((LONG*)&This->dc_state, SaveDC(dc));
|
2024-08-15 12:06:02 +02:00
|
|
|
|
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
|
|
|
{
|
2021-05-26 19:48:48 +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
|
|
|
{
|
2020-10-14 09:58:59 +02:00
|
|
|
if (ddpfPixelFormat)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
|
|
|
memset(ddpfPixelFormat, 0, sizeof(DDPIXELFORMAT));
|
|
|
|
|
2020-10-14 09:58:59 +02:00
|
|
|
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;
|
|
|
|
}
|
2024-12-23 04:55:15 +01:00
|
|
|
else if (This->bpp == 32 || This->bpp == 24)
|
2021-06-02 01:52:45 +02:00
|
|
|
{
|
|
|
|
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(
|
2022-09-08 02:19:15 +02:00
|
|
|
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
|
|
|
{
|
2023-09-22 00:38:42 +02:00
|
|
|
if (g_config.lock_surfaces)
|
2022-09-17 13:46:45 +02:00
|
|
|
EnterCriticalSection(&This->cs);
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
dbg_dump_dds_lock_flags(dwFlags);
|
|
|
|
|
2024-09-11 18:01:21 +02:00
|
|
|
util_pull_messages();
|
2021-08-18 16:25:29 +02:00
|
|
|
|
2021-04-24 08:14:48 +02:00
|
|
|
HRESULT ret = dds_GetSurfaceDesc(This, lpDDSurfaceDesc);
|
|
|
|
|
2021-05-05 03:02:32 +02:00
|
|
|
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 ||
|
2021-05-05 03:02:32 +02:00
|
|
|
lpDestRect->top > lpDestRect->bottom ||
|
|
|
|
lpDestRect->right > This->width ||
|
|
|
|
lpDestRect->bottom > This->height)
|
|
|
|
{
|
2023-11-19 02:25:16 +01:00
|
|
|
lpDDSurfaceDesc->lpSurface = NULL;
|
|
|
|
|
2021-05-05 03:02:32 +02:00
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
}
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
lpDDSurfaceDesc->lpSurface =
|
2022-10-19 03:20:31 +02:00
|
|
|
(char*)dds_GetBuffer(This) + (lpDestRect->left * This->bytes_pp) + (lpDestRect->top * This->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
|
|
|
{
|
2024-03-22 22:27:00 +01:00
|
|
|
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw.ref && g_ddraw.render.run)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-03-22 22:27:00 +01:00
|
|
|
InterlockedExchange(&g_ddraw.render.surface_updated, TRUE);
|
2024-12-22 02:21:23 +01:00
|
|
|
InterlockedExchange(&g_ddraw.render.screen_updated, TRUE);
|
2024-06-02 23:57:21 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
|
2024-10-18 18:02:30 +02:00
|
|
|
if (!(This->caps & DDSCAPS_OWNDC))
|
|
|
|
RestoreDC(hDC, InterlockedExchangeAdd((LONG*)&This->dc_state, 0));
|
2024-08-15 12:06:02 +02:00
|
|
|
|
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-08 23:42:29 +02:00
|
|
|
{
|
2021-05-09 00:51:02 +02:00
|
|
|
if (lpClipper)
|
2023-03-06 01:40:47 +01:00
|
|
|
{
|
2021-05-09 00:51:02 +02:00
|
|
|
IDirectDrawClipper_AddRef(lpClipper);
|
|
|
|
|
2023-03-06 01:40:47 +01:00
|
|
|
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && lpClipper->hwnd)
|
|
|
|
{
|
|
|
|
RECT rc = { 0, 0, This->width, This->height };
|
2024-05-28 00:33:05 +02:00
|
|
|
ddc_SetClipRect(lpClipper, &rc);
|
2023-03-06 01:40:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-09 00:51:02 +02:00
|
|
|
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
|
|
|
|
2021-05-08 23:42:29 +02:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
HRESULT dds_SetColorKey(IDirectDrawSurfaceImpl* This, DWORD dwFlags, LPDDCOLORKEY lpColorKey)
|
|
|
|
{
|
2022-09-29 18:06:51 +02:00
|
|
|
if (dwFlags != DDCKEY_SRCBLT || !lpColorKey)
|
2021-06-11 20:30:43 +02:00
|
|
|
{
|
2023-08-10 14:41:42 +02:00
|
|
|
TRACE(" NOT_IMPLEMENTED dwFlags=%08X, lpColorKey=%p\n", dwFlags, lpColorKey);
|
2022-09-29 18:06:51 +02:00
|
|
|
}
|
2021-06-11 20:30:43 +02:00
|
|
|
|
2022-09-29 18:06:51 +02:00
|
|
|
if (lpColorKey)
|
|
|
|
{
|
2024-05-08 03:30:18 +02:00
|
|
|
This->flags |= DDSD_CKSRCBLT;
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
This->color_key.dwColorSpaceLowValue = lpColorKey->dwColorSpaceLowValue;
|
2023-10-05 21:14:22 +02:00
|
|
|
|
|
|
|
if (dwFlags & DDCKEY_COLORSPACE)
|
|
|
|
{
|
|
|
|
This->color_key.dwColorSpaceHighValue = lpColorKey->dwColorSpaceHighValue;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
This->color_key.dwColorSpaceHighValue = lpColorKey->dwColorSpaceLowValue;
|
|
|
|
}
|
2021-06-11 20:30:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_SetPalette(IDirectDrawSurfaceImpl* This, IDirectDrawPaletteImpl* lpDDPalette)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-12-16 07:18:10 +01:00
|
|
|
if (This->bpp != 8)
|
|
|
|
return DDERR_INVALIDPIXELFORMAT;
|
|
|
|
|
2021-05-26 19:21:40 +02:00
|
|
|
if (lpDDPalette)
|
|
|
|
IDirectDrawPalette_AddRef(lpDDPalette);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2024-12-15 00:05:51 +01:00
|
|
|
IDirectDrawPaletteImpl* old_palette = This->palette;
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2024-03-22 22:27:00 +01:00
|
|
|
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw.ref)
|
2021-06-04 01:21:07 +02:00
|
|
|
{
|
2024-03-22 22:27:00 +01:00
|
|
|
EnterCriticalSection(&g_ddraw.cs);
|
2021-06-11 20:30:43 +02:00
|
|
|
This->palette = lpDDPalette;
|
2024-03-22 22:27:00 +01:00
|
|
|
LeaveCriticalSection(&g_ddraw.cs);
|
2021-06-04 01:21:07 +02:00
|
|
|
|
2024-03-22 22:27:00 +01:00
|
|
|
if (g_ddraw.render.run)
|
2021-06-04 01:21:07 +02:00
|
|
|
{
|
2024-03-22 22:27:00 +01:00
|
|
|
InterlockedExchange(&g_ddraw.render.palette_updated, TRUE);
|
|
|
|
ReleaseSemaphore(g_ddraw.render.sem, 1, NULL);
|
2021-06-04 01:21:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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
|
|
|
|
2024-12-15 00:05:51 +01:00
|
|
|
if (old_palette)
|
|
|
|
IDirectDrawPalette_Release(old_palette);
|
|
|
|
|
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 */
|
2024-03-22 22:27:00 +01:00
|
|
|
HWND hwnd = g_ddraw.ref && 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)
|
|
|
|
{
|
2024-05-31 21:43:33 +02:00
|
|
|
blt_clear(This->surface, 0xFE, This->size);
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
/* Hack for Star Trek Armada */
|
2024-03-22 22:27:00 +01:00
|
|
|
hwnd = g_ddraw.ref && g_config.armadahack ? FindWindowEx(HWND_DESKTOP, NULL, "#32770", NULL) : NULL;
|
2021-06-09 07:24:17 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2024-05-31 21:43:33 +02:00
|
|
|
blt_clear(This->surface, 0x00, This->size);
|
2021-06-09 07:24:17 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-03-22 22:27:00 +01:00
|
|
|
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw.ref && g_ddraw.render.run)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2024-05-31 21:12:07 +02:00
|
|
|
InterlockedExchange(&g_ddraw.render.surface_updated, TRUE);
|
2024-12-22 02:21:23 +01:00
|
|
|
InterlockedExchange(&g_ddraw.render.screen_updated, TRUE);
|
2024-06-02 23:57:21 +02:00
|
|
|
|
|
|
|
DWORD time = timeGetTime();
|
2024-05-31 21:12:07 +02:00
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (!(This->flags & DDSD_BACKBUFFERCOUNT) ||
|
|
|
|
(This->last_flip_tick + FLIP_REDRAW_TIMEOUT < time && This->last_blt_tick + FLIP_REDRAW_TIMEOUT < time))
|
|
|
|
{
|
2024-06-02 23:57:21 +02:00
|
|
|
ReleaseSemaphore(g_ddraw.render.sem, 1, NULL);
|
|
|
|
|
2024-07-28 10:37:14 +02:00
|
|
|
if (g_ddraw.ticks_limiter.tick_length > 0 &&
|
2024-12-22 02:21:23 +01:00
|
|
|
g_config.limiter_type != LIMIT_PEEKMESSAGE &&
|
2024-08-11 08:33:08 +02:00
|
|
|
(!g_ddraw.ticks_limiter.dds_unlock_limiter_disabled || g_config.limiter_type == LIMIT_UNLOCK))
|
2024-07-28 10:37:14 +02:00
|
|
|
{
|
2020-10-13 09:20:52 +02:00
|
|
|
util_limit_game_ticks();
|
2024-07-28 10:37:14 +02:00
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-22 00:38:42 +02:00
|
|
|
if (g_config.lock_surfaces)
|
2022-09-17 13:46:45 +02:00
|
|
|
LeaveCriticalSection(&This->cs);
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-09-21 16:37:13 +02:00
|
|
|
HRESULT dds_SetSurfaceDesc(IDirectDrawSurfaceImpl* This, LPDDSURFACEDESC2 lpDDSD, DWORD dwFlags)
|
2022-09-21 16:07:32 +02:00
|
|
|
{
|
|
|
|
dbg_dump_dds_flags(lpDDSD->dwFlags);
|
|
|
|
dbg_dump_dds_caps(lpDDSD->ddsCaps.dwCaps);
|
|
|
|
|
2024-05-13 05:45:50 +02:00
|
|
|
if ((lpDDSD->dwFlags & DDSD_LPSURFACE) == 0)
|
2022-09-21 16:07:32 +02:00
|
|
|
return DDERR_UNSUPPORTED;
|
|
|
|
|
|
|
|
|
|
|
|
if (This->bitmap)
|
|
|
|
{
|
|
|
|
DeleteObject(This->bitmap);
|
2023-07-31 09:17:57 +02:00
|
|
|
InterlockedDecrement(&g_dds_gdi_handles);
|
2022-09-21 16:07:32 +02:00
|
|
|
This->bitmap = NULL;
|
|
|
|
}
|
2022-10-19 03:20:31 +02:00
|
|
|
else if (This->surface && !This->custom_buf)
|
2022-09-21 16:07:32 +02:00
|
|
|
{
|
|
|
|
HeapFree(GetProcessHeap(), 0, This->surface);
|
|
|
|
This->surface = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (This->hdc)
|
|
|
|
{
|
|
|
|
DeleteDC(This->hdc);
|
2023-07-31 09:17:57 +02:00
|
|
|
InterlockedDecrement(&g_dds_gdi_handles);
|
2022-09-21 16:07:32 +02:00
|
|
|
This->hdc = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (This->bmi)
|
|
|
|
{
|
|
|
|
HeapFree(GetProcessHeap(), 0, This->bmi);
|
|
|
|
This->bmi = NULL;
|
|
|
|
}
|
|
|
|
|
2022-10-19 03:20:31 +02:00
|
|
|
if (This->mapping)
|
2022-09-21 16:07:32 +02:00
|
|
|
{
|
2022-10-19 03:20:31 +02:00
|
|
|
CloseHandle(This->mapping);
|
|
|
|
This->mapping = NULL;
|
2022-09-21 16:07:32 +02:00
|
|
|
}
|
|
|
|
|
2024-05-13 05:45:50 +02:00
|
|
|
if (lpDDSD->dwFlags & DDSD_PIXELFORMAT)
|
|
|
|
{
|
|
|
|
switch (lpDDSD->ddpfPixelFormat.dwRGBBitCount)
|
|
|
|
{
|
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
case 8:
|
|
|
|
This->bpp = 8;
|
|
|
|
break;
|
|
|
|
case 15:
|
|
|
|
TRACE(" NOT_IMPLEMENTED bpp=%u\n", lpDDSD->ddpfPixelFormat.dwRGBBitCount);
|
|
|
|
case 16:
|
|
|
|
This->bpp = 16;
|
|
|
|
break;
|
|
|
|
case 24:
|
2024-12-23 04:55:15 +01:00
|
|
|
This->bpp = 24;
|
|
|
|
break;
|
2024-05-13 05:45:50 +02:00
|
|
|
case 32:
|
|
|
|
This->bpp = 32;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
TRACE(" NOT_IMPLEMENTED bpp=%u\n", lpDDSD->ddpfPixelFormat.dwRGBBitCount);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lpDDSD->dwFlags & DDSD_WIDTH)
|
|
|
|
{
|
|
|
|
This->width = lpDDSD->dwWidth;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lpDDSD->dwFlags & DDSD_HEIGHT)
|
|
|
|
{
|
|
|
|
This->height = lpDDSD->dwHeight;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lpDDSD->dwFlags & DDSD_PITCH)
|
|
|
|
{
|
|
|
|
This->pitch = lpDDSD->lPitch;
|
|
|
|
}
|
2022-09-21 16:07:32 +02:00
|
|
|
|
2024-05-13 05:45:50 +02:00
|
|
|
if (lpDDSD->dwFlags & DDSD_LPSURFACE)
|
2022-09-21 16:07:32 +02:00
|
|
|
{
|
2024-05-13 05:45:50 +02:00
|
|
|
This->surface = lpDDSD->lpSurface;
|
2022-09-21 16:07:32 +02:00
|
|
|
}
|
|
|
|
|
2022-10-19 03:20:31 +02:00
|
|
|
This->bytes_pp = This->bpp / 8;
|
|
|
|
This->size = This->pitch * This->height;
|
|
|
|
This->custom_buf = TRUE;
|
2022-09-21 16:07:32 +02:00
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-05-04 22:49:22 +02:00
|
|
|
void* dds_GetBuffer(IDirectDrawSurfaceImpl* This)
|
|
|
|
{
|
|
|
|
if (!This)
|
|
|
|
return NULL;
|
|
|
|
|
2023-07-27 06:59:09 +02:00
|
|
|
if (This->backbuffer || (This->caps & DDSCAPS_FLIP))
|
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(
|
2022-09-08 02:19:15 +02:00
|
|
|
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);
|
2021-05-08 23:42:29 +02:00
|
|
|
dbg_dump_dds_caps(lpDDSurfaceDesc->ddsCaps.dwCaps);
|
|
|
|
|
2022-10-07 08:13:07 +02:00
|
|
|
if (lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_OVERLAY)
|
|
|
|
return DDERR_UNSUPPORTED;
|
|
|
|
|
2023-10-04 19:51:53 +02:00
|
|
|
if (!(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
|
2023-03-07 21:29:19 +01:00
|
|
|
(lpDDSurfaceDesc->dwWidth > 16384 || lpDDSurfaceDesc->dwHeight > 16384))
|
|
|
|
{
|
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
}
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
|
2024-03-22 22:27:00 +01:00
|
|
|
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-05-08 23:42:29 +02:00
|
|
|
{
|
2024-03-22 22:27:00 +01:00
|
|
|
g_ddraw.primary->skip_flip = TRUE;
|
2023-12-12 00:39:25 +01:00
|
|
|
|
2024-03-22 22:27:00 +01:00
|
|
|
*lpDDSurface = g_ddraw.primary;
|
|
|
|
IDirectDrawSurface_AddRef(g_ddraw.primary);
|
2021-05-08 23:42:29 +02:00
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2022-09-08 02:19:15 +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;
|
|
|
|
|
2022-09-17 13:46:45 +02:00
|
|
|
InitializeCriticalSection(&dst_surface->cs);
|
|
|
|
|
2024-03-22 22:27:00 +01:00
|
|
|
dst_surface->bpp = g_ddraw.bpp == 0 ? 16 : g_ddraw.bpp;
|
2020-10-13 09:20:52 +02:00
|
|
|
dst_surface->flags = lpDDSurfaceDesc->dwFlags;
|
2021-05-08 23:42:29 +02:00
|
|
|
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
|
|
|
|
2023-10-04 19:51:53 +02:00
|
|
|
if (dst_surface->flags & DDSD_CKSRCBLT)
|
|
|
|
{
|
|
|
|
dst_surface->color_key.dwColorSpaceHighValue = lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceHighValue;
|
|
|
|
dst_surface->color_key.dwColorSpaceLowValue = lpDDSurfaceDesc->ddckCKSrcBlt.dwColorSpaceLowValue;
|
|
|
|
}
|
|
|
|
|
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:
|
2024-12-23 04:55:15 +01:00
|
|
|
dst_surface->bpp = 24;
|
|
|
|
break;
|
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
|
|
|
{
|
2023-07-27 06:59:09 +02:00
|
|
|
if (dst_surface->caps & DDSCAPS_FLIP)
|
|
|
|
{
|
|
|
|
dst_surface->caps |= DDSCAPS_FRONTBUFFER;
|
|
|
|
}
|
|
|
|
|
2024-07-03 01:31:12 +02:00
|
|
|
if (!(dst_surface->caps & DDSCAPS_SYSTEMMEMORY))
|
|
|
|
{
|
|
|
|
dst_surface->caps |= DDSCAPS_VIDEOMEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
dst_surface->caps |= DDSCAPS_VISIBLE;
|
|
|
|
|
2024-08-15 14:20:13 +02:00
|
|
|
dst_surface->width = g_ddraw.width == 0 ? 1024 : g_ddraw.width;
|
|
|
|
dst_surface->height = g_ddraw.height == 0 ? 768 : g_ddraw.height;
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
2021-05-08 23:42:29 +02:00
|
|
|
else
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2023-09-22 00:38:42 +02:00
|
|
|
if (!(dst_surface->caps & DDSCAPS_SYSTEMMEMORY) || g_config.tshack)
|
2023-07-27 07:48:23 +02:00
|
|
|
{
|
|
|
|
dst_surface->caps |= DDSCAPS_VIDEOMEMORY;
|
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
dst_surface->width = lpDDSurfaceDesc->dwWidth;
|
|
|
|
dst_surface->height = lpDDSurfaceDesc->dwHeight;
|
|
|
|
}
|
|
|
|
|
2022-09-15 10:10:52 +02:00
|
|
|
if ((dst_surface->flags & DDSD_LPSURFACE) && (dst_surface->flags & DDSD_PITCH))
|
|
|
|
{
|
|
|
|
dst_surface->surface = lpDDSurfaceDesc->lpSurface;
|
2022-10-19 03:20:31 +02:00
|
|
|
dst_surface->pitch = lpDDSurfaceDesc->lPitch;
|
|
|
|
dst_surface->bytes_pp = dst_surface->bpp / 8;
|
|
|
|
dst_surface->size = dst_surface->pitch * dst_surface->height;
|
|
|
|
dst_surface->custom_buf = TRUE;
|
2022-09-15 10:10:52 +02:00
|
|
|
}
|
|
|
|
else if (dst_surface->width && dst_surface->height)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2022-10-19 03:20:31 +02:00
|
|
|
dst_surface->bytes_pp = dst_surface->bpp / 8;
|
2024-01-09 20:44:04 +01:00
|
|
|
dst_surface->pitch = ((dst_surface->width * dst_surface->bpp + 63) & ~63) >> 3;
|
2022-10-19 03:20:31 +02:00
|
|
|
dst_surface->size = dst_surface->pitch * dst_surface->height;
|
2021-05-23 06:16:58 +02:00
|
|
|
|
2022-10-19 03:20:31 +02:00
|
|
|
DWORD aligned_width = dst_surface->pitch / dst_surface->bytes_pp;
|
2021-06-11 20:30:43 +02:00
|
|
|
|
2023-09-22 00:38:42 +02:00
|
|
|
DWORD bmp_size = dst_surface->pitch * (dst_surface->height + g_config.guard_lines);
|
2021-05-23 06:16:58 +02:00
|
|
|
|
2024-12-20 08:45:51 +01:00
|
|
|
dst_surface->bmi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(DDBITMAPINFO));
|
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;
|
2023-09-22 00:38:42 +02:00
|
|
|
dst_surface->bmi->bmiHeader.biHeight = -((int)dst_surface->height + g_config.guard_lines);
|
2020-10-13 09:20:52 +02:00
|
|
|
dst_surface->bmi->bmiHeader.biPlanes = 1;
|
|
|
|
dst_surface->bmi->bmiHeader.biBitCount = dst_surface->bpp;
|
2024-12-23 04:55:15 +01:00
|
|
|
dst_surface->bmi->bmiHeader.biCompression = dst_surface->bpp == 16 ? BI_BITFIELDS : BI_RGB;
|
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
|
|
|
|
2024-12-23 04:55:15 +01:00
|
|
|
dst_surface->bmi->bmiHeader.biClrUsed =
|
|
|
|
dst_surface->bpp == 8 ? 256 :
|
|
|
|
dst_surface->bpp == 16 ? 3 :
|
|
|
|
dst_surface->bpp == 24 ? 0 :
|
|
|
|
dst_surface->bpp == 32 ? 0 :
|
|
|
|
0;
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2022-09-08 02:19:15 +02:00
|
|
|
dst_surface->bmi->bmiHeader.biSizeImage =
|
2024-01-09 20:44:04 +01:00
|
|
|
((aligned_width * clr_bits + 63) & ~63) / 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;
|
|
|
|
}
|
|
|
|
}
|
2023-09-22 00:38:42 +02:00
|
|
|
else if (dst_surface->bpp == 16 && g_config.rgb555)
|
2023-02-16 16:24:43 -08:00
|
|
|
{
|
|
|
|
((DWORD*)dst_surface->bmi->bmiColors)[0] = 0x7C00;
|
|
|
|
((DWORD*)dst_surface->bmi->bmiColors)[1] = 0x03E0;
|
|
|
|
((DWORD*)dst_surface->bmi->bmiColors)[2] = 0x001F;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
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;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2023-10-06 02:11:45 +02:00
|
|
|
/* Claw hack: 128x128 surfaces need a DC for custom levels to work properly */
|
2024-10-18 18:42:46 +02:00
|
|
|
if ((!g_config.limit_gdi_handles && InterlockedExchangeAdd(&g_dds_gdi_handles, 0) < 9000) ||
|
2024-03-22 22:27:00 +01:00
|
|
|
(dst_surface->width == g_ddraw.width && dst_surface->height == g_ddraw.height) ||
|
2023-10-06 02:11:45 +02:00
|
|
|
(dst_surface->width == 128 && dst_surface->height == 128))
|
2023-07-29 06:19:30 +02:00
|
|
|
{
|
2024-03-22 22:27:00 +01:00
|
|
|
dst_surface->hdc = CreateCompatibleDC(g_ddraw.render.hdc);
|
2022-09-16 11:22:05 +02:00
|
|
|
|
2023-07-31 09:17:57 +02:00
|
|
|
if (dst_surface->hdc)
|
|
|
|
InterlockedIncrement(&g_dds_gdi_handles);
|
|
|
|
|
2025-01-19 09:27:26 +01:00
|
|
|
// CreateDIBSection cannot handle values higher than a WORD - 0xFF00 (guard lines);
|
|
|
|
DWORD map_offset = min(65280, dst_surface->pitch * g_config.guard_lines);
|
2025-01-19 05:32:07 +01:00
|
|
|
|
2023-07-29 06:19:30 +02:00
|
|
|
dst_surface->mapping =
|
|
|
|
CreateFileMappingA(
|
|
|
|
INVALID_HANDLE_VALUE,
|
|
|
|
NULL,
|
|
|
|
PAGE_READWRITE | SEC_COMMIT,
|
|
|
|
0,
|
2025-01-19 05:32:07 +01:00
|
|
|
bmp_size + 256 + map_offset,
|
2023-07-29 06:19:30 +02:00
|
|
|
NULL);
|
2022-09-16 11:22:05 +02:00
|
|
|
|
2023-07-29 06:19:30 +02:00
|
|
|
if (dst_surface->mapping)
|
2022-09-16 11:22:05 +02:00
|
|
|
{
|
2023-07-29 06:19:30 +02:00
|
|
|
LPVOID data = MapViewOfFile(dst_surface->mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
|
|
|
|
if (data)
|
|
|
|
{
|
|
|
|
while (((DWORD)data + map_offset) % 128) map_offset++;
|
|
|
|
UnmapViewOfFile(data);
|
|
|
|
}
|
2022-09-16 11:22:05 +02:00
|
|
|
|
2023-07-29 06:19:30 +02:00
|
|
|
if (!data || (map_offset % sizeof(DWORD)))
|
|
|
|
{
|
|
|
|
map_offset = 0;
|
|
|
|
CloseHandle(dst_surface->mapping);
|
|
|
|
dst_surface->mapping = NULL;
|
|
|
|
}
|
|
|
|
}
|
2021-06-11 20:30:43 +02:00
|
|
|
|
2023-07-29 06:19:30 +02:00
|
|
|
dst_surface->bitmap =
|
|
|
|
CreateDIBSection(
|
|
|
|
dst_surface->hdc,
|
|
|
|
dst_surface->bmi,
|
|
|
|
DIB_RGB_COLORS,
|
|
|
|
(void**)&dst_surface->surface,
|
|
|
|
dst_surface->mapping,
|
|
|
|
map_offset);
|
2023-07-31 09:17:57 +02:00
|
|
|
|
|
|
|
if (dst_surface->bitmap)
|
|
|
|
InterlockedIncrement(&g_dds_gdi_handles);
|
2023-07-29 06:19:30 +02:00
|
|
|
}
|
2023-07-29 05:54:10 +02:00
|
|
|
|
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
|
|
|
{
|
2022-09-16 11:22:05 +02:00
|
|
|
dst_surface->surface = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bmp_size);
|
2020-10-13 21:58:04 +02:00
|
|
|
}
|
2023-07-29 06:19:30 +02:00
|
|
|
else
|
|
|
|
{
|
|
|
|
SelectObject(dst_surface->hdc, dst_surface->bitmap);
|
|
|
|
}
|
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
|
|
|
{
|
2024-03-22 22:27:00 +01:00
|
|
|
g_ddraw.primary = dst_surface;
|
2020-10-15 05:13:37 +02:00
|
|
|
FakePrimarySurface = dst_surface->surface;
|
2024-12-15 00:05:51 +01:00
|
|
|
|
|
|
|
if (dst_surface->bpp == 8)
|
|
|
|
{
|
|
|
|
IDirectDrawPaletteImpl* lpDDPalette;
|
2024-12-15 08:02:00 +01:00
|
|
|
dd_CreatePalette(DDPCAPS_ALLOW256, g_ddp_default_palette, &lpDDPalette, NULL);
|
2024-12-15 00:05:51 +01:00
|
|
|
dds_SetPalette(dst_surface, lpDDPalette);
|
|
|
|
|
|
|
|
// Make sure temp palette will be released once replaced
|
|
|
|
IDirectDrawPalette_Release(lpDDPalette);
|
|
|
|
}
|
2023-07-31 09:17:57 +02:00
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
|
2021-05-23 06:16:58 +02:00
|
|
|
if (dst_surface->flags & DDSD_BACKBUFFERCOUNT)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2022-09-15 10:21:33 +02:00
|
|
|
dst_surface->backbuffer_count = lpDDSurfaceDesc->dwBackBufferCount;
|
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
TRACE(" dwBackBufferCount=%d\n", lpDDSurfaceDesc->dwBackBufferCount);
|
2021-05-04 22:49:22 +02:00
|
|
|
|
2021-06-14 09:57:26 +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
|
|
|
|
2023-07-27 08:16:09 +02:00
|
|
|
desc.dwFlags |= DDSD_CAPS;
|
2023-07-27 07:25:26 +02:00
|
|
|
|
2021-06-11 20:30:43 +02:00
|
|
|
if (lpDDSurfaceDesc->dwBackBufferCount > 1)
|
|
|
|
{
|
|
|
|
desc.dwBackBufferCount = lpDDSurfaceDesc->dwBackBufferCount - 1;
|
2023-07-27 07:25:26 +02:00
|
|
|
desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
2021-06-11 20:30:43 +02:00
|
|
|
}
|
2021-05-31 18:54:32 +02:00
|
|
|
|
2023-07-27 06:59:09 +02:00
|
|
|
if (dst_surface->caps & DDSCAPS_FRONTBUFFER)
|
|
|
|
{
|
|
|
|
desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dst_surface->caps & DDSCAPS_FLIP)
|
|
|
|
{
|
|
|
|
desc.ddsCaps.dwCaps |= DDSCAPS_FLIP;
|
|
|
|
}
|
|
|
|
|
2024-07-03 01:31:12 +02:00
|
|
|
if (dst_surface->caps & DDSCAPS_COMPLEX)
|
|
|
|
{
|
|
|
|
desc.ddsCaps.dwCaps |= DDSCAPS_COMPLEX;
|
|
|
|
}
|
|
|
|
|
2023-07-27 06:59:09 +02:00
|
|
|
if (dst_surface->caps & DDSCAPS_VIDEOMEMORY)
|
|
|
|
{
|
|
|
|
desc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
|
|
|
|
}
|
2021-05-04 22:49:22 +02:00
|
|
|
|
2024-07-03 01:31:12 +02:00
|
|
|
if (dst_surface->caps & DDSCAPS_SYSTEMMEMORY)
|
|
|
|
{
|
|
|
|
desc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY;
|
|
|
|
}
|
|
|
|
|
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(
|
2023-07-29 05:54:10 +02:00
|
|
|
" surface = %p (%ux%u@%u), buf = %p\n",
|
2022-09-08 02:19:15 +02:00
|
|
|
dst_surface,
|
|
|
|
dst_surface->width,
|
|
|
|
dst_surface->height,
|
2023-07-29 05:54:10 +02:00
|
|
|
dst_surface->bpp,
|
|
|
|
dst_surface->surface);
|
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;
|
|
|
|
}
|