dolphin/Source/Plugins/Plugin_PadDX9/Src/multidi.h

146 lines
7.1 KiB
C++

//-----------------------------------------------------------------------------
// File: MultiDI.h
//
// Desc: Multiple user DirectInput support using action mapping
//
// Copyright (C) Microsoft Corporation. All Rights Reserved.
//-----------------------------------------------------------------------------
#ifndef MULTIDI_H
#define MULTIDI_H
#ifndef DIRECTINPUT_VERSION
#define DIRECTINPUT_VERSION 0x0800
#endif
#include <dinput.h>
//-----------------------------------------------------------------------------
// Miscellaneous helper functions
//-----------------------------------------------------------------------------
#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } }
#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } }
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
HRESULT DXUtil_WriteStringRegKey( HKEY hKey, LPCTSTR strRegName, LPCTSTR strValue );
HRESULT DXUtil_ReadStringRegKeyCch( HKEY hKey, LPCTSTR strRegName, TCHAR* strDest, DWORD cchDest, LPCTSTR strDefault );
HRESULT DXUtil_ConvertGUIDToStringCch( const GUID* pGuidSrc, TCHAR* strDest, int cchDestChar );
HRESULT DXUtil_ConvertWideStringToGenericCch( TCHAR* tstrDestination, const WCHAR* wstrSource, int cchDestChar );
//-----------------------------------------------------------------------------
// Name: DXUtil_Timer()
// Desc: Performs timer opertations. Use the following commands:
// TIMER_RESET - to reset the timer
// TIMER_START - to start the timer
// TIMER_STOP - to stop (or pause) the timer
// TIMER_ADVANCE - to advance the timer by 0.1 seconds
// TIMER_GETABSOLUTETIME - to get the absolute system time
// TIMER_GETAPPTIME - to get the current time
// TIMER_GETELAPSEDTIME - to get the time that elapsed between
// TIMER_GETELAPSEDTIME calls
//-----------------------------------------------------------------------------
enum TIMER_COMMAND { TIMER_RESET, TIMER_START, TIMER_STOP, TIMER_ADVANCE,
TIMER_GETABSOLUTETIME, TIMER_GETAPPTIME, TIMER_GETELAPSEDTIME };
FLOAT __stdcall DXUtil_Timer( TIMER_COMMAND command );
// E_DIUTILERR_PLAYERWITHOUTDEVICE is returned by the manager class after configuring
// device, and there's a player that hasn't been assigned a device.
#define E_DIUTILERR_PLAYERWITHOUTDEVICE MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,997)
// E_DIUTILERR_DEVICESTAKEN is returned by the manager class when one player
// on the machine has enough RECENT devices to prevent other players from
// playing. This return code is needed because this sample attempts to give
// all RECENT devices to that player.
#define E_DIUTILERR_DEVICESTAKEN MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,998)
// E_DIUTILERR_TOOMANYUSERS is returned by the manager class when the number of
// players exceeds the number of devices present on the system. For example,
// if you ask for 4 players on a machine that only has a keyboard and mouse,
// you're 2 short of what you need.
#define E_DIUTILERR_TOOMANYUSERS MAKE_HRESULT(SEVERITY_ERROR,FACILITY_ITF,999)
//-----------------------------------------------------------------------------
// Name: class CMultiplayerInputDeviceManager
// Desc: Input device manager using DX8 action mapping
//-----------------------------------------------------------------------------
class CMultiplayerInputDeviceManager
{
public:
struct PlayerInfo
{
DWORD dwPlayerIndex; // 0-based player number
TCHAR strPlayerName[MAX_PATH]; // player name
DWORD dwMaxDevices; // max number of elements in pDevices array
DWORD dwNumDevices; // current number of elements in pDevices array
BOOL bFoundDeviceForPlayer; // if a device has been found for this player yet
};
struct DeviceInfo
{
LPDIRECTINPUTDEVICE8 pdidDevice; // dinput device pointer
PlayerInfo* pPlayerInfo; // Player who owns this device
BOOL bRelativeAxis; // TRUE if device is using relative axis
BOOL bMapsPri1Actions; // TRUE if device maps pri 1 actions
BOOL bMapsPri2Actions; // TRUE if device maps pri 2 actions
LPVOID pParam; // app defined pointer assoicated with this device
DIDEVICEINSTANCE didi; // device instance info
};
typedef HRESULT (CALLBACK *LPDIMANAGERCALLBACK)(CMultiplayerInputDeviceManager::PlayerInfo* pPlayerInfo, CMultiplayerInputDeviceManager::DeviceInfo* pDeviceInfo, const DIDEVICEINSTANCE* pdidi, LPVOID);
private:
BOOL m_bCleanupCOM;
HWND m_hWnd;
LPDIRECTINPUT8 m_pDI;
DIACTIONFORMAT* m_pdiaf;
PlayerInfo** m_pUsers;
DWORD m_dwNumUsers;
DeviceInfo* m_pDeviceList;
DWORD m_dwNumDevices;
DWORD m_dwMaxDevices;
LPDIMANAGERCALLBACK m_AddDeviceCallback;
LPVOID m_AddDeviceCallbackParam;
TCHAR* m_strKey;
HKEY m_hKey;
public:
static BOOL CALLBACK StaticEnumSuitableDevicesCB( LPCDIDEVICEINSTANCE pdidi, LPDIRECTINPUTDEVICE8 pdidDevice, DWORD dwFlags, DWORD dwRemainingDevices, VOID* pContext );
static BOOL CALLBACK StaticBuildDeviceListCB( LPCDIDEVICEINSTANCE pdidi, VOID* pContext );
// Device control
BOOL EnumDevice( const DIDEVICEINSTANCE* pdidi, LPDIRECTINPUTDEVICE8 pdidDevice, DWORD dwFlags, DWORD dwDeviceRemaining );
BOOL BuildDeviceListCB( LPCDIDEVICEINSTANCE pdidi );
HRESULT AddDevice( DeviceInfo* pDeviceInfo, BOOL bForceReset );
HRESULT GetDevices( DeviceInfo** ppDeviceInfo, DWORD* pdwNumDevices );
HRESULT ConfigureDevices( HWND hWnd, IUnknown* pSurface, VOID* pCallback, DWORD dwFlags, LPVOID pvCBParam );
DWORD GetNumDevices() { return m_dwNumDevices; }
VOID UnacquireDevices();
VOID SetFocus( HWND hWnd );
PlayerInfo* LookupPlayer( TCHAR* strPlayerName );
HRESULT SaveDeviceOwnershipKeys();
VOID DeleteDeviceOwnershipKeys();
HRESULT UpdateDeviceOwnership();
HRESULT AssignDevices();
HRESULT VerifyAssignment();
HRESULT AddAssignedDevices( BOOL bResetMappings );
HRESULT BuildDeviceList();
VOID CleanupDeviceList();
// Construction
HRESULT SetActionFormat( DIACTIONFORMAT* pdiaf, BOOL bReenumerate, BOOL bResetOwnership, BOOL bResetMappings );
HRESULT Create( HWND hWnd, TCHAR* strUserNames[], DWORD dwNumUsers, DIACTIONFORMAT* pdiaf, LPDIMANAGERCALLBACK AddDeviceCallback, LPVOID pCallbackParam, BOOL bResetOwnership, BOOL bResetMappings );
CMultiplayerInputDeviceManager( TCHAR* strRegKey );
~CMultiplayerInputDeviceManager();
VOID Cleanup();
};
#endif