diff --git a/3rdparty/qt5.cmake b/3rdparty/qt5.cmake index 6f465458da..97a0003631 100644 --- a/3rdparty/qt5.cmake +++ b/3rdparty/qt5.cmake @@ -2,17 +2,17 @@ add_library(3rdparty_qt5 INTERFACE) set(QT_MIN_VER 5.15.2) -find_package(Qt5 ${QT_MIN_VER} CONFIG COMPONENTS Widgets Concurrent Multimedia) +find_package(Qt5 ${QT_MIN_VER} CONFIG COMPONENTS Widgets Concurrent Multimedia MultimediaWidgets) if(WIN32) find_package(Qt5 ${QT_MIN_VER} COMPONENTS WinExtras REQUIRED) - target_link_libraries(3rdparty_qt5 INTERFACE Qt5::Widgets Qt5::WinExtras Qt5::Concurrent Qt5::Multimedia) + target_link_libraries(3rdparty_qt5 INTERFACE Qt5::Widgets Qt5::WinExtras Qt5::Concurrent Qt5::Multimedia Qt5::MultimediaWidgets) else() find_package(Qt5 ${QT_MIN_VER} COMPONENTS DBus Gui) if(Qt5DBus_FOUND) - target_link_libraries(3rdparty_qt5 INTERFACE Qt5::Widgets Qt5::DBus Qt5::Concurrent Qt5::Multimedia) + target_link_libraries(3rdparty_qt5 INTERFACE Qt5::Widgets Qt5::DBus Qt5::Concurrent Qt5::Multimedia Qt5::MultimediaWidgets) target_compile_definitions(3rdparty_qt5 INTERFACE -DHAVE_QTDBUS) else() - target_link_libraries(3rdparty_qt5 INTERFACE Qt5::Widgets Qt5::Concurrent Qt5::Multimedia) + target_link_libraries(3rdparty_qt5 INTERFACE Qt5::Widgets Qt5::Concurrent Qt5::Multimedia Qt5::MultimediaWidgets) endif() target_include_directories(3rdparty_qt5 INTERFACE ${Qt5Gui_PRIVATE_INCLUDE_DIRS}) endif() diff --git a/rpcs3/Emu/CMakeLists.txt b/rpcs3/Emu/CMakeLists.txt index f7f28f44c5..712e46bbc1 100644 --- a/rpcs3/Emu/CMakeLists.txt +++ b/rpcs3/Emu/CMakeLists.txt @@ -359,6 +359,7 @@ target_link_libraries(rpcs3_emu # Io target_sources(rpcs3_emu PRIVATE + Io/camera_config.cpp Io/interception.cpp Io/KeyboardHandler.cpp Io/pad_config.cpp diff --git a/rpcs3/Emu/Io/camera_config.cpp b/rpcs3/Emu/Io/camera_config.cpp new file mode 100644 index 0000000000..4e69a45f74 --- /dev/null +++ b/rpcs3/Emu/Io/camera_config.cpp @@ -0,0 +1,125 @@ +#include "stdafx.h" +#include "camera_config.h" +#include + +LOG_CHANNEL(camera_log, "Camera"); + +cfg_camera g_cfg_camera; + +cfg_camera::cfg_camera() +#ifdef _WIN32 + : path(fs::get_config_dir() + "config/camera.yml") +#else + : path(fs::get_config_dir() + "camera.yml") +#endif +{ +} + +bool cfg_camera::load() +{ + camera_log.notice("Loading camera config from '%s'", path); + + if (fs::file cfg_file{ path, fs::read }) + { + return from_string(cfg_file.to_string()); + } + + from_default(); + return false; +} + +void cfg_camera::save() const +{ + camera_log.notice("Saving camera config to '%s'", path); + + fs::pending_file cfg_file(path); + + if (!cfg_file.file || (cfg_file.file.write(to_string()), !cfg_file.commit())) + { + camera_log.error("Failed to save camera config to '%s'", path); + } +} + +cfg_camera::camera_setting cfg_camera::get_camera_setting(const std::string& camera, bool& success) +{ + camera_setting setting; + const std::string value = cameras.get_value(camera); + success = !value.empty(); + if (success) + { + setting.from_string(cameras.get_value(camera)); + } + return setting; +} + +void cfg_camera::set_camera_setting(const std::string& camera, const camera_setting& setting) +{ + if (camera.empty()) + { + camera_log.error("String '%s' cannot be used as camera key.", camera); + return; + } + + cameras.set_value(camera, setting.to_string()); +} + +std::string cfg_camera::camera_setting::to_string() const +{ + return fmt::format("%d,%d,%f,%f,%d,%d,%d", width, height, min_fps, max_fps, format, pixel_aspect_width, pixel_aspect_height); +} + +void cfg_camera::camera_setting::from_string(const std::string& text) +{ + if (text.empty()) + { + return; + } + + const std::vector list = fmt::split(text, { "," }); + + if (list.size() != member_count) + { + camera_log.error("String '%s' cannot be interpreted as camera_setting.", text); + return; + } + + const auto to_integer = [](const std::string& str, int& out) -> bool + { + auto [ptr, ec] = std::from_chars(str.c_str(), str.c_str() + str.size(), out); + if (ec != std::errc{}) + { + camera_log.error("String '%s' cannot be interpreted as integer.", str); + return false; + } + return true; + }; + + const auto to_double = [](const std::string& str, double& out) -> bool + { + char* end{}; + out = std::strtod(str.c_str(), &end); + if (end != str.c_str() + str.size()) + { + camera_log.error("String '%s' cannot be interpreted as double.", str); + return false; + } + return true; + }; + + if (!to_integer(list.at(0), width) || + !to_integer(list.at(1), height) || + !to_double(list.at(2), min_fps) || + !to_double(list.at(3), max_fps) || + !to_integer(list.at(4), format) || + !to_integer(list.at(5), pixel_aspect_width) || + !to_integer(list.at(6), pixel_aspect_height)) + { + width = 0; + height = 0; + min_fps = 0; + max_fps = 0; + format = 0; + pixel_aspect_width = 0; + pixel_aspect_height = 0; + } +} diff --git a/rpcs3/Emu/Io/camera_config.h b/rpcs3/Emu/Io/camera_config.h new file mode 100644 index 0000000000..ca737f120e --- /dev/null +++ b/rpcs3/Emu/Io/camera_config.h @@ -0,0 +1,34 @@ +#pragma once + +#include "Utilities/Config.h" + +struct cfg_camera final : cfg::node +{ + cfg_camera(); + bool load(); + void save() const; + + struct camera_setting + { + int width = 0; + int height = 0; + double min_fps = 0; + double max_fps = 0; + int format = 0; + int pixel_aspect_width = 0; + int pixel_aspect_height = 0; + + static const u32 member_count = 7; + + std::string to_string() const; + void from_string(const std::string& text); + }; + camera_setting get_camera_setting(const std::string& camera, bool& success); + void set_camera_setting(const std::string& camera, const camera_setting& setting); + + const std::string path; + + cfg::map_entry cameras{ this, "Cameras" }; // : ,,,,,, +}; + +extern cfg_camera g_cfg_camera; diff --git a/rpcs3/Emu/Io/pad_config.cpp b/rpcs3/Emu/Io/pad_config.cpp index 65ed6833e4..37ae06f096 100644 --- a/rpcs3/Emu/Io/pad_config.cpp +++ b/rpcs3/Emu/Io/pad_config.cpp @@ -96,11 +96,9 @@ void cfg_profile::save() const { input_log.notice("Saving pad profile config to '%s'", path); - if (auto cfg_file = fs::file(path, fs::rewrite)) - { - cfg_file.write(to_string()); - } - else + fs::pending_file cfg_file(path); + + if (!cfg_file.file || (cfg_file.file.write(to_string()), !cfg_file.commit())) { input_log.error("Failed to save pad profile config to '%s'", path); } diff --git a/rpcs3/Emu/NP/rpcn_config.cpp b/rpcs3/Emu/NP/rpcn_config.cpp index 3966268012..03a8c6e096 100644 --- a/rpcs3/Emu/NP/rpcn_config.cpp +++ b/rpcs3/Emu/NP/rpcn_config.cpp @@ -25,12 +25,9 @@ void cfg_rpcn::save() const } #endif - fs::file cfg_file(cfg_rpcn::get_path(), fs::rewrite); - if (cfg_file) - { - cfg_file.write(to_string()); - } - else + fs::pending_file cfg_file(cfg_rpcn::get_path()); + + if (!cfg_file.file || (cfg_file.file.write(to_string()), !cfg_file.commit())) { rpcn_log.error("Could not save config: %s", cfg_rpcn::get_path()); } diff --git a/rpcs3/emucore.vcxproj b/rpcs3/emucore.vcxproj index 0fc877d913..1de06c8731 100644 --- a/rpcs3/emucore.vcxproj +++ b/rpcs3/emucore.vcxproj @@ -63,6 +63,7 @@ + @@ -445,6 +446,7 @@ + diff --git a/rpcs3/emucore.vcxproj.filters b/rpcs3/emucore.vcxproj.filters index 2f59ff84dc..ae6645451c 100644 --- a/rpcs3/emucore.vcxproj.filters +++ b/rpcs3/emucore.vcxproj.filters @@ -1009,6 +1009,9 @@ Emu + + Emu\Io + @@ -2005,6 +2008,9 @@ Emu\Io\Null + + Emu\Io + diff --git a/rpcs3/rpcs3.vcxproj b/rpcs3/rpcs3.vcxproj index 2c2a34b3e9..3d92ffe7cf 100644 --- a/rpcs3/rpcs3.vcxproj +++ b/rpcs3/rpcs3.vcxproj @@ -71,7 +71,7 @@ - ..\3rdparty\flatbuffers\include;..\3rdparty\wolfssl\wolfssl;..\3rdparty\curl\curl\include;..\3rdparty\libusb\libusb\libusb;$(VULKAN_SDK)\Include;..\3rdparty\XAudio2Redist\include;$(QTDIR)\include;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtCore;.\release;$(QTDIR)\mkspecs\win32-msvc2015;.\QTGeneratedFiles\$(ConfigurationName);.\QTGeneratedFiles;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtConcurrent;$(QTDIR)\include\QtMultimedia;%(AdditionalIncludeDirectories) + ..\3rdparty\flatbuffers\include;..\3rdparty\wolfssl\wolfssl;..\3rdparty\curl\curl\include;..\3rdparty\libusb\libusb\libusb;$(VULKAN_SDK)\Include;..\3rdparty\XAudio2Redist\include;$(QTDIR)\include;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtCore;.\release;$(QTDIR)\mkspecs\win32-msvc2015;.\QTGeneratedFiles\$(ConfigurationName);.\QTGeneratedFiles;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtConcurrent;$(QTDIR)\include\QtMultimedia;$(QTDIR)\include\QtMultimediaWidgets;%(AdditionalIncludeDirectories) -Zc:strictStrings -Zc:throwingNew- -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions) release\ false @@ -79,7 +79,7 @@ 4577;4467;%(DisableSpecificWarnings) $(IntDir) MaxSpeed - _WINDOWS;UNICODE;WIN32;WIN64;WITH_DISCORD_RPC;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;NDEBUG;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;QT_MULTIMEDIA_LIB;%(PreprocessorDefinitions) + _WINDOWS;UNICODE;WIN32;WIN64;WITH_DISCORD_RPC;QT_NO_DEBUG;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;NDEBUG;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB;%(PreprocessorDefinitions) false $(IntDir)vc$(PlatformToolsetVersion).pdb true @@ -88,7 +88,7 @@ Level3 - Ole32.lib;gdi32.lib;..\hidapi.lib;..\libusb-1.0.lib;winmm.lib;OpenAL.lib;XAudio.lib;GLGSRender.lib;shlwapi.lib;VKGSRender.lib;vulkan-1.lib;wolfssl.lib;libcurl.lib;Wldap32.lib;glslang.lib;OSDependent.lib;OGLCompiler.lib;SPIRV.lib;MachineIndependent.lib;GenericCodeGen.lib;Advapi32.lib;user32.lib;zlib.lib;..\libpng16.lib;asmjit.lib;yaml-cpp.lib;discord-rpc.lib;emucore.lib;dxgi.lib;$(QTDIR)\lib\qtmain.lib;shell32.lib;$(QTDIR)\lib\Qt5Widgets.lib;$(QTDIR)\lib\Qt5Gui.lib;$(QTDIR)\lib\Qt5Core.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;Qt5WinExtras.lib;Qt5Concurrent.lib;7zlib.lib;SPIRV-Tools.lib;SPIRV-Tools-opt.lib;Qt5Multimedia.lib;%(AdditionalDependencies) + Ole32.lib;gdi32.lib;..\hidapi.lib;..\libusb-1.0.lib;winmm.lib;OpenAL.lib;XAudio.lib;GLGSRender.lib;shlwapi.lib;VKGSRender.lib;vulkan-1.lib;wolfssl.lib;libcurl.lib;Wldap32.lib;glslang.lib;OSDependent.lib;OGLCompiler.lib;SPIRV.lib;MachineIndependent.lib;GenericCodeGen.lib;Advapi32.lib;user32.lib;zlib.lib;..\libpng16.lib;asmjit.lib;yaml-cpp.lib;discord-rpc.lib;emucore.lib;dxgi.lib;$(QTDIR)\lib\qtmain.lib;shell32.lib;$(QTDIR)\lib\Qt5Widgets.lib;$(QTDIR)\lib\Qt5Gui.lib;$(QTDIR)\lib\Qt5Core.lib;Qt5Core.lib;Qt5Gui.lib;Qt5Widgets.lib;Qt5WinExtras.lib;Qt5Concurrent.lib;7zlib.lib;SPIRV-Tools.lib;SPIRV-Tools-opt.lib;Qt5Multimedia.lib;Qt5MultimediaWidgets.lib;%(AdditionalDependencies) ..\3rdparty\OpenAL\libs\Win64;..\3rdparty\glslang\build\hlsl\Release;..\3rdparty\glslang\build\SPIRV\Release;..\3rdparty\glslang\build\OGLCompilersDLL\Release;..\3rdparty\glslang\build\glslang\OSDependent\Windows\Release;..\3rdparty\glslang\build\glslang\Release;..\3rdparty\SPIRV\build\source\Release;..\3rdparty\SPIRV\build\source\opt\Release;..\lib\$(CONFIGURATION)-$(PLATFORM);..\3rdparty\XAudio2Redist\libs;..\3rdparty\discord-rpc\lib;$(QTDIR)\lib;%(AdditionalLibraryDirectories);$(VULKAN_SDK)\Lib "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" %(AdditionalOptions) true @@ -122,7 +122,7 @@ - ..\3rdparty\flatbuffers\include;..\3rdparty\wolfssl\wolfssl;..\3rdparty\curl\curl\include;..\3rdparty\libusb\libusb\libusb;$(VULKAN_SDK)\Include;..\3rdparty\XAudio2Redist\include;$(QTDIR)\include;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtCore;.\debug;$(QTDIR)\mkspecs\win32-msvc2015;.\QTGeneratedFiles\$(ConfigurationName);.\QTGeneratedFiles;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtConcurrent;$(QTDIR)\include\QtMultimedia;%(AdditionalIncludeDirectories) + ..\3rdparty\flatbuffers\include;..\3rdparty\wolfssl\wolfssl;..\3rdparty\curl\curl\include;..\3rdparty\libusb\libusb\libusb;$(VULKAN_SDK)\Include;..\3rdparty\XAudio2Redist\include;$(QTDIR)\include;$(QTDIR)\include\QtWidgets;$(QTDIR)\include\QtGui;$(QTDIR)\include\QtANGLE;$(QTDIR)\include\QtCore;.\debug;$(QTDIR)\mkspecs\win32-msvc2015;.\QTGeneratedFiles\$(ConfigurationName);.\QTGeneratedFiles;$(QTDIR)\include\QtWinExtras;$(QTDIR)\include\QtConcurrent;$(QTDIR)\include\QtMultimedia;$(QTDIR)\include\QtMultimediaWidgets;%(AdditionalIncludeDirectories) -Zc:strictStrings -Zc:throwingNew- -w34100 -w34189 -w44996 -w44456 -w44457 -w44458 %(AdditionalOptions) debug\ false @@ -130,7 +130,7 @@ 4577;4467;%(DisableSpecificWarnings) $(IntDir) Disabled - _WINDOWS;UNICODE;WIN32;WIN64;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;QT_MULTIMEDIA_LIB;%(PreprocessorDefinitions) + _WINDOWS;UNICODE;WIN32;WIN64;QT_WIDGETS_LIB;QT_GUI_LIB;QT_CORE_LIB;QT_WINEXTRAS_LIB;QT_CONCURRENT_LIB;QT_MULTIMEDIA_LIB;QT_MULTIMEDIAWIDGETS_LIB;%(PreprocessorDefinitions) false true true @@ -139,7 +139,7 @@ $(IntDir)vc$(PlatformToolsetVersion).pdb - Ole32.lib;gdi32.lib;..\hidapi.lib;..\libusb-1.0.lib;winmm.lib;OpenAL.lib;XAudio.lib;GLGSRender.lib;shlwapi.lib;VKGSRender.lib;vulkan-1.lib;wolfssl.lib;libcurl.lib;Wldap32.lib;glslangd.lib;OSDependentd.lib;OGLCompilerd.lib;SPIRVd.lib;MachineIndependentd.lib;GenericCodeGend.lib;Advapi32.lib;user32.lib;zlib.lib;..\libpng16.lib;asmjit.lib;yaml-cpp.lib;discord-rpc.lib;emucore.lib;dxgi.lib;$(QTDIR)\lib\qtmaind.lib;shell32.lib;$(QTDIR)\lib\Qt5Widgetsd.lib;$(QTDIR)\lib\Qt5Guid.lib;$(QTDIR)\lib\Qt5Cored.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;Qt5WinExtrasd.lib;Qt5Concurrentd.lib;7zlib.lib;SPIRV-Tools.lib;SPIRV-Tools-opt.lib;Qt5Multimediad.lib;%(AdditionalDependencies) + Ole32.lib;gdi32.lib;..\hidapi.lib;..\libusb-1.0.lib;winmm.lib;OpenAL.lib;XAudio.lib;GLGSRender.lib;shlwapi.lib;VKGSRender.lib;vulkan-1.lib;wolfssl.lib;libcurl.lib;Wldap32.lib;glslangd.lib;OSDependentd.lib;OGLCompilerd.lib;SPIRVd.lib;MachineIndependentd.lib;GenericCodeGend.lib;Advapi32.lib;user32.lib;zlib.lib;..\libpng16.lib;asmjit.lib;yaml-cpp.lib;discord-rpc.lib;emucore.lib;dxgi.lib;$(QTDIR)\lib\qtmaind.lib;shell32.lib;$(QTDIR)\lib\Qt5Widgetsd.lib;$(QTDIR)\lib\Qt5Guid.lib;$(QTDIR)\lib\Qt5Cored.lib;Qt5Cored.lib;Qt5Guid.lib;Qt5Widgetsd.lib;Qt5WinExtrasd.lib;Qt5Concurrentd.lib;7zlib.lib;SPIRV-Tools.lib;SPIRV-Tools-opt.lib;Qt5Multimediad.lib;Qt5MultimediaWidgetsd.lib;%(AdditionalDependencies) ..\3rdparty\OpenAL\libs\Win64;..\3rdparty\glslang\build\hlsl\Debug;..\3rdparty\glslang\build\SPIRV\Debug;..\3rdparty\glslang\build\OGLCompilersDLL\Debug;..\3rdparty\glslang\build\glslang\OSDependent\Windows\Debug;..\3rdparty\glslang\build\glslang\Debug;..\3rdparty\SPIRV\build\source\opt\Debug;..\3rdparty\XAudio2Redist\libs;..\3rdparty\discord-rpc\lib;..\lib\$(CONFIGURATION)-$(PLATFORM);$(QTDIR)\lib;%(AdditionalLibraryDirectories);$(VULKAN_SDK)\Lib "/MANIFESTDEPENDENCY:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' publicKeyToken='6595b64144ccf1df' language='*' processorArchitecture='*'" /VERBOSE %(AdditionalOptions) true @@ -198,6 +198,9 @@ true + + true + true @@ -399,6 +402,9 @@ true + + true + true @@ -580,6 +586,7 @@ + @@ -831,6 +838,7 @@ + @@ -889,6 +897,16 @@ .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" + + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\debug" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" + $(QTDIR)\bin\moc.exe;%(FullPath) + Moc%27ing %(Identity)... + .\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp + "$(QTDIR)\bin\moc.exe" "%(FullPath)" -o ".\QTGeneratedFiles\$(ConfigurationName)\moc_%(Filename).cpp" -D_WINDOWS -DUNICODE -DWIN32 -DWIN64 -DWITH_DISCORD_RPC -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DNDEBUG -DQT_WINEXTRAS_LIB -DQT_CONCURRENT_LIB -DQT_MULTIMEDIA_LIB -D%(PreprocessorDefinitions) "-I.\..\3rdparty\flatbuffers\include" "-I.\..\3rdparty\wolfssl\wolfssl" "-I.\..\3rdparty\curl\curl\include" "-I.\..\3rdparty\libusb\libusb\libusb" "-I$(VULKAN_SDK)\Include" "-I.\..\3rdparty\XAudio2Redist\include" "-I$(QTDIR)\include" "-I$(QTDIR)\include\QtWidgets" "-I$(QTDIR)\include\QtGui" "-I$(QTDIR)\include\QtANGLE" "-I$(QTDIR)\include\QtCore" "-I.\release" "-I$(QTDIR)\mkspecs\win32-msvc2015" "-I.\QTGeneratedFiles\$(ConfigurationName)" "-I.\QTGeneratedFiles" "-I$(QTDIR)\include\QtWinExtras" "-I$(QTDIR)\include\QtConcurrent" "-I$(QTDIR)\include\QtMultimedia" + @@ -1481,6 +1499,16 @@ .\QTGeneratedFiles\ui_%(Filename).h;%(Outputs) "$(QTDIR)\bin\uic.exe" -o ".\QTGeneratedFiles\ui_%(Filename).h" "%(FullPath)" + + $(QTDIR)\bin\uic.exe;%(AdditionalInputs) + Uic%27ing %(Identity)... + .\QTGeneratedFiles\ui_%(Filename).h;%(Outputs) + "$(QTDIR)\bin\uic.exe" -o ".\QTGeneratedFiles\ui_%(Filename).h" "%(FullPath)" + $(QTDIR)\bin\uic.exe;%(AdditionalInputs) + Uic%27ing %(Identity)... + .\QTGeneratedFiles\ui_%(Filename).h;%(Outputs) + "$(QTDIR)\bin\uic.exe" -o ".\QTGeneratedFiles\ui_%(Filename).h" "%(FullPath)" + diff --git a/rpcs3/rpcs3.vcxproj.filters b/rpcs3/rpcs3.vcxproj.filters index 8cf6530b2f..baaca3c499 100644 --- a/rpcs3/rpcs3.vcxproj.filters +++ b/rpcs3/rpcs3.vcxproj.filters @@ -795,6 +795,15 @@ Generated Files\Release + + Gui\settings + + + Generated Files\Debug + + + Generated Files\Release + @@ -935,6 +944,9 @@ Io\camera + + Generated Files + @@ -1165,6 +1177,12 @@ Io\camera + + Form Files + + + Gui\settings + diff --git a/rpcs3/rpcs3qt/CMakeLists.txt b/rpcs3/rpcs3qt/CMakeLists.txt index 3200de5c76..de12f49031 100644 --- a/rpcs3/rpcs3qt/CMakeLists.txt +++ b/rpcs3/rpcs3qt/CMakeLists.txt @@ -7,6 +7,7 @@ set(SRC_FILES breakpoint_handler.cpp breakpoint_list.cpp call_stack_list.cpp + camera_settings_dialog.cpp cg_disasm_window.cpp cheat_manager.cpp config_adapter.cpp @@ -83,6 +84,7 @@ set(SRC_FILES set(UI_FILES about_dialog.ui + camera_settings_dialog.ui main_window.ui pad_led_settings_dialog.ui pad_settings_dialog.ui diff --git a/rpcs3/rpcs3qt/camera_settings_dialog.cpp b/rpcs3/rpcs3qt/camera_settings_dialog.cpp new file mode 100644 index 0000000000..b8a19c7139 --- /dev/null +++ b/rpcs3/rpcs3qt/camera_settings_dialog.cpp @@ -0,0 +1,285 @@ +#include "stdafx.h" +#include "camera_settings_dialog.h" +#include "ui_camera_settings_dialog.h" +#include "Emu/Io/camera_config.h" + +#include +#include +#include + +LOG_CHANNEL(camera_log, "Camera"); + +template <> +void fmt_class_string::format(std::string& out, u64 arg) +{ + format_enum(out, arg, [](QVideoFrame::PixelFormat value) + { + switch (value) + { + case QVideoFrame::Format_Invalid: return "Invalid"; + case QVideoFrame::Format_ARGB32: return "ARGB32"; + case QVideoFrame::Format_ARGB32_Premultiplied: return "ARGB32_Premultiplied"; + case QVideoFrame::Format_RGB32: return "RGB32"; + case QVideoFrame::Format_RGB24: return "RGB24"; + case QVideoFrame::Format_RGB565: return "RGB565"; + case QVideoFrame::Format_RGB555: return "RGB555"; + case QVideoFrame::Format_ARGB8565_Premultiplied: return "ARGB8565_Premultiplied"; + case QVideoFrame::Format_BGRA32: return "BGRA32"; + case QVideoFrame::Format_BGRA32_Premultiplied: return "BGRA32_Premultiplied"; + case QVideoFrame::Format_BGR32: return "BGR32"; + case QVideoFrame::Format_BGR24: return "BGR24"; + case QVideoFrame::Format_BGR565: return "BGR565"; + case QVideoFrame::Format_BGR555: return "BGR555"; + case QVideoFrame::Format_BGRA5658_Premultiplied: return "BGRA5658_Premultiplied"; + case QVideoFrame::Format_AYUV444: return "AYUV444"; + case QVideoFrame::Format_AYUV444_Premultiplied: return "AYUV444_Premultiplied"; + case QVideoFrame::Format_YUV444: return "YUV444"; + case QVideoFrame::Format_YUV420P: return "YUV420P"; + case QVideoFrame::Format_YV12: return "YV12"; + case QVideoFrame::Format_UYVY: return "UYVY"; + case QVideoFrame::Format_YUYV: return "YUYV"; + case QVideoFrame::Format_NV12: return "NV12"; + case QVideoFrame::Format_NV21: return "NV21"; + case QVideoFrame::Format_IMC1: return "IMC1"; + case QVideoFrame::Format_IMC2: return "IMC2"; + case QVideoFrame::Format_IMC3: return "IMC3"; + case QVideoFrame::Format_IMC4: return "IMC4"; + case QVideoFrame::Format_Y8: return "Y8"; + case QVideoFrame::Format_Y16: return "Y16"; + case QVideoFrame::Format_Jpeg: return "Jpeg"; + case QVideoFrame::Format_CameraRaw: return "CameraRaw"; + case QVideoFrame::Format_AdobeDng: return "AdobeDng"; + case QVideoFrame::Format_ABGR32: return "ABGR32"; + case QVideoFrame::Format_YUV422P: return "YUV422P"; + case QVideoFrame::Format_User: return "User"; + } + + return unknown; + }); +} + +Q_DECLARE_METATYPE(QCameraInfo); + +camera_settings_dialog::camera_settings_dialog(QWidget* parent) + : QDialog(parent) + , ui(new Ui::camera_settings_dialog) +{ + ui->setupUi(this); + + load_config(); + + for (const QCameraInfo& camera_info : QCameraInfo::availableCameras()) + { + if (camera_info.isNull()) continue; + ui->combo_camera->addItem(camera_info.description(), QVariant::fromValue(camera_info)); + } + + connect(ui->combo_camera, QOverload::of(&QComboBox::currentIndexChanged), this, &camera_settings_dialog::handle_camera_change); + connect(ui->combo_settings, QOverload::of(&QComboBox::currentIndexChanged), this, &camera_settings_dialog::handle_settings_change); + connect(ui->buttonBox, &QDialogButtonBox::clicked, [this](QAbstractButton* button) + { + if (button == ui->buttonBox->button(QDialogButtonBox::Save)) + { + save_config(); + accept(); + } + else if (button == ui->buttonBox->button(QDialogButtonBox::Apply)) + { + save_config(); + } + }); + + if (ui->combo_camera->count() == 0) + { + ui->combo_camera->setEnabled(false); + ui->combo_settings->setEnabled(false); + ui->buttonBox->button(QDialogButtonBox::Save)->setEnabled(false); + ui->buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); + } + else + { + // TODO: show camera ID somewhere + ui->combo_camera->setCurrentIndex(0); + } +} + +camera_settings_dialog::~camera_settings_dialog() +{ +} + +void camera_settings_dialog::handle_camera_change(int index) +{ + if (index < 0 || !ui->combo_camera->itemData(index).canConvert()) + { + ui->combo_settings->clear(); + return; + } + + const QCameraInfo camera_info = ui->combo_camera->itemData(index).value(); + + if (camera_info.isNull()) + { + ui->combo_settings->clear(); + return; + } + + m_camera.reset(new QCamera(camera_info)); + m_camera->setViewfinder(ui->viewfinder); + + if (!m_camera->isAvailable()) + { + ui->combo_settings->clear(); + QMessageBox::warning(this, tr("Camera not available"), tr("The selected camera is not available.\nIt might be blocked by another application.")); + return; + } + + m_camera->load(); + + ui->combo_settings->blockSignals(true); + ui->combo_settings->clear(); + + QList settings = m_camera->supportedViewfinderSettings(); + std::sort(settings.begin(), settings.end(), [](const QCameraViewfinderSettings& l, const QCameraViewfinderSettings& r) -> bool + { + if (l.resolution().width() > r.resolution().width()) return true; + if (l.resolution().width() < r.resolution().width()) return false; + if (l.resolution().height() > r.resolution().height()) return true; + if (l.resolution().height() < r.resolution().height()) return false; + if (l.minimumFrameRate() > r.minimumFrameRate()) return true; + if (l.minimumFrameRate() < r.minimumFrameRate()) return false; + if (l.maximumFrameRate() > r.maximumFrameRate()) return true; + if (l.maximumFrameRate() < r.maximumFrameRate()) return false; + if (l.pixelFormat() > r.pixelFormat()) return true; + if (l.pixelFormat() < r.pixelFormat()) return false; + if (l.pixelAspectRatio().width() > r.pixelAspectRatio().width()) return true; + if (l.pixelAspectRatio().width() < r.pixelAspectRatio().width()) return false; + if (l.pixelAspectRatio().height() > r.pixelAspectRatio().height()) return true; + if (l.pixelAspectRatio().height() < r.pixelAspectRatio().height()) return false; + return false; + }); + + for (const QCameraViewfinderSettings& setting : settings) + { + if (setting.isNull()) continue; + const QString description = tr("%0x%1, %2-%3 FPS, Format=%4, PixelAspectRatio=%5x%6") + .arg(setting.resolution().width()) + .arg(setting.resolution().height()) + .arg(setting.minimumFrameRate()) + .arg(setting.maximumFrameRate()) + .arg(QString::fromStdString(fmt::format("%s", setting.pixelFormat()))) + .arg(setting.pixelAspectRatio().width()) + .arg(setting.pixelAspectRatio().height()); + ui->combo_settings->addItem(description, QVariant::fromValue(setting)); + } + ui->combo_settings->blockSignals(false); + + if (ui->combo_settings->count() == 0) + { + ui->combo_settings->setEnabled(false); + } + else + { + // Load selected settings from config file + int index = 0; + bool success = false; + const std::string key = camera_info.deviceName().toStdString(); + cfg_camera::camera_setting cfg_setting = g_cfg_camera.get_camera_setting(key, success); + + if (success) + { + camera_log.notice("Found config entry for camera \"%s\"", key); + + // Convert to Qt data + QCameraViewfinderSettings setting; + setting.setResolution(cfg_setting.width, cfg_setting.height); + setting.setMinimumFrameRate(cfg_setting.min_fps); + setting.setMaximumFrameRate(cfg_setting.max_fps); + setting.setPixelFormat(static_cast(cfg_setting.format)); + setting.setPixelAspectRatio(cfg_setting.pixel_aspect_width, cfg_setting.pixel_aspect_height); + + // Select matching drowdown entry + const double epsilon = 0.001; + + for (int i = 0; i < ui->combo_settings->count(); i++) + { + const QCameraViewfinderSettings tmp = ui->combo_settings->itemData(i).value(); + + if (tmp.resolution().width() == setting.resolution().width() && + tmp.resolution().height() == setting.resolution().height() && + tmp.minimumFrameRate() >= (setting.minimumFrameRate() - epsilon) && + tmp.minimumFrameRate() <= (setting.minimumFrameRate() + epsilon) && + tmp.maximumFrameRate() >= (setting.maximumFrameRate() - epsilon) && + tmp.maximumFrameRate() <= (setting.maximumFrameRate() + epsilon) && + tmp.pixelFormat() == setting.pixelFormat() && + tmp.pixelAspectRatio().width() == setting.pixelAspectRatio().width() && + tmp.pixelAspectRatio().height() == setting.pixelAspectRatio().height()) + { + index = i; + break; + } + } + } + + ui->combo_settings->setCurrentIndex(std::max(0, index)); + ui->combo_settings->setEnabled(true); + + // Update config to match user interface outcome + const QCameraViewfinderSettings setting = ui->combo_settings->currentData().value(); + cfg_setting.width = setting.resolution().width(); + cfg_setting.height = setting.resolution().height(); + cfg_setting.min_fps = setting.minimumFrameRate(); + cfg_setting.max_fps = setting.maximumFrameRate(); + cfg_setting.format = static_cast(setting.pixelFormat()); + cfg_setting.pixel_aspect_width = setting.pixelAspectRatio().width(); + cfg_setting.pixel_aspect_height = setting.pixelAspectRatio().height(); + g_cfg_camera.set_camera_setting(key, cfg_setting); + } +} + +void camera_settings_dialog::handle_settings_change(int index) +{ + if (!m_camera) + { + return; + } + + if (!m_camera->isAvailable()) + { + QMessageBox::warning(this, tr("Camera not available"), tr("The selected camera is not available.\nIt might be blocked by another application.")); + return; + } + + if (index >= 0 && ui->combo_settings->itemData(index).canConvert() && ui->combo_camera->currentData().canConvert()) + { + const QCameraViewfinderSettings setting = ui->combo_settings->itemData(index).value(); + if (!setting.isNull()) + { + m_camera->setViewfinderSettings(setting); + } + + cfg_camera::camera_setting cfg_setting; + cfg_setting.width = setting.resolution().width(); + cfg_setting.height = setting.resolution().height(); + cfg_setting.min_fps = setting.minimumFrameRate(); + cfg_setting.max_fps = setting.maximumFrameRate(); + cfg_setting.format = static_cast(setting.pixelFormat()); + cfg_setting.pixel_aspect_width = setting.pixelAspectRatio().width(); + cfg_setting.pixel_aspect_height = setting.pixelAspectRatio().height(); + g_cfg_camera.set_camera_setting(ui->combo_camera->currentData().value().deviceName().toStdString(), cfg_setting); + } + + m_camera->start(); +} + +void camera_settings_dialog::load_config() +{ + if (!g_cfg_camera.load()) + { + camera_log.notice("Could not load camera config. Using defaults."); + } +} + +void camera_settings_dialog::save_config() +{ + g_cfg_camera.save(); +} diff --git a/rpcs3/rpcs3qt/camera_settings_dialog.h b/rpcs3/rpcs3qt/camera_settings_dialog.h new file mode 100644 index 0000000000..61fa0dc87e --- /dev/null +++ b/rpcs3/rpcs3qt/camera_settings_dialog.h @@ -0,0 +1,29 @@ +#pragma once + +#include +#include + +namespace Ui +{ + class camera_settings_dialog; +} + +class camera_settings_dialog : public QDialog +{ + Q_OBJECT + +public: + camera_settings_dialog(QWidget* parent = nullptr); + virtual ~camera_settings_dialog(); + +private Q_SLOTS: + void handle_camera_change(int index); + void handle_settings_change(int index); + +private: + void load_config(); + void save_config(); + + Ui::camera_settings_dialog* ui; + std::shared_ptr m_camera; +}; diff --git a/rpcs3/rpcs3qt/camera_settings_dialog.ui b/rpcs3/rpcs3qt/camera_settings_dialog.ui new file mode 100644 index 0000000000..6deef8173e --- /dev/null +++ b/rpcs3/rpcs3qt/camera_settings_dialog.ui @@ -0,0 +1,130 @@ + + + camera_settings_dialog + + + + 0 + 0 + 356 + 380 + + + + Camera Settings + + + + + + + + Camera + + + + + + No cameras found + + + + + + + + + + Settings + + + + + + No settings found + + + + + + + + + + + + Preview + + + + + + + 64 + 48 + + + + true + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Apply|QDialogButtonBox::Cancel|QDialogButtonBox::Save + + + + + + + + QCameraViewfinder + QWidget +
qcameraviewfinder.h
+ 1 +
+
+ + + + buttonBox + accepted() + camera_settings_dialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + camera_settings_dialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + +
diff --git a/rpcs3/rpcs3qt/main_window.cpp b/rpcs3/rpcs3qt/main_window.cpp index e1a557cbfb..92c1d65bc6 100644 --- a/rpcs3/rpcs3qt/main_window.cpp +++ b/rpcs3/rpcs3qt/main_window.cpp @@ -28,6 +28,7 @@ #include "category.h" #include "gui_settings.h" #include "input_dialog.h" +#include "camera_settings_dialog.h" #include #include @@ -1652,6 +1653,7 @@ void main_window::OnEmuStop() #endif } ui->actionManage_Users->setEnabled(true); + ui->confCamerasAct->setEnabled(true); if (std::exchange(m_sys_menu_opened, false)) { @@ -1691,6 +1693,7 @@ void main_window::OnEmuReady() const EnableMenus(true); ui->actionManage_Users->setEnabled(false); + ui->confCamerasAct->setEnabled(false); } void main_window::EnableMenus(bool enabled) const @@ -2116,6 +2119,12 @@ void main_window::CreateConnects() connect(ui->confPadsAct, &QAction::triggered, this, open_pad_settings); + connect(ui->confCamerasAct, &QAction::triggered, this, [this]() + { + camera_settings_dialog dlg(this); + dlg.exec(); + }); + connect(ui->confRPCNAct, &QAction::triggered, this, [this]() { rpcn_settings_dialog dlg(this); diff --git a/rpcs3/rpcs3qt/main_window.ui b/rpcs3/rpcs3qt/main_window.ui index 441393bac9..eb82e7d99d 100644 --- a/rpcs3/rpcs3qt/main_window.ui +++ b/rpcs3/rpcs3qt/main_window.ui @@ -220,6 +220,7 @@ + @@ -1175,6 +1176,11 @@ Patch Creator + + + Cameras + + diff --git a/rpcs3/rpcs3qt/qt_camera_handler.cpp b/rpcs3/rpcs3qt/qt_camera_handler.cpp index 848f5cd773..2c679e89cd 100644 --- a/rpcs3/rpcs3qt/qt_camera_handler.cpp +++ b/rpcs3/rpcs3qt/qt_camera_handler.cpp @@ -1,6 +1,7 @@ #include "stdafx.h" #include "qt_camera_handler.h" #include "Emu/system_config.h" +#include "Emu/Io/camera_config.h" #include #include @@ -14,6 +15,8 @@ qt_camera_handler::qt_camera_handler() : camera_handler_base() { camera_log.success("Found camera: name=%s, description=%s", cameraInfo.deviceName().toStdString(), cameraInfo.description().toStdString()); } + + g_cfg_camera.load(); } qt_camera_handler::~qt_camera_handler() @@ -218,14 +221,15 @@ void qt_camera_handler::set_format(s32 format, u32 bytesize) m_format = format; m_bytesize = bytesize; - update_camera_settings(); + if (m_surface) + { + m_surface->set_format(m_format, m_bytesize); + } } void qt_camera_handler::set_frame_rate(u32 frame_rate) { m_frame_rate = frame_rate; - - update_camera_settings(); } void qt_camera_handler::set_resolution(u32 width, u32 height) @@ -233,14 +237,20 @@ void qt_camera_handler::set_resolution(u32 width, u32 height) m_width = width; m_height = height; - update_camera_settings(); + if (m_surface) + { + m_surface->set_resolution(m_width, m_height); + } } void qt_camera_handler::set_mirrored(bool mirrored) { m_mirrored = mirrored; - update_camera_settings(); + if (m_surface) + { + m_surface->set_mirrored(m_mirrored); + } } u64 qt_camera_handler::frame_number() const @@ -298,73 +308,55 @@ void qt_camera_handler::update_camera_settings() // Update camera if possible. We can only do this if it is already loaded. if (m_camera && m_camera->state() != QCamera::State::UnloadedState) { - // List all available settings in a cascading fashion and choose the proper value if possible. - // After each step, the next one will only list the settings that are compatible with the prior ones. - QCameraViewfinderSettings settings; + // Load selected settings from config file + bool success = false; + cfg_camera::camera_setting cfg_setting = g_cfg_camera.get_camera_setting(m_camera_id, success); - // Set resolution if possible. - const QList resolutions = m_camera->supportedViewfinderResolutions(settings); - if (resolutions.isEmpty()) + if (success) { - camera_log.warning("No resolution available for the view finder settings: frame_rate=%f, width=%d, height=%d, pixel_format=%d", - settings.maximumFrameRate(), settings.resolution().width(), settings.resolution().height(), static_cast(settings.pixelFormat())); - } - for (const QSize& resolution : resolutions) - { - if (static_cast(m_width) == resolution.width() && static_cast(m_height) == resolution.height()) + camera_log.notice("Found config entry for camera \"%s\"", m_camera_id); + + QCameraViewfinderSettings setting; + setting.setResolution(cfg_setting.width, cfg_setting.height); + setting.setMinimumFrameRate(cfg_setting.min_fps); + setting.setMaximumFrameRate(cfg_setting.max_fps); + setting.setPixelFormat(static_cast(cfg_setting.format)); + setting.setPixelAspectRatio(cfg_setting.pixel_aspect_width, cfg_setting.pixel_aspect_height); + + // List all available settings and choose the proper value if possible. + const double epsilon = 0.001; + success = false; + for (const QCameraViewfinderSettings& supported_setting : m_camera->supportedViewfinderSettings(setting)) { - settings.setResolution(resolution.width(), resolution.height()); - break; + if (supported_setting.resolution().width() == setting.resolution().width() && + supported_setting.resolution().height() == setting.resolution().height() && + supported_setting.minimumFrameRate() >= (setting.minimumFrameRate() - epsilon) && + supported_setting.minimumFrameRate() <= (setting.minimumFrameRate() + epsilon) && + supported_setting.maximumFrameRate() >= (setting.maximumFrameRate() - epsilon) && + supported_setting.maximumFrameRate() <= (setting.maximumFrameRate() + epsilon) && + supported_setting.pixelFormat() == setting.pixelFormat() && + supported_setting.pixelAspectRatio().width() == setting.pixelAspectRatio().width() && + supported_setting.pixelAspectRatio().height() == setting.pixelAspectRatio().height()) + { + // Apply settings. + camera_log.notice("Setting view finder settings: frame_rate=%f, width=%d, height=%d, pixel_format=%s", + supported_setting.maximumFrameRate(), supported_setting.resolution().width(), supported_setting.resolution().height(), supported_setting.pixelFormat()); + m_camera->setViewfinderSettings(supported_setting); + success = true; + break; + } + } + + if (!success) + { + camera_log.warning("No matching camera setting available for the camera config: max_fps=%f, width=%d, height=%d, format=%d", + cfg_setting.max_fps, cfg_setting.width, cfg_setting.height, cfg_setting.format); } } - // Set frame rate if possible. - const QList frame_rate_ranges = m_camera->supportedViewfinderFrameRateRanges(settings); - if (frame_rate_ranges.isEmpty()) + if (!success) { - camera_log.warning("No frame rate available for the view finder settings: frame_rate=%f, width=%d, height=%d, pixel_format=%d", - settings.maximumFrameRate(), settings.resolution().width(), settings.resolution().height(), static_cast(settings.pixelFormat())); - } - for (const QCamera::FrameRateRange& frame_rate : frame_rate_ranges) - { - // Some cameras do not have an exact match, so let's approximate. - if (static_cast(m_frame_rate) >= (frame_rate.maximumFrameRate - 0.5) && static_cast(m_frame_rate) <= (frame_rate.maximumFrameRate + 0.5)) - { - // Lock the frame rate by setting the min and max to the same value. - settings.setMinimumFrameRate(m_frame_rate); - settings.setMaximumFrameRate(m_frame_rate); - break; - } - } - - // Set pixel format if possible. (Unused for now, because formats differ between Qt and cell) - const QList pixel_formats = m_camera->supportedViewfinderPixelFormats(settings); - if (pixel_formats.isEmpty()) - { - camera_log.warning("No pixel format available for the view finder settings: frame_rate=%f, width=%d, height=%d, pixel_format=%d", - settings.maximumFrameRate(), settings.resolution().width(), settings.resolution().height(), static_cast(settings.pixelFormat())); - } - for (const QVideoFrame::PixelFormat& pixel_format : pixel_formats) - { - if (pixel_format == QVideoFrame::Format_RGB32) - { - settings.setPixelFormat(pixel_format); - break; - } - } - - if (m_camera->supportedViewfinderSettings(settings).isEmpty()) - { - camera_log.warning("No camera setting available for the view finder settings: frame_rate=%f, width=%d, height=%d, pixel_format=%d", - settings.maximumFrameRate(), settings.resolution().width(), settings.resolution().height(), static_cast(settings.pixelFormat())); - } - else - { - camera_log.notice("Setting view finder settings: frame_rate=%f, width=%d, height=%d, pixel_format=%d", - settings.maximumFrameRate(), settings.resolution().width(), settings.resolution().height(), static_cast(settings.pixelFormat())); - - // Apply settings. - m_camera->setViewfinderSettings(settings); + camera_log.notice("Using default view finder settings"); } } diff --git a/rpcs3/rpcs3qt/qt_camera_video_surface.cpp b/rpcs3/rpcs3qt/qt_camera_video_surface.cpp index 8f32264ef8..459c632d0d 100644 --- a/rpcs3/rpcs3qt/qt_camera_video_surface.cpp +++ b/rpcs3/rpcs3qt/qt_camera_video_surface.cpp @@ -93,7 +93,7 @@ bool qt_camera_video_surface::present(const QVideoFrame& frame) if (image.isNull()) { - camera_log.warning("Image is invalid: pixel_format=%d, format=%d", static_cast(tmp.pixelFormat()), static_cast(QVideoFrame::imageFormatFromPixelFormat(tmp.pixelFormat()))); + camera_log.warning("Image is invalid: pixel_format=%s, format=%d", tmp.pixelFormat(), static_cast(QVideoFrame::imageFormatFromPixelFormat(tmp.pixelFormat()))); } else { diff --git a/rpcs3/rpcs3qt/settings_dialog.cpp b/rpcs3/rpcs3qt/settings_dialog.cpp index 7c43962361..8590fe9302 100644 --- a/rpcs3/rpcs3qt/settings_dialog.cpp +++ b/rpcs3/rpcs3qt/settings_dialog.cpp @@ -978,11 +978,11 @@ settings_dialog::settings_dialog(std::shared_ptr gui_settings, std cfg_log.error("The selected camera was not found. Selecting default camera as fallback."); ui->cameraIdBox->setCurrentIndex(ui->cameraIdBox->findData(qstr(default_camera))); } - connect(ui->cameraIdBox, QOverload::of(&QComboBox::currentIndexChanged), [this](int index) + connect(ui->cameraIdBox, QOverload::of(&QComboBox::currentIndexChanged), this, [this](int index) { if (index >= 0) m_emu_settings->SetSetting(emu_settings_type::CameraID, ui->cameraIdBox->itemData(index).toString().toStdString()); }); - connect(m_emu_settings.get(), &emu_settings::RestoreDefaultsSignal, [this, default_camera]() + connect(m_emu_settings.get(), &emu_settings::RestoreDefaultsSignal, this, [this, default_camera]() { m_emu_settings->SetSetting(emu_settings_type::CameraID, default_camera); ui->cameraIdBox->setCurrentIndex(ui->cameraIdBox->findData(qstr(default_camera))); diff --git a/rpcs3/rpcs3qt/settings_dialog.ui b/rpcs3/rpcs3qt/settings_dialog.ui index 3b89c7b8de..230dd1f330 100644 --- a/rpcs3/rpcs3qt/settings_dialog.ui +++ b/rpcs3/rpcs3qt/settings_dialog.ui @@ -1415,14 +1415,14 @@ - - + + - Keyboard Handler + DJ Hero emulated turntable - + - + @@ -1439,30 +1439,6 @@ - - - - Buzz! emulated controller - - - - - - - - - - - - DJ Hero emulated turntable - - - - - - - - @@ -1475,7 +1451,43 @@ - + + + + Move Handler + + + + + + + + + + + + Keyboard Handler + + + + + + + + + + + + Buzz! emulated controller + + + + + + + + + Camera Flip @@ -1487,7 +1499,7 @@ - + Camera Handler @@ -1511,19 +1523,7 @@ - - - - Move Handler - - - - - - - - - + Camera