diff options
| -rw-r--r-- | common/accel-experimenttwo.hpp | 43 | ||||
| -rw-r--r-- | common/rawaccel.hpp | 27 | ||||
| -rw-r--r-- | driver/driver.cpp | 29 | ||||
| -rw-r--r-- | wrapper/wrapper.cpp | 21 |
4 files changed, 90 insertions, 30 deletions
diff --git a/common/accel-experimenttwo.hpp b/common/accel-experimenttwo.hpp index 73428f7..a961f78 100644 --- a/common/accel-experimenttwo.hpp +++ b/common/accel-experimenttwo.hpp @@ -4,8 +4,17 @@ #include "accel-base.hpp" +#define RA_LOOKUP + namespace rawaccel { + constexpr size_t LUT_SIZE = 601; + + struct si_pair { + double slope = 0; + double intercept = 0; + }; + /// <summary> Struct to hold sigmoid (s-shaped) gain implementation. </summary> struct experimenttwo_impl { double rate; @@ -27,51 +36,49 @@ namespace rawaccel { inline double legacy_offset(double speed) const { return operator()(speed); } - inline double apply(double* lookup, double speed) + inline double apply(si_pair* lookup, double speed) const { - int index = map(speed); - double slope = lookup[index]; - double intercept = lookup[index + 1]; - return slope + intercept / speed; + si_pair pair = lookup[map(speed)]; + return pair.slope + pair.intercept / speed; } - inline int map(double speed) + inline int map(double speed) const { - int index = speed > 0 ? (int)floor(200*log10(speed)+402) : 0; + int index = speed > 0 ? (int)(100 * log10(speed) + 201) : 0; if (index < 0) return 0; - if (index > 1200) return 1200; + if (index >= LUT_SIZE) return LUT_SIZE - 1; return index; } - inline double fill(double* lookup) + inline void fill(si_pair* lookup) const { double lookup_speed = 0; double gain_integral_speed = 0; double gain = 0; double intercept = 0; double output = 0; - int index = 0; + double x = -2; - lookup[index] = gain; - lookup[index + 1] = intercept; + lookup[0] = {}; - for (double x = -2.0; x <= 4.0; x += 0.01) + for (size_t i = 1; i < LUT_SIZE; i++) { - index+=2; - lookup_speed = pow(10,x); + x += 0.01; + + lookup_speed = pow(10, x); while (gain_integral_speed < lookup_speed) { gain_integral_speed += 0.001; gain = operator()(gain_integral_speed); - output += gain*0.001; + output += gain * 0.001; } intercept = gain * lookup_speed - output; - lookup[index] = gain; - lookup[index + 1] = intercept; + + lookup[i] = { gain, intercept }; } } diff --git a/common/rawaccel.hpp b/common/rawaccel.hpp index 2914225..ca2d4d7 100644 --- a/common/rawaccel.hpp +++ b/common/rawaccel.hpp @@ -13,7 +13,7 @@ #include "accel-naturalgain.hpp" #include "accel-power.hpp" #include "accel-sigmoidgain.hpp" -#include "accel-experimentone.hpp" +#include "accel-experimenttwo.hpp" #include "accel-noaccel.hpp" namespace rawaccel { @@ -93,6 +93,8 @@ namespace rawaccel { } struct accel_variant { + si_pair* lookup; + accel_mode tag = accel_mode::noaccel; union union_t { @@ -107,15 +109,24 @@ namespace rawaccel { accel_noaccel noaccel = {}; } u = {}; - accel_variant(const accel_args& args, accel_mode mode) : - tag(mode) + accel_variant(const accel_args& args, accel_mode mode, si_pair* lut = nullptr) : + tag(mode), lookup(lut) { visit_accel([&](auto& impl) { impl = { args }; }, *this); + + if (lookup && tag == accel_mode::experimentone) { + u.experimentone.fn.fill(lookup); + } + } inline double apply(double speed) const { + if (lookup && tag == accel_mode::experimentone) { + return u.experimentone.fn.apply(lookup, speed); + } + return visit_accel([=](auto&& impl) { return impl(speed); }, *this); @@ -193,8 +204,8 @@ namespace rawaccel { velocity_gain_cap gain_cap; accel_scale_clamp clamp; - accelerator(const accel_args& args, accel_mode mode) : - accel(args, mode), gain_cap(args.gain_cap, accel), clamp(args.scale_cap) + 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) {} inline double apply(double speed) const { @@ -216,7 +227,7 @@ namespace rawaccel { vec2<accelerator> accels; vec2d sensitivity = { 1, 1 }; - mouse_modifier(const settings& args) : + mouse_modifier(const settings& args, vec2<si_pair*> luts = {}) : combine_magnitudes(args.combine_mags) { if (args.degrees_rotation != 0) { @@ -233,8 +244,8 @@ namespace rawaccel { return; } - accels.x = accelerator(args.argsv.x, args.modes.x); - accels.y = accelerator(args.argsv.y, args.modes.y); + accels.x = accelerator(args.argsv.x, args.modes.x, luts.x); + accels.y = accelerator(args.argsv.y, args.modes.y, luts.y); apply_accel = true; } diff --git a/driver/driver.cpp b/driver/driver.cpp index fb47477..4dd3d62 100644 --- a/driver/driver.cpp +++ b/driver/driver.cpp @@ -12,11 +12,13 @@ namespace ra = rawaccel; using milliseconds = double; +using lut_value_t = ra::si_pair; struct { ra::settings args; milliseconds tick_interval = 0; // set in DriverEntry ra::mouse_modifier modifier; + vec2<lut_value_t*> lookups = {}; } global; VOID @@ -168,8 +170,14 @@ Return Value: return; } - global.args = *reinterpret_cast<ra::settings*>(buffer); - global.modifier = { global.args }; + ra::settings new_settings = *reinterpret_cast<ra::settings*>(buffer); + + if (new_settings.time_min <= 0 || _isnanf(new_settings.time_min)) { + new_settings.time_min = ra::settings{}.time_min; + } + + global.args = new_settings; + global.modifier = { global.args, global.lookups }; WdfRequestComplete(Request, STATUS_SUCCESS); } @@ -251,6 +259,23 @@ Routine Description: KeQueryPerformanceCounter(&freq); global.tick_interval = 1e3 / freq.QuadPart; + auto make_lut = [] { + const size_t POOL_SIZE = sizeof(lut_value_t) * ra::LUT_SIZE; + + auto pool = ExAllocatePoolWithTag(NonPagedPool, POOL_SIZE, 'AR'); + + if (!pool) { + DebugPrint(("RA - failed to allocate LUT\n")); + } + else { + RtlZeroMemory(pool, POOL_SIZE); + } + + return reinterpret_cast<lut_value_t*>(pool); + }; + + global.lookups = { make_lut(), make_lut() }; + CreateControlDevice(driver); } else { diff --git a/wrapper/wrapper.cpp b/wrapper/wrapper.cpp index 3108bda..0778bc3 100644 --- a/wrapper/wrapper.cpp +++ b/wrapper/wrapper.cpp @@ -22,6 +22,13 @@ public ref struct DriverInterop public ref class ManagedAccel { mouse_modifier* const modifier_instance = new mouse_modifier(); +#ifdef RA_LOOKUP + si_pair* const lut_x = new si_pair[LUT_SIZE]; + si_pair* const lut_y = new si_pair[LUT_SIZE]; +#else + si_pair* lut_x = nullptr; + si_pair* lut_y = nullptr; +#endif public: static initonly double WriteDelay = -10000000 / -10000.0; @@ -29,11 +36,15 @@ public: virtual ~ManagedAccel() { delete modifier_instance; + delete[] lut_x; + delete[] lut_y; } !ManagedAccel() { delete modifier_instance; + delete[] lut_x; + delete[] lut_y; } Tuple<double, double>^ Accelerate(int x, int y, double time) @@ -49,7 +60,10 @@ public: void UpdateFromSettings(IntPtr argsIn) { - *modifier_instance = { *reinterpret_cast<settings*>(argsIn.ToPointer()) }; + *modifier_instance = { + *reinterpret_cast<settings*>(argsIn.ToPointer()) + , vec2<si_pair*>{ lut_x, lut_y } + }; } static ManagedAccel^ GetActiveAccel() @@ -58,7 +72,10 @@ public: wrapper_io::readFromDriver(args); auto active = gcnew ManagedAccel(); - *active->modifier_instance = { args }; + *active->modifier_instance = { + args + , vec2<si_pair*> { active->lut_x, active->lut_y } + }; return active; } }; |