1
0
mirror of https://github.com/narzoul/DDrawCompat synced 2024-12-30 08:55:36 +01:00

Added PalettizedTextures setting

This commit is contained in:
narzoul 2022-08-27 00:44:25 +02:00
parent a775e256ea
commit bb0eadc310
27 changed files with 529 additions and 22 deletions

View File

@ -33,6 +33,11 @@ inline auto toTuple(const POINT& pt)
return std::make_tuple(pt.x, pt.y);
}
inline auto toTuple(const RGBQUAD& q)
{
return std::make_tuple(q.rgbBlue, q.rgbGreen, q.rgbRed, q.rgbReserved);
}
inline auto toTuple(const SIZE& size)
{
return std::make_tuple(size.cx, size.cy);

View File

@ -19,6 +19,7 @@ namespace Config
Settings::FpsLimiter fpsLimiter;
Settings::FullscreenMode fullscreenMode;
Settings::LogLevel logLevel;
Settings::PalettizedTextures palettizedTextures;
Settings::RemoveBorders removeBorders;
Settings::RenderColorDepth renderColorDepth;
Settings::ResolutionScale resolutionScale;

View File

@ -17,6 +17,7 @@
#include <Config/Settings/FpsLimiter.h>
#include <Config/Settings/FullscreenMode.h>
#include <Config/Settings/LogLevel.h>
#include <Config/Settings/PalettizedTextures.h>
#include <Config/Settings/RemoveBorders.h>
#include <Config/Settings/RenderColorDepth.h>
#include <Config/Settings/ResolutionScale.h>
@ -48,6 +49,7 @@ namespace Config
extern Settings::FpsLimiter fpsLimiter;
extern Settings::FullscreenMode fullscreenMode;
extern Settings::LogLevel logLevel;
extern Settings::PalettizedTextures palettizedTextures;
extern Settings::RemoveBorders removeBorders;
extern Settings::RenderColorDepth renderColorDepth;
extern Settings::ResolutionScale resolutionScale;

View File

@ -0,0 +1,18 @@
#pragma once
#include <Config/EnumSetting.h>
namespace Config
{
namespace Settings
{
class PalettizedTextures : public MappedSetting<bool>
{
public:
PalettizedTextures()
: MappedSetting("PalettizedTextures", "on", { {"off", false}, {"on", true} })
{
}
};
}
}

View File

@ -266,6 +266,27 @@ namespace D3dDdi
{
caps.dwDeviceZBufferBitDepth = getInfo().supportedZBufferBitDepths;
}
if (Config::palettizedTextures.get())
{
caps.dpcTriCaps.dwTextureCaps |= D3DPTEXTURECAPS_ALPHAPALETTE;
}
break;
}
case D3DDDICAPS_GETFORMATDATA:
{
if (Config::palettizedTextures.get())
{
UINT count = pData->DataSize / sizeof(FORMATOP);
auto formatOp = static_cast<FORMATOP*>(pData->pData);
for (UINT i = 0; i < count; ++i)
{
if (D3DDDIFMT_P8 == formatOp[i].Format)
{
formatOp[i].Operations |= FORMATOP_TEXTURE | FORMATOP_CUBETEXTURE;
}
}
}
break;
}
}

View File

