1 // Copyright 2019 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4 
5 #include "InputCommon/ControlReference/FunctionExpression.h"
6 
7 #include <algorithm>
8 #include <chrono>
9 #include <cmath>
10 
11 namespace ciface::ExpressionParser
12 {
13 using Clock = std::chrono::steady_clock;
14 using FSec = std::chrono::duration<ControlState>;
15 
16 // usage: toggle(toggle_state_input, [clear_state_input])
17 class ToggleExpression : public FunctionExpression
18 {
19 private:
20   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)21   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
22   {
23     // Optional 2nd argument for clearing state:
24     if (args.size() == 1 || args.size() == 2)
25       return ArgumentsAreValid{};
26     else
27       return ExpectedArguments{"toggle_state_input, [clear_state_input]"};
28   }
29 
GetValue() const30   ControlState GetValue() const override
31   {
32     const ControlState inner_value = GetArg(0).GetValue();
33 
34     if (inner_value < CONDITION_THRESHOLD)
35     {
36       m_released = true;
37     }
38     else if (m_released && inner_value > CONDITION_THRESHOLD)
39     {
40       m_released = false;
41       m_state ^= true;
42     }
43 
44     if (2 == GetArgCount() && GetArg(1).GetValue() > CONDITION_THRESHOLD)
45     {
46       m_state = false;
47     }
48 
49     return m_state;
50   }
51 
52   mutable bool m_released{};
53   mutable bool m_state{};
54 };
55 
56 // usage: not(expression)
57 class NotExpression : public FunctionExpression
58 {
59 private:
60   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)61   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
62   {
63     if (args.size() == 1)
64       return ArgumentsAreValid{};
65     else
66       return ExpectedArguments{"expression"};
67   }
68 
GetValue() const69   ControlState GetValue() const override { return 1.0 - GetArg(0).GetValue(); }
SetValue(ControlState value)70   void SetValue(ControlState value) override { GetArg(0).SetValue(1.0 - value); }
71 };
72 
73 // usage: sin(expression)
74 class SinExpression : public FunctionExpression
75 {
76 private:
77   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)78   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
79   {
80     if (args.size() == 1)
81       return ArgumentsAreValid{};
82     else
83       return ExpectedArguments{"expression"};
84   }
85 
GetValue() const86   ControlState GetValue() const override { return std::sin(GetArg(0).GetValue()); }
87 };
88 
89 // usage: cos(expression)
90 class CosExpression : public FunctionExpression
91 {
92 private:
93   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)94   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
95   {
96     if (args.size() == 1)
97       return ArgumentsAreValid{};
98     else
99       return ExpectedArguments{"expression"};
100   }
101 
GetValue() const102   ControlState GetValue() const override { return std::cos(GetArg(0).GetValue()); }
103 };
104 
105 // usage: tan(expression)
106 class TanExpression : public FunctionExpression
107 {
108 private:
109   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)110   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
111   {
112     if (args.size() == 1)
113       return ArgumentsAreValid{};
114     else
115       return ExpectedArguments{"expression"};
116   }
117 
GetValue() const118   ControlState GetValue() const override { return std::tan(GetArg(0).GetValue()); }
119 };
120 
121 // usage: asin(expression)
122 class ASinExpression : public FunctionExpression
123 {
124 private:
125   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)126   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
127   {
128     if (args.size() == 1)
129       return ArgumentsAreValid{};
130     else
131       return ExpectedArguments{"expression"};
132   }
133 
GetValue() const134   ControlState GetValue() const override { return std::asin(GetArg(0).GetValue()); }
135 };
136 
137 // usage: acos(expression)
138 class ACosExpression : public FunctionExpression
139 {
140 private:
141   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)142   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
143   {
144     if (args.size() == 1)
145       return ArgumentsAreValid{};
146     else
147       return ExpectedArguments{"expression"};
148   }
149 
GetValue() const150   ControlState GetValue() const override { return std::acos(GetArg(0).GetValue()); }
151 };
152 
153 // usage: atan(expression)
154 class ATanExpression : public FunctionExpression
155 {
156 private:
157   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)158   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
159   {
160     if (args.size() == 1)
161       return ArgumentsAreValid{};
162     else
163       return ExpectedArguments{"expression"};
164   }
165 
GetValue() const166   ControlState GetValue() const override { return std::atan(GetArg(0).GetValue()); }
167 };
168 
169 // usage: atan2(y, x)
170 class ATan2Expression : public FunctionExpression
171 {
172 private:
173   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)174   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
175   {
176     if (args.size() == 2)
177       return ArgumentsAreValid{};
178     else
179       return ExpectedArguments{"y, x"};
180   }
181 
GetValue() const182   ControlState GetValue() const override
183   {
184     return std::atan2(GetArg(0).GetValue(), GetArg(1).GetValue());
185   }
186 };
187 
188 // usage: sqrt(expression)
189 class SqrtExpression : public FunctionExpression
190 {
191 private:
192   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)193   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
194   {
195     if (args.size() == 1)
196       return ArgumentsAreValid{};
197     else
198       return ExpectedArguments{"expression"};
199   }
200 
GetValue() const201   ControlState GetValue() const override { return std::sqrt(GetArg(0).GetValue()); }
202 };
203 
204 // usage: pow(base, exponent)
205 class PowExpression : public FunctionExpression
206 {
207 private:
208   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)209   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
210   {
211     if (args.size() == 2)
212       return ArgumentsAreValid{};
213     else
214       return ExpectedArguments{"base, exponent"};
215   }
216 
GetValue() const217   ControlState GetValue() const override
218   {
219     return std::pow(GetArg(0).GetValue(), GetArg(1).GetValue());
220   }
221 };
222 
223 // usage: min(a, b)
224 class MinExpression : public FunctionExpression
225 {
226 private:
227   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)228   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
229   {
230     if (args.size() == 2)
231       return ArgumentsAreValid{};
232     else
233       return ExpectedArguments{"a, b"};
234   }
235 
GetValue() const236   ControlState GetValue() const override
237   {
238     return std::min(GetArg(0).GetValue(), GetArg(1).GetValue());
239   }
240 };
241 
242 // usage: max(a, b)
243 class MaxExpression : public FunctionExpression
244 {
245 private:
246   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)247   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
248   {
249     if (args.size() == 2)
250       return ArgumentsAreValid{};
251     else
252       return ExpectedArguments{"a, b"};
253   }
254 
GetValue() const255   ControlState GetValue() const override
256   {
257     return std::max(GetArg(0).GetValue(), GetArg(1).GetValue());
258   }
259 };
260 
261 // usage: clamp(value, min, max)
262 class ClampExpression : public FunctionExpression
263 {
264 private:
265   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)266   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
267   {
268     if (args.size() == 3)
269       return ArgumentsAreValid{};
270     else
271       return ExpectedArguments{"value, min, max"};
272   }
273 
GetValue() const274   ControlState GetValue() const override
275   {
276     return std::clamp(GetArg(0).GetValue(), GetArg(1).GetValue(), GetArg(2).GetValue());
277   }
278 };
279 
280 // usage: timer(seconds)
281 class TimerExpression : public FunctionExpression
282 {
283 private:
284   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)285   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
286   {
287     if (args.size() == 1)
288       return ArgumentsAreValid{};
289     else
290       return ExpectedArguments{"seconds"};
291   }
292 
GetValue() const293   ControlState GetValue() const override
294   {
295     const auto now = Clock::now();
296     const auto elapsed = now - m_start_time;
297 
298     const ControlState val = GetArg(0).GetValue();
299 
300     ControlState progress = std::chrono::duration_cast<FSec>(elapsed).count() / val;
301 
302     if (std::isinf(progress) || progress < 0.0)
303     {
304       // User configured a non-positive timer. Reset the timer and return 0.0.
305       progress = 0.0;
306       m_start_time = now;
307     }
308     else if (progress >= 1.0)
309     {
310       const ControlState reset_count = std::floor(progress);
311 
312       m_start_time += std::chrono::duration_cast<Clock::duration>(FSec(val * reset_count));
313       progress -= reset_count;
314     }
315 
316     return progress;
317   }
318 
319 private:
320   mutable Clock::time_point m_start_time = Clock::now();
321 };
322 
323 // usage: if(condition, true_expression, false_expression)
324 class IfExpression : public FunctionExpression
325 {
326 private:
327   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)328   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
329   {
330     if (args.size() == 3)
331       return ArgumentsAreValid{};
332     else
333       return ExpectedArguments{"condition, true_expression, false_expression"};
334   }
335 
GetValue() const336   ControlState GetValue() const override
337   {
338     return (GetArg(0).GetValue() > CONDITION_THRESHOLD) ? GetArg(1).GetValue() :
339                                                           GetArg(2).GetValue();
340   }
341 };
342 
343 // usage: minus(expression)
344 class UnaryMinusExpression : public FunctionExpression
345 {
346 private:
347   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)348   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
349   {
350     if (args.size() == 1)
351       return ArgumentsAreValid{};
352     else
353       return ExpectedArguments{"expression"};
354   }
355 
GetValue() const356   ControlState GetValue() const override
357   {
358     // Subtraction for clarity:
359     return 0.0 - GetArg(0).GetValue();
360   }
361 };
362 
363 // usage: deadzone(input, amount)
364 class DeadzoneExpression : public FunctionExpression
365 {
366   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)367   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
368   {
369     if (args.size() == 2)
370       return ArgumentsAreValid{};
371     else
372       return ExpectedArguments{"input, amount"};
373   }
374 
GetValue() const375   ControlState GetValue() const override
376   {
377     const ControlState val = GetArg(0).GetValue();
378     const ControlState deadzone = GetArg(1).GetValue();
379     return std::copysign(std::max(0.0, std::abs(val) - deadzone) / (1.0 - deadzone), val);
380   }
381 };
382 
383 // usage: smooth(input, seconds_up, seconds_down = seconds_up)
384 // seconds is seconds to change from 0.0 to 1.0
385 class SmoothExpression : public FunctionExpression
386 {
387   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)388   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
389   {
390     if (args.size() == 2 || args.size() == 3)
391       return ArgumentsAreValid{};
392     else
393       return ExpectedArguments{"input, seconds_up, seconds_down = seconds_up"};
394   }
395 
GetValue() const396   ControlState GetValue() const override
397   {
398     const auto now = Clock::now();
399     const auto elapsed = now - m_last_update;
400     m_last_update = now;
401 
402     const ControlState desired_value = GetArg(0).GetValue();
403 
404     const ControlState smooth_up = GetArg(1).GetValue();
405     const ControlState smooth_down = GetArgCount() == 3 ? GetArg(2).GetValue() : smooth_up;
406 
407     const ControlState smooth = (desired_value < m_value) ? smooth_down : smooth_up;
408     const ControlState max_move = std::chrono::duration_cast<FSec>(elapsed).count() / smooth;
409 
410     if (std::isinf(max_move))
411     {
412       m_value = desired_value;
413     }
414     else
415     {
416       const ControlState diff = desired_value - m_value;
417       m_value += std::copysign(std::min(max_move, std::abs(diff)), diff);
418     }
419 
420     return m_value;
421   }
422 
423 private:
424   mutable ControlState m_value = 0.0;
425   mutable Clock::time_point m_last_update = Clock::now();
426 };
427 
428 // usage: hold(input, seconds)
429 class HoldExpression : public FunctionExpression
430 {
431   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)432   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
433   {
434     if (args.size() == 2)
435       return ArgumentsAreValid{};
436     else
437       return ExpectedArguments{"input, seconds"};
438   }
439 
GetValue() const440   ControlState GetValue() const override
441   {
442     const auto now = Clock::now();
443 
444     const ControlState input = GetArg(0).GetValue();
445 
446     if (input < CONDITION_THRESHOLD)
447     {
448       m_state = false;
449       m_start_time = Clock::now();
450     }
451     else if (!m_state)
452     {
453       const auto hold_time = now - m_start_time;
454 
455       if (std::chrono::duration_cast<FSec>(hold_time).count() >= GetArg(1).GetValue())
456         m_state = true;
457     }
458 
459     return m_state;
460   }
461 
462 private:
463   mutable bool m_state = false;
464   mutable Clock::time_point m_start_time = Clock::now();
465 };
466 
467 // usage: tap(input, seconds, taps=2)
468 class TapExpression : public FunctionExpression
469 {
470   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)471   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
472   {
473     if (args.size() == 2 || args.size() == 3)
474       return ArgumentsAreValid{};
475     else
476       return ExpectedArguments{"input, seconds, taps = 2"};
477   }
478 
GetValue() const479   ControlState GetValue() const override
480   {
481     const auto now = Clock::now();
482 
483     const auto elapsed = std::chrono::duration_cast<FSec>(now - m_start_time).count();
484 
485     const ControlState input = GetArg(0).GetValue();
486     const ControlState seconds = GetArg(1).GetValue();
487 
488     const bool is_time_up = elapsed > seconds;
489 
490     const u32 desired_taps = GetArgCount() == 3 ? u32(GetArg(2).GetValue() + 0.5) : 2;
491 
492     if (input < CONDITION_THRESHOLD)
493     {
494       m_released = true;
495 
496       if (m_taps > 0 && is_time_up)
497       {
498         m_taps = 0;
499       }
500     }
501     else
502     {
503       if (m_released)
504       {
505         if (!m_taps)
506         {
507           m_start_time = now;
508         }
509 
510         ++m_taps;
511         m_released = false;
512       }
513 
514       return desired_taps == m_taps;
515     }
516 
517     return 0.0;
518   }
519 
520 private:
521   mutable bool m_released = true;
522   mutable u32 m_taps = 0;
523   mutable Clock::time_point m_start_time = Clock::now();
524 };
525 
526 // usage: relative(input, speed, [max_abs_value, [shared_state]])
527 // speed is max movement per second
528 class RelativeExpression : public FunctionExpression
529 {
530   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)531   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
532   {
533     if (args.size() >= 2 && args.size() <= 4)
534       return ArgumentsAreValid{};
535     else
536       return ExpectedArguments{"input, speed, [max_abs_value, [shared_state]]"};
537   }
538 
GetValue() const539   ControlState GetValue() const override
540   {
541     // There is a lot of funky math in this function but it allows for a variety of uses:
542     //
543     // e.g. A single mapping with a relatively adjusted value between 0.0 and 1.0
544     // Potentially useful for a trigger input
545     //  relative(`Up` - `Down`, 2.0)
546     //
547     // e.g. A value with two mappings (such as analog stick Up/Down)
548     // The shared state allows the two mappings to work together.
549     // This mapping (for up) returns a value clamped between 0.0 and 1.0
550     //  relative(`Up`, 2.0, 1.0, $y)
551     // This mapping (for down) returns the negative value clamped between 0.0 and 1.0
552     // (Adjustments created by `Down` are applied negatively to the shared state)
553     //  relative(`Down`, 2.0, -1.0, $y)
554 
555     const auto now = Clock::now();
556 
557     if (GetArgCount() >= 4)
558       m_state = GetArg(3).GetValue();
559 
560     const auto elapsed = std::chrono::duration_cast<FSec>(now - m_last_update).count();
561     m_last_update = now;
562 
563     const ControlState input = GetArg(0).GetValue();
564     const ControlState speed = GetArg(1).GetValue();
565 
566     const ControlState max_abs_value = (GetArgCount() >= 3) ? GetArg(2).GetValue() : 1.0;
567 
568     const ControlState max_move = input * elapsed * speed;
569     const ControlState diff_from_zero = std::abs(0.0 - m_state);
570     const ControlState diff_from_max = std::abs(max_abs_value - m_state);
571 
572     m_state += std::min(std::max(max_move, -diff_from_zero), diff_from_max) *
573                std::copysign(1.0, max_abs_value);
574 
575     if (GetArgCount() >= 4)
576       const_cast<Expression&>(GetArg(3)).SetValue(m_state);
577 
578     return std::max(0.0, m_state * std::copysign(1.0, max_abs_value));
579   }
580 
581 private:
582   mutable ControlState m_state = 0.0;
583   mutable Clock::time_point m_last_update = Clock::now();
584 };
585 
586 // usage: pulse(input, seconds)
587 class PulseExpression : public FunctionExpression
588 {
589   ArgumentValidation
ValidateArguments(const std::vector<std::unique_ptr<Expression>> & args)590   ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
591   {
592     if (args.size() == 2)
593       return ArgumentsAreValid{};
594     else
595       return ExpectedArguments{"input, seconds"};
596   }
597 
GetValue() const598   ControlState GetValue() const override
599   {
600     const auto now = Clock::now();
601 
602     const ControlState input = GetArg(0).GetValue();
603 
604     if (input < CONDITION_THRESHOLD)
605     {
606       m_released = true;
607     }
608     else if (m_released)
609     {
610       m_released = false;
611 
612       const auto seconds = std::chrono::duration_cast<Clock::duration>(FSec(GetArg(1).GetValue()));
613 
614       if (m_state)
615       {
616         m_release_time += seconds;
617       }
618       else
619       {
620         m_state = true;
621         m_release_time = now + seconds;
622       }
623     }
624 
625     if (m_state && now >= m_release_time)
626     {
627       m_state = false;
628     }
629 
630     return m_state;
631   }
632 
633 private:
634   mutable bool m_released = false;
635   mutable bool m_state = false;
636   mutable Clock::time_point m_release_time = Clock::now();
637 };
638 
MakeFunctionExpression(std::string_view name)639 std::unique_ptr<FunctionExpression> MakeFunctionExpression(std::string_view name)
640 {
641   if (name == "not")
642     return std::make_unique<NotExpression>();
643   if (name == "if")
644     return std::make_unique<IfExpression>();
645   if (name == "sin")
646     return std::make_unique<SinExpression>();
647   if (name == "cos")
648     return std::make_unique<CosExpression>();
649   if (name == "tan")
650     return std::make_unique<TanExpression>();
651   if (name == "asin")
652     return std::make_unique<ASinExpression>();
653   if (name == "acos")
654     return std::make_unique<ACosExpression>();
655   if (name == "atan")
656     return std::make_unique<ATanExpression>();
657   if (name == "atan2")
658     return std::make_unique<ATan2Expression>();
659   if (name == "sqrt")
660     return std::make_unique<SqrtExpression>();
661   if (name == "pow")
662     return std::make_unique<PowExpression>();
663   if (name == "min")
664     return std::make_unique<MinExpression>();
665   if (name == "max")
666     return std::make_unique<MaxExpression>();
667   if (name == "clamp")
668     return std::make_unique<ClampExpression>();
669   if (name == "timer")
670     return std::make_unique<TimerExpression>();
671   if (name == "toggle")
672     return std::make_unique<ToggleExpression>();
673   if (name == "minus")
674     return std::make_unique<UnaryMinusExpression>();
675   if (name == "deadzone")
676     return std::make_unique<DeadzoneExpression>();
677   if (name == "smooth")
678     return std::make_unique<SmoothExpression>();
679   if (name == "hold")
680     return std::make_unique<HoldExpression>();
681   if (name == "tap")
682     return std::make_unique<TapExpression>();
683   if (name == "relative")
684     return std::make_unique<RelativeExpression>();
685   if (name == "pulse")
686     return std::make_unique<PulseExpression>();
687 
688   return nullptr;
689 }
690 
CountNumControls() const691 int FunctionExpression::CountNumControls() const
692 {
693   int result = 0;
694 
695   for (auto& arg : m_args)
696     result += arg->CountNumControls();
697 
698   return result;
699 }
700 
UpdateReferences(ControlEnvironment & env)701 void FunctionExpression::UpdateReferences(ControlEnvironment& env)
702 {
703   for (auto& arg : m_args)
704     arg->UpdateReferences(env);
705 }
706 
707 FunctionExpression::ArgumentValidation
SetArguments(std::vector<std::unique_ptr<Expression>> && args)708 FunctionExpression::SetArguments(std::vector<std::unique_ptr<Expression>>&& args)
709 {
710   m_args = std::move(args);
711 
712   return ValidateArguments(m_args);
713 }
714 
GetArg(u32 number)715 Expression& FunctionExpression::GetArg(u32 number)
716 {
717   return *m_args[number];
718 }
719 
GetArg(u32 number) const720 const Expression& FunctionExpression::GetArg(u32 number) const
721 {
722   return *m_args[number];
723 }
724 
GetArgCount() const725 u32 FunctionExpression::GetArgCount() const
726 {
727   return u32(m_args.size());
728 }
729 
SetValue(ControlState)730 void FunctionExpression::SetValue(ControlState)
731 {
732 }
733 
734 }  // namespace ciface::ExpressionParser
735