]> Devoid-pointer.net GitWeb - FFBChecker.git/commitdiff
- Query haptic devices directly insted of joysticks in SDL interface
authorMichal Malý <madcatxster@devoid-pointer.net>
Fri, 31 Jul 2015 00:26:27 +0000 (02:26 +0200)
committerMichal Malý <madcatxster@devoid-pointer.net>
Fri, 31 Jul 2015 00:26:27 +0000 (02:26 +0200)
- Continue implementation of SDL2 interface

CMakeLists.txt
sdl2deviceprober.cpp
sdl2deviceprober.h
sdl2ffbdevice.cpp [new file with mode: 0644]
sdl2ffbdevice.h [new file with mode: 0644]
sdl2ffbeffectfactory.cpp [new file with mode: 0644]
sdl2ffbeffectfactory.h [new file with mode: 0644]

index b6231d80836abc3fb76b0b6cfa8e05ab87b7354d..3ce373741af31765862d54d14e259d65984d2db6 100644 (file)
@@ -20,7 +20,7 @@ set(CMAKE_AUTOMOC ON)
 set(CMAKE_AUTOUIC ON)
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
-set(FFBChecker_SRCS
+set(FFBChecker_SRCS sdl2ffbeffectfactory.cpp sdl2ffbdevice.cpp
     conditioneffectsettings.cpp
     constanteffectsettings.cpp
     effectsettings.cpp
index 0934463b149b55ff08f7f20176a18d68c2210a01..3d40bd590f05a5781977f98c7333f201ddd486d9 100644 (file)
@@ -30,38 +30,23 @@ void SDL2DeviceProber::closeAllDevices()
   return;
 }
 
-
 DeviceProber::DeviceList SDL2DeviceProber::listDevices()
 {
   DeviceProber::DeviceList devList;
-  int numJoy;
+  int numHapt;
 
   if (!s_SDLInited)
     return devList;
 
-  numJoy = SDL_NumJoysticks();
+  numHapt = SDL_NumHaptics();
 
-  for (int idx = 0; idx < numJoy; idx++) {
+  for (int idx = 0; idx < numHapt; idx++) {
     DeviceProber::DeviceInfo dinfo;
 
-    SDL_Joystick* joystick = SDL_JoystickOpen(idx);
-
-    if (joystick == nullptr) {
-      qDebug() << "SDL2: Cannot open joystick at idx" << idx;
-      continue;
-    }
-
-    if (SDL_JoystickIsHaptic(joystick) != 1) {
-      qDebug() << "SDL2: Joystick at idx" << idx << "does not support force feedback";
-      SDL_JoystickClose(joystick);
-      continue;
-    }
-
-    dinfo.name = QString(SDL_JoystickName(joystick));
+    dinfo.name = QString(SDL_HapticName(idx));
     dinfo.id = QVariant(idx);
 
     devList.push_back(dinfo);
-    SDL_JoystickClose(joystick);
   }
 
   return devList;
@@ -69,9 +54,39 @@ DeviceProber::DeviceList SDL2DeviceProber::listDevices()
 
 std::shared_ptr<FFBDevice> SDL2DeviceProber::openDevice(const QString& id)
 {
+  SDL_Haptic* haptic;
+  std::shared_ptr<SDL2FFBDevice> device;
+  int idx;
+  int maxEffectCount;
+  bool ok;
+
   if (!s_SDLInited)
     return nullptr;
 
-  return nullptr;
+  idx = id.toInt(&ok);
+  if (!ok)
+    return nullptr;
+
+  haptic = SDL_HapticOpen(idx);
+  if (haptic == nullptr)
+    return nullptr;
+
+  maxEffectCount = SDL_HapticNumEffects(haptic);
+  if (maxEffectCount < 1) {
+    QMessageBox::critical(nullptr, "SDL2 device error", "Maximum effect count for this device is zero.");
+    SDL_HapticClose(haptic);
+    return nullptr;
+  }
+
+  device = std::make_shared<SDL2FFBDevice>(haptic, maxEffectCount);
+  if (!device->queryDeviceCapabilities()) {
+    QMessageBox::critical(nullptr, "SDL2 device error", "Unable to query device capabilities.");
+    device->close();
+    return nullptr;
+  }
+
+  m_openedDevices.push_back(device);
+  return device;
 }
 
+
index ae10f4d368f31f51bf7a34d10669672e35f12549..a6cb90b112c0bf23f1331950cb04d163f4cfbf19 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "deviceprober.h"
 #include "SDL.h"
+#include "sdl2ffbdevice.h"
+#include <list>
 
 class SDL2DeviceProber : public DeviceProber
 {
@@ -15,6 +17,8 @@ public:
   std::shared_ptr<FFBDevice> openDevice(const QString& id);
 
 private:
+  std::list<std::shared_ptr<SDL2FFBDevice>> m_openedDevices;
+
   static bool s_SDLInited;
 
 
diff --git a/sdl2ffbdevice.cpp b/sdl2ffbdevice.cpp
new file mode 100644 (file)
index 0000000..5405fe5
--- /dev/null
@@ -0,0 +1,94 @@
+#include "sdl2ffbdevice.h"
+#include "sdl2ffbeffectfactory.h"
+
+SDL2FFBDevice::SDL2FFBDevice(SDL_Haptic* haptic, const int maxEffectCount) :
+    FFBDevice(maxEffectCount),
+    c_haptic(haptic)
+{
+  for (int i = 0; i < maxEffectCount; i++)
+    m_effects.push_back(SDL2FFBEffectFactory::createEffect(FFBEffectTypes::NONE));
+}
+
+void SDL2FFBDevice::close()
+{
+  SDL_HapticClose(c_haptic);
+}
+
+bool SDL2FFBDevice::queryDeviceCapabilities()
+{
+  unsigned int caps;
+  bool hasPeriodic = false;
+  bool hasCondition = false;
+
+  caps = SDL_HapticQuery(c_haptic);
+  if (caps == 0)
+    return false;
+
+  if (caps & SDL_HAPTIC_CONSTANT)
+    m_availableEffects.push_back(FFBEffectTypes::CONSTANT);
+
+  if (caps & SDL_HAPTIC_SINE) {
+    hasPeriodic = true;
+    m_availablePeriodicWaveforms.push_back(PeriodicWaveforms::SINE);
+  }
+  if (caps & SDL_HAPTIC_TRIANGLE) {
+    hasPeriodic = true;
+    m_availablePeriodicWaveforms.push_back(PeriodicWaveforms::TRIANGLE);
+  }
+  if (caps & SDL_HAPTIC_SAWTOOTHUP) {
+    hasPeriodic = true;
+    m_availablePeriodicWaveforms.push_back(PeriodicWaveforms::SAW_UP);
+  }
+  if (caps & SDL_HAPTIC_SAWTOOTHDOWN) {
+    hasPeriodic = true;
+    m_availablePeriodicWaveforms.push_back(PeriodicWaveforms::SAW_DOWN);
+  }
+  if (hasPeriodic)
+    m_availableEffects.push_back(FFBEffectTypes::PERIODIC);
+
+  if (caps & SDL_HAPTIC_RAMP)
+    m_availableEffects.push_back(FFBEffectTypes::RAMP);
+
+  if (caps & SDL_HAPTIC_SPRING) {
+    hasCondition = true;
+    m_availableConditionSubtypes.push_back(ConditionSubtypes::SPRING);
+  }
+  if (caps & SDL_HAPTIC_DAMPER) {
+    hasCondition = true;
+    m_availableConditionSubtypes.push_back(ConditionSubtypes::DAMPER);
+  }
+  if (caps & SDL_HAPTIC_INERTIA) {
+    hasCondition = true;
+    m_availableConditionSubtypes.push_back(ConditionSubtypes::INERTIA);
+  }
+  if (caps & SDL_HAPTIC_FRICTION) {
+    hasCondition = true;
+    m_availableConditionSubtypes.push_back(ConditionSubtypes::FRICTION);
+  }
+
+  if (hasCondition)
+    m_availableEffects.push_back(FFBEffectTypes::CONDITION);
+
+  return true;
+}
+
+bool SDL2FFBDevice::removeAndEraseEffect(const int idx)
+{
+  return false;
+}
+
+bool SDL2FFBDevice::startEffect(const int idx, const FFBEffectTypes type, std::shared_ptr< FFBEffectParameters > parameters)
+{
+  return false;
+}
+
+bool SDL2FFBDevice::stopEffect(const int idx)
+{
+  return false;
+}
+
+bool SDL2FFBDevice::uploadEffect(const int idx, const FFBEffectTypes type, std::shared_ptr< FFBEffectParameters > parameters)
+{
+  return false;
+}
+
diff --git a/sdl2ffbdevice.h b/sdl2ffbdevice.h
new file mode 100644 (file)
index 0000000..e1acae6
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef SDL2FFBDEVICE_H
+#define SDL2FFBDEVICE_H
+
+#include "SDL.h"
+#include "ffbdevice.h"
+
+class SDL2FFBDevice : public FFBDevice {
+public:
+  SDL2FFBDevice(SDL_Haptic* haptic, const int maxEffectCount);
+  void close();
+  bool queryDeviceCapabilities();
+  bool removeAndEraseEffect(const int idx);
+  bool startEffect(const int idx, const FFBEffectTypes type, std::shared_ptr<FFBEffectParameters> parameters);
+  bool stopEffect(const int idx);
+  bool uploadEffect(const int idx, const FFBEffectTypes type, std::shared_ptr<FFBEffectParameters> parameters);
+
+private:
+  SDL_Haptic* c_haptic;
+};
+
+#endif // SDL2FFBDEVICE_H
\ No newline at end of file
diff --git a/sdl2ffbeffectfactory.cpp b/sdl2ffbeffectfactory.cpp
new file mode 100644 (file)
index 0000000..5ace543
--- /dev/null
@@ -0,0 +1,11 @@
+#include "sdl2ffbeffectfactory.h"
+
+std::shared_ptr<FFBEffect> SDL2FFBEffectFactory::createEffect(FFBEffectTypes type)
+{
+  switch (type) {
+    case FFBEffectTypes::NONE:
+      return std::shared_ptr<FFBEffect>(new FFBNullEffect());
+    default:
+      return std::shared_ptr<FFBEffect>(new FFBNullEffect());
+  }
+}
\ No newline at end of file
diff --git a/sdl2ffbeffectfactory.h b/sdl2ffbeffectfactory.h
new file mode 100644 (file)
index 0000000..599b021
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef SDL2FFBEFFECTFACTORY_H
+#define SDL2FFBEFFECTFACTORY_H
+
+#include "globals.h"
+#include "ffbnulleffect.h"
+
+class SDL2FFBEffectFactory
+{
+public:
+  static std::shared_ptr<FFBEffect> createEffect(FFBEffectTypes type);
+
+  SDL2FFBEffectFactory() = delete;
+};
+
+#endif // LINUXFFBEFFECTFACTORY_H