summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt251
-rw-r--r--CMakeModules/CopyYuzuQt5Deps.cmake7
-rw-r--r--src/common/cache_management.cpp5
-rw-r--r--src/common/cache_management.h2
-rw-r--r--src/common/input.h40
-rw-r--r--src/core/hid/emulated_console.cpp4
-rw-r--r--src/core/hid/emulated_controller.cpp38
-rw-r--r--src/core/hid/emulated_devices.cpp15
-rw-r--r--src/core/hle/service/nvdrv/core/syncpoint_manager.cpp46
-rw-r--r--src/core/hle/service/nvdrv/core/syncpoint_manager.h2
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp44
-rw-r--r--src/core/hle/service/nvflinger/buffer_item_consumer.cpp2
-rw-r--r--src/core/hle/service/nvflinger/buffer_item_consumer.h2
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_consumer.cpp2
-rw-r--r--src/core/hle/service/nvflinger/consumer_base.cpp6
-rw-r--r--src/core/hle/service/nvflinger/consumer_base.h16
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp3
-rw-r--r--src/core/hle/service/nvflinger/producer_listener.h1
-rw-r--r--src/input_common/helpers/stick_from_buttons.cpp25
-rw-r--r--src/input_common/helpers/touch_from_buttons.cpp13
-rw-r--r--src/input_common/main.cpp100
-rw-r--r--src/video_core/engines/engine_upload.cpp7
-rw-r--r--src/video_core/engines/engine_upload.h2
-rw-r--r--src/video_core/engines/fermi_2d.h2
-rw-r--r--src/video_core/engines/kepler_compute.cpp6
-rw-r--r--src/video_core/engines/kepler_compute.h14
-rw-r--r--src/video_core/engines/kepler_memory.cpp6
-rw-r--r--src/video_core/engines/maxwell_3d.cpp12
-rw-r--r--src/video_core/engines/maxwell_3d.h79
-rw-r--r--src/video_core/engines/maxwell_dma.cpp14
-rw-r--r--src/video_core/engines/puller.cpp6
-rw-r--r--src/video_core/host1x/syncpoint_manager.cpp6
-rw-r--r--src/video_core/host1x/syncpoint_manager.h12
-rw-r--r--src/video_core/surface.cpp15
-rw-r--r--src/yuzu/CMakeLists.txt26
-rw-r--r--src/yuzu/bootmanager.cpp8
-rw-r--r--src/yuzu/bootmanager.h2
-rw-r--r--src/yuzu/configuration/configure_camera.cpp7
-rw-r--r--src/yuzu/configuration/configure_camera.h2
-rw-r--r--src/yuzu/configuration/configure_input_advanced.cpp4
-rw-r--r--src/yuzu/main.cpp6
-rw-r--r--src/yuzu/multiplayer/direct_connect.cpp2
-rw-r--r--src/yuzu/multiplayer/validation.h16
-rw-r--r--src/yuzu_cmd/config.cpp6
-rw-r--r--src/yuzu_cmd/default_ini.h29
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp2
46 files changed, 517 insertions, 398 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1d13dc74e..2d2761ec1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,6 +19,9 @@ CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON
19CMAKE_DEPENDENT_OPTION(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" ON "ENABLE_SDL2;NOT MSVC" OFF) 19CMAKE_DEPENDENT_OPTION(YUZU_USE_EXTERNAL_SDL2 "Compile external SDL2" ON "ENABLE_SDL2;NOT MSVC" OFF)
20 20
21option(ENABLE_QT "Enable the Qt frontend" ON) 21option(ENABLE_QT "Enable the Qt frontend" ON)
22option(ENABLE_QT6 "Allow usage of Qt6 to be attempted" OFF)
23set(QT6_LOCATION "" CACHE PATH "Additional Location to search for Qt6 libraries like C:/Qt/6.3.1/msvc2019_64/")
24
22option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF) 25option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
23CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF) 26CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" "${MSVC}" "ENABLE_QT" OFF)
24 27
@@ -28,6 +31,8 @@ option(YUZU_USE_BUNDLED_LIBUSB "Compile bundled libusb" OFF)
28 31
29option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" "${WIN32}") 32option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" "${WIN32}")
30 33
34option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF)
35
31option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) 36option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF)
32 37
33option(ENABLE_CUBEB "Enables the cubeb audio backend" ON) 38option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
@@ -213,128 +218,166 @@ if (MINGW)
213 find_library(MSWSOCK_LIBRARY mswsock REQUIRED) 218 find_library(MSWSOCK_LIBRARY mswsock REQUIRED)
214endif() 219endif()
215 220
221# Please consider this as a stub
222if(ENABLE_QT6 AND Qt6_LOCATION)
223 list(APPEND CMAKE_PREFIX_PATH "${Qt6_LOCATION}")
224endif()
225
226function(set_yuzu_qt_components)
227 # Best practice is to ask for all components at once, so they are from the same version
228 set(YUZU_QT_COMPONENTS2 Core Widgets Concurrent)
229 if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
230 list(APPEND YUZU_QT_COMPONENTS2 DBus)
231 endif()
232 if (YUZU_USE_QT_MULTIMEDIA)
233 list(APPEND YUZU_QT_COMPONENTS2 Multimedia)
234 endif()
235 if (YUZU_USE_QT_WEB_ENGINE)
236 list(APPEND YUZU_QT_COMPONENTS2 WebEngineCore WebEngineWidgets)
237 endif()
238 if (ENABLE_QT_TRANSLATION)
239 list(APPEND YUZU_QT_COMPONENTS2 LinguistTools)
240 endif()
241 set(YUZU_QT_COMPONENTS ${YUZU_QT_COMPONENTS2} PARENT_SCOPE)
242endfunction(set_yuzu_qt_components)
243
216# Qt5 requires that we find components, so it doesn't fit our pretty little find package function 244# Qt5 requires that we find components, so it doesn't fit our pretty little find package function
217if(ENABLE_QT) 245if(ENABLE_QT)
218 set(QT_VERSION 5.15) 246 set(QT_VERSION 5.15)
247 # These are used to specify minimum versions
248 set(QT5_VERSION 5.15)
249 set(QT6_VERSION 6.3.1)
219 250
220 # Check for system Qt on Linux, fallback to bundled Qt 251 set_yuzu_qt_components()
221 if (UNIX AND NOT APPLE) 252 if (ENABLE_QT6)
222 if (NOT YUZU_USE_BUNDLED_QT) 253 find_package(Qt6 ${QT6_VERSION} COMPONENTS ${YUZU_QT_COMPONENTS})
223 find_package(Qt5 ${QT_VERSION} COMPONENTS Widgets DBus Multimedia) 254 endif()
224 endif() 255 if (Qt6_FOUND)
225 if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT)) 256 message(STATUS "yuzu/CMakeLists.txt: Qt6Widgets_VERSION ${Qt6Widgets_VERSION}, setting QT_VERSION")
226 # Check for dependencies, then enable bundled Qt download 257 set(QT_VERSION ${Qt6Widgets_VERSION})
227 258 set(QT_MAJOR_VERSION 6)
228 # Check that the system GLIBCXX version is compatible 259 # Qt6 sets cxx_std_17 and we need to undo that
229 find_program(OBJDUMP objdump) 260 set_target_properties(Qt6::Platform PROPERTIES INTERFACE_COMPILE_FEATURES "")
230 if ("${OBJDUMP}" STREQUAL "OBJDUMP-NOTFOUND") 261 else()
231 message(FATAL_ERROR "Required program `objdump` not found.") 262 message(STATUS "yuzu/CMakeLists.txt: Qt6 not found/not selected, trying for Qt5")
232 endif() 263 # When Qt6 partially found, need this set to use Qt5 when not specifying version
233 find_library(LIBSTDCXX libstdc++.so.6) 264 set(QT_DEFAULT_MAJOR_VERSION 5)
234 execute_process( 265 set(QT_MAJOR_VERSION 5)
235 COMMAND 266
236 ${OBJDUMP} -T ${LIBSTDCXX} 267 set(YUZU_USE_QT_MULTIMEDIA ON)
237 COMMAND 268 # Check for system Qt on Linux, fallback to bundled Qt
238 grep GLIBCXX_3.4.28 269 if (UNIX AND NOT APPLE)
239 COMMAND 270 if (NOT YUZU_USE_BUNDLED_QT)
240 sed "s/[0-9a-f]*.* //" 271 find_package(Qt5 ${QT5_VERSION} COMPONENTS Widgets DBus Multimedia)
241 COMMAND
242 sed "s/ .*//"
243 COMMAND
244 sort -u
245 OUTPUT_VARIABLE
246 GLIBCXX_MET
247 )
248 if (NOT GLIBCXX_MET)
249 message(FATAL_ERROR "Qt too old or not found, and bundled Qt package is not \
250 compatible with this system. Either install Qt ${QT_VERSION}, or provide the path \
251 to Qt by setting the variable Qt5_ROOT.")
252 endif() 272 endif()
273 if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND (NOT Qt5_FOUND OR YUZU_USE_BUNDLED_QT))
274 # Check for dependencies, then enable bundled Qt download
253 275
254 # Check for headers 276 # Check that the system GLIBCXX version is compatible
255 find_package(PkgConfig REQUIRED) 277 find_program(OBJDUMP objdump)
256 pkg_check_modules(QT_DEP_GLU QUIET glu>=9.0.0) 278 if (NOT OBJDUMP)
257 if (NOT QT_DEP_GLU_FOUND) 279 message(FATAL_ERROR "Required program `objdump` not found.")
258 message(FATAL_ERROR "Qt bundled pacakge dependency `glu` not found. \ 280 endif()
259 Perhaps `libglu1-mesa-dev` needs to be installed?") 281 find_library(LIBSTDCXX libstdc++.so.6)
260 endif() 282 execute_process(
261 pkg_check_modules(QT_DEP_MESA QUIET dri>=20.0.8) 283 COMMAND
262 if (NOT QT_DEP_MESA_FOUND) 284 ${OBJDUMP} -T ${LIBSTDCXX}
263 message(FATAL_ERROR "Qt bundled pacakge dependency `dri` not found. \ 285 COMMAND
264 Perhaps `mesa-common-dev` needs to be installed?") 286 grep GLIBCXX_3.4.28
265 endif() 287 COMMAND
288 sed "s/[0-9a-f]*.* //"
289 COMMAND
290 sed "s/ .*//"
291 COMMAND
292 sort -u
293 OUTPUT_VARIABLE
294 GLIBCXX_MET
295 )
296 if (NOT GLIBCXX_MET)
297 message(FATAL_ERROR "Qt too old or not found, and bundled Qt package is not \
298 compatible with this system. Either install Qt ${QT_VERSION}, or provide the path \
299 to Qt by setting the variable Qt5_ROOT.")
300 endif()
266 301
267 # Check for X libraries 302 # Check for headers
268 set(BUNDLED_QT_REQUIREMENTS 303 find_package(PkgConfig REQUIRED)
269 libxcb-icccm.so.4 304 pkg_check_modules(QT_DEP_GLU QUIET glu>=9.0.0)
270 libxcb-image.so.0 305 if (NOT QT_DEP_GLU_FOUND)
271 libxcb-keysyms.so.1 306 message(FATAL_ERROR "Qt bundled pacakge dependency `glu` not found. \
272 libxcb-randr.so.0 307 Perhaps `libglu1-mesa-dev` needs to be installed?")
273 libxcb-render-util.so.0 308 endif()
274 libxcb-render.so.0 309 pkg_check_modules(QT_DEP_MESA QUIET dri>=20.0.8)
275 libxcb-shape.so.0 310 if (NOT QT_DEP_MESA_FOUND)
276 libxcb-shm.so.0 311 message(FATAL_ERROR "Qt bundled pacakge dependency `dri` not found. \
277 libxcb-sync.so.1 312 Perhaps `mesa-common-dev` needs to be installed?")
278 libxcb-xfixes.so.0
279 libxcb-xinerama.so.0
280 libxcb-xkb.so.1
281 libxcb.so.1
282 libxkbcommon-x11.so.0
283 libxkbcommon.so.0
284 )
285 set(UNRESOLVED_QT_DEPS "")
286 foreach (REQUIREMENT ${BUNDLED_QT_REQUIREMENTS})
287 find_library(BUNDLED_QT_${REQUIREMENT} ${REQUIREMENT})
288 if ("${BUNDLED_QT_${REQUIREMENT}}" STREQUAL "BUNDLED_QT_${REQUIREMENT}-NOTFOUND")
289 set(UNRESOLVED_QT_DEPS ${UNRESOLVED_QT_DEPS} ${REQUIREMENT})
290 endif() 313 endif()
291 unset(BUNDLED_QT_${REQUIREMENT})
292 endforeach()
293 unset(BUNDLED_QT_REQUIREMENTS)
294 314
295 if (NOT "${UNRESOLVED_QT_DEPS}" STREQUAL "") 315 # Check for X libraries
296 message(FATAL_ERROR "Bundled Qt package missing required dependencies: ${UNRESOLVED_QT_DEPS}") 316 set(BUNDLED_QT_REQUIREMENTS
297 endif() 317 libxcb-icccm.so.4
318 libxcb-image.so.0
319 libxcb-keysyms.so.1
320 libxcb-randr.so.0
321 libxcb-render-util.so.0
322 libxcb-render.so.0
323 libxcb-shape.so.0
324 libxcb-shm.so.0
325 libxcb-sync.so.1
326 libxcb-xfixes.so.0
327 libxcb-xinerama.so.0
328 libxcb-xkb.so.1
329 libxcb.so.1
330 libxkbcommon-x11.so.0
331 libxkbcommon.so.0
332 )
333 set(UNRESOLVED_QT_DEPS "")
334 foreach (REQUIREMENT ${BUNDLED_QT_REQUIREMENTS})
335 find_library(BUNDLED_QT_${REQUIREMENT} ${REQUIREMENT})
336 if (NOT BUNDLED_QT_${REQUIREMENT})
337 set(UNRESOLVED_QT_DEPS ${UNRESOLVED_QT_DEPS} ${REQUIREMENT})
338 endif()
339 unset(BUNDLED_QT_${REQUIREMENT})
340 endforeach()
341 unset(BUNDLED_QT_REQUIREMENTS)
342
343 if (NOT "${UNRESOLVED_QT_DEPS}" STREQUAL "")
344 message(FATAL_ERROR "Bundled Qt package missing required dependencies: ${UNRESOLVED_QT_DEPS}")
345 endif()
298 346
299 set(YUZU_USE_BUNDLED_QT ON CACHE BOOL "Download bundled Qt" FORCE) 347 set(YUZU_USE_BUNDLED_QT ON CACHE BOOL "Download bundled Qt" FORCE)
300 endif() 348 endif()
301 if (YUZU_USE_BUNDLED_QT) 349 if (YUZU_USE_BUNDLED_QT)
302 # Binary package currently does not support Qt webengine, so make sure it's disabled 350 # Binary package currently does not support Qt webengine, so make sure it's disabled
303 set(YUZU_USE_QT_WEB_ENGINE OFF CACHE BOOL "Use Qt Webengine" FORCE) 351 set(YUZU_USE_QT_WEB_ENGINE OFF CACHE BOOL "Use Qt Webengine" FORCE)
352 endif()
304 endif() 353 endif()
305 endif()
306 354
307 set(YUZU_QT_NO_CMAKE_SYSTEM_PATH) 355 set(YUZU_QT_NO_CMAKE_SYSTEM_PATH)
308 356
309 if(YUZU_USE_BUNDLED_QT) 357 if(YUZU_USE_BUNDLED_QT)
310 if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND ARCHITECTURE_x86_64) 358 if ((MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1940) AND ARCHITECTURE_x86_64)
311 set(QT_BUILD qt-5.15.2-msvc2019_64) 359 set(QT_BUILD qt-5.15.2-msvc2019_64)
312 elseif ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") AND NOT MINGW AND ARCHITECTURE_x86_64) 360 elseif ((${CMAKE_SYSTEM_NAME} STREQUAL "Linux") AND NOT MINGW AND ARCHITECTURE_x86_64)
313 set(QT_BUILD qt5_5_15_2) 361 set(QT_BUILD qt5_5_15_2)
314 else() 362 else()
315 message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable YUZU_USE_BUNDLED_QT and provide your own.") 363 message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable YUZU_USE_BUNDLED_QT and provide your own.")
316 endif() 364 endif()
317 365
318 if (DEFINED QT_BUILD) 366 if (DEFINED QT_BUILD)
319 download_bundled_external("qt/" ${QT_BUILD} QT_PREFIX) 367 download_bundled_external("qt/" ${QT_BUILD} QT_PREFIX)
320 endif() 368 endif()
321 369
322 set(QT_PREFIX_HINT HINTS "${QT_PREFIX}") 370 set(QT_PREFIX_HINT HINTS "${QT_PREFIX}")
323 371
324 set(YUZU_QT_NO_CMAKE_SYSTEM_PATH "NO_CMAKE_SYSTEM_PATH") 372 set(YUZU_QT_NO_CMAKE_SYSTEM_PATH "NO_CMAKE_SYSTEM_PATH")
325 endif() 373 # Binary package for Qt5 has Qt Multimedia
326 if (UNIX AND NOT APPLE AND YUZU_USE_BUNDLED_QT) 374 set(YUZU_USE_QT_MULTIMEDIA ON CACHE BOOL "Use Qt Multimedia" FORCE)
327 find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent Multimedia DBus ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH}) 375 endif()
328 else()
329 find_package(Qt5 ${QT_VERSION} REQUIRED COMPONENTS Widgets Concurrent Multimedia ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH})
330 endif()
331 if (YUZU_USE_QT_WEB_ENGINE)
332 find_package(Qt5 REQUIRED COMPONENTS WebEngineCore WebEngineWidgets)
333 endif()
334 376
335 if (ENABLE_QT_TRANSLATION) 377 set_yuzu_qt_components()
336 find_package(Qt5 REQUIRED COMPONENTS LinguistTools ${QT_PREFIX_HINT}) 378 find_package(Qt5 ${QT5_VERSION} COMPONENTS ${YUZU_QT_COMPONENTS} ${QT_PREFIX_HINT} ${YUZU_QT_NO_CMAKE_SYSTEM_PATH})
337 endif() 379 endif()
380
338endif() 381endif()
339 382
340# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the yuzu_find_package 383# find SDL2 exports a bunch of variables that are needed, so its easier to do this outside of the yuzu_find_package
diff --git a/CMakeModules/CopyYuzuQt5Deps.cmake b/CMakeModules/CopyYuzuQt5Deps.cmake
index a353ddbb7..ab56de444 100644
--- a/CMakeModules/CopyYuzuQt5Deps.cmake
+++ b/CMakeModules/CopyYuzuQt5Deps.cmake
@@ -27,10 +27,13 @@ function(copy_yuzu_Qt5_deps target_dir)
27 Qt5Core$<$<CONFIG:Debug>:d>.* 27 Qt5Core$<$<CONFIG:Debug>:d>.*
28 Qt5Gui$<$<CONFIG:Debug>:d>.* 28 Qt5Gui$<$<CONFIG:Debug>:d>.*
29 Qt5Widgets$<$<CONFIG:Debug>:d>.* 29 Qt5Widgets$<$<CONFIG:Debug>:d>.*
30 Qt5Multimedia$<$<CONFIG:Debug>:d>.*
31 Qt5Network$<$<CONFIG:Debug>:d>.* 30 Qt5Network$<$<CONFIG:Debug>:d>.*
32 ) 31 )
33 32 if (YUZU_USE_QT_MULTIMEDIA)
33 windows_copy_files(${target_dir} ${Qt5_DLL_DIR} ${DLL_DEST}
34 Qt5Multimedia$<$<CONFIG:Debug>:d>.*
35 )
36 endif()
34 if (YUZU_USE_QT_WEB_ENGINE) 37 if (YUZU_USE_QT_WEB_ENGINE)
35 windows_copy_files(${target_dir} ${Qt5_DLL_DIR} ${DLL_DEST} 38 windows_copy_files(${target_dir} ${Qt5_DLL_DIR} ${DLL_DEST}
36 Qt5Network$<$<CONFIG:Debug>:d>.* 39 Qt5Network$<$<CONFIG:Debug>:d>.*
diff --git a/src/common/cache_management.cpp b/src/common/cache_management.cpp
index 57810b76a..ed353828a 100644
--- a/src/common/cache_management.cpp
+++ b/src/common/cache_management.cpp
@@ -1,11 +1,10 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <cstdint>
4#include <cstring> 5#include <cstring>
5 6
6#include "alignment.h" 7#include "common/cache_management.h"
7#include "cache_management.h"
8#include "common_types.h"
9 8
10namespace Common { 9namespace Common {
11 10
diff --git a/src/common/cache_management.h b/src/common/cache_management.h
index e467b87e4..038323e95 100644
--- a/src/common/cache_management.h
+++ b/src/common/cache_management.h
@@ -3,7 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include "stdlib.h" 6#include <cstddef>
7 7
8namespace Common { 8namespace Common {
9 9
diff --git a/src/common/input.h b/src/common/input.h
index cb30b7254..449e0193f 100644
--- a/src/common/input.h
+++ b/src/common/input.h
@@ -383,6 +383,16 @@ void RegisterFactory(const std::string& name, std::shared_ptr<Factory<InputDevic
383 } 383 }
384} 384}
385 385
386inline void RegisterInputFactory(const std::string& name,
387 std::shared_ptr<Factory<InputDevice>> factory) {
388 RegisterFactory<InputDevice>(name, std::move(factory));
389}
390
391inline void RegisterOutputFactory(const std::string& name,
392 std::shared_ptr<Factory<OutputDevice>> factory) {
393 RegisterFactory<OutputDevice>(name, std::move(factory));
394}
395
386/** 396/**
387 * Unregisters an input device factory. 397 * Unregisters an input device factory.
388 * @tparam InputDeviceType the type of input devices the factory can create 398 * @tparam InputDeviceType the type of input devices the factory can create
@@ -395,6 +405,14 @@ void UnregisterFactory(const std::string& name) {
395 } 405 }
396} 406}
397 407
408inline void UnregisterInputFactory(const std::string& name) {
409 UnregisterFactory<InputDevice>(name);
410}
411
412inline void UnregisterOutputFactory(const std::string& name) {
413 UnregisterFactory<OutputDevice>(name);
414}
415
398/** 416/**
399 * Create an input device from given paramters. 417 * Create an input device from given paramters.
400 * @tparam InputDeviceType the type of input devices to create 418 * @tparam InputDeviceType the type of input devices to create
@@ -416,13 +434,21 @@ std::unique_ptr<InputDeviceType> CreateDeviceFromString(const std::string& param
416 return pair->second->Create(package); 434 return pair->second->Create(package);
417} 435}
418 436
437inline std::unique_ptr<InputDevice> CreateInputDeviceFromString(const std::string& params) {
438 return CreateDeviceFromString<InputDevice>(params);
439}
440
441inline std::unique_ptr<OutputDevice> CreateOutputDeviceFromString(const std::string& params) {
442 return CreateDeviceFromString<OutputDevice>(params);
443}
444
419/** 445/**
420 * Create an input device from given paramters. 446 * Create an input device from given parameters.
421 * @tparam InputDeviceType the type of input devices to create 447 * @tparam InputDeviceType the type of input devices to create
422 * @param A ParamPackage that contains all parameters for creating the device 448 * @param package A ParamPackage that contains all parameters for creating the device
423 */ 449 */
424template <typename InputDeviceType> 450template <typename InputDeviceType>
425std::unique_ptr<InputDeviceType> CreateDevice(const Common::ParamPackage package) { 451std::unique_ptr<InputDeviceType> CreateDevice(const ParamPackage& package) {
426 const std::string engine = package.Get("engine", "null"); 452 const std::string engine = package.Get("engine", "null");
427 const auto& factory_list = Impl::FactoryList<InputDeviceType>::list; 453 const auto& factory_list = Impl::FactoryList<InputDeviceType>::list;
428 const auto pair = factory_list.find(engine); 454 const auto pair = factory_list.find(engine);
@@ -435,4 +461,12 @@ std::unique_ptr<InputDeviceType> CreateDevice(const Common::ParamPackage package
435 return pair->second->Create(package); 461 return pair->second->Create(package);
436} 462}
437 463
464inline std::unique_ptr<InputDevice> CreateInputDevice(const ParamPackage& package) {
465 return CreateDevice<InputDevice>(package);
466}
467
468inline std::unique_ptr<OutputDevice> CreateOutputDevice(const ParamPackage& package) {
469 return CreateDevice<OutputDevice>(package);
470}
471
438} // namespace Common::Input 472} // namespace Common::Input
diff --git a/src/core/hid/emulated_console.cpp b/src/core/hid/emulated_console.cpp
index fb7e5802a..b6c8cc58d 100644
--- a/src/core/hid/emulated_console.cpp
+++ b/src/core/hid/emulated_console.cpp
@@ -68,7 +68,7 @@ void EmulatedConsole::ReloadInput() {
68 // If you load any device here add the equivalent to the UnloadInput() function 68 // If you load any device here add the equivalent to the UnloadInput() function
69 SetTouchParams(); 69 SetTouchParams();
70 70
71 motion_devices = Common::Input::CreateDevice<Common::Input::InputDevice>(motion_params); 71 motion_devices = Common::Input::CreateInputDevice(motion_params);
72 if (motion_devices) { 72 if (motion_devices) {
73 motion_devices->SetCallback({ 73 motion_devices->SetCallback({
74 .on_change = 74 .on_change =
@@ -79,7 +79,7 @@ void EmulatedConsole::ReloadInput() {
79 // Unique index for identifying touch device source 79 // Unique index for identifying touch device source
80 std::size_t index = 0; 80 std::size_t index = 0;
81 for (auto& touch_device : touch_devices) { 81 for (auto& touch_device : touch_devices) {
82 touch_device = Common::Input::CreateDevice<Common::Input::InputDevice>(touch_params[index]); 82 touch_device = Common::Input::CreateInputDevice(touch_params[index]);
83 if (!touch_device) { 83 if (!touch_device) {
84 continue; 84 continue;
85 } 85 }
diff --git a/src/core/hid/emulated_controller.cpp b/src/core/hid/emulated_controller.cpp
index ec1364452..c96d9eef3 100644
--- a/src/core/hid/emulated_controller.cpp
+++ b/src/core/hid/emulated_controller.cpp
@@ -1,6 +1,8 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include <algorithm>
5
4#include "common/thread.h" 6#include "common/thread.h"
5#include "core/hid/emulated_controller.h" 7#include "core/hid/emulated_controller.h"
6#include "core/hid/input_converter.h" 8#include "core/hid/input_converter.h"
@@ -144,29 +146,23 @@ void EmulatedController::LoadDevices() {
144 146
145 LoadTASParams(); 147 LoadTASParams();
146 148
147 std::transform(button_params.begin() + Settings::NativeButton::BUTTON_HID_BEGIN, 149 std::ranges::transform(button_params, button_devices.begin(), Common::Input::CreateInputDevice);
148 button_params.begin() + Settings::NativeButton::BUTTON_NS_END, 150 std::ranges::transform(stick_params, stick_devices.begin(), Common::Input::CreateInputDevice);
149 button_devices.begin(), Common::Input::CreateDevice<Common::Input::InputDevice>); 151 std::ranges::transform(motion_params, motion_devices.begin(), Common::Input::CreateInputDevice);
150 std::transform(stick_params.begin() + Settings::NativeAnalog::STICK_HID_BEGIN, 152 std::ranges::transform(trigger_params, trigger_devices.begin(),
151 stick_params.begin() + Settings::NativeAnalog::STICK_HID_END, 153 Common::Input::CreateInputDevice);
152 stick_devices.begin(), Common::Input::CreateDevice<Common::Input::InputDevice>); 154 std::ranges::transform(battery_params, battery_devices.begin(),
153 std::transform(motion_params.begin() + Settings::NativeMotion::MOTION_HID_BEGIN, 155 Common::Input::CreateInputDevice);
154 motion_params.begin() + Settings::NativeMotion::MOTION_HID_END, 156 camera_devices = Common::Input::CreateInputDevice(camera_params);
155 motion_devices.begin(), Common::Input::CreateDevice<Common::Input::InputDevice>); 157 nfc_devices = Common::Input::CreateInputDevice(nfc_params);
156 std::transform(trigger_params.begin(), trigger_params.end(), trigger_devices.begin(), 158 std::ranges::transform(output_params, output_devices.begin(),
157 Common::Input::CreateDevice<Common::Input::InputDevice>); 159 Common::Input::CreateOutputDevice);
158 std::transform(battery_params.begin(), battery_params.end(), battery_devices.begin(),
159 Common::Input::CreateDevice<Common::Input::InputDevice>);
160 camera_devices = Common::Input::CreateDevice<Common::Input::InputDevice>(camera_params);
161 nfc_devices = Common::Input::CreateDevice<Common::Input::InputDevice>(nfc_params);
162 std::transform(output_params.begin(), output_params.end(), output_devices.begin(),
163 Common::Input::CreateDevice<Common::Input::OutputDevice>);
164 160
165 // Initialize TAS devices 161 // Initialize TAS devices
166 std::transform(tas_button_params.begin(), tas_button_params.end(), tas_button_devices.begin(), 162 std::ranges::transform(tas_button_params, tas_button_devices.begin(),
167 Common::Input::CreateDevice<Common::Input::InputDevice>); 163 Common::Input::CreateInputDevice);
168 std::transform(tas_stick_params.begin(), tas_stick_params.end(), tas_stick_devices.begin(), 164 std::ranges::transform(tas_stick_params, tas_stick_devices.begin(),
169 Common::Input::CreateDevice<Common::Input::InputDevice>); 165 Common::Input::CreateInputDevice);
170} 166}
171 167
172void EmulatedController::LoadTASParams() { 168void EmulatedController::LoadTASParams() {
diff --git a/src/core/hid/emulated_devices.cpp b/src/core/hid/emulated_devices.cpp
index 8d367b546..e421828d2 100644
--- a/src/core/hid/emulated_devices.cpp
+++ b/src/core/hid/emulated_devices.cpp
@@ -25,12 +25,12 @@ void EmulatedDevices::ReloadInput() {
25 Common::ParamPackage mouse_params; 25 Common::ParamPackage mouse_params;
26 mouse_params.Set("engine", "mouse"); 26 mouse_params.Set("engine", "mouse");
27 mouse_params.Set("button", static_cast<int>(key_index)); 27 mouse_params.Set("button", static_cast<int>(key_index));
28 mouse_device = Common::Input::CreateDevice<Common::Input::InputDevice>(mouse_params); 28 mouse_device = Common::Input::CreateInputDevice(mouse_params);
29 key_index++; 29 key_index++;
30 } 30 }
31 31
32 mouse_stick_device = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>( 32 mouse_stick_device =
33 "engine:mouse,axis_x:0,axis_y:1"); 33 Common::Input::CreateInputDeviceFromString("engine:mouse,axis_x:0,axis_y:1");
34 34
35 // First two axis are reserved for mouse position 35 // First two axis are reserved for mouse position
36 key_index = 2; 36 key_index = 2;
@@ -38,7 +38,7 @@ void EmulatedDevices::ReloadInput() {
38 Common::ParamPackage mouse_params; 38 Common::ParamPackage mouse_params;
39 mouse_params.Set("engine", "mouse"); 39 mouse_params.Set("engine", "mouse");
40 mouse_params.Set("axis", static_cast<int>(key_index)); 40 mouse_params.Set("axis", static_cast<int>(key_index));
41 mouse_device = Common::Input::CreateDevice<Common::Input::InputDevice>(mouse_params); 41 mouse_device = Common::Input::CreateInputDevice(mouse_params);
42 key_index++; 42 key_index++;
43 } 43 }
44 44
@@ -50,7 +50,7 @@ void EmulatedDevices::ReloadInput() {
50 keyboard_params.Set("button", static_cast<int>(key_index)); 50 keyboard_params.Set("button", static_cast<int>(key_index));
51 keyboard_params.Set("port", 1); 51 keyboard_params.Set("port", 1);
52 keyboard_params.Set("pad", 0); 52 keyboard_params.Set("pad", 0);
53 keyboard_device = Common::Input::CreateDevice<Common::Input::InputDevice>(keyboard_params); 53 keyboard_device = Common::Input::CreateInputDevice(keyboard_params);
54 key_index++; 54 key_index++;
55 } 55 }
56 56
@@ -62,11 +62,11 @@ void EmulatedDevices::ReloadInput() {
62 keyboard_params.Set("button", static_cast<int>(key_index)); 62 keyboard_params.Set("button", static_cast<int>(key_index));
63 keyboard_params.Set("port", 1); 63 keyboard_params.Set("port", 1);
64 keyboard_params.Set("pad", 1); 64 keyboard_params.Set("pad", 1);
65 keyboard_device = Common::Input::CreateDevice<Common::Input::InputDevice>(keyboard_params); 65 keyboard_device = Common::Input::CreateInputDevice(keyboard_params);
66 key_index++; 66 key_index++;
67 } 67 }
68 68
69 ring_analog_device = Common::Input::CreateDevice<Common::Input::InputDevice>(ring_params); 69 ring_analog_device = Common::Input::CreateInputDevice(ring_params);
70 70
71 for (std::size_t index = 0; index < mouse_button_devices.size(); ++index) { 71 for (std::size_t index = 0; index < mouse_button_devices.size(); ++index) {
72 if (!mouse_button_devices[index]) { 72 if (!mouse_button_devices[index]) {
@@ -145,6 +145,7 @@ void EmulatedDevices::UnloadInput() {
145 for (auto& button : keyboard_modifier_devices) { 145 for (auto& button : keyboard_modifier_devices) {
146 button.reset(); 146 button.reset();
147 } 147 }
148 ring_analog_device.reset();
148} 149}
149 150
150void EmulatedDevices::EnableConfiguration() { 151void EmulatedDevices::EnableConfiguration() {
diff --git a/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp b/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp
index eda2041a0..aba51d280 100644
--- a/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp
+++ b/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp
@@ -28,13 +28,15 @@ SyncpointManager::SyncpointManager(Tegra::Host1x::Host1x& host1x_) : host1x{host
28SyncpointManager::~SyncpointManager() = default; 28SyncpointManager::~SyncpointManager() = default;
29 29
30u32 SyncpointManager::ReserveSyncpoint(u32 id, bool client_managed) { 30u32 SyncpointManager::ReserveSyncpoint(u32 id, bool client_managed) {
31 if (syncpoints.at(id).reserved) { 31 auto& syncpoint = syncpoints.at(id);
32
33 if (syncpoint.reserved) {
32 ASSERT_MSG(false, "Requested syncpoint is in use"); 34 ASSERT_MSG(false, "Requested syncpoint is in use");
33 return 0; 35 return 0;
34 } 36 }
35 37
36 syncpoints.at(id).reserved = true; 38 syncpoint.reserved = true;
37 syncpoints.at(id).interface_managed = client_managed; 39 syncpoint.interface_managed = client_managed;
38 40
39 return id; 41 return id;
40} 42}
@@ -56,11 +58,12 @@ u32 SyncpointManager::AllocateSyncpoint(bool client_managed) {
56 58
57void SyncpointManager::FreeSyncpoint(u32 id) { 59void SyncpointManager::FreeSyncpoint(u32 id) {
58 std::lock_guard lock(reservation_lock); 60 std::lock_guard lock(reservation_lock);
59 ASSERT(syncpoints.at(id).reserved); 61 auto& syncpoint = syncpoints.at(id);
60 syncpoints.at(id).reserved = false; 62 ASSERT(syncpoint.reserved);
63 syncpoint.reserved = false;
61} 64}
62 65
63bool SyncpointManager::IsSyncpointAllocated(u32 id) { 66bool SyncpointManager::IsSyncpointAllocated(u32 id) const {
64 return (id <= SyncpointCount) && syncpoints[id].reserved; 67 return (id <= SyncpointCount) && syncpoints[id].reserved;
65} 68}
66 69
@@ -69,7 +72,7 @@ bool SyncpointManager::HasSyncpointExpired(u32 id, u32 threshold) const {
69 72
70 if (!syncpoint.reserved) { 73 if (!syncpoint.reserved) {
71 ASSERT(false); 74 ASSERT(false);
72 return 0; 75 return false;
73 } 76 }
74 77
75 // If the interface manages counters then we don't keep track of the maximum value as it handles 78 // If the interface manages counters then we don't keep track of the maximum value as it handles
@@ -82,40 +85,51 @@ bool SyncpointManager::HasSyncpointExpired(u32 id, u32 threshold) const {
82} 85}
83 86
84u32 SyncpointManager::IncrementSyncpointMaxExt(u32 id, u32 amount) { 87u32 SyncpointManager::IncrementSyncpointMaxExt(u32 id, u32 amount) {
85 if (!syncpoints.at(id).reserved) { 88 auto& syncpoint = syncpoints.at(id);
89
90 if (!syncpoint.reserved) {
86 ASSERT(false); 91 ASSERT(false);
87 return 0; 92 return 0;
88 } 93 }
89 94
90 return syncpoints.at(id).counter_max += amount; 95 return syncpoint.counter_max += amount;
91} 96}
92 97
93u32 SyncpointManager::ReadSyncpointMinValue(u32 id) { 98u32 SyncpointManager::ReadSyncpointMinValue(u32 id) {
94 if (!syncpoints.at(id).reserved) { 99 auto& syncpoint = syncpoints.at(id);
100
101 if (!syncpoint.reserved) {
95 ASSERT(false); 102 ASSERT(false);
96 return 0; 103 return 0;
97 } 104 }
98 105
99 return syncpoints.at(id).counter_min; 106 return syncpoint.counter_min;
100} 107}
101 108
102u32 SyncpointManager::UpdateMin(u32 id) { 109u32 SyncpointManager::UpdateMin(u32 id) {
103 if (!syncpoints.at(id).reserved) { 110 auto& syncpoint = syncpoints.at(id);
111
112 if (!syncpoint.reserved) {
104 ASSERT(false); 113 ASSERT(false);
105 return 0; 114 return 0;
106 } 115 }
107 116
108 syncpoints.at(id).counter_min = host1x.GetSyncpointManager().GetHostSyncpointValue(id); 117 syncpoint.counter_min = host1x.GetSyncpointManager().GetHostSyncpointValue(id);
109 return syncpoints.at(id).counter_min; 118 return syncpoint.counter_min;
110} 119}
111 120
112NvFence SyncpointManager::GetSyncpointFence(u32 id) { 121NvFence SyncpointManager::GetSyncpointFence(u32 id) {
113 if (!syncpoints.at(id).reserved) { 122 auto& syncpoint = syncpoints.at(id);
123
124 if (!syncpoint.reserved) {
114 ASSERT(false); 125 ASSERT(false);
115 return NvFence{}; 126 return NvFence{};
116 } 127 }
117 128
118 return {.id = static_cast<s32>(id), .value = syncpoints.at(id).counter_max}; 129 return {
130 .id = static_cast<s32>(id),
131 .value = syncpoint.counter_max,
132 };
119} 133}
120 134
121} // namespace Service::Nvidia::NvCore 135} // namespace Service::Nvidia::NvCore
diff --git a/src/core/hle/service/nvdrv/core/syncpoint_manager.h b/src/core/hle/service/nvdrv/core/syncpoint_manager.h
index b76ef9032..4f2cefae5 100644
--- a/src/core/hle/service/nvdrv/core/syncpoint_manager.h
+++ b/src/core/hle/service/nvdrv/core/syncpoint_manager.h
@@ -44,7 +44,7 @@ public:
44 /** 44 /**
45 * @brief Checks if the given syncpoint is both allocated and below the number of HW syncpoints 45 * @brief Checks if the given syncpoint is both allocated and below the number of HW syncpoints
46 */ 46 */
47 bool IsSyncpointAllocated(u32 id); 47 bool IsSyncpointAllocated(u32 id) const;
48 48
49 /** 49 /**
50 * @brief Finds a free syncpoint and reserves it 50 * @brief Finds a free syncpoint and reserves it
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 9f4c7c99a..6fc8565c0 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -55,48 +55,40 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
55Module::Module(Core::System& system) 55Module::Module(Core::System& system)
56 : container{system.Host1x()}, service_context{system, "nvdrv"}, events_interface{*this} { 56 : container{system.Host1x()}, service_context{system, "nvdrv"}, events_interface{*this} {
57 builders["/dev/nvhost-as-gpu"] = [this, &system](DeviceFD fd) { 57 builders["/dev/nvhost-as-gpu"] = [this, &system](DeviceFD fd) {
58 std::shared_ptr<Devices::nvdevice> device = 58 auto device = std::make_shared<Devices::nvhost_as_gpu>(system, *this, container);
59 std::make_shared<Devices::nvhost_as_gpu>(system, *this, container); 59 return open_files.emplace(fd, std::move(device)).first;
60 return open_files.emplace(fd, device).first;
61 }; 60 };
62 builders["/dev/nvhost-gpu"] = [this, &system](DeviceFD fd) { 61 builders["/dev/nvhost-gpu"] = [this, &system](DeviceFD fd) {
63 std::shared_ptr<Devices::nvdevice> device = 62 auto device = std::make_shared<Devices::nvhost_gpu>(system, events_interface, container);
64 std::make_shared<Devices::nvhost_gpu>(system, events_interface, container); 63 return open_files.emplace(fd, std::move(device)).first;
65 return open_files.emplace(fd, device).first;
66 }; 64 };
67 builders["/dev/nvhost-ctrl-gpu"] = [this, &system](DeviceFD fd) { 65 builders["/dev/nvhost-ctrl-gpu"] = [this, &system](DeviceFD fd) {
68 std::shared_ptr<Devices::nvdevice> device = 66 auto device = std::make_shared<Devices::nvhost_ctrl_gpu>(system, events_interface);
69 std::make_shared<Devices::nvhost_ctrl_gpu>(system, events_interface); 67 return open_files.emplace(fd, std::move(device)).first;
70 return open_files.emplace(fd, device).first;
71 }; 68 };
72 builders["/dev/nvmap"] = [this, &system](DeviceFD fd) { 69 builders["/dev/nvmap"] = [this, &system](DeviceFD fd) {
73 std::shared_ptr<Devices::nvdevice> device = 70 auto device = std::make_shared<Devices::nvmap>(system, container);
74 std::make_shared<Devices::nvmap>(system, container); 71 return open_files.emplace(fd, std::move(device)).first;
75 return open_files.emplace(fd, device).first;
76 }; 72 };
77 builders["/dev/nvdisp_disp0"] = [this, &system](DeviceFD fd) { 73 builders["/dev/nvdisp_disp0"] = [this, &system](DeviceFD fd) {
78 std::shared_ptr<Devices::nvdevice> device = 74 auto device = std::make_shared<Devices::nvdisp_disp0>(system, container);
79 std::make_shared<Devices::nvdisp_disp0>(system, container); 75 return open_files.emplace(fd, std::move(device)).first;
80 return open_files.emplace(fd, device).first;
81 }; 76 };
82 builders["/dev/nvhost-ctrl"] = [this, &system](DeviceFD fd) { 77 builders["/dev/nvhost-ctrl"] = [this, &system](DeviceFD fd) {
83 std::shared_ptr<Devices::nvdevice> device = 78 auto device = std::make_shared<Devices::nvhost_ctrl>(system, events_interface, container);
84 std::make_shared<Devices::nvhost_ctrl>(system, events_interface, container); 79 return open_files.emplace(fd, std::move(device)).first;
85 return open_files.emplace(fd, device).first;
86 }; 80 };
87 builders["/dev/nvhost-nvdec"] = [this, &system](DeviceFD fd) { 81 builders["/dev/nvhost-nvdec"] = [this, &system](DeviceFD fd) {
88 std::shared_ptr<Devices::nvdevice> device = 82 auto device = std::make_shared<Devices::nvhost_nvdec>(system, container);
89 std::make_shared<Devices::nvhost_nvdec>(system, container); 83 return open_files.emplace(fd, std::move(device)).first;
90 return open_files.emplace(fd, device).first;
91 }; 84 };
92 builders["/dev/nvhost-nvjpg"] = [this, &system](DeviceFD fd) { 85 builders["/dev/nvhost-nvjpg"] = [this, &system](DeviceFD fd) {
93 std::shared_ptr<Devices::nvdevice> device = std::make_shared<Devices::nvhost_nvjpg>(system); 86 auto device = std::make_shared<Devices::nvhost_nvjpg>(system);
94 return open_files.emplace(fd, device).first; 87 return open_files.emplace(fd, std::move(device)).first;
95 }; 88 };
96 builders["/dev/nvhost-vic"] = [this, &system](DeviceFD fd) { 89 builders["/dev/nvhost-vic"] = [this, &system](DeviceFD fd) {
97 std::shared_ptr<Devices::nvdevice> device = 90 auto device = std::make_shared<Devices::nvhost_vic>(system, container);
98 std::make_shared<Devices::nvhost_vic>(system, container); 91 return open_files.emplace(fd, std::move(device)).first;
99 return open_files.emplace(fd, device).first;
100 }; 92 };
101} 93}
102 94
diff --git a/src/core/hle/service/nvflinger/buffer_item_consumer.cpp b/src/core/hle/service/nvflinger/buffer_item_consumer.cpp
index 6d2c92a2c..152bb5bdf 100644
--- a/src/core/hle/service/nvflinger/buffer_item_consumer.cpp
+++ b/src/core/hle/service/nvflinger/buffer_item_consumer.cpp
@@ -39,7 +39,7 @@ Status BufferItemConsumer::AcquireBuffer(BufferItem* item, std::chrono::nanoseco
39 return Status::NoError; 39 return Status::NoError;
40} 40}
41 41
42Status BufferItemConsumer::ReleaseBuffer(const BufferItem& item, Fence& release_fence) { 42Status BufferItemConsumer::ReleaseBuffer(const BufferItem& item, const Fence& release_fence) {
43 std::scoped_lock lock{mutex}; 43 std::scoped_lock lock{mutex};
44 44
45 if (const auto status = AddReleaseFenceLocked(item.buf, item.graphic_buffer, release_fence); 45 if (const auto status = AddReleaseFenceLocked(item.buf, item.graphic_buffer, release_fence);
diff --git a/src/core/hle/service/nvflinger/buffer_item_consumer.h b/src/core/hle/service/nvflinger/buffer_item_consumer.h
index 69046233d..a5c655d9e 100644
--- a/src/core/hle/service/nvflinger/buffer_item_consumer.h
+++ b/src/core/hle/service/nvflinger/buffer_item_consumer.h
@@ -22,7 +22,7 @@ public:
22 explicit BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer); 22 explicit BufferItemConsumer(std::unique_ptr<BufferQueueConsumer> consumer);
23 Status AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when, 23 Status AcquireBuffer(BufferItem* item, std::chrono::nanoseconds present_when,
24 bool wait_for_fence = true); 24 bool wait_for_fence = true);
25 Status ReleaseBuffer(const BufferItem& item, Fence& release_fence); 25 Status ReleaseBuffer(const BufferItem& item, const Fence& release_fence);
26}; 26};
27 27
28} // namespace Service::android 28} // namespace Service::android
diff --git a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp b/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp
index 1ce67c771..0767e548d 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue_consumer.cpp
@@ -169,7 +169,7 @@ Status BufferQueueConsumer::Connect(std::shared_ptr<IConsumerListener> consumer_
169 return Status::NoInit; 169 return Status::NoInit;
170 } 170 }
171 171
172 core->consumer_listener = consumer_listener; 172 core->consumer_listener = std::move(consumer_listener);
173 core->consumer_controlled_by_app = controlled_by_app; 173 core->consumer_controlled_by_app = controlled_by_app;
174 174
175 return Status::NoError; 175 return Status::NoError;
diff --git a/src/core/hle/service/nvflinger/consumer_base.cpp b/src/core/hle/service/nvflinger/consumer_base.cpp
index 5b9995854..982531e2d 100644
--- a/src/core/hle/service/nvflinger/consumer_base.cpp
+++ b/src/core/hle/service/nvflinger/consumer_base.cpp
@@ -83,7 +83,7 @@ Status ConsumerBase::AcquireBufferLocked(BufferItem* item, std::chrono::nanoseco
83} 83}
84 84
85Status ConsumerBase::AddReleaseFenceLocked(s32 slot, 85Status ConsumerBase::AddReleaseFenceLocked(s32 slot,
86 const std::shared_ptr<GraphicBuffer> graphic_buffer, 86 const std::shared_ptr<GraphicBuffer>& graphic_buffer,
87 const Fence& fence) { 87 const Fence& fence) {
88 LOG_DEBUG(Service_NVFlinger, "slot={}", slot); 88 LOG_DEBUG(Service_NVFlinger, "slot={}", slot);
89 89
@@ -100,7 +100,7 @@ Status ConsumerBase::AddReleaseFenceLocked(s32 slot,
100} 100}
101 101
102Status ConsumerBase::ReleaseBufferLocked(s32 slot, 102Status ConsumerBase::ReleaseBufferLocked(s32 slot,
103 const std::shared_ptr<GraphicBuffer> graphic_buffer) { 103 const std::shared_ptr<GraphicBuffer>& graphic_buffer) {
104 // If consumer no longer tracks this graphic_buffer (we received a new 104 // If consumer no longer tracks this graphic_buffer (we received a new
105 // buffer on the same slot), the buffer producer is definitely no longer 105 // buffer on the same slot), the buffer producer is definitely no longer
106 // tracking it. 106 // tracking it.
@@ -121,7 +121,7 @@ Status ConsumerBase::ReleaseBufferLocked(s32 slot,
121} 121}
122 122
123bool ConsumerBase::StillTracking(s32 slot, 123bool ConsumerBase::StillTracking(s32 slot,
124 const std::shared_ptr<GraphicBuffer> graphic_buffer) const { 124 const std::shared_ptr<GraphicBuffer>& graphic_buffer) const {
125 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) { 125 if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
126 return false; 126 return false;
127 } 127 }
diff --git a/src/core/hle/service/nvflinger/consumer_base.h b/src/core/hle/service/nvflinger/consumer_base.h
index 90ba07f45..9a8a5f6bb 100644
--- a/src/core/hle/service/nvflinger/consumer_base.h
+++ b/src/core/hle/service/nvflinger/consumer_base.h
@@ -27,18 +27,18 @@ public:
27 27
28protected: 28protected:
29 explicit ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_); 29 explicit ConsumerBase(std::unique_ptr<BufferQueueConsumer> consumer_);
30 virtual ~ConsumerBase(); 30 ~ConsumerBase() override;
31 31
32 virtual void OnFrameAvailable(const BufferItem& item) override; 32 void OnFrameAvailable(const BufferItem& item) override;
33 virtual void OnFrameReplaced(const BufferItem& item) override; 33 void OnFrameReplaced(const BufferItem& item) override;
34 virtual void OnBuffersReleased() override; 34 void OnBuffersReleased() override;
35 virtual void OnSidebandStreamChanged() override; 35 void OnSidebandStreamChanged() override;
36 36
37 void FreeBufferLocked(s32 slot_index); 37 void FreeBufferLocked(s32 slot_index);
38 Status AcquireBufferLocked(BufferItem* item, std::chrono::nanoseconds present_when); 38 Status AcquireBufferLocked(BufferItem* item, std::chrono::nanoseconds present_when);
39 Status ReleaseBufferLocked(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer); 39 Status ReleaseBufferLocked(s32 slot, const std::shared_ptr<GraphicBuffer>& graphic_buffer);
40 bool StillTracking(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer) const; 40 bool StillTracking(s32 slot, const std::shared_ptr<GraphicBuffer>& graphic_buffer) const;
41 Status AddReleaseFenceLocked(s32 slot, const std::shared_ptr<GraphicBuffer> graphic_buffer, 41 Status AddReleaseFenceLocked(s32 slot, const std::shared_ptr<GraphicBuffer>& graphic_buffer,
42 const Fence& fence); 42 const Fence& fence);
43 43
44 struct Slot final { 44 struct Slot final {
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index c3af12c90..d1cbadde4 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -307,8 +307,7 @@ void NVFlinger::Compose() {
307 307
308 swap_interval = buffer.swap_interval; 308 swap_interval = buffer.swap_interval;
309 309
310 auto fence = android::Fence::NoFence(); 310 layer.GetConsumer().ReleaseBuffer(buffer, android::Fence::NoFence());
311 layer.GetConsumer().ReleaseBuffer(buffer, fence);
312 } 311 }
313} 312}
314 313
diff --git a/src/core/hle/service/nvflinger/producer_listener.h b/src/core/hle/service/nvflinger/producer_listener.h
index 1c4d5db0e..6bf8aaf1e 100644
--- a/src/core/hle/service/nvflinger/producer_listener.h
+++ b/src/core/hle/service/nvflinger/producer_listener.h
@@ -10,6 +10,7 @@ namespace Service::android {
10 10
11class IProducerListener { 11class IProducerListener {
12public: 12public:
13 virtual ~IProducerListener() = default;
13 virtual void OnBufferReleased() = 0; 14 virtual void OnBufferReleased() = 0;
14}; 15};
15 16
diff --git a/src/input_common/helpers/stick_from_buttons.cpp b/src/input_common/helpers/stick_from_buttons.cpp
index 536d413a5..82aa6ac2f 100644
--- a/src/input_common/helpers/stick_from_buttons.cpp
+++ b/src/input_common/helpers/stick_from_buttons.cpp
@@ -294,6 +294,15 @@ public:
294 } 294 }
295 295
296private: 296private:
297 static constexpr Common::Input::AnalogProperties properties{
298 .deadzone = 0.0f,
299 .range = 1.0f,
300 .threshold = 0.5f,
301 .offset = 0.0f,
302 .inverted = false,
303 .toggle = false,
304 };
305
297 Button up; 306 Button up;
298 Button down; 307 Button down;
299 Button left; 308 Button left;
@@ -311,23 +320,17 @@ private:
311 float last_x_axis_value{}; 320 float last_x_axis_value{};
312 float last_y_axis_value{}; 321 float last_y_axis_value{};
313 Common::Input::ButtonStatus modifier_status{}; 322 Common::Input::ButtonStatus modifier_status{};
314 const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false};
315 std::chrono::time_point<std::chrono::steady_clock> last_update; 323 std::chrono::time_point<std::chrono::steady_clock> last_update;
316}; 324};
317 325
318std::unique_ptr<Common::Input::InputDevice> StickFromButton::Create( 326std::unique_ptr<Common::Input::InputDevice> StickFromButton::Create(
319 const Common::ParamPackage& params) { 327 const Common::ParamPackage& params) {
320 const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); 328 const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize();
321 auto up = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>( 329 auto up = Common::Input::CreateInputDeviceFromString(params.Get("up", null_engine));
322 params.Get("up", null_engine)); 330 auto down = Common::Input::CreateInputDeviceFromString(params.Get("down", null_engine));
323 auto down = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>( 331 auto left = Common::Input::CreateInputDeviceFromString(params.Get("left", null_engine));
324 params.Get("down", null_engine)); 332 auto right = Common::Input::CreateInputDeviceFromString(params.Get("right", null_engine));
325 auto left = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>( 333 auto modifier = Common::Input::CreateInputDeviceFromString(params.Get("modifier", null_engine));
326 params.Get("left", null_engine));
327 auto right = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
328 params.Get("right", null_engine));
329 auto modifier = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>(
330 params.Get("modifier", null_engine));
331 auto modifier_scale = params.Get("modifier_scale", 0.5f); 334 auto modifier_scale = params.Get("modifier_scale", 0.5f);
332 auto modifier_angle = params.Get("modifier_angle", 5.5f); 335 auto modifier_angle = params.Get("modifier_angle", 5.5f);
333 return std::make_unique<Stick>(std::move(up), std::move(down), std::move(left), 336 return std::make_unique<Stick>(std::move(up), std::move(down), std::move(left),
diff --git a/src/input_common/helpers/touch_from_buttons.cpp b/src/input_common/helpers/touch_from_buttons.cpp
index 003a38da5..e064b13d9 100644
--- a/src/input_common/helpers/touch_from_buttons.cpp
+++ b/src/input_common/helpers/touch_from_buttons.cpp
@@ -59,18 +59,25 @@ public:
59 } 59 }
60 60
61private: 61private:
62 static constexpr Common::Input::AnalogProperties properties{
63 .deadzone = 0.0f,
64 .range = 1.0f,
65 .threshold = 0.5f,
66 .offset = 0.0f,
67 .inverted = false,
68 .toggle = false,
69 };
70
62 Button button; 71 Button button;
63 bool last_button_value; 72 bool last_button_value;
64 const float x; 73 const float x;
65 const float y; 74 const float y;
66 const Common::Input::AnalogProperties properties{0.0f, 1.0f, 0.5f, 0.0f, false};
67}; 75};
68 76
69std::unique_ptr<Common::Input::InputDevice> TouchFromButton::Create( 77std::unique_ptr<Common::Input::InputDevice> TouchFromButton::Create(
70 const Common::ParamPackage& params) { 78 const Common::ParamPackage& params) {
71 const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize(); 79 const std::string null_engine = Common::ParamPackage{{"engine", "null"}}.Serialize();
72 auto button = Common::Input::CreateDeviceFromString<Common::Input::InputDevice>( 80 auto button = Common::Input::CreateInputDeviceFromString(params.Get("button", null_engine));
73 params.Get("button", null_engine));
74 const float x = params.Get("x", 0.0f) / 1280.0f; 81 const float x = params.Get("x", 0.0f) / 1280.0f;
75 const float y = params.Get("y", 0.0f) / 720.0f; 82 const float y = params.Get("y", 0.0f) / 720.0f;
76 return std::make_unique<TouchFromButtonDevice>(std::move(button), x, y); 83 return std::make_unique<TouchFromButtonDevice>(std::move(button), x, y);
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp
index cd42344aa..942a13535 100644
--- a/src/input_common/main.cpp
+++ b/src/input_common/main.cpp
@@ -33,119 +33,113 @@ struct InputSubsystem::Impl {
33 keyboard->SetMappingCallback(mapping_callback); 33 keyboard->SetMappingCallback(mapping_callback);
34 keyboard_factory = std::make_shared<InputFactory>(keyboard); 34 keyboard_factory = std::make_shared<InputFactory>(keyboard);
35 keyboard_output_factory = std::make_shared<OutputFactory>(keyboard); 35 keyboard_output_factory = std::make_shared<OutputFactory>(keyboard);
36 Common::Input::RegisterFactory<Common::Input::InputDevice>(keyboard->GetEngineName(), 36 Common::Input::RegisterInputFactory(keyboard->GetEngineName(), keyboard_factory);
37 keyboard_factory); 37 Common::Input::RegisterOutputFactory(keyboard->GetEngineName(), keyboard_output_factory);
38 Common::Input::RegisterFactory<Common::Input::OutputDevice>(keyboard->GetEngineName(),
39 keyboard_output_factory);
40 38
41 mouse = std::make_shared<Mouse>("mouse"); 39 mouse = std::make_shared<Mouse>("mouse");
42 mouse->SetMappingCallback(mapping_callback); 40 mouse->SetMappingCallback(mapping_callback);
43 mouse_factory = std::make_shared<InputFactory>(mouse); 41 mouse_factory = std::make_shared<InputFactory>(mouse);
44 mouse_output_factory = std::make_shared<OutputFactory>(mouse); 42 mouse_output_factory = std::make_shared<OutputFactory>(mouse);
45 Common::Input::RegisterFactory<Common::Input::InputDevice>(mouse->GetEngineName(), 43 Common::Input::RegisterInputFactory(mouse->GetEngineName(), mouse_factory);
46 mouse_factory); 44 Common::Input::RegisterOutputFactory(mouse->GetEngineName(), mouse_output_factory);
47 Common::Input::RegisterFactory<Common::Input::OutputDevice>(mouse->GetEngineName(),
48 mouse_output_factory);
49 45
50 touch_screen = std::make_shared<TouchScreen>("touch"); 46 touch_screen = std::make_shared<TouchScreen>("touch");
51 touch_screen_factory = std::make_shared<InputFactory>(touch_screen); 47 touch_screen_factory = std::make_shared<InputFactory>(touch_screen);
52 Common::Input::RegisterFactory<Common::Input::InputDevice>(touch_screen->GetEngineName(), 48 Common::Input::RegisterInputFactory(touch_screen->GetEngineName(), touch_screen_factory);
53 touch_screen_factory);
54 49
55 gcadapter = std::make_shared<GCAdapter>("gcpad"); 50 gcadapter = std::make_shared<GCAdapter>("gcpad");
56 gcadapter->SetMappingCallback(mapping_callback); 51 gcadapter->SetMappingCallback(mapping_callback);
57 gcadapter_input_factory = std::make_shared<InputFactory>(gcadapter); 52 gcadapter_input_factory = std::make_shared<InputFactory>(gcadapter);
58 gcadapter_output_factory = std::make_shared<OutputFactory>(gcadapter); 53 gcadapter_output_factory = std::make_shared<OutputFactory>(gcadapter);
59 Common::Input::RegisterFactory<Common::Input::InputDevice>(gcadapter->GetEngineName(), 54 Common::Input::RegisterInputFactory(gcadapter->GetEngineName(), gcadapter_input_factory);
60 gcadapter_input_factory); 55 Common::Input::RegisterOutputFactory(gcadapter->GetEngineName(), gcadapter_output_factory);
61 Common::Input::RegisterFactory<Common::Input::OutputDevice>(gcadapter->GetEngineName(),
62 gcadapter_output_factory);
63 56
64 udp_client = std::make_shared<CemuhookUDP::UDPClient>("cemuhookudp"); 57 udp_client = std::make_shared<CemuhookUDP::UDPClient>("cemuhookudp");
65 udp_client->SetMappingCallback(mapping_callback); 58 udp_client->SetMappingCallback(mapping_callback);
66 udp_client_input_factory = std::make_shared<InputFactory>(udp_client); 59 udp_client_input_factory = std::make_shared<InputFactory>(udp_client);
67 udp_client_output_factory = std::make_shared<OutputFactory>(udp_client); 60 udp_client_output_factory = std::make_shared<OutputFactory>(udp_client);
68 Common::Input::RegisterFactory<Common::Input::InputDevice>(udp_client->GetEngineName(), 61 Common::Input::RegisterInputFactory(udp_client->GetEngineName(), udp_client_input_factory);
69 udp_client_input_factory); 62 Common::Input::RegisterOutputFactory(udp_client->GetEngineName(),
70 Common::Input::RegisterFactory<Common::Input::OutputDevice>(udp_client->GetEngineName(), 63 udp_client_output_factory);
71 udp_client_output_factory);
72 64
73 tas_input = std::make_shared<TasInput::Tas>("tas"); 65 tas_input = std::make_shared<TasInput::Tas>("tas");
74 tas_input->SetMappingCallback(mapping_callback); 66 tas_input->SetMappingCallback(mapping_callback);
75 tas_input_factory = std::make_shared<InputFactory>(tas_input); 67 tas_input_factory = std::make_shared<InputFactory>(tas_input);
76 tas_output_factory = std::make_shared<OutputFactory>(tas_input); 68 tas_output_factory = std::make_shared<OutputFactory>(tas_input);
77 Common::Input::RegisterFactory<Common::Input::InputDevice>(tas_input->GetEngineName(), 69 Common::Input::RegisterInputFactory(tas_input->GetEngineName(), tas_input_factory);
78 tas_input_factory); 70 Common::Input::RegisterOutputFactory(tas_input->GetEngineName(), tas_output_factory);
79 Common::Input::RegisterFactory<Common::Input::OutputDevice>(tas_input->GetEngineName(),
80 tas_output_factory);
81 71
82 camera = std::make_shared<Camera>("camera"); 72 camera = std::make_shared<Camera>("camera");
83 camera->SetMappingCallback(mapping_callback); 73 camera->SetMappingCallback(mapping_callback);
84 camera_input_factory = std::make_shared<InputFactory>(camera); 74 camera_input_factory = std::make_shared<InputFactory>(camera);
85 camera_output_factory = std::make_shared<OutputFactory>(camera); 75 camera_output_factory = std::make_shared<OutputFactory>(camera);
86 Common::Input::RegisterFactory<Common::Input::InputDevice>(camera->GetEngineName(), 76 Common::Input::RegisterInputFactory(camera->GetEngineName(), camera_input_factory);
87 camera_input_factory); 77 Common::Input::RegisterOutputFactory(camera->GetEngineName(), camera_output_factory);
88 Common::Input::RegisterFactory<Common::Input::OutputDevice>(camera->GetEngineName(),
89 camera_output_factory);
90 78
91 virtual_amiibo = std::make_shared<VirtualAmiibo>("virtual_amiibo"); 79 virtual_amiibo = std::make_shared<VirtualAmiibo>("virtual_amiibo");
92 virtual_amiibo->SetMappingCallback(mapping_callback); 80 virtual_amiibo->SetMappingCallback(mapping_callback);
93 virtual_amiibo_input_factory = std::make_shared<InputFactory>(virtual_amiibo); 81 virtual_amiibo_input_factory = std::make_shared<InputFactory>(virtual_amiibo);
94 virtual_amiibo_output_factory = std::make_shared<OutputFactory>(virtual_amiibo); 82 virtual_amiibo_output_factory = std::make_shared<OutputFactory>(virtual_amiibo);
95 Common::Input::RegisterFactory<Common::Input::InputDevice>(virtual_amiibo->GetEngineName(), 83 Common::Input::RegisterInputFactory(virtual_amiibo->GetEngineName(),
96 virtual_amiibo_input_factory); 84 virtual_amiibo_input_factory);
97 Common::Input::RegisterFactory<Common::Input::OutputDevice>(virtual_amiibo->GetEngineName(), 85 Common::Input::RegisterOutputFactory(virtual_amiibo->GetEngineName(),
98 virtual_amiibo_output_factory); 86 virtual_amiibo_output_factory);
99 87
100#ifdef HAVE_SDL2 88#ifdef HAVE_SDL2
101 sdl = std::make_shared<SDLDriver>("sdl"); 89 sdl = std::make_shared<SDLDriver>("sdl");
102 sdl->SetMappingCallback(mapping_callback); 90 sdl->SetMappingCallback(mapping_callback);
103 sdl_input_factory = std::make_shared<InputFactory>(sdl); 91 sdl_input_factory = std::make_shared<InputFactory>(sdl);
104 sdl_output_factory = std::make_shared<OutputFactory>(sdl); 92 sdl_output_factory = std::make_shared<OutputFactory>(sdl);
105 Common::Input::RegisterFactory<Common::Input::InputDevice>(sdl->GetEngineName(), 93 Common::Input::RegisterInputFactory(sdl->GetEngineName(), sdl_input_factory);
106 sdl_input_factory); 94 Common::Input::RegisterOutputFactory(sdl->GetEngineName(), sdl_output_factory);
107 Common::Input::RegisterFactory<Common::Input::OutputDevice>(sdl->GetEngineName(),
108 sdl_output_factory);
109#endif 95#endif
110 96
111 Common::Input::RegisterFactory<Common::Input::InputDevice>( 97 Common::Input::RegisterInputFactory("touch_from_button",
112 "touch_from_button", std::make_shared<TouchFromButton>()); 98 std::make_shared<TouchFromButton>());
113 Common::Input::RegisterFactory<Common::Input::InputDevice>( 99 Common::Input::RegisterInputFactory("analog_from_button",
114 "analog_from_button", std::make_shared<StickFromButton>()); 100 std::make_shared<StickFromButton>());
115 } 101 }
116 102
117 void Shutdown() { 103 void Shutdown() {
118 Common::Input::UnregisterFactory<Common::Input::InputDevice>(keyboard->GetEngineName()); 104 Common::Input::UnregisterInputFactory(keyboard->GetEngineName());
119 Common::Input::UnregisterFactory<Common::Input::OutputDevice>(keyboard->GetEngineName()); 105 Common::Input::UnregisterOutputFactory(keyboard->GetEngineName());
120 keyboard.reset(); 106 keyboard.reset();
121 107
122 Common::Input::UnregisterFactory<Common::Input::InputDevice>(mouse->GetEngineName()); 108 Common::Input::UnregisterInputFactory(mouse->GetEngineName());
123 Common::Input::UnregisterFactory<Common::Input::OutputDevice>(mouse->GetEngineName()); 109 Common::Input::UnregisterOutputFactory(mouse->GetEngineName());
124 mouse.reset(); 110 mouse.reset();
125 111
126 Common::Input::UnregisterFactory<Common::Input::InputDevice>(touch_screen->GetEngineName()); 112 Common::Input::UnregisterInputFactory(touch_screen->GetEngineName());
127 touch_screen.reset(); 113 touch_screen.reset();
128 114
129 Common::Input::UnregisterFactory<Common::Input::InputDevice>(gcadapter->GetEngineName()); 115 Common::Input::UnregisterInputFactory(gcadapter->GetEngineName());
130 Common::Input::UnregisterFactory<Common::Input::OutputDevice>(gcadapter->GetEngineName()); 116 Common::Input::UnregisterOutputFactory(gcadapter->GetEngineName());
131 gcadapter.reset(); 117 gcadapter.reset();
132 118
133 Common::Input::UnregisterFactory<Common::Input::InputDevice>(udp_client->GetEngineName()); 119 Common::Input::UnregisterInputFactory(udp_client->GetEngineName());
134 Common::Input::UnregisterFactory<Common::Input::OutputDevice>(udp_client->GetEngineName()); 120 Common::Input::UnregisterOutputFactory(udp_client->GetEngineName());
135 udp_client.reset(); 121 udp_client.reset();
136 122
137 Common::Input::UnregisterFactory<Common::Input::InputDevice>(tas_input->GetEngineName()); 123 Common::Input::UnregisterInputFactory(tas_input->GetEngineName());
138 Common::Input::UnregisterFactory<Common::Input::OutputDevice>(tas_input->GetEngineName()); 124 Common::Input::UnregisterOutputFactory(tas_input->GetEngineName());
139 tas_input.reset(); 125 tas_input.reset();
140 126
127 Common::Input::UnregisterInputFactory(camera->GetEngineName());
128 Common::Input::UnregisterOutputFactory(camera->GetEngineName());
129 camera.reset();
130
131 Common::Input::UnregisterInputFactory(virtual_amiibo->GetEngineName());
132 Common::Input::UnregisterOutputFactory(virtual_amiibo->GetEngineName());
133 virtual_amiibo.reset();
134
141#ifdef HAVE_SDL2 135#ifdef HAVE_SDL2
142 Common::Input::UnregisterFactory<Common::Input::InputDevice>(sdl->GetEngineName()); 136 Common::Input::UnregisterInputFactory(sdl->GetEngineName());
143 Common::Input::UnregisterFactory<Common::Input::OutputDevice>(sdl->GetEngineName()); 137 Common::Input::UnregisterOutputFactory(sdl->GetEngineName());
144 sdl.reset(); 138 sdl.reset();
145#endif 139#endif
146 140
147 Common::Input::UnregisterFactory<Common::Input::InputDevice>("touch_from_button"); 141 Common::Input::UnregisterInputFactory("touch_from_button");
148 Common::Input::UnregisterFactory<Common::Input::InputDevice>("analog_from_button"); 142 Common::Input::UnregisterInputFactory("analog_from_button");
149 } 143 }
150 144
151 [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const { 145 [[nodiscard]] std::vector<Common::ParamPackage> GetInputDevices() const {
diff --git a/src/video_core/engines/engine_upload.cpp b/src/video_core/engines/engine_upload.cpp
index 28aa85f32..e4f8331ab 100644
--- a/src/video_core/engines/engine_upload.cpp
+++ b/src/video_core/engines/engine_upload.cpp
@@ -49,10 +49,9 @@ void State::ProcessData(std::span<const u8> read_buffer) {
49 if (regs.line_count == 1) { 49 if (regs.line_count == 1) {
50 rasterizer->AccelerateInlineToMemory(address, copy_size, read_buffer); 50 rasterizer->AccelerateInlineToMemory(address, copy_size, read_buffer);
51 } else { 51 } else {
52 for (u32 line = 0; line < regs.line_count; ++line) { 52 for (size_t line = 0; line < regs.line_count; ++line) {
53 const GPUVAddr dest_line = address + static_cast<size_t>(line) * regs.dest.pitch; 53 const GPUVAddr dest_line = address + line * regs.dest.pitch;
54 std::span<const u8> buffer(read_buffer.data() + 54 std::span<const u8> buffer(read_buffer.data() + line * regs.line_length_in,
55 static_cast<size_t>(line) * regs.line_length_in,
56 regs.line_length_in); 55 regs.line_length_in);
57 rasterizer->AccelerateInlineToMemory(dest_line, regs.line_length_in, buffer); 56 rasterizer->AccelerateInlineToMemory(dest_line, regs.line_length_in, buffer);
58 } 57 }
diff --git a/src/video_core/engines/engine_upload.h b/src/video_core/engines/engine_upload.h
index f08f6e36a..94fafd9dc 100644
--- a/src/video_core/engines/engine_upload.h
+++ b/src/video_core/engines/engine_upload.h
@@ -39,7 +39,7 @@ struct Registers {
39 u32 y; 39 u32 y;
40 40
41 GPUVAddr Address() const { 41 GPUVAddr Address() const {
42 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | address_low); 42 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
43 } 43 }
44 44
45 u32 BlockWidth() const { 45 u32 BlockWidth() const {
diff --git a/src/video_core/engines/fermi_2d.h b/src/video_core/engines/fermi_2d.h
index 24b518cb5..100b21bac 100644
--- a/src/video_core/engines/fermi_2d.h
+++ b/src/video_core/engines/fermi_2d.h
@@ -97,7 +97,7 @@ public:
97 u32 addr_lower; 97 u32 addr_lower;
98 98
99 [[nodiscard]] constexpr GPUVAddr Address() const noexcept { 99 [[nodiscard]] constexpr GPUVAddr Address() const noexcept {
100 return (static_cast<GPUVAddr>(addr_upper) << 32) | static_cast<GPUVAddr>(addr_lower); 100 return (GPUVAddr{addr_upper} << 32) | GPUVAddr{addr_lower};
101 } 101 }
102 }; 102 };
103 static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size"); 103 static_assert(sizeof(Surface) == 0x28, "Surface has incorrect size");
diff --git a/src/video_core/engines/kepler_compute.cpp b/src/video_core/engines/kepler_compute.cpp
index 7c50bdbe0..e5c622155 100644
--- a/src/video_core/engines/kepler_compute.cpp
+++ b/src/video_core/engines/kepler_compute.cpp
@@ -50,11 +50,11 @@ void KeplerCompute::CallMultiMethod(u32 method, const u32* base_start, u32 amoun
50 u32 methods_pending) { 50 u32 methods_pending) {
51 switch (method) { 51 switch (method) {
52 case KEPLER_COMPUTE_REG_INDEX(data_upload): 52 case KEPLER_COMPUTE_REG_INDEX(data_upload):
53 upload_state.ProcessData(base_start, static_cast<size_t>(amount)); 53 upload_state.ProcessData(base_start, amount);
54 return; 54 return;
55 default: 55 default:
56 for (std::size_t i = 0; i < amount; i++) { 56 for (u32 i = 0; i < amount; i++) {
57 CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1); 57 CallMethod(method, base_start[i], methods_pending - i <= 1);
58 } 58 }
59 break; 59 break;
60 } 60 }
diff --git a/src/video_core/engines/kepler_compute.h b/src/video_core/engines/kepler_compute.h
index aab309ecc..e154e3f06 100644
--- a/src/video_core/engines/kepler_compute.h
+++ b/src/video_core/engines/kepler_compute.h
@@ -68,7 +68,7 @@ public:
68 struct { 68 struct {
69 u32 address; 69 u32 address;
70 GPUVAddr Address() const { 70 GPUVAddr Address() const {
71 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address) << 8)); 71 return GPUVAddr{address} << 8;
72 } 72 }
73 } launch_desc_loc; 73 } launch_desc_loc;
74 74
@@ -83,8 +83,7 @@ public:
83 u32 address_low; 83 u32 address_low;
84 u32 limit; 84 u32 limit;
85 GPUVAddr Address() const { 85 GPUVAddr Address() const {
86 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 86 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
87 address_low);
88 } 87 }
89 } tsc; 88 } tsc;
90 89
@@ -95,8 +94,7 @@ public:
95 u32 address_low; 94 u32 address_low;
96 u32 limit; 95 u32 limit;
97 GPUVAddr Address() const { 96 GPUVAddr Address() const {
98 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 97 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
99 address_low);
100 } 98 }
101 } tic; 99 } tic;
102 100
@@ -106,8 +104,7 @@ public:
106 u32 address_high; 104 u32 address_high;
107 u32 address_low; 105 u32 address_low;
108 GPUVAddr Address() const { 106 GPUVAddr Address() const {
109 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 107 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
110 address_low);
111 } 108 }
112 } code_loc; 109 } code_loc;
113 110
@@ -162,8 +159,7 @@ public:
162 BitField<15, 17, u32> size; 159 BitField<15, 17, u32> size;
163 }; 160 };
164 GPUVAddr Address() const { 161 GPUVAddr Address() const {
165 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high.Value()) << 32) | 162 return (GPUVAddr{address_high.Value()} << 32) | GPUVAddr{address_low};
166 address_low);
167 } 163 }
168 }; 164 };
169 std::array<ConstBufferConfig, NumConstBuffers> const_buffer_config; 165 std::array<ConstBufferConfig, NumConstBuffers> const_buffer_config;
diff --git a/src/video_core/engines/kepler_memory.cpp b/src/video_core/engines/kepler_memory.cpp
index a3fbab1e5..08045d1cf 100644
--- a/src/video_core/engines/kepler_memory.cpp
+++ b/src/video_core/engines/kepler_memory.cpp
@@ -42,11 +42,11 @@ void KeplerMemory::CallMultiMethod(u32 method, const u32* base_start, u32 amount
42 u32 methods_pending) { 42 u32 methods_pending) {
43 switch (method) { 43 switch (method) {
44 case KEPLERMEMORY_REG_INDEX(data): 44 case KEPLERMEMORY_REG_INDEX(data):
45 upload_state.ProcessData(base_start, static_cast<size_t>(amount)); 45 upload_state.ProcessData(base_start, amount);
46 return; 46 return;
47 default: 47 default:
48 for (std::size_t i = 0; i < amount; i++) { 48 for (u32 i = 0; i < amount; i++) {
49 CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1); 49 CallMethod(method, base_start[i], methods_pending - i <= 1);
50 } 50 }
51 break; 51 break;
52 } 52 }
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index 212427b8b..55462752c 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -370,11 +370,11 @@ void Maxwell3D::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
370 ProcessCBMultiData(base_start, amount); 370 ProcessCBMultiData(base_start, amount);
371 break; 371 break;
372 case MAXWELL3D_REG_INDEX(inline_data): 372 case MAXWELL3D_REG_INDEX(inline_data):
373 upload_state.ProcessData(base_start, static_cast<size_t>(amount)); 373 upload_state.ProcessData(base_start, amount);
374 return; 374 return;
375 default: 375 default:
376 for (std::size_t i = 0; i < amount; i++) { 376 for (u32 i = 0; i < amount; i++) {
377 CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1); 377 CallMethod(method, base_start[i], methods_pending - i <= 1);
378 } 378 }
379 break; 379 break;
380 } 380 }
@@ -652,12 +652,12 @@ void Maxwell3D::ProcessDeferredDraw() {
652 return; 652 return;
653 } 653 }
654 654
655 u32 method_count = static_cast<u32>(deferred_draw_method.size()); 655 const auto method_count = deferred_draw_method.size();
656 u32 instance_count = 1; 656 u32 instance_count = 1;
657 u32 vertex_buffer_count = 0; 657 u32 vertex_buffer_count = 0;
658 u32 index_buffer_count = 0; 658 u32 index_buffer_count = 0;
659 for (u32 index = 0; index < method_count; ++index) { 659 for (size_t index = 0; index < method_count; ++index) {
660 u32 method = deferred_draw_method[index]; 660 const u32 method = deferred_draw_method[index];
661 if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count)) { 661 if (method == MAXWELL3D_REG_INDEX(vertex_buffer.count)) {
662 instance_count = ++vertex_buffer_count; 662 instance_count = ++vertex_buffer_count;
663 } else if (method == MAXWELL3D_REG_INDEX(index_buffer.count)) { 663 } else if (method == MAXWELL3D_REG_INDEX(index_buffer.count)) {
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 84c497ebd..deba292a5 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -96,8 +96,7 @@ public:
96 u32 type; 96 u32 type;
97 97
98 GPUVAddr Address() const { 98 GPUVAddr Address() const {
99 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 99 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
100 address_low);
101 } 100 }
102 }; 101 };
103 102
@@ -106,8 +105,7 @@ public:
106 u32 address_low; 105 u32 address_low;
107 106
108 GPUVAddr Address() const { 107 GPUVAddr Address() const {
109 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 108 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
110 address_low);
111 } 109 }
112 }; 110 };
113 111
@@ -124,8 +122,7 @@ public:
124 Mode mode; 122 Mode mode;
125 123
126 GPUVAddr Address() const { 124 GPUVAddr Address() const {
127 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(offset_high) << 32) | 125 return (GPUVAddr{offset_high} << 32) | GPUVAddr{offset_low};
128 offset_low);
129 } 126 }
130 }; 127 };
131 128
@@ -187,7 +184,7 @@ public:
187 default: 184 default:
188 // Thresholds begin at 0x10 (1 << 4) 185 // Thresholds begin at 0x10 (1 << 4)
189 // Threshold is in the range 0x1 to 0x13 186 // Threshold is in the range 0x1 to 0x13
190 return 1 << (4 + threshold.Value() - 1); 187 return 1U << (4 + threshold.Value() - 1);
191 } 188 }
192 } 189 }
193 }; 190 };
@@ -468,8 +465,7 @@ public:
468 INSERT_PADDING_BYTES_NOINIT(0xC); 465 INSERT_PADDING_BYTES_NOINIT(0xC);
469 466
470 GPUVAddr Address() const { 467 GPUVAddr Address() const {
471 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 468 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
472 address_low);
473 } 469 }
474 }; 470 };
475 static_assert(sizeof(Buffer) == 0x20); 471 static_assert(sizeof(Buffer) == 0x20);
@@ -511,12 +507,11 @@ public:
511 u32 default_size_per_warp; 507 u32 default_size_per_warp;
512 508
513 GPUVAddr Address() const { 509 GPUVAddr Address() const {
514 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 510 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
515 address_low);
516 } 511 }
517 512
518 u64 Size() const { 513 u64 Size() const {
519 return (static_cast<u64>(size_high) << 32) | size_low; 514 return (u64{size_high} << 32) | u64{size_low};
520 } 515 }
521 }; 516 };
522 517
@@ -538,13 +533,11 @@ public:
538 u32 storage_limit_address_low; 533 u32 storage_limit_address_low;
539 534
540 GPUVAddr StorageAddress() const { 535 GPUVAddr StorageAddress() const {
541 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(storage_address_high) << 32) | 536 return (GPUVAddr{storage_address_high} << 32) | GPUVAddr{storage_address_low};
542 storage_address_low);
543 } 537 }
544 GPUVAddr StorageLimitAddress() const { 538 GPUVAddr StorageLimitAddress() const {
545 return static_cast<GPUVAddr>( 539 return (GPUVAddr{storage_limit_address_high} << 32) |
546 (static_cast<GPUVAddr>(storage_limit_address_high) << 32) | 540 GPUVAddr{storage_limit_address_low};
547 storage_limit_address_low);
548 } 541 }
549 }; 542 };
550 543
@@ -829,11 +822,11 @@ public:
829 struct CompressionThresholdSamples { 822 struct CompressionThresholdSamples {
830 u32 samples; 823 u32 samples;
831 824
832 u32 Samples() { 825 u32 Samples() const {
833 if (samples == 0) { 826 if (samples == 0) {
834 return 0; 827 return 0;
835 } 828 }
836 return 1 << (samples - 1); 829 return 1U << (samples - 1);
837 } 830 }
838 }; 831 };
839 832
@@ -1138,8 +1131,7 @@ public:
1138 INSERT_PADDING_BYTES_NOINIT(0x18); 1131 INSERT_PADDING_BYTES_NOINIT(0x18);
1139 1132
1140 GPUVAddr Address() const { 1133 GPUVAddr Address() const {
1141 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 1134 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
1142 address_low);
1143 } 1135 }
1144 }; 1136 };
1145 static_assert(sizeof(RenderTargetConfig) == 0x40); 1137 static_assert(sizeof(RenderTargetConfig) == 0x40);
@@ -1482,8 +1474,7 @@ public:
1482 u32 address_low; 1474 u32 address_low;
1483 1475
1484 GPUVAddr Address() const { 1476 GPUVAddr Address() const {
1485 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 1477 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
1486 address_low);
1487 } 1478 }
1488 }; 1479 };
1489 1480
@@ -1533,8 +1524,7 @@ public:
1533 u32 address_low; 1524 u32 address_low;
1534 1525
1535 GPUVAddr Address() const { 1526 GPUVAddr Address() const {
1536 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 1527 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
1537 address_low);
1538 } 1528 }
1539 }; 1529 };
1540 1530
@@ -1561,8 +1551,7 @@ public:
1561 u32 array_pitch; 1551 u32 array_pitch;
1562 1552
1563 GPUVAddr Address() const { 1553 GPUVAddr Address() const {
1564 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 1554 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
1565 address_low);
1566 } 1555 }
1567 }; 1556 };
1568 1557
@@ -1910,8 +1899,7 @@ public:
1910 Mode mode; 1899 Mode mode;
1911 1900
1912 GPUVAddr Address() const { 1901 GPUVAddr Address() const {
1913 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 1902 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
1914 address_low);
1915 } 1903 }
1916 }; 1904 };
1917 1905
@@ -1921,8 +1909,7 @@ public:
1921 u32 limit; 1909 u32 limit;
1922 1910
1923 GPUVAddr Address() const { 1911 GPUVAddr Address() const {
1924 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 1912 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
1925 address_low);
1926 } 1913 }
1927 }; 1914 };
1928 1915
@@ -1932,8 +1919,7 @@ public:
1932 u32 limit; 1919 u32 limit;
1933 1920
1934 GPUVAddr Address() const { 1921 GPUVAddr Address() const {
1935 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 1922 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
1936 address_low);
1937 } 1923 }
1938 }; 1924 };
1939 1925
@@ -1981,8 +1967,7 @@ public:
1981 u32 address_low; 1967 u32 address_low;
1982 1968
1983 GPUVAddr Address() const { 1969 GPUVAddr Address() const {
1984 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 1970 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
1985 address_low);
1986 } 1971 }
1987 }; 1972 };
1988 1973
@@ -2027,8 +2012,7 @@ public:
2027 u32 address_low; 2012 u32 address_low;
2028 2013
2029 GPUVAddr Address() const { 2014 GPUVAddr Address() const {
2030 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 2015 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
2031 address_low);
2032 } 2016 }
2033 }; 2017 };
2034 2018
@@ -2224,19 +2208,16 @@ public:
2224 } 2208 }
2225 2209
2226 GPUVAddr StartAddress() const { 2210 GPUVAddr StartAddress() const {
2227 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(start_addr_high) << 32) | 2211 return (GPUVAddr{start_addr_high} << 32) | GPUVAddr{start_addr_low};
2228 start_addr_low);
2229 } 2212 }
2230 2213
2231 GPUVAddr EndAddress() const { 2214 GPUVAddr EndAddress() const {
2232 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_addr_high) << 32) | 2215 return (GPUVAddr{limit_addr_high} << 32) | GPUVAddr{limit_addr_low};
2233 limit_addr_low);
2234 } 2216 }
2235 2217
2236 /// Adjust the index buffer offset so it points to the first desired index. 2218 /// Adjust the index buffer offset so it points to the first desired index.
2237 GPUVAddr IndexStart() const { 2219 GPUVAddr IndexStart() const {
2238 return StartAddress() + 2220 return StartAddress() + size_t{first} * size_t{FormatSizeInBytes()};
2239 static_cast<size_t>(first) * static_cast<size_t>(FormatSizeInBytes());
2240 } 2221 }
2241 }; 2222 };
2242 2223
@@ -2464,8 +2445,7 @@ public:
2464 } query; 2445 } query;
2465 2446
2466 GPUVAddr Address() const { 2447 GPUVAddr Address() const {
2467 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 2448 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
2468 address_low);
2469 } 2449 }
2470 }; 2450 };
2471 2451
@@ -2479,8 +2459,7 @@ public:
2479 u32 frequency; 2459 u32 frequency;
2480 2460
2481 GPUVAddr Address() const { 2461 GPUVAddr Address() const {
2482 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 2462 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
2483 address_low);
2484 } 2463 }
2485 2464
2486 bool IsEnabled() const { 2465 bool IsEnabled() const {
@@ -2494,8 +2473,7 @@ public:
2494 u32 address_low; 2473 u32 address_low;
2495 2474
2496 GPUVAddr Address() const { 2475 GPUVAddr Address() const {
2497 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 2476 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
2498 address_low);
2499 } 2477 }
2500 }; 2478 };
2501 static_assert(sizeof(VertexStreamLimit) == 0x8); 2479 static_assert(sizeof(VertexStreamLimit) == 0x8);
@@ -2543,8 +2521,7 @@ public:
2543 std::array<u32, NumCBData> buffer; 2521 std::array<u32, NumCBData> buffer;
2544 2522
2545 GPUVAddr Address() const { 2523 GPUVAddr Address() const {
2546 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(address_high) << 32) | 2524 return (GPUVAddr{address_high} << 32) | GPUVAddr{address_low};
2547 address_low);
2548 } 2525 }
2549 }; 2526 };
2550 2527
diff --git a/src/video_core/engines/maxwell_dma.cpp b/src/video_core/engines/maxwell_dma.cpp
index 334429514..a189e60ae 100644
--- a/src/video_core/engines/maxwell_dma.cpp
+++ b/src/video_core/engines/maxwell_dma.cpp
@@ -41,8 +41,8 @@ void MaxwellDMA::CallMethod(u32 method, u32 method_argument, bool is_last_call)
41 41
42void MaxwellDMA::CallMultiMethod(u32 method, const u32* base_start, u32 amount, 42void MaxwellDMA::CallMultiMethod(u32 method, const u32* base_start, u32 amount,
43 u32 methods_pending) { 43 u32 methods_pending) {
44 for (size_t i = 0; i < amount; ++i) { 44 for (u32 i = 0; i < amount; ++i) {
45 CallMethod(method, base_start[i], methods_pending - static_cast<u32>(i) <= 1); 45 CallMethod(method, base_start[i], methods_pending - i <= 1);
46 } 46 }
47} 47}
48 48
@@ -94,14 +94,14 @@ void MaxwellDMA::Launch() {
94 reinterpret_cast<u8*>(tmp_buffer.data()), 94 reinterpret_cast<u8*>(tmp_buffer.data()),
95 regs.line_length_in * sizeof(u32)); 95 regs.line_length_in * sizeof(u32));
96 } else { 96 } else {
97 auto convert_linear_2_blocklinear_addr = [](u64 address) { 97 const auto convert_linear_2_blocklinear_addr = [](u64 address) {
98 return (address & ~0x1f0ULL) | ((address & 0x40) >> 2) | ((address & 0x10) << 1) | 98 return (address & ~0x1f0ULL) | ((address & 0x40) >> 2) | ((address & 0x10) << 1) |
99 ((address & 0x180) >> 1) | ((address & 0x20) << 3); 99 ((address & 0x180) >> 1) | ((address & 0x20) << 3);
100 }; 100 };
101 auto src_kind = memory_manager.GetPageKind(regs.offset_in); 101 const auto src_kind = memory_manager.GetPageKind(regs.offset_in);
102 auto dst_kind = memory_manager.GetPageKind(regs.offset_out); 102 const auto dst_kind = memory_manager.GetPageKind(regs.offset_out);
103 const bool is_src_pitch = IsPitchKind(static_cast<PTEKind>(src_kind)); 103 const bool is_src_pitch = IsPitchKind(src_kind);
104 const bool is_dst_pitch = IsPitchKind(static_cast<PTEKind>(dst_kind)); 104 const bool is_dst_pitch = IsPitchKind(dst_kind);
105 if (!is_src_pitch && is_dst_pitch) { 105 if (!is_src_pitch && is_dst_pitch) {
106 UNIMPLEMENTED_IF(regs.line_length_in % 16 != 0); 106 UNIMPLEMENTED_IF(regs.line_length_in % 16 != 0);
107 UNIMPLEMENTED_IF(regs.offset_in % 16 != 0); 107 UNIMPLEMENTED_IF(regs.offset_in % 16 != 0);
diff --git a/src/video_core/engines/puller.cpp b/src/video_core/engines/puller.cpp
index c308ba3fc..7718a09b3 100644
--- a/src/video_core/engines/puller.cpp
+++ b/src/video_core/engines/puller.cpp
@@ -31,7 +31,7 @@ void Puller::ProcessBindMethod(const MethodCall& method_call) {
31 LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel, 31 LOG_DEBUG(HW_GPU, "Binding subchannel {} to engine {}", method_call.subchannel,
32 method_call.argument); 32 method_call.argument);
33 const auto engine_id = static_cast<EngineID>(method_call.argument); 33 const auto engine_id = static_cast<EngineID>(method_call.argument);
34 bound_engines[method_call.subchannel] = static_cast<EngineID>(engine_id); 34 bound_engines[method_call.subchannel] = engine_id;
35 switch (engine_id) { 35 switch (engine_id) {
36 case EngineID::FERMI_TWOD_A: 36 case EngineID::FERMI_TWOD_A:
37 dma_pusher.BindSubchannel(channel_state.fermi_2d.get(), method_call.subchannel); 37 dma_pusher.BindSubchannel(channel_state.fermi_2d.get(), method_call.subchannel);
@@ -285,12 +285,12 @@ void Puller::CallMultiMethod(u32 method, u32 subchannel, const u32* base_start,
285 if (ExecuteMethodOnEngine(method)) { 285 if (ExecuteMethodOnEngine(method)) {
286 CallEngineMultiMethod(method, subchannel, base_start, amount, methods_pending); 286 CallEngineMultiMethod(method, subchannel, base_start, amount, methods_pending);
287 } else { 287 } else {
288 for (std::size_t i = 0; i < amount; i++) { 288 for (u32 i = 0; i < amount; i++) {
289 CallPullerMethod(MethodCall{ 289 CallPullerMethod(MethodCall{
290 method, 290 method,
291 base_start[i], 291 base_start[i],
292 subchannel, 292 subchannel,
293 methods_pending - static_cast<u32>(i), 293 methods_pending - i,
294 }); 294 });
295 } 295 }
296 } 296 }
diff --git a/src/video_core/host1x/syncpoint_manager.cpp b/src/video_core/host1x/syncpoint_manager.cpp
index a44fc83d3..8f23ce527 100644
--- a/src/video_core/host1x/syncpoint_manager.cpp
+++ b/src/video_core/host1x/syncpoint_manager.cpp
@@ -34,7 +34,7 @@ SyncpointManager::ActionHandle SyncpointManager::RegisterAction(
34} 34}
35 35
36void SyncpointManager::DeregisterAction(std::list<RegisteredAction>& action_storage, 36void SyncpointManager::DeregisterAction(std::list<RegisteredAction>& action_storage,
37 ActionHandle& handle) { 37 const ActionHandle& handle) {
38 std::unique_lock lk(guard); 38 std::unique_lock lk(guard);
39 39
40 // We want to ensure the iterator still exists prior to erasing it 40 // We want to ensure the iterator still exists prior to erasing it
@@ -49,11 +49,11 @@ void SyncpointManager::DeregisterAction(std::list<RegisteredAction>& action_stor
49 } 49 }
50} 50}
51 51
52void SyncpointManager::DeregisterGuestAction(u32 syncpoint_id, ActionHandle& handle) { 52void SyncpointManager::DeregisterGuestAction(u32 syncpoint_id, const ActionHandle& handle) {
53 DeregisterAction(guest_action_storage[syncpoint_id], handle); 53 DeregisterAction(guest_action_storage[syncpoint_id], handle);
54} 54}
55 55
56void SyncpointManager::DeregisterHostAction(u32 syncpoint_id, ActionHandle& handle) { 56void SyncpointManager::DeregisterHostAction(u32 syncpoint_id, const ActionHandle& handle) {
57 DeregisterAction(host_action_storage[syncpoint_id], handle); 57 DeregisterAction(host_action_storage[syncpoint_id], handle);
58} 58}
59 59
diff --git a/src/video_core/host1x/syncpoint_manager.h b/src/video_core/host1x/syncpoint_manager.h
index 50a264e23..847ed20c8 100644
--- a/src/video_core/host1x/syncpoint_manager.h
+++ b/src/video_core/host1x/syncpoint_manager.h
@@ -36,21 +36,19 @@ public:
36 36
37 template <typename Func> 37 template <typename Func>
38 ActionHandle RegisterGuestAction(u32 syncpoint_id, u32 expected_value, Func&& action) { 38 ActionHandle RegisterGuestAction(u32 syncpoint_id, u32 expected_value, Func&& action) {
39 std::function<void()> func(action);
40 return RegisterAction(syncpoints_guest[syncpoint_id], guest_action_storage[syncpoint_id], 39 return RegisterAction(syncpoints_guest[syncpoint_id], guest_action_storage[syncpoint_id],
41 expected_value, std::move(func)); 40 expected_value, std::move(action));
42 } 41 }
43 42
44 template <typename Func> 43 template <typename Func>
45 ActionHandle RegisterHostAction(u32 syncpoint_id, u32 expected_value, Func&& action) { 44 ActionHandle RegisterHostAction(u32 syncpoint_id, u32 expected_value, Func&& action) {
46 std::function<void()> func(action);
47 return RegisterAction(syncpoints_host[syncpoint_id], host_action_storage[syncpoint_id], 45 return RegisterAction(syncpoints_host[syncpoint_id], host_action_storage[syncpoint_id],
48 expected_value, std::move(func)); 46 expected_value, std::move(action));
49 } 47 }
50 48
51 void DeregisterGuestAction(u32 syncpoint_id, ActionHandle& handle); 49 void DeregisterGuestAction(u32 syncpoint_id, const ActionHandle& handle);
52 50
53 void DeregisterHostAction(u32 syncpoint_id, ActionHandle& handle); 51 void DeregisterHostAction(u32 syncpoint_id, const ActionHandle& handle);
54 52
55 void IncrementGuest(u32 syncpoint_id); 53 void IncrementGuest(u32 syncpoint_id);
56 54
@@ -76,7 +74,7 @@ private:
76 std::list<RegisteredAction>& action_storage, u32 expected_value, 74 std::list<RegisteredAction>& action_storage, u32 expected_value,
77 std::function<void()>&& action); 75 std::function<void()>&& action);
78 76
79 void DeregisterAction(std::list<RegisteredAction>& action_storage, ActionHandle& handle); 77 void DeregisterAction(std::list<RegisteredAction>& action_storage, const ActionHandle& handle);
80 78
81 void Wait(std::atomic<u32>& syncpoint, std::condition_variable& wait_cv, u32 expected_value); 79 void Wait(std::atomic<u32>& syncpoint, std::condition_variable& wait_cv, u32 expected_value);
82 80
diff --git a/src/video_core/surface.cpp b/src/video_core/surface.cpp
index b618e1a25..1a76d4178 100644
--- a/src/video_core/surface.cpp
+++ b/src/video_core/surface.cpp
@@ -214,23 +214,16 @@ PixelFormat PixelFormatFromGPUPixelFormat(Service::android::PixelFormat format)
214} 214}
215 215
216SurfaceType GetFormatType(PixelFormat pixel_format) { 216SurfaceType GetFormatType(PixelFormat pixel_format) {
217 if (static_cast<std::size_t>(pixel_format) < 217 if (pixel_format < PixelFormat::MaxColorFormat) {
218 static_cast<std::size_t>(PixelFormat::MaxColorFormat)) {
219 return SurfaceType::ColorTexture; 218 return SurfaceType::ColorTexture;
220 } 219 }
221 220 if (pixel_format < PixelFormat::MaxDepthFormat) {
222 if (static_cast<std::size_t>(pixel_format) <
223 static_cast<std::size_t>(PixelFormat::MaxDepthFormat)) {
224 return SurfaceType::Depth; 221 return SurfaceType::Depth;
225 } 222 }
226 223 if (pixel_format < PixelFormat::MaxStencilFormat) {
227 if (static_cast<std::size_t>(pixel_format) <
228 static_cast<std::size_t>(PixelFormat::MaxStencilFormat)) {
229 return SurfaceType::Stencil; 224 return SurfaceType::Stencil;
230 } 225 }
231 226 if (pixel_format < PixelFormat::MaxDepthStencilFormat) {
232 if (static_cast<std::size_t>(pixel_format) <
233 static_cast<std::size_t>(PixelFormat::MaxDepthStencilFormat)) {
234 return SurfaceType::DepthStencil; 227 return SurfaceType::DepthStencil;
235 } 228 }
236 229
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index adad36221..0aa109dd3 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -295,7 +295,7 @@ if (APPLE)
295 set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist) 295 set_target_properties(yuzu PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
296elseif(WIN32) 296elseif(WIN32)
297 # compile as a win32 gui application instead of a console application 297 # compile as a win32 gui application instead of a console application
298 if (QT_VERSION VERSION_GREATER 6) 298 if (QT_VERSION VERSION_GREATER_EQUAL 6)
299 target_link_libraries(yuzu PRIVATE Qt6::EntryPointPrivate) 299 target_link_libraries(yuzu PRIVATE Qt6::EntryPointPrivate)
300 else() 300 else()
301 target_link_libraries(yuzu PRIVATE Qt5::WinMain) 301 target_link_libraries(yuzu PRIVATE Qt5::WinMain)
@@ -311,15 +311,15 @@ endif()
311create_target_directory_groups(yuzu) 311create_target_directory_groups(yuzu)
312 312
313target_link_libraries(yuzu PRIVATE common core input_common network video_core) 313target_link_libraries(yuzu PRIVATE common core input_common network video_core)
314target_link_libraries(yuzu PRIVATE Boost::boost glad Qt::Widgets Qt::Multimedia) 314target_link_libraries(yuzu PRIVATE Boost::boost glad Qt${QT_MAJOR_VERSION}::Widgets)
315target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) 315target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
316 316
317target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include) 317target_include_directories(yuzu PRIVATE ../../externals/Vulkan-Headers/include)
318if (NOT WIN32) 318if (NOT WIN32)
319 target_include_directories(yuzu PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS}) 319 target_include_directories(yuzu PRIVATE ${Qt${QT_MAJOR_VERSION}Gui_PRIVATE_INCLUDE_DIRS})
320endif() 320endif()
321if (UNIX AND NOT APPLE) 321if (UNIX AND NOT APPLE)
322 target_link_libraries(yuzu PRIVATE Qt::DBus) 322 target_link_libraries(yuzu PRIVATE Qt${QT_MAJOR_VERSION}::DBus)
323endif() 323endif()
324 324
325target_compile_definitions(yuzu PRIVATE 325target_compile_definitions(yuzu PRIVATE
@@ -358,8 +358,13 @@ if (ENABLE_WEB_SERVICE)
358 target_compile_definitions(yuzu PRIVATE -DENABLE_WEB_SERVICE) 358 target_compile_definitions(yuzu PRIVATE -DENABLE_WEB_SERVICE)
359endif() 359endif()
360 360
361if (YUZU_USE_QT_MULTIMEDIA)
362 target_link_libraries(yuzu PRIVATE Qt${QT_MAJOR_VERSION}::Multimedia)
363 target_compile_definitions(yuzu PRIVATE -DYUZU_USE_QT_MULTIMEDIA)
364endif ()
365
361if (YUZU_USE_QT_WEB_ENGINE) 366if (YUZU_USE_QT_WEB_ENGINE)
362 target_link_libraries(yuzu PRIVATE Qt::WebEngineCore Qt::WebEngineWidgets) 367 target_link_libraries(yuzu PRIVATE Qt${QT_MAJOR_VERSION}::WebEngineCore Qt${QT_MAJOR_VERSION}::WebEngineWidgets)
363 target_compile_definitions(yuzu PRIVATE -DYUZU_USE_QT_WEB_ENGINE) 368 target_compile_definitions(yuzu PRIVATE -DYUZU_USE_QT_WEB_ENGINE)
364endif () 369endif ()
365 370
@@ -367,7 +372,16 @@ if(UNIX AND NOT APPLE)
367 install(TARGETS yuzu) 372 install(TARGETS yuzu)
368endif() 373endif()
369 374
370if (YUZU_USE_BUNDLED_QT) 375if (WIN32 AND QT_VERSION VERSION_GREATER_EQUAL 6)
376 if (MSVC AND NOT ${CMAKE_GENERATOR} STREQUAL "Ninja")
377 set(YUZU_EXE_DIR "${CMAKE_BINARY_DIR}/bin/$<CONFIG>")
378 else()
379 set(YUZU_EXE_DIR "${CMAKE_BINARY_DIR}/bin")
380 endif()
381 add_custom_command(TARGET yuzu POST_BUILD COMMAND ${WINDEPLOYQT_EXECUTABLE} "${YUZU_EXE_DIR}/yuzu.exe" --dir "${YUZU_EXE_DIR}" --libdir "${YUZU_EXE_DIR}" --plugindir "${YUZU_EXE_DIR}/plugins" --no-compiler-runtime --no-opengl-sw --no-system-d3d-compiler --no-translations --verbose 0)
382endif()
383
384if (YUZU_USE_BUNDLED_QT AND QT_VERSION VERSION_LESS 6)
371 include(CopyYuzuQt5Deps) 385 include(CopyYuzuQt5Deps)
372 copy_yuzu_Qt5_deps(yuzu) 386 copy_yuzu_Qt5_deps(yuzu)
373endif() 387endif()
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index d88efacd7..c934069dd 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -4,8 +4,10 @@
4#include <glad/glad.h> 4#include <glad/glad.h>
5 5
6#include <QApplication> 6#include <QApplication>
7#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
7#include <QCameraImageCapture> 8#include <QCameraImageCapture>
8#include <QCameraInfo> 9#include <QCameraInfo>
10#endif
9#include <QHBoxLayout> 11#include <QHBoxLayout>
10#include <QMessageBox> 12#include <QMessageBox>
11#include <QPainter> 13#include <QPainter>
@@ -707,6 +709,7 @@ void GRenderWindow::TouchEndEvent() {
707} 709}
708 710
709void GRenderWindow::InitializeCamera() { 711void GRenderWindow::InitializeCamera() {
712#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
710 constexpr auto camera_update_ms = std::chrono::milliseconds{50}; // (50ms, 20Hz) 713 constexpr auto camera_update_ms = std::chrono::milliseconds{50}; // (50ms, 20Hz)
711 if (!Settings::values.enable_ir_sensor) { 714 if (!Settings::values.enable_ir_sensor) {
712 return; 715 return;
@@ -760,18 +763,22 @@ void GRenderWindow::InitializeCamera() {
760 connect(camera_timer.get(), &QTimer::timeout, [this] { RequestCameraCapture(); }); 763 connect(camera_timer.get(), &QTimer::timeout, [this] { RequestCameraCapture(); });
761 // This timer should be dependent of camera resolution 5ms for every 100 pixels 764 // This timer should be dependent of camera resolution 5ms for every 100 pixels
762 camera_timer->start(camera_update_ms); 765 camera_timer->start(camera_update_ms);
766#endif
763} 767}
764 768
765void GRenderWindow::FinalizeCamera() { 769void GRenderWindow::FinalizeCamera() {
770#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
766 if (camera_timer) { 771 if (camera_timer) {
767 camera_timer->stop(); 772 camera_timer->stop();
768 } 773 }
769 if (camera) { 774 if (camera) {
770 camera->unload(); 775 camera->unload();
771 } 776 }
777#endif
772} 778}
773 779
774void GRenderWindow::RequestCameraCapture() { 780void GRenderWindow::RequestCameraCapture() {
781#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
775 if (!Settings::values.enable_ir_sensor) { 782 if (!Settings::values.enable_ir_sensor) {
776 return; 783 return;
777 } 784 }
@@ -788,6 +795,7 @@ void GRenderWindow::RequestCameraCapture() {
788 795
789 pending_camera_snapshots++; 796 pending_camera_snapshots++;
790 camera_capture->capture(); 797 camera_capture->capture();
798#endif
791} 799}
792 800
793void GRenderWindow::OnCameraCapture(int requestId, const QImage& img) { 801void GRenderWindow::OnCameraCapture(int requestId, const QImage& img) {
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index c45ebf1a2..4a01481cd 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -241,8 +241,10 @@ private:
241 241
242 bool is_virtual_camera; 242 bool is_virtual_camera;
243 int pending_camera_snapshots; 243 int pending_camera_snapshots;
244#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
244 std::unique_ptr<QCamera> camera; 245 std::unique_ptr<QCamera> camera;
245 std::unique_ptr<QCameraImageCapture> camera_capture; 246 std::unique_ptr<QCameraImageCapture> camera_capture;
247#endif
246 std::unique_ptr<QTimer> camera_timer; 248 std::unique_ptr<QTimer> camera_timer;
247 249
248 Core::System& system; 250 Core::System& system;
diff --git a/src/yuzu/configuration/configure_camera.cpp b/src/yuzu/configuration/configure_camera.cpp
index 2a61de2a1..d95e96696 100644
--- a/src/yuzu/configuration/configure_camera.cpp
+++ b/src/yuzu/configuration/configure_camera.cpp
@@ -2,8 +2,11 @@
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4#include <memory> 4#include <memory>
5#include <QtCore>
6#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
5#include <QCameraImageCapture> 7#include <QCameraImageCapture>
6#include <QCameraInfo> 8#include <QCameraInfo>
9#endif
7#include <QStandardItemModel> 10#include <QStandardItemModel>
8#include <QTimer> 11#include <QTimer>
9 12
@@ -33,6 +36,7 @@ ConfigureCamera::ConfigureCamera(QWidget* parent, InputCommon::InputSubsystem* i
33ConfigureCamera::~ConfigureCamera() = default; 36ConfigureCamera::~ConfigureCamera() = default;
34 37
35void ConfigureCamera::PreviewCamera() { 38void ConfigureCamera::PreviewCamera() {
39#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
36 const auto index = ui->ir_sensor_combo_box->currentIndex(); 40 const auto index = ui->ir_sensor_combo_box->currentIndex();
37 bool camera_found = false; 41 bool camera_found = false;
38 const QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); 42 const QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
@@ -101,6 +105,7 @@ void ConfigureCamera::PreviewCamera() {
101 }); 105 });
102 106
103 camera_timer->start(250); 107 camera_timer->start(250);
108#endif
104} 109}
105 110
106void ConfigureCamera::DisplayCapturedFrame(int requestId, const QImage& img) { 111void ConfigureCamera::DisplayCapturedFrame(int requestId, const QImage& img) {
@@ -133,11 +138,13 @@ void ConfigureCamera::LoadConfiguration() {
133 ui->ir_sensor_combo_box->clear(); 138 ui->ir_sensor_combo_box->clear();
134 input_devices.push_back("Auto"); 139 input_devices.push_back("Auto");
135 ui->ir_sensor_combo_box->addItem(tr("Auto")); 140 ui->ir_sensor_combo_box->addItem(tr("Auto"));
141#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
136 const auto cameras = QCameraInfo::availableCameras(); 142 const auto cameras = QCameraInfo::availableCameras();
137 for (const QCameraInfo& cameraInfo : cameras) { 143 for (const QCameraInfo& cameraInfo : cameras) {
138 input_devices.push_back(cameraInfo.deviceName().toStdString()); 144 input_devices.push_back(cameraInfo.deviceName().toStdString());
139 ui->ir_sensor_combo_box->addItem(cameraInfo.description()); 145 ui->ir_sensor_combo_box->addItem(cameraInfo.description());
140 } 146 }
147#endif
141 148
142 const auto current_device = Settings::values.ir_sensor_device.GetValue(); 149 const auto current_device = Settings::values.ir_sensor_device.GetValue();
143 150
diff --git a/src/yuzu/configuration/configure_camera.h b/src/yuzu/configuration/configure_camera.h
index db9833b5c..9a90512b3 100644
--- a/src/yuzu/configuration/configure_camera.h
+++ b/src/yuzu/configuration/configure_camera.h
@@ -46,8 +46,10 @@ private:
46 46
47 bool is_virtual_camera; 47 bool is_virtual_camera;
48 int pending_snapshots; 48 int pending_snapshots;
49#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0)) && YUZU_USE_QT_MULTIMEDIA
49 std::unique_ptr<QCamera> camera; 50 std::unique_ptr<QCamera> camera;
50 std::unique_ptr<QCameraImageCapture> camera_capture; 51 std::unique_ptr<QCameraImageCapture> camera_capture;
52#endif
51 std::unique_ptr<QTimer> camera_timer; 53 std::unique_ptr<QTimer> camera_timer;
52 std::vector<std::string> input_devices; 54 std::vector<std::string> input_devices;
53 std::unique_ptr<Ui::ConfigureCamera> ui; 55 std::unique_ptr<Ui::ConfigureCamera> ui;
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index 10f841b98..235b813d9 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -194,4 +194,8 @@ void ConfigureInputAdvanced::UpdateUIEnabled() {
194 ui->mouse_panning->setEnabled(!ui->mouse_enabled->isChecked()); 194 ui->mouse_panning->setEnabled(!ui->mouse_enabled->isChecked());
195 ui->mouse_panning_sensitivity->setEnabled(!ui->mouse_enabled->isChecked()); 195 ui->mouse_panning_sensitivity->setEnabled(!ui->mouse_enabled->isChecked());
196 ui->ring_controller_configure->setEnabled(ui->enable_ring_controller->isChecked()); 196 ui->ring_controller_configure->setEnabled(ui->enable_ring_controller->isChecked());
197#if QT_VERSION > QT_VERSION_CHECK(6, 0, 0) || !defined(YUZU_USE_QT_MULTIMEDIA)
198 ui->enable_ir_sensor->setEnabled(false);
199 ui->camera_configure->setEnabled(false);
200#endif
197} 201}
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 7c225cccc..c21153560 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -238,6 +238,7 @@ static void LogRuntimes() {
238 LOG_INFO(Frontend, "Unable to inspect {}", runtime_dll_name); 238 LOG_INFO(Frontend, "Unable to inspect {}", runtime_dll_name);
239 } 239 }
240#endif 240#endif
241 LOG_INFO(Frontend, "Qt Compile: {} Runtime: {}", QT_VERSION_STR, qVersion());
241} 242}
242 243
243static QString PrettyProductName() { 244static QString PrettyProductName() {
@@ -4048,7 +4049,6 @@ void GMainWindow::UpdateUITheme() {
4048 const QString default_theme = 4049 const QString default_theme =
4049 QString::fromUtf8(UISettings::themes[static_cast<size_t>(Config::default_theme)].second); 4050 QString::fromUtf8(UISettings::themes[static_cast<size_t>(Config::default_theme)].second);
4050 QString current_theme = UISettings::values.theme; 4051 QString current_theme = UISettings::values.theme;
4051 QStringList theme_paths(default_theme_paths);
4052 4052
4053 if (current_theme.isEmpty()) { 4053 if (current_theme.isEmpty()) {
4054 current_theme = default_theme; 4054 current_theme = default_theme;
@@ -4061,7 +4061,7 @@ void GMainWindow::UpdateUITheme() {
4061 if (current_theme == QStringLiteral("default") || current_theme == QStringLiteral("colorful")) { 4061 if (current_theme == QStringLiteral("default") || current_theme == QStringLiteral("colorful")) {
4062 QIcon::setThemeName(current_theme == QStringLiteral("colorful") ? current_theme 4062 QIcon::setThemeName(current_theme == QStringLiteral("colorful") ? current_theme
4063 : startup_icon_theme); 4063 : startup_icon_theme);
4064 QIcon::setThemeSearchPaths(theme_paths); 4064 QIcon::setThemeSearchPaths(QStringList(default_theme_paths));
4065 if (CheckDarkMode()) { 4065 if (CheckDarkMode()) {
4066 current_theme = QStringLiteral("default_dark"); 4066 current_theme = QStringLiteral("default_dark");
4067 } 4067 }
@@ -4229,10 +4229,12 @@ int main(int argc, char* argv[]) {
4229 // so we can see if we get \u3008 instead 4229 // so we can see if we get \u3008 instead
4230 // TL;DR all other number formats are consecutive in unicode code points 4230 // TL;DR all other number formats are consecutive in unicode code points
4231 // This bug is fixed in Qt6, specifically 6.0.0-alpha1 4231 // This bug is fixed in Qt6, specifically 6.0.0-alpha1
4232#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
4232 const QLocale locale = QLocale::system(); 4233 const QLocale locale = QLocale::system();
4233 if (QStringLiteral("\u3008") == locale.toString(1)) { 4234 if (QStringLiteral("\u3008") == locale.toString(1)) {
4234 QLocale::setDefault(QLocale::system().name()); 4235 QLocale::setDefault(QLocale::system().name());
4235 } 4236 }
4237#endif
4236 4238
4237 // Qt changes the locale and causes issues in float conversion using std::to_string() when 4239 // Qt changes the locale and causes issues in float conversion using std::to_string() when
4238 // generating shaders 4240 // generating shaders
diff --git a/src/yuzu/multiplayer/direct_connect.cpp b/src/yuzu/multiplayer/direct_connect.cpp
index 10bf0a4fb..cbd52da85 100644
--- a/src/yuzu/multiplayer/direct_connect.cpp
+++ b/src/yuzu/multiplayer/direct_connect.cpp
@@ -4,7 +4,7 @@
4#include <QComboBox> 4#include <QComboBox>
5#include <QFuture> 5#include <QFuture>
6#include <QIntValidator> 6#include <QIntValidator>
7#include <QRegExpValidator> 7#include <QRegularExpressionValidator>
8#include <QString> 8#include <QString>
9#include <QtConcurrent/QtConcurrentRun> 9#include <QtConcurrent/QtConcurrentRun>
10#include "common/settings.h" 10#include "common/settings.h"
diff --git a/src/yuzu/multiplayer/validation.h b/src/yuzu/multiplayer/validation.h
index dabf860be..dd25af280 100644
--- a/src/yuzu/multiplayer/validation.h
+++ b/src/yuzu/multiplayer/validation.h
@@ -3,7 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <QRegExp> 6#include <QRegularExpression>
7#include <QString> 7#include <QString>
8#include <QValidator> 8#include <QValidator>
9 9
@@ -29,19 +29,21 @@ public:
29 29
30private: 30private:
31 /// room name can be alphanumeric and " " "_" "." and "-" and must have a size of 4-20 31 /// room name can be alphanumeric and " " "_" "." and "-" and must have a size of 4-20
32 QRegExp room_name_regex = QRegExp(QStringLiteral("^[a-zA-Z0-9._- ]{4,20}$")); 32 QRegularExpression room_name_regex =
33 QRegExpValidator room_name; 33 QRegularExpression(QStringLiteral("^[a-zA-Z0-9._ -]{4,20}"));
34 QRegularExpressionValidator room_name;
34 35
35 /// nickname can be alphanumeric and " " "_" "." and "-" and must have a size of 4-20 36 /// nickname can be alphanumeric and " " "_" "." and "-" and must have a size of 4-20
36 QRegExp nickname_regex = QRegExp(QStringLiteral("^[a-zA-Z0-9._- ]{4,20}$")); 37 const QRegularExpression nickname_regex =
37 QRegExpValidator nickname; 38 QRegularExpression(QStringLiteral("^[a-zA-Z0-9._ -]{4,20}"));
39 QRegularExpressionValidator nickname;
38 40
39 /// ipv4 address only 41 /// ipv4 address only
40 // TODO remove this when we support hostnames in direct connect 42 // TODO remove this when we support hostnames in direct connect
41 QRegExp ip_regex = QRegExp(QStringLiteral( 43 QRegularExpression ip_regex = QRegularExpression(QStringLiteral(
42 "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|" 44 "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|"
43 "2[0-4][0-9]|25[0-5])")); 45 "2[0-4][0-9]|25[0-5])"));
44 QRegExpValidator ip; 46 QRegularExpressionValidator ip;
45 47
46 /// port must be between 0 and 65535 48 /// port must be between 0 and 65535
47 QIntValidator port; 49 QIntValidator port;
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index d6bea9aa8..59f9c8e09 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -90,7 +90,11 @@ static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs>
90 90
91template <> 91template <>
92void Config::ReadSetting(const std::string& group, Settings::Setting<std::string>& setting) { 92void Config::ReadSetting(const std::string& group, Settings::Setting<std::string>& setting) {
93 setting = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault()); 93 std::string setting_value = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault());
94 if (setting_value.empty()) {
95 setting_value = setting.GetDefault();
96 }
97 setting = std::move(setting_value);
94} 98}
95 99
96template <> 100template <>
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h
index d214771b0..5bbc3f532 100644
--- a/src/yuzu_cmd/default_ini.h
+++ b/src/yuzu_cmd/default_ini.h
@@ -6,16 +6,22 @@
6namespace DefaultINI { 6namespace DefaultINI {
7 7
8const char* sdl2_config_file = R"( 8const char* sdl2_config_file = R"(
9[ControlsGeneral] 9
10[ControlsP0]
10# The input devices and parameters for each Switch native input 11# The input devices and parameters for each Switch native input
12# The config section determines the player number where the config will be applied on. For example "ControlsP0", "ControlsP1", ...
11# It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..." 13# It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..."
12# Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values 14# Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values
13 15
16# Indicates if this player should be connected at boot
17connected=
18
14# for button input, the following devices are available: 19# for button input, the following devices are available:
15# - "keyboard" (default) for keyboard input. Required parameters: 20# - "keyboard" (default) for keyboard input. Required parameters:
16# - "code": the code of the key to bind 21# - "code": the code of the key to bind
17# - "sdl" for joystick input using SDL. Required parameters: 22# - "sdl" for joystick input using SDL. Required parameters:
18# - "joystick": the index of the joystick to bind 23# - "guid": SDL identification GUID of the joystick
24# - "port": the index of the joystick to bind
19# - "button"(optional): the index of the button to bind 25# - "button"(optional): the index of the button to bind
20# - "hat"(optional): the index of the hat to bind as direction buttons 26# - "hat"(optional): the index of the hat to bind as direction buttons
21# - "axis"(optional): the index of the axis to bind 27# - "axis"(optional): the index of the axis to bind
@@ -58,12 +64,29 @@ button_screenshot=
58# - "modifier_scale": a float number representing the applied modifier scale to the analog input. 64# - "modifier_scale": a float number representing the applied modifier scale to the analog input.
59# Must be in range of 0.0-1.0. Defaults to 0.5 65# Must be in range of 0.0-1.0. Defaults to 0.5
60# - "sdl" for joystick input using SDL. Required parameters: 66# - "sdl" for joystick input using SDL. Required parameters:
61# - "joystick": the index of the joystick to bind 67# - "guid": SDL identification GUID of the joystick
68# - "port": the index of the joystick to bind
62# - "axis_x": the index of the axis to bind as x-axis (default to 0) 69# - "axis_x": the index of the axis to bind as x-axis (default to 0)
63# - "axis_y": the index of the axis to bind as y-axis (default to 1) 70# - "axis_y": the index of the axis to bind as y-axis (default to 1)
64lstick= 71lstick=
65rstick= 72rstick=
66 73
74# for motion input, the following devices are available:
75# - "keyboard" (default) for emulating random motion input from buttons. Required parameters:
76# - "code": the code of the key to bind
77# - "sdl" for motion input using SDL. Required parameters:
78# - "guid": SDL identification GUID of the joystick
79# - "port": the index of the joystick to bind
80# - "motion": the index of the motion sensor to bind
81# - "cemuhookudp" for motion input using Cemu Hook protocol. Required parameters:
82# - "guid": the IP address of the cemu hook server encoded to a hex string. for example 192.168.0.1 = "c0a80001"
83# - "port": the port of the cemu hook server
84# - "pad": the index of the joystick
85# - "motion": the index of the motion sensor of the joystick to bind
86motionleft=
87motionright=
88
89[ControlsGeneral]
67# To use the debug_pad, prepend `debug_pad_` before each button setting above. 90# To use the debug_pad, prepend `debug_pad_` before each button setting above.
68# i.e. debug_pad_button_a= 91# i.e. debug_pad_button_a=
69 92
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 4ac72c2f6..37dd1747c 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -7,6 +7,7 @@
7#include "common/scm_rev.h" 7#include "common/scm_rev.h"
8#include "common/settings.h" 8#include "common/settings.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "core/hid/hid_core.h"
10#include "core/perf_stats.h" 11#include "core/perf_stats.h"
11#include "input_common/drivers/keyboard.h" 12#include "input_common/drivers/keyboard.h"
12#include "input_common/drivers/mouse.h" 13#include "input_common/drivers/mouse.h"
@@ -26,6 +27,7 @@ EmuWindow_SDL2::EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Co
26} 27}
27 28
28EmuWindow_SDL2::~EmuWindow_SDL2() { 29EmuWindow_SDL2::~EmuWindow_SDL2() {
30 system.HIDCore().UnloadInputDevices();
29 input_subsystem->Shutdown(); 31 input_subsystem->Shutdown();
30 SDL_Quit(); 32 SDL_Quit();
31} 33}