@ -359,6 +359,25 @@ namespace D3dDdi
return result;
}
HRESULT Device::pfnSetPalette(const D3DDDIARG_SETPALETTE* data)
{
flushPrimitives();
if (data->PaletteHandle >= m_palettes.size())
{
m_palettes.resize(data->PaletteHandle + 1);
m_paletteFlags.resize(data->PaletteHandle + 1);
}
m_paletteFlags[data->PaletteHandle] = data->PaletteFlags;
auto it = m_resources.find(data->hResource);
if (it != m_resources.end())
{
it->second->setPaletteHandle(data->PaletteHandle);
}
return S_OK;
}
HRESULT Device::pfnUnlock(const D3DDDIARG_UNLOCK* data)
{
flushPrimitives();
@ -370,6 +389,35 @@ namespace D3dDdi
return m_origVtable.pfnUnlock(m_device, data);
}
HRESULT Device::pfnUpdatePalette(const D3DDDIARG_UPDATEPALETTE* data, const PALETTEENTRY* paletteData)
{
LOG_DEBUG << Compat::array(reinterpret_cast<const HANDLE*>(paletteData), data->NumEntries);
flushPrimitives();
if (data->PaletteHandle >= m_palettes.size())
{
m_palettes.resize(data->PaletteHandle + 1);
}
const bool useAlpha = m_paletteFlags[data->PaletteHandle] & D3DDDISETPALETTE_ALPHA;
for (UINT i = 0; i < data->NumEntries; ++i)
{
auto& rgbQuad = m_palettes[data->PaletteHandle][data->StartIndex + i];
rgbQuad.rgbReserved = useAlpha ? paletteData[i].peFlags : 0xFF;
rgbQuad.rgbRed = paletteData[i].peRed;
rgbQuad.rgbGreen = paletteData[i].peGreen;
rgbQuad.rgbBlue = paletteData[i].peBlue;
}
for (auto& resourcePair : m_resources)
{
if (resourcePair.second->getPaletteHandle() == data->PaletteHandle)
{
resourcePair.second->invalidatePalettizedTexture();
}
}
return S_OK;
}
void Device::updateAllConfig()
{
g_isConfigUpdatePending = true;

View File

@ -1,7 +1,9 @@
#pragma once
#include <array>
#include <map>
#include <memory>
#include <vector>
#include <d3d.h>
#include <d3dnthal.h>
@ -44,11 +46,14 @@ namespace D3dDdi
HRESULT pfnOpenResource(D3DDDIARG_OPENRESOURCE* data);
HRESULT pfnPresent(const D3DDDIARG_PRESENT* data);
HRESULT pfnPresent1(D3DDDIARG_PRESENT1* data);
HRESULT pfnSetPalette(const D3DDDIARG_SETPALETTE* data);
HRESULT pfnUnlock(const D3DDDIARG_UNLOCK* data);
HRESULT pfnUpdatePalette(const D3DDDIARG_UPDATEPALETTE* data, const PALETTEENTRY* paletteData);
Adapter& getAdapter() const { return m_adapter; }
DrawPrimitive& getDrawPrimitive() { return m_drawPrimitive; }
const D3DDDI_DEVICEFUNCS& getOrigVtable() const { return m_origVtable; }
RGBQUAD* getPalette(UINT paletteHandle) { return m_palettes[paletteHandle].data(); }
Resource* getResource(HANDLE resource);
DeviceState& getState() { return m_state; }
ShaderBlitter& getShaderBlitter() { return m_shaderBlitter; }
@ -84,6 +89,8 @@ namespace D3dDdi
DrawPrimitive m_drawPrimitive;
DeviceState m_state;
ShaderBlitter m_shaderBlitter;
std::vector<std::array<RGBQUAD, 256>> m_palettes;
std::vector<UINT> m_paletteFlags;
static std::map<HANDLE, Device> s_devices;
static bool s_isFlushEnabled;

View File

@ -64,7 +64,9 @@ namespace
SET_DEVICE_FUNC(pfnOpenResource);
SET_DEVICE_FUNC(pfnPresent);
SET_DEVICE_FUNC(pfnPresent1);
SET_DEVICE_FUNC(pfnSetPalette);
SET_DEVICE_FUNC(pfnUnlock);
SET_DEVICE_FUNC(pfnUpdatePalette);
SET_DEVICE_STATE_FUNC(pfnCreateVertexShaderDecl);
SET_DEVICE_STATE_FUNC(pfnDeletePixelShader);
@ -96,12 +98,10 @@ namespace
SET_FLUSH_PRIMITIVES_FUNC(pfnDiscard);
SET_FLUSH_PRIMITIVES_FUNC(pfnGenerateMipSubLevels);
SET_FLUSH_PRIMITIVES_FUNC(pfnSetClipPlane);
SET_FLUSH_PRIMITIVES_FUNC(pfnSetPalette);
SET_FLUSH_PRIMITIVES_FUNC(pfnSetScissorRect);
SET_FLUSH_PRIMITIVES_FUNC(pfnStateSet);
SET_FLUSH_PRIMITIVES_FUNC(pfnTexBlt);
SET_FLUSH_PRIMITIVES_FUNC(pfnTexBlt1);
SET_FLUSH_PRIMITIVES_FUNC(pfnUpdatePalette);
}
}

View File

