reactos/dll/directx/wine/ddraw/palette.c
Joachim Henze 67dd70e5ef [0.4.13] Avoid regressions CORE-14955 "Ddraw fullscreen crashes", CORE-15652
This brings us back to before guilty commit 0.4.10-dev-55-g
7af3969e9f

and therefore downgrades
dll/directx/wine/
D3D8,D3D9,DDRAW,D3DCOMPILER_43
to WineStaging 3.3 for this rls.
Also downgrades related header sdk/include/reactos/wine/wined3d.h
and for the first time also media/doc/README.WINE

Same versions of these dlls we had in every ros rls since 0.4.10rls.

Purpose of this revert is to fix crashes when Ddraw apps switch
into fullscreen with VBEMP and inbuilt Mesa.
I tested, before:
 DxDiag crashed when switching to fullscreen (CORE-14955),
 Diablo II crashed immediately (CORE-15652),
 Monster-Truck-Madness 2 demo crashed after main menu

Afterwards all of these apps do run.
DXTN does still work after that, even with VBEMP and inbuilt Mesa.

This will be the interim fix, which I will keep for rls at least
until someone manages to fix CORE-14955 properly in master with current Wine.

analog to 0.4.10-RC-17-g
bb4c55d650
2019-10-02 01:27:03 +02:00

295 lines
8.7 KiB
C

