1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 14:52:11 +01:00

[d3d9] Fix software cursor reset and transitions

This commit is contained in:
WinterSnowfall 2024-10-08 20:55:52 +03:00 committed by Philip Rebohle
parent a30fdc466b
commit a1a3800b3f
3 changed files with 50 additions and 23 deletions

View File

@ -9,15 +9,22 @@ namespace dxvk {
void D3D9Cursor::ResetCursor() {
ShowCursor(FALSE);
if (likely(m_hCursor != nullptr)) {
::DestroyCursor(m_hCursor);
m_hCursor = nullptr;
} else {
m_sCursor.Width = 0;
m_sCursor.Height = 0;
m_sCursor.X = 0;
m_sCursor.Y = 0;
}
if (m_hCursor != nullptr)
ResetHardwareCursor();
else
ResetSoftwareCursor();
}
void D3D9Cursor::ResetHardwareCursor() {
::DestroyCursor(m_hCursor);
m_hCursor = nullptr;
}
void D3D9Cursor::ResetSoftwareCursor() {
m_sCursor.DrawCursor = false;
m_sCursor.ResetCursor = true;
}
@ -44,20 +51,18 @@ namespace dxvk {
if (unlikely(m_hCursor == nullptr && m_sCursor.Width == 0 && m_sCursor.Height == 0))
return m_visible;
if (likely(m_hCursor != nullptr))
if (m_hCursor != nullptr)
::SetCursor(bShow ? m_hCursor : nullptr);
else
m_sCursor.DrawCursor = bShow;
return std::exchange(m_visible, bShow);
}
HRESULT D3D9Cursor::SetHardwareCursor(UINT XHotSpot, UINT YHotSpot, const CursorBitmap& bitmap) {
if (unlikely(IsSoftwareCursor())) {
m_sCursor.Width = 0;
m_sCursor.Height = 0;
m_sCursor.X = 0;
m_sCursor.Y = 0;
}
if (IsSoftwareCursor())
ResetSoftwareCursor();
CursorMask mask;
std::memset(mask, ~0, sizeof(mask));
@ -87,10 +92,8 @@ namespace dxvk {
// Make sure to hide the win32 cursor
::SetCursor(nullptr);
if (unlikely(m_hCursor != nullptr)) {
::DestroyCursor(m_hCursor);
m_hCursor = nullptr;
}
if (m_hCursor != nullptr)
ResetHardwareCursor();
m_sCursor.Width = Width;
m_sCursor.Height = Height;
@ -107,6 +110,13 @@ namespace dxvk {
Logger::warn("D3D9Cursor::ResetCursor: Not supported on current platform.");
}
void D3D9Cursor::ResetHardwareCursor() {
Logger::warn("D3D9Cursor::ResetHardwareCursor: Not supported on current platform.");
}
void D3D9Cursor::ResetSoftwareCursor() {
Logger::warn("D3D9Cursor::ResetSoftwareCursor: Not supported on current platform.");
}
void D3D9Cursor::UpdateCursor(int X, int Y) {
Logger::warn("D3D9Cursor::UpdateCursor: Not supported on current platform.");

View File

@ -8,10 +8,12 @@ namespace dxvk {
* \brief D3D9 Software Cursor
*/
struct D3D9_SOFTWARE_CURSOR {
UINT Width = 0;
UINT Width = 0;
UINT Height = 0;
UINT X = 0;
UINT Y = 0;
bool DrawCursor = false;
bool ResetCursor = false;
};
constexpr uint32_t HardwareCursorWidth = 32u;
@ -37,6 +39,10 @@ namespace dxvk {
void ResetCursor();
void ResetHardwareCursor();
void ResetSoftwareCursor();
void UpdateCursor(int X, int Y);
void RefreshSoftwareCursorPosition();

View File

@ -3917,11 +3917,22 @@ namespace dxvk {
D3D9_SOFTWARE_CURSOR* pSoftwareCursor = m_cursor.GetSoftwareCursor();
UINT cursorWidth = m_cursor.IsCursorVisible() ? pSoftwareCursor->Width : 0;
UINT cursorHeight = m_cursor.IsCursorVisible() ? pSoftwareCursor->Height : 0;
UINT cursorWidth = pSoftwareCursor->DrawCursor ? pSoftwareCursor->Width : 0;
UINT cursorHeight = pSoftwareCursor->DrawCursor ? pSoftwareCursor->Height : 0;
m_implicitSwapchain->SetCursorPosition(pSoftwareCursor->X, pSoftwareCursor->Y,
cursorWidth, cursorHeight);
// Once a hardware cursor has been set or the device has been reset,
// we need to ensure that we render a 0-sized rectangle first, and
// only then fully clear the software cursor.
if (unlikely(pSoftwareCursor->ResetCursor)) {
pSoftwareCursor->Width = 0;
pSoftwareCursor->Height = 0;
pSoftwareCursor->X = 0;
pSoftwareCursor->Y = 0;
pSoftwareCursor->ResetCursor = false;
}
}
return m_implicitSwapchain->Present(