@ -230,6 +230,8 @@ namespace D3dDdi
return;
}
prepareTextures();
if (m_changedStates & CS_RENDER_STATE)
{
updateRenderStates();
@ -257,6 +259,10 @@ namespace D3dDdi
Resource* DeviceState::getTextureResource(UINT stage)
{
if (!m_app.textures[stage])
{
return nullptr;
}
if (!m_textureResource[stage] || *m_textureResource[stage] != m_app.textures[stage])
{
m_textureResource[stage] = m_device.getResource(m_app.textures[stage]);
@ -336,7 +342,7 @@ namespace D3dDdi
return value;
}
void DeviceState::onDestroyResource(D3dDdi::Resource* resource, HANDLE resourceHandle)
void DeviceState::onDestroyResource(Resource* resource, HANDLE resourceHandle)
{
for (UINT i = 0; i < m_current.textures.size(); ++i)
{
@ -574,6 +580,18 @@ namespace D3dDdi
return S_OK;
}
void DeviceState::prepareTextures()
{
for (UINT stage = 0; stage < m_app.textures.size(); ++stage)
{
auto resource = getTextureResource(stage);
if (resource)
{
resource->updatePalettizedTexture(stage);
}
}
}
template <typename Data>
void DeviceState::removeResource(HANDLE resource, Data State::* data, HANDLE Data::* resourceMember,
HRESULT(DeviceState::* pfnSetResourceFunc)(const Data*))
@ -985,6 +1003,13 @@ namespace D3dDdi
void DeviceState::updateTextureColorKey(UINT stage)
{
m_changedTextureStageStates[stage].reset(D3DDDITSS_DISABLETEXTURECOLORKEY);
m_changedTextureStageStates[stage].reset(D3DDDITSS_TEXTURECOLORKEYVAL);
if (!m_app.textures[stage])
{
return;
}
D3DDDIARG_TEXTURESTAGESTATE tss = {};
tss.Stage = stage;
@ -998,14 +1023,18 @@ namespace D3dDdi
{
tss.State = D3DDDITSS_TEXTURECOLORKEYVAL;
tss.Value = m_app.textureStageState[stage][D3DDDITSS_TEXTURECOLORKEYVAL];
auto resource = getTextureResource(stage);
if (resource && resource->getPalettizedTexture())
{
tss.Value = reinterpret_cast<DWORD&>(
m_device.getPalette(resource->getPalettizedTexture()->getPaletteHandle())[tss.Value]);
}
m_current.textureStageState[stage][D3DDDITSS_TEXTURECOLORKEYVAL] = tss.Value;
m_current.textureStageState[stage][D3DDDITSS_DISABLETEXTURECOLORKEY] = FALSE;
}
m_device.flushPrimitives();
m_device.getOrigVtable().pfnSetTextureStageState(m_device, &tss);
m_changedTextureStageStates[stage].reset(D3DDDITSS_DISABLETEXTURECOLORKEY);
m_changedTextureStageStates[stage].reset(D3DDDITSS_TEXTURECOLORKEYVAL);
LOG_DS << tss;
}
@ -1013,21 +1042,11 @@ namespace D3dDdi
{
for (UINT stage = 0; stage <= m_maxChangedTextureStage; ++stage)
{
if (setTexture(stage, m_app.textures[stage]))
{
updateTextureColorKey(stage);
}
else if (m_changedTextureStageStates[stage].test(D3DDDITSS_DISABLETEXTURECOLORKEY) ||
if (setTexture(stage, m_app.textures[stage]) ||
m_changedTextureStageStates[stage].test(D3DDDITSS_DISABLETEXTURECOLORKEY) ||
m_changedTextureStageStates[stage].test(D3DDDITSS_TEXTURECOLORKEYVAL))
{
if (m_app.textureStageState[stage][D3DDDITSS_DISABLETEXTURECOLORKEY] !=
m_current.textureStageState[stage][D3DDDITSS_DISABLETEXTURECOLORKEY] ||
!m_app.textureStageState[stage][D3DDDITSS_DISABLETEXTURECOLORKEY] &&
m_current.textureStageState[stage][D3DDDITSS_TEXTURECOLORKEYVAL] !=
m_app.textureStageState[stage][D3DDDITSS_TEXTURECOLORKEYVAL])
{
updateTextureColorKey(stage);
}
updateTextureColorKey(stage);
}
m_changedTextureStageStates[stage].forEach([&](UINT stateIndex)

View File

@ -131,7 +131,7 @@ namespace D3dDdi
const VertexDecl& getVertexDecl() const;
HANDLE getVertexFixupDecl() const { return m_vsVertexFixup.get(); }
bool isLocked() const { return m_isLocked; }
void onDestroyResource(D3dDdi::Resource* resource, HANDLE resourceHandle);
void onDestroyResource(Resource* resource, HANDLE resourceHandle);
void updateConfig();
void updateStreamSource();
@ -159,6 +159,7 @@ namespace D3dDdi
UINT mapRsValue(D3DDDIRENDERSTATETYPE state, UINT value);
UINT mapTssValue(UINT stage, D3DDDITEXTURESTAGESTATETYPE state, UINT value);
void prepareTextures();
template <typename Data>
void removeResource(HANDLE resource, Data State::* data, HANDLE Data::* resourceMember,

View File

@ -218,6 +218,14 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETDEPTHSTENCIL& val)
<< val.hZBuffer;
}
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETPALETTE& val)
{
return Compat::LogStruct(os)
<< Compat::hex(val.PaletteHandle)
<< Compat::hex(val.PaletteFlags)
<< val.hResource;
}
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETPIXELSHADERCONST& val)
{
return Compat::LogStruct(os)
@ -272,6 +280,14 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_UNLOCK& val)
<< Compat::hex(val.Flags.Value);
}
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_UPDATEPALETTE& val)
{
return Compat::LogStruct(os)
<< Compat::hex(val.PaletteHandle)
<< val.StartIndex
<< val.NumEntries;
}
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_VIEWPORTINFO& val)
{
return Compat::LogStruct(os)

View File

@ -27,6 +27,7 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_PRESENT1& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_PRESENTSURFACE& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_RENDERSTATE& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETDEPTHSTENCIL& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETPALETTE& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETPIXELSHADERCONST& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETRENDERTARGET& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETSTREAMSOURCE& val);
@ -34,6 +35,7 @@ std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETSTREAMSOURCEUM& va
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_SETVERTEXSHADERCONST& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_TEXTURESTAGESTATE& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_UNLOCK& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_UPDATEPALETTE& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_VIEWPORTINFO& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_WINFO& val);
std::ostream& operator<<(std::ostream& os, const D3DDDIARG_ZRANGE& val);

