diff options
| author | liamwhite <liamwhite@users.noreply.github.com> | 2022-07-24 13:31:28 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-07-24 13:31:28 -0400 | 
| commit | 5af06d14337a61d9ed1093079d13f68cbb1f5451 (patch) | |
| tree | 88df3fada076b04c2ab2da8972d1d785f492b520 /src/yuzu/configuration | |
| parent | 97729fd8e9c2f8cabc626ab03a666c9428e01c5e (diff) | |
| parent | 403bdc4dafe89a463f3d93b9a389a1010ca5ff16 (diff) | |
Merge pull request #8484 from german77/irs_release
service: irs: Add camera support, split processors and implement ImageTransferProcessor
Diffstat (limited to 'src/yuzu/configuration')
| -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 | 138 | ||||
| -rw-r--r-- | src/yuzu/configuration/configure_camera.h | 54 | ||||
| -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 | 
9 files changed, 399 insertions, 0 deletions
| 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..73cdcf3f2 --- /dev/null +++ b/src/yuzu/configuration/configure_camera.cpp @@ -0,0 +1,138 @@ +// 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_INFO(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->start(); + +    pending_snapshots = 0; +    is_virtual_camera = false; + +    camera_timer = std::make_unique<QTimer>(); +    connect(camera_timer.get(), &QTimer::timeout, [this] { +        // If the camera doesn't capture, test for virtual cameras +        if (pending_snapshots > 5) { +            is_virtual_camera = true; +        } +        // Virtual cameras like obs need to reset the camera every capture +        if (is_virtual_camera) { +            camera->stop(); +            camera->start(); +        } +        pending_snapshots++; +        camera_capture->capture(); +    }); + +    camera_timer->start(250); +} + +void ConfigureCamera::DisplayCapturedFrame(int requestId, const QImage& img) { +    LOG_INFO(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)); +    pending_snapshots = 0; +} + +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..db9833b5c --- /dev/null +++ b/src/yuzu/configuration/configure_camera.h @@ -0,0 +1,54 @@ +// 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; + +    bool is_virtual_camera; +    int pending_snapshots; +    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> | 
