mirror of
https://github.com/elasota/Aerofoil.git
synced 2025-09-24 23:26:37 +00:00
Add mouse cursor handling
This commit is contained in:
@@ -143,6 +143,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\GpCommon\GpColorCursor_Win32.cpp" />
|
||||
<ClCompile Include="GpAppEnvironment.cpp" />
|
||||
<ClCompile Include="GpAudioDriverFactory.cpp" />
|
||||
<ClCompile Include="GpDisplayDriverFactory.cpp" />
|
||||
@@ -172,7 +173,10 @@
|
||||
<ClCompile Include="ShadersD3D11\DrawQuadV_D3D11.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\GpCommon\EGpStandardCursor.h" />
|
||||
<ClInclude Include="..\GpCommon\IGpColorCursor.h" />
|
||||
<ClInclude Include="..\GpCommon\IGpAudioChannelCallbacks.h" />
|
||||
<ClInclude Include="..\GpCommon\GpColorCursor_Win32.h" />
|
||||
<ClInclude Include="..\GpCommon\IGpDisplayDriverSurface.h" />
|
||||
<ClInclude Include="EGpAudioDriverType.h" />
|
||||
<ClInclude Include="EGpDisplayDriverType.h" />
|
||||
|
@@ -99,6 +99,9 @@
|
||||
<ClCompile Include="ShadersD3D11\DrawQuadRGBP_D3D11.cpp">
|
||||
<Filter>Source Files\CompiledShaders</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\GpCommon\GpColorCursor_Win32.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="GpWindows.h">
|
||||
@@ -212,5 +215,14 @@
|
||||
<ClInclude Include="GpComPtr.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\GpCommon\IGpColorCursor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\GpCommon\GpColorCursor_Win32.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\GpCommon\EGpStandardCursor.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -1,6 +1,8 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#include "GpDisplayDriverD3D11.h"
|
||||
#include "GpDisplayDriverSurfaceD3D11.h"
|
||||
#include "GpWindows.h"
|
||||
#include "GpColorCursor_Win32.h"
|
||||
#include "GpFiber_Win32.h"
|
||||
|
||||
#include <d3d11.h>
|
||||
@@ -308,6 +310,8 @@ bool GpDisplayDriverD3D11::InitResources()
|
||||
|
||||
bool GpDisplayDriverD3D11::PresentFrameAndSync()
|
||||
{
|
||||
SynchronizeCursors();
|
||||
|
||||
float clearColor[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
|
||||
m_deviceContext->ClearRenderTargetView(m_backBufferRTV, clearColor);
|
||||
@@ -443,9 +447,74 @@ bool GpDisplayDriverD3D11::PresentFrameAndSync()
|
||||
return true;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::SynchronizeCursors()
|
||||
{
|
||||
HCURSOR replacementCursor = nullptr;
|
||||
|
||||
if (m_activeCursor)
|
||||
{
|
||||
if (m_pendingCursor != m_activeCursor)
|
||||
{
|
||||
if (m_pendingCursor == nullptr)
|
||||
{
|
||||
m_currentStandardCursor = m_pendingStandardCursor;
|
||||
ChangeToStandardCursor(m_currentStandardCursor);
|
||||
|
||||
m_activeCursor->DecRef();
|
||||
m_activeCursor = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ChangeToCursor(m_pendingCursor->GetHCursor());
|
||||
|
||||
m_pendingCursor->IncRef();
|
||||
m_activeCursor->DecRef();
|
||||
m_activeCursor = m_pendingCursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pendingCursor)
|
||||
{
|
||||
m_pendingCursor->IncRef();
|
||||
m_activeCursor = m_pendingCursor;
|
||||
|
||||
ChangeToCursor(m_activeCursor->GetHCursor());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_pendingStandardCursor != m_currentStandardCursor)
|
||||
{
|
||||
ChangeToStandardCursor(m_pendingStandardCursor);
|
||||
m_currentStandardCursor = m_pendingStandardCursor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void GpDisplayDriverD3D11::ChangeToCursor(HCURSOR cursor)
|
||||
{
|
||||
if (m_mouseIsInClientArea)
|
||||
SetCursor(cursor);
|
||||
|
||||
SetClassLongPtrW(m_hwnd, GCLP_HCURSOR, reinterpret_cast<LONG_PTR>(cursor));
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::ChangeToStandardCursor(EGpStandardCursor_t cursor)
|
||||
{
|
||||
switch (cursor)
|
||||
{
|
||||
case EGpStandardCursors::kArrow:
|
||||
default:
|
||||
ChangeToCursor(m_arrowCursor);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::Run()
|
||||
{
|
||||
HWND hWnd;
|
||||
WNDCLASSEX wc;
|
||||
|
||||
LPVOID fiber = ConvertThreadToFiberEx(this, 0);
|
||||
@@ -460,7 +529,7 @@ void GpDisplayDriverD3D11::Run()
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.lpfnWndProc = WinProc;
|
||||
wc.hInstance = g_gpWindowsGlobals.m_hInstance;
|
||||
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hCursor = m_arrowCursor;
|
||||
wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
|
||||
wc.lpszClassName = "GPD3D11WindowClass";
|
||||
|
||||
@@ -473,11 +542,11 @@ void GpDisplayDriverD3D11::Run()
|
||||
RECT wr = { 0, 0, m_windowWidth, m_windowHeight };
|
||||
AdjustWindowRect(&wr, windowStyle, menus != NULL);
|
||||
|
||||
hWnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, g_gpWindowsGlobals.m_hInstance, NULL);
|
||||
m_hwnd = CreateWindowExW(NULL, L"GPD3D11WindowClass", L"GlidePort (Direct3D 11)", WS_OVERLAPPEDWINDOW, 300, 300, wr.right - wr.left, wr.bottom - wr.top, NULL, menus, g_gpWindowsGlobals.m_hInstance, NULL);
|
||||
|
||||
ShowWindow(hWnd, g_gpWindowsGlobals.m_nCmdShow);
|
||||
ShowWindow(m_hwnd, g_gpWindowsGlobals.m_nCmdShow);
|
||||
|
||||
StartD3DForWindow(hWnd, m_swapChain, m_device, m_deviceContext);
|
||||
StartD3DForWindow(m_hwnd, m_swapChain, m_device, m_deviceContext);
|
||||
|
||||
InitResources();
|
||||
|
||||
@@ -495,6 +564,10 @@ void GpDisplayDriverD3D11::Run()
|
||||
|
||||
if (msg.message == WM_QUIT)
|
||||
break;
|
||||
else if (msg.message == WM_MOUSEMOVE)
|
||||
m_mouseIsInClientArea = true;
|
||||
else if (msg.message == WM_MOUSELEAVE)
|
||||
m_mouseIsInClientArea = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -612,6 +685,44 @@ void GpDisplayDriverD3D11::DrawSurface(IGpDisplayDriverSurface *surface, size_t
|
||||
m_deviceContext->DrawIndexed(6, 0, 0);
|
||||
}
|
||||
|
||||
IGpColorCursor *GpDisplayDriverD3D11::LoadColorCursor(int cursorID)
|
||||
{
|
||||
const size_t bufSize = MAX_PATH;
|
||||
wchar_t path[bufSize];
|
||||
|
||||
int sz = _snwprintf(path, bufSize, L"%sPackaged\\WinCursors\\%i.cur", m_osGlobals->m_baseDir, cursorID);
|
||||
if (sz < 0 || static_cast<size_t>(sz) >= bufSize)
|
||||
return nullptr;
|
||||
|
||||
return GpColorCursor_Win32::Load(path);
|
||||
}
|
||||
|
||||
// We can't just set the cursor because we want to post WM_SETCURSOR to keep it limited
|
||||
// to the game window area, but depending on the fiber implementation, this may not be
|
||||
// the window thread.
|
||||
void GpDisplayDriverD3D11::SetColorCursor(IGpColorCursor *colorCursor)
|
||||
{
|
||||
GpColorCursor_Win32 *winCursor = static_cast<GpColorCursor_Win32*>(colorCursor);
|
||||
|
||||
winCursor->IncRef();
|
||||
|
||||
if (m_pendingCursor)
|
||||
m_pendingCursor->DecRef();
|
||||
|
||||
m_pendingCursor = winCursor;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::SetStandardCursor(EGpStandardCursor_t standardCursor)
|
||||
{
|
||||
if (m_pendingCursor)
|
||||
{
|
||||
m_pendingCursor->DecRef();
|
||||
m_pendingCursor = nullptr;
|
||||
}
|
||||
|
||||
m_pendingStandardCursor = standardCursor;
|
||||
}
|
||||
|
||||
void GpDisplayDriverD3D11::UpdatePalette(const void *paletteData)
|
||||
{
|
||||
const size_t dataSize = 256 * 4;
|
||||
@@ -643,14 +754,23 @@ GpDisplayDriverD3D11::GpDisplayDriverD3D11(const GpDisplayDriverProperties &prop
|
||||
, m_windowWidth(640)
|
||||
, m_windowHeight(480)
|
||||
, m_vosFiber(nullptr)
|
||||
, m_osGlobals(static_cast<GpWindowsGlobals*>(properties.m_osGlobals))
|
||||
, m_pendingCursor(nullptr)
|
||||
, m_activeCursor(nullptr)
|
||||
, m_currentStandardCursor(EGpStandardCursors::kArrow)
|
||||
, m_pendingStandardCursor(EGpStandardCursors::kArrow)
|
||||
, m_mouseIsInClientArea(false)
|
||||
{
|
||||
memset(&m_syncTimeBase, 0, sizeof(m_syncTimeBase));
|
||||
|
||||
QueryPerformanceFrequency(&m_QPFrequency);
|
||||
|
||||
m_frameTimeSliceSize = m_QPFrequency.QuadPart * static_cast<LONGLONG>(properties.m_frameTimeLockNumerator) / static_cast<LONGLONG>(properties.m_frameTimeLockDenominator);
|
||||
|
||||
m_arrowCursor = reinterpret_cast<HCURSOR>(LoadImageW(nullptr, MAKEINTRESOURCEW(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED));
|
||||
}
|
||||
|
||||
GpDisplayDriverD3D11::~GpDisplayDriverD3D11()
|
||||
{
|
||||
// GP TODO: Sloppy cleanup... Close the window!!
|
||||
}
|
||||
|
@@ -10,6 +10,9 @@
|
||||
|
||||
#include "PixelFormat.h"
|
||||
|
||||
struct GpWindowsGlobals;
|
||||
class GpColorCursor_Win32;
|
||||
|
||||
struct IDXGISwapChain1;
|
||||
struct ID3D11Buffer;
|
||||
struct ID3D11DepthStencilState;
|
||||
@@ -35,6 +38,10 @@ public:
|
||||
IGpDisplayDriverSurface *CreateSurface(size_t width, size_t height, PortabilityLayer::PixelFormat pixelFormat) override;
|
||||
void DrawSurface(IGpDisplayDriverSurface *surface, size_t x, size_t y, size_t width, size_t height) override;
|
||||
|
||||
IGpColorCursor *LoadColorCursor(int cursorID) override;
|
||||
void SetColorCursor(IGpColorCursor *colorCursor) override;
|
||||
void SetStandardCursor(EGpStandardCursor_t standardCursor) override;
|
||||
|
||||
void UpdatePalette(const void *paletteData) override;
|
||||
|
||||
static GpDisplayDriverD3D11 *Create(const GpDisplayDriverProperties &properties);
|
||||
@@ -52,12 +59,22 @@ private:
|
||||
float m_unused[2];
|
||||
};
|
||||
|
||||
struct CompactedPresentHistoryItem
|
||||
{
|
||||
LARGE_INTEGER m_timestamp;
|
||||
unsigned int m_numFrames;
|
||||
};
|
||||
|
||||
GpDisplayDriverD3D11(const GpDisplayDriverProperties &properties);
|
||||
~GpDisplayDriverD3D11();
|
||||
|
||||
bool InitResources();
|
||||
bool PresentFrameAndSync();
|
||||
|
||||
void SynchronizeCursors();
|
||||
void ChangeToCursor(HCURSOR cursor);
|
||||
void ChangeToStandardCursor(EGpStandardCursor_t cursor);
|
||||
|
||||
GpComPtr<IDXGISwapChain1> m_swapChain;
|
||||
GpComPtr<ID3D11Device> m_device;
|
||||
GpComPtr<ID3D11DeviceContext> m_deviceContext;
|
||||
@@ -77,12 +94,6 @@ private:
|
||||
GpComPtr<ID3D11Texture2D> m_backBufferTexture;
|
||||
GpComPtr<ID3D11RenderTargetView> m_backBufferRTV;
|
||||
|
||||
struct CompactedPresentHistoryItem
|
||||
{
|
||||
LARGE_INTEGER m_timestamp;
|
||||
unsigned int m_numFrames;
|
||||
};
|
||||
|
||||
GpRingBuffer<CompactedPresentHistoryItem, 60> m_presentHistory;
|
||||
GpDisplayDriverProperties m_properties;
|
||||
|
||||
@@ -97,5 +108,15 @@ private:
|
||||
DWORD m_windowWidth;
|
||||
DWORD m_windowHeight;
|
||||
|
||||
GpColorCursor_Win32 *m_activeCursor;
|
||||
GpColorCursor_Win32 *m_pendingCursor;
|
||||
EGpStandardCursor_t m_currentStandardCursor;
|
||||
EGpStandardCursor_t m_pendingStandardCursor;
|
||||
bool m_mouseIsInClientArea;
|
||||
|
||||
GpFiber *m_vosFiber;
|
||||
GpWindowsGlobals *m_osGlobals;
|
||||
|
||||
HCURSOR m_arrowCursor;
|
||||
HWND m_hwnd;
|
||||
};
|
||||
|
@@ -95,6 +95,7 @@ GpDirectoryCursor_Win32::~GpDirectoryCursor_Win32()
|
||||
|
||||
GpFileSystem_Win32::GpFileSystem_Win32()
|
||||
{
|
||||
// GP TODO: This shouldn't be static init since it allocates memory
|
||||
m_executablePath[0] = 0;
|
||||
|
||||
PWSTR docsPath;
|
||||
@@ -201,6 +202,11 @@ PortabilityLayer::HostDirectoryCursor *GpFileSystem_Win32::ScanDirectory(Portabi
|
||||
return GpDirectoryCursor_Win32::Create(ff, findData);
|
||||
}
|
||||
|
||||
const wchar_t *GpFileSystem_Win32::GetBasePath() const
|
||||
{
|
||||
return m_executablePath;
|
||||
}
|
||||
|
||||
GpFileSystem_Win32 *GpFileSystem_Win32::GetInstance()
|
||||
{
|
||||
return &ms_instance;
|
||||
|
@@ -1,31 +1,33 @@
|
||||
#pragma once
|
||||
|
||||
#include "HostFileSystem.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "HostFileSystem.h"
|
||||
|
||||
#include "GpCoreDefs.h"
|
||||
#include "GpWindows.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class GpFileSystem_Win32 final : public PortabilityLayer::HostFileSystem
|
||||
{
|
||||
public:
|
||||
GpFileSystem_Win32();
|
||||
|
||||
bool FileExists(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path) override;
|
||||
PortabilityLayer::IOStream *OpenFile(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, bool writeAccess, bool create) override;
|
||||
PortabilityLayer::HostDirectoryCursor *ScanDirectory(PortabilityLayer::EVirtualDirectory virtualDirectory) override;
|
||||
|
||||
static GpFileSystem_Win32 *GetInstance();
|
||||
|
||||
private:
|
||||
bool ResolvePath(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, wchar_t *outPath);
|
||||
|
||||
std::wstring m_prefsDir;
|
||||
std::wstring m_packagedDir;
|
||||
#include "GpWindows.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class GpFileSystem_Win32 final : public PortabilityLayer::HostFileSystem
|
||||
{
|
||||
public:
|
||||
GpFileSystem_Win32();
|
||||
|
||||
bool FileExists(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path) override;
|
||||
PortabilityLayer::IOStream *OpenFile(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, bool writeAccess, bool create) override;
|
||||
PortabilityLayer::HostDirectoryCursor *ScanDirectory(PortabilityLayer::EVirtualDirectory virtualDirectory) override;
|
||||
|
||||
const wchar_t *GetBasePath() const;
|
||||
|
||||
static GpFileSystem_Win32 *GetInstance();
|
||||
|
||||
private:
|
||||
bool ResolvePath(PortabilityLayer::EVirtualDirectory virtualDirectory, const char *path, wchar_t *outPath);
|
||||
|
||||
std::wstring m_prefsDir;
|
||||
std::wstring m_packagedDir;
|
||||
std::wstring m_housesDir;
|
||||
std::wstring m_resourcesDir;
|
||||
wchar_t m_executablePath[MAX_PATH];
|
||||
|
||||
static GpFileSystem_Win32 ms_instance;
|
||||
};
|
||||
wchar_t m_executablePath[MAX_PATH];
|
||||
|
||||
static GpFileSystem_Win32 ms_instance;
|
||||
};
|
||||
|
@@ -4,7 +4,8 @@
|
||||
|
||||
struct GpGlobalConfig
|
||||
{
|
||||
EGpDisplayDriverType m_displayDriverType;
|
||||
EGpDisplayDriverType m_displayDriverType;
|
||||
void *m_osGlobals;
|
||||
};
|
||||
|
||||
extern GpGlobalConfig g_gpGlobalConfig;
|
||||
|
@@ -49,6 +49,7 @@ int GpMain::Run()
|
||||
ddProps.m_renderFuncContext = appEnvironment;
|
||||
|
||||
ddProps.m_type = g_gpGlobalConfig.m_displayDriverType;
|
||||
ddProps.m_osGlobals = g_gpGlobalConfig.m_osGlobals;
|
||||
|
||||
GpAudioDriverProperties adProps;
|
||||
memset(&adProps, 0, sizeof(adProps));
|
||||
|
@@ -13,7 +13,7 @@
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
GPWindowsGlobals g_gpWindowsGlobals;
|
||||
GpWindowsGlobals g_gpWindowsGlobals;
|
||||
|
||||
extern "C" __declspec(dllimport) IGpAudioDriver *GpDriver_CreateAudioDriver_XAudio2(const GpAudioDriverProperties &properties);
|
||||
|
||||
@@ -26,8 +26,10 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
|
||||
g_gpWindowsGlobals.m_hPrevInstance = hPrevInstance;
|
||||
g_gpWindowsGlobals.m_cmdLine = lpCmdLine;
|
||||
g_gpWindowsGlobals.m_nCmdShow = nCmdShow;
|
||||
g_gpWindowsGlobals.m_baseDir = GpFileSystem_Win32::GetInstance()->GetBasePath();
|
||||
|
||||
g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_D3D11;
|
||||
g_gpGlobalConfig.m_osGlobals = &g_gpWindowsGlobals;
|
||||
|
||||
GpDisplayDriverFactory::RegisterDisplayDriverFactory(EGpDisplayDriverType_D3D11, GpDisplayDriverFactoryD3D11::Create);
|
||||
GpAudioDriverFactory::RegisterAudioDriverFactory(EGpAudioDriverType_XAudio2, GpDriver_CreateAudioDriver_XAudio2);
|
||||
|
@@ -1,4 +1,5 @@
|
||||
#include "GpPLGlueDisplayDriver.h"
|
||||
#include "GpPLGlueDisplayDriver.h"
|
||||
#include "VirtualDirectory.h"
|
||||
#include "IGpDisplayDriver.h"
|
||||
|
||||
GpPLGlueDisplayDriver::GpPLGlueDisplayDriver()
|
||||
@@ -9,10 +10,21 @@ GpPLGlueDisplayDriver::GpPLGlueDisplayDriver()
|
||||
void GpPLGlueDisplayDriver::GetDisplayResolution(unsigned int *width, unsigned int *height, PortabilityLayer::PixelFormat *bpp)
|
||||
{
|
||||
m_displayDriver->GetDisplayResolution(width, height, bpp);
|
||||
}
|
||||
|
||||
IGpColorCursor *GpPLGlueDisplayDriver::LoadColorCursor(int cursorID)
|
||||
{
|
||||
return m_displayDriver->LoadColorCursor(cursorID);
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::HideCursor()
|
||||
void GpPLGlueDisplayDriver::SetColorCursor(IGpColorCursor *colorCursor)
|
||||
{
|
||||
m_displayDriver->SetColorCursor(colorCursor);
|
||||
}
|
||||
|
||||
void GpPLGlueDisplayDriver::SetStandardCursor(EGpStandardCursor_t standardCursor)
|
||||
{
|
||||
m_displayDriver->SetStandardCursor(standardCursor);
|
||||
}
|
||||
|
||||
GpPLGlueDisplayDriver *GpPLGlueDisplayDriver::GetInstance()
|
||||
|
@@ -10,7 +10,9 @@ public:
|
||||
GpPLGlueDisplayDriver();
|
||||
|
||||
void GetDisplayResolution(unsigned int *width, unsigned int *height, PortabilityLayer::PixelFormat *bpp) override;
|
||||
void HideCursor() override;
|
||||
IGpColorCursor *LoadColorCursor(int id) override;
|
||||
void SetColorCursor(IGpColorCursor *colorCursor) override;
|
||||
void SetStandardCursor(EGpStandardCursor_t standardCursor) override;
|
||||
|
||||
void SetGpDisplayDriver(IGpDisplayDriver *displayDriver);
|
||||
|
||||
|
Reference in New Issue
Block a user