chore: make yuzu REUSE compliant
[REUSE] is a specification that aims at making file copyright
information consistent, so that it can be both human and machine
readable. It basically requires that all files have a header containing
copyright and licensing information. When this isn't possible, like
when dealing with binary assets, generated files or embedded third-party
dependencies, it is permitted to insert copyright information in the
`.reuse/dep5` file.
Oh, and it also requires that all the licenses used in the project are
present in the `LICENSES` folder, that's why the diff is so huge.
This can be done automatically with `reuse download --all`.
The `reuse` tool also contains a handy subcommand that analyzes the
project and tells whether or not the project is (still) compliant,
`reuse lint`.
Following REUSE has a few advantages over the current approach:
- Copyright information is easy to access for users / downstream
- Files like `dist/license.md` do not need to exist anymore, as
`.reuse/dep5` is used instead
- `reuse lint` makes it easy to ensure that copyright information of
files like binary assets / images is always accurate and up to date
To add copyright information of files that didn't have it I looked up
who committed what and when, for each file. As yuzu contributors do not
have to sign a CLA or similar I couldn't assume that copyright ownership
was of the "yuzu Emulator Project", so I used the name and/or email of
the commit author instead.
[REUSE]: https://reuse.software
Follow-up to 01cf05bc75b1e47beb08937439f3ed9339e7b254
2022-05-15 00:06:02 +00:00
|
|
|
// SPDX-FileCopyrightText: 2015 Citra Emulator Project
|
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2021-01-22 00:51:24 +00:00
|
|
|
|
|
|
|
#include <QAction>
|
|
|
|
#include <QLayout>
|
|
|
|
#include <QString>
|
2021-04-14 23:07:40 +00:00
|
|
|
#include "common/settings.h"
|
2021-10-31 01:16:10 +00:00
|
|
|
#include "core/hid/emulated_controller.h"
|
2021-11-05 01:05:58 +00:00
|
|
|
#include "core/hid/hid_core.h"
|
2021-10-31 01:16:10 +00:00
|
|
|
#include "input_common/drivers/tas_input.h"
|
|
|
|
#include "input_common/main.h"
|
2021-01-22 00:51:24 +00:00
|
|
|
#include "yuzu/configuration/configure_input_player_widget.h"
|
|
|
|
#include "yuzu/debugger/controller.h"
|
|
|
|
|
2021-11-05 01:05:58 +00:00
|
|
|
ControllerDialog::ControllerDialog(Core::HID::HIDCore& hid_core_,
|
2021-10-31 01:16:10 +00:00
|
|
|
std::shared_ptr<InputCommon::InputSubsystem> input_subsystem_,
|
|
|
|
QWidget* parent)
|
2021-11-05 01:05:58 +00:00
|
|
|
: QWidget(parent, Qt::Dialog), hid_core{hid_core_}, input_subsystem{input_subsystem_} {
|
2021-01-22 00:51:24 +00:00
|
|
|
setObjectName(QStringLiteral("Controller"));
|
|
|
|
setWindowTitle(tr("Controller P1"));
|
|
|
|
resize(500, 350);
|
|
|
|
setMinimumSize(500, 350);
|
2023-01-25 06:11:20 +00:00
|
|
|
// Enable the maximize button
|
|
|
|
setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint);
|
2021-01-22 00:51:24 +00:00
|
|
|
|
2021-02-04 14:54:27 +00:00
|
|
|
widget = new PlayerControlPreview(this);
|
2021-10-31 01:16:10 +00:00
|
|
|
refreshConfiguration();
|
2021-01-22 00:51:24 +00:00
|
|
|
QLayout* layout = new QVBoxLayout(this);
|
|
|
|
layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
layout->addWidget(widget);
|
|
|
|
setLayout(layout);
|
|
|
|
|
|
|
|
// Configure focus so that widget is focusable and the dialog automatically forwards focus to
|
|
|
|
// it.
|
|
|
|
setFocusProxy(widget);
|
|
|
|
widget->setFocusPolicy(Qt::StrongFocus);
|
|
|
|
widget->setFocus();
|
|
|
|
}
|
|
|
|
|
2021-10-31 01:16:10 +00:00
|
|
|
void ControllerDialog::refreshConfiguration() {
|
|
|
|
UnloadController();
|
2021-11-05 01:05:58 +00:00
|
|
|
auto* player_1 = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1);
|
|
|
|
auto* handheld = hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
2021-10-31 01:16:10 +00:00
|
|
|
// Display the correct controller
|
|
|
|
controller = handheld->IsConnected() ? handheld : player_1;
|
|
|
|
|
|
|
|
Core::HID::ControllerUpdateCallback engine_callback{
|
|
|
|
.on_change = [this](Core::HID::ControllerTriggerType type) { ControllerUpdate(type); },
|
|
|
|
.is_npad_service = true,
|
|
|
|
};
|
|
|
|
callback_key = controller->SetCallback(engine_callback);
|
|
|
|
widget->SetController(controller);
|
|
|
|
is_controller_set = true;
|
|
|
|
}
|
|
|
|
|
2021-01-22 00:51:24 +00:00
|
|
|
QAction* ControllerDialog::toggleViewAction() {
|
|
|
|
if (toggle_view_action == nullptr) {
|
2021-02-14 20:57:47 +00:00
|
|
|
toggle_view_action = new QAction(tr("&Controller P1"), this);
|
2021-01-22 00:51:24 +00:00
|
|
|
toggle_view_action->setCheckable(true);
|
|
|
|
toggle_view_action->setChecked(isVisible());
|
|
|
|
connect(toggle_view_action, &QAction::toggled, this, &ControllerDialog::setVisible);
|
|
|
|
}
|
|
|
|
|
|
|
|
return toggle_view_action;
|
|
|
|
}
|
|
|
|
|
2021-10-16 00:07:47 +00:00
|
|
|
void ControllerDialog::UnloadController() {
|
|
|
|
widget->UnloadController();
|
2021-10-31 01:16:10 +00:00
|
|
|
if (is_controller_set) {
|
|
|
|
controller->DeleteCallback(callback_key);
|
|
|
|
is_controller_set = false;
|
|
|
|
}
|
2021-10-16 00:07:47 +00:00
|
|
|
}
|
|
|
|
|
2021-01-22 00:51:24 +00:00
|
|
|
void ControllerDialog::showEvent(QShowEvent* ev) {
|
|
|
|
if (toggle_view_action) {
|
|
|
|
toggle_view_action->setChecked(isVisible());
|
|
|
|
}
|
|
|
|
QWidget::showEvent(ev);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ControllerDialog::hideEvent(QHideEvent* ev) {
|
|
|
|
if (toggle_view_action) {
|
|
|
|
toggle_view_action->setChecked(isVisible());
|
|
|
|
}
|
|
|
|
QWidget::hideEvent(ev);
|
|
|
|
}
|
2021-10-31 01:16:10 +00:00
|
|
|
|
|
|
|
void ControllerDialog::ControllerUpdate(Core::HID::ControllerTriggerType type) {
|
|
|
|
// TODO(german77): Remove TAS from here
|
|
|
|
switch (type) {
|
|
|
|
case Core::HID::ControllerTriggerType::Button:
|
|
|
|
case Core::HID::ControllerTriggerType::Stick: {
|
|
|
|
const auto buttons_values = controller->GetButtonsValues();
|
2023-01-01 21:39:18 +00:00
|
|
|
const auto stick_values = controller->GetSticks();
|
2021-10-31 01:16:10 +00:00
|
|
|
u64 buttons = 0;
|
|
|
|
std::size_t index = 0;
|
|
|
|
for (const auto& button : buttons_values) {
|
|
|
|
buttons |= button.value ? 1LLU << index : 0;
|
|
|
|
index++;
|
|
|
|
}
|
|
|
|
const InputCommon::TasInput::TasAnalog left_axis = {
|
2023-01-01 21:39:18 +00:00
|
|
|
.x = stick_values.left.x / 32767.f,
|
|
|
|
.y = stick_values.left.y / 32767.f,
|
2021-10-31 01:16:10 +00:00
|
|
|
};
|
|
|
|
const InputCommon::TasInput::TasAnalog right_axis = {
|
2023-01-01 21:39:18 +00:00
|
|
|
.x = stick_values.right.x / 32767.f,
|
|
|
|
.y = stick_values.right.y / 32767.f,
|
2021-10-31 01:16:10 +00:00
|
|
|
};
|
|
|
|
input_subsystem->GetTas()->RecordInput(buttons, left_axis, right_axis);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|