summaryrefslogtreecommitdiff
path: root/common/accel-classic.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'common/accel-classic.hpp')
-rw-r--r--common/accel-classic.hpp121
1 files changed, 93 insertions, 28 deletions
diff --git a/common/accel-classic.hpp b/common/accel-classic.hpp
index 1df888a..c7d6519 100644
--- a/common/accel-classic.hpp
+++ b/common/accel-classic.hpp
@@ -1,36 +1,101 @@
#pragma once
#include <math.h>
+#include <float.h>
-#include "accel-base.hpp"
+#include "rawaccel-settings.h"
namespace rawaccel {
- /// <summary> Struct to hold "classic" (linear raised to power) acceleration implementation. </summary>
- struct classic_impl {
- double accel;
- double power;
- double power_inc;
- double offset;
- double multiplicative_const;
-
- classic_impl(const accel_args& args) :
- accel(args.accel), power(args.exponent - 1), offset(args.offset) {
- multiplicative_const = pow(accel, power);
- power_inc = power + 1;
- }
-
- inline double operator()(double speed) const {
- //f(x) = (mx)^(k-1)
- double base_speed = speed + offset;
- return multiplicative_const * pow(speed, power_inc) / base_speed;
- }
-
- inline double legacy_offset(double speed) const {
- return pow(accel * speed, power);
- }
- };
-
- using accel_classic = additive_accel<classic_impl>;
-
+ /// <summary> Struct to hold "classic" (linear raised to power) acceleration implementation. </summary>
+ struct classic_base {
+ double offset;
+ double power;
+ double accel_raised;
+
+ classic_base(const accel_args& args) :
+ offset(args.offset),
+ power(args.power),
+ accel_raised(pow(args.accel_classic, power - 1)) {}
+
+ double base_fn(double x) const {
+ return accel_raised * pow(x - offset, power) / x;
+ }
+ };
+
+ struct classic_legacy : classic_base {
+ double sens_cap = DBL_MAX;
+ double sign = 1;
+
+ classic_legacy(const accel_args& args) :
+ classic_base(args)
+ {
+ if (args.cap > 0) {
+ sens_cap = args.cap - 1;
+
+ if (sens_cap < 0) {
+ sens_cap = -sens_cap;
+ sign = -sign;
+ }
+ }
+ }
+
+ inline double operator()(double x) const {
+ if (x <= offset) return 1;
+ return sign * minsd(base_fn(x), sens_cap) + 1;
+ }
+ };
+
+ struct classic : classic_base {
+ vec2d gain_cap = { DBL_MAX, DBL_MAX };
+ double constant = 0;
+ double sign = 1;
+
+ classic(const accel_args& args) :
+ classic_base(args)
+ {
+ if (args.cap > 0) {
+ gain_cap.y = args.cap - 1;
+
+ if (gain_cap.y < 0) {
+ gain_cap.y = -gain_cap.y;
+ sign = -sign;
+ }
+
+ gain_cap.x = gain_inverse(gain_cap.y, args.accel_classic, power, offset);
+ constant = (base_fn(gain_cap.x) - gain_cap.y) * gain_cap.x;
+ }
+ }
+
+ double operator()(double x) const {
+ double output;
+
+ if (x <= offset) return 1;
+
+ if (x < gain_cap.x) {
+ output = base_fn(x);
+ }
+ else {
+ output = constant / x + gain_cap.y;
+ }
+
+ return sign * output + 1;
+ }
+
+ static double gain(double x, double accel, double power, double offset)
+ {
+ return power * pow(accel * (x - offset), power - 1);
+ }
+
+ static double gain_inverse(double y, double accel, double power, double offset)
+ {
+ return (accel * offset + pow(y / power, 1 / (power - 1))) / accel;
+ }
+
+ static double gain_accel(double x, double y, double power, double offset)
+ {
+ return -pow(y / power, 1 / (power - 1)) / (offset - x);
+ }
+ };
+
}