Skip to content

Commit

Permalink
Automatically invoke Acquire() on DirectInput device objects when the…
Browse files Browse the repository at this point in the history
… application attempts certain operations that require acquisition and the application has not explicitly invoke Acquire() previously.
  • Loading branch information
samuelgr committed Jul 23, 2022
1 parent 2ca5716 commit 518e75a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 19 deletions.
6 changes: 6 additions & 0 deletions Include/Xidi/VirtualDirectInputDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,12 @@ namespace Xidi

// -------- INSTANCE METHODS ----------------------------------------------- //

/// Obtains the force feedback device associated with this controller.
/// If this controller is not yet acquired then an attempt is made to acquire it automatically.
/// @return Pointer to the force feedback device object if successful, `nullptr` otherwise.
Controller::ForceFeedback::Device* AutoAcquireAndGetForceFeedbackDevice(void);


/// Registers a force feedback effect by adding it to the effect registry.
/// Intended to be invoked automaticaly as effects are constructed.
/// @param [in] effect Address of the effect object to register.
Expand Down
46 changes: 31 additions & 15 deletions Source/VirtualDirectInputDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,23 @@ namespace Xidi
// -------- INSTANCE METHODS ------------------------------------------- //
// See "VirtualDirectInputDevice.h" for documentation.

template <ECharMode charMode> Controller::ForceFeedback::Device* VirtualDirectInputDevice<charMode>::AutoAcquireAndGetForceFeedbackDevice(void)
{
Controller::ForceFeedback::Device* forceFeedbackDevice = controller->ForceFeedbackGetDevice();

if (nullptr == forceFeedbackDevice)
{
Message::OutputFormatted(Message::ESeverity::Info, L"Attempting to acquire Xidi virtual controller %u automatically because the application did not do so explicitly.", (1 + controller->GetIdentifier()));

Acquire();
forceFeedbackDevice = controller->ForceFeedbackGetDevice();
}

return forceFeedbackDevice;
}

// --------

template <ECharMode charMode> std::optional<Controller::SElementIdentifier> VirtualDirectInputDevice<charMode>::IdentifyElement(DWORD dwObj, DWORD dwHow) const
{
switch (dwHow)
Expand Down Expand Up @@ -1421,19 +1438,19 @@ namespace Xidi
if (nullptr == pdwOut)
LOG_INVOCATION_AND_RETURN(DIERR_INVALIDPARAM, kMethodSeverity);

if (false == controller->ForceFeedbackIsRegistered())
Controller::ForceFeedback::Device* forceFeedbackDevice = AutoAcquireAndGetForceFeedbackDevice();
if (nullptr == forceFeedbackDevice)
LOG_INVOCATION_AND_RETURN(DIERR_NOTEXCLUSIVEACQUIRED, kMethodSeverity);

Controller::ForceFeedback::Device& forceFeedbackDevice = *controller->ForceFeedbackGetDevice();
DWORD forceFeedbackDeviceState = DIGFFS_POWERON;

if (true == forceFeedbackDevice.IsDeviceOutputMuted())
if (true == forceFeedbackDevice->IsDeviceOutputMuted())
forceFeedbackDeviceState |= DIGFFS_ACTUATORSOFF;
else
forceFeedbackDeviceState |= DIGFFS_ACTUATORSON;

const bool kDeviceIsEmpty = forceFeedbackDevice.IsDeviceEmpty();
const bool kDeviceIsPaused = forceFeedbackDevice.IsDeviceOutputPaused();
const bool kDeviceIsEmpty = forceFeedbackDevice->IsDeviceEmpty();
const bool kDeviceIsPaused = forceFeedbackDevice->IsDeviceOutputPaused();

if (true == kDeviceIsEmpty)
{
Expand All @@ -1451,7 +1468,7 @@ namespace Xidi

if (true == kDeviceIsPaused)
forceFeedbackDeviceState |= DIGFFS_PAUSED;
else if (false == forceFeedbackDevice.IsDevicePlayingAnyEffects())
else if (false == forceFeedbackDevice->IsDevicePlayingAnyEffects())
forceFeedbackDeviceState |= DIGFFS_STOPPED;
}

Expand Down Expand Up @@ -1650,41 +1667,40 @@ namespace Xidi
LOG_INVOCATION_AND_RETURN(DIERR_UNSUPPORTED, kMethodSeverity);
}

