Project Mjölnir: Part 1
Co-authored-by: James Rowe <jroweboy@gmail.com> Co-authored-by: Its-Rei <kupfel@gmail.com>master
@ -0,0 +1,25 @@
|
|||||||
|
<RCC>
|
||||||
|
<qresource prefix="controller">
|
||||||
|
<file alias="dual_joycon">dual_joycon.png</file>
|
||||||
|
<file alias="dual_joycon_dark">dual_joycon_dark.png</file>
|
||||||
|
<file alias="dual_joycon_midnight">dual_joycon_midnight.png</file>
|
||||||
|
<file alias="handheld">handheld.png</file>
|
||||||
|
<file alias="handheld_dark">handheld_dark.png</file>
|
||||||
|
<file alias="handheld_midnight">handheld_midnight.png</file>
|
||||||
|
<file alias="pro_controller">pro_controller.png</file>
|
||||||
|
<file alias="pro_controller_dark">pro_controller_dark.png</file>
|
||||||
|
<file alias="pro_controller_midnight">pro_controller_midnight.png</file>
|
||||||
|
<file alias="single_joycon_left">single_joycon_left.png</file>
|
||||||
|
<file alias="single_joycon_left_dark">single_joycon_left_dark.png</file>
|
||||||
|
<file alias="single_joycon_left_midnight">single_joycon_left_midnight.png</file>
|
||||||
|
<file alias="single_joycon_right">single_joycon_right.png</file>
|
||||||
|
<file alias="single_joycon_right_dark">single_joycon_right_dark.png</file>
|
||||||
|
<file alias="single_joycon_right_midnight">single_joycon_right_midnight.png</file>
|
||||||
|
<file alias="single_joycon_left_vertical">single_joycon_left_vertical.png</file>
|
||||||
|
<file alias="single_joycon_left_vertical_dark">single_joycon_left_vertical_dark.png</file>
|
||||||
|
<file alias="single_joycon_left_vertical_midnight">single_joycon_left_vertical_midnight.png</file>
|
||||||
|
<file alias="single_joycon_right_vertical">single_joycon_right_vertical.png</file>
|
||||||
|
<file alias="single_joycon_right_vertical_dark">single_joycon_right_vertical_dark.png</file>
|
||||||
|
<file alias="single_joycon_right_vertical_midnight">single_joycon_right_vertical_midnight.png</file>
|
||||||
|
</qresource>
|
||||||
|
</RCC>
|
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 25 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 24 KiB |
After Width: | Height: | Size: 23 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 27 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 349 B |
After Width: | Height: | Size: 349 B |
After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 362 B |
After Width: | Height: | Size: 362 B |
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "input_common/settings.h"
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
namespace NativeButton {
|
||||||
|
const std::array<const char*, NumButtons> mapping = {{
|
||||||
|
"button_a", "button_b", "button_x", "button_y", "button_lstick",
|
||||||
|
"button_rstick", "button_l", "button_r", "button_zl", "button_zr",
|
||||||
|
"button_plus", "button_minus", "button_dleft", "button_dup", "button_dright",
|
||||||
|
"button_ddown", "button_sl", "button_sr", "button_home", "button_screenshot",
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace NativeAnalog {
|
||||||
|
const std::array<const char*, NumAnalogs> mapping = {{
|
||||||
|
"lstick",
|
||||||
|
"rstick",
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace NativeMouseButton {
|
||||||
|
const std::array<const char*, NumMouseButtons> mapping = {{
|
||||||
|
"left",
|
||||||
|
"right",
|
||||||
|
"middle",
|
||||||
|
"forward",
|
||||||
|
"back",
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
} // namespace Settings
|
@ -0,0 +1,335 @@
|
|||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <string>
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace Settings {
|
||||||
|
namespace NativeButton {
|
||||||
|
enum Values {
|
||||||
|
A,
|
||||||
|
B,
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
LStick,
|
||||||
|
RStick,
|
||||||
|
L,
|
||||||
|
R,
|
||||||
|
ZL,
|
||||||
|
ZR,
|
||||||
|
Plus,
|
||||||
|
Minus,
|
||||||
|
|
||||||
|
DLeft,
|
||||||
|
DUp,
|
||||||
|
DRight,
|
||||||
|
DDown,
|
||||||
|
|
||||||
|
SL,
|
||||||
|
SR,
|
||||||
|
|
||||||
|
Home,
|
||||||
|
Screenshot,
|
||||||
|
|
||||||
|
NumButtons,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int BUTTON_HID_BEGIN = A;
|
||||||
|
constexpr int BUTTON_NS_BEGIN = Home;
|
||||||
|
|
||||||
|
constexpr int BUTTON_HID_END = BUTTON_NS_BEGIN;
|
||||||
|
constexpr int BUTTON_NS_END = NumButtons;
|
||||||
|
|
||||||
|
constexpr int NUM_BUTTONS_HID = BUTTON_HID_END - BUTTON_HID_BEGIN;
|
||||||
|
constexpr int NUM_BUTTONS_NS = BUTTON_NS_END - BUTTON_NS_BEGIN;
|
||||||
|
|
||||||
|
extern const std::array<const char*, NumButtons> mapping;
|
||||||
|
|
||||||
|
} // namespace NativeButton
|
||||||
|
|
||||||
|
namespace NativeAnalog {
|
||||||
|
enum Values {
|
||||||
|
LStick,
|
||||||
|
RStick,
|
||||||
|
|
||||||
|
NumAnalogs,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int STICK_HID_BEGIN = LStick;
|
||||||
|
constexpr int STICK_HID_END = NumAnalogs;
|
||||||
|
constexpr int NUM_STICKS_HID = NumAnalogs;
|
||||||
|
|
||||||
|
extern const std::array<const char*, NumAnalogs> mapping;
|
||||||
|
} // namespace NativeAnalog
|
||||||
|
|
||||||
|
namespace NativeMouseButton {
|
||||||
|
enum Values {
|
||||||
|
Left,
|
||||||
|
Right,
|
||||||
|
Middle,
|
||||||
|
Forward,
|
||||||
|
Back,
|
||||||
|
|
||||||
|
NumMouseButtons,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int MOUSE_HID_BEGIN = Left;
|
||||||
|
constexpr int MOUSE_HID_END = NumMouseButtons;
|
||||||
|
constexpr int NUM_MOUSE_HID = NumMouseButtons;
|
||||||
|
|
||||||
|
extern const std::array<const char*, NumMouseButtons> mapping;
|
||||||
|
} // namespace NativeMouseButton
|
||||||
|
|
||||||
|
namespace NativeKeyboard {
|
||||||
|
enum Keys {
|
||||||
|
None,
|
||||||
|
Error,
|
||||||
|
|
||||||
|
A = 4,
|
||||||
|
B,
|
||||||
|
C,
|
||||||
|
D,
|
||||||
|
E,
|
||||||
|
F,
|
||||||
|
G,
|
||||||
|
H,
|
||||||
|
I,
|
||||||
|
J,
|
||||||
|
K,
|
||||||
|
L,
|
||||||
|
M,
|
||||||
|
N,
|
||||||
|
O,
|
||||||
|
P,
|
||||||
|
Q,
|
||||||
|
R,
|
||||||
|
S,
|
||||||
|
T,
|
||||||
|
U,
|
||||||
|
V,
|
||||||
|
W,
|
||||||
|
X,
|
||||||
|
Y,
|
||||||
|
Z,
|
||||||
|
N1,
|
||||||
|
N2,
|
||||||
|
N3,
|
||||||
|
N4,
|
||||||
|
N5,
|
||||||
|
N6,
|
||||||
|
N7,
|
||||||
|
N8,
|
||||||
|
N9,
|
||||||
|
N0,
|
||||||
|
Enter,
|
||||||
|
Escape,
|
||||||
|
Backspace,
|
||||||
|
Tab,
|
||||||
|
Space,
|
||||||
|
Minus,
|
||||||
|
Equal,
|
||||||
|
LeftBrace,
|
||||||
|
RightBrace,
|
||||||
|
Backslash,
|
||||||
|
Tilde,
|
||||||
|
Semicolon,
|
||||||
|
Apostrophe,
|
||||||
|
Grave,
|
||||||
|
Comma,
|
||||||
|
Dot,
|
||||||
|
Slash,
|
||||||
|
CapsLockKey,
|
||||||
|
|
||||||
|
F1,
|
||||||
|
F2,
|
||||||
|
F3,
|
||||||
|
F4,
|
||||||
|
F5,
|
||||||
|
F6,
|
||||||
|
F7,
|
||||||
|
F8,
|
||||||
|
F9,
|
||||||
|
F10,
|
||||||
|
F11,
|
||||||
|
F12,
|
||||||
|
|
||||||
|
SystemRequest,
|
||||||
|
ScrollLockKey,
|
||||||
|
Pause,
|
||||||
|
Insert,
|
||||||
|
Home,
|
||||||
|
PageUp,
|
||||||
|
Delete,
|
||||||
|
End,
|
||||||
|
PageDown,
|
||||||
|
Right,
|
||||||
|
Left,
|
||||||
|
Down,
|
||||||
|
Up,
|
||||||
|
|
||||||
|
NumLockKey,
|
||||||
|
KPSlash,
|
||||||
|
KPAsterisk,
|
||||||
|
KPMinus,
|
||||||
|
KPPlus,
|
||||||
|
KPEnter,
|
||||||
|
KP1,
|
||||||
|
KP2,
|
||||||
|
KP3,
|
||||||
|
KP4,
|
||||||
|
KP5,
|
||||||
|
KP6,
|
||||||
|
KP7,
|
||||||
|
KP8,
|
||||||
|
KP9,
|
||||||
|
KP0,
|
||||||
|
KPDot,
|
||||||
|
|
||||||
|
Key102,
|
||||||
|
Compose,
|
||||||
|
Power,
|
||||||
|
KPEqual,
|
||||||
|
|
||||||
|
F13,
|
||||||
|
F14,
|
||||||
|
F15,
|
||||||
|
F16,
|
||||||
|
F17,
|
||||||
|
F18,
|
||||||
|
F19,
|
||||||
|
F20,
|
||||||
|
F21,
|
||||||
|
F22,
|
||||||
|
F23,
|
||||||
|
F24,
|
||||||
|
|
||||||
|
Open,
|
||||||
|
Help,
|
||||||
|
Properties,
|
||||||
|
Front,
|
||||||
|
Stop,
|
||||||
|
Repeat,
|
||||||
|
Undo,
|
||||||
|
Cut,
|
||||||
|
Copy,
|
||||||
|
Paste,
|
||||||
|
Find,
|
||||||
|
Mute,
|
||||||
|
VolumeUp,
|
||||||
|
VolumeDown,
|
||||||
|
CapsLockActive,
|
||||||
|
NumLockActive,
|
||||||
|
ScrollLockActive,
|
||||||
|
KPComma,
|
||||||
|
|
||||||
|
KPLeftParenthesis,
|
||||||
|
KPRightParenthesis,
|
||||||
|
|
||||||
|
LeftControlKey = 0xE0,
|
||||||
|
LeftShiftKey,
|
||||||
|
LeftAltKey,
|
||||||
|
LeftMetaKey,
|
||||||
|
RightControlKey,
|
||||||
|
RightShiftKey,
|
||||||
|
RightAltKey,
|
||||||
|
RightMetaKey,
|
||||||
|
|
||||||
|
MediaPlayPause,
|
||||||
|
MediaStopCD,
|
||||||
|
MediaPrevious,
|
||||||
|
MediaNext,
|
||||||
|
MediaEject,
|
||||||
|
MediaVolumeUp,
|
||||||
|
MediaVolumeDown,
|
||||||
|
MediaMute,
|
||||||
|
MediaWebsite,
|
||||||
|
MediaBack,
|
||||||
|
MediaForward,
|
||||||
|
MediaStop,
|
||||||
|
MediaFind,
|
||||||
|
MediaScrollUp,
|
||||||
|
MediaScrollDown,
|
||||||
|
MediaEdit,
|
||||||
|
MediaSleep,
|
||||||
|
MediaCoffee,
|
||||||
|
MediaRefresh,
|
||||||
|
MediaCalculator,
|
||||||
|
|
||||||
|
NumKeyboardKeys,
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(NumKeyboardKeys == 0xFC, "Incorrect number of keyboard keys.");
|
||||||
|
|
||||||
|
enum Modifiers {
|
||||||
|
LeftControl,
|
||||||
|
LeftShift,
|
||||||
|
LeftAlt,
|
||||||
|
LeftMeta,
|
||||||
|
RightControl,
|
||||||
|
RightShift,
|
||||||
|
RightAlt,
|
||||||
|
RightMeta,
|
||||||
|
CapsLock,
|
||||||
|
ScrollLock,
|
||||||
|
NumLock,
|
||||||
|
|
||||||
|
NumKeyboardMods,
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int KEYBOARD_KEYS_HID_BEGIN = None;
|
||||||
|
constexpr int KEYBOARD_KEYS_HID_END = NumKeyboardKeys;
|
||||||
|
constexpr int NUM_KEYBOARD_KEYS_HID = NumKeyboardKeys;
|
||||||
|
|
||||||
|
constexpr int KEYBOARD_MODS_HID_BEGIN = LeftControl;
|
||||||
|
constexpr int KEYBOARD_MODS_HID_END = NumKeyboardMods;
|
||||||
|
constexpr int NUM_KEYBOARD_MODS_HID = NumKeyboardMods;
|
||||||
|
|
||||||
|
} // namespace NativeKeyboard
|
||||||
|
|
||||||
|
using ButtonsRaw = std::array<std::string, NativeButton::NumButtons>;
|
||||||
|
using AnalogsRaw = std::array<std::string, NativeAnalog::NumAnalogs>;
|
||||||
|
using MouseButtonsRaw = std::array<std::string, NativeMouseButton::NumMouseButtons>;
|
||||||
|
using KeyboardKeysRaw = std::array<std::string, NativeKeyboard::NumKeyboardKeys>;
|
||||||
|
using KeyboardModsRaw = std::array<std::string, NativeKeyboard::NumKeyboardMods>;
|
||||||
|
|
||||||
|
constexpr u32 JOYCON_BODY_NEON_RED = 0xFF3C28;
|
||||||
|
constexpr u32 JOYCON_BUTTONS_NEON_RED = 0x1E0A0A;
|
||||||
|
constexpr u32 JOYCON_BODY_NEON_BLUE = 0x0AB9E6;
|
||||||
|
constexpr u32 JOYCON_BUTTONS_NEON_BLUE = 0x001E1E;
|
||||||
|
|
||||||
|
enum class ControllerType {
|
||||||
|
ProController,
|
||||||
|
DualJoyconDetached,
|
||||||
|
LeftJoycon,
|
||||||
|
RightJoycon,
|
||||||
|
Handheld,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlayerInput {
|
||||||
|
bool connected;
|
||||||
|
ControllerType controller_type;
|
||||||
|
ButtonsRaw buttons;
|
||||||
|
AnalogsRaw analogs;
|
||||||
|
std::string lstick_mod;
|
||||||
|
std::string rstick_mod;
|
||||||
|
|
||||||
|
u32 body_color_left;
|
||||||
|
u32 body_color_right;
|
||||||
|
u32 button_color_left;
|
||||||
|
u32 button_color_right;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TouchscreenInput {
|
||||||
|
bool enabled;
|
||||||
|
std::string device;
|
||||||
|
|
||||||
|
u32 finger;
|
||||||
|
u32 diameter_x;
|
||||||
|
u32 diameter_y;
|
||||||
|
u32 rotation_angle;
|
||||||
|
};
|
||||||
|
} // namespace Settings
|
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "ui_configure_debug_controller.h"
|
||||||
|
#include "yuzu/configuration/configure_debug_controller.h"
|
||||||
|
|
||||||
|
ConfigureDebugController::ConfigureDebugController(QWidget* parent)
|
||||||
|
: QDialog(parent), ui(std::make_unique<Ui::ConfigureDebugController>()) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
debug_controller = new ConfigureInputPlayer(this, 9, nullptr, true);
|
||||||
|
ui->controllerLayout->addWidget(debug_controller);
|
||||||
|
|
||||||
|
connect(ui->clear_all_button, &QPushButton::clicked, this,
|
||||||
|
[this] { debug_controller->ClearAll(); });
|
||||||
|
connect(ui->restore_defaults_button, &QPushButton::clicked, this,
|
||||||
|
[this] { debug_controller->RestoreDefaults(); });
|
||||||
|
|
||||||
|
RetranslateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigureDebugController::~ConfigureDebugController() = default;
|
||||||
|
|
||||||
|
void ConfigureDebugController::ApplyConfiguration() {
|
||||||
|
debug_controller->ApplyConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureDebugController::changeEvent(QEvent* event) {
|
||||||
|
if (event->type() == QEvent::LanguageChange) {
|
||||||
|
RetranslateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
QDialog::changeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureDebugController::RetranslateUI() {
|
||||||
|
ui->retranslateUi(this);
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <QDialog>
|
||||||
|
#include "yuzu/configuration/configure_input_player.h"
|
||||||
|
|
||||||
|
class QPushButton;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ConfigureDebugController;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureDebugController : public QDialog {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ConfigureDebugController(QWidget* parent);
|
||||||
|
~ConfigureDebugController() override;
|
||||||
|
|
||||||
|
void ApplyConfiguration();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void changeEvent(QEvent* event) override;
|
||||||
|
void RetranslateUI();
|
||||||
|
|
||||||
|
ConfigureInputPlayer* debug_controller;
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::ConfigureDebugController> ui;
|
||||||
|
};
|
@ -0,0 +1,97 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>ConfigureDebugController</class>
|
||||||
|
<widget class="QDialog" name="ConfigureDebugController">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>780</width>
|
||||||
|
<height>500</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Configure Debug Controller</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
|
<property name="spacing">
|
||||||
|
<number>2</number>
|
||||||
|
</property>
|
||||||
|
<property name="leftMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="topMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="rightMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<property name="bottomMargin">
|
||||||
|
<number>9</number>
|
||||||
|
</property>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="controllerLayout"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="clear_all_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Clear</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="restore_defaults_button">
|
||||||
|
<property name="text">
|
||||||
|
<string>Defaults</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>ConfigureDebugController</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>140</x>
|
||||||
|
<y>318</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>140</x>
|
||||||
|
<y>169</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>ConfigureDebugController</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>140</x>
|
||||||
|
<y>318</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>140</x>
|
||||||
|
<y>169</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
@ -0,0 +1,169 @@
|
|||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <QColorDialog>
|
||||||
|
#include "core/core.h"
|
||||||
|
#include "core/settings.h"
|
||||||
|
#include "ui_configure_input_advanced.h"
|
||||||
|
#include "yuzu/configuration/configure_input_advanced.h"
|
||||||
|
|
||||||
|
ConfigureInputAdvanced::ConfigureInputAdvanced(QWidget* parent)
|
||||||
|
: QWidget(parent), ui(new Ui::ConfigureInputAdvanced) {
|
||||||
|
ui->setupUi(this);
|
||||||
|
|
||||||
|
controllers_color_buttons = {{
|
||||||
|
{
|
||||||
|
ui->player1_left_body_button,
|
||||||
|
ui->player1_left_buttons_button,
|
||||||
|
ui->player1_right_body_button,
|
||||||
|
ui->player1_right_buttons_button,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ui->player2_left_body_button,
|
||||||
|
ui->player2_left_buttons_button,
|
||||||
|
ui->player2_right_body_button,
|
||||||
|
ui->player2_right_buttons_button,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ui->player3_left_body_button,
|
||||||
|
ui->player3_left_buttons_button,
|
||||||
|
ui->player3_right_body_button,
|
||||||
|
ui->player3_right_buttons_button,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ui->player4_left_body_button,
|
||||||
|
ui->player4_left_buttons_button,
|
||||||
|
ui->player4_right_body_button,
|
||||||
|
ui->player4_right_buttons_button,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ui->player5_left_body_button,
|
||||||
|
ui->player5_left_buttons_button,
|
||||||
|
ui->player5_right_body_button,
|
||||||
|
ui->player5_right_buttons_button,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ui->player6_left_body_button,
|
||||||
|
ui->player6_left_buttons_button,
|
||||||
|
ui->player6_right_body_button,
|
||||||
|
ui->player6_right_buttons_button,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ui->player7_left_body_button,
|
||||||
|
ui->player7_left_buttons_button,
|
||||||
|
ui->player7_right_body_button,
|
||||||
|
ui->player7_right_buttons_button,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ui->player8_left_body_button,
|
||||||
|
ui->player8_left_buttons_button,
|
||||||
|
ui->player8_right_body_button,
|
||||||
|
ui->player8_right_buttons_button,
|
||||||
|
},
|
||||||
|
}};
|
||||||
|
|
||||||
|
for (std::size_t player_idx = 0; player_idx < controllers_color_buttons.size(); ++player_idx) {
|
||||||
|
auto& color_buttons = controllers_color_buttons[player_idx];
|
||||||
|
for (std::size_t button_idx = 0; button_idx < color_buttons.size(); ++button_idx) {
|
||||||
|
connect(color_buttons[button_idx], &QPushButton::clicked, this,
|
||||||
|
[this, player_idx, button_idx] {
|
||||||
|
OnControllerButtonClick(static_cast<int>(player_idx),
|
||||||
|
static_cast<int>(button_idx));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connect(ui->mouse_enabled, &QCheckBox::stateChanged, this,
|
||||||
|
&ConfigureInputAdvanced::UpdateUIEnabled);
|
||||||
|
connect(ui->debug_enabled, &QCheckBox::stateChanged, this,
|
||||||
|
&ConfigureInputAdvanced::UpdateUIEnabled);
|
||||||
|
connect(ui->touchscreen_enabled, &QCheckBox::stateChanged, this,
|
||||||
|
&ConfigureInputAdvanced::UpdateUIEnabled);
|
||||||
|
|
||||||
|
connect(ui->debug_configure, &QPushButton::clicked, this,
|
||||||
|
[this] { CallDebugControllerDialog(); });
|
||||||
|
connect(ui->mouse_advanced, &QPushButton::clicked, this, [this] { CallMouseConfigDialog(); });
|
||||||
|
connect(ui->touchscreen_advanced, &QPushButton::clicked, this,
|
||||||
|
[this] { CallTouchscreenConfigDialog(); });
|
||||||
|
|
||||||
|
LoadConfiguration();
|
||||||
|
}
|
||||||
|
|
||||||
|
ConfigureInputAdvanced::~ConfigureInputAdvanced() = default;
|
||||||
|
|
||||||
|
void ConfigureInputAdvanced::OnControllerButtonClick(int player_idx, int button_idx) {
|
||||||
|
const QColor new_bg_color = QColorDialog::getColor(controllers_colors[player_idx][button_idx]);
|
||||||
|
if (!new_bg_color.isValid()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
controllers_colors[player_idx][button_idx] = new_bg_color;
|
||||||
|
controllers_color_buttons[player_idx][button_idx]->setStyleSheet(
|
||||||
|
QStringLiteral("background-color: %1; min-width: 55px;")
|
||||||
|
.arg(controllers_colors[player_idx][button_idx].name()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInputAdvanced::ApplyConfiguration() {
|
||||||
|
for (std::size_t player_idx = 0; player_idx < controllers_color_buttons.size(); ++player_idx) {
|
||||||
|
auto& player = Settings::values.players[player_idx];
|
||||||
|
std::array<u32, 4> colors{};
|
||||||
|
std::transform(controllers_colors[player_idx].begin(), controllers_colors[player_idx].end(),
|
||||||
|
colors.begin(), [](QColor color) { return color.rgb(); });
|
||||||
|
|
||||||
|
player.body_color_left = colors[0];
|
||||||
|
player.button_color_left = colors[1];
|
||||||
|
player.body_color_right = colors[2];
|
||||||
|
player.button_color_right = colors[3];
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::values.debug_pad_enabled = ui->debug_enabled->isChecked();
|
||||||
|
Settings::values.mouse_enabled = ui->mouse_enabled->isChecked();
|
||||||
|
Settings::values.keyboard_enabled = ui->keyboard_enabled->isChecked();
|
||||||
|
Settings::values.touchscreen.enabled = ui->touchscreen_enabled->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInputAdvanced::LoadConfiguration() {
|
||||||
|
for (std::size_t player_idx = 0; player_idx < controllers_color_buttons.size(); ++player_idx) {
|
||||||
|
auto& player = Settings::values.players[player_idx];
|
||||||
|
std::array<u32, 4> colors = {
|
||||||
|
player.body_color_left,
|
||||||
|
player.button_color_left,
|
||||||
|
player.body_color_right,
|
||||||
|
player.button_color_right,
|
||||||
|
};
|
||||||
|
|
||||||
|
std::transform(colors.begin(), colors.end(), controllers_colors[player_idx].begin(),
|
||||||
|
[](u32 rgb) { return QColor::fromRgb(rgb); });
|
||||||
|
|
||||||
|
for (std::size_t button_idx = 0; button_idx < colors.size(); ++button_idx) {
|
||||||
|
controllers_color_buttons[player_idx][button_idx]->setStyleSheet(
|
||||||
|
QStringLiteral("background-color: %1; min-width: 55px;")
|
||||||
|
.arg(controllers_colors[player_idx][button_idx].name()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->debug_enabled->setChecked(Settings::values.debug_pad_enabled);
|
||||||
|
ui->mouse_enabled->setChecked(Settings::values.mouse_enabled);
|
||||||
|
ui->keyboard_enabled->setChecked(Settings::values.keyboard_enabled);
|
||||||
|
ui->touchscreen_enabled->setChecked(Settings::values.touchscreen.enabled);
|
||||||
|
|
||||||
|
UpdateUIEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInputAdvanced::changeEvent(QEvent* event) {
|
||||||
|
if (event->type() == QEvent::LanguageChange) {
|
||||||
|
RetranslateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget::changeEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInputAdvanced::RetranslateUI() {
|
||||||
|
ui->retranslateUi(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigureInputAdvanced::UpdateUIEnabled() {
|
||||||
|
ui->mouse_advanced->setEnabled(ui->mouse_enabled->isChecked());
|
||||||
|
ui->debug_configure->setEnabled(ui->debug_enabled->isChecked());
|
||||||
|
ui->touchscreen_advanced->setEnabled(ui->touchscreen_enabled->isChecked());
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright 2020 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <QWidget>
|
||||||
|
|
||||||
|
class QColor;
|
||||||
|
class QPushButton;
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class ConfigureInputAdvanced;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigureInputAdvanced : public QWidget {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit ConfigureInputAdvanced(QWidget* parent = nullptr);
|
||||||
|
~ConfigureInputAdvanced() override;
|
||||||
|
|
||||||
|
void ApplyConfiguration();
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void CallDebugControllerDialog();
|
||||||
|
void CallMouseConfigDialog();
|
||||||
|
void CallTouchscreenConfigDialog();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void changeEvent(QEvent* event) override;
|
||||||
|
void RetranslateUI();
|
||||||
|
void UpdateUIEnabled();
|
||||||
|
|
||||||
|
void OnControllerButtonClick(int player_idx, int button_idx);
|
||||||
|
|
||||||
|
void LoadConfiguration();
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::ConfigureInputAdvanced> ui;
|
||||||
|
|
||||||
|
std::array<std::array<QColor, 4>, 8> controllers_colors;
|
||||||
|
std::array<std::array<QPushButton*, 4>, 8> controllers_color_buttons;
|
||||||
|
};
|
@ -1,152 +0,0 @@
|
|||||||
// Copyright 2016 Citra Emulator Project
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include <array>
|
|
||||||
#include <tuple>
|
|
||||||
|
|
||||||
#include "ui_configure_input_simple.h"
|
|
||||||
#include "yuzu/configuration/configure_input.h"
|
|
||||||
#include "yuzu/configuration/configure_input_player.h"
|
|
||||||
#include "yuzu/configuration/configure_input_simple.h"
|
|
||||||
#include "yuzu/uisettings.h"
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
template <typename Dialog, typename... Args>
|
|
||||||
void CallConfigureDialog(ConfigureInputSimple* caller, Args&&... args) {
|
|
||||||
caller->ApplyConfiguration();
|
|
||||||
Dialog dialog(caller, std::forward<Args>(args)...);
|
|
||||||
|
|
||||||
const auto res = dialog.exec();
|
|
||||||
if (res == QDialog::Accepted) {
|
|
||||||
dialog.ApplyConfiguration();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// OnProfileSelect functions should (when applicable):
|
|
||||||
// - Set controller types
|
|
||||||
// - Set controller enabled
|
|
||||||
// - Set docked mode
|
|
||||||
// - Set advanced controller config/enabled (i.e. debug, kbd, mouse, touch)
|
|
||||||
//
|
|
||||||
// OnProfileSelect function should NOT however:
|
|
||||||
// - Reset any button mappings
|
|
||||||
// - Open any dialogs
|
|
||||||
// - Block in any way
|
|
||||||
|
|
||||||
constexpr std::size_t PLAYER_0_INDEX = 0;
|
|
||||||
constexpr std::size_t HANDHELD_INDEX = 8;
|
|
||||||
|
|
||||||
void HandheldOnProfileSelect() {
|
|
||||||
Settings::values.players[HANDHELD_INDEX].connected = true;
|
|
||||||
Settings::values.players[HANDHELD_INDEX].type = Settings::ControllerType::DualJoycon;
|
|
||||||
|
|
||||||
for (std::size_t player = 0; player < HANDHELD_INDEX; ++player) {
|
|
||||||
Settings::values.players[player].connected = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings::values.use_docked_mode = false;
|
|
||||||
Settings::values.keyboard_enabled = false;
|
|
||||||
Settings::values.mouse_enabled = false;
|
|
||||||
Settings::values.debug_pad_enabled = false;
|
|
||||||
Settings::values.touchscreen.enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DualJoyconsDockedOnProfileSelect() {
|
|
||||||
Settings::values.players[PLAYER_0_INDEX].connected = true;
|
|
||||||
Settings::values.players[PLAYER_0_INDEX].type = Settings::ControllerType::DualJoycon;
|
|
||||||
|
|
||||||
for (std::size_t player = 1; player <= HANDHELD_INDEX; ++player) {
|
|
||||||
Settings::values.players[player].connected = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Settings::values.use_docked_mode = true;
|
|
||||||
Settings::values.keyboard_enabled = false;
|
|
||||||
Settings::values.mouse_enabled = false;
|
|
||||||
Settings::values.debug_pad_enabled = false;
|
|
||||||
Settings::values.touchscreen.enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name, OnProfileSelect (called when selected in drop down), OnConfigure (called when configure
|
|
||||||
// is clicked)
|
|
||||||
using InputProfile = std::tuple<const char*, void (*)(), void (*)(ConfigureInputSimple*)>;
|
|
||||||
|
|
||||||
constexpr std::array<InputProfile, 3> INPUT_PROFILES{{
|
|
||||||
{QT_TR_NOOP("Single Player - Handheld - Undocked"), HandheldOnProfileSelect,
|
|
||||||
[](ConfigureInputSimple* caller) {
|
|
||||||
CallConfigureDialog<ConfigureInputPlayer>(caller, HANDHELD_INDEX, false);
|
|
||||||
}},
|
|
||||||
{QT_TR_NOOP("Single Player - Dual Joycons - Docked"), DualJoyconsDockedOnProfileSelect,
|
|
||||||
[](ConfigureInputSimple* caller) {
|
|
||||||
CallConfigureDialog<ConfigureInputPlayer>(caller, PLAYER_0_INDEX, false);
|
|
||||||
}},
|
|
||||||
{QT_TR_NOOP("Custom"), [] {}, CallConfigureDialog<ConfigureInput>},
|
|
||||||
}};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
void ApplyInputProfileConfiguration(int profile_index) {
|
|
||||||
std::get<1>(
|
|
||||||
INPUT_PROFILES.at(std::min(profile_index, static_cast<int>(INPUT_PROFILES.size() - 1))))();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigureInputSimple::ConfigureInputSimple(QWidget* parent)
|
|
||||||
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInputSimple>()) {
|
|
||||||
ui->setupUi(this);
|
|
||||||
|
|
||||||
for (const auto& profile : INPUT_PROFILES) {
|
|
||||||
const QString label = tr(std::get<0>(profile));
|
|
||||||
ui->profile_combobox->addItem(label, label);
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(ui->profile_combobox, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
|
|
||||||
&ConfigureInputSimple::OnSelectProfile);
|
|
||||||
connect(ui->profile_configure, &QPushButton::clicked, this, &ConfigureInputSimple::OnConfigure);
|
|
||||||
|
|
||||||
LoadConfiguration();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConfigureInputSimple::~ConfigureInputSimple() = default;
|
|
||||||
|
|
||||||
void ConfigureInputSimple::ApplyConfiguration() {
|
|
||||||
auto index = ui->profile_combobox->currentIndex();
|
|
||||||
// Make the stored index for "Custom" very large so that if new profiles are added it
|
|
||||||
// doesn't change.
|
|
||||||
if (index >= static_cast<int>(INPUT_PROFILES.size() - 1)) {
|
|
||||||
index = std::numeric_limits<int>::max();
|
|
||||||
}
|
|
||||||
|
|
||||||
UISettings::values.profile_index = index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureInputSimple::changeEvent(QEvent* event) {
|
|
||||||
if (event->type() == QEvent::LanguageChange) {
|
|
||||||
RetranslateUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
QWidget::changeEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureInputSimple::RetranslateUI() {
|
|
||||||
ui->retranslateUi(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureInputSimple::LoadConfiguration() {
|
|
||||||
const auto index = UISettings::values.profile_index;
|
|
||||||
if (index >= static_cast<int>(INPUT_PROFILES.size()) || index < 0) {
|
|
||||||
ui->profile_combobox->setCurrentIndex(static_cast<int>(INPUT_PROFILES.size() - 1));
|
|
||||||
} else {
|
|
||||||
ui->profile_combobox->setCurrentIndex(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureInputSimple::OnSelectProfile(int index) {
|
|
||||||
const auto old_docked = Settings::values.use_docked_mode;
|
|
||||||
ApplyInputProfileConfiguration(index);
|
|
||||||
OnDockedModeChanged(old_docked, Settings::values.use_docked_mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ConfigureInputSimple::OnConfigure() {
|
|
||||||
std::get<2>(INPUT_PROFILES.at(ui->profile_combobox->currentIndex()))(this);
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>ConfigureInputSimple</class>
|
|
||||||
<widget class="QWidget" name="ConfigureInputSimple">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>473</width>
|
|
||||||
<height>685</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="windowTitle">
|
|
||||||
<string>ConfigureInputSimple</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
|
||||||
<item>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<item>
|
|
||||||
<widget class="QGroupBox" name="gridGroupBox">
|
|
||||||
<property name="title">
|
|
||||||
<string>Profile</string>
|
|
||||||
</property>
|
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
|
||||||
<item row="1" column="2">
|
|
||||||
<widget class="QPushButton" name="profile_configure">
|
|
||||||
<property name="text">
|
|
||||||
<string>Configure</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0">
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="3">
|
|
||||||
<spacer name="horizontalSpacer_2">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QComboBox" name="profile_combobox">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>250</width>
|
|
||||||
<height>0</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="1" colspan="2">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Choose a controller configuration:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<spacer name="verticalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Vertical</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>20</width>
|
|
||||||
<height>40</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|