From 16dc4df3d438142ae378c9c6983585d06e0c6a33 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Mon, 29 Mar 2021 17:14:49 -0400
Subject: refactor common/settings
only driver compiles
remove accel-base types
merge linear + classic
move gain cap logic into classic impl, cap is now set in terms of output
use cap/limit to determine negation
remove weight, add replacement for power mode only
remove legacy offset option
remove naturalgain mode
add legacy mode flag
naturalgain -> natural
natural -> natural + legacy flag
add dpi setting and more accel args + defaults (prep for ips mode)
replace output speed cap with input cap
---
common/accel-base.hpp | 66 ------------
common/accel-classic.hpp | 121 ++++++++++++++++------
common/accel-linear.hpp | 31 ------
common/accel-motivity.hpp | 12 +--
common/accel-natural.hpp | 48 ++++++---
common/accel-naturalgain.hpp | 28 ------
common/accel-noaccel.hpp | 4 +-
common/accel-power.hpp | 18 ++--
common/common.vcxitems | 5 +-
common/rawaccel-settings.h | 50 ++++++++--
common/rawaccel.hpp | 233 +++++++++++++------------------------------
11 files changed, 253 insertions(+), 363 deletions(-)
delete mode 100644 common/accel-base.hpp
delete mode 100644 common/accel-linear.hpp
delete mode 100644 common/accel-naturalgain.hpp
(limited to 'common')
diff --git a/common/accel-base.hpp b/common/accel-base.hpp
deleted file mode 100644
index 42b3bb1..0000000
--- a/common/accel-base.hpp
+++ /dev/null
@@ -1,66 +0,0 @@
-#pragma once
-
-namespace rawaccel {
-
- /// Struct to hold arguments for an acceleration function.
- struct accel_args {
- double offset = 0;
- bool legacy_offset = false;
- double accel = 0;
- double scale = 1;
- double limit = 2;
- double exponent = 2;
- double midpoint = 10;
- double weight = 1;
- double scale_cap = 0;
- double gain_cap = 0;
- double speed_cap = 0;
- };
-
- struct domain_args {
- vec2d domain_weights = { 1, 1 };
- double lp_norm = 2;
- };
-
- template
- struct accel_val_base {
- bool legacy_offset = false;
- double offset = 0;
- double weight = 1;
- Func fn;
-
- accel_val_base(const accel_args& args) : fn(args) {}
-
- };
-
- template
- struct additive_accel : accel_val_base {
-
- additive_accel(const accel_args& args) : accel_val_base(args) {
- this->legacy_offset = args.legacy_offset;
- this->offset = args.offset;
- this->weight = args.weight;
- }
-
- inline double operator()(double speed) const {
- double offset_speed = speed - this->offset;
- if (offset_speed <= 0) return 1;
- if (this->legacy_offset) return 1 + this->fn.legacy_offset(offset_speed) * this->weight;
- return 1 + this->fn(offset_speed) * this->weight;
- }
- };
-
- template
- struct nonadditive_accel : accel_val_base {
-
- nonadditive_accel(const accel_args& args) : accel_val_base(args) {
- if (args.weight > 0) this->weight = args.weight;
- }
-
- inline double operator()(double speed) const {
- return this->fn(speed) * this->weight;
- }
-
- };
-
-}
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
+#include
-#include "accel-base.hpp"
+#include "rawaccel-settings.h"
namespace rawaccel {
- /// Struct to hold "classic" (linear raised to power) acceleration implementation.
- 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;
-
+ /// Struct to hold "classic" (linear raised to power) acceleration implementation.
+ 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);
+ }
+ };
+
}
diff --git a/common/accel-linear.hpp b/common/accel-linear.hpp
deleted file mode 100644
index 2bd57b8..0000000
--- a/common/accel-linear.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#pragma once
-
-#include "accel-base.hpp"
-
-namespace rawaccel {
-
- /// Struct to hold linear acceleration implementation.
- struct linear_impl {
- double accel;
- double offset;
- double subtractive_const;
- double divisive_const;
-
- linear_impl(const accel_args& args) : accel(args.accel), offset(args.offset) {
- subtractive_const = 2 * accel * offset;
- divisive_const = accel * offset * offset;
- }
-
- inline double operator()(double speed) const {
- double base_speed = speed + offset;
- return accel * base_speed - subtractive_const + divisive_const / base_speed;
- }
-
- inline double legacy_offset(double speed) const {
- return accel * speed;
- }
- };
-
- using accel_linear = additive_accel;
-
-}
diff --git a/common/accel-motivity.hpp b/common/accel-motivity.hpp
index 246cf37..abeedf1 100644
--- a/common/accel-motivity.hpp
+++ b/common/accel-motivity.hpp
@@ -2,7 +2,7 @@
#include
-#include "accel-base.hpp"
+#include "rawaccel-settings.h"
#define RA_LOOKUP
@@ -16,14 +16,14 @@ namespace rawaccel {
};
/// Struct to hold sigmoid (s-shaped) gain implementation.
- struct motivity_impl {
+ struct motivity {
double rate;
double limit;
double midpoint;
double subtractive_constant;
- motivity_impl(const accel_args& args) :
- rate(pow(10,args.accel)), limit(2*log10(args.limit)), midpoint(log10(args.midpoint))
+ motivity(const accel_args& args) :
+ rate(pow(10,args.accel_motivity)), limit(2*log10(args.limit)), midpoint(log10(args.midpoint))
{
subtractive_constant = limit / 2;
}
@@ -34,8 +34,6 @@ namespace rawaccel {
}
- inline double legacy_offset(double speed) const { return operator()(speed); }
-
inline double apply(si_pair* lookup, double speed) const
{
si_pair pair = lookup[map(speed)];
@@ -96,6 +94,4 @@ namespace rawaccel {
}
};
- using accel_motivity = nonadditive_accel;
-
}
diff --git a/common/accel-natural.hpp b/common/accel-natural.hpp
index 03700c1..2939dbd 100644
--- a/common/accel-natural.hpp
+++ b/common/accel-natural.hpp
@@ -2,34 +2,52 @@
#include
-#include "accel-base.hpp"
+#include "rawaccel-settings.h"
namespace rawaccel {
/// Struct to hold "natural" (vanishing difference) acceleration implementation.
- struct natural_impl {
- double rate;
- double limit;
+ struct natural_base {
double offset;
+ double accel;
+ double limit;
- natural_impl(const accel_args& args) :
- rate(args.accel), limit(args.limit - 1), offset(args.offset)
+ natural_base(const accel_args& args) :
+ offset(args.offset),
+ limit(args.limit - 1)
{
- rate /= limit;
+ accel = args.accel_natural / fabs(limit);
}
+ };
- inline double operator()(double speed) const {
- // f(x) = k(1-e^(-mx))
- double base_speed = speed + offset;
- return limit * (1 - ((exp(-rate * speed) * speed + offset) / base_speed));
- }
+ struct natural_legacy : natural_base {
+
+ double operator()(double x) const {
+ if (x <= offset) return 1;
- inline double legacy_offset(double speed) const {
- return limit - (limit * exp(-rate * speed));
+ double offset_x = x - offset;
+ double decay = exp(-accel * offset_x);
+ return limit * (1 - (decay * offset_x + offset) / x) + 1;
}
+ using natural_base::natural_base;
};
- using accel_natural = additive_accel;
+ struct natural : natural_base {
+ double constant;
+
+ double operator()(double x) const {
+ if (x <= offset) return 1;
+
+ double offset_x = x - offset;
+ double decay = exp(-accel * offset_x);
+ double output = limit * (offset_x + decay / accel) + constant;
+ return output / x + 1;
+ }
+
+ natural(const accel_args& args) :
+ natural_base(args),
+ constant(-limit / accel) {}
+ };
}
diff --git a/common/accel-naturalgain.hpp b/common/accel-naturalgain.hpp
deleted file mode 100644
index cdfd1fa..0000000
--- a/common/accel-naturalgain.hpp
+++ /dev/null
@@ -1,28 +0,0 @@
-#pragma once
-
-#include
-
-#include "accel-natural.hpp"
-
-namespace rawaccel {
-
- /// Struct to hold "natural" (vanishing difference) gain implementation.
- struct naturalgain_impl : natural_impl {
-
- using natural_impl::natural_impl;
-
- inline double operator()(double speed) const {
- // f(x) = k((e^(-mx)-1)/mx + 1)
- double base_speed = speed + offset;
- double scaled_speed = rate * speed;
- return limit * (((exp(-scaled_speed) - 1) / (base_speed * rate) ) + 1 - offset / base_speed);
- }
-
- inline double legacy_offset(double speed) const {
- double scaled_speed = rate * speed;
- return limit * (((exp(-scaled_speed) - 1) / scaled_speed) + 1);
- }
- };
-
- using accel_naturalgain = additive_accel;
-}
diff --git a/common/accel-noaccel.hpp b/common/accel-noaccel.hpp
index c803c2f..b4f1704 100644
--- a/common/accel-noaccel.hpp
+++ b/common/accel-noaccel.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "accel-base.hpp"
+#include "rawaccel-settings.h"
namespace rawaccel {
@@ -11,8 +11,6 @@ namespace rawaccel {
accel_noaccel() = default;
inline double operator()(double) const { return 1; }
-
- inline double legacy_offset(double speed) const { return operator()(speed); }
};
}
diff --git a/common/accel-power.hpp b/common/accel-power.hpp
index 5d0c451..17977a0 100644
--- a/common/accel-power.hpp
+++ b/common/accel-power.hpp
@@ -2,25 +2,25 @@
#include
-#include "accel-base.hpp"
+#include "rawaccel-settings.h"
namespace rawaccel {
/// Struct to hold power (non-additive) acceleration implementation.
- struct power_impl {
- double scale;
+ struct power {
+ double pre_scale;
double exponent;
+ double post_scale;
- power_impl(const accel_args& args) :
- scale(args.scale), exponent(args.exponent)
- {}
+ power(const accel_args& args) :
+ pre_scale(args.scale),
+ exponent(args.exponent),
+ post_scale(args.weight) {}
inline double operator()(double speed) const {
// f(x) = (mx)^k
- return pow(speed * scale, exponent);
+ return post_scale * pow(speed * pre_scale, exponent);
}
};
- using accel_power = nonadditive_accel;
-
}
diff --git a/common/common.vcxitems b/common/common.vcxitems
index ba9bd98..7600755 100644
--- a/common/common.vcxitems
+++ b/common/common.vcxitems
@@ -14,12 +14,9 @@
-
-
-
@@ -30,7 +27,7 @@
-
+
\ No newline at end of file
diff --git a/common/rawaccel-settings.h b/common/rawaccel-settings.h
index dedef6d..308a3fc 100644
--- a/common/rawaccel-settings.h
+++ b/common/rawaccel-settings.h
@@ -1,34 +1,64 @@
#pragma once
#include "vec2.h"
-#include "accel-base.hpp"
-
-#define MAX_DEV_ID_LEN 200
namespace rawaccel {
-
using milliseconds = double;
- inline constexpr int MAX_POLL_RATE_KHZ = 8;
- inline constexpr milliseconds DEFAULT_TIME_MIN = 1.0 / MAX_POLL_RATE_KHZ * 0.8;
+ inline constexpr int POLL_RATE_MAX = 8000;
+
+ inline constexpr milliseconds DEFAULT_TIME_MIN = 1000.0 / POLL_RATE_MAX / 2;
+
inline constexpr milliseconds WRITE_DELAY = 1000;
+ inline constexpr size_t MAX_DEV_ID_LEN = 200;
+
enum class accel_mode {
- linear, classic, natural, naturalgain, power, motivity, noaccel
+ classic,
+ natural,
+ motivity,
+ power,
+ noaccel
+ };
+
+ struct accel_args {
+ accel_mode mode = accel_mode::noaccel;
+ bool legacy = false;
+
+ double offset = 0;
+ double cap = 1.5;
+ double accel_classic = 0.005;
+ double accel_natural = 0.1;
+ double accel_motivity = 1;
+ double motivity = 1.5;
+ double power = 2;
+ double scale = 1;
+ double weight = 1;
+ double exponent = 0.05;
+ double limit = 1.5;
+ double midpoint = 5;
+ };
+
+ struct domain_args {
+ vec2d domain_weights = { 1, 1 };
+ double lp_norm = 2;
};
struct settings {
double degrees_rotation = 0;
double degrees_snap = 0;
bool combine_mags = true;
- vec2 modes = { accel_mode::noaccel, accel_mode::noaccel };
+ double dpi = 1000;
+ double speed_cap = 0;
+
vec2 argsv;
vec2d sens = { 1, 1 };
vec2d dir_multipliers = {};
- domain_args domain_args = {};
+ domain_args dom_args = {};
vec2d range_weights = { 1, 1 };
milliseconds time_min = DEFAULT_TIME_MIN;
- wchar_t device_id[MAX_DEV_ID_LEN] = {0};
+
+ wchar_t device_id[MAX_DEV_ID_LEN] = {};
};
}
diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp
index e28cd92..cb30820 100644
--- a/common/rawaccel.hpp
+++ b/common/rawaccel.hpp
@@ -3,13 +3,10 @@
#define _USE_MATH_DEFINES
#include
-#include "rawaccel-settings.h"
#include "x64-util.hpp"
-#include "accel-linear.hpp"
#include "accel-classic.hpp"
#include "accel-natural.hpp"
-#include "accel-naturalgain.hpp"
#include "accel-power.hpp"
#include "accel-motivity.hpp"
#include "accel-noaccel.hpp"
@@ -62,81 +59,86 @@ namespace rawaccel {
snapper() = default;
};
- /// Struct to hold clamp (min and max) details for acceleration application
- struct accel_scale_clamp {
- double lo = 0;
- double hi = 1e9;
+ inline void cap_speed(vec2d& v, double cap, double norm) {
+ double speed = sqrtsd(v.x * v.x + v.y * v.y) * norm;
+ double ratio = minsd(speed, cap) / speed;
+ v.x *= ratio;
+ v.y *= ratio;
+ }
+
+ enum class internal_mode {
+ classic_lgcy,
+ classic_gain,
+ natural_lgcy,
+ natural_gain,
+ power,
+ motivity,
+ noaccel
+ };
- ///
- /// Clamps given input to min at lo, max at hi.
- ///
- /// Double to be clamped
- /// Clamped input as double
- inline double operator()(double scale) const {
- return clampsd(scale, lo, hi);
+ constexpr internal_mode make_mode(accel_mode m, bool legacy) {
+ switch (m) {
+ case accel_mode::classic:
+ return legacy ? internal_mode::classic_lgcy : internal_mode::classic_gain;
+ case accel_mode::natural:
+ return legacy ? internal_mode::natural_lgcy : internal_mode::natural_gain;
+ case accel_mode::power:
+ return internal_mode::power;
+ case accel_mode::motivity:
+ return internal_mode::motivity;
+ default:
+ return internal_mode::noaccel;
}
+ }
- accel_scale_clamp(double cap) {
- if (cap <= 0) {
- // use default, effectively uncapped accel
- return;
- }
-
- if (cap < 1) {
- // assume negative accel
- lo = cap;
- hi = 1;
- }
- else hi = cap;
- }
+ constexpr internal_mode make_mode(const accel_args& args) {
+ return make_mode(args.mode, args.legacy);
+ }
- accel_scale_clamp() = default;
- };
-
template
inline auto visit_accel(Visitor vis, Variant&& var) {
switch (var.tag) {
- case accel_mode::linear: return vis(var.u.linear);
- case accel_mode::classic: return vis(var.u.classic);
- case accel_mode::natural: return vis(var.u.natural);
- case accel_mode::naturalgain: return vis(var.u.naturalgain);
- case accel_mode::power: return vis(var.u.power);
- case accel_mode::motivity: return vis(var.u.motivity);
- default: return vis(var.u.noaccel);
+ case internal_mode::classic_lgcy: return vis(var.u.classic_l);
+ case internal_mode::classic_gain: return vis(var.u.classic_g);
+ case internal_mode::natural_lgcy: return vis(var.u.natural_l);
+ case internal_mode::natural_gain: return vis(var.u.natural_g);
+ case internal_mode::power: return vis(var.u.power);
+ case internal_mode::motivity: return vis(var.u.motivity);
+ default: return vis(var.u.noaccel);
}
}
struct accel_variant {
si_pair* lookup;
- accel_mode tag = accel_mode::noaccel;
+ internal_mode tag = internal_mode::noaccel;
union union_t {
- accel_linear linear;
- accel_classic classic;
- accel_natural natural;
- accel_naturalgain naturalgain;
- accel_power power;
- accel_motivity motivity;
+ classic classic_g;
+ classic_legacy classic_l;
+ natural natural_g;
+ natural_legacy natural_l;
+ power power;
+ motivity motivity;
accel_noaccel noaccel = {};
} u = {};
- accel_variant(const accel_args& args, accel_mode mode, si_pair* lut = nullptr) :
- tag(mode), lookup(lut)
+ accel_variant(const accel_args& args, si_pair* lut = nullptr) :
+ tag(make_mode(args)), lookup(lut)
{
visit_accel([&](auto& impl) {
impl = { args };
}, *this);
- if (lookup && tag == accel_mode::motivity) {
- u.motivity.fn.fill(lookup);
+ if (lookup && tag == internal_mode::motivity) {
+ u.motivity.fill(lookup);
}
}
inline double apply(double speed) const {
- if (lookup && tag == accel_mode::motivity) {
- return u.motivity.fn.apply(lookup, speed);
+ if (lookup && tag == internal_mode::motivity) {
+ return u.motivity.apply(lookup, speed);
}
return visit_accel([=](auto&& impl) {
@@ -147,104 +149,6 @@ namespace rawaccel {
accel_variant() = default;
};
- /// Struct to hold information about applying a gain cap.
- struct velocity_gain_cap {
-
- // The minimum speed past which gain cap is applied.
- double threshold = 0;
-
- // The gain at the point of cap
- double slope = 0;
-
- // The intercept for the line with above slope to give continuous velocity function
- double intercept = 0;
-
- ///
- /// Initializes a velocity gain cap for a certain speed threshold
- /// by estimating the slope at the threshold and creating a line
- /// with that slope for output velocity calculations.
- ///
- /// The speed at which velocity gain cap will kick in
- /// The accel implementation used in the containing accel_variant
- velocity_gain_cap(double speed, const accel_variant& accel)
- {
- if (speed <= 0) return;
-
- // Estimate gain at cap point by taking line between two input vs output velocity points.
- // First input velocity point is at cap; for second pick a velocity a tiny bit larger.
- double speed_second = 1.001 * speed;
- double speed_diff = speed_second - speed;
-
- // Return if by glitch or strange values the difference in points is 0.
- if (speed_diff == 0) return;
-
- // Find the corresponding output velocities for the two points.
- double out_first = accel.apply(speed) * speed;
- double out_second = accel.apply(speed_second) * speed_second;
-
- // Calculate slope and intercept from two points.
- slope = (out_second - out_first) / speed_diff;
- intercept = out_first - slope * speed;
-
- threshold = speed;
- }
-
- ///
- /// Applies velocity gain cap to speed.
- /// Returns scale value by which to multiply input to place on gain cap line.
- ///
- /// Speed to be capped
- /// Scale multiplier for input
- inline double apply(double speed) const {
- return slope + intercept / speed;
- }
-
- ///
- /// Whether gain cap should be applied to given speed.
- ///
- /// Speed to check against threshold.
- /// Whether gain cap should be applied.
- inline bool should_apply(double speed) const {
- return threshold > 0 && speed > threshold;
- }
-
- velocity_gain_cap() = default;
- };
-
- struct accelerator {
- accel_variant accel;
- velocity_gain_cap gain_cap;
- accel_scale_clamp clamp;
- double output_speed_cap = 0;
-
- accelerator(const accel_args& args, accel_mode mode, si_pair* lut = nullptr) :
- accel(args, mode, lut), gain_cap(args.gain_cap, accel), clamp(args.scale_cap)
- {
- output_speed_cap = maxsd(args.speed_cap, 0);
- }
-
- inline double apply(double speed) const {
- double scale;
-
- if (gain_cap.should_apply(speed)) {
- scale = gain_cap.apply(speed);
- }
- else {
- scale = accel.apply(speed);
- }
-
- scale = clamp(scale);
-
- if (output_speed_cap > 0 && (scale * speed) > output_speed_cap) {
- scale = output_speed_cap / speed;
- }
-
- return scale;
- }
-
- accelerator() = default;
- };
-
struct weighted_distance {
double p = 2.0;
double p_inverse = 0.5;
@@ -318,17 +222,21 @@ namespace rawaccel {
bool apply_rotate = false;
bool apply_snap = false;
bool apply_accel = false;
- bool combine_magnitudes = true;
+ bool by_component = false;
rotator rotate;
snapper snap;
+ double dpi_factor = 1;
+ double speed_cap = 0;
weighted_distance distance;
direction_weight directional;
- vec2 accels;
+ vec2 accels;
vec2d sensitivity = { 1, 1 };
vec2d directional_multipliers = {};
mouse_modifier(const settings& args, vec2 luts = {}) :
- combine_magnitudes(args.combine_mags)
+ by_component(!args.combine_mags),
+ dpi_factor(1000 / args.dpi),
+ speed_cap(args.speed_cap)
{
if (args.degrees_rotation != 0) {
rotate = rotator(args.degrees_rotation);
@@ -346,16 +254,16 @@ namespace rawaccel {
directional_multipliers.x = fabs(args.dir_multipliers.x);
directional_multipliers.y = fabs(args.dir_multipliers.y);
- if ((combine_magnitudes && args.modes.x == accel_mode::noaccel) ||
- (args.modes.x == accel_mode::noaccel &&
- args.modes.y == accel_mode::noaccel)) {
+ if ((!by_component && args.argsv.x.mode == accel_mode::noaccel) ||
+ (args.argsv.x.mode == accel_mode::noaccel &&
+ args.argsv.y.mode == accel_mode::noaccel)) {
return;
}
- accels.x = accelerator(args.argsv.x, args.modes.x, luts.x);
- accels.y = accelerator(args.argsv.y, args.modes.y, luts.y);
+ accels.x = accel_variant(args.argsv.x, luts.x);
+ accels.y = accel_variant(args.argsv.y, luts.y);
- distance = weighted_distance(args.domain_args);
+ distance = weighted_distance(args.dom_args);
directional = direction_weight(args.range_weights);
apply_accel = true;
@@ -380,10 +288,13 @@ namespace rawaccel {
inline void apply_acceleration(vec2d& movement, TimeSupplier time_supp) {
if (apply_accel) {
milliseconds time = time_supp();
+ double norm = dpi_factor / time;
+
+ if (speed_cap > 0) cap_speed(movement, speed_cap, norm);
- if (combine_magnitudes) {
+ if (!by_component) {
double mag = distance.calculate(movement.x, movement.y);
- double speed = mag / time;
+ double speed = mag * norm;
double scale = accels.x.apply(speed);
if (directional.should_apply)
@@ -395,8 +306,8 @@ namespace rawaccel {
movement.y *= scale;
}
else {
- movement.x *= accels.x.apply(fabs(movement.x) / time);
- movement.y *= accels.y.apply(fabs(movement.y) / time);
+ movement.x *= accels.x.apply(fabs(movement.x) * norm);
+ movement.y *= accels.y.apply(fabs(movement.y) * norm);
}
}
}
--
cgit v1.2.3
From ed0bbc22681681a16b7d45b05133c38a0b82006f Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Mon, 29 Mar 2021 18:01:20 -0400
Subject: formatting + file renames
---
common/accel-classic.hpp | 16 +++++---
common/accel-motivity.hpp | 17 ++++----
common/accel-natural.hpp | 10 +++--
common/accel-noaccel.hpp | 4 +-
common/accel-power.hpp | 7 ++--
common/accel-union.hpp | 98 +++++++++++++++++++++++++++++++++++++++++++++
common/common.vcxitems | 5 ++-
common/rawaccel-base.hpp | 64 +++++++++++++++++++++++++++++
common/rawaccel-io.hpp | 14 ++++---
common/rawaccel-settings.h | 64 -----------------------------
common/rawaccel.hpp | 94 ++-----------------------------------------
common/utility-rawinput.hpp | 15 +++++--
common/utility.hpp | 30 ++++++++++++++
common/x64-util.hpp | 30 --------------
14 files changed, 250 insertions(+), 218 deletions(-)
create mode 100644 common/accel-union.hpp
create mode 100644 common/rawaccel-base.hpp
delete mode 100644 common/rawaccel-settings.h
create mode 100644 common/utility.hpp
delete mode 100644 common/x64-util.hpp
(limited to 'common')
diff --git a/common/accel-classic.hpp b/common/accel-classic.hpp
index c7d6519..4385897 100644
--- a/common/accel-classic.hpp
+++ b/common/accel-classic.hpp
@@ -1,10 +1,11 @@
#pragma once
+#include "rawaccel-base.hpp"
+#include "utility.hpp"
+
#include
#include
-#include "rawaccel-settings.h"
-
namespace rawaccel {
/// Struct to hold "classic" (linear raised to power) acceleration implementation.
@@ -18,7 +19,8 @@ namespace rawaccel {
power(args.power),
accel_raised(pow(args.accel_classic, power - 1)) {}
- double base_fn(double x) const {
+ double base_fn(double x) const
+ {
return accel_raised * pow(x - offset, power) / x;
}
};
@@ -40,7 +42,8 @@ namespace rawaccel {
}
}
- inline double operator()(double x) const {
+ double operator()(double x) const
+ {
if (x <= offset) return 1;
return sign * minsd(base_fn(x), sens_cap) + 1;
}
@@ -67,7 +70,8 @@ namespace rawaccel {
}
}
- double operator()(double x) const {
+ double operator()(double x) const
+ {
double output;
if (x <= offset) return 1;
@@ -81,7 +85,7 @@ namespace rawaccel {
return sign * output + 1;
}
-
+
static double gain(double x, double accel, double power, double offset)
{
return power * pow(accel * (x - offset), power - 1);
diff --git a/common/accel-motivity.hpp b/common/accel-motivity.hpp
index abeedf1..a3cb027 100644
--- a/common/accel-motivity.hpp
+++ b/common/accel-motivity.hpp
@@ -1,8 +1,8 @@
#pragma once
-#include
+#include "rawaccel-base.hpp"
-#include "rawaccel-settings.h"
+#include
#define RA_LOOKUP
@@ -23,24 +23,27 @@ namespace rawaccel {
double subtractive_constant;
motivity(const accel_args& args) :
- rate(pow(10,args.accel_motivity)), limit(2*log10(args.limit)), midpoint(log10(args.midpoint))
+ rate(pow(10,args.accel_motivity)),
+ limit(2*log10(args.limit)),
+ midpoint(log10(args.midpoint))
{
subtractive_constant = limit / 2;
}
- inline double operator()(double speed) const {
+ double operator()(double speed) const
+ {
double log_speed = log10(speed);
return pow(10, limit / (exp(-rate * (log_speed - midpoint)) + 1) - subtractive_constant);
}
- inline double apply(si_pair* lookup, double speed) const
+ double apply(si_pair* lookup, double speed) const
{
si_pair pair = lookup[map(speed)];
return pair.slope + pair.intercept / speed;
}
- inline int map(double speed) const
+ int map(double speed) const
{
int index = speed > 0 ? (int)(100 * log10(speed) + 201) : 0;
@@ -50,7 +53,7 @@ namespace rawaccel {
return index;
}
- inline void fill(si_pair* lookup) const
+ void fill(si_pair* lookup) const
{
double lookup_speed = 0;
double integral_interval = 0;
diff --git a/common/accel-natural.hpp b/common/accel-natural.hpp
index 2939dbd..31ed190 100644
--- a/common/accel-natural.hpp
+++ b/common/accel-natural.hpp
@@ -1,8 +1,8 @@
#pragma once
-#include
+#include "rawaccel-base.hpp"
-#include "rawaccel-settings.h"
+#include
namespace rawaccel {
@@ -22,7 +22,8 @@ namespace rawaccel {
struct natural_legacy : natural_base {
- double operator()(double x) const {
+ double operator()(double x) const
+ {
if (x <= offset) return 1;
double offset_x = x - offset;
@@ -36,7 +37,8 @@ namespace rawaccel {
struct natural : natural_base {
double constant;
- double operator()(double x) const {
+ double operator()(double x) const
+ {
if (x <= offset) return 1;
double offset_x = x - offset;
diff --git a/common/accel-noaccel.hpp b/common/accel-noaccel.hpp
index b4f1704..8d1e758 100644
--- a/common/accel-noaccel.hpp
+++ b/common/accel-noaccel.hpp
@@ -1,6 +1,6 @@
#pragma once
-#include "rawaccel-settings.h"
+#include "rawaccel-base.hpp"
namespace rawaccel {
@@ -10,7 +10,7 @@ namespace rawaccel {
accel_noaccel(const accel_args&) {}
accel_noaccel() = default;
- inline double operator()(double) const { return 1; }
+ double operator()(double) const { return 1; }
};
}
diff --git a/common/accel-power.hpp b/common/accel-power.hpp
index 17977a0..c8faabb 100644
--- a/common/accel-power.hpp
+++ b/common/accel-power.hpp
@@ -1,8 +1,8 @@
#pragma once
-#include
+#include "rawaccel-base.hpp"
-#include "rawaccel-settings.h"
+#include
namespace rawaccel {
@@ -17,7 +17,8 @@ namespace rawaccel {
exponent(args.exponent),
post_scale(args.weight) {}
- inline double operator()(double speed) const {
+ double operator()(double speed) const
+ {
// f(x) = (mx)^k
return post_scale * pow(speed * pre_scale, exponent);
}
diff --git a/common/accel-union.hpp b/common/accel-union.hpp
new file mode 100644
index 0000000..86d0cf4
--- /dev/null
+++ b/common/accel-union.hpp
@@ -0,0 +1,98 @@
+#pragma once
+
+#include "accel-classic.hpp"
+#include "accel-natural.hpp"
+#include "accel-power.hpp"
+#include "accel-motivity.hpp"
+#include "accel-noaccel.hpp"
+
+namespace rawaccel {
+
+ enum class internal_mode {
+ classic_lgcy,
+ classic_gain,
+ natural_lgcy,
+ natural_gain,
+ power,
+ motivity,
+ noaccel
+ };
+
+ constexpr internal_mode make_mode(accel_mode m, bool legacy)
+ {
+ switch (m) {
+ case accel_mode::classic:
+ return legacy ? internal_mode::classic_lgcy : internal_mode::classic_gain;
+ case accel_mode::natural:
+ return legacy ? internal_mode::natural_lgcy : internal_mode::natural_gain;
+ case accel_mode::power:
+ return internal_mode::power;
+ case accel_mode::motivity:
+ return internal_mode::motivity;
+ default:
+ return internal_mode::noaccel;
+ }
+ }
+
+ constexpr internal_mode make_mode(const accel_args& args)
+ {
+ return make_mode(args.mode, args.legacy);
+ }
+
+ template
+ inline auto visit_accel(Visitor vis, Variant&& var)
+ {
+ switch (var.tag) {
+ case internal_mode::classic_lgcy: return vis(var.u.classic_l);
+ case internal_mode::classic_gain: return vis(var.u.classic_g);
+ case internal_mode::natural_lgcy: return vis(var.u.natural_l);
+ case internal_mode::natural_gain: return vis(var.u.natural_g);
+ case internal_mode::power: return vis(var.u.power);
+ case internal_mode::motivity: return vis(var.u.motivity);
+ default: return vis(var.u.noaccel);
+ }
+ }
+
+ struct accel_variant {
+ si_pair* lookup;
+
+ internal_mode tag = internal_mode::noaccel;
+
+ union union_t {
+ classic classic_g;
+ classic_legacy classic_l;
+ natural natural_g;
+ natural_legacy natural_l;
+ power power;
+ motivity motivity;
+ accel_noaccel noaccel = {};
+ } u = {};
+
+ accel_variant(const accel_args& args, si_pair* lut = nullptr) :
+ tag(make_mode(args)), lookup(lut)
+ {
+ visit_accel([&](auto& impl) {
+ impl = { args };
+ }, *this);
+
+ if (lookup && tag == internal_mode::motivity) {
+ u.motivity.fill(lookup);
+ }
+
+ }
+
+ double apply(double speed) const
+ {
+ if (lookup && tag == internal_mode::motivity) {
+ return u.motivity.apply(lookup, speed);
+ }
+
+ return visit_accel([=](auto&& impl) {
+ return impl(speed);
+ }, *this);
+ }
+
+ accel_variant() = default;
+ };
+
+}
diff --git a/common/common.vcxitems b/common/common.vcxitems
index 7600755..9e0d971 100644
--- a/common/common.vcxitems
+++ b/common/common.vcxitems
@@ -19,15 +19,16 @@
+
-
+
-
+
\ No newline at end of file
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
new file mode 100644
index 0000000..308a3fc
--- /dev/null
+++ b/common/rawaccel-base.hpp
@@ -0,0 +1,64 @@
+#pragma once
+
+#include "vec2.h"
+
+namespace rawaccel {
+ using milliseconds = double;
+
+ inline constexpr int POLL_RATE_MAX = 8000;
+
+ inline constexpr milliseconds DEFAULT_TIME_MIN = 1000.0 / POLL_RATE_MAX / 2;
+
+ inline constexpr milliseconds WRITE_DELAY = 1000;
+
+ inline constexpr size_t MAX_DEV_ID_LEN = 200;
+
+ enum class accel_mode {
+ classic,
+ natural,
+ motivity,
+ power,
+ noaccel
+ };
+
+ struct accel_args {
+ accel_mode mode = accel_mode::noaccel;
+ bool legacy = false;
+
+ double offset = 0;
+ double cap = 1.5;
+ double accel_classic = 0.005;
+ double accel_natural = 0.1;
+ double accel_motivity = 1;
+ double motivity = 1.5;
+ double power = 2;
+ double scale = 1;
+ double weight = 1;
+ double exponent = 0.05;
+ double limit = 1.5;
+ double midpoint = 5;
+ };
+
+ struct domain_args {
+ vec2d domain_weights = { 1, 1 };
+ double lp_norm = 2;
+ };
+
+ struct settings {
+ double degrees_rotation = 0;
+ double degrees_snap = 0;
+ bool combine_mags = true;
+ double dpi = 1000;
+ double speed_cap = 0;
+
+ vec2 argsv;
+ vec2d sens = { 1, 1 };
+ vec2d dir_multipliers = {};
+ domain_args dom_args = {};
+ vec2d range_weights = { 1, 1 };
+ milliseconds time_min = DEFAULT_TIME_MIN;
+
+ wchar_t device_id[MAX_DEV_ID_LEN] = {};
+ };
+
+}
diff --git a/common/rawaccel-io.hpp b/common/rawaccel-io.hpp
index 703ea92..0d3ddee 100644
--- a/common/rawaccel-io.hpp
+++ b/common/rawaccel-io.hpp
@@ -6,7 +6,7 @@
#include
#include "rawaccel-io-def.h"
-#include "rawaccel-settings.h"
+#include "rawaccel-base.hpp"
#include "rawaccel-version.h"
#include "rawaccel-error.hpp"
@@ -15,7 +15,8 @@
namespace rawaccel {
- void io_control(DWORD code, void* in, DWORD in_size, void* out, DWORD out_size) {
+ inline void io_control(DWORD code, void* in, DWORD in_size, void* out, DWORD out_size)
+ {
HANDLE ra_handle = INVALID_HANDLE_VALUE;
ra_handle = CreateFileW(L"\\\\.\\rawaccel", 0, 0, 0, OPEN_EXISTING, 0, 0);
@@ -44,19 +45,22 @@ namespace rawaccel {
}
}
- settings read() {
+ inline settings read()
+ {
settings args;
io_control(RA_READ, NULL, 0, &args, sizeof(settings));
return args;
}
- void write(const settings& args) {
+ inline void write(const settings& args)
+ {
auto in_ptr = const_cast(&args);
io_control(RA_WRITE, in_ptr, sizeof(settings), NULL, 0);
}
- version_t get_version() {
+ inline version_t get_version()
+ {
version_t ver;
io_control(RA_GET_VERSION, NULL, 0, &ver, sizeof(version_t));
return ver;
diff --git a/common/rawaccel-settings.h b/common/rawaccel-settings.h
deleted file mode 100644
index 308a3fc..0000000
--- a/common/rawaccel-settings.h
+++ /dev/null
@@ -1,64 +0,0 @@
-#pragma once
-
-#include "vec2.h"
-
-namespace rawaccel {
- using milliseconds = double;
-
- inline constexpr int POLL_RATE_MAX = 8000;
-
- inline constexpr milliseconds DEFAULT_TIME_MIN = 1000.0 / POLL_RATE_MAX / 2;
-
- inline constexpr milliseconds WRITE_DELAY = 1000;
-
- inline constexpr size_t MAX_DEV_ID_LEN = 200;
-
- enum class accel_mode {
- classic,
- natural,
- motivity,
- power,
- noaccel
- };
-
- struct accel_args {
- accel_mode mode = accel_mode::noaccel;
- bool legacy = false;
-
- double offset = 0;
- double cap = 1.5;
- double accel_classic = 0.005;
- double accel_natural = 0.1;
- double accel_motivity = 1;
- double motivity = 1.5;
- double power = 2;
- double scale = 1;
- double weight = 1;
- double exponent = 0.05;
- double limit = 1.5;
- double midpoint = 5;
- };
-
- struct domain_args {
- vec2d domain_weights = { 1, 1 };
- double lp_norm = 2;
- };
-
- struct settings {
- double degrees_rotation = 0;
- double degrees_snap = 0;
- bool combine_mags = true;
- double dpi = 1000;
- double speed_cap = 0;
-
- vec2 argsv;
- vec2d sens = { 1, 1 };
- vec2d dir_multipliers = {};
- domain_args dom_args = {};
- vec2d range_weights = { 1, 1 };
- milliseconds time_min = DEFAULT_TIME_MIN;
-
- wchar_t device_id[MAX_DEV_ID_LEN] = {};
- };
-
-}
diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp
index cb30820..67b4e61 100644
--- a/common/rawaccel.hpp
+++ b/common/rawaccel.hpp
@@ -1,16 +1,11 @@
#pragma once
+#include "accel-union.hpp"
+#include "utility.hpp"
+
#define _USE_MATH_DEFINES
#include
-#include "x64-util.hpp"
-
-#include "accel-classic.hpp"
-#include "accel-natural.hpp"
-#include "accel-power.hpp"
-#include "accel-motivity.hpp"
-#include "accel-noaccel.hpp"
-
namespace rawaccel {
/// Struct to hold vector rotation details.
@@ -66,89 +61,6 @@ namespace rawaccel {
v.y *= ratio;
}
- enum class internal_mode {
- classic_lgcy,
- classic_gain,
- natural_lgcy,
- natural_gain,
- power,
- motivity,
- noaccel
- };
-
- constexpr internal_mode make_mode(accel_mode m, bool legacy) {
- switch (m) {
- case accel_mode::classic:
- return legacy ? internal_mode::classic_lgcy : internal_mode::classic_gain;
- case accel_mode::natural:
- return legacy ? internal_mode::natural_lgcy : internal_mode::natural_gain;
- case accel_mode::power:
- return internal_mode::power;
- case accel_mode::motivity:
- return internal_mode::motivity;
- default:
- return internal_mode::noaccel;
- }
- }
-
- constexpr internal_mode make_mode(const accel_args& args) {
- return make_mode(args.mode, args.legacy);
- }
-
- template
- inline auto visit_accel(Visitor vis, Variant&& var) {
- switch (var.tag) {
- case internal_mode::classic_lgcy: return vis(var.u.classic_l);
- case internal_mode::classic_gain: return vis(var.u.classic_g);
- case internal_mode::natural_lgcy: return vis(var.u.natural_l);
- case internal_mode::natural_gain: return vis(var.u.natural_g);
- case internal_mode::power: return vis(var.u.power);
- case internal_mode::motivity: return vis(var.u.motivity);
- default: return vis(var.u.noaccel);
- }
- }
-
- struct accel_variant {
- si_pair* lookup;
-
- internal_mode tag = internal_mode::noaccel;
-
- union union_t {
- classic classic_g;
- classic_legacy classic_l;
- natural natural_g;
- natural_legacy natural_l;
- power power;
- motivity motivity;
- accel_noaccel noaccel = {};
- } u = {};
-
- accel_variant(const accel_args& args, si_pair* lut = nullptr) :
- tag(make_mode(args)), lookup(lut)
- {
- visit_accel([&](auto& impl) {
- impl = { args };
- }, *this);
-
- if (lookup && tag == internal_mode::motivity) {
- u.motivity.fill(lookup);
- }
-
- }
-
- inline double apply(double speed) const {
- if (lookup && tag == internal_mode::motivity) {
- return u.motivity.apply(lookup, speed);
- }
-
- return visit_accel([=](auto&& impl) {
- return impl(speed);
- }, *this);
- }
-
- accel_variant() = default;
- };
-
struct weighted_distance {
double p = 2.0;
double p_inverse = 0.5;
diff --git a/common/utility-rawinput.hpp b/common/utility-rawinput.hpp
index c43084b..eaa23db 100644
--- a/common/utility-rawinput.hpp
+++ b/common/utility-rawinput.hpp
@@ -11,7 +11,9 @@
#include // needed for devpkey.h to parse properly
#include
-std::wstring dev_prop_wstr_from_interface(const WCHAR* interface_name, const DEVPROPKEY* key) {
+inline
+std::wstring dev_prop_wstr_from_interface(const WCHAR* interface_name, const DEVPROPKEY* key)
+{
ULONG size = 0;
DEVPROPTYPE type;
CONFIGRET cm_res;
@@ -37,14 +39,17 @@ std::wstring dev_prop_wstr_from_interface(const WCHAR* interface_name, const DEV
return prop;
}
-std::wstring dev_id_from_interface(const WCHAR* interface_name) {
+inline
+std::wstring dev_id_from_interface(const WCHAR* interface_name)
+{
auto id = dev_prop_wstr_from_interface(interface_name, &DEVPKEY_Device_InstanceId);
id.resize(id.find_last_of('\\'));
return id;
}
template
-void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE) {
+void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE)
+{
const UINT RI_ERROR = -1;
UINT num_devs = 0;
@@ -75,7 +80,9 @@ void rawinput_foreach_with_interface(Func fn, DWORD input_type = RIM_TYPEMOUSE)
// returns device handles corresponding to a "device id"
// https://docs.microsoft.com/en-us/windows-hardware/drivers/install/device-ids
-std::vector rawinput_handles_from_dev_id(const std::wstring& device_id, DWORD input_type = RIM_TYPEMOUSE) {
+inline
+std::vector rawinput_handles_from_dev_id(const std::wstring& device_id, DWORD input_type = RIM_TYPEMOUSE)
+{
std::vector handles;
rawinput_foreach_with_interface([&](const auto& dev, const WCHAR* name) {
diff --git a/common/utility.hpp b/common/utility.hpp
new file mode 100644
index 0000000..40bc7c4
--- /dev/null
+++ b/common/utility.hpp
@@ -0,0 +1,30 @@
+#pragma once
+
+#ifdef _MANAGED
+
+#include
+inline double sqrtsd(double val) { return sqrt(val); }
+
+#else
+
+#include
+inline double sqrtsd(double val) {
+ __m128d src = _mm_load_sd(&val);
+ __m128d dst = _mm_sqrt_sd(src, src);
+ _mm_store_sd(&val, dst);
+ return val;
+}
+
+#endif
+
+inline constexpr double minsd(double a, double b) {
+ return (a < b) ? a : b;
+}
+
+inline constexpr double maxsd(double a, double b) {
+ return (b < a) ? a : b;
+}
+
+inline constexpr double clampsd(double v, double lo, double hi) {
+ return minsd(maxsd(v, lo), hi);
+}
diff --git a/common/x64-util.hpp b/common/x64-util.hpp
deleted file mode 100644
index 40bc7c4..0000000
--- a/common/x64-util.hpp
+++ /dev/null
@@ -1,30 +0,0 @@
-#pragma once
-
-#ifdef _MANAGED
-
-#include
-inline double sqrtsd(double val) { return sqrt(val); }
-
-#else
-
-#include
-inline double sqrtsd(double val) {
- __m128d src = _mm_load_sd(&val);
- __m128d dst = _mm_sqrt_sd(src, src);
- _mm_store_sd(&val, dst);
- return val;
-}
-
-#endif
-
-inline constexpr double minsd(double a, double b) {
- return (a < b) ? a : b;
-}
-
-inline constexpr double maxsd(double a, double b) {
- return (b < a) ? a : b;
-}
-
-inline constexpr double clampsd(double v, double lo, double hi) {
- return minsd(maxsd(v, lo), hi);
-}
--
cgit v1.2.3
From 5a0db3165d1ad050fd5e3f48d290f5ec7289a4f2 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Mon, 29 Mar 2021 19:41:42 -0400
Subject: add jump type
---
common/accel-jump.hpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++++
common/accel-union.hpp | 9 ++++++
common/common.vcxitems | 1 +
common/rawaccel-base.hpp | 2 ++
4 files changed, 85 insertions(+)
create mode 100644 common/accel-jump.hpp
(limited to 'common')
diff --git a/common/accel-jump.hpp b/common/accel-jump.hpp
new file mode 100644
index 0000000..2d13cae
--- /dev/null
+++ b/common/accel-jump.hpp
@@ -0,0 +1,73 @@
+#pragma once
+
+#include "rawaccel-base.hpp"
+
+#define _USE_MATH_DEFINES
+#include
+
+namespace rawaccel {
+
+ struct jump_base {
+ vec2d step;
+ double smooth_rate;
+
+ jump_base(const accel_args& args) :
+ step({ args.offset, args.cap - 1 })
+ {
+ if (args.smooth == 0 || args.offset == 0) {
+ smooth_rate = 0;
+ }
+ else {
+ smooth_rate = 2 * M_PI / (args.offset * args.smooth);
+ }
+
+ }
+
+ bool is_smooth() const
+ {
+ return smooth_rate != 0;
+ }
+
+ double decay(double x) const
+ {
+ return exp(smooth_rate * (step.x - x));
+ }
+
+ double smooth(double x) const
+ {
+ return step.y * 1 / (1 + decay(x));
+ }
+
+ double smooth_antideriv(double x) const
+ {
+ return step.y * (x + log(1 + decay(x)) / smooth_rate);
+ }
+ };
+
+ struct jump_legacy : jump_base {
+ using jump_base::jump_base;
+
+ double operator()(double x) const
+ {
+ if (is_smooth()) return smooth(x) + 1;
+ else if (x < step.x) return 1;
+ else return step.y;
+ }
+ };
+
+ struct jump : jump_base {
+ double C;
+
+ jump(const accel_args& args) :
+ jump_base(args),
+ C(-smooth_antideriv(0)) {}
+
+ double operator()(double x) const
+ {
+ if (is_smooth()) return 1 + (smooth_antideriv(x) + C) / x;
+ else if (x < step.x) return 1;
+ else return 1 + step.y * (x - step.x) / x;
+ }
+ };
+
+}
diff --git a/common/accel-union.hpp b/common/accel-union.hpp
index 86d0cf4..97496e1 100644
--- a/common/accel-union.hpp
+++ b/common/accel-union.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "accel-classic.hpp"
+#include "accel-jump.hpp"
#include "accel-natural.hpp"
#include "accel-power.hpp"
#include "accel-motivity.hpp"
@@ -11,6 +12,8 @@ namespace rawaccel {
enum class internal_mode {
classic_lgcy,
classic_gain,
+ jump_lgcy,
+ jump_gain,
natural_lgcy,
natural_gain,
power,
@@ -23,6 +26,8 @@ namespace rawaccel {
switch (m) {
case accel_mode::classic:
return legacy ? internal_mode::classic_lgcy : internal_mode::classic_gain;
+ case accel_mode::jump:
+ return legacy ? internal_mode::jump_lgcy : internal_mode::jump_gain;
case accel_mode::natural:
return legacy ? internal_mode::natural_lgcy : internal_mode::natural_gain;
case accel_mode::power:
@@ -45,6 +50,8 @@ namespace rawaccel {
switch (var.tag) {
case internal_mode::classic_lgcy: return vis(var.u.classic_l);
case internal_mode::classic_gain: return vis(var.u.classic_g);
+ case internal_mode::jump_lgcy: return vis(var.u.jump_l);
+ case internal_mode::jump_gain: return vis(var.u.jump_g);
case internal_mode::natural_lgcy: return vis(var.u.natural_l);
case internal_mode::natural_gain: return vis(var.u.natural_g);
case internal_mode::power: return vis(var.u.power);
@@ -61,6 +68,8 @@ namespace rawaccel {
union union_t {
classic classic_g;
classic_legacy classic_l;
+ jump jump_g;
+ jump_legacy jump_l;
natural natural_g;
natural_legacy natural_l;
power power;
diff --git a/common/common.vcxitems b/common/common.vcxitems
index 9e0d971..6ee47ed 100644
--- a/common/common.vcxitems
+++ b/common/common.vcxitems
@@ -15,6 +15,7 @@
+
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index 308a3fc..ac60ff0 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -15,6 +15,7 @@ namespace rawaccel {
enum class accel_mode {
classic,
+ jump,
natural,
motivity,
power,
@@ -37,6 +38,7 @@ namespace rawaccel {
double exponent = 0.05;
double limit = 1.5;
double midpoint = 5;
+ double smooth = 0.5;
};
struct domain_args {
--
cgit v1.2.3
From 11045335c14371847411b8fb5096f479e18fbf5e Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Mon, 29 Mar 2021 19:57:33 -0400
Subject: add zero/inf/nan guards
---
common/rawaccel.hpp | 8 ++++++--
common/utility.hpp | 12 ++++++++++++
2 files changed, 18 insertions(+), 2 deletions(-)
(limited to 'common')
diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp
index 67b4e61..f6bc0fd 100644
--- a/common/rawaccel.hpp
+++ b/common/rawaccel.hpp
@@ -218,8 +218,12 @@ namespace rawaccel {
movement.y *= scale;
}
else {
- movement.x *= accels.x.apply(fabs(movement.x) * norm);
- movement.y *= accels.y.apply(fabs(movement.y) * norm);
+ if (movement.x != 0) {
+ movement.x *= accels.x.apply(fabs(movement.x) * norm);
+ }
+ if (movement.y != 0) {
+ movement.y *= accels.y.apply(fabs(movement.y) * norm);
+ }
}
}
}
diff --git a/common/utility.hpp b/common/utility.hpp
index 40bc7c4..d7b63cf 100644
--- a/common/utility.hpp
+++ b/common/utility.hpp
@@ -28,3 +28,15 @@ inline constexpr double maxsd(double a, double b) {
inline constexpr double clampsd(double v, double lo, double hi) {
return minsd(maxsd(v, lo), hi);
}
+
+// returns the unbiased exponent of x if x is normal
+inline int ilogb(double x)
+{
+ union { double f; unsigned long long i; } u = { x };
+ return static_cast((u.i >> 52) & 0x7ff) - 0x3ff;
+}
+
+inline bool infnan(double x)
+{
+ return ilogb(x) == 0x400;
+}
--
cgit v1.2.3
From 4456e2bc8b9c1ef9c1aa2e3509adc8f456bb5fdc Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Tue, 30 Mar 2021 18:26:20 -0400
Subject: put utility in namespace
---
common/utility.hpp | 67 ++++++++++++++++++++++++++++++------------------------
1 file changed, 37 insertions(+), 30 deletions(-)
(limited to 'common')
diff --git a/common/utility.hpp b/common/utility.hpp
index d7b63cf..ae14b48 100644
--- a/common/utility.hpp
+++ b/common/utility.hpp
@@ -1,42 +1,49 @@
#pragma once
#ifdef _MANAGED
-
#include
-inline double sqrtsd(double val) { return sqrt(val); }
-
#else
-
#include
-inline double sqrtsd(double val) {
- __m128d src = _mm_load_sd(&val);
- __m128d dst = _mm_sqrt_sd(src, src);
- _mm_store_sd(&val, dst);
- return val;
-}
-
#endif
-inline constexpr double minsd(double a, double b) {
- return (a < b) ? a : b;
-}
+namespace rawaccel {
-inline constexpr double maxsd(double a, double b) {
- return (b < a) ? a : b;
-}
-
-inline constexpr double clampsd(double v, double lo, double hi) {
- return minsd(maxsd(v, lo), hi);
-}
+#ifdef _MANAGED
+ inline double sqrtsd(double val) { return sqrt(val); }
+#else
+ inline double sqrtsd(double val) {
+ __m128d src = _mm_load_sd(&val);
+ __m128d dst = _mm_sqrt_sd(src, src);
+ _mm_store_sd(&val, dst);
+ return val;
+ }
+#endif
-// returns the unbiased exponent of x if x is normal
-inline int ilogb(double x)
-{
- union { double f; unsigned long long i; } u = { x };
- return static_cast((u.i >> 52) & 0x7ff) - 0x3ff;
-}
+ constexpr double minsd(double a, double b)
+ {
+ return (a < b) ? a : b;
+ }
+
+ constexpr double maxsd(double a, double b)
+ {
+ return (b < a) ? a : b;
+ }
+
+ constexpr double clampsd(double v, double lo, double hi)
+ {
+ return minsd(maxsd(v, lo), hi);
+ }
+
+ // returns the unbiased exponent of x if x is normal
+ inline int ilogb(double x)
+ {
+ union { double f; unsigned long long i; } u = { x };
+ return static_cast((u.i >> 52) & 0x7ff) - 0x3ff;
+ }
+
+ inline bool infnan(double x)
+ {
+ return ilogb(x) == 0x400;
+ }
-inline bool infnan(double x)
-{
- return ilogb(x) == 0x400;
}
--
cgit v1.2.3
From fa3ebfb1eb054ba88824a908c996094bb98e85c5 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Tue, 30 Mar 2021 18:27:02 -0400
Subject: refactor lut/motivity
---
common/accel-lookup.hpp | 152 ++++++++++++++++++++++++++++++++++++++++++++++
common/accel-motivity.hpp | 114 +++++++++++-----------------------
common/accel-power.hpp | 1 +
common/accel-union.hpp | 81 ++++++++++++------------
common/common.vcxitems | 1 +
common/rawaccel-base.hpp | 21 ++++++-
common/rawaccel-io.hpp | 23 +++----
common/rawaccel.hpp | 11 +++-
common/utility.hpp | 35 +++++++++++
9 files changed, 303 insertions(+), 136 deletions(-)
create mode 100644 common/accel-lookup.hpp
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
new file mode 100644
index 0000000..18c9ea5
--- /dev/null
+++ b/common/accel-lookup.hpp
@@ -0,0 +1,152 @@
+#pragma once
+
+#include "rawaccel-base.hpp"
+#include "utility.hpp"
+
+namespace rawaccel {
+
+ struct linear_range {
+ double start;
+ double stop;
+ int num;
+
+ template
+ void for_each(Func fn) const
+ {
+ double interval = (stop - start) / (num - 1);
+ for (int i = 0; i < num; i++) {
+ fn(i * interval + start);
+ }
+ }
+
+ int size() const
+ {
+ return num;
+ }
+ };
+
+
+ // represents the range [2^start, 2^stop], with num - 1
+ // elements linearly spaced between each exponential step
+ struct fp_rep_range {
+ int start;
+ int stop;
+ int num;
+
+ template
+ void for_each(Func fn) const
+ {
+ for (int e = 0; e < stop - start; e++) {
+ double exp_scale = scalbn(1, e + start) / num;
+
+ for (int i = 0; i < num; i++) {
+ fn((i + num) * exp_scale);
+ }
+ }
+
+ fn(scalbn(1, stop));
+ }
+
+ int size() const
+ {
+ return (stop - start) * num + 1;
+ }
+ };
+
+ template
+ struct lut_base {
+ enum { capacity = LUT_CAPACITY };
+ using value_t = float;
+
+ template
+ void fill(Func fn)
+ {
+ auto* self = static_cast(this);
+
+ self->range.for_each([&, fn, i = 0](double x) mutable {
+ self->data[i++] = static_cast(fn(x));
+ });
+ }
+
+ };
+
+ struct linear_lut : lut_base {
+ linear_range range;
+ bool transfer = false;
+ value_t data[capacity] = {};
+
+ double operator()(double x) const
+ {
+ if (x > range.start) {
+ double range_dist = range.stop - range.start;
+ double idx_f = (x - range.start) * (range.num - 1) / range_dist;
+
+ unsigned idx = min(static_cast(idx_f), range.size() - 2);
+
+ if (idx < capacity - 1) {
+ double y = lerp(data[idx], data[idx + 1], idx_f - idx);
+ if (transfer) y /= x;
+ return y;
+ }
+ }
+
+ double y = data[0];
+ if (transfer) y /= range.start;
+ return y;
+ }
+
+ linear_lut(const table_args& args) :
+ range({
+ args.start,
+ args.stop,
+ args.num_elements
+ }),
+ transfer(args.transfer) {}
+
+ linear_lut(const accel_args& args) :
+ linear_lut(args.lut_args) {}
+ };
+
+ struct binlog_lut : lut_base {
+ fp_rep_range range;
+ double x_start;
+ bool transfer = false;
+ value_t data[capacity] = {};
+
+ double operator()(double x) const
+ {
+ int e = min(ilogb(x), range.stop - 1);
+
+ if (e >= range.start) {
+ int idx_int_log_part = e - range.start;
+ double idx_frac_lin_part = scalbn(x, -e) - 1;
+ double idx_f = range.num * (idx_int_log_part + idx_frac_lin_part);
+
+ unsigned idx = min(static_cast(idx_f), range.size() - 2);
+
+ if (idx < capacity - 1) {
+ double y = lerp(data[idx], data[idx + 1], idx_f - idx);
+ if (transfer) y /= x;
+ return y;
+ }
+ }
+
+ double y = data[0];
+ if (transfer) y /= x_start;
+ return y;
+ }
+
+ binlog_lut(const table_args& args) :
+ range({
+ static_cast(args.start),
+ static_cast(args.stop),
+ args.num_elements
+ }),
+ x_start(scalbn(1, range.start)),
+ transfer(args.transfer) {}
+
+ binlog_lut(const accel_args& args) :
+ binlog_lut(args.lut_args) {}
+ };
+
+}
diff --git a/common/accel-motivity.hpp b/common/accel-motivity.hpp
index a3cb027..0c15598 100644
--- a/common/accel-motivity.hpp
+++ b/common/accel-motivity.hpp
@@ -1,100 +1,56 @@
#pragma once
-#include "rawaccel-base.hpp"
+#include "accel-lookup.hpp"
#include
-#define RA_LOOKUP
-
namespace rawaccel {
- constexpr size_t LUT_SIZE = 601;
-
- struct si_pair {
- double slope = 0;
- double intercept = 0;
- };
-
- /// Struct to hold sigmoid (s-shaped) gain implementation.
- struct motivity {
- double rate;
- double limit;
+ struct sigmoid {
+ double accel;
+ double motivity;
double midpoint;
- double subtractive_constant;
-
- motivity(const accel_args& args) :
- rate(pow(10,args.accel_motivity)),
- limit(2*log10(args.limit)),
- midpoint(log10(args.midpoint))
- {
- subtractive_constant = limit / 2;
- }
+ double constant;
- double operator()(double speed) const
- {
- double log_speed = log10(speed);
- return pow(10, limit / (exp(-rate * (log_speed - midpoint)) + 1) - subtractive_constant);
+ sigmoid(const accel_args& args) :
+ accel(exp(args.accel_motivity)),
+ motivity(2 * log(args.motivity)),
+ midpoint(log(args.midpoint)),
+ constant(-motivity / 2) {}
- }
-
- double apply(si_pair* lookup, double speed) const
+ double operator()(double x) const
{
- si_pair pair = lookup[map(speed)];
- return pair.slope + pair.intercept / speed;
+ double denom = exp(accel * (midpoint - log(x))) + 1;
+ return exp(motivity / denom + constant);
}
+ };
- int map(double speed) const
- {
- int index = speed > 0 ? (int)(100 * log10(speed) + 201) : 0;
-
- if (index < 0) return 0;
- if (index >= LUT_SIZE) return LUT_SIZE - 1;
+ /// Struct to hold sigmoid (s-shaped) gain implementation.
+ struct motivity : binlog_lut {
- return index;
- }
+ using binlog_lut::operator();
- void fill(si_pair* lookup) const
+ motivity(const accel_args& args) :
+ binlog_lut(args)
{
- double lookup_speed = 0;
- double integral_interval = 0;
- double gain_integral_speed = 0;
- double gain_integral_speed_prev = 0;
- double gain = 0;
- double intercept = 0;
- double output = 0;
- double output_prev = 0;
- double x = -2;
-
- double logarithm_interval = 0.01;
- double integral_intervals_per_speed = 10;
- double integral_interval_factor = pow(10, logarithm_interval) / integral_intervals_per_speed;
-
- lookup[0] = {};
-
- for (size_t i = 1; i < LUT_SIZE; i++)
- {
- x += logarithm_interval;
-
- // Each lookup speed will be 10^0.01 = 2.33% higher than the previous
- // To get 10 integral intervals per speed, set interval to 0.233%
- lookup_speed = pow(10, x);
- integral_interval = lookup_speed * integral_interval_factor;
-
- while (gain_integral_speed < lookup_speed)
- {
- output_prev = output;
- gain_integral_speed_prev = gain_integral_speed;
- gain_integral_speed += integral_interval;
- gain = operator()(gain_integral_speed);
- output += gain * integral_interval;
+ double sum = 0;
+ double a = 0;
+ auto sigmoid_sum = [&, sig = sigmoid(args)](double b) mutable {
+ double interval = (b - a) / args.lut_args.partitions;
+ for (int i = 1; i <= args.lut_args.partitions; i++) {
+ sum += sig(a + i * interval) * interval;
}
-
- intercept = output_prev - gain_integral_speed_prev * gain;
-
- lookup[i] = { gain, intercept };
- }
-
+ a = b;
+ return sum;
+ };
+
+ fill([&](double x) {
+ double y = sigmoid_sum(x);
+ if (!this->transfer) y /= x;
+ return y;
+ });
}
+
};
}
diff --git a/common/accel-power.hpp b/common/accel-power.hpp
index c8faabb..a21f926 100644
--- a/common/accel-power.hpp
+++ b/common/accel-power.hpp
@@ -24,4 +24,5 @@ namespace rawaccel {
}
};
+ using power_legacy = power;
}
diff --git a/common/accel-union.hpp b/common/accel-union.hpp
index 97496e1..c63a9cc 100644
--- a/common/accel-union.hpp
+++ b/common/accel-union.hpp
@@ -16,53 +16,59 @@ namespace rawaccel {
jump_gain,
natural_lgcy,
natural_gain,
- power,
- motivity,
+ power_lgcy,
+ power_gain,
+ motivity_lgcy,
+ motivity_gain,
+ lut_log,
+ lut_lin,
noaccel
};
- constexpr internal_mode make_mode(accel_mode m, bool legacy)
+ constexpr internal_mode make_mode(accel_mode mode, table_mode lut_mode, bool legacy)
{
- switch (m) {
- case accel_mode::classic:
- return legacy ? internal_mode::classic_lgcy : internal_mode::classic_gain;
- case accel_mode::jump:
- return legacy ? internal_mode::jump_lgcy : internal_mode::jump_gain;
- case accel_mode::natural:
- return legacy ? internal_mode::natural_lgcy : internal_mode::natural_gain;
- case accel_mode::power:
- return internal_mode::power;
- case accel_mode::motivity:
- return internal_mode::motivity;
- default:
+ if (lut_mode != table_mode::off) {
+ switch (lut_mode) {
+ case table_mode::binlog: return internal_mode::lut_log;
+ case table_mode::linear: return internal_mode::lut_lin;
+ default: return internal_mode::noaccel;
+ }
+ }
+ else if (mode < accel_mode{} || mode >= accel_mode::noaccel) {
return internal_mode::noaccel;
}
+ else {
+ int im = static_cast(mode) * 2 + (legacy ? 0 : 1);
+ return static_cast(im);
+ }
}
constexpr internal_mode make_mode(const accel_args& args)
{
- return make_mode(args.mode, args.legacy);
+ return make_mode(args.mode, args.lut_args.mode, args.legacy);
}
template
inline auto visit_accel(Visitor vis, Variant&& var)
{
switch (var.tag) {
- case internal_mode::classic_lgcy: return vis(var.u.classic_l);
- case internal_mode::classic_gain: return vis(var.u.classic_g);
- case internal_mode::jump_lgcy: return vis(var.u.jump_l);
- case internal_mode::jump_gain: return vis(var.u.jump_g);
- case internal_mode::natural_lgcy: return vis(var.u.natural_l);
- case internal_mode::natural_gain: return vis(var.u.natural_g);
- case internal_mode::power: return vis(var.u.power);
- case internal_mode::motivity: return vis(var.u.motivity);
- default: return vis(var.u.noaccel);
+ case internal_mode::classic_lgcy: return vis(var.u.classic_l);
+ case internal_mode::classic_gain: return vis(var.u.classic_g);
+ case internal_mode::jump_lgcy: return vis(var.u.jump_l);
+ case internal_mode::jump_gain: return vis(var.u.jump_g);
+ case internal_mode::natural_lgcy: return vis(var.u.natural_l);
+ case internal_mode::natural_gain: return vis(var.u.natural_g);
+ case internal_mode::power_lgcy: return vis(var.u.power_l);
+ case internal_mode::power_gain: return vis(var.u.power_g);
+ case internal_mode::motivity_lgcy: return vis(var.u.motivity_l);
+ case internal_mode::motivity_gain: return vis(var.u.motivity_g);
+ case internal_mode::lut_log: return vis(var.u.log_lut);
+ case internal_mode::lut_lin: return vis(var.u.lin_lut);
+ default: return vis(var.u.noaccel);
}
}
struct accel_variant {
- si_pair* lookup;
-
internal_mode tag = internal_mode::noaccel;
union union_t {
@@ -72,30 +78,25 @@ namespace rawaccel {
jump_legacy jump_l;
natural natural_g;
natural_legacy natural_l;
- power power;
- motivity motivity;
+ power power_g;
+ power_legacy power_l;
+ sigmoid motivity_l;
+ motivity motivity_g;
+ linear_lut lin_lut;
+ binlog_lut log_lut;
accel_noaccel noaccel = {};
} u = {};
- accel_variant(const accel_args& args, si_pair* lut = nullptr) :
- tag(make_mode(args)), lookup(lut)
+ accel_variant(const accel_args& args) :
+ tag(make_mode(args))
{
visit_accel([&](auto& impl) {
impl = { args };
}, *this);
-
- if (lookup && tag == internal_mode::motivity) {
- u.motivity.fill(lookup);
- }
-
}
double apply(double speed) const
{
- if (lookup && tag == internal_mode::motivity) {
- return u.motivity.apply(lookup, speed);
- }
-
return visit_accel([=](auto&& impl) {
return impl(speed);
}, *this);
diff --git a/common/common.vcxitems b/common/common.vcxitems
index 6ee47ed..4cbe2b7 100644
--- a/common/common.vcxitems
+++ b/common/common.vcxitems
@@ -16,6 +16,7 @@
+
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index ac60ff0..6996164 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -13,19 +13,38 @@ namespace rawaccel {
inline constexpr size_t MAX_DEV_ID_LEN = 200;
+ inline constexpr size_t LUT_CAPACITY = 1025;
+
enum class accel_mode {
classic,
jump,
natural,
- motivity,
power,
+ motivity,
noaccel
};
+ enum class table_mode {
+ off,
+ binlog,
+ linear
+ };
+
+ struct table_args {
+ table_mode mode = table_mode::off;
+ bool transfer = true;
+ unsigned char partitions = 2;
+ short num_elements = 8;
+ double start = 0;
+ double stop = 8;
+ };
+
struct accel_args {
accel_mode mode = accel_mode::noaccel;
bool legacy = false;
+ table_args lut_args = {};
+
double offset = 0;
double cap = 1.5;
double accel_classic = 0.005;
diff --git a/common/rawaccel-io.hpp b/common/rawaccel-io.hpp
index 0d3ddee..da496fa 100644
--- a/common/rawaccel-io.hpp
+++ b/common/rawaccel-io.hpp
@@ -1,14 +1,15 @@
#pragma once
-#include
+#include "rawaccel-io-def.h"
+#include "rawaccel.hpp"
+#include "rawaccel-version.h"
+#include "rawaccel-error.hpp"
#define NOMINMAX
+#define WIN32_LEAN_AND_MEAN
#include
-#include "rawaccel-io-def.h"
-#include "rawaccel-base.hpp"
-#include "rawaccel-version.h"
-#include "rawaccel-error.hpp"
+#include
#pragma warning(push)
#pragma warning(disable:4245) // int -> DWORD conversion while passing CTL_CODE
@@ -45,18 +46,14 @@ namespace rawaccel {
}
}
- inline settings read()
+ inline void read(io_t& args)
{
- settings args;
- io_control(RA_READ, NULL, 0, &args, sizeof(settings));
- return args;
+ io_control(RA_READ, NULL, 0, &args, sizeof(io_t));
}
-
- inline void write(const settings& args)
+ inline void write(const io_t& args)
{
- auto in_ptr = const_cast(&args);
- io_control(RA_WRITE, in_ptr, sizeof(settings), NULL, 0);
+ io_control(RA_WRITE, const_cast(&args), sizeof(io_t), NULL, 0);
}
inline version_t get_version()
diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp
index f6bc0fd..5d3ee15 100644
--- a/common/rawaccel.hpp
+++ b/common/rawaccel.hpp
@@ -145,7 +145,7 @@ namespace rawaccel {
vec2d sensitivity = { 1, 1 };
vec2d directional_multipliers = {};
- mouse_modifier(const settings& args, vec2 luts = {}) :
+ mouse_modifier(const settings& args) :
by_component(!args.combine_mags),
dpi_factor(1000 / args.dpi),
speed_cap(args.speed_cap)
@@ -172,8 +172,8 @@ namespace rawaccel {
return;
}
- accels.x = accel_variant(args.argsv.x, luts.x);
- accels.y = accel_variant(args.argsv.y, luts.y);
+ accels.x = accel_variant(args.argsv.x);
+ accels.y = accel_variant(args.argsv.y);
distance = weighted_distance(args.dom_args);
directional = direction_weight(args.range_weights);
@@ -243,4 +243,9 @@ namespace rawaccel {
mouse_modifier() = default;
};
+ struct io_t {
+ settings args;
+ mouse_modifier mod;
+ };
+
} // rawaccel
diff --git a/common/utility.hpp b/common/utility.hpp
index ae14b48..de90d44 100644
--- a/common/utility.hpp
+++ b/common/utility.hpp
@@ -34,6 +34,33 @@ namespace rawaccel {
return minsd(maxsd(v, lo), hi);
}
+ template
+ constexpr const T& min(const T& a, const T& b)
+ {
+ return (b < a) ? b : a;
+ }
+
+ template
+ constexpr const T& max(const T& a, const T& b)
+ {
+ return (b < a) ? a : b;
+ }
+
+ template
+ constexpr const T& clamp(const T& v, const T& lo, const T& hi)
+ {
+ return (v < lo) ? lo : (hi < v) ? hi : v;
+ }
+
+ constexpr double lerp(double a, double b, double t)
+ {
+ double x = a + t * (b - a);
+ if ((t > 1) == (a < b)) {
+ return maxsd(x, b);
+ }
+ return minsd(x, b);
+ }
+
// returns the unbiased exponent of x if x is normal
inline int ilogb(double x)
{
@@ -41,6 +68,14 @@ namespace rawaccel {
return static_cast((u.i >> 52) & 0x7ff) - 0x3ff;
}
+ // returns x * 2^n if n is in [-1022, 1023]
+ inline double scalbn(double x, int n)
+ {
+ union { double f; unsigned long long i; } u;
+ u.i = static_cast(0x3ff + n) << 52;
+ return x * u.f;
+ }
+
inline bool infnan(double x)
{
return ilogb(x) == 0x400;
--
cgit v1.2.3
From 14bde56daf188bfc027dc8ead5b45ec0aa1109d6 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 1 Apr 2021 01:51:31 -0400
Subject: update rest
grapher is still broken
refactored io / error handling a bit
---
common/common.vcxitems | 1 +
common/rawaccel-error.hpp | 27 +++++--
common/rawaccel-io-def.h | 4 +-
common/rawaccel-io.hpp | 123 +++++++++++++++++--------------
common/rawaccel-validate.hpp | 168 +++++++++++++++++++++++++++++++++++++++++++
common/rawaccel-version.h | 30 +++++---
common/utility.hpp | 4 ++
7 files changed, 289 insertions(+), 68 deletions(-)
create mode 100644 common/rawaccel-validate.hpp
(limited to 'common')
diff --git a/common/common.vcxitems b/common/common.vcxitems
index 4cbe2b7..6d1b861 100644
--- a/common/common.vcxitems
+++ b/common/common.vcxitems
@@ -26,6 +26,7 @@
+
diff --git a/common/rawaccel-error.hpp b/common/rawaccel-error.hpp
index cdbe1e5..a9cb7b8 100644
--- a/common/rawaccel-error.hpp
+++ b/common/rawaccel-error.hpp
@@ -1,11 +1,12 @@
#pragma once
-#include
+#include
+#include
namespace rawaccel {
- class error : public std::runtime_error {
- using std::runtime_error::runtime_error;
+ class error : public std::runtime_error {
+ using std::runtime_error::runtime_error;
};
class io_error : public error {
@@ -14,7 +15,25 @@ namespace rawaccel {
class install_error : public io_error {
public:
- install_error() : io_error("Raw Accel driver is not installed, run installer.exe") {}
+ install_error() :
+ io_error("Raw Accel is not installed, run installer.exe") {}
+ };
+
+ class sys_error : public io_error {
+ public:
+ sys_error(const char* msg, DWORD code = GetLastError()) :
+ io_error(build_msg(code, msg)) {}
+
+ static std::string build_msg(DWORD code, const char* msg)
+ {
+ std::string ret =
+ std::system_error(code, std::system_category(), msg).what();
+ ret += " (";
+ ret += std::to_string(code);
+ ret += ")";
+ return ret;
+ }
+
};
}
diff --git a/common/rawaccel-io-def.h b/common/rawaccel-io-def.h
index e169390..399e0f2 100644
--- a/common/rawaccel-io-def.h
+++ b/common/rawaccel-io-def.h
@@ -1,9 +1,11 @@
#pragma once
+#define NOMINMAX
+
#ifdef _KERNEL_MODE
#include
#else
-#include
+#include
#endif
#define RA_DEV_TYPE 0x8888u
diff --git a/common/rawaccel-io.hpp b/common/rawaccel-io.hpp
index da496fa..a80e254 100644
--- a/common/rawaccel-io.hpp
+++ b/common/rawaccel-io.hpp
@@ -1,67 +1,84 @@
#pragma once
#include "rawaccel-io-def.h"
-#include "rawaccel.hpp"
#include "rawaccel-version.h"
#include "rawaccel-error.hpp"
-
-#define NOMINMAX
-#define WIN32_LEAN_AND_MEAN
-#include
-
-#include
+#include "rawaccel.hpp"
#pragma warning(push)
#pragma warning(disable:4245) // int -> DWORD conversion while passing CTL_CODE
namespace rawaccel {
- inline void io_control(DWORD code, void* in, DWORD in_size, void* out, DWORD out_size)
- {
- HANDLE ra_handle = INVALID_HANDLE_VALUE;
-
- ra_handle = CreateFileW(L"\\\\.\\rawaccel", 0, 0, 0, OPEN_EXISTING, 0, 0);
-
- if (ra_handle == INVALID_HANDLE_VALUE) {
- throw install_error();
- }
-
- DWORD dummy;
-
- BOOL success = DeviceIoControl(
- ra_handle,
- code,
- in,
- in_size,
- out,
- out_size,
- &dummy, // bytes returned
- NULL // overlapped structure
- );
-
- CloseHandle(ra_handle);
-
- if (!success) {
- throw std::system_error(GetLastError(), std::system_category(), "DeviceIoControl failed");
- }
- }
-
- inline void read(io_t& args)
- {
- io_control(RA_READ, NULL, 0, &args, sizeof(io_t));
- }
-
- inline void write(const io_t& args)
- {
- io_control(RA_WRITE, const_cast(&args), sizeof(io_t), NULL, 0);
- }
-
- inline version_t get_version()
- {
- version_t ver;
- io_control(RA_GET_VERSION, NULL, 0, &ver, sizeof(version_t));
- return ver;
- }
+ inline void io_control(DWORD code, void* in, DWORD in_size, void* out, DWORD out_size)
+ {
+ HANDLE ra_handle = INVALID_HANDLE_VALUE;
+
+ ra_handle = CreateFileW(L"\\\\.\\rawaccel", 0, 0, 0, OPEN_EXISTING, 0, 0);
+
+ if (ra_handle == INVALID_HANDLE_VALUE) {
+ throw install_error();
+ }
+
+ DWORD dummy;
+
+ BOOL success = DeviceIoControl(
+ ra_handle,
+ code,
+ in,
+ in_size,
+ out,
+ out_size,
+ &dummy, // bytes returned
+ NULL // overlapped structure
+ );
+
+ CloseHandle(ra_handle);
+
+ if (!success) {
+ throw sys_error("DeviceIoControl failed");
+ }
+ }
+
+ inline void read(io_t& args)
+ {
+ io_control(RA_READ, NULL, 0, &args, sizeof(io_t));
+ }
+
+ inline void write(const io_t& args)
+ {
+ io_control(RA_WRITE, const_cast(&args), sizeof(io_t), NULL, 0);
+ }
+
+ inline version_t get_version()
+ {
+ version_t v;
+
+ try {
+ io_control(RA_GET_VERSION, NULL, 0, &v, sizeof(version_t));
+ }
+ catch (const sys_error&) {
+ // assume request is not implemented (< 1.3)
+ v = { 0 };
+ }
+
+ return v;
+ }
+
+ inline version_t valid_version_or_throw()
+ {
+ auto v = get_version();
+
+ if (v < min_driver_version) {
+ throw error("reinstallation required");
+ }
+
+ if (version < v) {
+ throw error("newer driver is installed");
+ }
+
+ return v;
+ }
}
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
new file mode 100644
index 0000000..b9ee2af
--- /dev/null
+++ b/common/rawaccel-validate.hpp
@@ -0,0 +1,168 @@
+#pragma once
+
+#include "rawaccel-base.hpp"
+#include "utility.hpp"
+
+namespace rawaccel {
+
+ struct valid_ret_t {
+ int count_x = 0;
+ int count_y = 0;
+ int count = 0;
+
+ explicit operator bool() const
+ {
+ return count == 0;
+ }
+ };
+
+ template
+ valid_ret_t valid(const settings& args, MsgHandler fn = {})
+ {
+ valid_ret_t ret;
+
+ auto error = [&](auto msg) {
+ ++ret.count;
+ fn(msg);
+ };
+
+ auto check_accel = [&error](const accel_args& args) {
+ static_assert(LUT_CAPACITY == 1025, "update error msg");
+
+ const auto& lut_args = args.lut_args;
+
+ if (lut_args.partitions <= 0) {
+ error("lut partitions"" must be positive");
+ }
+
+ if (lut_args.mode == table_mode::linear) {
+ if (lut_args.start <= 0) {
+ error("start"" must be positive");
+ }
+
+ if (lut_args.stop <= lut_args.start) {
+ error("stop must be greater than start");
+ }
+
+ if (lut_args.num_elements < 2 ||
+ lut_args.num_elements > 1025) {
+ error("num must be between 2 and 1025");
+ }
+ }
+ else if (lut_args.mode == table_mode::binlog) {
+ int istart = static_cast(lut_args.start);
+ int istop = static_cast(lut_args.stop);
+
+ if (lut_args.start < -99) {
+ error("start is too small");
+ }
+ else if (lut_args.stop > 99) {
+ error("stop is too large");
+ }
+ else if (istart != lut_args.start || istop != lut_args.stop) {
+ error("start and stop must be integers");
+ }
+ else if (istop <= istart) {
+ error("stop must be greater than start");
+ }
+ else if (lut_args.num_elements <= 0) {
+ error("num"" must be positive");
+ }
+ else if (((lut_args.stop - lut_args.start) * lut_args.num_elements) >= 1025) {
+ error("binlog mode requires (num * (stop - start)) < 1025");
+ }
+ }
+
+ if (args.offset < 0) {
+ error("offset can not be negative");
+ }
+
+ if (args.cap <= 0) {
+ error("cap"" must be positive");
+ }
+
+ if (args.accel_motivity <= 0 ||
+ args.accel_natural <= 0 ||
+ args.accel_classic <= 0) {
+ error("acceleration"" must be positive");
+ }
+
+ if (args.motivity <= 1) {
+ error("motivity must be greater than 1");
+ }
+
+ if (args.power <= 1) {
+ error("power must be greater than 1");
+ }
+
+ if (args.scale <= 0) {
+ error("scale"" must be positive");
+ }
+
+ if (args.weight <= 0) {
+ error("weight"" must be positive");
+ }
+
+ if (args.exponent <= 0) {
+ error("exponent"" must be positive");
+ }
+
+ if (args.limit <= 0) {
+ error("limit"" must be positive");
+ }
+
+ if (args.midpoint <= 0) {
+ error("midpoint"" must be positive");
+ }
+
+ if (args.smooth < 0 || args.smooth > 1) {
+ error("smooth must be between 0 and 1");
+ }
+
+ };
+
+ check_accel(args.argsv.x);
+
+ if (!args.combine_mags) {
+ ret.count_x = ret.count;
+ check_accel(args.argsv.y);
+ ret.count_y = ret.count;
+ }
+
+ if (args.dpi <= 0) {
+ error("dpi"" must be positive");
+ }
+
+ if (args.speed_cap <= 0) {
+ error("speed cap"" must be positive");
+ }
+
+ if (args.sens.x == 0 || args.sens.y == 0) {
+ error("sens multiplier is 0");
+ }
+
+ if (args.dom_args.domain_weights.x <= 0 ||
+ args.dom_args.domain_weights.y <= 0) {
+ error("domain weights"" must be positive");
+ }
+
+ if (args.dom_args.lp_norm <= 0) {
+ error("Lp norm can not be negative");
+ }
+
+ if (args.dir_multipliers.x < 0 || args.dir_multipliers.y < 0) {
+ error("directional multipliers can not be negative");
+ }
+
+ if (args.range_weights.x <= 0 || args.range_weights.y <= 0) {
+ error("range weights"" must be positive");
+ }
+
+ if (args.time_min <= 0) {
+ error("minimum time"" must be positive");
+ }
+
+ return ret;
+ }
+
+}
diff --git a/common/rawaccel-version.h b/common/rawaccel-version.h
index 40ff2d2..de8644b 100644
--- a/common/rawaccel-version.h
+++ b/common/rawaccel-version.h
@@ -6,21 +6,31 @@
#define RA_OS "Win7+"
-#define M_STR_HELPER(x) #x
-#define M_STR(x) M_STR_HELPER(x)
+#define RA_M_STR_HELPER(x) #x
+#define RA_M_STR(x) RA_M_STR_HELPER(x)
-#define RA_VER_STRING M_STR(RA_VER_MAJOR) "." M_STR(RA_VER_MINOR) "." M_STR(RA_VER_PATCH)
+#define RA_VER_STRING RA_M_STR(RA_VER_MAJOR) "." RA_M_STR(RA_VER_MINOR) "." RA_M_STR(RA_VER_PATCH)
namespace rawaccel {
- struct version_t {
- int major;
- int minor;
- int patch;
- };
-
+ struct version_t {
+ int major;
+ int minor;
+ int patch;
+ };
+
+ constexpr bool operator<(const version_t& lhs, const version_t& rhs)
+ {
+ return (lhs.major != rhs.major) ?
+ (lhs.major < rhs.major) :
+ (lhs.minor != rhs.minor) ?
+ (lhs.minor < rhs.minor) :
+ (lhs.patch < rhs.patch) ;
+ }
+
+ inline constexpr version_t version = { RA_VER_MAJOR, RA_VER_MINOR, RA_VER_PATCH };
#ifndef _KERNEL_MODE
- inline constexpr version_t min_driver_version = { 1, 4, 0 };
+ inline constexpr version_t min_driver_version = { 1, 4, 0 };
#endif
}
diff --git a/common/utility.hpp b/common/utility.hpp
index de90d44..5f5c186 100644
--- a/common/utility.hpp
+++ b/common/utility.hpp
@@ -81,4 +81,8 @@ namespace rawaccel {
return ilogb(x) == 0x400;
}
+ struct noop {
+ template
+ constexpr void operator()(Ts&&...) const noexcept {}
+ };
}
--
cgit v1.2.3
From 98de0eaac2f6d780da8ff4ad9533dad10be40204 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 1 Apr 2021 18:15:50 -0400
Subject: add flag to negate device match
---
common/rawaccel-base.hpp | 1 +
1 file changed, 1 insertion(+)
(limited to 'common')
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index 6996164..200c7d4 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -79,6 +79,7 @@ namespace rawaccel {
vec2d range_weights = { 1, 1 };
milliseconds time_min = DEFAULT_TIME_MIN;
+ bool ignore = false;
wchar_t device_id[MAX_DEV_ID_LEN] = {};
};
--
cgit v1.2.3
From e9866f27d78d9909fd4639cbd14a54b8ad5c2ec1 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 1 Apr 2021 18:33:00 -0400
Subject: driver - apply accel disregarding num packets
add setting for max time threshold
---
common/rawaccel-base.hpp | 4 ++++
common/rawaccel-validate.hpp | 4 ++++
2 files changed, 8 insertions(+)
(limited to 'common')
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index 200c7d4..ebc3f3e 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -5,9 +5,11 @@
namespace rawaccel {
using milliseconds = double;
+ inline constexpr int POLL_RATE_MIN = 125;
inline constexpr int POLL_RATE_MAX = 8000;
inline constexpr milliseconds DEFAULT_TIME_MIN = 1000.0 / POLL_RATE_MAX / 2;
+ inline constexpr milliseconds DEFAULT_TIME_MAX = 1000.0 / POLL_RATE_MIN * 2;
inline constexpr milliseconds WRITE_DELAY = 1000;
@@ -77,7 +79,9 @@ namespace rawaccel {
vec2d dir_multipliers = {};
domain_args dom_args = {};
vec2d range_weights = { 1, 1 };
+
milliseconds time_min = DEFAULT_TIME_MIN;
+ milliseconds time_max = DEFAULT_TIME_MAX;
bool ignore = false;
wchar_t device_id[MAX_DEV_ID_LEN] = {};
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
index b9ee2af..a02324b 100644
--- a/common/rawaccel-validate.hpp
+++ b/common/rawaccel-validate.hpp
@@ -162,6 +162,10 @@ namespace rawaccel {
error("minimum time"" must be positive");
}
+ if (args.time_max < args.time_min) {
+ error("max time is less than min time");
+ }
+
return ret;
}
--
cgit v1.2.3
From 31ffabf6f32ae14b6e2f6ce33763bf4ef1bff809 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 1 Apr 2021 19:40:19 -0400
Subject: make weights work in by component mode
domain weights now applied under inf norm
range weights now applied when equal
---
common/accel-union.hpp | 4 +--
common/rawaccel-base.hpp | 6 ++++
common/rawaccel.hpp | 74 +++++++++++++++++++++---------------------------
3 files changed, 41 insertions(+), 43 deletions(-)
(limited to 'common')
diff --git a/common/accel-union.hpp b/common/accel-union.hpp
index c63a9cc..7a6b173 100644
--- a/common/accel-union.hpp
+++ b/common/accel-union.hpp
@@ -95,10 +95,10 @@ namespace rawaccel {
}, *this);
}
- double apply(double speed) const
+ double apply(double speed, double weight = 1) const
{
return visit_accel([=](auto&& impl) {
- return impl(speed);
+ return apply_weighted(impl, speed, weight);
}, *this);
}
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index ebc3f3e..a9da458 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -87,4 +87,10 @@ namespace rawaccel {
wchar_t device_id[MAX_DEV_ID_LEN] = {};
};
+ template
+ inline double apply_weighted(AccelFunc&& f, double x, double w)
+ {
+ return 1 + (f(x) - 1) * w;
+ }
+
}
diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp
index 5d3ee15..ad4def4 100644
--- a/common/rawaccel.hpp
+++ b/common/rawaccel.hpp
@@ -88,46 +88,30 @@ namespace rawaccel {
inline double calculate(double x, double y)
{
- double abs_x = fabs(x);
- double abs_y = fabs(y);
+ double abs_scaled_x = fabs(x) * sigma_x;
+ double abs_scaled_y = fabs(y) * sigma_y;
- if (lp_norm_infinity) return maxsd(abs_x, abs_y);
+ if (lp_norm_infinity) {
+ return maxsd(abs_scaled_x, abs_scaled_y);
+ }
- double x_scaled = abs_x * sigma_x;
- double y_scaled = abs_y * sigma_y;
+ if (p == 2) {
+ return sqrtsd(abs_scaled_x * abs_scaled_x +
+ abs_scaled_y * abs_scaled_y);
+ }
- if (p == 2) return sqrtsd(x_scaled * x_scaled + y_scaled * y_scaled);
- else return pow(pow(x_scaled, p) + pow(y_scaled, p), p_inverse);
+ double dist_p = pow(abs_scaled_x, p) + pow(abs_scaled_y, p);
+ return pow(dist_p, p_inverse);
}
weighted_distance() = default;
};
- struct direction_weight {
- double diff = 0.0;
- double start = 1.0;
- bool should_apply = false;
-
- direction_weight(const vec2d& thetas)
- {
- diff = thetas.y - thetas.x;
- start = thetas.x;
-
- should_apply = diff != 0;
- }
-
- inline double atan_scale(double x, double y)
- {
- return M_2_PI * atan2(fabs(y), fabs(x));
- }
-
- inline double apply(double x, double y)
- {
- return atan_scale(x, y) * diff + start;
- }
-
- direction_weight() = default;
- };
+ inline double directional_weight(const vec2d& in, const vec2d& weights)
+ {
+ double atan_scale = M_2_PI * atan2(fabs(in.y), fabs(in.x));
+ return atan_scale * (weights.y - weights.x) + weights.x;
+ }
/// Struct to hold variables and methods for modifying mouse input
struct mouse_modifier {
@@ -135,12 +119,13 @@ namespace rawaccel {
bool apply_snap = false;
bool apply_accel = false;
bool by_component = false;
+ bool apply_directional_weight = false;
rotator rotate;
snapper snap;
double dpi_factor = 1;
double speed_cap = 0;
weighted_distance distance;
- direction_weight directional;
+ vec2d range_weights = { 1, 1 };
vec2 accels;
vec2d sensitivity = { 1, 1 };
vec2d directional_multipliers = {};
@@ -148,7 +133,8 @@ namespace rawaccel {
mouse_modifier(const settings& args) :
by_component(!args.combine_mags),
dpi_factor(1000 / args.dpi),
- speed_cap(args.speed_cap)
+ speed_cap(args.speed_cap),
+ range_weights(args.range_weights)
{
if (args.degrees_rotation != 0) {
rotate = rotator(args.degrees_rotation);
@@ -176,8 +162,8 @@ namespace rawaccel {
accels.y = accel_variant(args.argsv.y);
distance = weighted_distance(args.dom_args);
- directional = direction_weight(args.range_weights);
+ apply_directional_weight = range_weights.x != range_weights.y;
apply_accel = true;
}
@@ -207,22 +193,28 @@ namespace rawaccel {
if (!by_component) {
double mag = distance.calculate(movement.x, movement.y);
double speed = mag * norm;
- double scale = accels.x.apply(speed);
- if (directional.should_apply)
- {
- scale = (scale - 1)*directional.apply(movement.x, movement.y) + 1;
+ double weight;
+
+ if (apply_directional_weight) {
+ weight = directional_weight(movement, range_weights);
+ }
+ else {
+ weight = range_weights.x;
}
+ double scale = accels.x.apply(speed, weight);
movement.x *= scale;
movement.y *= scale;
}
else {
if (movement.x != 0) {
- movement.x *= accels.x.apply(fabs(movement.x) * norm);
+ double x = fabs(movement.x) * norm * distance.sigma_x;
+ movement.x *= accels.x.apply(x, range_weights.x);
}
if (movement.y != 0) {
- movement.y *= accels.y.apply(fabs(movement.y) * norm);
+ double y = fabs(movement.y) * norm * distance.sigma_y;
+ movement.y *= accels.y.apply(y, range_weights.y);
}
}
}
--
cgit v1.2.3
From 3751ac95831412dbdf9de9744c0ef59c34033d3d Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 1 Apr 2021 20:56:29 -0400
Subject: add minimum to complement speed cap
important feature
fixes some validation checks
---
common/rawaccel-base.hpp | 3 +-
common/rawaccel-validate.hpp | 9 +++--
common/rawaccel.hpp | 84 +++++++++++++++++++++++---------------------
3 files changed, 51 insertions(+), 45 deletions(-)
(limited to 'common')
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index a9da458..9900aab 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -72,7 +72,8 @@ namespace rawaccel {
double degrees_snap = 0;
bool combine_mags = true;
double dpi = 1000;
- double speed_cap = 0;
+ double speed_min = 0;
+ double speed_max = 0;
vec2 argsv;
vec2d sens = { 1, 1 };
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
index a02324b..bccb21c 100644
--- a/common/rawaccel-validate.hpp
+++ b/common/rawaccel-validate.hpp
@@ -133,8 +133,11 @@ namespace rawaccel {
error("dpi"" must be positive");
}
- if (args.speed_cap <= 0) {
- error("speed cap"" must be positive");
+ if (args.speed_max < 0) {
+ error("speed cap is negative");
+ }
+ else if (args.speed_max < args.speed_min) {
+ error("max speed is less than min speed");
}
if (args.sens.x == 0 || args.sens.y == 0) {
@@ -147,7 +150,7 @@ namespace rawaccel {
}
if (args.dom_args.lp_norm <= 0) {
- error("Lp norm can not be negative");
+ error("Lp norm must be positive");
}
if (args.dir_multipliers.x < 0 || args.dir_multipliers.y < 0) {
diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp
index ad4def4..8e10644 100644
--- a/common/rawaccel.hpp
+++ b/common/rawaccel.hpp
@@ -49,18 +49,18 @@ namespace rawaccel {
return input;
}
- snapper(double degrees) : threshold(minsd(fabs(degrees), 45) * M_PI / 180) {}
+ snapper(double degrees) : threshold(minsd(fabs(degrees), 45)* M_PI / 180) {}
snapper() = default;
};
- inline void cap_speed(vec2d& v, double cap, double norm) {
+ inline void clamp_speed(vec2d& v, double min, double max, double norm) {
double speed = sqrtsd(v.x * v.x + v.y * v.y) * norm;
- double ratio = minsd(speed, cap) / speed;
+ double ratio = clampsd(speed, min, max) / speed;
v.x *= ratio;
v.y *= ratio;
}
-
+
struct weighted_distance {
double p = 2.0;
double p_inverse = 0.5;
@@ -88,8 +88,8 @@ namespace rawaccel {
inline double calculate(double x, double y)
{
- double abs_scaled_x = fabs(x) * sigma_x;
- double abs_scaled_y = fabs(y) * sigma_y;
+ double abs_scaled_x = fabs(x) * sigma_x;
+ double abs_scaled_y = fabs(y) * sigma_y;
if (lp_norm_infinity) {
return maxsd(abs_scaled_x, abs_scaled_y);
@@ -97,7 +97,7 @@ namespace rawaccel {
if (p == 2) {
return sqrtsd(abs_scaled_x * abs_scaled_x +
- abs_scaled_y * abs_scaled_y);
+ abs_scaled_y * abs_scaled_y);
}
double dist_p = pow(abs_scaled_x, p) + pow(abs_scaled_y, p);
@@ -117,13 +117,14 @@ namespace rawaccel {
struct mouse_modifier {
bool apply_rotate = false;
bool apply_snap = false;
- bool apply_accel = false;
+ bool apply_speed_clamp = false;
bool by_component = false;
bool apply_directional_weight = false;
rotator rotate;
snapper snap;
double dpi_factor = 1;
- double speed_cap = 0;
+ double speed_min = 0;
+ double speed_max = 0;
weighted_distance distance;
vec2d range_weights = { 1, 1 };
vec2 accels;
@@ -133,14 +134,15 @@ namespace rawaccel {
mouse_modifier(const settings& args) :
by_component(!args.combine_mags),
dpi_factor(1000 / args.dpi),
- speed_cap(args.speed_cap),
+ speed_min(args.speed_min),
+ speed_max(args.speed_max),
range_weights(args.range_weights)
{
if (args.degrees_rotation != 0) {
rotate = rotator(args.degrees_rotation);
apply_rotate = true;
}
-
+
if (args.degrees_snap != 0) {
snap = snapper(args.degrees_snap);
apply_snap = true;
@@ -152,6 +154,8 @@ namespace rawaccel {
directional_multipliers.x = fabs(args.dir_multipliers.x);
directional_multipliers.y = fabs(args.dir_multipliers.y);
+ apply_speed_clamp = speed_max > 0;
+
if ((!by_component && args.argsv.x.mode == accel_mode::noaccel) ||
(args.argsv.x.mode == accel_mode::noaccel &&
args.argsv.y.mode == accel_mode::noaccel)) {
@@ -164,13 +168,12 @@ namespace rawaccel {
distance = weighted_distance(args.dom_args);
apply_directional_weight = range_weights.x != range_weights.y;
- apply_accel = true;
}
void modify(vec2d& movement, milliseconds time) {
apply_rotation(movement);
apply_angle_snap(movement);
- apply_acceleration(movement, [=] { return time; });
+ apply_acceleration(movement, time);
apply_sensitivity(movement);
}
@@ -182,43 +185,42 @@ namespace rawaccel {
if (apply_snap) movement = snap.apply(movement);
}
- template
- inline void apply_acceleration(vec2d& movement, TimeSupplier time_supp) {
- if (apply_accel) {
- milliseconds time = time_supp();
- double norm = dpi_factor / time;
-
- if (speed_cap > 0) cap_speed(movement, speed_cap, norm);
+ inline void apply_acceleration(vec2d& movement, milliseconds time) {
+ double norm = dpi_factor / time;
- if (!by_component) {
- double mag = distance.calculate(movement.x, movement.y);
- double speed = mag * norm;
+ if (apply_speed_clamp) {
+ clamp_speed(movement, speed_min, speed_max, norm);
+ }
- double weight;
+ if (!by_component) {
+ double mag = distance.calculate(movement.x, movement.y);
+ double speed = mag * norm;
- if (apply_directional_weight) {
- weight = directional_weight(movement, range_weights);
- }
- else {
- weight = range_weights.x;
- }
+ double weight;
- double scale = accels.x.apply(speed, weight);
- movement.x *= scale;
- movement.y *= scale;
+ if (apply_directional_weight) {
+ weight = directional_weight(movement, range_weights);
}
else {
- if (movement.x != 0) {
- double x = fabs(movement.x) * norm * distance.sigma_x;
- movement.x *= accels.x.apply(x, range_weights.x);
- }
- if (movement.y != 0) {
- double y = fabs(movement.y) * norm * distance.sigma_y;
- movement.y *= accels.y.apply(y, range_weights.y);
- }
+ weight = range_weights.x;
+ }
+
+ double scale = accels.x.apply(speed, weight);
+ movement.x *= scale;
+ movement.y *= scale;
+ }
+ else {
+ if (movement.x != 0) {
+ double x = fabs(movement.x) * norm * distance.sigma_x;
+ movement.x *= accels.x.apply(x, range_weights.x);
+ }
+ if (movement.y != 0) {
+ double y = fabs(movement.y) * norm * distance.sigma_y;
+ movement.y *= accels.y.apply(y, range_weights.y);
}
}
}
+
inline void apply_sensitivity(vec2d& movement) {
movement.x *= sensitivity.x;
--
cgit v1.2.3
From d8140fb31ba622f48756986d4d66db6b6ab8b511 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 1 Apr 2021 23:28:41 -0400
Subject: use callbacks for applying accel
---
common/accel-invoke.hpp | 43 ++++++++++++++++++++++++++
common/accel-union.hpp | 80 +++++++++++++++++++++----------------------------
common/common.vcxitems | 1 +
common/rawaccel.hpp | 21 +++++++------
common/utility.hpp | 7 +++++
5 files changed, 95 insertions(+), 57 deletions(-)
create mode 100644 common/accel-invoke.hpp
(limited to 'common')
diff --git a/common/accel-invoke.hpp b/common/accel-invoke.hpp
new file mode 100644
index 0000000..0e264c1
--- /dev/null
+++ b/common/accel-invoke.hpp
@@ -0,0 +1,43 @@
+#pragma once
+
+#include "accel-union.hpp"
+
+namespace rawaccel {
+
+ class accel_invoker {
+ using callback_t = double (*)(const accel_union&, double, double);
+
+ callback_t cb = &invoke_impl;
+
+ template
+ static double invoke_impl(const accel_union& u, double x, double w)
+ {
+ return apply_weighted(reinterpret_cast(u), x, w);
+ }
+
+ public:
+
+ accel_invoker(const accel_args& args)
+ {
+ cb = visit_accel([](auto&& arg) {
+ return &invoke_impl>;
+ }, make_mode(args), accel_union{});
+ }
+
+ accel_invoker() = default;
+
+ double invoke(const accel_union& u, double x, double weight = 1) const
+ {
+ return (*cb)(u, x, weight);
+ }
+ };
+
+ inline vec2 invokers(const settings& args)
+ {
+ return {
+ accel_invoker(args.argsv.x),
+ accel_invoker(args.argsv.y)
+ };
+ }
+
+}
diff --git a/common/accel-union.hpp b/common/accel-union.hpp
index 7a6b173..3d41a18 100644
--- a/common/accel-union.hpp
+++ b/common/accel-union.hpp
@@ -34,7 +34,7 @@ namespace rawaccel {
default: return internal_mode::noaccel;
}
}
- else if (mode < accel_mode{} || mode >= accel_mode::noaccel) {
+ else if (mode == accel_mode::noaccel) {
return internal_mode::noaccel;
}
else {
@@ -48,61 +48,49 @@ namespace rawaccel {
return make_mode(args.mode, args.lut_args.mode, args.legacy);
}
- template
- inline auto visit_accel(Visitor vis, Variant&& var)
+ template
+ constexpr auto visit_accel(Visitor vis, internal_mode mode, AccelUnion&& u)
{
- switch (var.tag) {
- case internal_mode::classic_lgcy: return vis(var.u.classic_l);
- case internal_mode::classic_gain: return vis(var.u.classic_g);
- case internal_mode::jump_lgcy: return vis(var.u.jump_l);
- case internal_mode::jump_gain: return vis(var.u.jump_g);
- case internal_mode::natural_lgcy: return vis(var.u.natural_l);
- case internal_mode::natural_gain: return vis(var.u.natural_g);
- case internal_mode::power_lgcy: return vis(var.u.power_l);
- case internal_mode::power_gain: return vis(var.u.power_g);
- case internal_mode::motivity_lgcy: return vis(var.u.motivity_l);
- case internal_mode::motivity_gain: return vis(var.u.motivity_g);
- case internal_mode::lut_log: return vis(var.u.log_lut);
- case internal_mode::lut_lin: return vis(var.u.lin_lut);
- default: return vis(var.u.noaccel);
+ switch (mode) {
+ case internal_mode::classic_lgcy: return vis(u.classic_l);
+ case internal_mode::classic_gain: return vis(u.classic_g);
+ case internal_mode::jump_lgcy: return vis(u.jump_l);
+ case internal_mode::jump_gain: return vis(u.jump_g);
+ case internal_mode::natural_lgcy: return vis(u.natural_l);
+ case internal_mode::natural_gain: return vis(u.natural_g);
+ case internal_mode::power_lgcy: return vis(u.power_l);
+ case internal_mode::power_gain: return vis(u.power_g);
+ case internal_mode::motivity_lgcy: return vis(u.motivity_l);
+ case internal_mode::motivity_gain: return vis(u.motivity_g);
+ case internal_mode::lut_log: return vis(u.log_lut);
+ case internal_mode::lut_lin: return vis(u.lin_lut);
+ default: return vis(u.noaccel);
}
}
- struct accel_variant {
- internal_mode tag = internal_mode::noaccel;
+ union accel_union {
+ classic classic_g;
+ classic_legacy classic_l;
+ jump jump_g;
+ jump_legacy jump_l;
+ natural natural_g;
+ natural_legacy natural_l;
+ power power_g;
+ power_legacy power_l;
+ sigmoid motivity_l;
+ motivity motivity_g;
+ linear_lut lin_lut;
+ binlog_lut log_lut;
+ accel_noaccel noaccel = {};
- union union_t {
- classic classic_g;
- classic_legacy classic_l;
- jump jump_g;
- jump_legacy jump_l;
- natural natural_g;
- natural_legacy natural_l;
- power power_g;
- power_legacy power_l;
- sigmoid motivity_l;
- motivity motivity_g;
- linear_lut lin_lut;
- binlog_lut log_lut;
- accel_noaccel noaccel = {};
- } u = {};
-
- accel_variant(const accel_args& args) :
- tag(make_mode(args))
+ accel_union(const accel_args& args)
{
visit_accel([&](auto& impl) {
impl = { args };
- }, *this);
- }
-
- double apply(double speed, double weight = 1) const
- {
- return visit_accel([=](auto&& impl) {
- return apply_weighted(impl, speed, weight);
- }, *this);
+ }, make_mode(args), *this);
}
- accel_variant() = default;
+ accel_union() = default;
};
}
diff --git a/common/common.vcxitems b/common/common.vcxitems
index 6d1b861..2cf2df2 100644
--- a/common/common.vcxitems
+++ b/common/common.vcxitems
@@ -15,6 +15,7 @@
+
diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp
index 8e10644..6710a0c 100644
--- a/common/rawaccel.hpp
+++ b/common/rawaccel.hpp
@@ -1,7 +1,6 @@
#pragma once
-#include "accel-union.hpp"
-#include "utility.hpp"
+#include "accel-invoke.hpp"
#define _USE_MATH_DEFINES
#include
@@ -127,7 +126,7 @@ namespace rawaccel {
double speed_max = 0;
weighted_distance distance;
vec2d range_weights = { 1, 1 };
- vec2 accels;
+ vec2 accels;
vec2d sensitivity = { 1, 1 };
vec2d directional_multipliers = {};
@@ -162,18 +161,18 @@ namespace rawaccel {
return;
}
- accels.x = accel_variant(args.argsv.x);
- accels.y = accel_variant(args.argsv.y);
+ accels.x = accel_union(args.argsv.x);
+ accels.y = accel_union(args.argsv.y);
distance = weighted_distance(args.dom_args);
apply_directional_weight = range_weights.x != range_weights.y;
}
- void modify(vec2d& movement, milliseconds time) {
+ void modify(vec2d& movement, const vec2& inv = {}, milliseconds time = 1) {
apply_rotation(movement);
apply_angle_snap(movement);
- apply_acceleration(movement, time);
+ apply_acceleration(movement, inv, time);
apply_sensitivity(movement);
}
@@ -185,7 +184,7 @@ namespace rawaccel {
if (apply_snap) movement = snap.apply(movement);
}
- inline void apply_acceleration(vec2d& movement, milliseconds time) {
+ inline void apply_acceleration(vec2d& movement, const vec2& inv, milliseconds time) {
double norm = dpi_factor / time;
if (apply_speed_clamp) {
@@ -205,18 +204,18 @@ namespace rawaccel {
weight = range_weights.x;
}
- double scale = accels.x.apply(speed, weight);
+ double scale = inv.x.invoke(accels.x, speed, weight);
movement.x *= scale;
movement.y *= scale;
}
else {
if (movement.x != 0) {
double x = fabs(movement.x) * norm * distance.sigma_x;
- movement.x *= accels.x.apply(x, range_weights.x);
+ movement.x *= inv.x.invoke(accels.x, x, range_weights.x);
}
if (movement.y != 0) {
double y = fabs(movement.y) * norm * distance.sigma_y;
- movement.y *= accels.y.apply(y, range_weights.y);
+ movement.y *= inv.y.invoke(accels.y, y, range_weights.y);
}
}
}
diff --git a/common/utility.hpp b/common/utility.hpp
index 5f5c186..a8e5f83 100644
--- a/common/utility.hpp
+++ b/common/utility.hpp
@@ -85,4 +85,11 @@ namespace rawaccel {
template
constexpr void operator()(Ts&&...) const noexcept {}
};
+
+ template struct remove_ref { using type = T; };
+ template struct remove_ref { using type = T; };
+ template struct remove_ref { using type = T; };
+
+ template
+ using remove_ref_t = typename remove_ref::type;
}
--
cgit v1.2.3
From 7c1f14845bc948e9ea25908e96099203d9433a69 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Tue, 6 Apr 2021 01:21:42 -0400
Subject: update wrapper + writer to handle lut
grapher is building but applying options still broken for the most part
---
common/accel-union.hpp | 3 +++
common/rawaccel-base.hpp | 3 ++-
common/rawaccel-validate.hpp | 3 ++-
3 files changed, 7 insertions(+), 2 deletions(-)
(limited to 'common')
diff --git a/common/accel-union.hpp b/common/accel-union.hpp
index 3d41a18..7f3d5d5 100644
--- a/common/accel-union.hpp
+++ b/common/accel-union.hpp
@@ -22,6 +22,7 @@ namespace rawaccel {
motivity_gain,
lut_log,
lut_lin,
+ lut_arb,
noaccel
};
@@ -31,6 +32,7 @@ namespace rawaccel {
switch (lut_mode) {
case table_mode::binlog: return internal_mode::lut_log;
case table_mode::linear: return internal_mode::lut_lin;
+ case table_mode::arbitrary: return internal_mode::lut_arb;
default: return internal_mode::noaccel;
}
}
@@ -64,6 +66,7 @@ namespace rawaccel {
case internal_mode::motivity_gain: return vis(u.motivity_g);
case internal_mode::lut_log: return vis(u.log_lut);
case internal_mode::lut_lin: return vis(u.lin_lut);
+ case internal_mode::lut_arb:
default: return vis(u.noaccel);
}
}
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index 9900aab..d318db5 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -29,7 +29,8 @@ namespace rawaccel {
enum class table_mode {
off,
binlog,
- linear
+ linear,
+ arbitrary
};
struct table_args {
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
index bccb21c..d625d20 100644
--- a/common/rawaccel-validate.hpp
+++ b/common/rawaccel-validate.hpp
@@ -44,7 +44,7 @@ namespace rawaccel {
error("stop must be greater than start");
}
- if (lut_args.num_elements < 2 ||
+ if (lut_args.num_elements < 2 ||
lut_args.num_elements > 1025) {
error("num must be between 2 and 1025");
}
@@ -73,6 +73,7 @@ namespace rawaccel {
}
}
+
if (args.offset < 0) {
error("offset can not be negative");
}
--
cgit v1.2.3
From 758de1d236f591de1d8b2fba4c58bfd8d5bbd26e Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Tue, 6 Apr 2021 18:04:28 -0700
Subject: Rename accelMotivity to growthRate
---
common/accel-motivity.hpp | 2 +-
common/rawaccel-base.hpp | 2 +-
common/rawaccel-validate.hpp | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
(limited to 'common')
diff --git a/common/accel-motivity.hpp b/common/accel-motivity.hpp
index 0c15598..c7ecb13 100644
--- a/common/accel-motivity.hpp
+++ b/common/accel-motivity.hpp
@@ -13,7 +13,7 @@ namespace rawaccel {
double constant;
sigmoid(const accel_args& args) :
- accel(exp(args.accel_motivity)),
+ accel(exp(args.growth_rate)),
motivity(2 * log(args.motivity)),
midpoint(log(args.midpoint)),
constant(-motivity / 2) {}
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index d318db5..fc49a62 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -52,7 +52,7 @@ namespace rawaccel {
double cap = 1.5;
double accel_classic = 0.005;
double accel_natural = 0.1;
- double accel_motivity = 1;
+ double growth_rate = 1;
double motivity = 1.5;
double power = 2;
double scale = 1;
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
index d625d20..338fbdc 100644
--- a/common/rawaccel-validate.hpp
+++ b/common/rawaccel-validate.hpp
@@ -82,7 +82,7 @@ namespace rawaccel {
error("cap"" must be positive");
}
- if (args.accel_motivity <= 0 ||
+ if (args.growth_rate <= 0 ||
args.accel_natural <= 0 ||
args.accel_classic <= 0) {
error("acceleration"" must be positive");
--
cgit v1.2.3
From 258fcd3bd236a787f07d7dac2049be524d86cb75 Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Tue, 6 Apr 2021 23:11:20 -0700
Subject: Fix natural legacy algorithm, rename accelNatural to decayRate
---
common/accel-natural.hpp | 4 ++--
common/rawaccel-base.hpp | 2 +-
common/rawaccel-validate.hpp | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
(limited to 'common')
diff --git a/common/accel-natural.hpp b/common/accel-natural.hpp
index 31ed190..1f18e0d 100644
--- a/common/accel-natural.hpp
+++ b/common/accel-natural.hpp
@@ -16,7 +16,7 @@ namespace rawaccel {
offset(args.offset),
limit(args.limit - 1)
{
- accel = args.accel_natural / fabs(limit);
+ accel = args.decay_rate / fabs(limit);
}
};
@@ -28,7 +28,7 @@ namespace rawaccel {
double offset_x = x - offset;
double decay = exp(-accel * offset_x);
- return limit * (1 - (decay * offset_x + offset) / x) + 1;
+ return limit * (1 - (decay)) + 1;
}
using natural_base::natural_base;
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index fc49a62..7dc1b96 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -51,7 +51,7 @@ namespace rawaccel {
double offset = 0;
double cap = 1.5;
double accel_classic = 0.005;
- double accel_natural = 0.1;
+ double decay_rate = 0.1;
double growth_rate = 1;
double motivity = 1.5;
double power = 2;
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
index 338fbdc..230ddac 100644
--- a/common/rawaccel-validate.hpp
+++ b/common/rawaccel-validate.hpp
@@ -83,7 +83,7 @@ namespace rawaccel {
}
if (args.growth_rate <= 0 ||
- args.accel_natural <= 0 ||
+ args.decay_rate <= 0 ||
args.accel_classic <= 0) {
error("acceleration"" must be positive");
}
--
cgit v1.2.3
From c06d88e602983b650d4a61b8fb248be3e15d822b Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Tue, 6 Apr 2021 23:34:13 -0700
Subject: natural legacy algorithm was correct, leave as it was
---
common/accel-natural.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'common')
diff --git a/common/accel-natural.hpp b/common/accel-natural.hpp
index 1f18e0d..28e17c2 100644
--- a/common/accel-natural.hpp
+++ b/common/accel-natural.hpp
@@ -28,7 +28,7 @@ namespace rawaccel {
double offset_x = x - offset;
double decay = exp(-accel * offset_x);
- return limit * (1 - (decay)) + 1;
+ return limit * (1 - (decay * offset_x + offset) / x) + 1;
}
using natural_base::natural_base;
--
cgit v1.2.3
From 5e858b059436375ed1c17f7dc1b3e47a7e8e1d5d Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Wed, 7 Apr 2021 01:05:59 -0700
Subject: Add active value labels for gain switch
---
common/rawaccel-base.hpp | 1 +
1 file changed, 1 insertion(+)
(limited to 'common')
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index 7dc1b96..6ce4468 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -23,6 +23,7 @@ namespace rawaccel {
natural,
power,
motivity,
+ lookuptable,
noaccel
};
--
cgit v1.2.3
From 8b3409bdd892481b459a1afbfa6fddea9b7bb448 Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Wed, 7 Apr 2021 23:13:01 -0700
Subject: Add arbitrary lut struct
---
common/accel-lookup.hpp | 103 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 18c9ea5..6c73605 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -149,4 +149,107 @@ namespace rawaccel {
binlog_lut(args.lut_args) {}
};
+ struct si_pair {
+ double slope = 0;
+ double intercept = 0;
+ };
+
+ struct arbitrary_lut_point {
+ double applicable_speed = 0;
+ si_pair slope_intercept = {};
+ };
+
+ struct arbitrary_lut {
+ fp_rep_range range;
+ arbitrary_lut_point data[LUT_CAPACITY] = {};
+ int log_lookup[LUT_CAPACITY] = {};
+ double first_point_speed;
+ double last_point_speed;
+ int last_index;
+
+ double operator()(double speed) const
+ {
+ int index = 0;
+
+ if (speed < first_point_speed)
+ {
+ // Apply from 0 index
+ }
+ else if (speed > last_point_speed)
+ {
+ index = last_index;
+ }
+ else if (speed > range.stop)
+ {
+ index = search_from(log_lookup[LUT_CAPACITY - 1], speed);
+ }
+ else if (speed < range.start)
+ {
+ index = search_from(0, speed);
+ }
+ else
+ {
+ int log_lookup = get_log_index(speed);
+ index = search_from(log_lookup, speed);
+ }
+
+ return apply(index, speed);
+ }
+
+ int inline get_log_index(double speed) const
+ {
+ double speed_log = log(speed) - range.start;
+ int index = (int)floor(speed_log * range.num);
+ return index;
+ }
+
+ int inline search_from(int index, double speed) const
+ {
+ int prev_index;
+
+ do
+ {
+ prev_index = index;
+ index++;
+ }
+ while (index <= last_index && data[index].applicable_speed < speed);
+
+ index--;
+ }
+
+ double inline apply(int index, double speed) const
+ {
+ si_pair pair = data[index].slope_intercept;
+ return pair.slope + pair.intercept / speed;
+ }
+
+ void fill(vec2d* points, int length) const
+ {
+ vec2d current = {0, 0};
+ vec2d next;
+ int log_index = 0;
+ double log_inner_iterator = range.start;
+ double log_inner_slice = 1 / range.num;
+ double log_value = pow(2, log_inner_iterator);
+
+ for (int i = 0; i < length; i++)
+ {
+ 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 };
+
+ this->data[i] = current_lut_point;
+
+ while (log_value < next.x)
+ {
+ this->log_lookup[log_index] = log_value;
+ log_index++;
+ log_inner_iterator += log_inner_slice;
+ log_value = pow(2, log_inner_iterator);
+ }
+ }
+ }
+ };
}
--
cgit v1.2.3
From 805ed31165c745e08d039a27838ccc5494df2db3 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 8 Apr 2021 02:29:18 -0400
Subject: unmark fill as const
---
common/accel-lookup.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 6c73605..965cbec 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -223,7 +223,7 @@ namespace rawaccel {
return pair.slope + pair.intercept / speed;
}
- void fill(vec2d* points, int length) const
+ void fill(vec2d* points, int length)
{
vec2d current = {0, 0};
vec2d next;
--
cgit v1.2.3
From c55d1bfd01147fa014ac07d4b03ef3cad8427ae6 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 8 Apr 2021 02:30:01 -0400
Subject: optimize a bit/refactor modify
---
common/accel-invoke.hpp | 11 +-
common/accel-jump.hpp | 5 +-
common/accel-natural.hpp | 8 +-
common/rawaccel-base.hpp | 5 +-
common/rawaccel-validate.hpp | 12 +-
common/rawaccel.hpp | 323 +++++++++++++++++--------------------------
common/utility.hpp | 27 ++--
7 files changed, 166 insertions(+), 225 deletions(-)
(limited to 'common')
diff --git a/common/accel-invoke.hpp b/common/accel-invoke.hpp
index 0e264c1..f2a95dc 100644
--- a/common/accel-invoke.hpp
+++ b/common/accel-invoke.hpp
@@ -20,7 +20,16 @@ namespace rawaccel {
accel_invoker(const accel_args& args)
{
cb = visit_accel([](auto&& arg) {
- return &invoke_impl>;
+ using T = remove_ref_t;
+
+ if constexpr (is_same_v) {
+ static_assert(sizeof motivity == sizeof binlog_lut);
+ return &invoke_impl;
+ }
+ else {
+ return &invoke_impl;
+ }
+
}, make_mode(args), accel_union{});
}
diff --git a/common/accel-jump.hpp b/common/accel-jump.hpp
index 2d13cae..30f9a49 100644
--- a/common/accel-jump.hpp
+++ b/common/accel-jump.hpp
@@ -2,9 +2,6 @@
#include "rawaccel-base.hpp"
-#define _USE_MATH_DEFINES
-#include
-
namespace rawaccel {
struct jump_base {
@@ -18,7 +15,7 @@ namespace rawaccel {
smooth_rate = 0;
}
else {
- smooth_rate = 2 * M_PI / (args.offset * args.smooth);
+ smooth_rate = 2 * PI / (args.offset * args.smooth);
}
}
diff --git a/common/accel-natural.hpp b/common/accel-natural.hpp
index 28e17c2..8d25351 100644
--- a/common/accel-natural.hpp
+++ b/common/accel-natural.hpp
@@ -26,8 +26,8 @@ namespace rawaccel {
{
if (x <= offset) return 1;
- double offset_x = x - offset;
- double decay = exp(-accel * offset_x);
+ double offset_x = offset - x;
+ double decay = exp(accel * offset_x);
return limit * (1 - (decay * offset_x + offset) / x) + 1;
}
@@ -41,8 +41,8 @@ namespace rawaccel {
{
if (x <= offset) return 1;
- double offset_x = x - offset;
- double decay = exp(-accel * offset_x);
+ double offset_x = offset - x;
+ double decay = exp(accel * offset_x);
double output = limit * (offset_x + decay / accel) + constant;
return output / x + 1;
}
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index 6ce4468..dde56f5 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -17,6 +17,9 @@ namespace rawaccel {
inline constexpr size_t LUT_CAPACITY = 1025;
+ inline constexpr double MAX_NORM = 16;
+ inline constexpr double PI = 3.14159265358979323846;
+
enum class accel_mode {
classic,
jump,
@@ -79,7 +82,7 @@ namespace rawaccel {
vec2 argsv;
vec2d sens = { 1, 1 };
- vec2d dir_multipliers = {};
+ vec2d dir_multipliers = { 1, 1 };
domain_args dom_args = {};
vec2d range_weights = { 1, 1 };
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
index 230ddac..4f7dd9c 100644
--- a/common/rawaccel-validate.hpp
+++ b/common/rawaccel-validate.hpp
@@ -141,6 +141,10 @@ namespace rawaccel {
error("max speed is less than min speed");
}
+ if (args.degrees_snap < 0 || args.degrees_snap > 45) {
+ error("snap angle must be between 0 and 45 degrees");
+ }
+
if (args.sens.x == 0 || args.sens.y == 0) {
error("sens multiplier is 0");
}
@@ -150,12 +154,12 @@ namespace rawaccel {
error("domain weights"" must be positive");
}
- if (args.dom_args.lp_norm <= 0) {
- error("Lp norm must be positive");
+ if (args.dir_multipliers.x <= 0 || args.dir_multipliers.y <= 0) {
+ error("directional multipliers must be positive");
}
- if (args.dir_multipliers.x < 0 || args.dir_multipliers.y < 0) {
- error("directional multipliers can not be negative");
+ if (args.dom_args.lp_norm < 2) {
+ error("Lp norm is less than 2 (default=2)");
}
if (args.range_weights.x <= 0 || args.range_weights.y <= 0) {
diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp
index 6710a0c..fb2d81a 100644
--- a/common/rawaccel.hpp
+++ b/common/rawaccel.hpp
@@ -2,235 +2,170 @@
#include "accel-invoke.hpp"
-#define _USE_MATH_DEFINES
-#include
-
namespace rawaccel {
- /// Struct to hold vector rotation details.
- struct rotator {
-
- /// Rotational vector, which points in the direction of the post-rotation positive x axis.
- vec2d rot_vec = { 1, 0 };
-
- ///
- /// Rotates given input vector according to struct's rotational vector.
- ///
- /// Input vector to be rotated
- /// 2d vector of rotated input.
- inline vec2d apply(const vec2d& input) const {
- return {
- input.x * rot_vec.x - input.y * rot_vec.y,
- input.x * rot_vec.y + input.y * rot_vec.x
- };
- }
-
- rotator(double degrees) {
- double rads = degrees * M_PI / 180;
- rot_vec = { cos(rads), sin(rads) };
- }
-
- rotator() = default;
- };
-
- struct snapper {
- double threshold = 0;
-
- inline vec2d apply(const vec2d& input) const {
- if (input.x != 0 && input.y != 0) {
- double angle = fabs(atan(input.y / input.x));
- auto mag = [&] { return sqrtsd(input.x * input.x + input.y * input.y); };
-
- if (angle > M_PI_2 - threshold) return { 0, _copysign(mag(), input.y) };
- if (angle < threshold) return { _copysign(mag(), input.x), 0 };
- }
-
- return input;
- }
-
- snapper(double degrees) : threshold(minsd(fabs(degrees), 45)* M_PI / 180) {}
-
- snapper() = default;
- };
-
- inline void clamp_speed(vec2d& v, double min, double max, double norm) {
- double speed = sqrtsd(v.x * v.x + v.y * v.y) * norm;
- double ratio = clampsd(speed, min, max) / speed;
- v.x *= ratio;
- v.y *= ratio;
+ inline vec2d direction(double degrees)
+ {
+ double radians = degrees * PI / 180;
+ return { cos(radians), sin(radians) };
}
- struct weighted_distance {
- double p = 2.0;
- double p_inverse = 0.5;
- bool lp_norm_infinity = false;
- double sigma_x = 1.0;
- double sigma_y = 1.0;
-
- weighted_distance(const domain_args& args)
- {
- sigma_x = args.domain_weights.x;
- sigma_y = args.domain_weights.y;
- if (args.lp_norm <= 0)
- {
- lp_norm_infinity = true;
- p = 0.0;
- p_inverse = 0.0;
- }
- else
- {
- lp_norm_infinity = false;
- p = args.lp_norm;
- p_inverse = 1 / args.lp_norm;
- }
- }
-
- inline double calculate(double x, double y)
- {
- double abs_scaled_x = fabs(x) * sigma_x;
- double abs_scaled_y = fabs(y) * sigma_y;
-
- if (lp_norm_infinity) {
- return maxsd(abs_scaled_x, abs_scaled_y);
- }
-
- if (p == 2) {
- return sqrtsd(abs_scaled_x * abs_scaled_x +
- abs_scaled_y * abs_scaled_y);
- }
-
- double dist_p = pow(abs_scaled_x, p) + pow(abs_scaled_y, p);
- return pow(dist_p, p_inverse);
- }
+ constexpr vec2d rotate(const vec2d& v, const vec2d& direction)
+ {
+ return {
+ v.x * direction.x - v.y * direction.y,
+ v.x * direction.y + v.y * direction.x
+ };
+ }
- weighted_distance() = default;
- };
+ inline double magnitude(const vec2d& v)
+ {
+ return sqrt(v.x * v.x + v.y * v.y);
+ }
- inline double directional_weight(const vec2d& in, const vec2d& weights)
+ inline double lp_distance(const vec2d& v, double p)
{
- double atan_scale = M_2_PI * atan2(fabs(in.y), fabs(in.x));
- return atan_scale * (weights.y - weights.x) + weights.x;
+ return pow(pow(v.x, p) + pow(v.y, p), 1 / p);
}
- /// Struct to hold variables and methods for modifying mouse input
- struct mouse_modifier {
+ class mouse_modifier {
+ public:
+ enum accel_distance_mode : unsigned char {
+ separate,
+ max,
+ Lp,
+ euclidean,
+ };
+
bool apply_rotate = false;
+ bool compute_ref_angle = false;
bool apply_snap = false;
- bool apply_speed_clamp = false;
- bool by_component = false;
+ bool cap_speed = false;
+ accel_distance_mode dist_mode = euclidean;
bool apply_directional_weight = false;
- rotator rotate;
- snapper snap;
- double dpi_factor = 1;
+ bool apply_dir_mul_x = false;
+ bool apply_dir_mul_y = false;
+
+ vec2d rot_vec = { 1, 0 };
+ double snap = 0;
+ double dpi_norm_factor = 1;
double speed_min = 0;
double speed_max = 0;
- weighted_distance distance;
+ vec2d domain_weights = { 1, 1 };
+ double p = 2;
vec2d range_weights = { 1, 1 };
- vec2 accels;
+ vec2d directional_multipliers = { 1, 1 };
vec2d sensitivity = { 1, 1 };
- vec2d directional_multipliers = {};
+ vec2 accel;
- mouse_modifier(const settings& args) :
- by_component(!args.combine_mags),
- dpi_factor(1000 / args.dpi),
- speed_min(args.speed_min),
- speed_max(args.speed_max),
- range_weights(args.range_weights)
+#ifdef _KERNEL_MODE
+ __forceinline
+#endif
+ void modify(vec2d& in, const vec2& inv, milliseconds time = 1) const
{
- if (args.degrees_rotation != 0) {
- rotate = rotator(args.degrees_rotation);
- apply_rotate = true;
- }
-
- if (args.degrees_snap != 0) {
- snap = snapper(args.degrees_snap);
- apply_snap = true;
- }
-
- if (args.sens.x != 0) sensitivity.x = args.sens.x;
- if (args.sens.y != 0) sensitivity.y = args.sens.y;
+ double ips_factor = dpi_norm_factor / time;
+ double reference_angle = 0;
- directional_multipliers.x = fabs(args.dir_multipliers.x);
- directional_multipliers.y = fabs(args.dir_multipliers.y);
+ if (apply_rotate) in = rotate(in, rot_vec);
- apply_speed_clamp = speed_max > 0;
-
- if ((!by_component && args.argsv.x.mode == accel_mode::noaccel) ||
- (args.argsv.x.mode == accel_mode::noaccel &&
- args.argsv.y.mode == accel_mode::noaccel)) {
- return;
+ if (compute_ref_angle && in.y != 0) {
+ if (in.x == 0) {
+ reference_angle = PI / 2;
+ }
+ else {
+ reference_angle = atan(fabs(in.y / in.x));
+
+ if (apply_snap) {
+ if (reference_angle > PI / 2 - snap) {
+ reference_angle = PI / 2;
+ in = { 0, _copysign(magnitude(in), in.y) };
+ }
+ else if (reference_angle < snap) {
+ reference_angle = 0;
+ in = { _copysign(magnitude(in), in.x), 0 };
+ }
+ }
+ }
}
- accels.x = accel_union(args.argsv.x);
- accels.y = accel_union(args.argsv.y);
-
- distance = weighted_distance(args.dom_args);
-
- apply_directional_weight = range_weights.x != range_weights.y;
- }
-
- void modify(vec2d& movement, const vec2& inv = {}, milliseconds time = 1) {
- apply_rotation(movement);
- apply_angle_snap(movement);
- apply_acceleration(movement, inv, time);
- apply_sensitivity(movement);
- }
-
- inline void apply_rotation(vec2d& movement) {
- if (apply_rotate) movement = rotate.apply(movement);
- }
-
- inline void apply_angle_snap(vec2d& movement) {
- if (apply_snap) movement = snap.apply(movement);
- }
-
- inline void apply_acceleration(vec2d& movement, const vec2& inv, milliseconds time) {
- double norm = dpi_factor / time;
-
- if (apply_speed_clamp) {
- clamp_speed(movement, speed_min, speed_max, norm);
+ if (cap_speed) {
+ double speed = magnitude(in) * ips_factor;
+ double ratio = clampsd(speed, speed_min, speed_max) / speed;
+ in.x *= ratio;
+ in.y *= ratio;
}
- if (!by_component) {
- double mag = distance.calculate(movement.x, movement.y);
- double speed = mag * norm;
+ vec2d abs_weighted_vel = {
+ fabs(in.x * ips_factor * domain_weights.x),
+ fabs(in.y * ips_factor * domain_weights.y)
+ };
- double weight;
+ if (dist_mode == separate) {
+ in.x *= inv.x.invoke(accel.x, abs_weighted_vel.x, range_weights.x);
+ in.y *= inv.y.invoke(accel.y, abs_weighted_vel.y, range_weights.y);
+ }
+ else {
+ double speed;
- if (apply_directional_weight) {
- weight = directional_weight(movement, range_weights);
+ if (dist_mode == max) {
+ speed = maxsd(abs_weighted_vel.x, abs_weighted_vel.y);
+ }
+ else if (dist_mode == Lp) {
+ speed = lp_distance(abs_weighted_vel, p);
}
else {
- weight = range_weights.x;
+ speed = magnitude(abs_weighted_vel);
}
- double scale = inv.x.invoke(accels.x, speed, weight);
- movement.x *= scale;
- movement.y *= scale;
- }
- else {
- if (movement.x != 0) {
- double x = fabs(movement.x) * norm * distance.sigma_x;
- movement.x *= inv.x.invoke(accels.x, x, range_weights.x);
- }
- if (movement.y != 0) {
- double y = fabs(movement.y) * norm * distance.sigma_y;
- movement.y *= inv.y.invoke(accels.y, y, range_weights.y);
+ double weight = range_weights.x;
+
+ if (apply_directional_weight) {
+ double diff = range_weights.y - range_weights.x;
+ weight += 2 / PI * reference_angle * diff;
}
- }
- }
-
- inline void apply_sensitivity(vec2d& movement) {
- movement.x *= sensitivity.x;
- movement.y *= sensitivity.y;
+ double scale = inv.x.invoke(accel.x, speed, weight);
+ in.x *= scale;
+ in.y *= scale;
+ }
- if (directional_multipliers.x > 0 && movement.x < 0) {
- movement.x *= directional_multipliers.x;
+ if (apply_dir_mul_x && in.x < 0) {
+ in.x *= directional_multipliers.x;
}
- if (directional_multipliers.y > 0 && movement.y < 0) {
- movement.y *= directional_multipliers.y;
+
+ if (apply_dir_mul_y && in.y < 0) {
+ in.y *= directional_multipliers.y;
}
+
+ in.x *= sensitivity.x;
+ in.y *= sensitivity.y;
+ }
+
+ mouse_modifier(const settings& args) :
+ rot_vec(direction(args.degrees_rotation)),
+ snap(args.degrees_snap * PI / 180),
+ dpi_norm_factor(1000 / args.dpi),
+ speed_min(args.speed_min),
+ speed_max(args.speed_max),
+ p(args.dom_args.lp_norm),
+ domain_weights(args.dom_args.domain_weights),
+ range_weights(args.range_weights),
+ directional_multipliers(args.dir_multipliers),
+ sensitivity(args.sens),
+ accel({ { args.argsv.x }, { args.argsv.y } })
+ {
+ cap_speed = speed_max > 0 && speed_min <= speed_max;
+ apply_rotate = rot_vec.x != 1;
+ apply_snap = snap != 0;
+ apply_directional_weight = range_weights.x != range_weights.y;
+ compute_ref_angle = apply_snap || apply_directional_weight;
+ apply_dir_mul_x = directional_multipliers.x != 1;
+ apply_dir_mul_y = directional_multipliers.y != 1;
+
+ if (!args.combine_mags) dist_mode = separate;
+ else if (p >= MAX_NORM) dist_mode = max;
+ else if (p > 2) dist_mode = Lp;
+ else dist_mode = euclidean;
}
mouse_modifier() = default;
diff --git a/common/utility.hpp b/common/utility.hpp
index a8e5f83..cbd19e3 100644
--- a/common/utility.hpp
+++ b/common/utility.hpp
@@ -1,24 +1,7 @@
#pragma once
-#ifdef _MANAGED
-#include
-#else
-#include
-#endif
-
namespace rawaccel {
-#ifdef _MANAGED
- inline double sqrtsd(double val) { return sqrt(val); }
-#else
- inline double sqrtsd(double val) {
- __m128d src = _mm_load_sd(&val);
- __m128d dst = _mm_sqrt_sd(src, src);
- _mm_store_sd(&val, dst);
- return val;
- }
-#endif
-
constexpr double minsd(double a, double b)
{
return (a < b) ? a : b;
@@ -92,4 +75,14 @@ namespace rawaccel {
template
using remove_ref_t = typename remove_ref::type;
+
+ template
+ struct is_same { static constexpr bool value = false; };
+
+ template
+ struct is_same { static constexpr bool value = true; };
+
+ template
+ inline constexpr bool is_same_v = is_same::value;
+
}
--
cgit v1.2.3
From b1d1a6ba629acb2e3748398a962ed274fade4e5f Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Wed, 7 Apr 2021 23:56:00 -0700
Subject: add constructor and improvements
---
common/accel-lookup.hpp | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 965cbec..5778de2 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -165,7 +165,8 @@ namespace rawaccel {
int log_lookup[LUT_CAPACITY] = {};
double first_point_speed;
double last_point_speed;
- int last_index;
+ int last_arbitrary_index;
+ int last_log_lookup_index;
double operator()(double speed) const
{
@@ -177,11 +178,11 @@ namespace rawaccel {
}
else if (speed > last_point_speed)
{
- index = last_index;
+ index = last_arbitrary_index;
}
else if (speed > range.stop)
{
- index = search_from(log_lookup[LUT_CAPACITY - 1], speed);
+ index = search_from(log_lookup[last_log_lookup_index], speed);
}
else if (speed < range.start)
{
@@ -212,7 +213,7 @@ namespace rawaccel {
prev_index = index;
index++;
}
- while (index <= last_index && data[index].applicable_speed < speed);
+ while (index <= last_arbitrary_index && data[index].applicable_speed < speed);
index--;
}
@@ -251,5 +252,21 @@ namespace rawaccel {
}
}
}
+
+ arbitrary_lut(vec2d* points, int length)
+ {
+ 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;
+
+ 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(points, length);
+ }
};
}
--
cgit v1.2.3
From 3b4a6f179d0c102f578024268f3cde129b384f55 Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Thu, 8 Apr 2021 00:02:37 -0700
Subject: Fix return bug
---
common/accel-lookup.hpp | 2 ++
1 file changed, 2 insertions(+)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 5778de2..24b61e5 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -216,6 +216,8 @@ namespace rawaccel {
while (index <= last_arbitrary_index && data[index].applicable_speed < speed);
index--;
+
+ return index;
}
double inline apply(int index, double speed) const
--
cgit v1.2.3
From e3fe51dde5afed99a393e3b1b1f611fde011d9f3 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 8 Apr 2021 12:38:08 -0400
Subject: fix some things
---
common/accel-natural.hpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'common')
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;
}
--
cgit v1.2.3
From 6197390760eba8ca1123d03637cbb9af0414c5f7 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 8 Apr 2021 12:45:43 -0400
Subject: fix conversions in arbitrary constructor
---
common/accel-lookup.hpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 24b61e5..ff89fa7 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -262,9 +262,9 @@ namespace rawaccel {
last_arbitrary_index = length - 2;
last_point_speed = points[last_arbitrary_index].x;
- double start = (int)floor(log(first_point_speed));
- double end = (int)floor(log(last_point_speed));
- double num = (int)floor(LUT_CAPACITY / (end - start));
+ int start = static_cast(log(first_point_speed));
+ int end = static_cast(log(last_point_speed));
+ int num = static_cast(LUT_CAPACITY / (end - start));
range = fp_rep_range{ start, end, num };
last_log_lookup_index = num * (end - start) - 1;
--
cgit v1.2.3
From 74ffcb8553795f4b50e544a1b2a0e53aec32a860 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 8 Apr 2021 21:48:17 -0400
Subject: make sizeof arbitrary close to others
refactor constructor/fix conversions
---
common/accel-lookup.hpp | 57 +++++++++++++++++++++++++++-----------------
common/accel-union.hpp | 3 ++-
common/rawaccel-base.hpp | 2 +-
common/rawaccel-validate.hpp | 2 +-
4 files changed, 39 insertions(+), 25 deletions(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index ff89fa7..6ebc90b 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -3,6 +3,8 @@
#include "rawaccel-base.hpp"
#include "utility.hpp"
+#include
+
namespace rawaccel {
struct linear_range {
@@ -55,7 +57,7 @@ namespace rawaccel {
template
struct lut_base {
- enum { capacity = LUT_CAPACITY };
+ enum { capacity = SPACED_LUT_CAPACITY };
using value_t = float;
template
@@ -150,19 +152,21 @@ 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] = {};
+ arbitrary_lut_point data[capacity] = {};
+ int log_lookup[capacity] = {};
double first_point_speed;
double last_point_speed;
int last_arbitrary_index;
@@ -226,8 +230,20 @@ namespace rawaccel {
return pair.slope + pair.intercept / speed;
}
- void fill(vec2d* points, int length)
+
+ void init(vec2d* points, int length)
{
+ 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(floor(log(first_point_speed)));
+ int end = static_cast(floor(log(last_point_speed)));
+ int num = static_cast(capacity / (end - start));
+ range = fp_rep_range{ start, end, num };
+ last_log_lookup_index = num * (end - start) - 1;
+
vec2d current = {0, 0};
vec2d next;
int log_index = 0;
@@ -240,14 +256,20 @@ namespace rawaccel {
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(slope),
+ static_cast(intercept)
+ };
+ arbitrary_lut_point current_lut_point = {
+ static_cast(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(log_value);
log_index++;
log_inner_iterator += log_inner_slice;
log_value = pow(2, log_inner_iterator);
@@ -257,18 +279,9 @@ namespace rawaccel {
arbitrary_lut(vec2d* points, int length)
{
- 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(log(first_point_speed));
- int end = static_cast(log(last_point_speed));
- int num = static_cast(LUT_CAPACITY / (end - start));
- range = fp_rep_range{ start, end, num };
- last_log_lookup_index = num * (end - start) - 1;
-
- fill(points, length);
+ init(points, length);
}
+
+ arbitrary_lut(const accel_args&) {}
};
}
diff --git a/common/accel-union.hpp b/common/accel-union.hpp
index 7f3d5d5..f5c26ba 100644
--- a/common/accel-union.hpp
+++ b/common/accel-union.hpp
@@ -66,7 +66,7 @@ namespace rawaccel {
case internal_mode::motivity_gain: return vis(u.motivity_g);
case internal_mode::lut_log: return vis(u.log_lut);
case internal_mode::lut_lin: return vis(u.lin_lut);
- case internal_mode::lut_arb:
+ case internal_mode::lut_arb: return vis(u.arb_lut);
default: return vis(u.noaccel);
}
}
@@ -84,6 +84,7 @@ namespace rawaccel {
motivity motivity_g;
linear_lut lin_lut;
binlog_lut log_lut;
+ arbitrary_lut arb_lut;
accel_noaccel noaccel = {};
accel_union(const accel_args& args)
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;
--
cgit v1.2.3
From 1494d248953ceedadd7a8e2fef7c957fa1f7350e Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Thu, 8 Apr 2021 22:00:08 -0400
Subject: make it safe
---
common/accel-lookup.hpp | 49 ++++++++++++++++++++++++++++---------------------
1 file changed, 28 insertions(+), 21 deletions(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 6ebc90b..6eb16d9 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -175,27 +175,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)
+ if (unsigned(last_arb_index) < capacity &&
+ unsigned(last_log_index) < capacity &&
+ 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)
- {
- 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);
@@ -208,7 +215,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;
@@ -217,7 +224,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--;
--
cgit v1.2.3
From aad1822effaa16c29dba316601923f31d66ce063 Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Thu, 8 Apr 2021 21:49:25 -0700
Subject: Progress in arbitrary
---
common/accel-lookup.hpp | 15 ++++++++-------
common/accel-union.hpp | 3 ++-
2 files changed, 10 insertions(+), 8 deletions(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 24b61e5..be107f8 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -163,6 +163,7 @@ namespace rawaccel {
fp_rep_range range;
arbitrary_lut_point data[LUT_CAPACITY] = {};
int log_lookup[LUT_CAPACITY] = {};
+ float raw_data_in[LUT_CAPACITY * 2] = {};
double first_point_speed;
double last_point_speed;
int last_arbitrary_index;
@@ -226,7 +227,7 @@ namespace rawaccel {
return pair.slope + pair.intercept / speed;
}
- void fill(vec2d* points, int length)
+ void fill(float* points, int length)
{
vec2d current = {0, 0};
vec2d next;
@@ -237,7 +238,7 @@ namespace rawaccel {
for (int i = 0; i < length; i++)
{
- next = points[i];
+ next = vec2d{ points[i * 2], points[i * 2 + 1] };
double slope = (next.y - current.y) / (next.x - current.x);
double intercept = next.y - slope * next.x;
si_pair current_si = { slope, intercept };
@@ -255,12 +256,12 @@ namespace rawaccel {
}
}
- arbitrary_lut(vec2d* points, int length)
+ arbitrary_lut(const table_args &args)
{
- first_point_speed = points[0].x;
+ 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;
- last_point_speed = points[last_arbitrary_index].x;
+ 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));
@@ -268,7 +269,7 @@ namespace rawaccel {
range = fp_rep_range{ start, end, num };
last_log_lookup_index = num * (end - start) - 1;
- fill(points, length);
+ fill(raw_data_in, length);
}
};
}
diff --git a/common/accel-union.hpp b/common/accel-union.hpp
index 7f3d5d5..f5c26ba 100644
--- a/common/accel-union.hpp
+++ b/common/accel-union.hpp
@@ -66,7 +66,7 @@ namespace rawaccel {
case internal_mode::motivity_gain: return vis(u.motivity_g);
case internal_mode::lut_log: return vis(u.log_lut);
case internal_mode::lut_lin: return vis(u.lin_lut);
- case internal_mode::lut_arb:
+ case internal_mode::lut_arb: return vis(u.arb_lut);
default: return vis(u.noaccel);
}
}
@@ -84,6 +84,7 @@ namespace rawaccel {
motivity motivity_g;
linear_lut lin_lut;
binlog_lut log_lut;
+ arbitrary_lut arb_lut;
accel_noaccel noaccel = {};
accel_union(const accel_args& args)
--
cgit v1.2.3
From e5e7896d0df3f73bf153a83dd5022ccf6365f8ee Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Fri, 9 Apr 2021 00:42:55 -0700
Subject: Fixed some bugs
---
common/accel-lookup.hpp | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index f70f2b1..c014b84 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -172,6 +172,8 @@ namespace rawaccel {
double last_point_speed;
int last_arbitrary_index;
int last_log_lookup_index;
+ double last_log_lookup_speed;
+ double first_log_lookup_speed;
double operator()(double speed) const
{
@@ -187,13 +189,13 @@ namespace rawaccel {
{
index = last_arb_index;
}
- else if (speed > range.stop)
+ else if (speed > last_log_lookup_speed)
{
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)
+ else if (speed < first_log_lookup_speed)
{
index = search_from(0, last_arb_index, speed);
}
@@ -246,8 +248,10 @@ namespace rawaccel {
last_arbitrary_index = length - 2;
last_point_speed = points[last_arbitrary_index].x;
- int start = static_cast(floor(log(first_point_speed)));
- int end = static_cast(floor(log(last_point_speed)));
+ int start = static_cast(floor(log(first_point_speed) / log(2.0)));
+ first_log_lookup_speed = pow(2.0, start);
+ int end = static_cast(floor(log(last_point_speed) / log(2.0)));
+ last_log_lookup_speed = pow(2.0, end);
int num = static_cast(capacity / (end - start));
range = fp_rep_range{ start, end, num };
last_log_lookup_index = num * (end - start) - 1;
@@ -256,7 +260,7 @@ namespace rawaccel {
vec2 next;
int log_index = 0;
double log_inner_iterator = range.start;
- double log_inner_slice = 1 / range.num;
+ double log_inner_slice = 1.0 / (range.num * 1.0);
double log_value = pow(2, log_inner_iterator);
for (int i = 0; i < length; i++)
@@ -275,9 +279,9 @@ namespace rawaccel {
this->data[i] = current_lut_point;
- while (log_value < next.x)
+ while (log_value < next.x && log_inner_iterator < end)
{
- this->log_lookup[log_index] = static_cast(log_value);
+ this->log_lookup[log_index] = i;
log_index++;
log_inner_iterator += log_inner_slice;
log_value = pow(2, log_inner_iterator);
--
cgit v1.2.3
From 060b79bda0b656bd9aec253389706681a565443e Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Fri, 9 Apr 2021 16:27:32 -0700
Subject: Some more small additions and fixes
---
common/accel-lookup.hpp | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index c014b84..97af0ff 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -167,6 +167,7 @@ namespace rawaccel {
fp_rep_range range;
;
arbitrary_lut_point data[capacity] = {};
+ float raw_data_in[capacity*2] = {};
int log_lookup[capacity] = {};
double first_point_speed;
double last_point_speed;
@@ -248,10 +249,10 @@ namespace rawaccel {
last_arbitrary_index = length - 2;
last_point_speed = points[last_arbitrary_index].x;
- int start = static_cast(floor(log(first_point_speed) / log(2.0)));
- first_log_lookup_speed = pow(2.0, start);
- int end = static_cast(floor(log(last_point_speed) / log(2.0)));
- last_log_lookup_speed = pow(2.0, end);
+ int start = static_cast(floor(log(first_point_speed)));
+ first_log_lookup_speed = exp(start*1.0);
+ int end = static_cast(floor(log(last_point_speed)));
+ last_log_lookup_speed = exp(end*1.0);
int num = static_cast(capacity / (end - start));
range = fp_rep_range{ start, end, num };
last_log_lookup_index = num * (end - start) - 1;
@@ -266,6 +267,8 @@ namespace rawaccel {
for (int i = 0; i < length; i++)
{
next = points[i];
+ raw_data_in[i * 2] = next.x;
+ raw_data_in[i * 2 + 1] = next.y;
double slope = (next.y - current.y) / (next.x - current.x);
double intercept = next.y - slope * next.x;
si_pair current_si = {
@@ -284,8 +287,10 @@ namespace rawaccel {
this->log_lookup[log_index] = i;
log_index++;
log_inner_iterator += log_inner_slice;
- log_value = pow(2, log_inner_iterator);
+ log_value = exp(log_inner_iterator);
}
+
+ current = next;
}
}
--
cgit v1.2.3
From 93f4475f969e75e9722edaad3645c51b184786d6 Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Fri, 9 Apr 2021 17:03:31 -0700
Subject: Mostly working now
---
common/accel-lookup.hpp | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 97af0ff..4314bfa 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -204,7 +204,8 @@ namespace rawaccel {
{
int log_index = get_log_index(speed);
if (unsigned(log_index) >= capacity) return 1;
- index = search_from(log_index, last_arb_index, speed);
+ int arbitrary_index = log_lookup[log_index];
+ index = search_from(arbitrary_index, last_arb_index, speed);
}
}
@@ -245,9 +246,9 @@ namespace rawaccel {
void fill(vec2* points, int length)
{
first_point_speed = points[0].x;
+ last_arbitrary_index = length - 1;
// -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;
+ last_point_speed = points[length-2].x;
int start = static_cast(floor(log(first_point_speed)));
first_log_lookup_speed = exp(start*1.0);
@@ -262,7 +263,7 @@ namespace rawaccel {
int log_index = 0;
double log_inner_iterator = range.start;
double log_inner_slice = 1.0 / (range.num * 1.0);
- double log_value = pow(2, log_inner_iterator);
+ double log_value = exp(log_inner_iterator);
for (int i = 0; i < length; i++)
{
@@ -276,7 +277,7 @@ namespace rawaccel {
static_cast(intercept)
};
arbitrary_lut_point current_lut_point = {
- static_cast(next.x),
+ static_cast(current.x),
current_si
};
--
cgit v1.2.3
From f1aae3548db5096fbea879d5c92cec532e606e5b Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Fri, 9 Apr 2021 17:38:32 -0700
Subject: additional fixes
---
common/accel-lookup.hpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 4314bfa..968eb6a 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -254,9 +254,9 @@ namespace rawaccel {
first_log_lookup_speed = exp(start*1.0);
int end = static_cast(floor(log(last_point_speed)));
last_log_lookup_speed = exp(end*1.0);
- int num = static_cast(capacity / (end - start));
+ int num = end > start ? static_cast(capacity / (end - start)) : 1;
range = fp_rep_range{ start, end, num };
- last_log_lookup_index = num * (end - start) - 1;
+ last_log_lookup_index = end > start ? num * (end - start) - 1 : 0;
vec2 current = {0, 0};
vec2 next;
--
cgit v1.2.3
From a6926be0e911b7b7637861866f41c3bca31a87a3 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Tue, 13 Apr 2021 23:59:21 -0400
Subject: move arbitrary input into settings
separate arbitrary mode from spaced modes, arbitrary now deserializes from default settings file
---
common/accel-lookup.hpp | 35 +++++++++++++++++++++--------------
common/accel-motivity.hpp | 4 ++--
common/accel-power.hpp | 1 -
common/accel-union.hpp | 32 +++++++++++++++++---------------
common/rawaccel-base.hpp | 25 ++++++++++++++++---------
common/rawaccel-validate.hpp | 11 ++++++++---
6 files changed, 64 insertions(+), 44 deletions(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 968eb6a..4e8354f 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -97,7 +97,7 @@ namespace rawaccel {
return y;
}
- linear_lut(const table_args& args) :
+ linear_lut(const spaced_lut_args& args) :
range({
args.start,
args.stop,
@@ -106,7 +106,7 @@ namespace rawaccel {
transfer(args.transfer) {}
linear_lut(const accel_args& args) :
- linear_lut(args.lut_args) {}
+ linear_lut(args.spaced_args) {}
};
struct binlog_lut : lut_base {
@@ -138,7 +138,7 @@ namespace rawaccel {
return y;
}
- binlog_lut(const table_args& args) :
+ binlog_lut(const spaced_lut_args& args) :
range({
static_cast(args.start),
static_cast(args.stop),
@@ -148,7 +148,7 @@ namespace rawaccel {
transfer(args.transfer) {}
binlog_lut(const accel_args& args) :
- binlog_lut(args.lut_args) {}
+ binlog_lut(args.spaced_args) {}
};
struct si_pair {
@@ -162,12 +162,10 @@ namespace rawaccel {
};
struct arbitrary_lut {
- enum { capacity = SPACED_LUT_CAPACITY / 4 };
+ enum { capacity = ARB_LUT_CAPACITY };
fp_rep_range range;
-;
arbitrary_lut_point data[capacity] = {};
- float raw_data_in[capacity*2] = {};
int log_lookup[capacity] = {};
double first_point_speed;
double last_point_speed;
@@ -175,6 +173,7 @@ namespace rawaccel {
int last_log_lookup_index;
double last_log_lookup_speed;
double first_log_lookup_speed;
+ bool velocity_points;
double operator()(double speed) const
{
@@ -205,6 +204,7 @@ namespace rawaccel {
int log_index = get_log_index(speed);
if (unsigned(log_index) >= capacity) return 1;
int arbitrary_index = log_lookup[log_index];
+ if (arbitrary_index < 0) return 1;
index = search_from(arbitrary_index, last_arb_index, speed);
}
@@ -238,12 +238,19 @@ namespace rawaccel {
double inline apply(int index, double speed) const
{
- si_pair pair = data[index].slope_intercept;
- return pair.slope + pair.intercept / speed;
- }
+ auto [slope, intercept] = data[index].slope_intercept;
+ if (velocity_points)
+ {
+ return slope + intercept / speed;
+ }
+ else
+ {
+ return slope * speed + intercept;
+ }
+ }
- void fill(vec2* points, int length)
+ void fill(const vec2* points, int length)
{
first_point_speed = points[0].x;
last_arbitrary_index = length - 1;
@@ -268,8 +275,6 @@ namespace rawaccel {
for (int i = 0; i < length; i++)
{
next = points[i];
- raw_data_in[i * 2] = next.x;
- raw_data_in[i * 2 + 1] = next.y;
double slope = (next.y - current.y) / (next.x - current.x);
double intercept = next.y - slope * next.x;
si_pair current_si = {
@@ -295,8 +300,10 @@ namespace rawaccel {
}
}
- arbitrary_lut(const accel_args&)
+ arbitrary_lut(const accel_args& args)
{
+ velocity_points = args.arb_args.velocity;
+ fill(args.arb_args.data, args.arb_args.length);
}
};
}
diff --git a/common/accel-motivity.hpp b/common/accel-motivity.hpp
index c7ecb13..0efe7ea 100644
--- a/common/accel-motivity.hpp
+++ b/common/accel-motivity.hpp
@@ -36,8 +36,8 @@ namespace rawaccel {
double sum = 0;
double a = 0;
auto sigmoid_sum = [&, sig = sigmoid(args)](double b) mutable {
- double interval = (b - a) / args.lut_args.partitions;
- for (int i = 1; i <= args.lut_args.partitions; i++) {
+ double interval = (b - a) / args.spaced_args.partitions;
+ for (int i = 1; i <= args.spaced_args.partitions; i++) {
sum += sig(a + i * interval) * interval;
}
a = b;
diff --git a/common/accel-power.hpp b/common/accel-power.hpp
index a21f926..c8faabb 100644
--- a/common/accel-power.hpp
+++ b/common/accel-power.hpp
@@ -24,5 +24,4 @@ namespace rawaccel {
}
};
- using power_legacy = power;
}
diff --git a/common/accel-union.hpp b/common/accel-union.hpp
index f5c26ba..8495a62 100644
--- a/common/accel-union.hpp
+++ b/common/accel-union.hpp
@@ -16,27 +16,31 @@ namespace rawaccel {
jump_gain,
natural_lgcy,
natural_gain,
- power_lgcy,
- power_gain,
motivity_lgcy,
motivity_gain,
+ power,
+ lut_arb,
lut_log,
lut_lin,
- lut_arb,
noaccel
};
- constexpr internal_mode make_mode(accel_mode mode, table_mode lut_mode, bool legacy)
+ constexpr internal_mode make_mode(accel_mode mode, spaced_lut_mode lut_mode, bool legacy)
{
- if (lut_mode != table_mode::off) {
+ if (lut_mode != spaced_lut_mode::off) {
switch (lut_mode) {
- case table_mode::binlog: return internal_mode::lut_log;
- case table_mode::linear: return internal_mode::lut_lin;
- case table_mode::arbitrary: return internal_mode::lut_arb;
+ case spaced_lut_mode::binlog: return internal_mode::lut_log;
+ case spaced_lut_mode::linear: return internal_mode::lut_lin;
default: return internal_mode::noaccel;
}
}
- else if (mode == accel_mode::noaccel) {
+ else if (mode == accel_mode::power) {
+ return internal_mode::power;
+ }
+ else if (mode == accel_mode::arb_lookup) {
+ return internal_mode::lut_arb;
+ }
+ else if (mode >= accel_mode::noaccel) {
return internal_mode::noaccel;
}
else {
@@ -47,7 +51,7 @@ namespace rawaccel {
constexpr internal_mode make_mode(const accel_args& args)
{
- return make_mode(args.mode, args.lut_args.mode, args.legacy);
+ return make_mode(args.mode, args.spaced_args.mode, args.legacy);
}
template
@@ -60,13 +64,12 @@ namespace rawaccel {
case internal_mode::jump_gain: return vis(u.jump_g);
case internal_mode::natural_lgcy: return vis(u.natural_l);
case internal_mode::natural_gain: return vis(u.natural_g);
- case internal_mode::power_lgcy: return vis(u.power_l);
- case internal_mode::power_gain: return vis(u.power_g);
case internal_mode::motivity_lgcy: return vis(u.motivity_l);
case internal_mode::motivity_gain: return vis(u.motivity_g);
+ case internal_mode::power: return vis(u.power);
+ case internal_mode::lut_arb: return vis(u.arb_lut);
case internal_mode::lut_log: return vis(u.log_lut);
case internal_mode::lut_lin: return vis(u.lin_lut);
- case internal_mode::lut_arb: return vis(u.arb_lut);
default: return vis(u.noaccel);
}
}
@@ -78,8 +81,7 @@ namespace rawaccel {
jump_legacy jump_l;
natural natural_g;
natural_legacy natural_l;
- power power_g;
- power_legacy power_l;
+ power power;
sigmoid motivity_l;
motivity motivity_g;
linear_lut lin_lut;
diff --git a/common/rawaccel-base.hpp b/common/rawaccel-base.hpp
index 2f49ec0..c1b2db3 100644
--- a/common/rawaccel-base.hpp
+++ b/common/rawaccel-base.hpp
@@ -16,6 +16,7 @@ namespace rawaccel {
inline constexpr size_t MAX_DEV_ID_LEN = 200;
inline constexpr size_t SPACED_LUT_CAPACITY = 1025;
+ inline constexpr size_t ARB_LUT_CAPACITY = SPACED_LUT_CAPACITY / 4;
inline constexpr double MAX_NORM = 16;
inline constexpr double PI = 3.14159265358979323846;
@@ -24,21 +25,20 @@ namespace rawaccel {
classic,
jump,
natural,
- power,
motivity,
- lookuptable,
+ power,
+ arb_lookup,
noaccel
};
- enum class table_mode {
+ enum class spaced_lut_mode {
off,
binlog,
- linear,
- arbitrary
+ linear
};
- struct table_args {
- table_mode mode = table_mode::off;
+ struct spaced_lut_args {
+ spaced_lut_mode mode = spaced_lut_mode::off;
bool transfer = true;
unsigned char partitions = 2;
short num_elements = 8;
@@ -46,12 +46,16 @@ namespace rawaccel {
double stop = 8;
};
+ struct table_args {
+ bool velocity = true;
+ int length = 0;
+ vec2 data[ARB_LUT_CAPACITY] = {};
+ };
+
struct accel_args {
accel_mode mode = accel_mode::noaccel;
bool legacy = false;
- table_args lut_args = {};
-
double offset = 0;
double cap = 1.5;
double accel_classic = 0.005;
@@ -65,6 +69,9 @@ namespace rawaccel {
double limit = 1.5;
double midpoint = 5;
double smooth = 0.5;
+
+ spaced_lut_args spaced_args;
+ table_args arb_args;
};
struct domain_args {
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
index ef6f667..2f54b5f 100644
--- a/common/rawaccel-validate.hpp
+++ b/common/rawaccel-validate.hpp
@@ -29,13 +29,13 @@ namespace rawaccel {
auto check_accel = [&error](const accel_args& args) {
static_assert(SPACED_LUT_CAPACITY == 1025, "update error msg");
- const auto& lut_args = args.lut_args;
+ const auto& lut_args = args.spaced_args;
if (lut_args.partitions <= 0) {
error("lut partitions"" must be positive");
}
- if (lut_args.mode == table_mode::linear) {
+ if (lut_args.mode == spaced_lut_mode::linear) {
if (lut_args.start <= 0) {
error("start"" must be positive");
}
@@ -49,7 +49,7 @@ namespace rawaccel {
error("num must be between 2 and 1025");
}
}
- else if (lut_args.mode == table_mode::binlog) {
+ else if (lut_args.mode == spaced_lut_mode::binlog) {
int istart = static_cast(lut_args.start);
int istop = static_cast(lut_args.stop);
@@ -73,6 +73,11 @@ namespace rawaccel {
}
}
+ if (args.mode == accel_mode::arb_lookup) {
+ if (args.arb_args.length < 2) {
+ error("lookup mode requires at least 2 points");
+ }
+ }
if (args.offset < 0) {
error("offset can not be negative");
--
cgit v1.2.3
From 7a08f3e261b7799cbc1daad54c1fbc2d5ec363a4 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Wed, 14 Apr 2021 00:13:19 -0400
Subject: fix arbitrary output starting from 0 in sens mode
---
common/accel-lookup.hpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
(limited to 'common')
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 4e8354f..2ca387f 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -265,7 +265,7 @@ namespace rawaccel {
range = fp_rep_range{ start, end, num };
last_log_lookup_index = end > start ? num * (end - start) - 1 : 0;
- vec2 current = {0, 0};
+ vec2 current = {0, velocity_points ? 0.0f : 1.0f };
vec2 next;
int log_index = 0;
double log_inner_iterator = range.start;
--
cgit v1.2.3
From 4995368332953c3a3bffa4599ba0bbac16ad7018 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Wed, 14 Apr 2021 14:00:30 -0400
Subject: bump version
---
common/rawaccel-version.h | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
(limited to 'common')
diff --git a/common/rawaccel-version.h b/common/rawaccel-version.h
index de8644b..384ba6f 100644
--- a/common/rawaccel-version.h
+++ b/common/rawaccel-version.h
@@ -1,8 +1,8 @@
#pragma once
#define RA_VER_MAJOR 1
-#define RA_VER_MINOR 4
-#define RA_VER_PATCH 3
+#define RA_VER_MINOR 5
+#define RA_VER_PATCH 0
#define RA_OS "Win7+"
@@ -30,7 +30,7 @@ namespace rawaccel {
inline constexpr version_t version = { RA_VER_MAJOR, RA_VER_MINOR, RA_VER_PATCH };
#ifndef _KERNEL_MODE
- inline constexpr version_t min_driver_version = { 1, 4, 0 };
+ inline constexpr version_t min_driver_version = { 1, 5, 0 };
#endif
}
--
cgit v1.2.3
From 0bff91add8525c3c3b3ac00d0508d3a798dee5e2 Mon Sep 17 00:00:00 2001
From: a1xd <68629610+a1xd@users.noreply.github.com>
Date: Wed, 14 Apr 2021 21:30:26 -0400
Subject: ensure normal return values from accel
---
common/accel-jump.hpp | 7 +++++--
common/accel-lookup.hpp | 11 ++++-------
2 files changed, 9 insertions(+), 9 deletions(-)
(limited to 'common')
diff --git a/common/accel-jump.hpp b/common/accel-jump.hpp
index 30f9a49..198891a 100644
--- a/common/accel-jump.hpp
+++ b/common/accel-jump.hpp
@@ -32,7 +32,7 @@ namespace rawaccel {
double smooth(double x) const
{
- return step.y * 1 / (1 + decay(x));
+ return step.y / (1 + decay(x));
}
double smooth_antideriv(double x) const
@@ -61,8 +61,11 @@ namespace rawaccel {
double operator()(double x) const
{
+ if (x <= 0) return 1;
+
if (is_smooth()) return 1 + (smooth_antideriv(x) + C) / x;
- else if (x < step.x) return 1;
+
+ if (x < step.x) return 1;
else return 1 + step.y * (x - step.x) / x;
}
};
diff --git a/common/accel-lookup.hpp b/common/accel-lookup.hpp
index 2ca387f..99f39e9 100644
--- a/common/accel-lookup.hpp
+++ b/common/accel-lookup.hpp
@@ -181,6 +181,8 @@ namespace rawaccel {
int last_arb_index = last_arbitrary_index;
int last_log_index = last_log_lookup_index;
+ if (speed <= 0) return 1;
+
if (unsigned(last_arb_index) < capacity &&
unsigned(last_log_index) < capacity &&
speed > first_point_speed)
@@ -222,18 +224,13 @@ namespace rawaccel {
int inline search_from(int index, int last, double speed) const
{
- int prev_index;
-
do
{
- prev_index = index;
index++;
- }
+ }
while (index <= last && data[index].applicable_speed < speed);
- index--;
-
- return index;
+ return index - 1;
}
double inline apply(int index, double speed) const
--
cgit v1.2.3
From 44c20e12d53434c47b08dbe855567316159d0469 Mon Sep 17 00:00:00 2001
From: Jacob Palecki
Date: Sat, 3 Jul 2021 14:52:54 -0700
Subject: Small fixes, guide additions, tweaks
---
common/rawaccel-validate.hpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
(limited to 'common')
diff --git a/common/rawaccel-validate.hpp b/common/rawaccel-validate.hpp
index 2f54b5f..e9d1120 100644
--- a/common/rawaccel-validate.hpp
+++ b/common/rawaccel-validate.hpp
@@ -83,8 +83,8 @@ namespace rawaccel {
error("offset can not be negative");
}
- if (args.cap <= 0) {
- error("cap"" must be positive");
+ if (args.cap < 0) {
+ error("cap"" must not be negative");
}
if (args.growth_rate <= 0 ||
--
cgit v1.2.3