View File

@ -118,10 +118,14 @@ namespace D3dDdi
, m_formatConfig(D3DDDIFMT_UNKNOWN)
, m_multiSampleConfig{ D3DDDIMULTISAMPLE_NONE, 0 }
, m_scaledSize{}
, m_palettizedTexture(nullptr)
, m_paletteHandle(0)
, m_paletteColorKeyIndex(-1)
, m_isOversized(false)
, m_isSurfaceRepoResource(SurfaceRepository::inCreateSurface())
, m_isClampable(true)
, m_isPrimary(false)
, m_isPalettizedTextureUpToDate(false)
{
if (m_origData.Flags.VertexBuffer &&
m_origData.Flags.MightDrawFromLocked &&
@ -888,6 +892,10 @@ namespace D3dDdi
return bltLock(data);
}
if (!data.Flags.ReadOnly)
{
m_isPalettizedTextureUpToDate = false;
}
return m_device.getOrigVtable().pfnLock(m_device, &data);
}
@ -932,6 +940,7 @@ namespace D3dDdi
Resource& Resource::prepareForBltDst(HANDLE& resource, UINT subResourceIndex, RECT& rect)
{
m_isPalettizedTextureUpToDate = false;
if (m_lockResource)
{
loadFromLockRefResource(subResourceIndex);
@ -1272,6 +1281,18 @@ namespace D3dDdi
}
}
void Resource::setPaletteHandle(UINT paletteHandle)
{
m_paletteHandle = paletteHandle;
m_isPalettizedTextureUpToDate = false;
}
void Resource::setPalettizedTexture(Resource& resource)
{
m_palettizedTexture = &resource;
resource.m_isPalettizedTextureUpToDate = false;
}
HRESULT Resource::shaderBlt(D3DDDIARG_BLT& data, Resource& dstResource, Resource& srcResource)
{
LOG_FUNC("Resource::shaderBlt", data, srcResource);
@ -1462,4 +1483,43 @@ namespace D3dDdi
}
}
}
void Resource::updatePalettizedTexture(UINT stage)
{
if (!m_palettizedTexture)
{
return;
}
auto& appState = m_device.getState().getAppState();
int paletteColorKeyIndex = appState.textureStageState[stage][D3DDDITSS_DISABLETEXTURECOLORKEY]
? -1 : appState.textureStageState[stage][D3DDDITSS_TEXTURECOLORKEYVAL];
if (m_palettizedTexture->m_isPalettizedTextureUpToDate &&
(-1 == paletteColorKeyIndex || paletteColorKeyIndex == m_paletteColorKeyIndex))
{
return;
}
auto palettePtr = m_device.getPalette(m_palettizedTexture->m_paletteHandle);
if (paletteColorKeyIndex >= 0)
{
static RGBQUAD palette[256] = {};
memcpy(palette, m_device.getPalette(m_palettizedTexture->m_paletteHandle), sizeof(palette));
for (int i = 0; i < 256; ++i)
{
if (i != paletteColorKeyIndex && palette[i] == palette[paletteColorKeyIndex])
{
palette[i].rgbBlue += 0xFF == palette[i].rgbBlue ? -1 : 1;
}
}
palettePtr = palette;
}
auto rect = getRect(0);
m_device.getShaderBlitter().palettizedBlt(*this, 0, rect, *m_palettizedTexture, 0, rect, palettePtr);
m_palettizedTexture->m_isPalettizedTextureUpToDate = true;
m_paletteColorKeyIndex = paletteColorKeyIndex;
}
}

View File