if (false == controller->ForceFeedbackIsRegistered())
Controller::ForceFeedback::Device* forceFeedbackDevice = AutoAcquireAndGetForceFeedbackDevice();
if (nullptr == forceFeedbackDevice)
LOG_INVOCATION_AND_RETURN(DIERR_NOTEXCLUSIVEACQUIRED, kMethodSeverity);

Controller::ForceFeedback::Device& forceFeedbackDevice = *controller->ForceFeedbackGetDevice();

switch (dwFlags)
{
case DISFFC_CONTINUE:
Message::Output(Message::ESeverity::Debug, L"Sending force feedback command DISFFC_CONTINUE.");
forceFeedbackDevice.SetPauseState(false);
forceFeedbackDevice->SetPauseState(false);
break;

case DISFFC_PAUSE:
Message::Output(Message::ESeverity::Debug, L"Sending force feedback command DISFFC_PAUSE.");
forceFeedbackDevice.SetPauseState(true);
forceFeedbackDevice->SetPauseState(true);
break;

case DISFFC_RESET:
Message::Output(Message::ESeverity::Debug, L"Sending force feedback command DISFFC_RESET.");
forceFeedbackDevice.Clear();
forceFeedbackDevice->Clear();
break;

case DISFFC_SETACTUATORSOFF:
Message::Output(Message::ESeverity::Debug, L"Sending force feedback command DISFFC_SETACTUATORSOFF.");
forceFeedbackDevice.SetMutedState(true);
forceFeedbackDevice->SetMutedState(true);
break;

case DISFFC_SETACTUATORSON:
Message::Output(Message::ESeverity::Debug, L"Sending force feedback command DISFFC_SETACTUATORSON.");
forceFeedbackDevice.SetMutedState(false);
forceFeedbackDevice->SetMutedState(false);
break;

case DISFFC_STOPALL:
Message::Output(Message::ESeverity::Debug, L"Sending force feedback command DISFFC_STOPALL.");
forceFeedbackDevice.StopAllEffects();
forceFeedbackDevice->StopAllEffects();
break;

default:
Expand Down
8 changes: 4 additions & 4 deletions Source/VirtualDirectInputEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,7 @@ namespace Xidi

template <ECharMode charMode> HRESULT VirtualDirectInputEffect<charMode>::DownloadInternal(void)
{
Controller::ForceFeedback::Device* const forceFeedbackDevice = associatedDevice.GetVirtualController().ForceFeedbackGetDevice();
Controller::ForceFeedback::Device* const forceFeedbackDevice = associatedDevice.AutoAcquireAndGetForceFeedbackDevice();
if (nullptr == forceFeedbackDevice)
return DIERR_NOTEXCLUSIVEACQUIRED;

Expand Down Expand Up @@ -636,7 +636,7 @@ namespace Xidi
if (0 == dwIterations)
return DIERR_INVALIDPARAM;

Controller::ForceFeedback::Device* const forceFeedbackDevice = associatedDevice.GetVirtualController().ForceFeedbackGetDevice();
Controller::ForceFeedback::Device* const forceFeedbackDevice = associatedDevice.AutoAcquireAndGetForceFeedbackDevice();
if (nullptr == forceFeedbackDevice)
return DIERR_NOTEXCLUSIVEACQUIRED;

Expand Down Expand Up @@ -1023,7 +1023,7 @@ namespace Xidi
{
constexpr Message::ESeverity kMethodSeverity = Message::ESeverity::Info;

Controller::ForceFeedback::Device* const forceFeedbackDevice = associatedDevice.GetVirtualController().ForceFeedbackGetDevice();
Controller::ForceFeedback::Device* const forceFeedbackDevice = associatedDevice.AutoAcquireAndGetForceFeedbackDevice();
if (nullptr == forceFeedbackDevice)
LOG_INVOCATION_AND_RETURN(DIERR_NOTEXCLUSIVEACQUIRED, kMethodSeverity);

Expand Down Expand Up @@ -1066,7 +1066,7 @@ namespace Xidi
{
constexpr Message::ESeverity kMethodSeverity = Message::ESeverity::Info;

Controller::ForceFeedback::Device* const forceFeedbackDevice = associatedDevice.GetVirtualController().ForceFeedbackGetDevice();
Controller::ForceFeedback::Device* const forceFeedbackDevice = associatedDevice.AutoAcquireAndGetForceFeedbackDevice();
if (nullptr == forceFeedbackDevice)
LOG_INVOCATION_AND_RETURN(DIERR_NOTEXCLUSIVEACQUIRED, kMethodSeverity);

Expand Down

0 comments on commit 518e75a

Please sign in to comment.