mirror of
https://github.com/reactos/reactos.git
synced 2024-08-08 04:08:29 +00:00
![Joachim Henze](/assets/img/avatar_default.png)
This nice patch of Jerome Gardou improves palette when VBEMP & inbuilt Mesa is used for Diablo II, MS Age Of Empires 1, Anno 1602 to the state we had in SVN r75060 and below. Palette still not perfect in fullscreen but at least as good as it was before it regressed by SVN r75061 == git4b0ee92f91
We do intend to improve on the remaining fullscreen palette issues in CORE-10738. fix cherry picked from 0.4.9-dev-675-g14f0e62f9a
124 lines
3.8 KiB
C
124 lines
3.8 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS kernel
|
|
* PURPOSE: Native DirectDraw implementation
|
|
* FILE: win32ss/reactx/ntddraw/d3dkmt.c
|
|
* PROGRAMER: Sebastian Gasiorek (sebastian.gasiorek@reactos.com)
|
|
*/
|
|
|
|
#include <win32k.h>
|
|
#include <debug.h>
|
|
|
|
DWORD
|
|
APIENTRY
|
|
NtGdiDdDDICreateDCFromMemory(D3DKMT_CREATEDCFROMMEMORY *desc)
|
|
{
|
|
PSURFACE psurf;
|
|
HDC hDC;
|
|
|
|
const struct d3dddi_format_info
|
|
{
|
|
D3DDDIFORMAT format;
|
|
unsigned int bit_count;
|
|
DWORD compression;
|
|
unsigned int palette_size;
|
|
DWORD mask_r, mask_g, mask_b;
|
|
} *format = NULL;
|
|
unsigned int i;
|
|
|
|
static const struct d3dddi_format_info format_info[] =
|
|
{
|
|
{ D3DDDIFMT_R8G8B8, 24, BI_RGB, 0, 0x00000000, 0x00000000, 0x00000000 },
|
|
{ D3DDDIFMT_A8R8G8B8, 32, BI_RGB, 0, 0x00000000, 0x00000000, 0x00000000 },
|
|
{ D3DDDIFMT_X8R8G8B8, 32, BI_RGB, 0, 0x00000000, 0x00000000, 0x00000000 },
|
|
{ D3DDDIFMT_R5G6B5, 16, BI_BITFIELDS, 0, 0x0000f800, 0x000007e0, 0x0000001f },
|
|
{ D3DDDIFMT_X1R5G5B5, 16, BI_BITFIELDS, 0, 0x00007c00, 0x000003e0, 0x0000001f },
|
|
{ D3DDDIFMT_A1R5G5B5, 16, BI_BITFIELDS, 0, 0x00007c00, 0x000003e0, 0x0000001f },
|
|
{ D3DDDIFMT_A4R4G4B4, 16, BI_BITFIELDS, 0, 0x00000f00, 0x000000f0, 0x0000000f },
|
|
{ D3DDDIFMT_X4R4G4B4, 16, BI_BITFIELDS, 0, 0x00000f00, 0x000000f0, 0x0000000f },
|
|
{ D3DDDIFMT_P8, 8, BI_RGB, 256, 0x00000000, 0x00000000, 0x00000000 },
|
|
};
|
|
|
|
if (!desc)
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
if (!desc->pMemory)
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
for (i = 0; i < sizeof(format_info) / sizeof(*format_info); ++i)
|
|
{
|
|
if (format_info[i].format == desc->Format)
|
|
{
|
|
format = &format_info[i];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!format)
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
if (desc->Width > (UINT_MAX & ~3) / (format->bit_count / 8) ||
|
|
!desc->Pitch || desc->Pitch < (((desc->Width * format->bit_count + 31) >> 3) & ~3) ||
|
|
!desc->Height || desc->Height > UINT_MAX / desc->Pitch)
|
|
{
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (!desc->hDeviceDc || !(hDC = NtGdiCreateCompatibleDC(desc->hDeviceDc)))
|
|
{
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
/* Allocate a surface */
|
|
psurf = SURFACE_AllocSurface(STYPE_BITMAP,
|
|
desc->Width,
|
|
desc->Height,
|
|
BitmapFormat(format->bit_count, format->compression),
|
|
BMF_TOPDOWN | BMF_NOZEROINIT,
|
|
desc->Pitch,
|
|
0,
|
|
desc->pMemory);
|
|
|
|
/* Mark as API bitmap */
|
|
psurf->flags |= (DDB_SURFACE | API_BITMAP);
|
|
|
|
desc->hDc = hDC;
|
|
/* Get the handle for the bitmap */
|
|
desc->hBitmap = (HBITMAP)psurf->SurfObj.hsurf;
|
|
|
|
/* Allocate a palette for this surface */
|
|
if (format->bit_count <= 8)
|
|
{
|
|
PPALETTE palette = PALETTE_AllocPalette(PAL_INDEXED, 1 << format->bit_count, NULL, 0, 0, 0);
|
|
if (palette)
|
|
{
|
|
SURFACE_vSetPalette(psurf, palette);
|
|
PALETTE_ShareUnlockPalette(palette);
|
|
}
|
|
}
|
|
|
|
/* Unlock the surface and return */
|
|
SURFACE_UnlockSurface(psurf);
|
|
|
|
NtGdiSelectBitmap(desc->hDc, desc->hBitmap);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
DWORD
|
|
APIENTRY
|
|
NtGdiDdDDIDestroyDCFromMemory(const D3DKMT_DESTROYDCFROMMEMORY *desc)
|
|
{
|
|
if (!desc)
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
if (GDI_HANDLE_GET_TYPE(desc->hDc) != GDI_OBJECT_TYPE_DC ||
|
|
GDI_HANDLE_GET_TYPE(desc->hBitmap) != GDI_OBJECT_TYPE_BITMAP)
|
|
return STATUS_INVALID_PARAMETER;
|
|
|
|
NtGdiDeleteObjectApp(desc->hBitmap);
|
|
NtGdiDeleteObjectApp(desc->hDc);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|