From 73be50b30847b71f0284a34b45e2c9fe31a04c73 Mon Sep 17 00:00:00 2001
From: James Turner <zakalawe@mac.com>
Date: Sat, 13 Oct 2018 00:03:30 +0100
Subject: [PATCH] Event-input: axis interpolater support

Expand the range of filtering options on axis values to include the
optional use of an interpolation table, which gives many more options
when dealing with some devices.
---
 src/Input/FGEventInput.cxx | 21 +++++++++++++++++++++
 src/Input/FGEventInput.hxx |  8 ++++++++
 2 files changed, 29 insertions(+)

diff --git a/src/Input/FGEventInput.cxx b/src/Input/FGEventInput.cxx
index 3ca566903..91528c23f 100644
--- a/src/Input/FGEventInput.cxx
+++ b/src/Input/FGEventInput.cxx
@@ -30,6 +30,7 @@
 #include <simgear/io/sg_file.hxx>
 #include <simgear/props/props_io.hxx>
 #include <simgear/math/SGMath.hxx>
+#include <simgear/math/interpolater.hxx>
 #include <Scripting/NasalSys.hxx>
 
 using simgear::PropertyList;
@@ -153,6 +154,17 @@ FGAxisEvent::FGAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node ) :
   lowThreshold = node->getDoubleValue("low-threshold", -0.9);
   highThreshold = node->getDoubleValue("high-threshold", 0.9);
   lastValue = 9999999;
+    
+// interpolation of values
+  if (node->hasChild("interpolater")) {
+    interpolater.reset(new SGInterpTable{node->getChild("interpolater")});
+    mirrorInterpolater = node->getBoolValue("interpolater/mirrored", false);
+  }
+}
+
+FGAxisEvent::~FGAxisEvent()
+{
+    
 }
 
 void FGAxisEvent::fire( FGEventData & eventData )
@@ -170,6 +182,15 @@ void FGAxisEvent::fire( FGEventData & eventData )
   if( minRange != maxRange )
     ed.value = 2.0*(eventData.value-minRange)/(maxRange-minRange)-1.0;
 
+  if (interpolater) {
+    if ((ed.value < 0.0) && mirrorInterpolater) {
+      // mirror the positive interpolation for negative values
+      ed.value = -interpolater->interpolate(fabs(ed.value));
+    } else {
+      ed.value = interpolater->interpolate(ed.value);
+    }
+  }
+    
   FGInputEvent::fire( ed );
 }
 
diff --git a/src/Input/FGEventInput.hxx b/src/Input/FGEventInput.hxx
index 6034b2321..d2990e22a 100644
--- a/src/Input/FGEventInput.hxx
+++ b/src/Input/FGEventInput.hxx
@@ -26,11 +26,15 @@
 #include "FGCommonInput.hxx"
 
 #include <vector>
+#include <memory>
 
 #include "FGButton.hxx"
 #include "FGDeviceConfigurationMap.hxx"
 #include <simgear/structure/subsystem_mgr.hxx>
 
+// forward decls
+class SGInterpTable;
+
 /*
  * A base structure for event data. 
  * To be extended for O/S specific implementation data
@@ -179,6 +183,8 @@ protected:
 class FGAxisEvent : public FGInputEvent {
 public:
   FGAxisEvent( FGInputDevice * device, SGPropertyNode_ptr node );
+  ~FGAxisEvent();
+    
   void SetMaxRange( double value ) { maxRange = value; }
   void SetMinRange( double value ) { minRange = value; }
   void SetRange( double min, double max ) { minRange = min; maxRange = max; }
@@ -192,6 +198,8 @@ protected:
   double lowThreshold;
   double highThreshold;
   double lastValue;
+  std::unique_ptr<SGInterpTable> interpolater;
+  bool mirrorInterpolater = false;
 };
 
 class FGRelAxisEvent : public FGAxisEvent {