mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
parent
329679b4e9
commit
537f79f453
@ -1317,18 +1317,46 @@ namespace D3dDdi
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
D3DDDIFORMAT format = D3DDDIFMT_X8R8G8B8;
|
||||||
|
COLORREF colorKey = 0;
|
||||||
|
BYTE alpha = 0;
|
||||||
|
DWORD flags = 0;
|
||||||
|
if (layeredWindow.dc)
|
||||||
|
{
|
||||||
|
colorKey = layeredWindow.colorKey;
|
||||||
|
alpha = layeredWindow.alpha;
|
||||||
|
if (CLR_INVALID != colorKey)
|
||||||
|
{
|
||||||
|
flags |= ULW_COLORKEY;
|
||||||
|
}
|
||||||
|
if (255 != alpha)
|
||||||
|
{
|
||||||
|
flags |= ULW_ALPHA;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layeredWindow.alphaFormat & AC_SRC_ALPHA)
|
||||||
|
{
|
||||||
|
format = D3DDDIFMT_A8R8G8B8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetLayeredWindowAttributes(layeredWindow.hwnd, &colorKey, &alpha, &flags);
|
||||||
|
}
|
||||||
|
|
||||||
RECT srcRect = { 0, 0, visibleRect.right - visibleRect.left + 1, visibleRect.bottom - visibleRect.top + 1 };
|
RECT srcRect = { 0, 0, visibleRect.right - visibleRect.left + 1, visibleRect.bottom - visibleRect.top + 1 };
|
||||||
auto& windowSurface = repo.getTempSysMemSurface(srcRect.right, srcRect.bottom);
|
auto& windowSurface = repo.getTempSysMemSurface(srcRect.right, srcRect.bottom);
|
||||||
auto& texture = repo.getTempTexture(srcRect.right, srcRect.bottom, D3DDDIFMT_A8R8G8B8);
|
auto& texture = repo.getTempTexture(srcRect.right, srcRect.bottom, format);
|
||||||
if (!windowSurface.resource || !texture.resource)
|
if (!windowSurface.resource || !texture.resource)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
HDC srcDc = GetWindowDC(layeredWindow.hwnd);
|
HDC srcDc = layeredWindow.dc ? layeredWindow.dc : GetWindowDC(layeredWindow.hwnd);
|
||||||
HDC dstDc = nullptr;
|
HDC dstDc = nullptr;
|
||||||
POINT srcOrig = { visibleRect.left - layeredWindow.rect.left, visibleRect.top - layeredWindow.rect.top };
|
POINT srcOrig = { visibleRect.left - layeredWindow.rect.left, visibleRect.top - layeredWindow.rect.top };
|
||||||
windowSurface.surface->GetDC(windowSurface.surface, &dstDc);
|
windowSurface.surface->GetDC(windowSurface.surface, &dstDc);
|
||||||
|
|
||||||
CALL_ORIG_FUNC(BitBlt)(dstDc, 0, 0, srcRect.right - 1, srcRect.bottom - 1,
|
CALL_ORIG_FUNC(BitBlt)(dstDc, 0, 0, srcRect.right - 1, srcRect.bottom - 1,
|
||||||
srcDc, srcOrig.x, srcOrig.y, SRCCOPY);
|
srcDc, srcOrig.x, srcOrig.y, SRCCOPY);
|
||||||
CALL_ORIG_FUNC(BitBlt)(dstDc, srcRect.right - 1, 0, 1, srcRect.bottom - 1,
|
CALL_ORIG_FUNC(BitBlt)(dstDc, srcRect.right - 1, 0, 1, srcRect.bottom - 1,
|
||||||
@ -1337,16 +1365,16 @@ namespace D3dDdi
|
|||||||
srcDc, srcOrig.x, srcOrig.y + srcRect.bottom - 2, SRCCOPY);
|
srcDc, srcOrig.x, srcOrig.y + srcRect.bottom - 2, SRCCOPY);
|
||||||
CALL_ORIG_FUNC(BitBlt)(dstDc, srcRect.right - 1, srcRect.bottom - 1, 1, 1,
|
CALL_ORIG_FUNC(BitBlt)(dstDc, srcRect.right - 1, srcRect.bottom - 1, 1, 1,
|
||||||
srcDc, srcOrig.x + srcRect.right - 2, srcOrig.y + srcRect.bottom - 2, SRCCOPY);
|
srcDc, srcOrig.x + srcRect.right - 2, srcOrig.y + srcRect.bottom - 2, SRCCOPY);
|
||||||
|
|
||||||
windowSurface.surface->ReleaseDC(windowSurface.surface, dstDc);
|
windowSurface.surface->ReleaseDC(windowSurface.surface, dstDc);
|
||||||
ReleaseDC(layeredWindow.hwnd, srcDc);
|
if (!layeredWindow.dc)
|
||||||
|
{
|
||||||
|
ReleaseDC(layeredWindow.hwnd, srcDc);
|
||||||
|
}
|
||||||
|
|
||||||
copySubResourceRegion(*texture.resource, 0, srcRect, *windowSurface.resource, 0, srcRect);
|
copySubResourceRegion(*texture.resource, 0, srcRect, *windowSurface.resource, 0, srcRect);
|
||||||
windowSurface.resource->notifyLock(0);
|
windowSurface.resource->notifyLock(0);
|
||||||
|
|
||||||
COLORREF colorKey = 0;
|
|
||||||
BYTE alpha = 0;
|
|
||||||
DWORD flags = 0;
|
|
||||||
GetLayeredWindowAttributes(layeredWindow.hwnd, &colorKey, &alpha, &flags);
|
|
||||||
const ShaderBlitter::ColorKeyInfo ck = { colorKey,
|
const ShaderBlitter::ColorKeyInfo ck = { colorKey,
|
||||||
(flags & ULW_COLORKEY) ? D3DDDIFMT_A8R8G8B8 : D3DDDIFMT_UNKNOWN };
|
(flags & ULW_COLORKEY) ? D3DDDIFMT_A8R8G8B8 : D3DDDIFMT_UNKNOWN };
|
||||||
|
|
||||||
@ -1359,9 +1387,17 @@ namespace D3dDdi
|
|||||||
|
|
||||||
srcRect.right--;
|
srcRect.right--;
|
||||||
srcRect.bottom--;
|
srcRect.bottom--;
|
||||||
blitter.textureBlt(dst, dstSubResourceIndex, visibleRect, *texture.resource, 0, srcRect,
|
if (layeredWindow.dc)
|
||||||
D3DTEXF_LINEAR | D3DTEXF_SRGB, ck, (flags & ULW_ALPHA) ? &alpha : nullptr,
|
{
|
||||||
layeredWindow.region);
|
blitter.alphaBlendBlt(dst, dstSubResourceIndex, visibleRect, *texture.resource, 0, srcRect,
|
||||||
|
ck, (flags & ULW_ALPHA) ? alpha : 255, layeredWindow.region);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
blitter.textureBlt(dst, dstSubResourceIndex, visibleRect, *texture.resource, 0, srcRect,
|
||||||
|
D3DTEXF_LINEAR | D3DTEXF_SRGB, ck, (flags & ULW_ALPHA) ? &alpha : nullptr,
|
||||||
|
layeredWindow.region);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
#include <Config/Settings/DisplayFilter.h>
|
#include <Config/Settings/DisplayFilter.h>
|
||||||
#include <D3dDdi/Adapter.h>
|
#include <D3dDdi/Adapter.h>
|
||||||
#include <D3dDdi/Device.h>
|
#include <D3dDdi/Device.h>
|
||||||
|
#include <D3dDdi/Log/CommonLog.h>
|
||||||
#include <D3dDdi/Resource.h>
|
#include <D3dDdi/Resource.h>
|
||||||
#include <D3dDdi/ShaderBlitter.h>
|
#include <D3dDdi/ShaderBlitter.h>
|
||||||
#include <D3dDdi/SurfaceRepository.h>
|
#include <D3dDdi/SurfaceRepository.h>
|
||||||
#include <DDraw/Surfaces/PrimarySurface.h>
|
#include <DDraw/Surfaces/PrimarySurface.h>
|
||||||
|
#include <Shaders/AlphaBlend.h>
|
||||||
#include <Shaders/Bilinear.h>
|
#include <Shaders/Bilinear.h>
|
||||||
#include <Shaders/ColorKey.h>
|
#include <Shaders/ColorKey.h>
|
||||||
#include <Shaders/ColorKeyBlend.h>
|
#include <Shaders/ColorKeyBlend.h>
|
||||||
@ -29,7 +31,8 @@
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
const UINT BLT_SRCALPHA = 1;
|
const UINT BLT_SRCALPHA = 1;
|
||||||
const UINT BLT_COLORKEYTEST = 2;
|
const UINT BLT_PREMULTIPLIED = 2;
|
||||||
|
const UINT BLT_COLORKEYTEST = 4;
|
||||||
|
|
||||||
const UINT CF_HORIZONTAL = 1;
|
const UINT CF_HORIZONTAL = 1;
|
||||||
const UINT CF_GAMMARAMP = 2;
|
const UINT CF_GAMMARAMP = 2;
|
||||||
@ -41,6 +44,11 @@ namespace
|
|||||||
|
|
||||||
std::array<D3dDdi::DeviceState::ShaderConstF, 2> convertToShaderConst(D3dDdi::ShaderBlitter::ColorKeyInfo colorKeyInfo)
|
std::array<D3dDdi::DeviceState::ShaderConstF, 2> convertToShaderConst(D3dDdi::ShaderBlitter::ColorKeyInfo colorKeyInfo)
|
||||||
{
|
{
|
||||||
|
if (D3DDDIFMT_UNKNOWN == colorKeyInfo.format)
|
||||||
|
{
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
const auto& fi = D3dDdi::getFormatInfo(colorKeyInfo.format);
|
const auto& fi = D3dDdi::getFormatInfo(colorKeyInfo.format);
|
||||||
return { {
|
return { {
|
||||||
{
|
{
|
||||||
@ -78,8 +86,16 @@ namespace
|
|||||||
|
|
||||||
namespace D3dDdi
|
namespace D3dDdi
|
||||||
{
|
{
|
||||||
|
std::ostream& operator<<(std::ostream& os, ShaderBlitter::ColorKeyInfo ck)
|
||||||
|
{
|
||||||
|
return Compat::LogStruct(os)
|
||||||
|
<< Compat::hex(ck.colorKey)
|
||||||
|
<< ck.format;
|
||||||
|
}
|
||||||
|
|
||||||
ShaderBlitter::ShaderBlitter(Device& device)
|
ShaderBlitter::ShaderBlitter(Device& device)
|
||||||
: m_device(device)
|
: m_device(device)
|
||||||
|
, m_psAlphaBlend(createPixelShader(g_psAlphaBlend))
|
||||||
, m_psBilinear(createPixelShader(g_psBilinear))
|
, m_psBilinear(createPixelShader(g_psBilinear))
|
||||||
, m_psColorKey(createPixelShader(g_psColorKey))
|
, m_psColorKey(createPixelShader(g_psColorKey))
|
||||||
, m_psColorKeyBlend(createPixelShader(g_psColorKeyBlend))
|
, m_psColorKeyBlend(createPixelShader(g_psColorKeyBlend))
|
||||||
@ -106,6 +122,22 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShaderBlitter::alphaBlendBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||||
|
ColorKeyInfo srcColorKey, BYTE alpha, const Gdi::Region& srcRgn)
|
||||||
|
{
|
||||||
|
LOG_FUNC("ShaderBlitter::alphaBlendBlt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||||
|
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect,
|
||||||
|
srcColorKey, static_cast<UINT>(alpha), static_cast<HRGN>(srcRgn));
|
||||||
|
|
||||||
|
auto ck = convertToShaderConst(srcColorKey);
|
||||||
|
ck[0][3] = alpha / 255.0f;
|
||||||
|
DeviceState::TempPixelShaderConst psConst(m_device.getState(), { 30, 2 }, ck.data());
|
||||||
|
blt(dstResource, dstSubResourceIndex, dstRect,
|
||||||
|
srcResource, srcSubResourceIndex, srcRect,
|
||||||
|
m_psAlphaBlend.get(), D3DTEXF_LINEAR, BLT_SRCALPHA | BLT_PREMULTIPLIED, nullptr, srcRgn);
|
||||||
|
}
|
||||||
|
|
||||||
void ShaderBlitter::bicubicBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void ShaderBlitter::bicubicBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, UINT blurPercent)
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, UINT blurPercent)
|
||||||
{
|
{
|
||||||
@ -156,7 +188,7 @@ namespace D3dDdi
|
|||||||
HANDLE pixelShader, UINT filter, UINT flags, const BYTE* alpha, const Gdi::Region& srcRgn)
|
HANDLE pixelShader, UINT filter, UINT flags, const BYTE* alpha, const Gdi::Region& srcRgn)
|
||||||
{
|
{
|
||||||
LOG_FUNC("ShaderBlitter::blt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
LOG_FUNC("ShaderBlitter::blt", static_cast<HANDLE>(dstResource), dstSubResourceIndex, dstRect,
|
||||||
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect, pixelShader, filter,
|
static_cast<HANDLE>(srcResource), srcSubResourceIndex, srcRect, pixelShader, Compat::hex(filter),
|
||||||
Compat::hex(flags), alpha, static_cast<HRGN>(srcRgn));
|
Compat::hex(flags), alpha, static_cast<HRGN>(srcRgn));
|
||||||
|
|
||||||
if (!m_vertexShaderDecl || !pixelShader)
|
if (!m_vertexShaderDecl || !pixelShader)
|
||||||
@ -214,9 +246,10 @@ namespace D3dDdi
|
|||||||
}
|
}
|
||||||
else if (flags & BLT_SRCALPHA)
|
else if (flags & BLT_SRCALPHA)
|
||||||
{
|
{
|
||||||
|
const UINT D3DBLEND_ONE = 2;
|
||||||
const UINT D3DBLEND_SRCALPHA = 5;
|
const UINT D3DBLEND_SRCALPHA = 5;
|
||||||
const UINT D3DBLEND_INVSRCALPHA = 6;
|
const UINT D3DBLEND_INVSRCALPHA = 6;
|
||||||
state.setTempRenderState({ D3DDDIRS_SRCBLEND, D3DBLEND_SRCALPHA });
|
state.setTempRenderState({ D3DDDIRS_SRCBLEND, (flags & BLT_PREMULTIPLIED) ? D3DBLEND_ONE : D3DBLEND_SRCALPHA });
|
||||||
state.setTempRenderState({ D3DDDIRS_DESTBLEND, D3DBLEND_INVSRCALPHA });
|
state.setTempRenderState({ D3DDDIRS_DESTBLEND, D3DBLEND_INVSRCALPHA });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +31,9 @@ namespace D3dDdi
|
|||||||
ShaderBlitter& operator=(const ShaderBlitter&) = delete;
|
ShaderBlitter& operator=(const ShaderBlitter&) = delete;
|
||||||
ShaderBlitter& operator=(ShaderBlitter&&) = delete;
|
ShaderBlitter& operator=(ShaderBlitter&&) = delete;
|
||||||
|
|
||||||
|
void alphaBlendBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect,
|
||||||
|
ColorKeyInfo srcColorKey, BYTE alpha, const Gdi::Region& srcRgn);
|
||||||
void bilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void bilinearBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, UINT blurPercent);
|
const Resource& srcResource, UINT srcSubResourceIndex, const RECT& srcRect, UINT blurPercent);
|
||||||
void bicubicBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
void bicubicBlt(const Resource& dstResource, UINT dstSubResourceIndex, const RECT& dstRect,
|
||||||
@ -117,6 +120,7 @@ namespace D3dDdi
|
|||||||
void setTextureCoords(UINT stage, const RECT& rect, UINT width, UINT height);
|
void setTextureCoords(UINT stage, const RECT& rect, UINT width, UINT height);
|
||||||
|
|
||||||
Device& m_device;
|
Device& m_device;
|
||||||
|
std::unique_ptr<void, ResourceDeleter> m_psAlphaBlend;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psBilinear;
|
std::unique_ptr<void, ResourceDeleter> m_psBilinear;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psColorKey;
|
std::unique_ptr<void, ResourceDeleter> m_psColorKey;
|
||||||
std::unique_ptr<void, ResourceDeleter> m_psColorKeyBlend;
|
std::unique_ptr<void, ResourceDeleter> m_psColorKeyBlend;
|
||||||
@ -134,4 +138,6 @@ namespace D3dDdi
|
|||||||
ConvolutionParams m_convolutionParams;
|
ConvolutionParams m_convolutionParams;
|
||||||
std::array<Vertex, 4> m_vertices;
|
std::array<Vertex, 4> m_vertices;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, ShaderBlitter::ColorKeyInfo ck);
|
||||||
}
|
}
|
||||||
|
@ -478,6 +478,7 @@
|
|||||||
<None Include="Shaders\CubicConvolution.hlsli" />
|
<None Include="Shaders\CubicConvolution.hlsli" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<FxCompile Include="Shaders\AlphaBlend.hlsl" />
|
||||||
<FxCompile Include="Shaders\Bilinear.hlsl" />
|
<FxCompile Include="Shaders\Bilinear.hlsl" />
|
||||||
<FxCompile Include="Shaders\ColorKey.hlsl" />
|
<FxCompile Include="Shaders\ColorKey.hlsl" />
|
||||||
<FxCompile Include="Shaders\ColorKeyBlend.hlsl" />
|
<FxCompile Include="Shaders\ColorKeyBlend.hlsl" />
|
||||||
|
@ -1169,6 +1169,9 @@
|
|||||||
<FxCompile Include="Shaders\PointNoFilter.hlsl">
|
<FxCompile Include="Shaders\PointNoFilter.hlsl">
|
||||||
<Filter>Shaders</Filter>
|
<Filter>Shaders</Filter>
|
||||||
</FxCompile>
|
</FxCompile>
|
||||||
|
<FxCompile Include="Shaders\AlphaBlend.hlsl">
|
||||||
|
<Filter>Shaders</Filter>
|
||||||
|
</FxCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Image Include="arrow.bmp">
|
<Image Include="arrow.bmp">
|
||||||
|
@ -40,6 +40,10 @@ namespace Gdi
|
|||||||
if (presentationWindow)
|
if (presentationWindow)
|
||||||
{
|
{
|
||||||
CALL_ORIG_FUNC(SetLayeredWindowAttributes)(presentationWindow, 0, 255, LWA_ALPHA);
|
CALL_ORIG_FUNC(SetLayeredWindowAttributes)(presentationWindow, 0, 255, LWA_ALPHA);
|
||||||
|
if (owner)
|
||||||
|
{
|
||||||
|
AttachThreadInput(GetCurrentThreadId(), GetWindowThreadProcessId(owner, nullptr), FALSE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return LOG_RESULT(presentationWindow);
|
return LOG_RESULT(presentationWindow);
|
||||||
|
@ -755,6 +755,36 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI updateLayeredWindow(HWND hWnd, HDC hdcDst, POINT* pptDst, SIZE* psize,
|
||||||
|
HDC hdcSrc, POINT* pptSrc, COLORREF crKey, BLENDFUNCTION* pblend, DWORD dwFlags)
|
||||||
|
{
|
||||||
|
LOG_FUNC("UpdateLayeredWindow", hWnd, hdcDst, pptDst, psize, hdcSrc, pptSrc, crKey, pblend, dwFlags);
|
||||||
|
BOOL result = CALL_ORIG_FUNC(UpdateLayeredWindow)(
|
||||||
|
hWnd, hdcDst, pptDst, psize, hdcSrc, pptSrc, crKey, pblend, dwFlags);
|
||||||
|
if (result)
|
||||||
|
{
|
||||||
|
Gdi::Window::updateLayeredWindowInfo(hWnd, hdcSrc, pptSrc,
|
||||||
|
(dwFlags & ULW_COLORKEY) ? crKey : CLR_INVALID,
|
||||||
|
((dwFlags & ULW_ALPHA) && pblend) ? pblend->SourceConstantAlpha : 255,
|
||||||
|
pblend ? pblend->AlphaFormat : 0);
|
||||||
|
}
|
||||||
|
return LOG_RESULT(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL WINAPI updateLayeredWindowIndirect(HWND hwnd, const UPDATELAYEREDWINDOWINFO* pULWInfo)
|
||||||
|
{
|
||||||
|
LOG_FUNC("UpdateLayeredWindowIndirect", hwnd, pULWInfo);
|
||||||
|
BOOL result = CALL_ORIG_FUNC(UpdateLayeredWindowIndirect)(hwnd, pULWInfo);
|
||||||
|
if (result && pULWInfo)
|
||||||
|
{
|
||||||
|
Gdi::Window::updateLayeredWindowInfo(hwnd, pULWInfo->hdcSrc, pULWInfo->pptSrc,
|
||||||
|
(pULWInfo->dwFlags & ULW_COLORKEY) ? pULWInfo->crKey : CLR_INVALID,
|
||||||
|
((pULWInfo->dwFlags & ULW_ALPHA) && pULWInfo->pblend) ? pULWInfo->pblend->SourceConstantAlpha : 255,
|
||||||
|
pULWInfo->pblend ? pULWInfo->pblend->AlphaFormat : 0);
|
||||||
|
}
|
||||||
|
return LOG_RESULT(result);
|
||||||
|
}
|
||||||
|
|
||||||
void CALLBACK winEventProc(
|
void CALLBACK winEventProc(
|
||||||
HWINEVENTHOOK /*hWinEventHook*/,
|
HWINEVENTHOOK /*hWinEventHook*/,
|
||||||
DWORD event,
|
DWORD event,
|
||||||
@ -880,6 +910,8 @@ namespace Gdi
|
|||||||
HOOK_FUNCTION(user32, SetWindowLongA, setWindowLongA);
|
HOOK_FUNCTION(user32, SetWindowLongA, setWindowLongA);
|
||||||
HOOK_FUNCTION(user32, SetWindowLongW, setWindowLongW);
|
HOOK_FUNCTION(user32, SetWindowLongW, setWindowLongW);
|
||||||
HOOK_FUNCTION(user32, SetWindowPos, setWindowPos);
|
HOOK_FUNCTION(user32, SetWindowPos, setWindowPos);
|
||||||
|
HOOK_FUNCTION(user32, UpdateLayeredWindow, updateLayeredWindow);
|
||||||
|
HOOK_FUNCTION(user32, UpdateLayeredWindowIndirect, updateLayeredWindowIndirect);
|
||||||
|
|
||||||
g_dwmSetIconicThumbnail = reinterpret_cast<decltype(&DwmSetIconicThumbnail)>(
|
g_dwmSetIconicThumbnail = reinterpret_cast<decltype(&DwmSetIconicThumbnail)>(
|
||||||
GetProcAddress(GetModuleHandle("dwmapi"), "DwmSetIconicThumbnail"));
|
GetProcAddress(GetModuleHandle("dwmapi"), "DwmSetIconicThumbnail"));
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
|
|
||||||
#include <Common/Log.h>
|
#include <Common/Log.h>
|
||||||
|
#include <Common/Rect.h>
|
||||||
#include <D3dDdi/KernelModeThunks.h>
|
#include <D3dDdi/KernelModeThunks.h>
|
||||||
#include <D3dDdi/ScopedCriticalSection.h>
|
#include <D3dDdi/ScopedCriticalSection.h>
|
||||||
#include <DDraw/RealPrimarySurface.h>
|
#include <DDraw/RealPrimarySurface.h>
|
||||||
@ -23,6 +24,74 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
class LayeredWindowContent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
~LayeredWindowContent()
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE getAlpha() const { return m_alpha; }
|
||||||
|
BYTE getAlphaFormat() const { return m_alphaFormat; }
|
||||||
|
COLORREF getColorKey() const { return m_colorKey; }
|
||||||
|
HDC getDc() const { return m_dc; }
|
||||||
|
|
||||||
|
void set(HWND hwnd, HDC hdcSrc, const POINT* pptSrc, COLORREF colorKey, BYTE alpha, BYTE alphaFormat)
|
||||||
|
{
|
||||||
|
if (hdcSrc)
|
||||||
|
{
|
||||||
|
RECT wr = {};
|
||||||
|
GetWindowRect(hwnd, &wr);
|
||||||
|
const SIZE size = Rect::getSize(wr);
|
||||||
|
|
||||||
|
if (size != m_size)
|
||||||
|
{
|
||||||
|
destroy();
|
||||||
|
m_size = size;
|
||||||
|
m_dc = CreateCompatibleDC(nullptr);
|
||||||
|
m_origBmp = SelectObject(m_dc, CALL_ORIG_FUNC(CreateBitmap)(size.cx, size.cy, 1, 32, nullptr));
|
||||||
|
}
|
||||||
|
|
||||||
|
CALL_ORIG_FUNC(BitBlt)(m_dc, 0, 0, size.cx, size.cy,
|
||||||
|
hdcSrc, pptSrc ? pptSrc->x : 0, pptSrc ? pptSrc->y : 0, SRCCOPY);
|
||||||
|
|
||||||
|
if (alphaFormat & AC_SRC_ALPHA)
|
||||||
|
{
|
||||||
|
BITMAP bm = {};
|
||||||
|
GetObject(GetCurrentObject(hdcSrc, OBJ_BITMAP), sizeof(bm), &bm);
|
||||||
|
if (32 != bm.bmBitsPixel)
|
||||||
|
{
|
||||||
|
alphaFormat &= ~AC_SRC_ALPHA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_colorKey = colorKey;
|
||||||
|
m_alpha = alpha;
|
||||||
|
m_alphaFormat = alphaFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void destroy()
|
||||||
|
{
|
||||||
|
if (m_dc)
|
||||||
|
{
|
||||||
|
DeleteObject(SelectObject(m_dc, m_origBmp));
|
||||||
|
DeleteDC(m_dc);
|
||||||
|
m_dc = nullptr;
|
||||||
|
m_origBmp = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HDC m_dc = nullptr;
|
||||||
|
HGDIOBJ m_origBmp = nullptr;
|
||||||
|
SIZE m_size = {};
|
||||||
|
COLORREF m_colorKey = CLR_INVALID;
|
||||||
|
BYTE m_alpha = 255;
|
||||||
|
BYTE m_alphaFormat = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct UpdateWindowContext
|
struct UpdateWindowContext
|
||||||
{
|
{
|
||||||
Gdi::Region obscuredRegion;
|
Gdi::Region obscuredRegion;
|
||||||
@ -39,6 +108,7 @@ namespace
|
|||||||
RECT clientRect;
|
RECT clientRect;
|
||||||
Gdi::Region visibleRegion;
|
Gdi::Region visibleRegion;
|
||||||
Gdi::Region invalidatedRegion;
|
Gdi::Region invalidatedRegion;
|
||||||
|
LayeredWindowContent layeredWindowContent;
|
||||||
bool isMenu;
|
bool isMenu;
|
||||||
bool isLayered;
|
bool isLayered;
|
||||||
bool isDpiAware;
|
bool isDpiAware;
|
||||||
@ -90,57 +160,6 @@ namespace
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void presentLayeredWindow(CompatWeakPtr<IDirectDrawSurface7> dst,
|
|
||||||
HWND hwnd, RECT wr, const RECT& monitorRect, HDC& dstDc, Gdi::Region* rgn = nullptr, bool isMenu = false)
|
|
||||||
{
|
|
||||||
if (!dst)
|
|
||||||
{
|
|
||||||
throw true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!dstDc)
|
|
||||||
{
|
|
||||||
dst->GetDC(dst, &dstDc);
|
|
||||||
if (!dstDc)
|
|
||||||
{
|
|
||||||
throw false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
OffsetRect(&wr, -monitorRect.left, -monitorRect.top);
|
|
||||||
if (rgn)
|
|
||||||
{
|
|
||||||
rgn->offset(-monitorRect.left, -monitorRect.top);
|
|
||||||
}
|
|
||||||
|
|
||||||
HDC windowDc = GetWindowDC(hwnd);
|
|
||||||
if (rgn)
|
|
||||||
{
|
|
||||||
SelectClipRgn(dstDc, *rgn);
|
|
||||||
}
|
|
||||||
|
|
||||||
COLORREF colorKey = 0;
|
|
||||||
BYTE alpha = 255;
|
|
||||||
DWORD flags = ULW_ALPHA;
|
|
||||||
if (isMenu || CALL_ORIG_FUNC(GetLayeredWindowAttributes)(hwnd, &colorKey, &alpha, &flags))
|
|
||||||
{
|
|
||||||
if (flags & LWA_COLORKEY)
|
|
||||||
{
|
|
||||||
CALL_ORIG_FUNC(TransparentBlt)(dstDc, wr.left, wr.top, wr.right - wr.left, wr.bottom - wr.top,
|
|
||||||
windowDc, 0, 0, wr.right - wr.left, wr.bottom - wr.top, colorKey);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BLENDFUNCTION blend = {};
|
|
||||||
blend.SourceConstantAlpha = alpha;
|
|
||||||
CALL_ORIG_FUNC(AlphaBlend)(dstDc, wr.left, wr.top, wr.right - wr.left, wr.bottom - wr.top,
|
|
||||||
windowDc, 0, 0, wr.right - wr.left, wr.bottom - wr.top, blend);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CALL_ORIG_FUNC(ReleaseDC)(hwnd, windowDc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void updatePosition(Window& window, const RECT& oldWindowRect, const RECT& oldClientRect,
|
void updatePosition(Window& window, const RECT& oldWindowRect, const RECT& oldClientRect,
|
||||||
const Gdi::Region& oldVisibleRegion, Gdi::Region& invalidatedRegion)
|
const Gdi::Region& oldVisibleRegion, Gdi::Region& invalidatedRegion)
|
||||||
{
|
{
|
||||||
@ -351,7 +370,14 @@ namespace Gdi
|
|||||||
auto& window = **it;
|
auto& window = **it;
|
||||||
if (window.isLayered && !window.visibleRegion.isEmpty())
|
if (window.isLayered && !window.visibleRegion.isEmpty())
|
||||||
{
|
{
|
||||||
layeredWindows.push_back({ window.hwnd, window.windowRect, window.visibleRegion });
|
layeredWindows.push_back({
|
||||||
|
window.hwnd,
|
||||||
|
window.windowRect,
|
||||||
|
window.visibleRegion,
|
||||||
|
window.layeredWindowContent.getDc(),
|
||||||
|
window.layeredWindowContent.getColorKey(),
|
||||||
|
window.layeredWindowContent.getAlpha(),
|
||||||
|
window.layeredWindowContent.getAlphaFormat() });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return layeredWindows;
|
return layeredWindows;
|
||||||
@ -640,6 +666,21 @@ namespace Gdi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateLayeredWindowInfo(HWND hwnd, HDC hdcSrc, const POINT* pptSrc,
|
||||||
|
COLORREF colorKey, BYTE alpha, BYTE alphaFormat)
|
||||||
|
{
|
||||||
|
D3dDdi::ScopedCriticalSection lock;
|
||||||
|
auto it = g_windows.find(hwnd);
|
||||||
|
if (it != g_windows.end())
|
||||||
|
{
|
||||||
|
it->second.layeredWindowContent.set(hwnd, hdcSrc, pptSrc, colorKey, alpha, alphaFormat);
|
||||||
|
if (DDraw::RealPrimarySurface::isFullscreen())
|
||||||
|
{
|
||||||
|
DDraw::RealPrimarySurface::scheduleOverlayUpdate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void updatePresentationWindowPos(HWND presentationWindow, HWND owner)
|
void updatePresentationWindowPos(HWND presentationWindow, HWND owner)
|
||||||
{
|
{
|
||||||
if (IsIconic(owner))
|
if (IsIconic(owner))
|
||||||
|
@ -15,6 +15,10 @@ namespace Gdi
|
|||||||
HWND hwnd;
|
HWND hwnd;
|
||||||
RECT rect;
|
RECT rect;
|
||||||
Gdi::Region region;
|
Gdi::Region region;
|
||||||
|
HDC dc;
|
||||||
|
COLORREF colorKey;
|
||||||
|
BYTE alpha;
|
||||||
|
BYTE alphaFormat;
|
||||||
};
|
};
|
||||||
|
|
||||||
HWND getPresentationWindow(HWND hwnd);
|
HWND getPresentationWindow(HWND hwnd);
|
||||||
@ -31,6 +35,8 @@ namespace Gdi
|
|||||||
void present(Gdi::Region excludeRegion);
|
void present(Gdi::Region excludeRegion);
|
||||||
void setDpiAwareness(HWND hwnd, bool dpiAware);
|
void setDpiAwareness(HWND hwnd, bool dpiAware);
|
||||||
void updateAll();
|
void updateAll();
|
||||||
|
void updateLayeredWindowInfo(HWND hwnd, HDC hdcSrc, const POINT* pptSrc,
|
||||||
|
COLORREF colorKey, BYTE alpha, BYTE alphaFormat);
|
||||||
void updatePresentationWindowPos(HWND presentationWindow, HWND owner);
|
void updatePresentationWindowPos(HWND presentationWindow, HWND owner);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
DDrawCompat/Shaders/AlphaBlend.hlsl
Normal file
10
DDrawCompat/Shaders/AlphaBlend.hlsl
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
sampler2D s_texture : register(s0);
|
||||||
|
float4 g_colorKey : register(c30);
|
||||||
|
float4 g_threshold : register(c31);
|
||||||
|
|
||||||
|
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
|
||||||
|
{
|
||||||
|
float4 color = tex2D(s_texture, texCoord);
|
||||||
|
const float4 diff = abs(color - g_colorKey);
|
||||||
|
return all(diff.rgb < g_threshold.rgb) ? 0 : (g_colorKey.a * color);
|
||||||
|
}
|
@ -134,6 +134,15 @@ std::ostream& operator<<(std::ostream& os, const BITMAPINFOHEADER& bmih)
|
|||||||
<< bmih.biClrImportant;
|
<< bmih.biClrImportant;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::ostream& operator<<(std::ostream& os, const BLENDFUNCTION& bf)
|
||||||
|
{
|
||||||
|
return Compat::LogStruct(os)
|
||||||
|
<< static_cast<UINT>(bf.BlendOp)
|
||||||
|
<< static_cast<UINT>(bf.BlendFlags)
|
||||||
|
<< static_cast<UINT>(bf.SourceConstantAlpha)
|
||||||
|
<< static_cast<UINT>(bf.AlphaFormat);
|
||||||
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, const COMPAREITEMSTRUCT& cis)
|
std::ostream& operator<<(std::ostream& os, const COMPAREITEMSTRUCT& cis)
|
||||||
{
|
{
|
||||||
return Compat::LogStruct(os)
|
return Compat::LogStruct(os)
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
std::ostream& operator<<(std::ostream& os, const BITMAP& bm);
|
std::ostream& operator<<(std::ostream& os, const BITMAP& bm);
|
||||||
std::ostream& operator<<(std::ostream& os, const BITMAPINFO& bmi);
|
std::ostream& operator<<(std::ostream& os, const BITMAPINFO& bmi);
|
||||||
std::ostream& operator<<(std::ostream& os, const BITMAPINFOHEADER& bmih);
|
std::ostream& operator<<(std::ostream& os, const BITMAPINFOHEADER& bmih);
|
||||||
|
std::ostream& operator<<(std::ostream& os, const BLENDFUNCTION& bf);
|
||||||
std::ostream& operator<<(std::ostream& os, const COMPAREITEMSTRUCT& cis);
|
std::ostream& operator<<(std::ostream& os, const COMPAREITEMSTRUCT& cis);
|
||||||
std::ostream& operator<<(std::ostream& os, const COPYDATASTRUCT& cds);
|
std::ostream& operator<<(std::ostream& os, const COPYDATASTRUCT& cds);
|
||||||
std::ostream& operator<<(std::ostream& os, const CREATESTRUCTA& cs);
|
std::ostream& operator<<(std::ostream& os, const CREATESTRUCTA& cs);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user