mirror of https://github.com/doitsujin/dxvk
[d3d9] Add a software cursor emulation config option
This commit is contained in:
parent
037d0fa1ad
commit
1299ad050f
11
dxvk.conf
11
dxvk.conf
|
@ -625,6 +625,17 @@
|
|||
|
||||
# d3d9.seamlessCubes = False
|
||||
|
||||
# Software Cursor Emulation
|
||||
#
|
||||
# Will atempt to emulate a software cursor by using a hardware cursor. This is useful
|
||||
# for applications that rely on d3d9 API calls to create the cursor and potentially use
|
||||
# bitmap sizes in excess of 32 x 32.
|
||||
#
|
||||
# Supported values:
|
||||
# - True/False
|
||||
|
||||
# d3d9.softwareCursorEmulation = False
|
||||
|
||||
# Debug Utils
|
||||
#
|
||||
# Enables debug utils as this is off by default, this enables user annotations like BeginEvent()/EndEvent().
|
||||
|
|
|
@ -25,25 +25,53 @@ namespace dxvk {
|
|||
}
|
||||
|
||||
|
||||
HRESULT D3D9Cursor::SetHardwareCursor(UINT XHotSpot, UINT YHotSpot, const CursorBitmap& bitmap) {
|
||||
DWORD mask[32];
|
||||
std::memset(mask, ~0, sizeof(mask));
|
||||
HRESULT D3D9Cursor::SetHardwareCursor(
|
||||
UINT XHotSpot,
|
||||
UINT YHotSpot,
|
||||
const std::vector<uint8_t>& bitmap,
|
||||
bool cursorEmulation,
|
||||
UINT width,
|
||||
UINT height,
|
||||
HWND window) {
|
||||
bool noPreviousHardwareCursor = false;
|
||||
|
||||
uint32_t cursorWidth = cursorEmulation ? width : HardwareCursorWidth;
|
||||
uint32_t cursorHeight = cursorEmulation ? height : HardwareCursorHeight;
|
||||
|
||||
// For color icons, the hbmMask and hbmColor bitmaps
|
||||
// are the same size, each of which is the size of the icon.
|
||||
std::vector<DWORD> mask(cursorWidth * cursorHeight, ~0);
|
||||
|
||||
ICONINFO info;
|
||||
info.fIcon = FALSE;
|
||||
info.xHotspot = XHotSpot;
|
||||
info.yHotspot = YHotSpot;
|
||||
info.hbmMask = ::CreateBitmap(HardwareCursorWidth, HardwareCursorHeight, 1, 1, mask);
|
||||
info.hbmColor = ::CreateBitmap(HardwareCursorWidth, HardwareCursorHeight, 1, 32, &bitmap[0]);
|
||||
info.hbmMask = ::CreateBitmap(cursorWidth, cursorHeight, 1, 1, &mask[0]);
|
||||
info.hbmColor = ::CreateBitmap(cursorWidth, cursorHeight, 1, 32, &bitmap[0]);
|
||||
|
||||
if (m_hCursor != nullptr)
|
||||
::DestroyCursor(m_hCursor);
|
||||
else
|
||||
noPreviousHardwareCursor = true;
|
||||
|
||||
m_hCursor = ::CreateIconIndirect(&info);
|
||||
|
||||
::DeleteObject(info.hbmMask);
|
||||
::DeleteObject(info.hbmColor);
|
||||
|
||||
if (cursorEmulation) {
|
||||
::SetClassLongPtr(window, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(m_hCursor));
|
||||
|
||||
CURSORINFO ci;
|
||||
while (::GetCursorInfo(&ci) && ci.flags == 0u)
|
||||
::ShowCursor(TRUE);
|
||||
|
||||
// Castle Strike needs one extra initial increment
|
||||
// to display the emulated cursor on its menu
|
||||
if (noPreviousHardwareCursor)
|
||||
::ShowCursor(TRUE);
|
||||
}
|
||||
|
||||
ShowCursor(m_visible);
|
||||
|
||||
return D3D_OK;
|
||||
|
@ -60,7 +88,14 @@ namespace dxvk {
|
|||
}
|
||||
|
||||
|
||||
HRESULT D3D9Cursor::SetHardwareCursor(UINT XHotSpot, UINT YHotSpot, const CursorBitmap& bitmap) {
|
||||
HRESULT D3D9Cursor::SetHardwareCursor(
|
||||
UINT XHotSpot,
|
||||
UINT YHotSpot,
|
||||
const std::vector<uint8_t>& bitmap,
|
||||
bool cursorEmulation,
|
||||
UINT width,
|
||||
UINT height,
|
||||
HWND window) {
|
||||
Logger::warn("D3D9Cursor::SetHardwareCursor: Not supported on current platform.");
|
||||
|
||||
return D3D_OK;
|
||||
|
|
|
@ -9,9 +9,6 @@ namespace dxvk {
|
|||
constexpr uint32_t HardwareCursorFormatSize = 4u;
|
||||
constexpr uint32_t HardwareCursorPitch = HardwareCursorWidth * HardwareCursorFormatSize;
|
||||
|
||||
// Format Size of 4 bytes (ARGB)
|
||||
using CursorBitmap = uint8_t[HardwareCursorHeight * HardwareCursorPitch];
|
||||
|
||||
class D3D9Cursor {
|
||||
|
||||
public:
|
||||
|
@ -20,7 +17,14 @@ namespace dxvk {
|
|||
|
||||
BOOL ShowCursor(BOOL bShow);
|
||||
|
||||
HRESULT SetHardwareCursor(UINT XHotSpot, UINT YHotSpot, const CursorBitmap& bitmap);
|
||||
HRESULT SetHardwareCursor(
|
||||
UINT XHotSpot,
|
||||
UINT YHotSpot,
|
||||
const std::vector<uint8_t>& bitmap,
|
||||
bool cursorEmulation,
|
||||
UINT width,
|
||||
UINT height,
|
||||
HWND window);
|
||||
|
||||
private:
|
||||
|
||||
|
|
|
@ -345,7 +345,7 @@ namespace dxvk {
|
|||
// Always use a hardware cursor when windowed.
|
||||
D3DPRESENT_PARAMETERS params;
|
||||
m_implicitSwapchain->GetPresentParameters(¶ms);
|
||||
bool hwCursor = params.Windowed;
|
||||
bool hwCursor = params.Windowed || m_d3d9Options.softwareCursorEmulation;
|
||||
|
||||
// Always use a hardware cursor w/h <= 32 px
|
||||
hwCursor |= inputWidth <= HardwareCursorWidth
|
||||
|
@ -359,20 +359,32 @@ namespace dxvk {
|
|||
|
||||
const uint8_t* data = reinterpret_cast<const uint8_t*>(lockedBox.pBits);
|
||||
|
||||
uint32_t emulatedCursorPitch = inputWidth * HardwareCursorFormatSize;
|
||||
|
||||
uint32_t cursorHeight = m_d3d9Options.softwareCursorEmulation ? inputHeight : HardwareCursorHeight;
|
||||
uint32_t cursorPitch = m_d3d9Options.softwareCursorEmulation ? emulatedCursorPitch : HardwareCursorPitch;
|
||||
|
||||
// Windows works with a stride of 128, lets respect that.
|
||||
// Copy data to the bitmap...
|
||||
CursorBitmap bitmap = { 0 };
|
||||
// Format Size of 4 bytes (ARGB)
|
||||
std::vector<uint8_t> bitmap(cursorHeight * cursorPitch, 0);
|
||||
size_t copyPitch = std::min<size_t>(
|
||||
HardwareCursorPitch,
|
||||
cursorPitch,
|
||||
inputWidth * inputHeight * HardwareCursorFormatSize);
|
||||
|
||||
for (uint32_t h = 0; h < HardwareCursorHeight; h++)
|
||||
std::memcpy(&bitmap[h * HardwareCursorPitch], &data[h * lockedBox.RowPitch], copyPitch);
|
||||
for (uint32_t h = 0; h < cursorHeight; h++)
|
||||
std::memcpy(&bitmap[h * cursorPitch], &data[h * lockedBox.RowPitch], copyPitch);
|
||||
|
||||
UnlockImage(cursorTex, 0, 0);
|
||||
|
||||
// Set this as our cursor.
|
||||
return m_cursor.SetHardwareCursor(XHotSpot, YHotSpot, bitmap);
|
||||
return m_cursor.SetHardwareCursor(XHotSpot,
|
||||
YHotSpot,
|
||||
bitmap,
|
||||
m_d3d9Options.softwareCursorEmulation,
|
||||
inputWidth,
|
||||
inputHeight,
|
||||
m_window);
|
||||
}
|
||||
|
||||
// Software Cursor...
|
||||
|
|
|
@ -77,6 +77,7 @@ namespace dxvk {
|
|||
this->samplerLodBias = config.getOption<float> ("d3d9.samplerLodBias", 0.0f);
|
||||
this->clampNegativeLodBias = config.getOption<bool> ("d3d9.clampNegativeLodBias", false);
|
||||
this->countLosableResources = config.getOption<bool> ("d3d9.countLosableResources", true);
|
||||
this->softwareCursorEmulation = config.getOption<bool> ("d3d9.softwareCursorEmulation", false);
|
||||
|
||||
// Clamp LOD bias so that people don't abuse this in unintended ways
|
||||
this->samplerLodBias = dxvk::fclamp(this->samplerLodBias, -2.0f, 1.0f);
|
||||
|
|
|
@ -144,6 +144,9 @@ namespace dxvk {
|
|||
/// Clamps negative LOD bias
|
||||
bool clampNegativeLodBias;
|
||||
|
||||
/// Emulate a software cursor using a hardware cursor
|
||||
bool softwareCursorEmulation;
|
||||
|
||||
/// How much virtual memory will be used for textures (in MB).
|
||||
int32_t textureMemory;
|
||||
|
||||
|
|
Loading…
Reference in New Issue