summaryrefslogtreecommitdiff
path: root/grapher/Models/Serialized/DriverSettings.cs
blob: d42187c2fc3d4906939b8b835d1139afeaccd33f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
using System;
using System.Runtime.InteropServices;
using System.Threading;

namespace grapher.Models.Serialized
{
    #region Enumerations

    public enum AccelMode
    {
        linear, classic, natural, naturalgain, sigmoidgain, power, logarithm, noaccel
    }

    #endregion Enumerations

    #region Structs

    [StructLayout(LayoutKind.Sequential)]
    public struct AccelArgs
    {
        public double offset;
        public double legacy_offset;
        public double accel;
        public double limit;
        public double exponent;
        public double midpoint;
        public double powerScale;
        public double powerExponent;
        public double weight;
        public double rate;
        public double scaleCap;
        public double gainCap;
    };

    [StructLayout(LayoutKind.Sequential)]
    public struct Vec2 <T>
    {
        public T x;
        public T y;
    }

    #endregion Structs

    [StructLayout(LayoutKind.Sequential)]
    [Serializable]
    public class DriverSettings
    {
        #region Fields

        private static readonly IntPtr UnmanagedSettingsHandle = 
            Marshal.AllocHGlobal(Marshal.SizeOf<DriverSettings>());
        private static object UnmanagedSettingsLock = new object();

        public double rotation;
        public bool combineMagnitudes;
        public Vec2<AccelMode> modes;
        public Vec2<AccelArgs> args;
        public Vec2<double> sensitivity;
        public double minimumTime;

        #endregion Fields

        #region Methods

        public static DriverSettings GetActive()
        {
            DriverInterop.GetActiveSettings(UnmanagedSettingsHandle);
            return Marshal.PtrToStructure<DriverSettings>(UnmanagedSettingsHandle);
        }

        public static void SetActive(DriverSettings settings, Action<IntPtr> unmanagedActionBefore = null)
        {
            new Thread(() =>
            {
                lock (UnmanagedSettingsLock)
                {
                    Marshal.StructureToPtr(settings, UnmanagedSettingsHandle, false);
                    unmanagedActionBefore?.Invoke(UnmanagedSettingsHandle);
                    DriverInterop.SetActiveSettings(UnmanagedSettingsHandle);
                }
            }).Start();

        }

        public void SendToDriver(Action<IntPtr> unmanagedActionBefore = null)
        {
            SetActive(this, unmanagedActionBefore);
        }

        public void SendToDriverAndUpdate(ManagedAccel accel, Action betweenAccelAndWrite = null)
        {
            SendToDriver(settingsHandle =>
            {
                accel.UpdateFromSettings(settingsHandle);
                betweenAccelAndWrite?.Invoke();
            });
        }

        public bool verify()
        {
            /*
            if (args.accel < 0 || args.rate < 0) 
                    bad_arg("accel can not be negative, use a negative weight to compensate");
            if (args.rate > 1) bad_arg("rate can not be greater than 1");
            if (args.exponent <= 1) bad_arg("exponent must be greater than 1");
            if (args.limit <= 1) bad_arg("limit must be greater than 1");
            if (args.power_scale <= 0) bad_arg("scale must be positive");
            if (args.power_exp <= 0) bad_arg("exponent must be positive");
            if (args.midpoint < 0) bad_arg("midpoint must not be negative");
            if (args.time_min <= 0) bad_arg("min time must be positive");
            */
            return true;
        }

        #endregion Methods
    }
}