diff options
-rw-r--r-- | CMakeLists.txt | 6 | ||||
-rw-r--r-- | CMakeModules/CopyYuzuQt5Deps.cmake | 7 | ||||
-rw-r--r-- | src/yuzu/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/yuzu/bootmanager.cpp | 71 | ||||
-rw-r--r-- | src/yuzu/bootmanager.h | 12 | ||||
-rw-r--r-- | src/yuzu/configuration/config.cpp | 12 | ||||
-rw-r--r-- | src/yuzu/configuration/config.h | 2 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_camera.cpp | 126 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_camera.h | 52 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_camera.ui | 170 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_input.cpp | 5 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_input_advanced.cpp | 3 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_input_advanced.h | 1 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_input_advanced.ui | 14 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 9 |
15 files changed, 491 insertions, 4 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3f7dcc924..40ca8b149 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -196,7 +196,7 @@ if(ENABLE_QT) # Check for system Qt on Linux, fallback to bundled Qt if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if (NOT YUZU_USE_BUNDLED_QT) - find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets DBus) + find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets DBus Multimedia) endif() if (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT) # Check for dependencies, then enable bundled Qt download @@ -300,9 +300,9 @@ if(ENABLE_QT) set(YUZU_QT_NO_CMAKE_SYSTEM_PATH "NO_CMAKE_SYSTEM_PATH") endif() if ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") AND YUZU_USE_BUNDLED_QT) - find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent DBus ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) + find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent Multimedia DBus ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) else() - find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) + find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent Multimedia ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) endif() if (YUZU_USE_QT_WEB_ENGINE) find_package(Qt5 REQUIRED COMPONENTS WebEngineCore WebEngineWidgets) diff --git a/CMakeModules/CopyYuzuQt5Deps.cmake b/CMakeModules/CopyYuzuQt5Deps.cmake index 0c27d51a6..4702a504c 100644 --- a/CMakeModules/CopyYuzuQt5Deps.cmake +++ b/CMakeModules/CopyYuzuQt5Deps.cmake @@ -10,11 +10,13 @@ function(copy_yuzu_Qt5_deps target_dir) set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/") set(Qt5_PLATFORMTHEMES_DIR "${Qt5_DIR}/../../../plugins/platformthemes/") set(Qt5_PLATFORMINPUTCONTEXTS_DIR "${Qt5_DIR}/../../../plugins/platforminputcontexts/") + set(Qt5_MEDIASERVICE_DIR "${Qt5_DIR}/../../../plugins/mediaservice/") set(Qt5_XCBGLINTEGRATIONS_DIR "${Qt5_DIR}/../../../plugins/xcbglintegrations/") set(Qt5_STYLES_DIR "${Qt5_DIR}/../../../plugins/styles/") set(Qt5_IMAGEFORMATS_DIR "${Qt5_DIR}/../../../plugins/imageformats/") set(Qt5_RESOURCES_DIR "${Qt5_DIR}/../../../resources/") set(PLATFORMS ${DLL_DEST}plugins/platforms/) + set(MEDIASERVICE ${DLL_DEST}mediaservice/) set(STYLES ${DLL_DEST}plugins/styles/) set(IMAGEFORMATS ${DLL_DEST}plugins/imageformats/) if (MSVC) @@ -22,6 +24,7 @@ function(copy_yuzu_Qt5_deps target_dir) Qt5Core$<$<CONFIG:Debug>:d>.* Qt5Gui$<$<CONFIG:Debug>:d>.* Qt5Widgets$<$<CONFIG:Debug>:d>.* + Qt5Multimedia$<$<CONFIG:Debug>:d>.* ) if (YUZU_USE_QT_WEB_ENGINE) @@ -53,6 +56,10 @@ function(copy_yuzu_Qt5_deps target_dir) qjpeg$<$<CONFIG:Debug>:d>.* qgif$<$<CONFIG:Debug>:d>.* ) + windows_copy_files(yuzu ${Qt5_MEDIASERVICE_DIR} ${MEDIASERVICE} + dsengine$<$<CONFIG:Debug>:d>.* + wmfengine$<$<CONFIG:Debug>:d>.* + ) else() set(Qt5_DLLS "${Qt5_DLL_DIR}libQt5Core.so.5" diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 242867a4f..a11a3b908 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -43,6 +43,9 @@ add_executable(yuzu configuration/configure_audio.cpp configuration/configure_audio.h configuration/configure_audio.ui + configuration/configure_camera.cpp + configuration/configure_camera.h + configuration/configure_camera.ui configuration/configure_cpu.cpp configuration/configure_cpu.h configuration/configure_cpu.ui @@ -254,7 +257,7 @@ endif() create_target_directory_groups(yuzu) target_link_libraries(yuzu PRIVATE common core input_common video_core) -target_link_libraries(yuzu PRIVATE Boost::boost glad Qt::Widgets) +target_link_libraries(yuzu PRIVATE Boost::boost glad Qt::Widgets Qt::Multimedia) target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include) diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 01acda22b..774085809 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -5,6 +5,8 @@ #include <glad/glad.h> #include <QApplication> +#include <QCameraImageCapture> +#include <QCameraInfo> #include <QHBoxLayout> #include <QMessageBox> #include <QPainter> @@ -31,6 +33,7 @@ #include "core/core.h" #include "core/cpu_manager.h" #include "core/frontend/framebuffer_layout.h" +#include "input_common/drivers/camera.h" #include "input_common/drivers/keyboard.h" #include "input_common/drivers/mouse.h" #include "input_common/drivers/tas_input.h" @@ -801,6 +804,74 @@ void GRenderWindow::TouchEndEvent() { input_subsystem->GetTouchScreen()->ReleaseAllTouch(); } +void GRenderWindow::InitializeCamera() { + if (!Settings::values.enable_ir_sensor) { + return; + } + + bool camera_found = false; + const QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); + for (const QCameraInfo& cameraInfo : cameras) { + if (Settings::values.ir_sensor_device.GetValue() == cameraInfo.deviceName().toStdString() || + Settings::values.ir_sensor_device.GetValue() == "Auto") { + camera = std::make_unique<QCamera>(cameraInfo); + camera_found = true; + break; + } + } + + if (!camera_found) { + return; + } + + camera_capture = std::make_unique<QCameraImageCapture>(camera.get()); + connect(camera_capture.get(), &QCameraImageCapture::imageCaptured, this, + &GRenderWindow::OnCameraCapture); + camera->unload(); + camera->setCaptureMode(QCamera::CaptureViewfinder); + camera->load(); + + camera_timer = std::make_unique<QTimer>(); + connect(camera_timer.get(), &QTimer::timeout, [this] { RequestCameraCapture(); }); + // This timer should be dependent of camera resolution 5ms for every 100 pixels + camera_timer->start(100); +} + +void GRenderWindow::FinalizeCamera() { + if (camera_timer) { + camera_timer->stop(); + } + if (camera) { + camera->unload(); + } +} + +void GRenderWindow::RequestCameraCapture() { + if (!Settings::values.enable_ir_sensor) { + return; + } + + // Idealy one should only call capture but Qt refuses to take a second capture without + // stopping the camera + camera->stop(); + camera->start(); + + camera_capture->capture(); +} + +void GRenderWindow::OnCameraCapture(int requestId, const QImage& img) { + constexpr std::size_t camera_width = 320; + constexpr std::size_t camera_height = 240; + const auto converted = + img.scaled(camera_width, camera_height, Qt::AspectRatioMode::IgnoreAspectRatio, + Qt::TransformationMode::SmoothTransformation) + .mirrored(false, true); + std::vector<u32> camera_data{}; + camera_data.resize(camera_width * camera_height); + std::memcpy(camera_data.data(), converted.bits(), camera_width * camera_height * sizeof(u32)); + input_subsystem->GetCamera()->SetCameraData(camera_width, camera_height, camera_data); +} + bool GRenderWindow::event(QEvent* event) { if (event->type() == QEvent::TouchBegin) { TouchBeginEvent(static_cast<QTouchEvent*>(event)); diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index 81fe52c0e..346201768 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -20,6 +20,8 @@ class GRenderWindow; class GMainWindow; +class QCamera; +class QCameraImageCapture; class QKeyEvent; namespace Core { @@ -164,6 +166,9 @@ public: void mouseReleaseEvent(QMouseEvent* event) override; void wheelEvent(QWheelEvent* event) override; + void InitializeCamera(); + void FinalizeCamera(); + bool event(QEvent* event) override; void focusOutEvent(QFocusEvent* event) override; @@ -207,6 +212,9 @@ private: void TouchUpdateEvent(const QTouchEvent* event); void TouchEndEvent(); + void RequestCameraCapture(); + void OnCameraCapture(int requestId, const QImage& img); + void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override; bool InitializeOpenGL(); @@ -232,6 +240,10 @@ private: bool first_frame = false; InputCommon::TasInput::TasState last_tas_state; + std::unique_ptr<QCamera> camera; + std::unique_ptr<QCameraImageCapture> camera_capture; + std::unique_ptr<QTimer> camera_timer; + Core::System& system; protected: diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 2840bc5eb..1f76e86b9 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -368,6 +368,11 @@ void Config::ReadHidbusValues() { } } +void Config::ReadIrCameraValues() { + ReadBasicSetting(Settings::values.enable_ir_sensor); + ReadBasicSetting(Settings::values.ir_sensor_device); +} + void Config::ReadAudioValues() { qt_config->beginGroup(QStringLiteral("Audio")); @@ -393,6 +398,7 @@ void Config::ReadControlValues() { ReadTouchscreenValues(); ReadMotionTouchValues(); ReadHidbusValues(); + ReadIrCameraValues(); #ifdef _WIN32 ReadBasicSetting(Settings::values.enable_raw_input); @@ -1005,6 +1011,11 @@ void Config::SaveHidbusValues() { QString::fromStdString(default_param)); } +void Config::SaveIrCameraValues() { + WriteBasicSetting(Settings::values.enable_ir_sensor); + WriteBasicSetting(Settings::values.ir_sensor_device); +} + void Config::SaveValues() { if (global) { SaveControlValues(); @@ -1047,6 +1058,7 @@ void Config::SaveControlValues() { SaveTouchscreenValues(); SaveMotionTouchValues(); SaveHidbusValues(); + SaveIrCameraValues(); WriteGlobalSetting(Settings::values.use_docked_mode); WriteGlobalSetting(Settings::values.vibration_enabled); diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index d511b3dbd..a71eabe8e 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h @@ -68,6 +68,7 @@ private: void ReadTouchscreenValues(); void ReadMotionTouchValues(); void ReadHidbusValues(); + void ReadIrCameraValues(); // Read functions bases off the respective config section names. void ReadAudioValues(); @@ -96,6 +97,7 @@ private: void SaveTouchscreenValues(); void SaveMotionTouchValues(); void SaveHidbusValues(); + void SaveIrCameraValues(); // Save functions based off the respective config section names. void SaveAudioValues(); diff --git a/src/yuzu/configuration/configure_camera.cpp b/src/yuzu/configuration/configure_camera.cpp new file mode 100644 index 000000000..97febb33c --- /dev/null +++ b/src/yuzu/configuration/configure_camera.cpp @@ -0,0 +1,126 @@ +// Text : Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#include <memory> +#include <QCameraImageCapture> +#include <QCameraInfo> +#include <QStandardItemModel> +#include <QTimer> + +#include "input_common/drivers/camera.h" +#include "input_common/main.h" +#include "ui_configure_camera.h" +#include "yuzu/configuration/config.h" +#include "yuzu/configuration/configure_camera.h" + +ConfigureCamera::ConfigureCamera(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_) + : QDialog(parent), input_subsystem{input_subsystem_}, + ui(std::make_unique<Ui::ConfigureCamera>()) { + ui->setupUi(this); + + connect(ui->restore_defaults_button, &QPushButton::clicked, this, + &ConfigureCamera::RestoreDefaults); + connect(ui->preview_button, &QPushButton::clicked, this, &ConfigureCamera::PreviewCamera); + + auto blank_image = QImage(320, 240, QImage::Format::Format_RGB32); + blank_image.fill(Qt::black); + DisplayCapturedFrame(0, blank_image); + + LoadConfiguration(); + resize(0, 0); +} + +ConfigureCamera::~ConfigureCamera() = default; + +void ConfigureCamera::PreviewCamera() { + const auto index = ui->ir_sensor_combo_box->currentIndex(); + bool camera_found = false; + const QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); + for (const QCameraInfo& cameraInfo : cameras) { + if (input_devices[index] == cameraInfo.deviceName().toStdString() || + input_devices[index] == "Auto") { + LOG_ERROR(Frontend, "Selected Camera {} {}", cameraInfo.description().toStdString(), + cameraInfo.deviceName().toStdString()); + camera = std::make_unique<QCamera>(cameraInfo); + camera_found = true; + break; + } + } + + // Clear previous frame + auto blank_image = QImage(320, 240, QImage::Format::Format_RGB32); + blank_image.fill(Qt::black); + DisplayCapturedFrame(0, blank_image); + + if (!camera_found) { + return; + } + + camera_capture = std::make_unique<QCameraImageCapture>(camera.get()); + connect(camera_capture.get(), &QCameraImageCapture::imageCaptured, this, + &ConfigureCamera::DisplayCapturedFrame); + camera->unload(); + camera->setCaptureMode(QCamera::CaptureViewfinder); + camera->load(); + + camera_timer = std::make_unique<QTimer>(); + connect(camera_timer.get(), &QTimer::timeout, [this] { + camera->stop(); + camera->start(); + + camera_capture->capture(); + }); + + camera_timer->start(250); +} + +void ConfigureCamera::DisplayCapturedFrame(int requestId, const QImage& img) { + LOG_ERROR(Frontend, "ImageCaptured {} {}", img.width(), img.height()); + const auto converted = img.scaled(320, 240, Qt::AspectRatioMode::IgnoreAspectRatio, + Qt::TransformationMode::SmoothTransformation); + ui->preview_box->setPixmap(QPixmap::fromImage(converted)); +} + +void ConfigureCamera::changeEvent(QEvent* event) { + if (event->type() == QEvent::LanguageChange) { + RetranslateUI(); + } + + QDialog::changeEvent(event); +} + +void ConfigureCamera::RetranslateUI() { + ui->retranslateUi(this); +} + +void ConfigureCamera::ApplyConfiguration() { + const auto index = ui->ir_sensor_combo_box->currentIndex(); + Settings::values.ir_sensor_device.SetValue(input_devices[index]); +} + +void ConfigureCamera::LoadConfiguration() { + input_devices.clear(); + ui->ir_sensor_combo_box->clear(); + input_devices.push_back("Auto"); + ui->ir_sensor_combo_box->addItem(tr("Auto")); + const auto cameras = QCameraInfo::availableCameras(); + for (const QCameraInfo& cameraInfo : cameras) { + input_devices.push_back(cameraInfo.deviceName().toStdString()); + ui->ir_sensor_combo_box->addItem(cameraInfo.description()); + } + + const auto current_device = Settings::values.ir_sensor_device.GetValue(); + + const auto devices_it = std::find_if( + input_devices.begin(), input_devices.end(), + [current_device](const std::string& device) { return device == current_device; }); + const int device_index = + devices_it != input_devices.end() + ? static_cast<int>(std::distance(input_devices.begin(), devices_it)) + : 0; + ui->ir_sensor_combo_box->setCurrentIndex(device_index); +} + +void ConfigureCamera::RestoreDefaults() { + ui->ir_sensor_combo_box->setCurrentIndex(0); +} diff --git a/src/yuzu/configuration/configure_camera.h b/src/yuzu/configuration/configure_camera.h new file mode 100644 index 000000000..af7551c03 --- /dev/null +++ b/src/yuzu/configuration/configure_camera.h @@ -0,0 +1,52 @@ +// Text : Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <memory> +#include <QDialog> + +class QTimer; +class QCamera; +class QCameraImageCapture; + +namespace InputCommon { +class InputSubsystem; +} // namespace InputCommon + +namespace Ui { +class ConfigureCamera; +} + +class ConfigureCamera : public QDialog { + Q_OBJECT + +public: + explicit ConfigureCamera(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_); + ~ConfigureCamera() override; + + void ApplyConfiguration(); + +private: + void changeEvent(QEvent* event) override; + void RetranslateUI(); + + /// Load configuration settings. + void LoadConfiguration(); + + /// Restore all buttons to their default values. + void RestoreDefaults(); + + void DisplayCapturedFrame(int requestId, const QImage& img); + + /// Loads and signals the current selected camera to display a frame + void PreviewCamera(); + + InputCommon::InputSubsystem* input_subsystem; + + std::unique_ptr<QCamera> camera; + std::unique_ptr<QCameraImageCapture> camera_capture; + std::unique_ptr<QTimer> camera_timer; + std::vector<std::string> input_devices; + std::unique_ptr<Ui::ConfigureCamera> ui; +}; diff --git a/src/yuzu/configuration/configure_camera.ui b/src/yuzu/configuration/configure_camera.ui new file mode 100644 index 000000000..976a9b1ec --- /dev/null +++ b/src/yuzu/configuration/configure_camera.ui @@ -0,0 +1,170 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>ConfigureCamera</class> + <widget class="QDialog" name="ConfigureCamera"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>298</width> + <height>339</height> + </rect> + </property> + <property name="windowTitle"> + <string>Configure Infrared Camera</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QLabel" name="label_2"> + <property name="minimumSize"> + <size> + <width>280</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string>Select where the image of the emulated camera comes from. It may be a virtual camera or a real camera.</string> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Fixed</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QGroupBox" name="gridGroupBox"> + <property name="title"> + <string>Camera Image Source:</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" 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="0" column="1"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Input device:</string> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QComboBox" name="ir_sensor_combo_box"/> + </item> + <item row="0" 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> + </layout> + </widget> + </item><item> + <widget class="QGroupBox" name="previewBox"> + <property name="title"> + <string>Preview</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="QLabel" name="preview_box"> + <property name="minimumSize"> + <size> + <width>320</width> + <height>240</height> + </size> + </property> + <property name="toolTip"> + <string>Resolution: 320*240</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="preview_button"> + <property name="text"> + <string>Click to preview</string> + </property> + </widget> + </item> + </layout> + </widget> + </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> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="restore_defaults_button"> + <property name="text"> + <string>Restore 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>ConfigureCamera</receiver> + <slot>accept()</slot> + </connection> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>ConfigureCamera</receiver> + <slot>reject()</slot> + </connection> + </connections> +</ui> diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp index 73d7ba24b..f1b061b13 100644 --- a/src/yuzu/configuration/configure_input.cpp +++ b/src/yuzu/configuration/configure_input.cpp @@ -15,6 +15,7 @@ #include "ui_configure_input.h" #include "ui_configure_input_advanced.h" #include "ui_configure_input_player.h" +#include "yuzu/configuration/configure_camera.h" #include "yuzu/configuration/configure_debug_controller.h" #include "yuzu/configuration/configure_input.h" #include "yuzu/configuration/configure_input_advanced.h" @@ -163,6 +164,10 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem, [this, input_subsystem, &hid_core] { CallConfigureDialog<ConfigureRingController>(*this, input_subsystem, hid_core); }); + connect(advanced, &ConfigureInputAdvanced::CallCameraDialog, + [this, input_subsystem, &hid_core] { + CallConfigureDialog<ConfigureCamera>(*this, input_subsystem); + }); connect(ui->vibrationButton, &QPushButton::clicked, [this, &hid_core] { CallConfigureDialog<ConfigureVibration>(*this, hid_core); }); diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp index f14bdc831..10f841b98 100644 --- a/src/yuzu/configuration/configure_input_advanced.cpp +++ b/src/yuzu/configuration/configure_input_advanced.cpp @@ -89,6 +89,7 @@ ConfigureInputAdvanced::ConfigureInputAdvanced(QWidget* parent) [this] { CallMotionTouchConfigDialog(); }); connect(ui->ring_controller_configure, &QPushButton::clicked, this, [this] { CallRingControllerDialog(); }); + connect(ui->camera_configure, &QPushButton::clicked, this, [this] { CallCameraDialog(); }); #ifndef _WIN32 ui->enable_raw_input->setVisible(false); @@ -136,6 +137,7 @@ void ConfigureInputAdvanced::ApplyConfiguration() { Settings::values.enable_udp_controller = ui->enable_udp_controller->isChecked(); Settings::values.controller_navigation = ui->controller_navigation->isChecked(); Settings::values.enable_ring_controller = ui->enable_ring_controller->isChecked(); + Settings::values.enable_ir_sensor = ui->enable_ir_sensor->isChecked(); } void ConfigureInputAdvanced::LoadConfiguration() { @@ -169,6 +171,7 @@ void ConfigureInputAdvanced::LoadConfiguration() { ui->enable_udp_controller->setChecked(Settings::values.enable_udp_controller.GetValue()); ui->controller_navigation->setChecked(Settings::values.controller_navigation.GetValue()); ui->enable_ring_controller->setChecked(Settings::values.enable_ring_controller.GetValue()); + ui->enable_ir_sensor->setChecked(Settings::values.enable_ir_sensor.GetValue()); UpdateUIEnabled(); } diff --git a/src/yuzu/configuration/configure_input_advanced.h b/src/yuzu/configuration/configure_input_advanced.h index 644e56dd8..fc1230284 100644 --- a/src/yuzu/configuration/configure_input_advanced.h +++ b/src/yuzu/configuration/configure_input_advanced.h @@ -29,6 +29,7 @@ signals: void CallTouchscreenConfigDialog(); void CallMotionTouchConfigDialog(); void CallRingControllerDialog(); + void CallCameraDialog(); private: void changeEvent(QEvent* event) override; diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui index 14403cb10..fac8cf827 100644 --- a/src/yuzu/configuration/configure_input_advanced.ui +++ b/src/yuzu/configuration/configure_input_advanced.ui @@ -2617,6 +2617,20 @@ </property> </widget> </item> + <item row="5" column="0"> + <widget class="QCheckBox" name="enable_ir_sensor"> + <property name="text"> + <string>Infrared Camera</string> + </property> + </widget> + </item> + <item row="5" column="2"> + <widget class="QPushButton" name="camera_configure"> + <property name="text"> + <string>Configure</string> + </property> + </widget> + </item> </layout> </widget> </item> diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index a120f2662..08ccc1555 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1542,6 +1542,8 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t mouse_hide_timer.start(); } + render_window->InitializeCamera(); + std::string title_name; std::string title_version; const auto res = system->GetGameName(title_name); @@ -1623,6 +1625,7 @@ void GMainWindow::ShutdownGame() { tas_label->clear(); input_subsystem->GetTas()->Stop(); OnTasStateChanged(); + render_window->FinalizeCamera(); // Enable all controllers system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All}); @@ -2862,6 +2865,12 @@ void GMainWindow::OnConfigure() { mouse_hide_timer.start(); } + // Restart camera config + if (emulation_running) { + render_window->FinalizeCamera(); + render_window->InitializeCamera(); + } + if (!UISettings::values.has_broken_vulkan) { renderer_status_button->setEnabled(!emulation_running); } |