/*
* Copyright 2006 Stefan Dösinger
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include "config.h"
#include "wine/port.h"
#include "ddraw_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
/*****************************************************************************
* IDirectDrawPalette::QueryInterface
*
* A usual QueryInterface implementation. Can only Query IUnknown and
* IDirectDrawPalette
*
* Params:
* refiid: The interface id queried for
* obj: Address to return the interface pointer at
*
* Returns:
* S_OK on success
* E_NOINTERFACE if the requested interface wasn't found
*****************************************************************************/
static HRESULT WINAPI ddraw_palette_QueryInterface(IDirectDrawPalette *iface, REFIID refiid, void **obj)
{
TRACE("iface %p, riid %s, object %p.\n", iface, debugstr_guid(refiid), obj);
if (IsEqualGUID(refiid, &IID_IUnknown)
|| IsEqualGUID(refiid, &IID_IDirectDrawPalette))
{
*obj = iface;
IDirectDrawPalette_AddRef(iface);
return S_OK;
}
else
{
*obj = NULL;
return E_NOINTERFACE;
}
}
/*****************************************************************************
* IDirectDrawPaletteImpl::AddRef
*
* Increases the refcount.
*
* Returns:
* The new refcount
*
*****************************************************************************/
static ULONG WINAPI ddraw_palette_AddRef(IDirectDrawPalette *iface)
{
struct ddraw_palette *This = impl_from_IDirectDrawPalette(iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("%p increasing refcount to %u.\n", This, ref);
return ref;
}
/*****************************************************************************
* IDirectDrawPaletteImpl::Release
*
* Reduces the refcount. If the refcount falls to 0, the object is destroyed
*
* Returns:
* The new refcount
*
*****************************************************************************/
static ULONG WINAPI ddraw_palette_Release(IDirectDrawPalette *iface)
{
struct ddraw_palette *palette = impl_from_IDirectDrawPalette(iface);
ULONG ref = InterlockedDecrement(&palette->ref);
TRACE("%p decreasing refcount to %u.\n", palette, ref);
if (ref == 0)
{
wined3d_mutex_lock();
wined3d_palette_decref(palette->wined3d_palette);
if ((palette->flags & DDPCAPS_PRIMARYSURFACE) && palette->ddraw->primary)
palette->ddraw->primary->palette = NULL;
if (palette->ifaceToRelease)
IUnknown_Release(palette->ifaceToRelease);
wined3d_mutex_unlock();
heap_free(palette);
}
return ref;
}
/*****************************************************************************
* IDirectDrawPalette::Initialize
*
* Initializes the palette. As we start initialized, return
* DDERR_ALREADYINITIALIZED
*
* Params:
* DD: DirectDraw interface this palette is assigned to
* Flags: Some flags, as usual
* ColorTable: The startup color table
*
* Returns:
* DDERR_ALREADYINITIALIZED
*
*****************************************************************************/
static HRESULT WINAPI ddraw_palette_Initialize(IDirectDrawPalette *iface,
IDirectDraw *ddraw, DWORD flags, PALETTEENTRY *entries)
{
TRACE("iface %p, ddraw %p, flags %#x, entries %p.\n",
iface, ddraw, flags, entries);
return DDERR_ALREADYINITIALIZED;
}
static HRESULT WINAPI ddraw_palette_GetCaps(IDirectDrawPalette *iface, DWORD *caps)
{
struct ddraw_palette *palette = impl_from_IDirectDrawPalette(iface);
TRACE("iface %p, caps %p.\n", iface, caps);
wined3d_mutex_lock();
*caps = palette->flags;
wined3d_mutex_unlock();
return D3D_OK;
}
/*****************************************************************************
* IDirectDrawPalette::SetEntries
*
* Sets the palette entries from a PALETTEENTRY structure. WineD3D takes
* care for updating the surface.
*
* Params:
* Flags: Flags, as usual
* Start: First palette entry to set
* Count: Number of entries to set
* PalEnt: Source entries
*
* Returns:
* D3D_OK on success
* DDERR_INVALIDPARAMS if PalEnt is NULL
*
*****************************************************************************/
static HRESULT WINAPI ddraw_palette_SetEntries(IDirectDrawPalette *iface,
DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries)
{
struct ddraw_palette *palette = impl_from_IDirectDrawPalette(iface);
HRESULT hr;
TRACE("iface %p, flags %#x, start %u, count %u, entries %p.\n",
iface, flags, start, count, entries);
if (!entries)
return DDERR_INVALIDPARAMS;
wined3d_mutex_lock();
hr = wined3d_palette_set_entries(palette->wined3d_palette, flags, start, count, entries);
if (SUCCEEDED(hr) && palette->flags & DDPCAPS_PRIMARYSURFACE)
ddraw_surface_update_frontbuffer(palette->ddraw->primary, NULL, FALSE);
wined3d_mutex_unlock();
return hr;
}
/*****************************************************************************
* IDirectDrawPalette::GetEntries
*
* Returns the entries stored in this interface.
*
* Params:
* Flags: Flags :)
* Start: First entry to return
* Count: The number of entries to return
* PalEnt: PALETTEENTRY structure to write the entries to
*
* Returns:
* D3D_OK on success
* DDERR_INVALIDPARAMS if PalEnt is NULL
*
*****************************************************************************/
static HRESULT WINAPI ddraw_palette_GetEntries(IDirectDrawPalette *iface,
DWORD flags, DWORD start, DWORD count, PALETTEENTRY *entries)
{
struct ddraw_palette *palette = impl_from_IDirectDrawPalette(iface);
HRESULT hr;
TRACE("iface %p, flags %#x, start %u, count %u, entries %p.\n",
iface, flags, start, count, entries);
if (!entries)
return DDERR_INVALIDPARAMS;
wined3d_mutex_lock();
hr = wined3d_palette_get_entries(palette->wined3d_palette, flags, start, count, entries);
wined3d_mutex_unlock();
return hr;
}
static const struct IDirectDrawPaletteVtbl ddraw_palette_vtbl =
{
/*** IUnknown ***/
ddraw_palette_QueryInterface,
ddraw_palette_AddRef,
ddraw_palette_Release,
/*** IDirectDrawPalette ***/
ddraw_palette_GetCaps,
ddraw_palette_GetEntries,
ddraw_palette_Initialize,
ddraw_palette_SetEntries
};
struct ddraw_palette *unsafe_impl_from_IDirectDrawPalette(IDirectDrawPalette *iface)
{
if (!iface) return NULL;
assert(iface->lpVtbl == &ddraw_palette_vtbl);
return CONTAINING_RECORD(iface, struct ddraw_palette, IDirectDrawPalette_iface);
}
static unsigned int palette_size(DWORD flags)
{
switch (flags & (DDPCAPS_1BIT | DDPCAPS_2BIT | DDPCAPS_4BIT | DDPCAPS_8BIT))
{
case DDPCAPS_1BIT:
return 2;
case DDPCAPS_2BIT:
return 4;
case DDPCAPS_4BIT:
return 16;
case DDPCAPS_8BIT:
return 256;
default:
return ~0u;
}
}
HRESULT ddraw_palette_init(struct ddraw_palette *palette,
struct ddraw *ddraw, DWORD flags, PALETTEENTRY *entries)
{
unsigned int entry_count;
DWORD wined3d_flags = 0;
HRESULT hr;
if ((entry_count = palette_size(flags)) == ~0u)
{
WARN("Invalid flags %#x.\n", flags);
return DDERR_INVALIDPARAMS;
}
if (flags & DDPCAPS_8BITENTRIES)
wined3d_flags |= WINED3D_PALETTE_8BIT_ENTRIES;
if (flags & DDPCAPS_ALLOW256)
wined3d_flags |= WINED3D_PALETTE_ALLOW_256;
if (flags & DDPCAPS_ALPHA)
wined3d_flags |= WINED3D_PALETTE_ALPHA;
palette->IDirectDrawPalette_iface.lpVtbl = &ddraw_palette_vtbl;
palette->ref = 1;
palette->flags = flags;
if (FAILED(hr = wined3d_palette_create(ddraw->wined3d_device,
wined3d_flags, entry_count, entries, &palette->wined3d_palette)))
{
WARN("Failed to create wined3d palette, hr %#x.\n", hr);
return hr;
}
palette->ddraw = ddraw;
palette->ifaceToRelease = (IUnknown *)&ddraw->IDirectDraw7_iface;
IUnknown_AddRef(palette->ifaceToRelease);
return DD_OK;
}