summaryrefslogtreecommitdiffstats
path: root/src/yuzu/configuration/configure_input_player_widget.h
blob: 91c3343f15a9a3a8c424c7381c01ce0ad17972c8 (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
// Copyright 2020 yuzu Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.

#pragma once

#include <array>
#include <QFrame>
#include <QPointer>
#include "core/frontend/input.h"
#include "core/settings.h"

class QLabel;

using AnalogParam = std::array<Common::ParamPackage, Settings::NativeAnalog::NumAnalogs>;
using ButtonParam = std::array<Common::ParamPackage, Settings::NativeButton::NumButtons>;

// Widget for representing controller animations
class PlayerControlPreview : public QFrame {
    Q_OBJECT

public:
    explicit PlayerControlPreview(QWidget* parent);
    ~PlayerControlPreview() override;

    void SetPlayerInput(std::size_t index, const ButtonParam& buttons_param,
                        const AnalogParam& analogs_param);
    void SetPlayerInputRaw(std::size_t index, const Settings::ButtonsRaw& buttons_,
                           Settings::AnalogsRaw analogs_);
    void SetConnectedStatus(bool checked);
    void SetControllerType(Settings::ControllerType type);
    void BeginMappingButton(std::size_t button_id);
    void BeginMappingAnalog(std::size_t button_id);
    void EndMapping();
    void UpdateInput();

protected:
    void paintEvent(QPaintEvent* event) override;

private:
    enum class Direction : std::size_t {
        None,
        Up,
        Right,
        Down,
        Left,
    };

    enum class Symbol {
        House,
        A,
        B,
        X,
        Y,
        L,
        R,
        C,
        SL,
        ZL,
        ZR,
        SR,
    };

    struct AxisValue {
        QPointF value{};
        QPointF raw_value{};
        Input::AnalogProperties properties{};
        int size{};
        QPoint offset{};
        bool active{};
    };

    struct LedPattern {
        bool position1;
        bool position2;
        bool position3;
        bool position4;
    };

    struct ColorMapping {
        QColor outline{};
        QColor primary{};
        QColor left{};
        QColor right{};
        QColor button{};
        QColor button2{};
        QColor font{};
        QColor font2{};
        QColor highlight{};
        QColor highlight2{};
        QColor transparent{};
        QColor indicator{};
        QColor led_on{};
        QColor led_off{};
        QColor slider{};
        QColor slider_button{};
        QColor slider_arrow{};
        QColor deadzone{};
    };

    static LedPattern GetColorPattern(std::size_t index, bool player_on);
    void UpdateColors();

    // Draw controller functions
    void DrawHandheldController(QPainter& p, QPointF center);
    void DrawDualController(QPainter& p, QPointF center);
    void DrawLeftController(QPainter& p, QPointF center);
    void DrawRightController(QPainter& p, QPointF center);
    void DrawProController(QPainter& p, QPointF center);
    void DrawGCController(QPainter& p, QPointF center);

    // Draw body functions
    void DrawHandheldBody(QPainter& p, QPointF center);
    void DrawDualBody(QPainter& p, QPointF center);
    void DrawLeftBody(QPainter& p, QPointF center);
    void DrawRightBody(QPainter& p, QPointF center);
    void DrawProBody(QPainter& p, QPointF center);
    void DrawGCBody(QPainter& p, QPointF center);

    // Draw triggers functions
    void DrawProTriggers(QPainter& p, QPointF center, bool left_pressed, bool right_pressed);
    void DrawGCTriggers(QPainter& p, QPointF center, bool left_pressed, bool right_pressed);
    void DrawHandheldTriggers(QPainter& p, QPointF center, bool left_pressed, bool right_pressed);
    void DrawDualTriggers(QPainter& p, QPointF center, bool left_pressed, bool right_pressed);
    void DrawDualTriggersTopView(QPainter& p, QPointF center, bool left_pressed,
                                 bool right_pressed);
    void DrawDualZTriggersTopView(QPainter& p, QPointF center, bool left_pressed,
                                  bool right_pressed);
    void DrawLeftTriggers(QPainter& p, QPointF center, bool left_pressed);
    void DrawLeftZTriggers(QPainter& p, QPointF center, bool left_pressed);
    void DrawLeftTriggersTopView(QPainter& p, QPointF center, bool left_pressed);
    void DrawLeftZTriggersTopView(QPainter& p, QPointF center, bool left_pressed);
    void DrawRightTriggers(QPainter& p, QPointF center, bool right_pressed);
    void DrawRightZTriggers(QPainter& p, QPointF center, bool right_pressed);
    void DrawRightTriggersTopView(QPainter& p, QPointF center, bool right_pressed);
    void DrawRightZTriggersTopView(QPainter& p, QPointF center, bool right_pressed);

    // Draw joystick functions
    void DrawJoystick(QPainter& p, QPointF center, float size, bool pressed);
    void DrawJoystickSideview(QPainter& p, QPointF center, float angle, float size, bool pressed);
    void DrawRawJoystick(QPainter& p, QPointF center, QPointF value,
                         const Input::AnalogProperties& properties);
    void DrawProJoystick(QPainter& p, QPointF center, QPointF offset, float scalar, bool pressed);
    void DrawGCJoystick(QPainter& p, QPointF center, bool pressed);

    // Draw button functions
    void DrawCircleButton(QPainter& p, QPointF center, bool pressed, float button_size);
    void DrawRoundButton(QPainter& p, QPointF center, bool pressed, float width, float height,
                         Direction direction = Direction::None, float radius = 2);
    void DrawMinusButton(QPainter& p, QPointF center, bool pressed, int button_size);
    void DrawPlusButton(QPainter& p, QPointF center, bool pressed, int button_size);
    void DrawGCButtonX(QPainter& p, QPointF center, bool pressed);
    void DrawGCButtonY(QPainter& p, QPointF center, bool pressed);
    void DrawGCButtonZ(QPainter& p, QPointF center, bool pressed);
    void DrawArrowButtonOutline(QPainter& p, const QPointF center, float size = 1.0f);
    void DrawArrowButton(QPainter& p, QPointF center, Direction direction, bool pressed,
                         float size = 1.0f);
    void DrawTriggerButton(QPainter& p, QPointF center, Direction direction, bool pressed);

    // Draw icon functions
    void DrawSymbol(QPainter& p, QPointF center, Symbol symbol, float icon_size);
    void DrawArrow(QPainter& p, QPointF center, Direction direction, float size);

    // Draw primitive types
    template <size_t N>
    void DrawPolygon(QPainter& p, const std::array<QPointF, N>& polygon);
    void DrawCircle(QPainter& p, QPointF center, float size);
    void DrawRectangle(QPainter& p, QPointF center, float width, float height);
    void DrawRoundRectangle(QPainter& p, QPointF center, float width, float height, float round);
    void DrawText(QPainter& p, QPointF center, float text_size, const QString& text);
    void SetTextFont(QPainter& p, float text_size,
                     const QString& font_family = QStringLiteral("sans-serif"));

    using ButtonArray =
        std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::BUTTON_NS_END>;
    using StickArray =
        std::array<std::unique_ptr<Input::AnalogDevice>, Settings::NativeAnalog::NUM_STICKS_HID>;

    bool mapping_active{};
    int blink_counter{};
    QColor button_color{};
    ColorMapping colors{};
    std::array<QColor, 4> led_color{};
    ButtonArray buttons{};
    StickArray sticks{};
    std::size_t player_index{};
    std::size_t button_mapping_index{Settings::NativeButton::BUTTON_NS_END};
    std::size_t analog_mapping_index{Settings::NativeAnalog::NUM_STICKS_HID};
    std::array<AxisValue, Settings::NativeAnalog::NUM_STICKS_HID> axis_values{};
    std::array<bool, Settings::NativeButton::NumButtons> button_values{};
    Settings::ControllerType controller_type{Settings::ControllerType::ProController};
};