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 "scale_pattern.h"
|
|
|
|
#include "IDirectDrawSurface.h"
|
|
|
|
#include "winapi_hooks.h"
|
|
|
|
#include "debug.h"
|
|
|
|
#include "utils.h"
|
|
|
|
|
|
|
|
|
|
|
|
HRESULT dds_AddAttachedSurface(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWSURFACE lpDDSurface)
|
|
|
|
{
|
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);
|
|
|
|
|
|
|
|
if (g_ddraw->backbuffer && !This->backbuffer)
|
|
|
|
{
|
|
|
|
IDirectDrawSurfaceImpl* surface = (IDirectDrawSurfaceImpl*)lpDDSurface;
|
|
|
|
surface->caps |= DDSCAPS_BACKBUFFER;
|
2021-05-06 00:15:47 +02:00
|
|
|
|
2021-05-06 01:24:07 +02:00
|
|
|
This->backbuffer = surface;
|
|
|
|
}
|
2021-05-06 00:15:47 +02:00
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_Blt(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx)
|
|
|
|
{
|
|
|
|
IDirectDrawSurfaceImpl *src_surface = (IDirectDrawSurfaceImpl *)lpDDSrcSurface;
|
|
|
|
|
|
|
|
dbg_dump_dds_blt_flags(dwFlags);
|
|
|
|
|
2021-06-05 22:15:52 +02:00
|
|
|
if (g_ddraw->iskkndx &&
|
|
|
|
(dwFlags & DDBLT_COLORFILL) &&
|
|
|
|
lpDestRect &&
|
|
|
|
lpDestRect->right == 640 &&
|
|
|
|
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
|
|
|
|
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));
|
|
|
|
|
|
|
|
// stretch or clip?
|
|
|
|
BOOL is_stretch_blt =
|
|
|
|
((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;
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
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
|
|
|
|
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
|
|
|
|
2021-05-04 22:49:22 +02:00
|
|
|
if (dst_buf && (dwFlags & DDBLT_COLORFILL) && dst_w > 0 && dst_h > 0)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-05-04 22:49:22 +02:00
|
|
|
unsigned char *dst = (unsigned char *)dst_buf + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
|
2020-10-13 09:20:52 +02:00
|
|
|
unsigned char *first_row = dst;
|
|
|
|
unsigned int dst_pitch = dst_w * This->lx_pitch;
|
|
|
|
int x, i;
|
|
|
|
|
|
|
|
if (This->bpp == 8)
|
|
|
|
{
|
|
|
|
unsigned char color = (unsigned char)lpDDBltFx->dwFillColor;
|
|
|
|
|
|
|
|
for (i = 0; i < dst_h; i++)
|
|
|
|
{
|
|
|
|
memset(dst, color, dst_pitch);
|
|
|
|
dst += This->l_pitch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (This->bpp == 16)
|
|
|
|
{
|
|
|
|
unsigned short *row1 = (unsigned short *)dst;
|
|
|
|
unsigned short color = (unsigned short)lpDDBltFx->dwFillColor;
|
|
|
|
|
|
|
|
if ((color & 0xFF) == (color >> 8))
|
|
|
|
{
|
|
|
|
unsigned char c8 = (unsigned char)(color & 0xFF);
|
|
|
|
|
|
|
|
for (i = 0; i < dst_h; i++)
|
|
|
|
{
|
|
|
|
memset(dst, c8, dst_pitch);
|
|
|
|
dst += This->l_pitch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (x = 0; x < dst_w; x++)
|
|
|
|
row1[x] = color;
|
|
|
|
|
|
|
|
for (i = 1; i < dst_h; i++)
|
|
|
|
{
|
|
|
|
dst += This->l_pitch;
|
|
|
|
memcpy(dst, first_row, dst_pitch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-06-02 01:52:45 +02:00
|
|
|
else if (This->bpp == 32)
|
|
|
|
{
|
|
|
|
unsigned int* row1 = (unsigned int*)dst;
|
|
|
|
unsigned int color = lpDDBltFx->dwFillColor;
|
|
|
|
|
|
|
|
if ((color & 0xFF) == ((color >> 8) & 0xFF) &&
|
|
|
|
(color & 0xFF) == ((color >> 16) & 0xFF) &&
|
|
|
|
(color & 0xFF) == ((color >> 24) & 0xFF))
|
|
|
|
{
|
|
|
|
unsigned char c8 = (unsigned char)(color & 0xFF);
|
|
|
|
|
|
|
|
for (i = 0; i < dst_h; i++)
|
|
|
|
{
|
|
|
|
memset(dst, c8, dst_pitch);
|
|
|
|
dst += This->l_pitch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (x = 0; x < dst_w; x++)
|
|
|
|
row1[x] = color;
|
|
|
|
|
|
|
|
for (i = 1; i < dst_h; i++)
|
|
|
|
{
|
|
|
|
dst += This->l_pitch;
|
|
|
|
memcpy(dst, first_row, dst_pitch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
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
|
|
|
{
|
2021-06-06 05:25:33 +02:00
|
|
|
if (This->bpp != src_surface->bpp)
|
|
|
|
{
|
|
|
|
dprintfex(" NOT_IMPLEMENTED This->bpp=%u, src_surface->bpp=%u\n", This->bpp, src_surface->bpp);
|
|
|
|
|
|
|
|
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))
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
|
|
|
DDCOLORKEY color_key;
|
|
|
|
|
|
|
|
color_key.dwColorSpaceLowValue =
|
2021-05-06 16:10:09 +02:00
|
|
|
(dwFlags & DDBLT_KEYSRCOVERRIDE) ?
|
2020-10-13 09:20:52 +02:00
|
|
|
lpDDBltFx->ddckSrcColorkey.dwColorSpaceLowValue : src_surface->color_key.dwColorSpaceLowValue;
|
|
|
|
|
|
|
|
color_key.dwColorSpaceHighValue =
|
|
|
|
(dwFlags & DDBLT_KEYSRCOVERRIDE) ?
|
|
|
|
lpDDBltFx->ddckSrcColorkey.dwColorSpaceHighValue : src_surface->color_key.dwColorSpaceHighValue;
|
|
|
|
|
2021-05-10 23:40:42 +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-05-06 16:10:09 +02:00
|
|
|
float scale_w = (float)src_w / dst_w;
|
|
|
|
float scale_h = (float)src_h / dst_h;
|
|
|
|
|
|
|
|
if (This->bpp == 8)
|
|
|
|
{
|
2021-05-10 23:40:42 +02:00
|
|
|
for (int y = 0; y < dst_h; y++)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-05-10 23:40:42 +02:00
|
|
|
int scaled_y = (int)(y * scale_h);
|
|
|
|
|
|
|
|
if (mirror_up_down)
|
|
|
|
scaled_y = src_h - 1 - scaled_y;
|
|
|
|
|
2021-06-02 01:52:45 +02:00
|
|
|
int src_row = src_surface->width * (scaled_y + src_y);
|
|
|
|
int dst_row = This->width * (y + dst_y);
|
2021-05-06 16:10:09 +02:00
|
|
|
|
2021-05-10 23:40:42 +02:00
|
|
|
for (int x = 0; x < dst_w; x++)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-05-10 23:40:42 +02:00
|
|
|
int scaled_x = (int)(x * scale_w);
|
|
|
|
|
|
|
|
if (mirror_left_right)
|
|
|
|
scaled_x = src_w - 1 - scaled_x;
|
|
|
|
|
2021-06-02 01:52:45 +02:00
|
|
|
unsigned char c = ((unsigned char*)src_buf)[scaled_x + src_x + src_row];
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2021-05-06 16:10:09 +02:00
|
|
|
if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-06-02 01:52:45 +02:00
|
|
|
((unsigned char*)dst_buf)[x + dst_x + dst_row] = c;
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-05-06 16:10:09 +02:00
|
|
|
}
|
|
|
|
else if (This->bpp == 16)
|
|
|
|
{
|
2021-05-10 23:40:42 +02:00
|
|
|
for (int y = 0; y < dst_h; y++)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-05-10 23:40:42 +02:00
|
|
|
int scaled_y = (int)(y * scale_h);
|
2021-05-06 16:10:09 +02:00
|
|
|
|
2021-05-10 23:40:42 +02:00
|
|
|
if (mirror_up_down)
|
|
|
|
scaled_y = src_h - 1 - scaled_y;
|
|
|
|
|
2021-06-02 01:52:45 +02:00
|
|
|
int src_row = src_surface->width * (scaled_y + src_y);
|
|
|
|
int dst_row = This->width * (y + dst_y);
|
|
|
|
|
|
|
|
for (int x = 0; x < dst_w; x++)
|
|
|
|
{
|
|
|
|
int scaled_x = (int)(x * scale_w);
|
|
|
|
|
|
|
|
if (mirror_left_right)
|
|
|
|
scaled_x = src_w - 1 - scaled_x;
|
|
|
|
|
|
|
|
unsigned short c = ((unsigned short*)src_buf)[scaled_x + src_x + src_row];
|
|
|
|
|
|
|
|
if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue)
|
|
|
|
{
|
|
|
|
((unsigned short*)dst_buf)[x + dst_x + dst_row] = c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (This->bpp == 32)
|
|
|
|
{
|
|
|
|
for (int y = 0; y < dst_h; y++)
|
|
|
|
{
|
|
|
|
int scaled_y = (int)(y * scale_h);
|
|
|
|
|
|
|
|
if (mirror_up_down)
|
|
|
|
scaled_y = src_h - 1 - scaled_y;
|
|
|
|
|
|
|
|
int src_row = src_surface->width * (scaled_y + src_y);
|
|
|
|
int dst_row = This->width * (y + dst_y);
|
2021-05-10 23:40:42 +02:00
|
|
|
|
|
|
|
for (int x = 0; x < dst_w; x++)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-05-10 23:40:42 +02:00
|
|
|
int scaled_x = (int)(x * scale_w);
|
|
|
|
|
|
|
|
if (mirror_left_right)
|
|
|
|
scaled_x = src_w - 1 - scaled_x;
|
|
|
|
|
2021-06-02 01:52:45 +02:00
|
|
|
unsigned int c = ((unsigned int*)src_buf)[scaled_x + src_x + src_row];
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2021-05-06 16:10:09 +02:00
|
|
|
if (c < color_key.dwColorSpaceLowValue || c > color_key.dwColorSpaceHighValue)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-06-02 01:52:45 +02:00
|
|
|
((unsigned int*)dst_buf)[x + dst_x + dst_row] = c;
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!is_stretch_blt)
|
|
|
|
{
|
|
|
|
int width = dst_w > src_w ? src_w : dst_w;
|
|
|
|
int height = dst_h > src_h ? src_h : dst_h;
|
|
|
|
|
|
|
|
unsigned char *src =
|
2021-05-04 22:49:22 +02:00
|
|
|
(unsigned char *)src_buf + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
unsigned char *dst =
|
2021-05-04 22:49:22 +02:00
|
|
|
(unsigned char *)dst_buf + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
unsigned int dst_pitch = width * This->lx_pitch;
|
|
|
|
|
2021-05-02 16:21:06 +02:00
|
|
|
if (This == src_surface)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-05-02 16:21:06 +02:00
|
|
|
if (dst_y > src_y)
|
|
|
|
{
|
|
|
|
src += src_surface->l_pitch * height;
|
|
|
|
dst += This->l_pitch * height;
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2021-05-02 16:21:06 +02:00
|
|
|
for (int i = height; i-- > 0;)
|
|
|
|
{
|
|
|
|
src -= src_surface->l_pitch;
|
|
|
|
dst -= This->l_pitch;
|
|
|
|
|
|
|
|
memmove(dst, src, dst_pitch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
memmove(dst, src, dst_pitch);
|
|
|
|
|
|
|
|
src += src_surface->l_pitch;
|
|
|
|
dst += This->l_pitch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int i = 0; i < height; i++)
|
|
|
|
{
|
|
|
|
memcpy(dst, src, dst_pitch);
|
|
|
|
|
|
|
|
src += src_surface->l_pitch;
|
|
|
|
dst += This->l_pitch;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Linear scaling using integer math
|
|
|
|
* Since the scaling pattern for x will aways be the same, the pattern itself gets pre-calculated
|
|
|
|
* and stored in an array.
|
|
|
|
* Y scaling pattern gets calculated during the blit loop
|
|
|
|
*/
|
|
|
|
unsigned int x_ratio = (unsigned int)((src_w << 16) / dst_w) + 1;
|
|
|
|
unsigned int y_ratio = (unsigned int)((src_h << 16) / dst_h) + 1;
|
|
|
|
|
|
|
|
unsigned int s_src_x, s_src_y;
|
|
|
|
unsigned int dest_base, source_base;
|
|
|
|
|
|
|
|
scale_pattern *pattern = malloc((dst_w + 1) * (sizeof(scale_pattern)));
|
|
|
|
int pattern_idx = 0;
|
|
|
|
unsigned int last_src_x = 0;
|
|
|
|
|
|
|
|
if (pattern != NULL)
|
|
|
|
{
|
|
|
|
pattern[pattern_idx] = (scale_pattern) { ONCE, 0, 0, 1 };
|
|
|
|
|
|
|
|
/* Build the pattern! */
|
|
|
|
int x;
|
|
|
|
for (x = 1; x < dst_w; x++) {
|
|
|
|
s_src_x = (x * x_ratio) >> 16;
|
|
|
|
if (s_src_x == last_src_x)
|
|
|
|
{
|
|
|
|
if (pattern[pattern_idx].type == REPEAT || pattern[pattern_idx].type == ONCE)
|
|
|
|
{
|
|
|
|
pattern[pattern_idx].type = REPEAT;
|
|
|
|
pattern[pattern_idx].count++;
|
|
|
|
}
|
|
|
|
else if (pattern[pattern_idx].type == SEQUENCE)
|
|
|
|
{
|
|
|
|
pattern_idx++;
|
|
|
|
pattern[pattern_idx] = (scale_pattern) { REPEAT, x, s_src_x, 1 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (s_src_x == last_src_x + 1)
|
|
|
|
{
|
|
|
|
if (pattern[pattern_idx].type == SEQUENCE || pattern[pattern_idx].type == ONCE)
|
|
|
|
{
|
|
|
|
pattern[pattern_idx].type = SEQUENCE;
|
|
|
|
pattern[pattern_idx].count++;
|
|
|
|
}
|
|
|
|
else if (pattern[pattern_idx].type == REPEAT)
|
|
|
|
{
|
|
|
|
pattern_idx++;
|
|
|
|
pattern[pattern_idx] = (scale_pattern) { ONCE, x, s_src_x, 1 };
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
pattern_idx++;
|
|
|
|
pattern[pattern_idx] = (scale_pattern) { ONCE, x, s_src_x, 1 };
|
|
|
|
}
|
|
|
|
last_src_x = s_src_x;
|
|
|
|
}
|
|
|
|
pattern[pattern_idx + 1] = (scale_pattern) { END, 0, 0, 0 };
|
|
|
|
|
|
|
|
|
|
|
|
/* Do the actual blitting */
|
|
|
|
int count = 0;
|
|
|
|
int y;
|
|
|
|
|
|
|
|
for (y = 0; y < dst_h; y++) {
|
|
|
|
|
|
|
|
dest_base = dst_x + This->width * (y + dst_y);
|
|
|
|
|
|
|
|
s_src_y = (y * y_ratio) >> 16;
|
|
|
|
|
|
|
|
source_base = src_x + src_surface->width * (s_src_y + src_y);
|
|
|
|
|
|
|
|
pattern_idx = 0;
|
|
|
|
scale_pattern *current = &pattern[pattern_idx];
|
|
|
|
|
|
|
|
if (This->bpp == 8)
|
|
|
|
{
|
|
|
|
unsigned char *d, *s, v;
|
2021-05-04 22:49:22 +02:00
|
|
|
unsigned char *src = (unsigned char *)src_buf;
|
|
|
|
unsigned char *dst = (unsigned char *)dst_buf;
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
do {
|
|
|
|
switch (current->type)
|
|
|
|
{
|
|
|
|
case ONCE:
|
|
|
|
dst[dest_base + current->dst_index] =
|
|
|
|
src[source_base + current->src_index];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REPEAT:
|
|
|
|
d = (dst + dest_base + current->dst_index);
|
|
|
|
v = src[source_base + current->src_index];
|
|
|
|
|
|
|
|
count = current->count;
|
|
|
|
while (count-- > 0)
|
|
|
|
*d++ = v;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SEQUENCE:
|
|
|
|
d = dst + dest_base + current->dst_index;
|
|
|
|
s = src + source_base + current->src_index;
|
|
|
|
|
|
|
|
memcpy((void *)d, (void *)s, current->count * This->lx_pitch);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case END:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
current = &pattern[++pattern_idx];
|
|
|
|
} while (current->type != END);
|
|
|
|
}
|
|
|
|
else if (This->bpp == 16)
|
|
|
|
{
|
|
|
|
unsigned short *d, *s, v;
|
2021-05-04 22:49:22 +02:00
|
|
|
unsigned short *src = (unsigned short *)src_buf;
|
|
|
|
unsigned short *dst = (unsigned short *)dst_buf;
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
do {
|
|
|
|
switch (current->type)
|
|
|
|
{
|
|
|
|
case ONCE:
|
|
|
|
dst[dest_base + current->dst_index] =
|
|
|
|
src[source_base + current->src_index];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REPEAT:
|
|
|
|
d = (dst + dest_base + current->dst_index);
|
|
|
|
v = src[source_base + current->src_index];
|
|
|
|
|
|
|
|
count = current->count;
|
|
|
|
while (count-- > 0)
|
|
|
|
*d++ = v;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SEQUENCE:
|
|
|
|
d = dst + dest_base + current->dst_index;
|
|
|
|
s = src + source_base + current->src_index;
|
|
|
|
|
|
|
|
memcpy((void *)d, (void *)s, current->count * This->lx_pitch);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case END:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-06-02 01:52:45 +02:00
|
|
|
current = &pattern[++pattern_idx];
|
|
|
|
} while (current->type != END);
|
|
|
|
}
|
|
|
|
else if (This->bpp == 32)
|
|
|
|
{
|
|
|
|
unsigned int* d, * s, v;
|
|
|
|
unsigned int* src = (unsigned int*)src_buf;
|
|
|
|
unsigned int* dst = (unsigned int*)dst_buf;
|
|
|
|
|
|
|
|
do {
|
|
|
|
switch (current->type)
|
|
|
|
{
|
|
|
|
case ONCE:
|
|
|
|
dst[dest_base + current->dst_index] =
|
|
|
|
src[source_base + current->src_index];
|
|
|
|
break;
|
|
|
|
|
|
|
|
case REPEAT:
|
|
|
|
d = (dst + dest_base + current->dst_index);
|
|
|
|
v = src[source_base + current->src_index];
|
|
|
|
|
|
|
|
count = current->count;
|
|
|
|
while (count-- > 0)
|
|
|
|
*d++ = v;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SEQUENCE:
|
|
|
|
d = dst + dest_base + current->dst_index;
|
|
|
|
s = src + source_base + current->src_index;
|
|
|
|
|
|
|
|
memcpy((void*)d, (void*)s, current->count * This->lx_pitch);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case END:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
current = &pattern[++pattern_idx];
|
|
|
|
} while (current->type != END);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
free(pattern);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if((This->caps & DDSCAPS_PRIMARYSURFACE) && g_ddraw->render.run)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_BltFast(IDirectDrawSurfaceImpl *This, DWORD dst_x, DWORD dst_y, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD flags)
|
|
|
|
{
|
|
|
|
IDirectDrawSurfaceImpl *src_surface = (IDirectDrawSurfaceImpl *)lpDDSrcSurface;
|
|
|
|
|
|
|
|
dbg_dump_dds_blt_fast_flags(flags);
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
|
|
|
int src_x = src_rect.left;
|
|
|
|
int src_y = src_rect.top;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
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;
|
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
|
|
|
{
|
2021-06-06 05:25:33 +02:00
|
|
|
if (This->bpp != src_surface->bpp)
|
|
|
|
{
|
|
|
|
dprintfex(" NOT_IMPLEMENTED This->bpp=%u, src_surface->bpp=%u\n", This->bpp, src_surface->bpp);
|
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
else if (flags & DDBLTFAST_SRCCOLORKEY)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
|
|
|
if (This->bpp == 8)
|
|
|
|
{
|
2021-05-10 23:40:42 +02:00
|
|
|
for (int y = 0; y < dst_h; y++)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-06-02 01:52:45 +02:00
|
|
|
int dst_row = This->width * (y + dst_y);
|
|
|
|
int src_row = src_surface->width * (y + src_y);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2021-05-10 23:40:42 +02:00
|
|
|
for (int x = 0; x < dst_w; x++)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-06-02 01:52:45 +02:00
|
|
|
unsigned char c = ((unsigned char *)src_buf)[x + src_x + src_row];
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue)
|
|
|
|
{
|
2021-06-02 01:52:45 +02:00
|
|
|
((unsigned char *)dst_buf)[x + dst_x + dst_row] = c;
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (This->bpp == 16)
|
|
|
|
{
|
2021-05-10 23:40:42 +02:00
|
|
|
for (int y = 0; y < dst_h; y++)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-06-02 01:52:45 +02:00
|
|
|
int dst_row = This->width * (y + dst_y);
|
|
|
|
int src_row = src_surface->width * (y + src_y);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2021-05-10 23:40:42 +02:00
|
|
|
for (int x = 0; x < dst_w; x++)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-06-02 01:52:45 +02:00
|
|
|
unsigned short c = ((unsigned short *)src_buf)[x + src_x + src_row];
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue)
|
|
|
|
{
|
2021-06-02 01:52:45 +02:00
|
|
|
((unsigned short *)dst_buf)[x + dst_x + dst_row] = c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (This->bpp == 32)
|
|
|
|
{
|
|
|
|
for (int y = 0; y < dst_h; y++)
|
|
|
|
{
|
|
|
|
int dst_row = This->width * (y + dst_y);
|
|
|
|
int src_row = src_surface->width * (y + src_y);
|
|
|
|
|
|
|
|
for (int x = 0; x < dst_w; x++)
|
|
|
|
{
|
|
|
|
unsigned int c = ((unsigned int*)src_buf)[x + src_x + src_row];
|
|
|
|
|
|
|
|
if (c < src_surface->color_key.dwColorSpaceLowValue || c > src_surface->color_key.dwColorSpaceHighValue)
|
|
|
|
{
|
|
|
|
((unsigned int*)dst_buf)[x + dst_x + dst_row] = c;
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
unsigned char *src =
|
2021-05-04 22:49:22 +02:00
|
|
|
(unsigned char *)src_buf + (src_x * src_surface->lx_pitch) + (src_surface->l_pitch * src_y);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
unsigned char *dst =
|
2021-05-04 22:49:22 +02:00
|
|
|
(unsigned char *)dst_buf + (dst_x * This->lx_pitch) + (This->l_pitch * dst_y);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
unsigned int dst_pitch = dst_w * This->lx_pitch;
|
|
|
|
|
2021-05-02 16:21:06 +02:00
|
|
|
if (This == src_surface)
|
|
|
|
{
|
|
|
|
if (dst_y > src_y)
|
|
|
|
{
|
|
|
|
src += src_surface->l_pitch * dst_h;
|
|
|
|
dst += This->l_pitch * dst_h;
|
|
|
|
|
|
|
|
for (int i = dst_h; i-- > 0;)
|
|
|
|
{
|
|
|
|
src -= src_surface->l_pitch;
|
|
|
|
dst -= This->l_pitch;
|
|
|
|
|
|
|
|
memmove(dst, src, dst_pitch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (int i = 0; i < dst_h; i++)
|
|
|
|
{
|
|
|
|
memmove(dst, src, dst_pitch);
|
|
|
|
|
|
|
|
src += src_surface->l_pitch;
|
|
|
|
dst += This->l_pitch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-05-02 16:21:06 +02:00
|
|
|
for (int i = 0; i < dst_h; i++)
|
|
|
|
{
|
|
|
|
memcpy(dst, src, dst_pitch);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2021-05-02 16:21:06 +02:00
|
|
|
src += src_surface->l_pitch;
|
|
|
|
dst += This->l_pitch;
|
|
|
|
}
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_DeleteAttachedSurface(IDirectDrawSurfaceImpl *This, DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSurface)
|
|
|
|
{
|
2021-05-06 01:24:07 +02:00
|
|
|
if (lpDDSurface)
|
|
|
|
{
|
|
|
|
IDirectDrawSurface_Release(lpDDSurface);
|
|
|
|
This->backbuffer = NULL;
|
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_GetSurfaceDesc(IDirectDrawSurfaceImpl *This, LPDDSURFACEDESC lpDDSurfaceDesc)
|
|
|
|
{
|
2020-10-14 09:58:59 +02:00
|
|
|
if (lpDDSurfaceDesc)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2020-10-14 09:58:59 +02:00
|
|
|
memset(lpDDSurfaceDesc, 0, sizeof(DDSURFACEDESC));
|
|
|
|
|
|
|
|
lpDDSurfaceDesc->dwSize = sizeof(DDSURFACEDESC);
|
|
|
|
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);
|
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;
|
|
|
|
|
|
|
|
if ((This->caps & DDSCAPS_PRIMARYSURFACE) || (This->caps & DDSCAPS_BACKBUFFER))
|
|
|
|
{
|
|
|
|
lpDDSurfaceDesc->ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
|
|
|
|
}
|
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;
|
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_EnumAttachedSurfaces(IDirectDrawSurfaceImpl *This, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback)
|
|
|
|
{
|
|
|
|
static DDSURFACEDESC dd_surface_desc;
|
|
|
|
memset(&dd_surface_desc, 0, sizeof(DDSURFACEDESC));
|
|
|
|
|
2021-05-04 23:52:52 +02:00
|
|
|
if (This->backbuffer)
|
|
|
|
{
|
|
|
|
dds_GetSurfaceDesc(This->backbuffer, &dd_surface_desc);
|
|
|
|
IDirectDrawSurface_AddRef(This->backbuffer);
|
|
|
|
lpEnumSurfacesCallback((LPDIRECTDRAWSURFACE)This->backbuffer, &dd_surface_desc, lpContext);
|
|
|
|
}
|
|
|
|
else if (!g_ddraw->backbuffer)
|
|
|
|
{
|
|
|
|
dds_GetSurfaceDesc(This, &dd_surface_desc);
|
|
|
|
This->caps |= DDSCAPS_BACKBUFFER; // Nox hack
|
|
|
|
lpEnumSurfacesCallback((LPDIRECTDRAWSURFACE)This, &dd_surface_desc, lpContext);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2021-05-04 23:52:52 +02:00
|
|
|
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && (This->caps & DDSCAPS_FLIP) && !(This->caps & DDSCAPS_BACKBUFFER))
|
|
|
|
IDirectDrawSurface_AddRef(This);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
2021-05-04 23:52:52 +02:00
|
|
|
This->caps &= ~DDSCAPS_BACKBUFFER;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_Flip(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWSURFACE surface, DWORD flags)
|
|
|
|
{
|
2021-05-06 00:15:47 +02:00
|
|
|
if (This->backbuffer)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-05-06 00:15:47 +02:00
|
|
|
EnterCriticalSection(&g_ddraw->cs);
|
2021-05-31 18:54:32 +02:00
|
|
|
IDirectDrawSurfaceImpl* backbuffer = surface ? (IDirectDrawSurfaceImpl*)surface : 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);
|
|
|
|
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);
|
2021-05-06 00:15:47 +02:00
|
|
|
LeaveCriticalSection(&g_ddraw->cs);
|
2021-06-04 02:44:04 +02:00
|
|
|
|
|
|
|
if (!surface && This->backbuffer->backbuffer)
|
|
|
|
{
|
|
|
|
dds_Flip(This->backbuffer, NULL, 0);
|
|
|
|
}
|
2021-05-06 00:15:47 +02:00
|
|
|
}
|
2021-05-04 22:49:22 +02:00
|
|
|
|
2021-05-06 00:15:47 +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-05-09 00:37:53 +02:00
|
|
|
if ((flags & 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, LPDIRECTDRAWSURFACE FAR *surface)
|
|
|
|
{
|
|
|
|
if ((This->caps & DDSCAPS_PRIMARYSURFACE) && (This->caps & DDSCAPS_FLIP) && (lpDdsCaps->dwCaps & DDSCAPS_BACKBUFFER))
|
|
|
|
{
|
2021-05-04 22:49:22 +02:00
|
|
|
if (This->backbuffer)
|
|
|
|
{
|
|
|
|
IDirectDrawSurface_AddRef(This->backbuffer);
|
|
|
|
*surface = (LPDIRECTDRAWSURFACE)This->backbuffer;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
IDirectDrawSurface_AddRef(This);
|
|
|
|
*surface = (LPDIRECTDRAWSURFACE)This;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_GetCaps(IDirectDrawSurfaceImpl *This, LPDDSCAPS lpDDSCaps)
|
|
|
|
{
|
|
|
|
lpDDSCaps->dwCaps = This->caps;
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-05-10 01:00:55 +02:00
|
|
|
HRESULT dds_GetClipper(IDirectDrawSurfaceImpl* This, LPDIRECTDRAWCLIPPER FAR* lpClipper)
|
2021-05-08 23:42:29 +02:00
|
|
|
{
|
2021-05-26 19:48:48 +02:00
|
|
|
if (!lpClipper)
|
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
|
|
|
|
*lpClipper = (LPDIRECTDRAWCLIPPER)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
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
HRESULT dds_GetColorKey(IDirectDrawSurfaceImpl *This, DWORD flags, LPDDCOLORKEY colorKey)
|
|
|
|
{
|
|
|
|
if (colorKey)
|
|
|
|
{
|
|
|
|
colorKey->dwColorSpaceHighValue = This->color_key.dwColorSpaceHighValue;
|
|
|
|
colorKey->dwColorSpaceLowValue = This->color_key.dwColorSpaceLowValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-05-08 23:42:29 +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
|
|
|
{
|
2020-10-22 22:37:57 +02:00
|
|
|
dprintf("NOT_IMPLEMENTED GetDC: width=%d height=%d\n", This->width, This->height);
|
2020-10-13 09:20:52 +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);
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
if (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
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-05-30 20:43:27 +02:00
|
|
|
HRESULT dds_ReleaseDC(IDirectDrawSurfaceImpl* This, HDC hDC)
|
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2021-06-02 22:28:00 +02:00
|
|
|
|
|
|
|
return DD_OK;
|
2021-05-30 20:43:27 +02:00
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
HRESULT dds_GetPalette(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWPALETTE FAR *lplpDDPalette)
|
|
|
|
{
|
2021-05-26 19:48:48 +02:00
|
|
|
if (!lplpDDPalette)
|
|
|
|
return DDERR_INVALIDPARAMS;
|
|
|
|
|
|
|
|
*lplpDDPalette = (LPDIRECTDRAWPALETTE)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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_GetPixelFormat(IDirectDrawSurfaceImpl *This, LPDDPIXELFORMAT ddpfPixelFormat)
|
|
|
|
{
|
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;
|
|
|
|
}
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_Lock(IDirectDrawSurfaceImpl *This, LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
|
|
|
|
{
|
|
|
|
dbg_dump_dds_lock_flags(dwFlags);
|
|
|
|
|
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-05-05 03:02:32 +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-04-24 08:14:48 +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
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_SetColorKey(IDirectDrawSurfaceImpl *This, DWORD flags, LPDDCOLORKEY colorKey)
|
|
|
|
{
|
|
|
|
if (colorKey)
|
|
|
|
{
|
|
|
|
dprintfex(" dwColorSpaceHighValue=%d\n", colorKey->dwColorSpaceHighValue);
|
|
|
|
dprintfex(" dwColorSpaceLowValue=%d\n", colorKey->dwColorSpaceLowValue);
|
|
|
|
|
|
|
|
This->color_key.dwColorSpaceHighValue = colorKey->dwColorSpaceHighValue;
|
|
|
|
This->color_key.dwColorSpaceLowValue = colorKey->dwColorSpaceLowValue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2021-05-08 23:42:29 +02:00
|
|
|
HRESULT dds_SetClipper(IDirectDrawSurfaceImpl* This, LPDIRECTDRAWCLIPPER lpClipper)
|
|
|
|
{
|
2021-05-09 00:51:02 +02:00
|
|
|
if (lpClipper)
|
|
|
|
IDirectDrawClipper_AddRef(lpClipper);
|
|
|
|
|
|
|
|
if (This->clipper)
|
|
|
|
IDirectDrawClipper_Release(This->clipper);
|
|
|
|
|
2021-05-08 23:42:29 +02:00
|
|
|
This->clipper = (IDirectDrawClipperImpl*)lpClipper;
|
2021-05-09 00:51:02 +02:00
|
|
|
|
2021-05-08 23:42:29 +02:00
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
HRESULT dds_SetPalette(IDirectDrawSurfaceImpl *This, LPDIRECTDRAWPALETTE lpDDPalette)
|
|
|
|
{
|
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);
|
|
|
|
This->palette = (IDirectDrawPaletteImpl*)lpDDPalette;
|
|
|
|
LeaveCriticalSection(&g_ddraw->cs);
|
|
|
|
|
|
|
|
if (g_ddraw->render.run)
|
|
|
|
{
|
|
|
|
InterlockedExchange(&g_ddraw->render.palette_updated, TRUE);
|
|
|
|
ReleaseSemaphore(g_ddraw->render.sem, 1, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
This->palette = (IDirectDrawPaletteImpl*)lpDDPalette;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
HRESULT dds_Unlock(IDirectDrawSurfaceImpl *This, LPVOID lpRect)
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
dds_GetDC(g_ddraw->primary, &primary_dc);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
//GdiTransparentBlt idea taken from Aqrit's war2 ddraw
|
|
|
|
|
|
|
|
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-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;
|
|
|
|
dds_GetDC(g_ddraw->primary, &primary_dc);
|
|
|
|
|
|
|
|
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-05-29 20:51:19 +02:00
|
|
|
HRESULT dd_CreateSurface(IDirectDrawImpl* This, LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE FAR *lpDDSurface, 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);
|
|
|
|
|
2021-06-05 22:16:20 +02:00
|
|
|
if ((lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) &&
|
|
|
|
!g_ddraw->passthrough &&
|
2021-05-08 23:42:29 +02: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)
|
|
|
|
{
|
|
|
|
*lpDDSurface = (LPDIRECTDRAWSURFACE)g_ddraw->primary;
|
|
|
|
IDirectDrawSurface_AddRef(g_ddraw->primary);
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
IDirectDrawSurfaceImpl *dst_surface = (IDirectDrawSurfaceImpl *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectDrawSurfaceImpl));
|
|
|
|
|
|
|
|
dst_surface->lpVtbl = &g_dds_vtbl;
|
|
|
|
|
|
|
|
lpDDSurfaceDesc->dwFlags |= DDSD_CAPS;
|
|
|
|
|
2021-05-08 23:42:29 +02: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
|
|
|
|
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:
|
|
|
|
dprintf(" NOT_IMPLEMENTED bpp=%u\n", lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount);
|
|
|
|
case 16:
|
|
|
|
dst_surface->bpp = 16;
|
|
|
|
break;
|
|
|
|
case 24:
|
|
|
|
dprintf(" NOT_IMPLEMENTED bpp=%u\n", lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount);
|
|
|
|
case 32:
|
|
|
|
dst_surface->bpp = 32;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
dprintf(" NOT_IMPLEMENTED bpp=%u\n", lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-23 06:16:58 +02:00
|
|
|
if (dst_surface->caps & DDSCAPS_PRIMARYSURFACE)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
2021-05-08 23:42:29 +02:00
|
|
|
dst_surface->width = g_ddraw->width;
|
|
|
|
dst_surface->height = 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
|
|
|
{
|
|
|
|
dst_surface->width = lpDDSurfaceDesc->dwWidth;
|
|
|
|
dst_surface->height = lpDDSurfaceDesc->dwHeight;
|
|
|
|
}
|
|
|
|
|
2021-05-08 23:42:29 +02:00
|
|
|
if (dst_surface->width && dst_surface->height)
|
2020-10-13 09:20:52 +02:00
|
|
|
{
|
|
|
|
if (dst_surface->width == 71 && dst_surface->height == 24) dst_surface->width = 72; //Commandos
|
|
|
|
|
2021-05-23 06:16:58 +02:00
|
|
|
dst_surface->lx_pitch = dst_surface->bpp / 8;
|
|
|
|
dst_surface->l_pitch = dst_surface->width * dst_surface->lx_pitch;
|
|
|
|
|
|
|
|
if (g_ddraw->fixpitch && !(dst_surface->caps & (DDSCAPS_PRIMARYSURFACE | DDSCAPS_BACKBUFFER)))
|
|
|
|
{
|
|
|
|
while (dst_surface->l_pitch % 4)
|
|
|
|
{
|
|
|
|
dst_surface->l_pitch = ++dst_surface->width * dst_surface->lx_pitch;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-13 09:20:52 +02:00
|
|
|
dst_surface->bmi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * 256);
|
|
|
|
dst_surface->bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
|
|
dst_surface->bmi->bmiHeader.biWidth = dst_surface->width;
|
2021-05-10 04:00:45 +02:00
|
|
|
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
|
|
|
|
2020-10-13 11:29:52 +02:00
|
|
|
dst_surface->bmi->bmiHeader.biSizeImage = ((dst_surface->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 = CreateDIBSection(dst_surface->hdc, dst_surface->bmi, DIB_RGB_COLORS, (void **)&dst_surface->surface, NULL, 0);
|
2021-05-10 04:00:45 +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
|
|
|
{
|
|
|
|
dst_surface->surface =
|
|
|
|
HeapAlloc(
|
|
|
|
GetProcessHeap(),
|
|
|
|
HEAP_ZERO_MEMORY,
|
|
|
|
dst_surface->l_pitch * (dst_surface->height + 200) * dst_surface->lx_pitch);
|
|
|
|
}
|
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
|
|
|
{
|
2021-05-08 23:42:29 +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
|
|
|
{
|
|
|
|
dprintf(" dwBackBufferCount=%d\n", lpDDSurfaceDesc->dwBackBufferCount);
|
2021-05-04 22:49:22 +02:00
|
|
|
|
|
|
|
if (g_ddraw->backbuffer)
|
|
|
|
{
|
|
|
|
DDSURFACEDESC desc;
|
|
|
|
memset(&desc, 0, sizeof(DDSURFACEDESC));
|
|
|
|
|
2021-05-31 18:54:32 +02:00
|
|
|
if (lpDDSurfaceDesc->dwBackBufferCount > 1)
|
|
|
|
{
|
|
|
|
desc.dwBackBufferCount = lpDDSurfaceDesc->dwBackBufferCount - 1;
|
|
|
|
desc.dwFlags |= DDSD_BACKBUFFERCOUNT;
|
|
|
|
}
|
|
|
|
|
2021-05-04 22:49:22 +02:00
|
|
|
desc.ddsCaps.dwCaps |= DDSCAPS_BACKBUFFER;
|
|
|
|
|
|
|
|
desc.dwWidth = dst_surface->width;
|
|
|
|
desc.dwHeight = dst_surface->height;
|
|
|
|
|
2021-05-29 20:51:19 +02:00
|
|
|
dd_CreateSurface(This, &desc, (LPDIRECTDRAWSURFACE*)&dst_surface->backbuffer, unkOuter);
|
2021-05-04 22:49:22 +02:00
|
|
|
}
|
2020-10-13 09:20:52 +02:00
|
|
|
}
|
|
|
|
|
2020-10-22 22:37:57 +02:00
|
|
|
dprintf(" surface = %p (%dx%d@%d)\n", dst_surface, (int)dst_surface->width, (int)dst_surface->height, (int)dst_surface->bpp);
|
2020-10-13 09:20:52 +02:00
|
|
|
|
|
|
|
*lpDDSurface = (LPDIRECTDRAWSURFACE)dst_surface;
|
|
|
|
|
|
|
|
dst_surface->ref = 0;
|
|
|
|
IDirectDrawSurface_AddRef(dst_surface);
|
|
|
|
|
|
|
|
return DD_OK;
|
|
|
|
}
|