diff options
| author | 2022-06-18 23:34:28 -0500 | |
|---|---|---|
| committer | 2022-07-23 19:40:21 -0500 | |
| commit | cc83e0a6006667d126a7a83dde23a7f8ae3af994 (patch) | |
| tree | c4adfe7019e6f54050f8341e929c3db417d491f6 | |
| parent | input_common: Add camera driver (diff) | |
| download | yuzu-cc83e0a6006667d126a7a83dde23a7f8ae3af994.tar.gz yuzu-cc83e0a6006667d126a7a83dde23a7f8ae3af994.tar.xz yuzu-cc83e0a6006667d126a7a83dde23a7f8ae3af994.zip | |
yuzu: Hook qt camera to camera driver
| -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) | |||
| 196 | # Check for system Qt on Linux, fallback to bundled Qt | 196 | # Check for system Qt on Linux, fallback to bundled Qt |
| 197 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") | 197 | if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") |
| 198 | if (NOT YUZU_USE_BUNDLED_QT) | 198 | if (NOT YUZU_USE_BUNDLED_QT) |
| 199 | find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets DBus) | 199 | find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets DBus Multimedia) |
| 200 | endif() | 200 | endif() |
| 201 | if (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT) | 201 | if (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT) |
| 202 | # Check for dependencies, then enable bundled Qt download | 202 | # Check for dependencies, then enable bundled Qt download |
| @@ -300,9 +300,9 @@ if(ENABLE_QT) | |||
| 300 | set(YUZU_QT_NO_CMAKE_SYSTEM_PATH "NO_CMAKE_SYSTEM_PATH") | 300 | set(YUZU_QT_NO_CMAKE_SYSTEM_PATH "NO_CMAKE_SYSTEM_PATH") |
| 301 | endif() | 301 | endif() |
| 302 | if ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") AND YUZU_USE_BUNDLED_QT) | 302 | if ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") AND YUZU_USE_BUNDLED_QT) |
| 303 | find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent DBus ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) | 303 | find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent Multimedia DBus ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) |
| 304 | else() | 304 | else() |
| 305 | find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) | 305 | find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent Multimedia ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) |
| 306 | endif() | 306 | endif() |
| 307 | if (YUZU_USE_QT_WEB_ENGINE) | 307 | if (YUZU_USE_QT_WEB_ENGINE) |
| 308 | find_package(Qt5 REQUIRED COMPONENTS WebEngineCore WebEngineWidgets) | 308 | 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) | |||
| 10 | set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/") | 10 | set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/") |
| 11 | set(Qt5_PLATFORMTHEMES_DIR "${Qt5_DIR}/../../../plugins/platformthemes/") | 11 | set(Qt5_PLATFORMTHEMES_DIR "${Qt5_DIR}/../../../plugins/platformthemes/") |
| 12 | set(Qt5_PLATFORMINPUTCONTEXTS_DIR "${Qt5_DIR}/../../../plugins/platforminputcontexts/") | 12 | set(Qt5_PLATFORMINPUTCONTEXTS_DIR "${Qt5_DIR}/../../../plugins/platforminputcontexts/") |
| 13 | set(Qt5_MEDIASERVICE_DIR "${Qt5_DIR}/../../../plugins/mediaservice/") | ||
| 13 | set(Qt5_XCBGLINTEGRATIONS_DIR "${Qt5_DIR}/../../../plugins/xcbglintegrations/") | 14 | set(Qt5_XCBGLINTEGRATIONS_DIR "${Qt5_DIR}/../../../plugins/xcbglintegrations/") |
| 14 | set(Qt5_STYLES_DIR "${Qt5_DIR}/../../../plugins/styles/") | 15 | set(Qt5_STYLES_DIR "${Qt5_DIR}/../../../plugins/styles/") |
| 15 | set(Qt5_IMAGEFORMATS_DIR "${Qt5_DIR}/../../../plugins/imageformats/") | 16 | set(Qt5_IMAGEFORMATS_DIR "${Qt5_DIR}/../../../plugins/imageformats/") |
| 16 | set(Qt5_RESOURCES_DIR "${Qt5_DIR}/../../../resources/") | 17 | set(Qt5_RESOURCES_DIR "${Qt5_DIR}/../../../resources/") |
| 17 | set(PLATFORMS ${DLL_DEST}plugins/platforms/) | 18 | set(PLATFORMS ${DLL_DEST}plugins/platforms/) |
| 19 | set(MEDIASERVICE ${DLL_DEST}mediaservice/) | ||
| 18 | set(STYLES ${DLL_DEST}plugins/styles/) | 20 | set(STYLES ${DLL_DEST}plugins/styles/) |
| 19 | set(IMAGEFORMATS ${DLL_DEST}plugins/imageformats/) | 21 | set(IMAGEFORMATS ${DLL_DEST}plugins/imageformats/) |
| 20 | if (MSVC) | 22 | if (MSVC) |
| @@ -22,6 +24,7 @@ function(copy_yuzu_Qt5_deps target_dir) | |||
| 22 | Qt5Core$<$<CONFIG:Debug>:d>.* | 24 | Qt5Core$<$<CONFIG:Debug>:d>.* |
| 23 | Qt5Gui$<$<CONFIG:Debug>:d>.* | 25 | Qt5Gui$<$<CONFIG:Debug>:d>.* |
| 24 | Qt5Widgets$<$<CONFIG:Debug>:d>.* | 26 | Qt5Widgets$<$<CONFIG:Debug>:d>.* |
| 27 | Qt5Multimedia$<$<CONFIG:Debug>:d>.* | ||
| 25 | ) | 28 | ) |
| 26 | 29 | ||
| 27 | if (YUZU_USE_QT_WEB_ENGINE) | 30 | if (YUZU_USE_QT_WEB_ENGINE) |
| @@ -53,6 +56,10 @@ function(copy_yuzu_Qt5_deps target_dir) | |||
| 53 | qjpeg$<$<CONFIG:Debug>:d>.* | 56 | qjpeg$<$<CONFIG:Debug>:d>.* |
| 54 | qgif$<$<CONFIG:Debug>:d>.* | 57 | qgif$<$<CONFIG:Debug>:d>.* |
| 55 | ) | 58 | ) |
| 59 | windows_copy_files(yuzu ${Qt5_MEDIASERVICE_DIR} ${MEDIASERVICE} | ||
| 60 | dsengine$<$<CONFIG:Debug>:d>.* | ||
| 61 | wmfengine$<$<CONFIG:Debug>:d>.* | ||
| 62 | ) | ||
| 56 | else() | 63 | else() |
| 57 | set(Qt5_DLLS | 64 | set(Qt5_DLLS |
| 58 | "${Qt5_DLL_DIR}libQt5Core.so.5" | 65 | "${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 | |||
| 43 | configuration/configure_audio.cpp | 43 | configuration/configure_audio.cpp |
| 44 | configuration/configure_audio.h | 44 | configuration/configure_audio.h |
| 45 | configuration/configure_audio.ui | 45 | configuration/configure_audio.ui |
| 46 | configuration/configure_camera.cpp | ||
| 47 | configuration/configure_camera.h | ||
| 48 | configuration/configure_camera.ui | ||
| 46 | configuration/configure_cpu.cpp | 49 | configuration/configure_cpu.cpp |
| 47 | configuration/configure_cpu.h | 50 | configuration/configure_cpu.h |
| 48 | configuration/configure_cpu.ui | 51 | configuration/configure_cpu.ui |
| @@ -254,7 +257,7 @@ endif() | |||
| 254 | create_target_directory_groups(yuzu) | 257 | create_target_directory_groups(yuzu) |
| 255 | 258 | ||
| 256 | target_link_libraries(yuzu PRIVATE common core input_common video_core) | 259 | target_link_libraries(yuzu PRIVATE common core input_common video_core) |
| 257 | target_link_libraries(yuzu PRIVATE Boost::boost glad Qt::Widgets) | 260 | target_link_libraries(yuzu PRIVATE Boost::boost glad Qt::Widgets Qt::Multimedia) |
| 258 | target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) | 261 | target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) |
| 259 | 262 | ||
| 260 | target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include) | 263 | 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 @@ | |||
| 5 | #include <glad/glad.h> | 5 | #include <glad/glad.h> |
| 6 | 6 | ||
| 7 | #include <QApplication> | 7 | #include <QApplication> |
| 8 | #include <QCameraImageCapture> | ||
| 9 | #include <QCameraInfo> | ||
| 8 | #include <QHBoxLayout> | 10 | #include <QHBoxLayout> |
| 9 | #include <QMessageBox> | 11 | #include <QMessageBox> |
| 10 | #include <QPainter> | 12 | #include <QPainter> |
| @@ -31,6 +33,7 @@ | |||
| 31 | #include "core/core.h" | 33 | #include "core/core.h" |
| 32 | #include "core/cpu_manager.h" | 34 | #include "core/cpu_manager.h" |
| 33 | #include "core/frontend/framebuffer_layout.h" | 35 | #include "core/frontend/framebuffer_layout.h" |
| 36 | #include "input_common/drivers/camera.h" | ||
| 34 | #include "input_common/drivers/keyboard.h" | 37 | #include "input_common/drivers/keyboard.h" |
| 35 | #include "input_common/drivers/mouse.h" | 38 | #include "input_common/drivers/mouse.h" |
| 36 | #include "input_common/drivers/tas_input.h" | 39 | #include "input_common/drivers/tas_input.h" |
| @@ -801,6 +804,74 @@ void GRenderWindow::TouchEndEvent() { | |||
| 801 | input_subsystem->GetTouchScreen()->ReleaseAllTouch(); | 804 | input_subsystem->GetTouchScreen()->ReleaseAllTouch(); |
| 802 | } | 805 | } |
| 803 | 806 | ||
| 807 | void GRenderWindow::InitializeCamera() { | ||
| 808 | if (!Settings::values.enable_ir_sensor) { | ||
| 809 | return; | ||
| 810 | } | ||
| 811 | |||
| 812 | bool camera_found = false; | ||
| 813 | const QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); | ||
| 814 | for (const QCameraInfo& cameraInfo : cameras) { | ||
| 815 | if (Settings::values.ir_sensor_device.GetValue() == cameraInfo.deviceName().toStdString() || | ||
| 816 | Settings::values.ir_sensor_device.GetValue() == "Auto") { | ||
| 817 | camera = std::make_unique<QCamera>(cameraInfo); | ||
| 818 | camera_found = true; | ||
| 819 | break; | ||
| 820 | } | ||
| 821 | } | ||
| 822 | |||
| 823 | if (!camera_found) { | ||
| 824 | return; | ||
| 825 | } | ||
| 826 | |||
| 827 | camera_capture = std::make_unique<QCameraImageCapture>(camera.get()); | ||
| 828 | connect(camera_capture.get(), &QCameraImageCapture::imageCaptured, this, | ||
| 829 | &GRenderWindow::OnCameraCapture); | ||
| 830 | camera->unload(); | ||
| 831 | camera->setCaptureMode(QCamera::CaptureViewfinder); | ||
| 832 | camera->load(); | ||
| 833 | |||
| 834 | camera_timer = std::make_unique<QTimer>(); | ||
| 835 | connect(camera_timer.get(), &QTimer::timeout, [this] { RequestCameraCapture(); }); | ||
| 836 | // This timer should be dependent of camera resolution 5ms for every 100 pixels | ||
| 837 | camera_timer->start(100); | ||
| 838 | } | ||
| 839 | |||
| 840 | void GRenderWindow::FinalizeCamera() { | ||
| 841 | if (camera_timer) { | ||
| 842 | camera_timer->stop(); | ||
| 843 | } | ||
| 844 | if (camera) { | ||
| 845 | camera->unload(); | ||
| 846 | } | ||
| 847 | } | ||
| 848 | |||
| 849 | void GRenderWindow::RequestCameraCapture() { | ||
| 850 | if (!Settings::values.enable_ir_sensor) { | ||
| 851 | return; | ||
| 852 | } | ||
| 853 | |||
| 854 | // Idealy one should only call capture but Qt refuses to take a second capture without | ||
| 855 | // stopping the camera | ||
| 856 | camera->stop(); | ||
| 857 | camera->start(); | ||
| 858 | |||
| 859 | camera_capture->capture(); | ||
| 860 | } | ||
| 861 | |||
| 862 | void GRenderWindow::OnCameraCapture(int requestId, const QImage& img) { | ||
| 863 | constexpr std::size_t camera_width = 320; | ||
| 864 | constexpr std::size_t camera_height = 240; | ||
| 865 | const auto converted = | ||
| 866 | img.scaled(camera_width, camera_height, Qt::AspectRatioMode::IgnoreAspectRatio, | ||
| 867 | Qt::TransformationMode::SmoothTransformation) | ||
| 868 | .mirrored(false, true); | ||
| 869 | std::vector<u32> camera_data{}; | ||
| 870 | camera_data.resize(camera_width * camera_height); | ||
| 871 | std::memcpy(camera_data.data(), converted.bits(), camera_width * camera_height * sizeof(u32)); | ||
| 872 | input_subsystem->GetCamera()->SetCameraData(camera_width, camera_height, camera_data); | ||
| 873 | } | ||
| 874 | |||
| 804 | bool GRenderWindow::event(QEvent* event) { | 875 | bool GRenderWindow::event(QEvent* event) { |
| 805 | if (event->type() == QEvent::TouchBegin) { | 876 | if (event->type() == QEvent::TouchBegin) { |
| 806 | TouchBeginEvent(static_cast<QTouchEvent*>(event)); | 877 | 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 @@ | |||
| 20 | 20 | ||
| 21 | class GRenderWindow; | 21 | class GRenderWindow; |
| 22 | class GMainWindow; | 22 | class GMainWindow; |
| 23 | class QCamera; | ||
| 24 | class QCameraImageCapture; | ||
| 23 | class QKeyEvent; | 25 | class QKeyEvent; |
| 24 | 26 | ||
| 25 | namespace Core { | 27 | namespace Core { |
| @@ -164,6 +166,9 @@ public: | |||
| 164 | void mouseReleaseEvent(QMouseEvent* event) override; | 166 | void mouseReleaseEvent(QMouseEvent* event) override; |
| 165 | void wheelEvent(QWheelEvent* event) override; | 167 | void wheelEvent(QWheelEvent* event) override; |
| 166 | 168 | ||
| 169 | void InitializeCamera(); | ||
| 170 | void FinalizeCamera(); | ||
| 171 | |||
| 167 | bool event(QEvent* event) override; | 172 | bool event(QEvent* event) override; |
| 168 | 173 | ||
| 169 | void focusOutEvent(QFocusEvent* event) override; | 174 | void focusOutEvent(QFocusEvent* event) override; |
| @@ -207,6 +212,9 @@ private: | |||
| 207 | void TouchUpdateEvent(const QTouchEvent* event); | 212 | void TouchUpdateEvent(const QTouchEvent* event); |
| 208 | void TouchEndEvent(); | 213 | void TouchEndEvent(); |
| 209 | 214 | ||
| 215 | void RequestCameraCapture(); | ||
| 216 | void OnCameraCapture(int requestId, const QImage& img); | ||
| 217 | |||
| 210 | void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override; | 218 | void OnMinimalClientAreaChangeRequest(std::pair<u32, u32> minimal_size) override; |
| 211 | 219 | ||
| 212 | bool InitializeOpenGL(); | 220 | bool InitializeOpenGL(); |
| @@ -232,6 +240,10 @@ private: | |||
| 232 | bool first_frame = false; | 240 | bool first_frame = false; |
| 233 | InputCommon::TasInput::TasState last_tas_state; | 241 | InputCommon::TasInput::TasState last_tas_state; |
| 234 | 242 | ||
| 243 | std::unique_ptr<QCamera> camera; | ||
| 244 | std::unique_ptr<QCameraImageCapture> camera_capture; | ||
| 245 | std::unique_ptr<QTimer> camera_timer; | ||
| 246 | |||
| 235 | Core::System& system; | 247 | Core::System& system; |
| 236 | 248 | ||
| 237 | protected: | 249 | 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() { | |||
| 368 | } | 368 | } |
| 369 | } | 369 | } |
| 370 | 370 | ||
| 371 | void Config::ReadIrCameraValues() { | ||
| 372 | ReadBasicSetting(Settings::values.enable_ir_sensor); | ||
| 373 | ReadBasicSetting(Settings::values.ir_sensor_device); | ||
| 374 | } | ||
| 375 | |||
| 371 | void Config::ReadAudioValues() { | 376 | void Config::ReadAudioValues() { |
| 372 | qt_config->beginGroup(QStringLiteral("Audio")); | 377 | qt_config->beginGroup(QStringLiteral("Audio")); |
| 373 | 378 | ||
| @@ -393,6 +398,7 @@ void Config::ReadControlValues() { | |||
| 393 | ReadTouchscreenValues(); | 398 | ReadTouchscreenValues(); |
| 394 | ReadMotionTouchValues(); | 399 | ReadMotionTouchValues(); |
| 395 | ReadHidbusValues(); | 400 | ReadHidbusValues(); |
| 401 | ReadIrCameraValues(); | ||
| 396 | 402 | ||
| 397 | #ifdef _WIN32 | 403 | #ifdef _WIN32 |
| 398 | ReadBasicSetting(Settings::values.enable_raw_input); | 404 | ReadBasicSetting(Settings::values.enable_raw_input); |
| @@ -1005,6 +1011,11 @@ void Config::SaveHidbusValues() { | |||
| 1005 | QString::fromStdString(default_param)); | 1011 | QString::fromStdString(default_param)); |
| 1006 | } | 1012 | } |
| 1007 | 1013 | ||
| 1014 | void Config::SaveIrCameraValues() { | ||
| 1015 | WriteBasicSetting(Settings::values.enable_ir_sensor); | ||
| 1016 | WriteBasicSetting(Settings::values.ir_sensor_device); | ||
| 1017 | } | ||
| 1018 | |||
| 1008 | void Config::SaveValues() { | 1019 | void Config::SaveValues() { |
| 1009 | if (global) { | 1020 | if (global) { |
| 1010 | SaveControlValues(); | 1021 | SaveControlValues(); |
| @@ -1047,6 +1058,7 @@ void Config::SaveControlValues() { | |||
| 1047 | SaveTouchscreenValues(); | 1058 | SaveTouchscreenValues(); |
| 1048 | SaveMotionTouchValues(); | 1059 | SaveMotionTouchValues(); |
| 1049 | SaveHidbusValues(); | 1060 | SaveHidbusValues(); |
| 1061 | SaveIrCameraValues(); | ||
| 1050 | 1062 | ||
| 1051 | WriteGlobalSetting(Settings::values.use_docked_mode); | 1063 | WriteGlobalSetting(Settings::values.use_docked_mode); |
| 1052 | WriteGlobalSetting(Settings::values.vibration_enabled); | 1064 | 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: | |||
| 68 | void ReadTouchscreenValues(); | 68 | void ReadTouchscreenValues(); |
| 69 | void ReadMotionTouchValues(); | 69 | void ReadMotionTouchValues(); |
| 70 | void ReadHidbusValues(); | 70 | void ReadHidbusValues(); |
| 71 | void ReadIrCameraValues(); | ||
| 71 | 72 | ||
| 72 | // Read functions bases off the respective config section names. | 73 | // Read functions bases off the respective config section names. |
| 73 | void ReadAudioValues(); | 74 | void ReadAudioValues(); |
| @@ -96,6 +97,7 @@ private: | |||
| 96 | void SaveTouchscreenValues(); | 97 | void SaveTouchscreenValues(); |
| 97 | void SaveMotionTouchValues(); | 98 | void SaveMotionTouchValues(); |
| 98 | void SaveHidbusValues(); | 99 | void SaveHidbusValues(); |
| 100 | void SaveIrCameraValues(); | ||
| 99 | 101 | ||
| 100 | // Save functions based off the respective config section names. | 102 | // Save functions based off the respective config section names. |
| 101 | void SaveAudioValues(); | 103 | 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 @@ | |||
| 1 | // Text : Copyright 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #include <memory> | ||
| 5 | #include <QCameraImageCapture> | ||
| 6 | #include <QCameraInfo> | ||
| 7 | #include <QStandardItemModel> | ||
| 8 | #include <QTimer> | ||
| 9 | |||
| 10 | #include "input_common/drivers/camera.h" | ||
| 11 | #include "input_common/main.h" | ||
| 12 | #include "ui_configure_camera.h" | ||
| 13 | #include "yuzu/configuration/config.h" | ||
| 14 | #include "yuzu/configuration/configure_camera.h" | ||
| 15 | |||
| 16 | ConfigureCamera::ConfigureCamera(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_) | ||
| 17 | : QDialog(parent), input_subsystem{input_subsystem_}, | ||
| 18 | ui(std::make_unique<Ui::ConfigureCamera>()) { | ||
| 19 | ui->setupUi(this); | ||
| 20 | |||
| 21 | connect(ui->restore_defaults_button, &QPushButton::clicked, this, | ||
| 22 | &ConfigureCamera::RestoreDefaults); | ||
| 23 | connect(ui->preview_button, &QPushButton::clicked, this, &ConfigureCamera::PreviewCamera); | ||
| 24 | |||
| 25 | auto blank_image = QImage(320, 240, QImage::Format::Format_RGB32); | ||
| 26 | blank_image.fill(Qt::black); | ||
| 27 | DisplayCapturedFrame(0, blank_image); | ||
| 28 | |||
| 29 | LoadConfiguration(); | ||
| 30 | resize(0, 0); | ||
| 31 | } | ||
| 32 | |||
| 33 | ConfigureCamera::~ConfigureCamera() = default; | ||
| 34 | |||
| 35 | void ConfigureCamera::PreviewCamera() { | ||
| 36 | const auto index = ui->ir_sensor_combo_box->currentIndex(); | ||
| 37 | bool camera_found = false; | ||
| 38 | const QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); | ||
| 39 | for (const QCameraInfo& cameraInfo : cameras) { | ||
| 40 | if (input_devices[index] == cameraInfo.deviceName().toStdString() || | ||
| 41 | input_devices[index] == "Auto") { | ||
| 42 | LOG_ERROR(Frontend, "Selected Camera {} {}", cameraInfo.description().toStdString(), | ||
| 43 | cameraInfo.deviceName().toStdString()); | ||
| 44 | camera = std::make_unique<QCamera>(cameraInfo); | ||
| 45 | camera_found = true; | ||
| 46 | break; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | // Clear previous frame | ||
| 51 | auto blank_image = QImage(320, 240, QImage::Format::Format_RGB32); | ||
| 52 | blank_image.fill(Qt::black); | ||
| 53 | DisplayCapturedFrame(0, blank_image); | ||
| 54 | |||
| 55 | if (!camera_found) { | ||
| 56 | return; | ||
| 57 | } | ||
| 58 | |||
| 59 | camera_capture = std::make_unique<QCameraImageCapture>(camera.get()); | ||
| 60 | connect(camera_capture.get(), &QCameraImageCapture::imageCaptured, this, | ||
| 61 | &ConfigureCamera::DisplayCapturedFrame); | ||
| 62 | camera->unload(); | ||
| 63 | camera->setCaptureMode(QCamera::CaptureViewfinder); | ||
| 64 | camera->load(); | ||
| 65 | |||
| 66 | camera_timer = std::make_unique<QTimer>(); | ||
| 67 | connect(camera_timer.get(), &QTimer::timeout, [this] { | ||
| 68 | camera->stop(); | ||
| 69 | camera->start(); | ||
| 70 | |||
| 71 | camera_capture->capture(); | ||
| 72 | }); | ||
| 73 | |||
| 74 | camera_timer->start(250); | ||
| 75 | } | ||
| 76 | |||
| 77 | void ConfigureCamera::DisplayCapturedFrame(int requestId, const QImage& img) { | ||
| 78 | LOG_ERROR(Frontend, "ImageCaptured {} {}", img.width(), img.height()); | ||
| 79 | const auto converted = img.scaled(320, 240, Qt::AspectRatioMode::IgnoreAspectRatio, | ||
| 80 | Qt::TransformationMode::SmoothTransformation); | ||
| 81 | ui->preview_box->setPixmap(QPixmap::fromImage(converted)); | ||
| 82 | } | ||
| 83 | |||
| 84 | void ConfigureCamera::changeEvent(QEvent* event) { | ||
| 85 | if (event->type() == QEvent::LanguageChange) { | ||
| 86 | RetranslateUI(); | ||
| 87 | } | ||
| 88 | |||
| 89 | QDialog::changeEvent(event); | ||
| 90 | } | ||
| 91 | |||
| 92 | void ConfigureCamera::RetranslateUI() { | ||
| 93 | ui->retranslateUi(this); | ||
| 94 | } | ||
| 95 | |||
| 96 | void ConfigureCamera::ApplyConfiguration() { | ||
| 97 | const auto index = ui->ir_sensor_combo_box->currentIndex(); | ||
| 98 | Settings::values.ir_sensor_device.SetValue(input_devices[index]); | ||
| 99 | } | ||
| 100 | |||
| 101 | void ConfigureCamera::LoadConfiguration() { | ||
| 102 | input_devices.clear(); | ||
| 103 | ui->ir_sensor_combo_box->clear(); | ||
| 104 | input_devices.push_back("Auto"); | ||
| 105 | ui->ir_sensor_combo_box->addItem(tr("Auto")); | ||
| 106 | const auto cameras = QCameraInfo::availableCameras(); | ||
| 107 | for (const QCameraInfo& cameraInfo : cameras) { | ||
| 108 | input_devices.push_back(cameraInfo.deviceName().toStdString()); | ||
| 109 | ui->ir_sensor_combo_box->addItem(cameraInfo.description()); | ||
| 110 | } | ||
| 111 | |||
| 112 | const auto current_device = Settings::values.ir_sensor_device.GetValue(); | ||
| 113 | |||
| 114 | const auto devices_it = std::find_if( | ||
| 115 | input_devices.begin(), input_devices.end(), | ||
| 116 | [current_device](const std::string& device) { return device == current_device; }); | ||
| 117 | const int device_index = | ||
| 118 | devices_it != input_devices.end() | ||
| 119 | ? static_cast<int>(std::distance(input_devices.begin(), devices_it)) | ||
| 120 | : 0; | ||
| 121 | ui->ir_sensor_combo_box->setCurrentIndex(device_index); | ||
| 122 | } | ||
| 123 | |||
| 124 | void ConfigureCamera::RestoreDefaults() { | ||
| 125 | ui->ir_sensor_combo_box->setCurrentIndex(0); | ||
| 126 | } | ||
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 @@ | |||
| 1 | // Text : Copyright 2022 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-3.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include <memory> | ||
| 7 | #include <QDialog> | ||
| 8 | |||
| 9 | class QTimer; | ||
| 10 | class QCamera; | ||
| 11 | class QCameraImageCapture; | ||
| 12 | |||
| 13 | namespace InputCommon { | ||
| 14 | class InputSubsystem; | ||
| 15 | } // namespace InputCommon | ||
| 16 | |||
| 17 | namespace Ui { | ||
| 18 | class ConfigureCamera; | ||
| 19 | } | ||
| 20 | |||
| 21 | class ConfigureCamera : public QDialog { | ||
| 22 | Q_OBJECT | ||
| 23 | |||
| 24 | public: | ||
| 25 | explicit ConfigureCamera(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_); | ||
| 26 | ~ConfigureCamera() override; | ||
| 27 | |||
| 28 | void ApplyConfiguration(); | ||
| 29 | |||
| 30 | private: | ||
| 31 | void changeEvent(QEvent* event) override; | ||
| 32 | void RetranslateUI(); | ||
| 33 | |||
| 34 | /// Load configuration settings. | ||
| 35 | void LoadConfiguration(); | ||
| 36 | |||
| 37 | /// Restore all buttons to their default values. | ||
| 38 | void RestoreDefaults(); | ||
| 39 | |||
| 40 | void DisplayCapturedFrame(int requestId, const QImage& img); | ||
| 41 | |||
| 42 | /// Loads and signals the current selected camera to display a frame | ||
| 43 | void PreviewCamera(); | ||
| 44 | |||
| 45 | InputCommon::InputSubsystem* input_subsystem; | ||
| 46 | |||
| 47 | std::unique_ptr<QCamera> camera; | ||
| 48 | std::unique_ptr<QCameraImageCapture> camera_capture; | ||
| 49 | std::unique_ptr<QTimer> camera_timer; | ||
| 50 | std::vector<std::string> input_devices; | ||
| 51 | std::unique_ptr<Ui::ConfigureCamera> ui; | ||
| 52 | }; | ||
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 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <ui version="4.0"> | ||
| 3 | <class>ConfigureCamera</class> | ||
| 4 | <widget class="QDialog" name="ConfigureCamera"> | ||
| 5 | <property name="geometry"> | ||
| 6 | <rect> | ||
| 7 | <x>0</x> | ||
| 8 | <y>0</y> | ||
| 9 | <width>298</width> | ||
| 10 | <height>339</height> | ||
| 11 | </rect> | ||
| 12 | </property> | ||
| 13 | <property name="windowTitle"> | ||
| 14 | <string>Configure Infrared Camera</string> | ||
| 15 | </property> | ||
| 16 | <layout class="QVBoxLayout" name="verticalLayout"> | ||
| 17 | <item> | ||
| 18 | <widget class="QLabel" name="label_2"> | ||
| 19 | <property name="minimumSize"> | ||
| 20 | <size> | ||
| 21 | <width>280</width> | ||
| 22 | <height>0</height> | ||
| 23 | </size> | ||
| 24 | </property> | ||
| 25 | <property name="text"> | ||
| 26 | <string>Select where the image of the emulated camera comes from. It may be a virtual camera or a real camera.</string> | ||
| 27 | </property> | ||
| 28 | <property name="wordWrap"> | ||
| 29 | <bool>true</bool> | ||
| 30 | </property> | ||
| 31 | </widget> | ||
| 32 | </item> | ||
| 33 | <item> | ||
| 34 | <spacer name="verticalSpacer_2"> | ||
| 35 | <property name="orientation"> | ||
| 36 | <enum>Qt::Vertical</enum> | ||
| 37 | </property> | ||
| 38 | <property name="sizeType"> | ||
| 39 | <enum>QSizePolicy::Fixed</enum> | ||
| 40 | </property> | ||
| 41 | <property name="sizeHint" stdset="0"> | ||
| 42 | <size> | ||
| 43 | <width>20</width> | ||
| 44 | <height>20</height> | ||
| 45 | </size> | ||
| 46 | </property> | ||
| 47 | </spacer> | ||
| 48 | </item> | ||
| 49 | <item> | ||
| 50 | <widget class="QGroupBox" name="gridGroupBox"> | ||
| 51 | <property name="title"> | ||
| 52 | <string>Camera Image Source:</string> | ||
| 53 | </property> | ||
| 54 | <layout class="QGridLayout" name="gridLayout"> | ||
| 55 | <item row="0" column="0"> | ||
| 56 | <spacer name="horizontalSpacer"> | ||
| 57 | <property name="orientation"> | ||
| 58 | <enum>Qt::Horizontal</enum> | ||
| 59 | </property> | ||
| 60 | <property name="sizeHint" stdset="0"> | ||
| 61 | <size> | ||
| 62 | <width>40</width> | ||
| 63 | <height>20</height> | ||
| 64 | </size> | ||
| 65 | </property> | ||
| 66 | </spacer> | ||
| 67 | </item> | ||
| 68 | <item row="0" column="1"> | ||
| 69 | <widget class="QLabel" name="label_3"> | ||
| 70 | <property name="text"> | ||
| 71 | <string>Input device:</string> | ||
| 72 | </property> | ||
| 73 | </widget> | ||
| 74 | </item> | ||
| 75 | <item row="0" column="2"> | ||
| 76 | <widget class="QComboBox" name="ir_sensor_combo_box"/> | ||
| 77 | </item> | ||
| 78 | <item row="0" column="3"> | ||
| 79 | <spacer name="horizontalSpacer_2"> | ||
| 80 | <property name="orientation"> | ||
| 81 | <enum>Qt::Horizontal</enum> | ||
| 82 | </property> | ||
| 83 | <property name="sizeHint" stdset="0"> | ||
| 84 | <size> | ||
| 85 | <width>40</width> | ||
| 86 | <height>20</height> | ||
| 87 | </size> | ||
| 88 | </property> | ||
| 89 | </spacer> | ||
| 90 | </item> | ||
| 91 | </layout> | ||
| 92 | </widget> | ||
| 93 | </item><item> | ||
| 94 | <widget class="QGroupBox" name="previewBox"> | ||
| 95 | <property name="title"> | ||
| 96 | <string>Preview</string> | ||
| 97 | </property> | ||
| 98 | <layout class="QVBoxLayout" name="verticalLayout_3"> | ||
| 99 | <item> | ||
| 100 | <widget class="QLabel" name="preview_box"> | ||
| 101 | <property name="minimumSize"> | ||
| 102 | <size> | ||
| 103 | <width>320</width> | ||
| 104 | <height>240</height> | ||
| 105 | </size> | ||
| 106 | </property> | ||
| 107 | <property name="toolTip"> | ||
| 108 | <string>Resolution: 320*240</string> | ||
| 109 | </property> | ||
| 110 | </widget> | ||
| 111 | </item> | ||
| 112 | <item> | ||
| 113 | <widget class="QPushButton" name="preview_button"> | ||
| 114 | <property name="text"> | ||
| 115 | <string>Click to preview</string> | ||
| 116 | </property> | ||
| 117 | </widget> | ||
| 118 | </item> | ||
| 119 | </layout> | ||
| 120 | </widget> | ||
| 121 | </item> | ||
| 122 | <item> | ||
| 123 | <spacer name="verticalSpacer"> | ||
| 124 | <property name="orientation"> | ||
| 125 | <enum>Qt::Vertical</enum> | ||
| 126 | </property> | ||
| 127 | <property name="sizeHint" stdset="0"> | ||
| 128 | <size> | ||
| 129 | <width>20</width> | ||
| 130 | <height>40</height> | ||
| 131 | </size> | ||
| 132 | </property> | ||
| 133 | </spacer> | ||
| 134 | </item> | ||
| 135 | <item> | ||
| 136 | <layout class="QHBoxLayout" name="horizontalLayout"> | ||
| 137 | <item> | ||
| 138 | <widget class="QPushButton" name="restore_defaults_button"> | ||
| 139 | <property name="text"> | ||
| 140 | <string>Restore Defaults</string> | ||
| 141 | </property> | ||
| 142 | </widget> | ||
| 143 | </item> | ||
| 144 | <item> | ||
| 145 | <widget class="QDialogButtonBox" name="buttonBox"> | ||
| 146 | <property name="standardButtons"> | ||
| 147 | <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> | ||
| 148 | </property> | ||
| 149 | </widget> | ||
| 150 | </item> | ||
| 151 | </layout> | ||
| 152 | </item> | ||
| 153 | </layout> | ||
| 154 | </widget> | ||
| 155 | <resources/> | ||
| 156 | <connections> | ||
| 157 | <connection> | ||
| 158 | <sender>buttonBox</sender> | ||
| 159 | <signal>accepted()</signal> | ||
| 160 | <receiver>ConfigureCamera</receiver> | ||
| 161 | <slot>accept()</slot> | ||
| 162 | </connection> | ||
| 163 | <connection> | ||
| 164 | <sender>buttonBox</sender> | ||
| 165 | <signal>rejected()</signal> | ||
| 166 | <receiver>ConfigureCamera</receiver> | ||
| 167 | <slot>reject()</slot> | ||
| 168 | </connection> | ||
| 169 | </connections> | ||
| 170 | </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 @@ | |||
| 15 | #include "ui_configure_input.h" | 15 | #include "ui_configure_input.h" |
| 16 | #include "ui_configure_input_advanced.h" | 16 | #include "ui_configure_input_advanced.h" |
| 17 | #include "ui_configure_input_player.h" | 17 | #include "ui_configure_input_player.h" |
| 18 | #include "yuzu/configuration/configure_camera.h" | ||
| 18 | #include "yuzu/configuration/configure_debug_controller.h" | 19 | #include "yuzu/configuration/configure_debug_controller.h" |
| 19 | #include "yuzu/configuration/configure_input.h" | 20 | #include "yuzu/configuration/configure_input.h" |
| 20 | #include "yuzu/configuration/configure_input_advanced.h" | 21 | #include "yuzu/configuration/configure_input_advanced.h" |
| @@ -163,6 +164,10 @@ void ConfigureInput::Initialize(InputCommon::InputSubsystem* input_subsystem, | |||
| 163 | [this, input_subsystem, &hid_core] { | 164 | [this, input_subsystem, &hid_core] { |
| 164 | CallConfigureDialog<ConfigureRingController>(*this, input_subsystem, hid_core); | 165 | CallConfigureDialog<ConfigureRingController>(*this, input_subsystem, hid_core); |
| 165 | }); | 166 | }); |
| 167 | connect(advanced, &ConfigureInputAdvanced::CallCameraDialog, | ||
| 168 | [this, input_subsystem, &hid_core] { | ||
| 169 | CallConfigureDialog<ConfigureCamera>(*this, input_subsystem); | ||
| 170 | }); | ||
| 166 | 171 | ||
| 167 | connect(ui->vibrationButton, &QPushButton::clicked, | 172 | connect(ui->vibrationButton, &QPushButton::clicked, |
| 168 | [this, &hid_core] { CallConfigureDialog<ConfigureVibration>(*this, hid_core); }); | 173 | [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) | |||
| 89 | [this] { CallMotionTouchConfigDialog(); }); | 89 | [this] { CallMotionTouchConfigDialog(); }); |
| 90 | connect(ui->ring_controller_configure, &QPushButton::clicked, this, | 90 | connect(ui->ring_controller_configure, &QPushButton::clicked, this, |
| 91 | [this] { CallRingControllerDialog(); }); | 91 | [this] { CallRingControllerDialog(); }); |
| 92 | connect(ui->camera_configure, &QPushButton::clicked, this, [this] { CallCameraDialog(); }); | ||
| 92 | 93 | ||
| 93 | #ifndef _WIN32 | 94 | #ifndef _WIN32 |
| 94 | ui->enable_raw_input->setVisible(false); | 95 | ui->enable_raw_input->setVisible(false); |
| @@ -136,6 +137,7 @@ void ConfigureInputAdvanced::ApplyConfiguration() { | |||
| 136 | Settings::values.enable_udp_controller = ui->enable_udp_controller->isChecked(); | 137 | Settings::values.enable_udp_controller = ui->enable_udp_controller->isChecked(); |
| 137 | Settings::values.controller_navigation = ui->controller_navigation->isChecked(); | 138 | Settings::values.controller_navigation = ui->controller_navigation->isChecked(); |
| 138 | Settings::values.enable_ring_controller = ui->enable_ring_controller->isChecked(); | 139 | Settings::values.enable_ring_controller = ui->enable_ring_controller->isChecked(); |
| 140 | Settings::values.enable_ir_sensor = ui->enable_ir_sensor->isChecked(); | ||
| 139 | } | 141 | } |
| 140 | 142 | ||
| 141 | void ConfigureInputAdvanced::LoadConfiguration() { | 143 | void ConfigureInputAdvanced::LoadConfiguration() { |
| @@ -169,6 +171,7 @@ void ConfigureInputAdvanced::LoadConfiguration() { | |||
| 169 | ui->enable_udp_controller->setChecked(Settings::values.enable_udp_controller.GetValue()); | 171 | ui->enable_udp_controller->setChecked(Settings::values.enable_udp_controller.GetValue()); |
| 170 | ui->controller_navigation->setChecked(Settings::values.controller_navigation.GetValue()); | 172 | ui->controller_navigation->setChecked(Settings::values.controller_navigation.GetValue()); |
| 171 | ui->enable_ring_controller->setChecked(Settings::values.enable_ring_controller.GetValue()); | 173 | ui->enable_ring_controller->setChecked(Settings::values.enable_ring_controller.GetValue()); |
| 174 | ui->enable_ir_sensor->setChecked(Settings::values.enable_ir_sensor.GetValue()); | ||
| 172 | 175 | ||
| 173 | UpdateUIEnabled(); | 176 | UpdateUIEnabled(); |
| 174 | } | 177 | } |
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: | |||
| 29 | void CallTouchscreenConfigDialog(); | 29 | void CallTouchscreenConfigDialog(); |
| 30 | void CallMotionTouchConfigDialog(); | 30 | void CallMotionTouchConfigDialog(); |
| 31 | void CallRingControllerDialog(); | 31 | void CallRingControllerDialog(); |
| 32 | void CallCameraDialog(); | ||
| 32 | 33 | ||
| 33 | private: | 34 | private: |
| 34 | void changeEvent(QEvent* event) override; | 35 | 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 @@ | |||
| 2617 | </property> | 2617 | </property> |
| 2618 | </widget> | 2618 | </widget> |
| 2619 | </item> | 2619 | </item> |
| 2620 | <item row="5" column="0"> | ||
| 2621 | <widget class="QCheckBox" name="enable_ir_sensor"> | ||
| 2622 | <property name="text"> | ||
| 2623 | <string>Infrared Camera</string> | ||
| 2624 | </property> | ||
| 2625 | </widget> | ||
| 2626 | </item> | ||
| 2627 | <item row="5" column="2"> | ||
| 2628 | <widget class="QPushButton" name="camera_configure"> | ||
| 2629 | <property name="text"> | ||
| 2630 | <string>Configure</string> | ||
| 2631 | </property> | ||
| 2632 | </widget> | ||
| 2633 | </item> | ||
| 2620 | </layout> | 2634 | </layout> |
| 2621 | </widget> | 2635 | </widget> |
| 2622 | </item> | 2636 | </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 | |||
| 1542 | mouse_hide_timer.start(); | 1542 | mouse_hide_timer.start(); |
| 1543 | } | 1543 | } |
| 1544 | 1544 | ||
| 1545 | render_window->InitializeCamera(); | ||
| 1546 | |||
| 1545 | std::string title_name; | 1547 | std::string title_name; |
| 1546 | std::string title_version; | 1548 | std::string title_version; |
| 1547 | const auto res = system->GetGameName(title_name); | 1549 | const auto res = system->GetGameName(title_name); |
| @@ -1623,6 +1625,7 @@ void GMainWindow::ShutdownGame() { | |||
| 1623 | tas_label->clear(); | 1625 | tas_label->clear(); |
| 1624 | input_subsystem->GetTas()->Stop(); | 1626 | input_subsystem->GetTas()->Stop(); |
| 1625 | OnTasStateChanged(); | 1627 | OnTasStateChanged(); |
| 1628 | render_window->FinalizeCamera(); | ||
| 1626 | 1629 | ||
| 1627 | // Enable all controllers | 1630 | // Enable all controllers |
| 1628 | system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All}); | 1631 | system->HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All}); |
| @@ -2862,6 +2865,12 @@ void GMainWindow::OnConfigure() { | |||
| 2862 | mouse_hide_timer.start(); | 2865 | mouse_hide_timer.start(); |
| 2863 | } | 2866 | } |
| 2864 | 2867 | ||
| 2868 | // Restart camera config | ||
| 2869 | if (emulation_running) { | ||
| 2870 | render_window->FinalizeCamera(); | ||
| 2871 | render_window->InitializeCamera(); | ||
| 2872 | } | ||
| 2873 | |||
| 2865 | if (!UISettings::values.has_broken_vulkan) { | 2874 | if (!UISettings::values.has_broken_vulkan) { |
| 2866 | renderer_status_button->setEnabled(!emulation_running); | 2875 | renderer_status_button->setEnabled(!emulation_running); |
| 2867 | } | 2876 | } |