summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authora1xd <[email protected]>2021-03-29 17:14:49 -0400
committera1xd <[email protected]>2021-03-29 17:14:49 -0400
commit16dc4df3d438142ae378c9c6983585d06e0c6a33 (patch)
tree1080b11b6ec98d6f47509ced922f2c338e0068bd
parentMerge pull request #81 from a1xd/log-unhandled-ex (diff)
downloadrawaccel-16dc4df3d438142ae378c9c6983585d06e0c6a33.tar.xz
rawaccel-16dc4df3d438142ae378c9c6983585d06e0c6a33.zip
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
-rw-r--r--common/accel-base.hpp66
-rw-r--r--common/accel-classic.hpp121
-rw-r--r--common/accel-linear.hpp31
-rw-r--r--common/accel-motivity.hpp12
-rw-r--r--common/accel-natural.hpp48
-rw-r--r--common/accel-naturalgain.hpp28
-rw-r--r--common/accel-noaccel.hpp4
-rw-r--r--common/accel-power.hpp18
-rw-r--r--common/common.vcxitems5
-rw-r--r--common/rawaccel-settings.h50
-rw-r--r--common/rawaccel.hpp233
-rw-r--r--driver/driver.cpp11
-rw-r--r--driver/driver.h3
13 files changed, 260 insertions, 370 deletions
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 {
-
- /// <summary> Struct to hold arguments for an acceleration function. </summary>
- 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 <typename Func>
- 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 <typename Func>
- struct additive_accel : accel_val_base<Func> {
-
- 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 <typename Func>
- struct nonadditive_accel : accel_val_base<Func> {
-
- 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 <math.h>
+#include <float.h>
-#include "accel-base.hpp"
+#include "rawaccel-settings.h"
namespace rawaccel {
- /// <summary> Struct to hold "classic" (linear raised to power) acceleration implementation. </summary>
- struct classic_impl {
- double accel;
- double power;
- double power_inc;
- double offset;
- double multiplicative_const;
-
- classic_impl(const accel_args& args) :
- accel(args.accel), power(args.exponent - 1), offset(args.offset) {
- multiplicative_const = pow(accel, power);
- power_inc = power + 1;
- }
-
- inline double operator()(double speed) const {
- //f(x) = (mx)^(k-1)
- double base_speed = speed + offset;
- return multiplicative_const * pow(speed, power_inc) / base_speed;
- }
-
- inline double legacy_offset(double speed) const {
- return pow(accel * speed, power);
- }
- };
-
- using accel_classic = additive_accel<classic_impl>;
-
+ /// <summary> Struct to hold "classic" (linear raised to power) acceleration implementation. </summary>
+ struct classic_base {
+ double offset;
+ double power;
+ double accel_raised;
+
+ classic_base(const accel_args& args) :
+ offset(args.offset),
+ power(args.power),
+ accel_raised(pow(args.accel_classic, power - 1)) {}
+
+ double base_fn(double x) const {
+ return accel_raised * pow(x - offset, power) / x;
+ }
+ };
+
+ struct classic_legacy : classic_base {
+ double sens_cap = DBL_MAX;
+ double sign = 1;
+
+ classic_legacy(const accel_args& args) :
+ classic_base(args)
+ {
+ if (args.cap > 0) {
+ sens_cap = args.cap - 1;
+
+ if (sens_cap < 0) {
+ sens_cap = -sens_cap;
+ sign = -sign;
+ }
+ }
+ }
+
+ inline double operator()(double x) const {
+ if (x <= offset) return 1;
+ return sign * minsd(base_fn(x), sens_cap) + 1;
+ }
+ };
+
+ struct classic : classic_base {
+ vec2d gain_cap = { DBL_MAX, DBL_MAX };
+ double constant = 0;
+ double sign = 1;
+
+ classic(const accel_args& args) :
+ classic_base(args)
+ {
+ if (args.cap > 0) {
+ gain_cap.y = args.cap - 1;
+
+ if (gain_cap.y < 0) {
+ gain_cap.y = -gain_cap.y;
+ sign = -sign;
+ }
+
+ gain_cap.x = gain_inverse(gain_cap.y, args.accel_classic, power, offset);
+ constant = (base_fn(gain_cap.x) - gain_cap.y) * gain_cap.x;
+ }
+ }
+
+ double operator()(double x) const {
+ double output;
+
+ if (x <= offset) return 1;
+
+ if (x < gain_cap.x) {
+ output = base_fn(x);
+ }
+ else {
+ output = constant / x + gain_cap.y;
+ }
+
+ return sign * output + 1;
+ }
+
+ static double gain(double x, double accel, double power, double offset)
+ {
+ return power * pow(accel * (x - offset), power - 1);
+ }
+
+ static double gain_inverse(double y, double accel, double power, double offset)
+ {
+ return (accel * offset + pow(y / power, 1 / (power - 1))) / accel;
+ }
+
+ static double gain_accel(double x, double y, double power, double offset)
+ {
+ return -pow(y / power, 1 / (power - 1)) / (offset - x);
+ }
+ };
+
}
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 {
-
- /// <summary> Struct to hold linear acceleration implementation. </summary>
- 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<linear_impl>;
-
-}
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 <math.h>
-#include "accel-base.hpp"
+#include "rawaccel-settings.h"
#define RA_LOOKUP
@@ -16,14 +16,14 @@ namespace rawaccel {
};
/// <summary> Struct to hold sigmoid (s-shaped) gain implementation. </summary>
- 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<motivity_impl>;
-
}
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 <math.h>
-#include "accel-base.hpp"
+#include "rawaccel-settings.h"
namespace rawaccel {
/// <summary> Struct to hold "natural" (vanishing difference) acceleration implementation. </summary>
- 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<natural_impl>;
+ 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 <math.h>
-
-#include "accel-natural.hpp"
-
-namespace rawaccel {
-
- /// <summary> Struct to hold "natural" (vanishing difference) gain implementation. </summary>
- 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<naturalgain_impl>;
-}
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 <math.h>
-#include "accel-base.hpp"
+#include "rawaccel-settings.h"
namespace rawaccel {
/// <summary> Struct to hold power (non-additive) acceleration implementation. </summary>
- 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<power_impl>;
-
}
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 @@
<ProjectCapability Include="SourceItemsFromImports" />
</ItemGroup>
<ItemGroup>
- <ClInclude Include="$(MSBuildThisFileDirectory)accel-base.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)accel-classic.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)accel-motivity.hpp" />
- <ClInclude Include="$(MSBuildThisFileDirectory)accel-linear.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)accel-natural.hpp" />
- <ClInclude Include="$(MSBuildThisFileDirectory)accel-naturalgain.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)accel-noaccel.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)accel-power.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)rawaccel-error.hpp" />
@@ -30,7 +27,7 @@
<ClInclude Include="$(MSBuildThisFileDirectory)rawaccel.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)utility-install.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)utility-rawinput.hpp" />
- <ClInclude Include="$(MSBuildThisFileDirectory)x64-util.hpp" />
<ClInclude Include="$(MSBuildThisFileDirectory)vec2.h" />
+ <ClInclude Include="$(MSBuildThisFileDirectory)x64-util.hpp" />
</ItemGroup>
</Project> \ 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<accel_mode> modes = { accel_mode::noaccel, accel_mode::noaccel };
+ double dpi = 1000;
+ double speed_cap = 0;
+
vec2<accel_args> 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 <math.h>
-#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;
};
- /// <summary> Struct to hold clamp (min and max) details for acceleration application </summary>
- 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
+ };
- /// <summary>
- /// Clamps given input to min at lo, max at hi.
- /// </summary>
- /// <param name="scale">Double to be clamped</param>
- /// <returns>Clamped input as double</returns>
- 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 <typename Visitor, typename Variant>
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;
};
- /// <summary> Struct to hold information about applying a gain cap. </summary>
- struct velocity_gain_cap {
-
- // <summary> The minimum speed past which gain cap is applied. </summary>
- double threshold = 0;
-
- // <summary> The gain at the point of cap </summary>
- double slope = 0;
-
- // <summary> The intercept for the line with above slope to give continuous velocity function </summary>
- double intercept = 0;
-
- /// <summary>
- /// 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.
- /// </summary>
- /// <param name="speed"> The speed at which velocity gain cap will kick in </param>
- /// <param name="accel"> The accel implementation used in the containing accel_variant </param>
- 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;
- }
-
- /// <summary>
- /// Applies velocity gain cap to speed.
- /// Returns scale value by which to multiply input to place on gain cap line.
- /// </summary>
- /// <param name="speed"> Speed to be capped </param>
- /// <returns> Scale multiplier for input </returns>
- inline double apply(double speed) const {
- return slope + intercept / speed;
- }
-
- /// <summary>
- /// Whether gain cap should be applied to given speed.
- /// </summary>
- /// <param name="speed"> Speed to check against threshold. </param>
- /// <returns> Whether gain cap should be applied. </returns>
- 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<accelerator> accels;
+ vec2<accel_variant> accels;
vec2d sensitivity = { 1, 1 };
vec2d directional_multipliers = {};
mouse_modifier(const settings& args, vec2<si_pair*> 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);
}
}
}
diff --git a/driver/driver.cpp b/driver/driver.cpp
index 0c21f34..235571c 100644
--- a/driver/driver.cpp
+++ b/driver/driver.cpp
@@ -1,8 +1,9 @@
+#include "driver.h"
+
#include <rawaccel.hpp>
#include <rawaccel-io-def.h>
#include <rawaccel-version.h>
-#include "driver.h"
#ifdef ALLOC_PRAGMA
#pragma alloc_text (INIT, DriverEntry)
@@ -11,8 +12,6 @@
#pragma alloc_text (PAGE, RawaccelControl)
#endif
-namespace ra = rawaccel;
-
using milliseconds = double;
using lut_value_t = ra::si_pair;
@@ -21,7 +20,7 @@ struct {
milliseconds tick_interval = 0; // set in DriverEntry
ra::mouse_modifier modifier;
vec2<lut_value_t*> lookups = {};
-} global;
+} global = {};
VOID
RawaccelCallback(
@@ -59,7 +58,7 @@ Arguments:
bool any = num_packets > 0;
bool rel_move = !(InputDataStart->Flags & MOUSE_MOVE_ABSOLUTE);
bool dev_match = global.args.device_id[0] == 0 ||
- wcsncmp(devExt->dev_id, global.args.device_id, MAX_DEV_ID_LEN) == 0;
+ wcsncmp(devExt->dev_id, global.args.device_id, ra::MAX_DEV_ID_LEN) == 0;
if (any && rel_move && dev_match) {
// if IO is backed up to the point where we get more than 1 packet here
@@ -507,7 +506,7 @@ Return Value:
if (NT_SUCCESS(nts)) {
auto* id_ptr = reinterpret_cast<WCHAR*>(iosb.Information);
- wcsncpy(FilterGetData(hDevice)->dev_id, id_ptr, MAX_DEV_ID_LEN);
+ wcsncpy(FilterGetData(hDevice)->dev_id, id_ptr, ra::MAX_DEV_ID_LEN);
DebugPrint(("Device ID = %ws\n", id_ptr));
ExFreePool(id_ptr);
}
diff --git a/driver/driver.h b/driver/driver.h
index a0381fb..ba575d3 100644
--- a/driver/driver.h
+++ b/driver/driver.h
@@ -16,12 +16,13 @@
#define SYMBOLIC_NAME_STRING L"\\DosDevices\\rawaccel"
using counter_t = long long;
+namespace ra = rawaccel;
typedef struct _DEVICE_EXTENSION {
counter_t counter;
vec2d carry;
CONNECT_DATA UpperConnectData;
- WCHAR dev_id[MAX_DEV_ID_LEN];
+ WCHAR dev_id[ra::MAX_DEV_ID_LEN];
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_EXTENSION, FilterGetData)