@ -30,7 +30,10 @@ namespace D3dDdi
Device& getDevice() const { return m_device; }
const D3DDDIARG_CREATERESOURCE2& getFixedDesc() const { return m_fixedData; }
const D3DDDIARG_CREATERESOURCE2& getOrigDesc() const { return m_origData; }
UINT getPaletteHandle() const { return m_paletteHandle; }
Resource* getPalettizedTexture() { return m_palettizedTexture; }
bool isClampable() const { return m_isClampable; }
void invalidatePalettizedTexture() { m_isPalettizedTextureUpToDate = false; }
HRESULT blt(D3DDDIARG_BLT data);
HRESULT colorFill(D3DDDIARG_COLORFILL data);
@ -50,8 +53,11 @@ namespace D3dDdi
void setAsGdiResource(bool isGdiResource);
void setAsPrimary();
void setFullscreenMode(bool isFullscreen);
void setPaletteHandle(UINT paletteHandle);
void setPalettizedTexture(Resource& resource);
HRESULT unlock(const D3DDDIARG_UNLOCK& data);
void updateConfig();
void updatePalettizedTexture(UINT stage);
private:
class Data : public D3DDDIARG_CREATERESOURCE2
@ -125,9 +131,13 @@ namespace D3dDdi
D3DDDIFORMAT m_formatConfig;
std::pair<D3DDDIMULTISAMPLE_TYPE, UINT> m_multiSampleConfig;
SIZE m_scaledSize;
Resource* m_palettizedTexture;
UINT m_paletteHandle;
int m_paletteColorKeyIndex;
bool m_isOversized;
bool m_isSurfaceRepoResource;
bool m_isClampable;
bool m_isPrimary;
bool m_isPalettizedTextureUpToDate;
};
}

View File

@ -94,6 +94,7 @@ namespace D3dDdi
}
auto& state = m_device.getState();
state.setSpriteMode(false);
state.setTempRenderState({ D3DDDIRS_SCENECAPTURE, TRUE });
state.setTempVertexShaderDecl(m_vertexShaderDecl.get());
state.setTempPixelShader(pixelShader);

View File

