summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/accel-classic.hpp14
-rw-r--r--common/accel-natural.hpp2
-rw-r--r--common/accel-power.hpp225
-rw-r--r--common/rawaccel-base.hpp5
-rw-r--r--common/rawaccel-validate.hpp15
5 files changed, 102 insertions, 159 deletions
diff --git a/common/accel-classic.hpp b/common/accel-classic.hpp
index c230bb4..ca0651c 100644
--- a/common/accel-classic.hpp
+++ b/common/accel-classic.hpp
@@ -11,13 +11,13 @@ namespace rawaccel {
struct classic_base {
double base_fn(double x, double accel_raised, const accel_args& args) const
{
- return accel_raised * pow(x - args.offset, args.exponent_classic) / x;
+ return accel_raised * pow(x - args.input_offset, args.exponent_classic) / x;
}
static double base_accel(double x, double y, const accel_args& args)
{
auto power = args.exponent_classic;
- return pow(x * y * pow(x - args.offset, -power), 1 / (power - 1));
+ return pow(x * y * pow(x - args.input_offset, -power), 1 / (power - 1));
}
};
@@ -70,7 +70,7 @@ namespace rawaccel {
double operator()(double x, const accel_args& args) const
{
- if (x <= args.offset) return 1;
+ if (x <= args.input_offset) return 1;
return sign * minsd(base_fn(x, accel_raised, args), cap) + 1;
}
@@ -96,7 +96,7 @@ namespace rawaccel {
}
{
- double a = gain_accel(cap.x, cap.y, args.exponent_classic, args.offset);
+ double a = gain_accel(cap.x, cap.y, args.exponent_classic, args.input_offset);
accel_raised = pow(a, args.exponent_classic - 1);
}
constant = (base_fn(cap.x, accel_raised, args) - cap.y) * cap.x;
@@ -105,7 +105,7 @@ namespace rawaccel {
accel_raised = pow(args.acceleration, args.exponent_classic - 1);
if (args.cap.x > 0) {
cap.x = args.cap.x;
- cap.y = gain(cap.x, args.acceleration, args.exponent_classic, args.offset);
+ cap.y = gain(cap.x, args.acceleration, args.exponent_classic, args.input_offset);
constant = (base_fn(cap.x, accel_raised, args) - cap.y) * cap.x;
}
break;
@@ -121,7 +121,7 @@ namespace rawaccel {
sign = -sign;
}
- cap.x = gain_inverse(cap.y, args.acceleration, args.exponent_classic, args.offset);
+ cap.x = gain_inverse(cap.y, args.acceleration, args.exponent_classic, args.input_offset);
constant = (base_fn(cap.x, accel_raised, args) - cap.y) * cap.x;
}
break;
@@ -132,7 +132,7 @@ namespace rawaccel {
{
double output;
- if (x <= args.offset) return 1;
+ if (x <= args.input_offset) return 1;
if (x < cap.x) {
output = base_fn(x, accel_raised, args);
diff --git a/common/accel-natural.hpp b/common/accel-natural.hpp
index 6f30a38..9d615a9 100644
--- a/common/accel-natural.hpp
+++ b/common/accel-natural.hpp
@@ -11,7 +11,7 @@ namespace rawaccel {
double limit;
natural_base(const accel_args& args) :
- offset(args.offset),
+ offset(args.input_offset),
limit(args.limit - 1)
{
accel = args.decay_rate / fabs(limit);
diff --git a/common/accel-power.hpp b/common/accel-power.hpp
index 014acae..ffbadb0 100644
--- a/common/accel-power.hpp
+++ b/common/accel-power.hpp
@@ -7,10 +7,66 @@
namespace rawaccel {
struct power_base {
- static double base_fn(double x, double scale, const accel_args& args)
+ vec2d offset;
+ double scale;
+ double constant;
+
+ power_base(const accel_args& args)
+ {
+ auto n = args.exponent_power;
+
+ if (args.cap_mode != classic_cap_mode::io) {
+ scale = args.scale;
+ }
+ else if (args.gain) {
+ scale = scale_from_gain_point(args.cap.x, args.cap.y, n);
+ }
+ else {
+ /*
+ * special case for legacy + io cap mode
+ *
+ * offset is ignored because of the circular dependency:
+ * scale -> constant -> offset
+ */
+ offset = {};
+ constant = 0;
+ scale = scale_from_sens_point(args.cap.x, args.cap.y, n, constant);
+ return;
+ }
+
+ offset.x = gain_inverse(args.output_offset, n, scale);
+ offset.y = args.output_offset;
+ constant = offset.x * offset.y * n / (n + 1);
+ }
+
+ double base_fn(double x, const accel_args& args) const
{
- // f(x) = w(mx)^k
- return pow(scale * x, args.exponent_power);
+ if (x <= offset.x) {
+ return offset.y;
+ }
+ else {
+ return pow(scale * x, args.exponent_power) + constant / x;
+ }
+ }
+
+ static double gain(double input, double power, double scale)
+ {
+ return (power + 1) * pow(input * scale, power);
+ }
+
+ static double gain_inverse(double gain, double power, double scale)
+ {
+ return pow(gain / (power + 1), 1 / power) / scale;
+ }
+
+ static double scale_from_gain_point(double input, double gain, double power)
+ {
+ return pow(gain / (power + 1), 1 / power) / input;
+ }
+
+ static double scale_from_sens_point(double input, double sens, double power, double C)
+ {
+ return pow(sens - C / input, 1 / power) / input;
}
};
@@ -19,88 +75,44 @@ namespace rawaccel {
template <>
struct power<LEGACY> : power_base {
double cap = DBL_MAX;
- double scale = 0;
- power(const accel_args& args)
+ power(const accel_args& args) :
+ power_base(args)
{
- // Note that cap types may overwrite scale below.
- scale = args.scale;
switch (args.cap_mode){
- case classic_cap_mode::in:
- if (args.cap.x > 0)
- {
- cap = base_fn(
- args.cap.x,
- args.scale,
- args);
- }
- break;
case classic_cap_mode::io:
- if (args.cap.x > 0 &&
- args.cap.y > 1)
- {
- cap = args.cap.y;
- scale = scale_from_sens_point(
- args.cap.y,
- args.cap.x,
- args.exponent_power);
- }
+ cap = args.cap.y;
+ break;
+ case classic_cap_mode::in:
+ if (args.cap.x > 0) cap = base_fn(args.cap.x, args);
break;
case classic_cap_mode::out:
default:
- if (args.cap.y > 1)
- {
- cap = args.cap.y;
- }
+ if (args.cap.y > 0) cap = args.cap.y;
break;
}
- /*
- if (args.cap.x > 0) {
- cap.x = args.cap.x;
- cap.y = base_fn(cap.x, args);
- }
- */
}
double operator()(double speed, const accel_args& args) const
{
- if (args.powerStartFromOne) {
- return minsd(maxsd(base_fn(speed, scale, args), 1), cap);
- }
- else {
- return minsd(base_fn(speed, scale, args), cap);
- }
+ return minsd(base_fn(speed, args), cap);
}
- double static scale_from_sens_point(double sens, double input, double power)
- {
- return pow(sens, 1 / power) / input;
- }
};
template <>
struct power<GAIN> : power_base {
vec2d cap = { DBL_MAX, DBL_MAX };
- double constant = 0;
- double scale = 0;
- vec2d startFromOne{ 0, 0 };
+ double constant_b;
- power(const accel_args& args)
+ power(const accel_args& args) :
+ power_base(args)
{
- /*
- if (args.cap.x > 0) {
- cap.x = args.cap.x;
- double output = base_fn(cap.x, args);
- cap.y = output * (args.exponent_power + 1);
- constant = -args.exponent_power * output * args.cap.x;
- }
- */
-
- // Note that cap types may overwrite this below.
- scale = args.scale;
-
switch (args.cap_mode) {
+ case classic_cap_mode::io:
+ cap = args.cap;
+ break;
case classic_cap_mode::in:
if (args.cap.x > 0) {
cap.x = args.cap.x;
@@ -110,111 +122,32 @@ namespace rawaccel {
scale);
}
break;
- case classic_cap_mode::io:
- if (args.cap.x > 0 &&
- args.cap.y > 1) {
- cap.x = args.cap.x;
- cap.y = args.cap.y;
- scale = scale_from_gain_point(
- args.cap.x,
- args.cap.y,
- args.exponent_power);
- }
- break;
case classic_cap_mode::out:
default:
- if (args.cap.y > 1) {
- cap.y = args.cap.y;
+ if (args.cap.y > 0) {
cap.x = gain_inverse(
args.cap.y,
args.exponent_power,
scale);
+ cap.y = args.cap.y;
}
break;
}
- if (args.powerStartFromOne)
- {
- startFromOne.x = gain_inverse(
- 1,
- args.exponent_power,
- scale);
- startFromOne.y = -1 * integration_constant(startFromOne.x,
- 1,
- base_fn(startFromOne.x, scale, args));
- }
-
- if (cap.x < DBL_MAX && cap.y < DBL_MAX)
- {
- if (args.powerStartFromOne) {
- constant = integration_constant(
- cap.x,
- cap.y,
- startFromOneOutput(
- startFromOne,
- cap.x,
- scale,
- args));
- }
- else {
- constant = integration_constant(
- cap.x,
- cap.y,
- base_fn(cap.x, scale, args));
- }
- }
-
+ constant_b = integration_constant(cap.x, cap.y, base_fn(cap.x, args));
}
double operator()(double speed, const accel_args& args) const
{
if (speed < cap.x) {
- if (args.powerStartFromOne) {
- return startFromOneOutput(
- startFromOne,
- speed,
- scale,
- args);
- }
- else {
- return base_fn(speed, scale, args);
- }
+ return base_fn(speed, args);
}
else {
- return cap.y + constant / speed;
- }
- }
-
- double static startFromOneOutput(
- const vec2d& startFromOne,
- double speed,
- double scale,
- const accel_args& args)
- {
- if (speed > startFromOne.x) {
- return base_fn(speed, scale, args) + startFromOne.y / speed;
- }
- else
- {
- return 1;
+ return cap.y + constant_b / speed;
}
}
- double static gain_inverse(double gain, double power, double scale)
- {
- return pow(gain / (power + 1), 1 / power) / scale;
- }
- double static gain(double input, double power, double scale)
- {
- return (power + 1) * pow(input * scale, power);
- }
-
- double static scale_from_gain_point(double input, double gain, double power)
- {
- return pow(gain / (power + 1), 1 / power) / input;
- }
-
- double static integration_constant(double input, double gain, double output)
+ static double integration_constant(double input, double gain, double output)
{
return (output - gain) * input;
}
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index 08d42c6..cee1a3e 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -42,7 +42,8 @@ namespace rawaccel {
accel_mode mode = accel_mode::noaccel;
bool gain = 1;
- double offset = 0;
+ double input_offset = 0;
+ double output_offset = 0;
double acceleration = 0.005;
double decay_rate = 0.1;
double growth_rate = 1;
@@ -53,7 +54,7 @@ namespace rawaccel {
double limit = 1.5;
double midpoint = 5;
double smooth = 0.5;
- bool powerStartFromOne = true;
+
vec2d cap = { 15, 1.5 };
classic_cap_mode cap_mode = classic_cap_mode::out;
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
index a88d514..23deb5f 100644
--- a/common/rawaccel-validate.hpp
+++ b/common/rawaccel-validate.hpp
@@ -50,16 +50,20 @@ namespace rawaccel {
error("data size > max");
}
- if (args.offset < 0) {
+ if (args.input_offset < 0) {
error("offset can not be negative");
}
- else if (args.mode == accel_mode::jump && args.offset == 0) {
+ else if (args.mode == accel_mode::jump && args.input_offset == 0) {
error("offset can not be 0");
}
+ if (args.output_offset < 0) {
+ error("offset can not be negative");
+ }
+
bool jump_or_io_cap =
(args.mode == accel_mode::jump ||
- (args.mode == accel_mode::classic &&
+ ((args.mode == accel_mode::classic || args.mode == accel_mode::power) &&
args.cap_mode == classic_cap_mode::io));
if (args.cap.x < 0) {
@@ -76,6 +80,11 @@ namespace rawaccel {
error("cap (output) can not be 0");
}
+ if (args.cap.x > 0 && args.cap.x < args.input_offset ||
+ args.cap.y > 0 && args.cap.y < args.output_offset) {
+ error("cap < offset");
+ }
+
if (args.growth_rate <= 0 ||
args.decay_rate <= 0 ||
args.acceleration <= 0) {