summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControllerEmu/ControlGroup/Cursor.cpp
blob: 154b0ca862332ac8d3f3ed1d092bcc8b838ef4e0 (plain)
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
// Copyright 2017 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.

#include "InputCommon/ControllerEmu/ControlGroup/Cursor.h"

#include <algorithm>
#include <cmath>
#include <memory>
#include <string>

#include "Common/Common.h"
#include "Common/MathUtil.h"

#include "InputCommon/ControlReference/ControlReference.h"
#include "InputCommon/ControllerEmu/Control/Control.h"
#include "InputCommon/ControllerEmu/Control/Input.h"
#include "InputCommon/ControllerEmu/ControllerEmu.h"
#include "InputCommon/ControllerEmu/Setting/BooleanSetting.h"
#include "InputCommon/ControllerEmu/Setting/NumericSetting.h"

namespace ControllerEmu
{
Cursor::Cursor(const std::string& name_) : ControlGroup(name_, GroupType::Cursor)
{
  for (auto& named_direction : named_directions)
    controls.emplace_back(std::make_unique<Input>(Translate, named_direction));

  controls.emplace_back(std::make_unique<Input>(Translate, _trans("Forward")));
  controls.emplace_back(std::make_unique<Input>(Translate, _trans("Backward")));
  controls.emplace_back(std::make_unique<Input>(Translate, _trans("Hide")));
  controls.emplace_back(std::make_unique<Input>(Translate, _trans("Recenter")));

  numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Center"), 0.5));
  numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Width"), 0.5));
  numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Height"), 0.5));
  numeric_settings.emplace_back(std::make_unique<NumericSetting>(_trans("Dead Zone"), 0, 0, 20));
  boolean_settings.emplace_back(std::make_unique<BooleanSetting>(_trans("Relative Input"), false));
  boolean_settings.emplace_back(std::make_unique<BooleanSetting>(_trans("Auto-Hide"), false));
}

void Cursor::GetState(ControlState* const x, ControlState* const y, ControlState* const z,
                      const bool adjusted)
{
  const ControlState zz = controls[4]->control_ref->State() - controls[5]->control_ref->State();

  // silly being here
  if (zz > m_z)
    m_z = std::min(m_z + 0.1, zz);
  else if (zz < m_z)
    m_z = std::max(m_z - 0.1, zz);

  *z = m_z;

  if (m_autohide_timer > -1)
  {
    --m_autohide_timer;
  }

  ControlState yy = controls[0]->control_ref->State() - controls[1]->control_ref->State();
  ControlState xx = controls[3]->control_ref->State() - controls[2]->control_ref->State();

  const ControlState deadzone = numeric_settings[3]->GetValue();

  // reset auto-hide timer
  if (std::abs(m_prev_xx - xx) > deadzone || std::abs(m_prev_yy - yy) > deadzone)
  {
    m_autohide_timer = TIMER_VALUE;
  }

  // hide
  bool autohide = boolean_settings[1]->GetValue() && m_autohide_timer < 0;
  if (controls[6]->control_ref->State() > 0.5 || autohide)
  {
    *x = 10000;
    *y = 0;
  }
  else
  {
    // adjust cursor according to settings
    if (adjusted)
    {
      xx *= (numeric_settings[1]->GetValue() * 2);
      yy *= (numeric_settings[2]->GetValue() * 2);
      yy += (numeric_settings[0]->GetValue() - 0.5);
    }

    // relative input
    if (boolean_settings[0]->GetValue())
    {
      // deadzone to avoid the cursor slowly drifting
      if (std::abs(xx) > deadzone)
        m_x = MathUtil::Clamp(m_x + xx * SPEED_MULTIPLIER, -1.0, 1.0);
      if (std::abs(yy) > deadzone)
        m_y = MathUtil::Clamp(m_y + yy * SPEED_MULTIPLIER, -1.0, 1.0);

      // recenter
      if (controls[7]->control_ref->State() > 0.5)
      {
        m_x = 0.0;
        m_y = 0.0;
      }
    }
    else
    {
      m_x = xx;
      m_y = yy;
    }

    *x = m_x;
    *y = m_y;
  }

  m_prev_xx = xx;
  m_prev_yy = yy;
}
}  // namespace ControllerEmu