@ -208,7 +208,7 @@ namespace D3dDdi
Resource* SurfaceRepository::getPaletteTexture()
{
return getSurface(m_paletteTexture, 256, 1, DDraw::DirectDraw::getRgbPixelFormat(32),
return getSurface(m_paletteTexture, 256, 1, getPixelFormat(D3DDDIFMT_A8R8G8B8),
DDSCAPS_TEXTURE | DDSCAPS_VIDEOMEMORY).resource;
}

View File

@ -14,6 +14,7 @@
#include <DDraw/DirectDrawSurface.h>
#include <DDraw/RealPrimarySurface.h>
#include <DDraw/ScopedThreadLock.h>
#include <DDraw/Surfaces/PalettizedTexture.h>
#include <DDraw/Surfaces/PrimarySurface.h>
#include <DDraw/Surfaces/TagSurface.h>
#include <DDraw/Visitors/DirectDrawVtblVisitor.h>
@ -33,6 +34,14 @@ namespace
{
return DDraw::PrimarySurface::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
}
else if (Config::palettizedTextures.get() &&
(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_TEXTURE) &&
!(lpDDSurfaceDesc->ddsCaps.dwCaps & DDSCAPS_SYSTEMMEMORY) &&
(lpDDSurfaceDesc->dwFlags & DDSD_PIXELFORMAT) &&
(DDPF_RGB | DDPF_PALETTEINDEXED8) == lpDDSurfaceDesc->ddpfPixelFormat.dwFlags)
{
return DDraw::PalettizedTexture::create<TDirectDraw>(*This, *lpDDSurfaceDesc, *lplpDDSurface);
}
else
{
return DDraw::Surface::create<TDirectDraw>(

View File

@ -62,6 +62,7 @@ namespace
SET_COMPAT_METHOD(Flip);
SET_COMPAT_METHOD(GetCaps);
SET_COMPAT_METHOD(GetDC);
SET_COMPAT_METHOD(GetPalette);
SET_COMPAT_METHOD(GetSurfaceDesc);
SET_COMPAT_METHOD(IsLost);
SET_COMPAT_METHOD(Lock);

View File

@ -0,0 +1,77 @@
#include <memory>
#include <Common/Log.h>
#include <D3dDdi/Device.h>
#include <D3dDdi/FormatInfo.h>
#include <D3dDdi/Resource.h>
#include <DDraw/DirectDrawSurface.h>
#include <DDraw/Surfaces/PalettizedTexture.h>
#include <DDraw/Surfaces/PalettizedTextureImpl.h>
namespace DDraw
{
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
HRESULT PalettizedTexture::create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface)
{
LOG_FUNC("PalettizedTexture::create", &dd, desc, surface);
DDSURFACEDESC d = {};
memcpy(&d, &desc, sizeof(d));
d.dwSize = sizeof(d);
auto dd1(CompatPtr<IDirectDraw>::from(&dd));
CompatPtr<IDirectDrawSurface> palettizedSurface;
HRESULT result = Surface::create<IDirectDraw>(*dd1, d, palettizedSurface.getRef(),
std::make_unique<DDraw::Surface>(desc.ddsCaps.dwCaps));
if (FAILED(result))
{
return LOG_RESULT(result);
}
auto privateData(std::make_unique<PalettizedTexture>(desc.ddsCaps.dwCaps));
auto data = privateData.get();
data->m_palettizedSurface = palettizedSurface;
desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS |
(desc.dwFlags & (DDSD_CKSRCBLT | DDSD_CKDESTBLT));
desc.ddpfPixelFormat = D3dDdi::getPixelFormat(D3DDDIFMT_A8R8G8B8);
desc.ddsCaps = {};
desc.ddsCaps.dwCaps = DDSCAPS_TEXTURE | DDSCAPS_3DDEVICE | DDSCAPS_VIDEOMEMORY;
result = Surface::create(dd, desc, surface, std::move(privateData));
if (FAILED(result))
{
return LOG_RESULT(result);
}
auto palettizedResource = D3dDdi::Device::findResource(
DDraw::DirectDrawSurface::getDriverResourceHandle(*data->m_palettizedSurface));
auto paletteResolvedResource = D3dDdi::Device::findResource(
DDraw::DirectDrawSurface::getDriverResourceHandle(*surface));
paletteResolvedResource->setPalettizedTexture(*palettizedResource);
return LOG_RESULT(DD_OK);
}
template HRESULT PalettizedTexture::create(
CompatRef<IDirectDraw> dd, DDSURFACEDESC desc, IDirectDrawSurface*& surface);
template HRESULT PalettizedTexture::create(
CompatRef<IDirectDraw2> dd, DDSURFACEDESC desc, IDirectDrawSurface*& surface);
template HRESULT PalettizedTexture::create(
CompatRef<IDirectDraw4> dd, DDSURFACEDESC2 desc, IDirectDrawSurface4*& surface);
template HRESULT PalettizedTexture::create(
CompatRef<IDirectDraw7> dd, DDSURFACEDESC2 desc, IDirectDrawSurface7*& surface);
PalettizedTexture::~PalettizedTexture()
{
LOG_FUNC("PalettizedTexture::~PalettizedTexture", this);
}
void PalettizedTexture::createImpl()
{
m_impl.reset(new PalettizedTextureImpl<IDirectDrawSurface>(*this, m_palettizedSurface));
m_impl2.reset(new PalettizedTextureImpl<IDirectDrawSurface2>(*this, m_palettizedSurface));
m_impl3.reset(new PalettizedTextureImpl<IDirectDrawSurface3>(*this, m_palettizedSurface));
m_impl4.reset(new PalettizedTextureImpl<IDirectDrawSurface4>(*this, m_palettizedSurface));
m_impl7.reset(new PalettizedTextureImpl<IDirectDrawSurface7>(*this, m_palettizedSurface));
}
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <ddraw.h>
#include <Common/CompatPtr.h>
#include <Common/CompatRef.h>
#include <DDraw/Surfaces/Surface.h>
namespace DDraw
{
class PalettizedTexture : public Surface
{
public:
PalettizedTexture(DWORD origCaps) : Surface(origCaps) {}
virtual ~PalettizedTexture() override;
template <typename TDirectDraw, typename TSurface, typename TSurfaceDesc>
static HRESULT create(CompatRef<TDirectDraw> dd, TSurfaceDesc desc, TSurface*& surface);
private:
CompatPtr<IDirectDrawSurface7> m_palettizedSurface;
virtual void createImpl() override;
};
}

View File

@ -0,0 +1,101 @@
#include <Common/CompatPtr.h>
#include <DDraw/Surfaces/PalettizedTexture.h>
#include <DDraw/Surfaces/PalettizedTextureImpl.h>
namespace DDraw
{
template <typename TSurface>
PalettizedTextureImpl<TSurface>::PalettizedTextureImpl(PalettizedTexture& data, CompatPtr<TSurface> palettizedSurface)
: SurfaceImpl(&data)
, m_data(data)
, m_palettizedSurface(palettizedSurface)
{
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::Blt(
TSurface* /*This*/, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
DWORD dwFlags, LPDDBLTFX lpDDBltFx)
{
return SurfaceImpl::Blt(m_palettizedSurface, lpDestRect, lpDDSrcSurface, lpSrcRect, dwFlags, lpDDBltFx);
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::BltFast(
TSurface* /*This*/, DWORD dwX, DWORD dwY, TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans)
{
return SurfaceImpl::BltFast(m_palettizedSurface, dwX, dwY, lpDDSrcSurface, lpSrcRect, dwTrans);
}
template <typename TSurface>
TSurface* PalettizedTextureImpl<TSurface>::getBltSrc(TSurface* /*src*/)
{
return m_palettizedSurface;
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::GetCaps(TSurface* /*This*/, TDdsCaps* lpDDSCaps)
{
return SurfaceImpl::GetCaps(m_palettizedSurface, lpDDSCaps);
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::GetDC(TSurface* /*This*/, HDC* lphDC)
{
return SurfaceImpl::GetDC(m_palettizedSurface, lphDC);
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::GetPalette(TSurface* /*This*/, LPDIRECTDRAWPALETTE* lplpDDPalette)
{
return SurfaceImpl::GetPalette(m_palettizedSurface, lplpDDPalette);
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::GetSurfaceDesc(TSurface* /*This*/, TSurfaceDesc* lpDDSurfaceDesc)
{
return SurfaceImpl::GetSurfaceDesc(m_palettizedSurface, lpDDSurfaceDesc);
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::Lock(
TSurface* /*This*/, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent)
{
return SurfaceImpl::Lock(m_palettizedSurface, lpDestRect, lpDDSurfaceDesc, dwFlags, hEvent);
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::ReleaseDC(TSurface* /*This*/, HDC hDC)
{
return SurfaceImpl::ReleaseDC(m_palettizedSurface, hDC);
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::Restore(TSurface* This)
{
HRESULT result = SurfaceImpl::Restore(m_palettizedSurface);
if (SUCCEEDED(result))
{
result = SurfaceImpl::Restore(This);
}
return result;
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::SetPalette(TSurface* /*This*/, LPDIRECTDRAWPALETTE lpDDPalette)
{
return SurfaceImpl::SetPalette(m_palettizedSurface, lpDDPalette);
}
template <typename TSurface>
HRESULT PalettizedTextureImpl<TSurface>::Unlock(TSurface* /*This*/, TUnlockParam lpRect)
{
return SurfaceImpl::Unlock(m_palettizedSurface, lpRect);
}
template PalettizedTextureImpl<IDirectDrawSurface>;
template PalettizedTextureImpl<IDirectDrawSurface2>;
template PalettizedTextureImpl<IDirectDrawSurface3>;
template PalettizedTextureImpl<IDirectDrawSurface4>;
template PalettizedTextureImpl<IDirectDrawSurface7>;
}

View File

@ -0,0 +1,42 @@
#pragma once
#include <ddraw.h>
#include <Common/CompatPtr.h>
#include <Common/CompatRef.h>
#include <Common/CompatVtable.h>
#include <DDraw/Surfaces/SurfaceImpl.h>
#include <DDraw/Types.h>
namespace DDraw
{
class PalettizedTexture;
template <typename TSurface>
class PalettizedTextureImpl : public SurfaceImpl<TSurface>
{
public:
PalettizedTextureImpl(PalettizedTexture& data, CompatPtr<TSurface> palettizedSurface);
virtual HRESULT Blt(TSurface* This, LPRECT lpDestRect, TSurface* lpDDSrcSurface, LPRECT lpSrcRect,
DWORD dwFlags, LPDDBLTFX lpDDBltFx) override;
virtual HRESULT BltFast(TSurface* This, DWORD dwX, DWORD dwY,
TSurface* lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) override;
virtual HRESULT GetCaps(TSurface* This, TDdsCaps* lpDDSCaps) override;
virtual HRESULT GetDC(TSurface* This, HDC* lphDC);
virtual HRESULT GetPalette(TSurface* This, LPDIRECTDRAWPALETTE* lplpDDPalette) override;
virtual HRESULT GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc) override;
virtual HRESULT Lock(TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
DWORD dwFlags, HANDLE hEvent) override;
virtual HRESULT ReleaseDC(TSurface* This, HDC hDC) override;
virtual HRESULT Restore(TSurface* This) override;
virtual HRESULT SetPalette(TSurface* This, LPDIRECTDRAWPALETTE lpDDPalette) override;
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect) override;
virtual TSurface* getBltSrc(TSurface* src) override;
private:
PalettizedTexture& m_data;
CompatPtr<TSurface> m_palettizedSurface;
};
}

View File

@ -79,8 +79,8 @@ namespace DDraw
if (SUCCEEDED(dds->SetPrivateData(&dds, IID_CompatSurfacePrivateData,
privateData.get(), sizeof(privateData.get()), DDSPD_IUNKNOWNPOINTER)))
{
privateData->createImpl();
privateData->m_surface = &dds;
privateData->createImpl();
privateData.release();
}
}

View File

@ -45,6 +45,12 @@ namespace
return bltFunc(This, lpDDSrcSurface, lpSrcRect);
}
auto srcSurface = DDraw::Surface::getSurface(*lpDDSrcSurface);
if (srcSurface)
{
lpDDSrcSurface = srcSurface->getImpl<TSurface>()->getBltSrc(lpDDSrcSurface);
}
auto dstDesc = getDesc(This);
if (!(dstDesc.ddsCaps.dwCaps & DDSCAPS_3DDEVICE) || !(dstDesc.ddsCaps.dwCaps & DDSCAPS_VIDEOMEMORY))
{
@ -134,6 +140,12 @@ namespace DDraw
return getOrigVtable(This).Flip(This, lpDDSurfaceTargetOverride, dwFlags);
}
template <typename TSurface>
TSurface* SurfaceImpl<TSurface>::getBltSrc(TSurface* src)
{
return src;
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetCaps(TSurface* This, TDdsCaps* lpDDSCaps)
{
@ -158,6 +170,12 @@ namespace DDraw
return result;
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetPalette(TSurface* This, LPDIRECTDRAWPALETTE* lplpDDPalette)
{
return getOrigVtable(This).GetPalette(This, lplpDDPalette);
}
template <typename TSurface>
HRESULT SurfaceImpl<TSurface>::GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc)
{

View File

@ -31,6 +31,7 @@ namespace DDraw
virtual HRESULT Flip(TSurface* This, TSurface* lpDDSurfaceTargetOverride, DWORD dwFlags);
virtual HRESULT GetCaps(TSurface* This, TDdsCaps* lpDDSCaps);
virtual HRESULT GetDC(TSurface* This, HDC* lphDC);
virtual HRESULT GetPalette(TSurface* This, LPDIRECTDRAWPALETTE* lplpDDPalette);
virtual HRESULT GetSurfaceDesc(TSurface* This, TSurfaceDesc* lpDDSurfaceDesc);
virtual HRESULT IsLost(TSurface* This);
virtual HRESULT Lock(TSurface* This, LPRECT lpDestRect, TSurfaceDesc* lpDDSurfaceDesc,
@ -43,6 +44,8 @@ namespace DDraw
virtual HRESULT SetSurfaceDesc(TSurface* This, TSurfaceDesc* lpddsd, DWORD dwFlags);
virtual HRESULT Unlock(TSurface* This, TUnlockParam lpRect);
virtual TSurface* getBltSrc(TSurface* src);
protected:
Surface* m_data;

View File

@ -176,6 +176,7 @@
<ClInclude Include="Config\Settings\FpsLimiter.h" />
<ClInclude Include="Config\Settings\FullscreenMode.h" />
<ClInclude Include="Config\Settings\LogLevel.h" />
<ClInclude Include="Config\Settings\PalettizedTextures.h" />
<ClInclude Include="Config\Settings\RemoveBorders.h" />
<ClInclude Include="Config\Settings\RenderColorDepth.h" />
<ClInclude Include="Config\Settings\ResolutionScale.h" />
@ -224,6 +225,8 @@
<ClInclude Include="DDraw\Hooks.h" />
<ClInclude Include="DDraw\Log.h" />
<ClInclude Include="DDraw\ScopedThreadLock.h" />
<ClInclude Include="DDraw\Surfaces\PalettizedTexture.h" />
<ClInclude Include="DDraw\Surfaces\PalettizedTextureImpl.h" />
<ClInclude Include="DDraw\Surfaces\PrimarySurface.h" />
<ClInclude Include="DDraw\Surfaces\PrimarySurfaceImpl.h" />
<ClInclude Include="DDraw\Surfaces\Surface.h" />
@ -352,6 +355,8 @@
<ClCompile Include="DDraw\IReleaseNotifier.cpp" />
<ClCompile Include="DDraw\Log.cpp" />
<ClCompile Include="DDraw\RealPrimarySurface.cpp" />
<ClCompile Include="DDraw\Surfaces\PalettizedTexture.cpp" />
<ClCompile Include="DDraw\Surfaces\PalettizedTextureImpl.cpp" />
<ClCompile Include="DDraw\Surfaces\PrimarySurface.cpp" />
<ClCompile Include="DDraw\Surfaces\PrimarySurfaceImpl.cpp" />
<ClCompile Include="DDraw\Surfaces\Surface.cpp" />
@ -437,4 +442,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View File

@ -588,6 +588,15 @@
<ClInclude Include="Win32\Winmm.h">
<Filter>Header Files\Win32</Filter>
</ClInclude>
<ClInclude Include="DDraw\Surfaces\PalettizedTexture.h">
<Filter>Header Files\DDraw\Surfaces</Filter>
</ClInclude>
<ClInclude Include="DDraw\Surfaces\PalettizedTextureImpl.h">
<Filter>Header Files\DDraw\Surfaces</Filter>
</ClInclude>
<ClInclude Include="Config\Settings\PalettizedTextures.h">
<Filter>Header Files\Config\Settings</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Gdi\Gdi.cpp">
@ -923,6 +932,12 @@
<ClCompile Include="Win32\Winmm.cpp">
<Filter>Source Files\Win32</Filter>
</ClCompile>
<ClCompile Include="DDraw\Surfaces\PalettizedTexture.cpp">
<Filter>Source Files\DDraw\Surfaces</Filter>
</ClCompile>
<ClCompile Include="DDraw\Surfaces\PalettizedTextureImpl.cpp">
<Filter>Source Files\DDraw\Surfaces</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="DDrawCompat.rc">