summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--common/accel-lookup.hpp113
-rw-r--r--common/accel-natural.hpp4
-rw-r--r--common/rawaccel-base.hpp2
-rw-r--r--common/rawaccel-validate.hpp2
-rw-r--r--wrapper/wrapper.cpp14
5 files changed, 76 insertions, 59 deletions
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index be107f8..f70f2b1 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -3,6 +3,8 @@
#include "rawaccel-base.hpp"
#include "utility.hpp"
+#include <math.h>
+
namespace rawaccel {
struct linear_range {
@@ -55,7 +57,7 @@ namespace rawaccel {
template <typename Lookup>
struct lut_base {
- enum { capacity = LUT_CAPACITY };
+ enum { capacity = SPACED_LUT_CAPACITY };
using value_t = float;
template <typename Func>
@@ -150,20 +152,22 @@ namespace rawaccel {
};
struct si_pair {
- double slope = 0;
- double intercept = 0;
+ float slope = 0;
+ float intercept = 0;
};
struct arbitrary_lut_point {
- double applicable_speed = 0;
+ float applicable_speed = 0;
si_pair slope_intercept = {};
};
struct arbitrary_lut {
+ enum { capacity = SPACED_LUT_CAPACITY / 4 };
+
fp_rep_range range;
- arbitrary_lut_point data[LUT_CAPACITY] = {};
- int log_lookup[LUT_CAPACITY] = {};
- float raw_data_in[LUT_CAPACITY * 2] = {};
+;
+ arbitrary_lut_point data[capacity] = {};
+ int log_lookup[capacity] = {};
double first_point_speed;
double last_point_speed;
int last_arbitrary_index;
@@ -172,27 +176,34 @@ namespace rawaccel {
double operator()(double speed) const
{
int index = 0;
+ int last_arb_index = last_arbitrary_index;
+ int last_log_index = last_log_lookup_index;
- if (speed < first_point_speed)
- {
- // Apply from 0 index
- }
- else if (speed > last_point_speed)
- {
- index = last_arbitrary_index;
- }
- else if (speed > range.stop)
- {
- index = search_from(log_lookup[last_log_lookup_index], speed);
- }
- else if (speed < range.start)
+ if (unsigned(last_arb_index) < capacity &&
+ unsigned(last_log_index) < capacity &&
+ speed > first_point_speed)
{
- index = search_from(0, speed);
- }
- else
- {
- int log_lookup = get_log_index(speed);
- index = search_from(log_lookup, speed);
+ if (speed > last_point_speed)
+ {
+ index = last_arb_index;
+ }
+ else if (speed > range.stop)
+ {
+ int last_log = log_lookup[last_log_index];
+ if (unsigned(last_log) >= capacity) return 1;
+ index = search_from(last_log, last_arb_index, speed);
+ }
+ else if (speed < range.start)
+ {
+ index = search_from(0, last_arb_index, speed);
+ }
+ else
+ {
+ int log_index = get_log_index(speed);
+ if (unsigned(log_index) >= capacity) return 1;
+ index = search_from(log_index, last_arb_index, speed);
+ }
+
}
return apply(index, speed);
@@ -205,7 +216,7 @@ namespace rawaccel {
return index;
}
- int inline search_from(int index, double speed) const
+ int inline search_from(int index, int last, double speed) const
{
int prev_index;
@@ -214,7 +225,7 @@ namespace rawaccel {
prev_index = index;
index++;
}
- while (index <= last_arbitrary_index && data[index].applicable_speed < speed);
+ while (index <= last && data[index].applicable_speed < speed);
index--;
@@ -227,10 +238,22 @@ namespace rawaccel {
return pair.slope + pair.intercept / speed;
}
- void fill(float* points, int length)
+
+ void fill(vec2<float>* points, int length)
{
- vec2d current = {0, 0};
- vec2d next;
+ first_point_speed = points[0].x;
+ // -2 because the last index in the arbitrary array is used for slope-intercept only
+ last_arbitrary_index = length - 2;
+ last_point_speed = points[last_arbitrary_index].x;
+
+ int start = static_cast<int>(floor(log(first_point_speed)));
+ int end = static_cast<int>(floor(log(last_point_speed)));
+ int num = static_cast<int>(capacity / (end - start));
+ range = fp_rep_range{ start, end, num };
+ last_log_lookup_index = num * (end - start) - 1;
+
+ vec2<float> current = {0, 0};
+ vec2<float> next;
int log_index = 0;
double log_inner_iterator = range.start;
double log_inner_slice = 1 / range.num;
@@ -238,17 +261,23 @@ namespace rawaccel {
for (int i = 0; i < length; i++)
{
- next = vec2d{ points[i * 2], points[i * 2 + 1] };
+ next = points[i];
double slope = (next.y - current.y) / (next.x - current.x);
double intercept = next.y - slope * next.x;
- si_pair current_si = { slope, intercept };
- arbitrary_lut_point current_lut_point = { next.x, current_si };
+ si_pair current_si = {
+ static_cast<float>(slope),
+ static_cast<float>(intercept)
+ };
+ arbitrary_lut_point current_lut_point = {
+ static_cast<float>(next.x),
+ current_si
+ };
this->data[i] = current_lut_point;
while (log_value < next.x)
{
- this->log_lookup[log_index] = log_value;
+ this->log_lookup[log_index] = static_cast<int>(log_value);
log_index++;
log_inner_iterator += log_inner_slice;
log_value = pow(2, log_inner_iterator);
@@ -256,20 +285,8 @@ namespace rawaccel {
}
}
- arbitrary_lut(const table_args &args)
+ arbitrary_lut(const accel_args&)
{
- first_point_speed = raw_data_in[0];
- // -2 because the last index in the arbitrary array is used for slope-intercept only
- last_arbitrary_index = (length - 2)*2;
- last_point_speed = raw_data_in[last_arbitrary_index];
-
- double start = (int)floor(log(first_point_speed));
- double end = (int)floor(log(last_point_speed));
- double num = (int)floor(LUT_CAPACITY / (end - start));
- range = fp_rep_range{ start, end, num };
- last_log_lookup_index = num * (end - start) - 1;
-
- fill(raw_data_in, length);
}
};
}
diff --git a/common/accel-natural.hpp b/common/accel-natural.hpp
index 8d25351..9f76d1a 100644
--- a/common/accel-natural.hpp
+++ b/common/accel-natural.hpp
@@ -28,7 +28,7 @@ namespace rawaccel {
double offset_x = offset - x;
double decay = exp(accel * offset_x);
- return limit * (1 - (decay * offset_x + offset) / x) + 1;
+ return limit * (1 - (offset - decay * offset_x) / x) + 1;
}
using natural_base::natural_base;
@@ -43,7 +43,7 @@ namespace rawaccel {
double offset_x = offset - x;
double decay = exp(accel * offset_x);
- double output = limit * (offset_x + decay / accel) + constant;
+ double output = limit * (decay / accel - offset_x) + constant;
return output / x + 1;
}
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index dde56f5..2f49ec0 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -15,7 +15,7 @@ namespace rawaccel {
inline constexpr size_t MAX_DEV_ID_LEN = 200;
- inline constexpr size_t LUT_CAPACITY = 1025;
+ inline constexpr size_t SPACED_LUT_CAPACITY = 1025;
inline constexpr double MAX_NORM = 16;
inline constexpr double PI = 3.14159265358979323846;
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
index 4f7dd9c..ef6f667 100644
--- a/common/rawaccel-validate.hpp
+++ b/common/rawaccel-validate.hpp
@@ -27,7 +27,7 @@ namespace rawaccel {
};
auto check_accel = [&error](const accel_args& args) {
- static_assert(LUT_CAPACITY == 1025, "update error msg");
+ static_assert(SPACED_LUT_CAPACITY == 1025, "update error msg");
const auto& lut_args = args.lut_args;
diff --git a/wrapper/wrapper.cpp b/wrapper/wrapper.cpp
index 263f019..f901ce1 100644
--- a/wrapper/wrapper.cpp
+++ b/wrapper/wrapper.cpp
@@ -187,9 +187,9 @@ public ref struct ArbitraryLut sealed : public LutBase
virtual void SetData(ra::accel_union& accel) override
{
pin_ptr<float> pdata = &data[0,0];
- std::memcpy(&accel.arb_lut.raw_data_in, pdata, sizeof(float) * data->Length * 2);
- }
+ accel.arb_lut.fill(pdata, data->Length);
+ }
};
[JsonObject(ItemRequired = Required::Always)]
@@ -211,7 +211,7 @@ public ref struct SpacedLut abstract : public LutBase
void SetDataBase(ra::accel_union& accel)
{
- if (size_t(data->LongLength) > ra::LUT_CAPACITY) {
+ if (size_t(data->LongLength) > ra::SPACED_LUT_CAPACITY) {
throw gcnew InteropException("data is too large");
}
}
@@ -518,9 +518,9 @@ public:
auto settings = gcnew ExtendedSettings();
Marshal::PtrToStructure(IntPtr(&instance->data.args), settings->baseSettings);
settings->tables.x = extract(instance->data.args.argsv.x.lut_args.mode,
- instance->data.mod.accels.x);
+ instance->data.mod.accel.x);
settings->tables.y = extract(instance->data.args.argsv.y.lut_args.mode,
- instance->data.mod.accels.y);
+ instance->data.mod.accel.y);
return settings;
}
@@ -531,11 +531,11 @@ public:
instance->inv = ra::invokers(instance->data.args);
if (val->tables.x) {
- val->tables.x->SetData(instance->data.mod.accels.x);
+ val->tables.x->SetData(instance->data.mod.accel.x);
}
if (val->tables.y) {
- val->tables.y->SetData(instance->data.mod.accels.y);
+ val->tables.y->SetData(instance->data.mod.accel.y);
}
}