From d493d50def31c7a70e982f603983da73a4c41dc0 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michal=20Mal=C3=BD?= Date: Fri, 31 Jul 2015 16:10:27 +0200 Subject: [PATCH] Add support for condition effects via SDL2 --- CMakeLists.txt | 1 + sdl2ffbconditioneffect.cpp | 139 +++++++++++++++++++++++++++++++++++++ sdl2ffbconditioneffect.h | 20 ++++++ sdl2ffbeffectfactory.cpp | 2 + sdl2ffbeffectfactory.h | 1 + 5 files changed, 163 insertions(+) create mode 100644 sdl2ffbconditioneffect.cpp create mode 100644 sdl2ffbconditioneffect.h diff --git a/CMakeLists.txt b/CMakeLists.txt index eabde32..a18ce44 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -58,6 +58,7 @@ if (SDL2_FOUND) sdl2ffbdevice.cpp sdl2ffbeffect.cpp sdl2ffbconstanteffect.cpp + sdl2ffbconditioneffect.cpp sdl2deviceprober.cpp) endif() diff --git a/sdl2ffbconditioneffect.cpp b/sdl2ffbconditioneffect.cpp new file mode 100644 index 0000000..fa7c6e6 --- /dev/null +++ b/sdl2ffbconditioneffect.cpp @@ -0,0 +1,139 @@ +#include "sdl2ffbconditioneffect.h" +#include "globalsettings.h" +#include + +SDL2FFBConditionEffect::SDL2FFBConditionEffect() : + SDL2FFBEffect(FFBEffectTypes::CONDITION) +{} + +SDL_HapticEffect* SDL2FFBConditionEffect::createFFstruct() +{ + SDL_HapticEffect* effect = SDL2FFBEffect::createFFstruct(); + if (effect == nullptr) + return nullptr; + + switch (m_params->subtype) { + case ConditionSubtypes::DAMPER: + effect->type = SDL_HAPTIC_DAMPER; + break; + case ConditionSubtypes::FRICTION: + effect->type = SDL_HAPTIC_FRICTION; + break; + case ConditionSubtypes::INERTIA: + effect->type = SDL_HAPTIC_INERTIA; + break; + case ConditionSubtypes::SPRING: + effect->type = SDL_HAPTIC_SPRING; + break; + default: + delete effect; + return nullptr; + } + + effect->condition.delay = m_params->replayDelay; + if (m_params->replayLength == 0) + effect->condition.length = SDL_HAPTIC_INFINITY; + else + effect->condition.length = m_params->replayLength; + + effect->condition.center[0] = m_params->center.at(FFBConditionEffectParameters::Axis::X); + effect->condition.deadband[0] = m_params->deadband.at(FFBConditionEffectParameters::Axis::X); + effect->condition.center[1] = m_params->center.at(FFBConditionEffectParameters::Axis::Y); + effect->condition.deadband[1] = m_params->deadband.at(FFBConditionEffectParameters::Axis::Y); + + effect->condition.left_sat[0] = m_params->leftSat.at(FFBConditionEffectParameters::Axis::X); + effect->condition.right_sat[0] = m_params->rightSat.at(FFBConditionEffectParameters::Axis::X); + effect->condition.left_coeff[0] = m_params->leftCoeff.at(FFBConditionEffectParameters::Axis::X);; + effect->condition.right_coeff[0] = m_params->rightCoeff.at(FFBConditionEffectParameters::Axis::X);; + + effect->condition.left_sat[1] = m_params->leftSat.at(FFBConditionEffectParameters::Axis::Y); + effect->condition.right_sat[1] = m_params->rightSat.at(FFBConditionEffectParameters::Axis::Y); + effect->condition.left_coeff[1] = m_params->leftCoeff.at(FFBConditionEffectParameters::Axis::Y);; + effect->condition.right_coeff[1] = m_params->rightCoeff.at(FFBConditionEffectParameters::Axis::Y);; + + return effect; +} + +bool SDL2FFBConditionEffect::setParameters(std::shared_ptr params) +{ + try { + const std::shared_ptr iParams = std::dynamic_pointer_cast(params); + return setParameters(iParams); + } catch (std::bad_cast& ) { + return false; + } +} + +bool SDL2FFBConditionEffect::setParameters(std::shared_ptr params) +{ + if (!GlobalSettings::GS()->doSanityChecks) + return true; + + if (!checkGenericParameters(params)) + return false; + + if (!checkBoundsInclusive(params->leftSat.at(FFBConditionEffectParameters::Axis::X), 0, 0xFFFF)) { + QMessageBox::warning(nullptr, CAPTION, "Left X saturation must be within <0; 65535>"); + return false; + } + + if (!checkBoundsInclusive(params->leftSat.at(FFBConditionEffectParameters::Axis::Y), 0, 0xFFFF)) { + QMessageBox::warning(nullptr, CAPTION, "Left Y saturation must be within <0; 65535>"); + return false; + } + + if (!checkBoundsInclusive(params->rightSat.at(FFBConditionEffectParameters::Axis::X), 0, 0xFFFF)) { + QMessageBox::warning(nullptr, CAPTION, "Right X saturation must be within <0; 65535>"); + return false; + } + + if (!checkBoundsInclusive(params->rightSat.at(FFBConditionEffectParameters::Axis::Y), 0, 0xFFFF)) { + QMessageBox::warning(nullptr, CAPTION, "Right Y saturation must be within <0; 65535>"); + return false; + } + + if (!checkBoundsInclusive(params->leftCoeff.at(FFBConditionEffectParameters::Axis::X), -0x7FFF, 0x7FFF)) { + QMessageBox::warning(nullptr, CAPTION, "Left X coefficient must be within <-32767; 32767>"); + return false; + } + + if (!checkBoundsInclusive(params->leftCoeff.at(FFBConditionEffectParameters::Axis::Y), -0x7FFF, 0x7FFF)) { + QMessageBox::warning(nullptr, CAPTION, "Left Y coefficient must be within <-32767; 32767>"); + return false; + } + + if (!checkBoundsInclusive(params->rightCoeff.at(FFBConditionEffectParameters::Axis::X), -0x7FFF, 0x7FFF)) { + QMessageBox::warning(nullptr, CAPTION, "Right X coefficient must be within <-32767; 32767>"); + return false; + } + + if (!checkBoundsInclusive(params->rightCoeff.at(FFBConditionEffectParameters::Axis::Y), -0x7FFF, 0x7FFF)) { + QMessageBox::warning(nullptr, CAPTION, "Right Y coefficient must be within <-32767; 32767>"); + return false; + } + + if (!checkBoundsInclusive(params->deadband.at(FFBConditionEffectParameters::Axis::X), 0, 0xFFFF)) { + QMessageBox::warning(nullptr, CAPTION, "Deadband X must be within <0; 65535>"); + return false; + } + + if (!checkBoundsInclusive(params->deadband.at(FFBConditionEffectParameters::Axis::Y), 0, 0xFFFF)) { + QMessageBox::warning(nullptr, CAPTION, "Deadband Y must be within <0; 65535>"); + return false; + } + + if (!checkBoundsInclusive(params->center.at(FFBConditionEffectParameters::Axis::X), -0x7FFF, 0x7FFF)) { + QMessageBox::warning(nullptr, CAPTION, "Center X must be within <-32767; 32767>"); + return false; + } + + if (!checkBoundsInclusive(params->center.at(FFBConditionEffectParameters::Axis::Y), -0x7FFF, 0x7FFF)) { + QMessageBox::warning(nullptr, CAPTION, "Center Y must be within <-32767; 32767>"); + return false; + } + + m_params = params; + return true; +} + + diff --git a/sdl2ffbconditioneffect.h b/sdl2ffbconditioneffect.h new file mode 100644 index 0000000..ed2345f --- /dev/null +++ b/sdl2ffbconditioneffect.h @@ -0,0 +1,20 @@ +#ifndef SDL2FFBCONDITIONEFFECT_H +#define SDL2FFBCONDITIONEFFECT_H + +#include "sdl2ffbeffect.h" +#include "ffbconditioneffectparameters.h" + +class SDL2FFBConditionEffect : public SDL2FFBEffect +{ +public: + SDL2FFBConditionEffect(); + virtual SDL_HapticEffect* createFFstruct(); + inline const std::shared_ptr parameters() const { return m_params; } + bool setParameters(std::shared_ptr params); + bool setParameters(std::shared_ptr params); + +private: + std::shared_ptr m_params; +}; + +#endif // SDL2FFBCONDITIONEFFECT_H diff --git a/sdl2ffbeffectfactory.cpp b/sdl2ffbeffectfactory.cpp index 8682e90..19fc4b2 100644 --- a/sdl2ffbeffectfactory.cpp +++ b/sdl2ffbeffectfactory.cpp @@ -5,6 +5,8 @@ std::shared_ptr SDL2FFBEffectFactory::createEffect(FFBEffectTypes typ switch (type) { case FFBEffectTypes::NONE: return std::shared_ptr(new FFBNullEffect()); + case FFBEffectTypes::CONDITION: + return std::shared_ptr(new SDL2FFBConditionEffect()); case FFBEffectTypes::CONSTANT: return std::shared_ptr(new SDL2FFBConstantEffect()); default: diff --git a/sdl2ffbeffectfactory.h b/sdl2ffbeffectfactory.h index 1ca167c..14453e4 100644 --- a/sdl2ffbeffectfactory.h +++ b/sdl2ffbeffectfactory.h @@ -4,6 +4,7 @@ #include "globals.h" #include "ffbnulleffect.h" #include "sdl2ffbconstanteffect.h" +#include "sdl2ffbconditioneffect.h" class SDL2FFBEffectFactory { -- 2.43.5