import upstream maccel baseline
Tests / test_core_function (push) Failing after 12s

This commit is contained in:
2026-03-24 12:10:31 +00:00
parent 6e948d7b39
commit 5f1254d11a
108 changed files with 18930 additions and 0 deletions
+358
View File
@@ -0,0 +1,358 @@
use crate::libmaccel::fixedptc::Fpt;
use paste::paste;
/// Declare an enum for every parameter.
macro_rules! declare_common_params {
($($param:tt,)+) => {
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Param {
$($param),+
}
paste!(
#[derive(Debug)]
pub struct AllParamArgs {
$( pub [< $param:snake:lower >]: Fpt ),+
}
);
pub const ALL_PARAMS: &[Param] = &[ $(Param::$param),+ ];
};
}
// Helper macro to create FFI-safe curve parameter structs
macro_rules! make_curve_params_struct {
// Case: has parameters
($mode:tt, $($param:tt),+) => {
paste! {
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct [< $mode CurveParams >] {
$( pub [< $param:snake:lower >]: Fpt ),+
}
}
};
// Case: no parameters, add a ZST field for FFI safety
($mode:tt, ) => {
paste! {
#[repr(C)]
#[derive(Debug, Clone, Copy, PartialEq, Default)]
pub struct [< $mode CurveParams >] {
pub _ffi_guard: [u8; 0],
}
}
};
}
macro_rules! declare_params {
( Common { $($common_param:tt),+$(,)? } , $( $mode:tt { $($param:tt),*$(,)? }, )+) => {
declare_common_params! {
$( $common_param, )+
$( $( $param, )* )+
}
/// Array of all the common parameters for convenience.
pub const ALL_COMMON_PARAMS: &[Param] = &[ $( Param::$common_param),+ ];
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
#[derive(Debug, Default, PartialEq, Clone, Copy)]
#[repr(u8)]
pub enum AccelMode {
#[default]
$( $mode, )+
}
pub const ALL_MODES: &[AccelMode] = &[ $( AccelMode::$mode, )+ ];
paste! {
/// Define the complete shape (and memory layout) of the argument
/// of the sensitivity function as it is expected to be in `C`
#[repr(C)]
pub struct AccelParams {
$( pub [< $common_param:snake:lower >] : Fpt, )+
pub by_mode: AccelParamsByMode,
}
/// Represents the tagged union of curve-specific parameters.
#[repr(C, u8)]
pub enum AccelParamsByMode {
$(
$mode([< $mode CurveParams >] ),
)+
}
/// Represents the common parameters and their float values.
/// Use it to bulk set the common parameters.
#[cfg_attr(feature = "clap", derive(clap::Args))]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct CommonParamArgs {
$( pub [< $common_param:snake:lower >]: f64 ),+
}
}
paste! {
$(
// Use the helper macro to define the struct
make_curve_params_struct!($mode, $($param),*);
#[doc = "Array of all parameters for the `" $mode "` mode for convenience." ]
pub const [< ALL_ $mode:upper _PARAMS >]: &[Param] = &[ $( Param::$param),* ];
#[doc = "Represents the parameters for `" $mode "` curve and their float values"]
/// Use it to bulk set the curve's parameters.
#[cfg_attr(feature = "clap", derive(clap::Args))]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct [< $mode ParamArgs >] {
$( pub [< $param:snake:lower >]: f64 ),*
}
)+
/// Subcommands for the CLI
#[cfg(feature = "clap")]
pub mod subcommads {
#[derive(clap::Subcommand)]
pub enum SetParamByModesSubcommands {
/// Set all the common parameters
Common(super::CommonParamArgs),
$(
#[doc = "Set all the parameters for the " $mode " curve" ]
$mode(super::[< $mode ParamArgs >]),
)+
}
#[derive(clap::Subcommand)]
pub enum CliSubcommandSetParams {
/// Set the value for a single parameter
Param { name: crate::params::Param, value: f64 },
/// Set the acceleration mode (curve)
Mode { mode: crate::params::AccelMode },
/// Set the values for all parameters for a curve in order
All {
#[clap(subcommand)]
command: SetParamByModesSubcommands
},
}
#[derive(clap::Subcommand)]
pub enum GetParamsByModesSubcommands {
/// Get all the common parameters
Common,
$(
#[doc = "Get all the parameters for the " $mode " curve" ]
$mode
),+
}
#[derive(clap::Subcommand)]
pub enum CliSubcommandGetParams {
/// Get the value for a single parameter
Param { name: crate::params::Param },
/// Get the current acceleration mode (curve)
Mode,
/// Get the values for all parameters for a curve in order
All {
/// Print the values in one line, separated by a space
#[arg(long)]
oneline: bool,
#[arg(short, long)]
/// Print only the values
quiet: bool,
#[clap(subcommand)]
command: GetParamsByModesSubcommands
},
}
}
}
};
}
declare_params!(
Common {
SensMult,
YxRatio,
InputDpi,
AngleRotation
},
Linear {
Accel,
OffsetLinear,
OutputCap,
},
Natural {
DecayRate,
OffsetNatural,
Limit,
},
Synchronous {
Gamma,
Smooth,
Motivity,
SyncSpeed,
},
NoAccel {},
);
impl AccelMode {
pub fn as_title(&self) -> &'static str {
match self {
AccelMode::Linear => "Linear Acceleration",
AccelMode::Natural => "Natural (w/ Gain)",
AccelMode::Synchronous => "Synchronous",
AccelMode::NoAccel => "No Acceleration",
}
}
}
impl AccelMode {
pub const PARAM_NAME: &'static str = "MODE";
pub fn ordinal(&self) -> i64 {
(*self as i8).into()
}
}
impl Param {
/// The canonical internal name of the parameter.
pub fn name(&self) -> &'static str {
match self {
Param::SensMult => "SENS_MULT",
Param::YxRatio => "YX_RATIO",
Param::InputDpi => "INPUT_DPI",
Param::Accel => "ACCEL",
Param::OffsetLinear => "OFFSET",
Param::OffsetNatural => "OFFSET",
Param::OutputCap => "OUTPUT_CAP",
Param::DecayRate => "DECAY_RATE",
Param::Limit => "LIMIT",
Param::Gamma => "GAMMA",
Param::Smooth => "SMOOTH",
Param::Motivity => "MOTIVITY",
Param::SyncSpeed => "SYNC_SPEED",
Param::AngleRotation => "ANGLE_ROTATION",
}
}
pub fn display_name(&self) -> &'static str {
match self {
Param::SensMult => "Sens-Multiplier",
Param::Accel => "Accel",
Param::InputDpi => "Input DPI",
Param::OffsetLinear => "Offset",
Param::OffsetNatural => "Offset",
Param::OutputCap => "Output-Cap",
Param::YxRatio => "Y/x Ratio",
Param::DecayRate => "Decay-Rate",
Param::Limit => "Limit",
Param::Gamma => "Gamma",
Param::Smooth => "Smooth",
Param::Motivity => "Motivity",
Param::SyncSpeed => "Sync Speed",
Param::AngleRotation => "Angle Rotation",
}
}
pub fn description(&self) -> &'static str {
match self {
Param::SensMult => "Base sensitivity multiplier. Adjusts overall mouse speed.",
Param::YxRatio => {
"Y to X axis sensitivity ratio. Values > 1 increase vertical sensitivity."
}
Param::InputDpi => {
"Mouse DPI. Used to normalize to 1000 DPI equivalent for consistent acceleration."
}
Param::AngleRotation => "Rotation angle in degrees for sensitivity direction.",
Param::Accel => "Acceleration strength. Higher values = faster cursor at high speeds.",
Param::OffsetLinear => "Speed threshold (counts/ms) before acceleration begins.",
Param::OutputCap => "Maximum sensitivity multiplier cap. Prevents excessive speed.",
Param::DecayRate => "How quickly acceleration decays. Higher = faster decay.",
Param::OffsetNatural => "Speed threshold (counts/ms) for natural curve activation.",
Param::Limit => "Maximum gain limit for natural acceleration.",
Param::Gamma => "Exponent controlling curve shape. Higher = more aggressive ramp-up.",
Param::Smooth => "Smoothing factor (0-1). Higher = more gradual transitions.",
Param::Motivity => "Degree of acceleration effect. Must be > 1.",
Param::SyncSpeed => "Synchronization speed. Controls how fast sync responds.",
}
}
}
pub(crate) fn format_param_value(value: f64) -> String {
let mut number = format!("{value:.5}");
for idx in (1..number.len()).rev() {
let this_char = &number[idx..idx + 1];
if this_char != "0" {
if this_char == "." {
number.remove(idx);
}
break;
}
number.remove(idx);
}
number
}
#[cfg(test)]
#[test]
fn format_param_value_works() {
assert_eq!(format_param_value(1.5), "1.5");
assert_eq!(format_param_value(1.50), "1.5");
assert_eq!(format_param_value(100.0), "100");
assert_eq!(format_param_value(0.0600), "0.06");
assert_eq!(format_param_value(0.055000), "0.055");
}
pub(crate) fn validate_param_value(param_tag: Param, value: f64) -> anyhow::Result<()> {
match param_tag {
Param::SensMult => {}
Param::YxRatio => {}
Param::InputDpi => {
if value <= 0.0 {
anyhow::bail!("Input DPI must be positive");
}
}
Param::AngleRotation => {}
Param::Accel => {}
Param::OutputCap => {}
Param::OffsetLinear | Param::OffsetNatural => {
if value < 0.0 {
anyhow::bail!("offset cannot be less than 0");
}
}
Param::DecayRate => {
if value <= 0.0 {
anyhow::bail!("decay rate must be positive");
}
}
Param::Limit => {
if value < 1.0 {
anyhow::bail!("limit cannot be less than 1");
}
}
Param::Gamma => {
if value <= 0.0 {
anyhow::bail!("Gamma must be positive");
}
}
Param::Smooth => {
if !(0.0..=1.0).contains(&value) {
anyhow::bail!("Smooth must be between 0 and 1");
}
}
Param::Motivity => {
if value <= 1.0 {
anyhow::bail!("Motivity must be greater than 1");
}
}
Param::SyncSpeed => {
if value <= 0.0 {
anyhow::bail!("'Synchronous speed' must be positive");
}
}
}
Ok(())
}