diff options
Diffstat (limited to '')
54 files changed, 627 insertions, 493 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9182dbfd4..39d038493 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -65,6 +65,10 @@ if (MSVC) /we4305 # 'context': truncation from 'type1' to 'type2' /we4388 # 'expression': signed/unsigned mismatch /we4389 # 'operator': signed/unsigned mismatch + /we4456 # Declaration of 'identifier' hides previous local declaration + /we4457 # Declaration of 'identifier' hides function parameter + /we4458 # Declaration of 'identifier' hides class member + /we4459 # Declaration of 'identifier' hides global declaration /we4505 # 'function': unreferenced local function has been removed /we4547 # 'operator': operator before comma has no effect; expected operator with side-effect /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? @@ -92,6 +96,7 @@ else() -Werror=missing-declarations -Werror=missing-field-initializers -Werror=reorder + -Werror=shadow -Werror=sign-compare -Werror=switch -Werror=uninitialized diff --git a/src/audio_core/CMakeLists.txt b/src/audio_core/CMakeLists.txt index e553b8203..89575a53e 100644 --- a/src/audio_core/CMakeLists.txt +++ b/src/audio_core/CMakeLists.txt @@ -49,9 +49,6 @@ if (NOT MSVC) target_compile_options(audio_core PRIVATE -Werror=conversion -Werror=ignored-qualifiers - -Werror=shadow - -Werror=unused-parameter - -Werror=unused-variable $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> diff --git a/src/common/bounded_threadsafe_queue.h b/src/common/bounded_threadsafe_queue.h index e83064c7f..7e465549b 100644 --- a/src/common/bounded_threadsafe_queue.h +++ b/src/common/bounded_threadsafe_queue.h @@ -1,10 +1,7 @@ // SPDX-FileCopyrightText: Copyright (c) 2020 Erik Rigtorp <erik@rigtorp.se> // SPDX-License-Identifier: MIT + #pragma once -#ifdef _MSC_VER -#pragma warning(push) -#pragma warning(disable : 4324) -#endif #include <atomic> #include <bit> @@ -12,105 +9,63 @@ #include <memory> #include <mutex> #include <new> -#include <stdexcept> #include <stop_token> #include <type_traits> #include <utility> namespace Common { -namespace mpsc { + #if defined(__cpp_lib_hardware_interference_size) constexpr size_t hardware_interference_size = std::hardware_destructive_interference_size; #else constexpr size_t hardware_interference_size = 64; #endif -template <typename T> -using AlignedAllocator = std::allocator<T>; - -template <typename T> -struct Slot { - ~Slot() noexcept { - if (turn.test()) { - destroy(); - } - } - - template <typename... Args> - void construct(Args&&... args) noexcept { - static_assert(std::is_nothrow_constructible_v<T, Args&&...>, - "T must be nothrow constructible with Args&&..."); - std::construct_at(reinterpret_cast<T*>(&storage), std::forward<Args>(args)...); - } - - void destroy() noexcept { - static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible"); - std::destroy_at(reinterpret_cast<T*>(&storage)); - } - - T&& move() noexcept { - return reinterpret_cast<T&&>(storage); - } - - // Align to avoid false sharing between adjacent slots - alignas(hardware_interference_size) std::atomic_flag turn{}; - struct aligned_store { - struct type { - alignas(T) unsigned char data[sizeof(T)]; - }; - }; - typename aligned_store::type storage; -}; +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4324) +#endif -template <typename T, typename Allocator = AlignedAllocator<Slot<T>>> -class Queue { +template <typename T, size_t capacity = 0x400> +class MPSCQueue { public: - explicit Queue(const size_t capacity, const Allocator& allocator = Allocator()) - : allocator_(allocator) { - if (capacity < 1) { - throw std::invalid_argument("capacity < 1"); - } - // Ensure that the queue length is an integer power of 2 - // This is so that idx(i) can be a simple i & mask_ insted of i % capacity - // https://github.com/rigtorp/MPMCQueue/pull/36 - if (!std::has_single_bit(capacity)) { - throw std::invalid_argument("capacity must be an integer power of 2"); - } - - mask_ = capacity - 1; - + explicit MPSCQueue() : allocator{std::allocator<Slot<T>>()} { // Allocate one extra slot to prevent false sharing on the last slot - slots_ = allocator_.allocate(mask_ + 2); + slots = allocator.allocate(capacity + 1); // Allocators are not required to honor alignment for over-aligned types // (see http://eel.is/c++draft/allocator.requirements#10) so we verify // alignment here - if (reinterpret_cast<uintptr_t>(slots_) % alignof(Slot<T>) != 0) { - allocator_.deallocate(slots_, mask_ + 2); + if (reinterpret_cast<uintptr_t>(slots) % alignof(Slot<T>) != 0) { + allocator.deallocate(slots, capacity + 1); throw std::bad_alloc(); } - for (size_t i = 0; i < mask_ + 1; ++i) { - std::construct_at(&slots_[i]); + for (size_t i = 0; i < capacity; ++i) { + std::construct_at(&slots[i]); } + static_assert(std::has_single_bit(capacity), "capacity must be an integer power of 2"); static_assert(alignof(Slot<T>) == hardware_interference_size, "Slot must be aligned to cache line boundary to prevent false sharing"); static_assert(sizeof(Slot<T>) % hardware_interference_size == 0, "Slot size must be a multiple of cache line size to prevent " "false sharing between adjacent slots"); - static_assert(sizeof(Queue) % hardware_interference_size == 0, + static_assert(sizeof(MPSCQueue) % hardware_interference_size == 0, "Queue size must be a multiple of cache line size to " "prevent false sharing between adjacent queues"); } - ~Queue() noexcept { - for (size_t i = 0; i < mask_ + 1; ++i) { - slots_[i].~Slot(); + ~MPSCQueue() noexcept { + for (size_t i = 0; i < capacity; ++i) { + std::destroy_at(&slots[i]); } - allocator_.deallocate(slots_, mask_ + 2); + allocator.deallocate(slots, capacity + 1); } - // non-copyable and non-movable - Queue(const Queue&) = delete; - Queue& operator=(const Queue&) = delete; + // The queue must be both non-copyable and non-movable + MPSCQueue(const MPSCQueue&) = delete; + MPSCQueue& operator=(const MPSCQueue&) = delete; + + MPSCQueue(MPSCQueue&&) = delete; + MPSCQueue& operator=(MPSCQueue&&) = delete; void Push(const T& v) noexcept { static_assert(std::is_nothrow_copy_constructible_v<T>, @@ -125,8 +80,8 @@ public: void Pop(T& v, std::stop_token stop) noexcept { auto const tail = tail_.fetch_add(1); - auto& slot = slots_[idx(tail)]; - if (false == slot.turn.test()) { + auto& slot = slots[idx(tail)]; + if (!slot.turn.test()) { std::unique_lock lock{cv_mutex}; cv.wait(lock, stop, [&slot] { return slot.turn.test(); }); } @@ -137,12 +92,46 @@ public: } private: + template <typename U = T> + struct Slot { + ~Slot() noexcept { + if (turn.test()) { + destroy(); + } + } + + template <typename... Args> + void construct(Args&&... args) noexcept { + static_assert(std::is_nothrow_constructible_v<U, Args&&...>, + "T must be nothrow constructible with Args&&..."); + std::construct_at(reinterpret_cast<U*>(&storage), std::forward<Args>(args)...); + } + + void destroy() noexcept { + static_assert(std::is_nothrow_destructible_v<U>, "T must be nothrow destructible"); + std::destroy_at(reinterpret_cast<U*>(&storage)); + } + + U&& move() noexcept { + return reinterpret_cast<U&&>(storage); + } + + // Align to avoid false sharing between adjacent slots + alignas(hardware_interference_size) std::atomic_flag turn{}; + struct aligned_store { + struct type { + alignas(U) unsigned char data[sizeof(U)]; + }; + }; + typename aligned_store::type storage; + }; + template <typename... Args> void emplace(Args&&... args) noexcept { static_assert(std::is_nothrow_constructible_v<T, Args&&...>, "T must be nothrow constructible with Args&&..."); auto const head = head_.fetch_add(1); - auto& slot = slots_[idx(head)]; + auto& slot = slots[idx(head)]; slot.turn.wait(true); slot.construct(std::forward<Args>(args)...); slot.turn.test_and_set(); @@ -150,31 +139,29 @@ private: } constexpr size_t idx(size_t i) const noexcept { - return i & mask_; + return i & mask; } - std::conditional_t<true, std::condition_variable_any, std::condition_variable> cv; - std::mutex cv_mutex; - size_t mask_; - Slot<T>* slots_; - [[no_unique_address]] Allocator allocator_; + static constexpr size_t mask = capacity - 1; // Align to avoid false sharing between head_ and tail_ alignas(hardware_interference_size) std::atomic<size_t> head_{0}; alignas(hardware_interference_size) std::atomic<size_t> tail_{0}; + std::mutex cv_mutex; + std::condition_variable_any cv; + + Slot<T>* slots; + [[no_unique_address]] std::allocator<Slot<T>> allocator; + static_assert(std::is_nothrow_copy_assignable_v<T> || std::is_nothrow_move_assignable_v<T>, "T must be nothrow copy or move assignable"); static_assert(std::is_nothrow_destructible_v<T>, "T must be nothrow destructible"); }; -} // namespace mpsc - -template <typename T, typename Allocator = mpsc::AlignedAllocator<mpsc::Slot<T>>> -using MPSCQueue = mpsc::Queue<T, Allocator>; - -} // namespace Common #ifdef _MSC_VER #pragma warning(pop) #endif + +} // namespace Common diff --git a/src/common/detached_tasks.cpp b/src/common/detached_tasks.cpp index c1362631e..ec31d0b88 100644 --- a/src/common/detached_tasks.cpp +++ b/src/common/detached_tasks.cpp @@ -33,9 +33,9 @@ void DetachedTasks::AddTask(std::function<void()> task) { ++instance->count; std::thread([task{std::move(task)}]() { task(); - std::unique_lock lock{instance->mutex}; + std::unique_lock thread_lock{instance->mutex}; --instance->count; - std::notify_all_at_thread_exit(instance->cv, std::move(lock)); + std::notify_all_at_thread_exit(instance->cv, std::move(thread_lock)); }).detach(); } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 2bd720f08..670410e75 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -743,16 +743,11 @@ if (MSVC) /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data /we4245 # 'conversion': conversion from 'type1' to 'type2', signed/unsigned mismatch /we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data - /we4456 # Declaration of 'identifier' hides previous local declaration - /we4457 # Declaration of 'identifier' hides function parameter - /we4458 # Declaration of 'identifier' hides class member - /we4459 # Declaration of 'identifier' hides global declaration ) else() target_compile_options(core PRIVATE -Werror=conversion -Werror=ignored-qualifiers - -Werror=shadow $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp index 9b5a5ca57..9a285dfc6 100644 --- a/src/core/arm/arm_interface.cpp +++ b/src/core/arm/arm_interface.cpp @@ -107,6 +107,7 @@ void ARM_Interface::Run() { } // Otherwise, run the thread. + system.EnterDynarmicProfile(); if (current_thread->GetStepState() == StepState::StepPending) { hr = StepJit(); @@ -116,6 +117,7 @@ void ARM_Interface::Run() { } else { hr = RunJit(); } + system.ExitDynarmicProfile(); // Notify the debugger and go to sleep if a breakpoint was hit. if (Has(hr, breakpoint)) { diff --git a/src/core/core.cpp b/src/core/core.cpp index 954136adb..7723d9782 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -138,7 +138,6 @@ struct System::Impl { kernel.Suspend(false); core_timing.SyncPause(false); - cpu_manager.Pause(false); is_paused = false; return status; @@ -150,25 +149,22 @@ struct System::Impl { core_timing.SyncPause(true); kernel.Suspend(true); - cpu_manager.Pause(true); is_paused = true; return status; } - std::unique_lock<std::mutex> StallCPU() { + std::unique_lock<std::mutex> StallProcesses() { std::unique_lock<std::mutex> lk(suspend_guard); kernel.Suspend(true); core_timing.SyncPause(true); - cpu_manager.Pause(true); return lk; } - void UnstallCPU() { + void UnstallProcesses() { if (!is_paused) { core_timing.SyncPause(false); kernel.Suspend(false); - cpu_manager.Pause(false); } } @@ -334,6 +330,8 @@ struct System::Impl { gpu_core->NotifyShutdown(); } + kernel.ShutdownCores(); + cpu_manager.Shutdown(); debugger.reset(); services.reset(); service_manager.reset(); @@ -499,12 +497,12 @@ void System::DetachDebugger() { } } -std::unique_lock<std::mutex> System::StallCPU() { - return impl->StallCPU(); +std::unique_lock<std::mutex> System::StallProcesses() { + return impl->StallProcesses(); } -void System::UnstallCPU() { - impl->UnstallCPU(); +void System::UnstallProcesses() { + impl->UnstallProcesses(); } void System::InitializeDebugger() { diff --git a/src/core/core.h b/src/core/core.h index 5c367349e..60efe4410 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -163,8 +163,8 @@ public: /// Forcibly detach the debugger if it is running. void DetachDebugger(); - std::unique_lock<std::mutex> StallCPU(); - void UnstallCPU(); + std::unique_lock<std::mutex> StallProcesses(); + void UnstallProcesses(); /** * Initialize the debugger. diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index b4718fbbe..1c07dc90e 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp @@ -16,31 +16,28 @@ namespace Core { -CpuManager::CpuManager(System& system_) - : pause_barrier{std::make_unique<Common::Barrier>(1)}, system{system_} {} +CpuManager::CpuManager(System& system_) : system{system_} {} CpuManager::~CpuManager() = default; void CpuManager::ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core) { - cpu_manager.RunThread(stop_token, core); + cpu_manager.RunThread(core); } void CpuManager::Initialize() { - running_mode = true; - if (is_multicore) { - for (std::size_t core = 0; core < Core::Hardware::NUM_CPU_CORES; core++) { - core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core); - } - pause_barrier = std::make_unique<Common::Barrier>(Core::Hardware::NUM_CPU_CORES + 1); - } else { - core_data[0].host_thread = std::jthread(ThreadStart, std::ref(*this), 0); - pause_barrier = std::make_unique<Common::Barrier>(2); + num_cores = is_multicore ? Core::Hardware::NUM_CPU_CORES : 1; + + for (std::size_t core = 0; core < num_cores; core++) { + core_data[core].host_thread = std::jthread(ThreadStart, std::ref(*this), core); } } void CpuManager::Shutdown() { - running_mode = false; - Pause(false); + for (std::size_t core = 0; core < num_cores; core++) { + if (core_data[core].host_thread.joinable()) { + core_data[core].host_thread.join(); + } + } } std::function<void(void*)> CpuManager::GetGuestThreadStartFunc() { @@ -51,8 +48,8 @@ std::function<void(void*)> CpuManager::GetIdleThreadStartFunc() { return IdleThreadFunction; } -std::function<void(void*)> CpuManager::GetSuspendThreadStartFunc() { - return SuspendThreadFunction; +std::function<void(void*)> CpuManager::GetShutdownThreadStartFunc() { + return ShutdownThreadFunction; } void CpuManager::GuestThreadFunction(void* cpu_manager_) { @@ -82,17 +79,12 @@ void CpuManager::IdleThreadFunction(void* cpu_manager_) { } } -void CpuManager::SuspendThreadFunction(void* cpu_manager_) { - CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_); - if (cpu_manager->is_multicore) { - cpu_manager->MultiCoreRunSuspendThread(); - } else { - cpu_manager->SingleCoreRunSuspendThread(); - } +void CpuManager::ShutdownThreadFunction(void* cpu_manager) { + static_cast<CpuManager*>(cpu_manager)->ShutdownThread(); } -void* CpuManager::GetStartFuncParamater() { - return static_cast<void*>(this); +void* CpuManager::GetStartFuncParameter() { + return this; } /////////////////////////////////////////////////////////////////////////////// @@ -113,12 +105,10 @@ void CpuManager::MultiCoreRunGuestLoop() { while (true) { auto* physical_core = &kernel.CurrentPhysicalCore(); - system.EnterDynarmicProfile(); while (!physical_core->IsInterrupted()) { physical_core->Run(); physical_core = &kernel.CurrentPhysicalCore(); } - system.ExitDynarmicProfile(); { Kernel::KScopedDisableDispatch dd(kernel); physical_core->ArmInterface().ClearExclusiveState(); @@ -134,21 +124,6 @@ void CpuManager::MultiCoreRunIdleThread() { } } -void CpuManager::MultiCoreRunSuspendThread() { - auto& kernel = system.Kernel(); - kernel.CurrentScheduler()->OnThreadStart(); - while (true) { - auto core = kernel.CurrentPhysicalCoreIndex(); - auto& scheduler = *kernel.CurrentScheduler(); - Kernel::KThread* current_thread = scheduler.GetCurrentThread(); - current_thread->DisableDispatch(); - - Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[core].host_context); - ASSERT(core == kernel.CurrentPhysicalCoreIndex()); - scheduler.RescheduleCurrentCore(); - } -} - /////////////////////////////////////////////////////////////////////////////// /// SingleCore /// /////////////////////////////////////////////////////////////////////////////// @@ -166,12 +141,10 @@ void CpuManager::SingleCoreRunGuestLoop() { auto& kernel = system.Kernel(); while (true) { auto* physical_core = &kernel.CurrentPhysicalCore(); - system.EnterDynarmicProfile(); if (!physical_core->IsInterrupted()) { physical_core->Run(); physical_core = &kernel.CurrentPhysicalCore(); } - system.ExitDynarmicProfile(); kernel.SetIsPhantomModeForSingleCore(true); system.CoreTiming().Advance(); kernel.SetIsPhantomModeForSingleCore(false); @@ -194,21 +167,6 @@ void CpuManager::SingleCoreRunIdleThread() { } } -void CpuManager::SingleCoreRunSuspendThread() { - auto& kernel = system.Kernel(); - kernel.CurrentScheduler()->OnThreadStart(); - while (true) { - auto core = kernel.GetCurrentHostThreadID(); - auto& scheduler = *kernel.CurrentScheduler(); - Kernel::KThread* current_thread = scheduler.GetCurrentThread(); - current_thread->DisableDispatch(); - - Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[0].host_context); - ASSERT(core == kernel.GetCurrentHostThreadID()); - scheduler.RescheduleCurrentCore(); - } -} - void CpuManager::PreemptSingleCore(bool from_running_enviroment) { { auto& kernel = system.Kernel(); @@ -241,24 +199,16 @@ void CpuManager::PreemptSingleCore(bool from_running_enviroment) { } } -void CpuManager::Pause(bool paused) { - std::scoped_lock lk{pause_lock}; - - if (pause_state == paused) { - return; - } - - // Set the new state - pause_state.store(paused); - - // Wake up any waiting threads - pause_state.notify_all(); +void CpuManager::ShutdownThread() { + auto& kernel = system.Kernel(); + auto core = is_multicore ? kernel.CurrentPhysicalCoreIndex() : 0; + auto* current_thread = kernel.GetCurrentEmuThread(); - // Wait for all threads to successfully change state before returning - pause_barrier->Sync(); + Common::Fiber::YieldTo(current_thread->GetHostContext(), *core_data[core].host_context); + UNREACHABLE(); } -void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) { +void CpuManager::RunThread(std::size_t core) { /// Initialization system.RegisterCoreThread(core); std::string name; @@ -272,8 +222,6 @@ void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) { Common::SetCurrentThreadPriority(Common::ThreadPriority::High); auto& data = core_data[core]; data.host_context = Common::Fiber::ThreadToFiber(); - const bool sc_sync = !is_async_gpu && !is_multicore; - bool sc_sync_first_use = sc_sync; // Cleanup SCOPE_EXIT({ @@ -281,32 +229,13 @@ void CpuManager::RunThread(std::stop_token stop_token, std::size_t core) { MicroProfileOnThreadExit(); }); - /// Running - while (running_mode) { - if (pause_state.load(std::memory_order_relaxed)) { - // Wait for caller to acknowledge pausing - pause_barrier->Sync(); - - // Wait until unpaused - pause_state.wait(true, std::memory_order_relaxed); - - // Wait for caller to acknowledge unpausing - pause_barrier->Sync(); - } - - if (sc_sync_first_use) { - system.GPU().ObtainContext(); - sc_sync_first_use = false; - } - - // Emulation was stopped - if (stop_token.stop_requested()) { - return; - } - - auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); - Common::Fiber::YieldTo(data.host_context, *current_thread->GetHostContext()); + // Running + if (!is_async_gpu && !is_multicore) { + system.GPU().ObtainContext(); } + + auto current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); + Common::Fiber::YieldTo(data.host_context, *current_thread->GetHostContext()); } } // namespace Core diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h index ddd9691ca..681bdaf19 100644 --- a/src/core/cpu_manager.h +++ b/src/core/cpu_manager.h @@ -46,12 +46,10 @@ public: void Initialize(); void Shutdown(); - void Pause(bool paused); - static std::function<void(void*)> GetGuestThreadStartFunc(); static std::function<void(void*)> GetIdleThreadStartFunc(); - static std::function<void(void*)> GetSuspendThreadStartFunc(); - void* GetStartFuncParamater(); + static std::function<void(void*)> GetShutdownThreadStartFunc(); + void* GetStartFuncParameter(); void PreemptSingleCore(bool from_running_enviroment = true); @@ -63,38 +61,33 @@ private: static void GuestThreadFunction(void* cpu_manager); static void GuestRewindFunction(void* cpu_manager); static void IdleThreadFunction(void* cpu_manager); - static void SuspendThreadFunction(void* cpu_manager); + static void ShutdownThreadFunction(void* cpu_manager); void MultiCoreRunGuestThread(); void MultiCoreRunGuestLoop(); void MultiCoreRunIdleThread(); - void MultiCoreRunSuspendThread(); void SingleCoreRunGuestThread(); void SingleCoreRunGuestLoop(); void SingleCoreRunIdleThread(); - void SingleCoreRunSuspendThread(); static void ThreadStart(std::stop_token stop_token, CpuManager& cpu_manager, std::size_t core); - void RunThread(std::stop_token stop_token, std::size_t core); + void ShutdownThread(); + void RunThread(std::size_t core); struct CoreData { std::shared_ptr<Common::Fiber> host_context; std::jthread host_thread; }; - std::atomic<bool> running_mode{}; - std::atomic<bool> pause_state{}; - std::unique_ptr<Common::Barrier> pause_barrier{}; - std::mutex pause_lock{}; - std::array<CoreData, Core::Hardware::NUM_CPU_CORES> core_data{}; bool is_async_gpu{}; bool is_multicore{}; std::atomic<std::size_t> current_core{}; std::size_t idle_count{}; + std::size_t num_cores{}; static constexpr std::size_t max_cycle_runs = 5; System& system; diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index edf991d71..ab3940922 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp @@ -67,17 +67,19 @@ public: } bool SignalDebugger(SignalInfo signal_info) { - std::scoped_lock lk{connection_lock}; + { + std::scoped_lock lk{connection_lock}; - if (stopped) { - // Do not notify the debugger about another event. - // It should be ignored. - return false; - } + if (stopped) { + // Do not notify the debugger about another event. + // It should be ignored. + return false; + } - // Set up the state. - stopped = true; - info = signal_info; + // Set up the state. + stopped = true; + info = signal_info; + } // Write a single byte into the pipe to wake up the debug interface. boost::asio::write(signal_pipe, boost::asio::buffer(&stopped, sizeof(stopped))); @@ -141,9 +143,6 @@ private: AsyncReceiveInto(signal_pipe, pipe_data, [&](auto d) { PipeData(d); }); AsyncReceiveInto(client_socket, client_data, [&](auto d) { ClientData(d); }); - // Stop the emulated CPU. - AllCoreStop(); - // Set the active thread. UpdateActiveThread(); @@ -159,7 +158,7 @@ private: switch (info.type) { case SignalType::Stopped: // Stop emulation. - AllCoreStop(); + PauseEmulation(); // Notify the client. active_thread = info.thread; @@ -171,7 +170,6 @@ private: frontend->ShuttingDown(); // Wait for emulation to shut down gracefully now. - suspend.reset(); signal_pipe.close(); client_socket.shutdown(boost::asio::socket_base::shutdown_both); LOG_INFO(Debug_GDBStub, "Shut down server"); @@ -189,32 +187,29 @@ private: std::scoped_lock lk{connection_lock}; stopped = true; } - AllCoreStop(); + PauseEmulation(); UpdateActiveThread(); frontend->Stopped(active_thread); break; } case DebuggerAction::Continue: - active_thread->SetStepState(Kernel::StepState::NotStepping); - ResumeInactiveThreads(); - AllCoreResume(); + MarkResumed([&] { ResumeEmulation(); }); break; case DebuggerAction::StepThreadUnlocked: - active_thread->SetStepState(Kernel::StepState::StepPending); - ResumeInactiveThreads(); - AllCoreResume(); + MarkResumed([&] { + active_thread->SetStepState(Kernel::StepState::StepPending); + active_thread->Resume(Kernel::SuspendType::Debug); + ResumeEmulation(active_thread); + }); break; - case DebuggerAction::StepThreadLocked: - active_thread->SetStepState(Kernel::StepState::StepPending); - SuspendInactiveThreads(); - AllCoreResume(); + case DebuggerAction::StepThreadLocked: { + MarkResumed([&] { + active_thread->SetStepState(Kernel::StepState::StepPending); + active_thread->Resume(Kernel::SuspendType::Debug); + }); break; + } case DebuggerAction::ShutdownEmulation: { - // Suspend all threads and release any locks held - active_thread->RequestSuspend(Kernel::SuspendType::Debug); - SuspendInactiveThreads(); - AllCoreResume(); - // Spawn another thread that will exit after shutdown, // to avoid a deadlock Core::System* system_ref{&system}; @@ -226,33 +221,33 @@ private: } } - void AllCoreStop() { - if (!suspend) { - suspend = system.StallCPU(); + void PauseEmulation() { + // Put all threads to sleep on next scheduler round. + for (auto* thread : ThreadList()) { + thread->RequestSuspend(Kernel::SuspendType::Debug); } - } - void AllCoreResume() { - stopped = false; - system.UnstallCPU(); - suspend.reset(); + // Signal an interrupt so that scheduler will fire. + system.Kernel().InterruptAllPhysicalCores(); } - void SuspendInactiveThreads() { + void ResumeEmulation(Kernel::KThread* except = nullptr) { + // Wake up all threads. for (auto* thread : ThreadList()) { - if (thread != active_thread) { - thread->RequestSuspend(Kernel::SuspendType::Debug); + if (thread == except) { + continue; } + + thread->SetStepState(Kernel::StepState::NotStepping); + thread->Resume(Kernel::SuspendType::Debug); } } - void ResumeInactiveThreads() { - for (auto* thread : ThreadList()) { - if (thread != active_thread) { - thread->Resume(Kernel::SuspendType::Debug); - thread->SetStepState(Kernel::StepState::NotStepping); - } - } + template <typename Callback> + void MarkResumed(Callback&& cb) { + std::scoped_lock lk{connection_lock}; + stopped = false; + cb(); } void UpdateActiveThread() { @@ -260,8 +255,6 @@ private: if (std::find(threads.begin(), threads.end(), active_thread) == threads.end()) { active_thread = threads[0]; } - active_thread->Resume(Kernel::SuspendType::Debug); - active_thread->SetStepState(Kernel::StepState::NotStepping); } const std::vector<Kernel::KThread*>& ThreadList() { @@ -277,7 +270,6 @@ private: boost::asio::io_context io_context; boost::process::async_pipe signal_pipe; boost::asio::ip::tcp::socket client_socket; - std::optional<std::unique_lock<std::mutex>> suspend; SignalInfo info; Kernel::KThread* active_thread; diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 8c79b4f0f..cd863e715 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -275,11 +275,15 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr a shmem->Close(); } -void KProcess::RegisterThread(const KThread* thread) { +void KProcess::RegisterThread(KThread* thread) { + KScopedLightLock lk{list_lock}; + thread_list.push_back(thread); } -void KProcess::UnregisterThread(const KThread* thread) { +void KProcess::UnregisterThread(KThread* thread) { + KScopedLightLock lk{list_lock}; + thread_list.remove(thread); } @@ -297,6 +301,50 @@ ResultCode KProcess::Reset() { return ResultSuccess; } +ResultCode KProcess::SetActivity(ProcessActivity activity) { + // Lock ourselves and the scheduler. + KScopedLightLock lk{state_lock}; + KScopedLightLock list_lk{list_lock}; + KScopedSchedulerLock sl{kernel}; + + // Validate our state. + R_UNLESS(status != ProcessStatus::Exiting, ResultInvalidState); + R_UNLESS(status != ProcessStatus::Exited, ResultInvalidState); + + // Either pause or resume. + if (activity == ProcessActivity::Paused) { + // Verify that we're not suspended. + if (is_suspended) { + return ResultInvalidState; + } + + // Suspend all threads. + for (auto* thread : GetThreadList()) { + thread->RequestSuspend(SuspendType::Process); + } + + // Set ourselves as suspended. + SetSuspended(true); + } else { + ASSERT(activity == ProcessActivity::Runnable); + + // Verify that we're suspended. + if (!is_suspended) { + return ResultInvalidState; + } + + // Resume all threads. + for (auto* thread : GetThreadList()) { + thread->Resume(SuspendType::Process); + } + + // Set ourselves as resumed. + SetSuspended(false); + } + + return ResultSuccess; +} + ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size) { program_id = metadata.GetTitleID(); @@ -556,9 +604,10 @@ bool KProcess::IsSignaled() const { } KProcess::KProcess(KernelCore& kernel_) - : KAutoObjectWithSlabHeapAndContainer{kernel_}, - page_table{std::make_unique<KPageTable>(kernel_.System())}, handle_table{kernel_}, - address_arbiter{kernel_.System()}, condition_var{kernel_.System()}, state_lock{kernel_} {} + : KAutoObjectWithSlabHeapAndContainer{kernel_}, page_table{std::make_unique<KPageTable>( + kernel_.System())}, + handle_table{kernel_}, address_arbiter{kernel_.System()}, condition_var{kernel_.System()}, + state_lock{kernel_}, list_lock{kernel_} {} KProcess::~KProcess() = default; diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 9f171e3da..e562a79b8 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -63,6 +63,11 @@ enum class ProcessStatus { DebugBreak, }; +enum class ProcessActivity : u32 { + Runnable, + Paused, +}; + class KProcess final : public KAutoObjectWithSlabHeapAndContainer<KProcess, KWorkerTask> { KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject); @@ -282,17 +287,17 @@ public: u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const; /// Gets the list of all threads created with this process as their owner. - const std::list<const KThread*>& GetThreadList() const { + std::list<KThread*>& GetThreadList() { return thread_list; } /// Registers a thread as being created under this process, /// adding it to this process' thread list. - void RegisterThread(const KThread* thread); + void RegisterThread(KThread* thread); /// Unregisters a thread from this process, removing it /// from this process' thread list. - void UnregisterThread(const KThread* thread); + void UnregisterThread(KThread* thread); /// Clears the signaled state of the process if and only if it's signaled. /// @@ -347,6 +352,8 @@ public: void DoWorkerTaskImpl(); + ResultCode SetActivity(ProcessActivity activity); + void PinCurrentThread(s32 core_id); void UnpinCurrentThread(s32 core_id); void UnpinThread(KThread* thread); @@ -442,7 +449,7 @@ private: std::array<u64, RANDOM_ENTROPY_SIZE> random_entropy{}; /// List of threads that are running with this process as their owner. - std::list<const KThread*> thread_list; + std::list<KThread*> thread_list; /// List of shared memory that are running with this process as their owner. std::list<KSharedMemoryInfo*> shared_memory_list; @@ -475,6 +482,7 @@ private: KThread* exception_thread{}; KLightLock state_lock; + KLightLock list_lock; using TLPTree = Common::IntrusiveRedBlackTreeBaseTraits<KThreadLocalPage>::TreeType<KThreadLocalPage>; diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index ea2160099..8d48a7901 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -267,15 +267,15 @@ ResultCode KThread::InitializeDummyThread(KThread* thread) { ResultCode KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) { return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main, Core::CpuManager::GetIdleThreadStartFunc(), - system.GetCpuManager().GetStartFuncParamater()); + system.GetCpuManager().GetStartFuncParameter()); } ResultCode KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread, KThreadFunction func, uintptr_t arg, s32 virt_core) { return InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority, - Core::CpuManager::GetSuspendThreadStartFunc(), - system.GetCpuManager().GetStartFuncParamater()); + Core::CpuManager::GetShutdownThreadStartFunc(), + system.GetCpuManager().GetStartFuncParameter()); } ResultCode KThread::InitializeUserThread(Core::System& system, KThread* thread, @@ -284,7 +284,7 @@ ResultCode KThread::InitializeUserThread(Core::System& system, KThread* thread, system.Kernel().GlobalSchedulerContext().AddThread(thread); return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, ThreadType::User, Core::CpuManager::GetGuestThreadStartFunc(), - system.GetCpuManager().GetStartFuncParamater()); + system.GetCpuManager().GetStartFuncParameter()); } void KThread::PostDestroy(uintptr_t arg) { diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b2c4f12b4..73593c7a0 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -76,7 +76,7 @@ struct KernelCore::Impl { InitializeMemoryLayout(); Init::InitializeKPageBufferSlabHeap(system); InitializeSchedulers(); - InitializeSuspendThreads(); + InitializeShutdownThreads(); InitializePreemption(kernel); RegisterHostThread(); @@ -143,9 +143,9 @@ struct KernelCore::Impl { CleanupObject(system_resource_limit); for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { - if (suspend_threads[core_id]) { - suspend_threads[core_id]->Close(); - suspend_threads[core_id] = nullptr; + if (shutdown_threads[core_id]) { + shutdown_threads[core_id]->Close(); + shutdown_threads[core_id] = nullptr; } schedulers[core_id]->Finalize(); @@ -247,14 +247,14 @@ struct KernelCore::Impl { system.CoreTiming().ScheduleEvent(time_interval, preemption_event); } - void InitializeSuspendThreads() { + void InitializeShutdownThreads() { for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { - suspend_threads[core_id] = KThread::Create(system.Kernel()); - ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id], {}, {}, + shutdown_threads[core_id] = KThread::Create(system.Kernel()); + ASSERT(KThread::InitializeHighPriorityThread(system, shutdown_threads[core_id], {}, {}, core_id) .IsSuccess()); - suspend_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); - suspend_threads[core_id]->DisableDispatch(); + shutdown_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); + shutdown_threads[core_id]->DisableDispatch(); } } @@ -769,7 +769,7 @@ struct KernelCore::Impl { std::weak_ptr<ServiceThread> default_service_thread; Common::ThreadWorker service_threads_manager; - std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads; + std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads; std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; @@ -920,6 +920,12 @@ const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const { return *impl->global_object_list_container; } +void KernelCore::InterruptAllPhysicalCores() { + for (auto& physical_core : impl->cores) { + physical_core.Interrupt(); + } +} + void KernelCore::InvalidateAllInstructionCaches() { for (auto& physical_core : impl->cores) { physical_core.ArmInterface().ClearInstructionCache(); @@ -1067,17 +1073,20 @@ const Kernel::KSharedMemory& KernelCore::GetHidBusSharedMem() const { return *impl->hidbus_shared_mem; } -void KernelCore::Suspend(bool in_suspention) { - const bool should_suspend = exception_exited || in_suspention; - { - KScopedSchedulerLock lock(*this); - const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; - for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { - impl->suspend_threads[core_id]->SetState(state); - impl->suspend_threads[core_id]->SetWaitReasonForDebugging( - ThreadWaitReasonForDebugging::Suspended); - } +void KernelCore::Suspend(bool suspended) { + const bool should_suspend{exception_exited || suspended}; + const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; + + for (auto* process : GetProcessList()) { + process->SetActivity(activity); + } +} + +void KernelCore::ShutdownCores() { + for (auto* thread : impl->shutdown_threads) { + void(thread->Run()); } + InterruptAllPhysicalCores(); } bool KernelCore::IsMulticore() const { diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 926e14c6f..4e7beab0e 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -184,6 +184,8 @@ public: const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const; + void InterruptAllPhysicalCores(); + void InvalidateAllInstructionCaches(); void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); @@ -269,12 +271,15 @@ public: /// Gets the shared memory object for HIDBus services. const Kernel::KSharedMemory& GetHidBusSharedMem() const; - /// Suspend/unsuspend the OS. - void Suspend(bool in_suspention); + /// Suspend/unsuspend all processes. + void Suspend(bool suspend); - /// Exceptional exit the OS. + /// Exceptional exit all processes. void ExceptionalExit(); + /// Notify emulated CPU cores to shut down. + void ShutdownCores(); + bool IsMulticore() const; bool IsShuttingDown() const; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 584fa5b1c..2ff6d5fa6 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -15,6 +15,7 @@ #include "common/scope_exit.h" #include "core/core.h" #include "core/core_timing.h" +#include "core/debugger/debugger.h" #include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/k_client_session.h" #include "core/hle/kernel/k_code_memory.h" @@ -627,6 +628,12 @@ static void Break(Core::System& system, u32 reason, u64 info1, u64 info2) { const auto thread_processor_id = current_thread->GetActiveCore(); system.ArmInterface(static_cast<std::size_t>(thread_processor_id)).LogBacktrace(); } + + if (system.DebuggerEnabled()) { + auto* thread = system.Kernel().GetCurrentEmuThread(); + system.GetDebugger().NotifyThreadStopped(thread); + thread->RequestSuspend(Kernel::SuspendType::Debug); + } } static void Break32(Core::System& system, u32 reason, u32 info1, u32 info2) { @@ -1719,11 +1726,12 @@ static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_ha /// Exits the current process static void ExitProcess(Core::System& system) { auto* current_process = system.Kernel().CurrentProcess(); - UNIMPLEMENTED(); LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->GetProcessID()); ASSERT_MSG(current_process->GetStatus() == ProcessStatus::Running, "Process has already exited"); + + system.Exit(); } static void ExitProcess32(Core::System& system) { @@ -2530,7 +2538,7 @@ static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAdd return ResultOutOfRange; } - const auto* const current_process = system.Kernel().CurrentProcess(); + auto* const current_process = system.Kernel().CurrentProcess(); const auto total_copy_size = out_thread_ids_size * sizeof(u64); if (out_thread_ids_size > 0 && @@ -2982,7 +2990,6 @@ static const FunctionDef* GetSVCInfo64(u32 func_num) { } void Call(Core::System& system, u32 immediate) { - system.ExitDynarmicProfile(); auto& kernel = system.Kernel(); kernel.EnterSVCProfile(); @@ -3007,8 +3014,6 @@ void Call(Core::System& system, u32 immediate) { auto* host_context = thread->GetHostContext().get(); host_context->Rewind(); } - - system.EnterDynarmicProfile(); } } // namespace Kernel::Svc diff --git a/src/core/hle/service/glue/notif.cpp b/src/core/hle/service/glue/notif.cpp index b971846e7..3ace2dabd 100644 --- a/src/core/hle/service/glue/notif.cpp +++ b/src/core/hle/service/glue/notif.cpp @@ -1,6 +1,11 @@ // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include <algorithm> +#include <cstring> + +#include "common/assert.h" +#include "common/logging/log.h" #include "core/hle/ipc_helpers.h" #include "core/hle/service/glue/notif.h" @@ -9,11 +14,11 @@ namespace Service::Glue { NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { // clang-format off static const FunctionInfo functions[] = { - {500, nullptr, "RegisterAlarmSetting"}, - {510, nullptr, "UpdateAlarmSetting"}, + {500, &NOTIF_A::RegisterAlarmSetting, "RegisterAlarmSetting"}, + {510, &NOTIF_A::UpdateAlarmSetting, "UpdateAlarmSetting"}, {520, &NOTIF_A::ListAlarmSettings, "ListAlarmSettings"}, - {530, nullptr, "LoadApplicationParameter"}, - {540, nullptr, "DeleteAlarmSetting"}, + {530, &NOTIF_A::LoadApplicationParameter, "LoadApplicationParameter"}, + {540, &NOTIF_A::DeleteAlarmSetting, "DeleteAlarmSetting"}, {1000, &NOTIF_A::Initialize, "Initialize"}, }; // clang-format on @@ -23,21 +28,132 @@ NOTIF_A::NOTIF_A(Core::System& system_) : ServiceFramework{system_, "notif:a"} { NOTIF_A::~NOTIF_A() = default; +void NOTIF_A::RegisterAlarmSetting(Kernel::HLERequestContext& ctx) { + const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); + const auto application_parameter_size = ctx.GetReadBufferSize(1); + + ASSERT_MSG(alarm_setting_buffer_size == sizeof(AlarmSetting), + "alarm_setting_buffer_size is not 0x40 bytes"); + ASSERT_MSG(application_parameter_size <= sizeof(ApplicationParameter), + "application_parameter_size is bigger than 0x400 bytes"); + + AlarmSetting new_alarm{}; + memcpy(&new_alarm, ctx.ReadBuffer(0).data(), sizeof(AlarmSetting)); + + // TODO: Count alarms per game id + if (alarms.size() >= max_alarms) { + LOG_ERROR(Service_NOTIF, "Alarm limit reached"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultUnknown); + return; + } + + new_alarm.alarm_setting_id = last_alarm_setting_id++; + alarms.push_back(new_alarm); + + // TODO: Save application parameter data + + LOG_WARNING(Service_NOTIF, + "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}", + application_parameter_size, new_alarm.alarm_setting_id, new_alarm.kind, + new_alarm.muted); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + rb.Push(new_alarm.alarm_setting_id); +} + +void NOTIF_A::UpdateAlarmSetting(Kernel::HLERequestContext& ctx) { + const auto alarm_setting_buffer_size = ctx.GetReadBufferSize(0); + const auto application_parameter_size = ctx.GetReadBufferSize(1); + + ASSERT_MSG(alarm_setting_buffer_size == sizeof(AlarmSetting), + "alarm_setting_buffer_size is not 0x40 bytes"); + ASSERT_MSG(application_parameter_size <= sizeof(ApplicationParameter), + "application_parameter_size is bigger than 0x400 bytes"); + + AlarmSetting alarm_setting{}; + memcpy(&alarm_setting, ctx.ReadBuffer(0).data(), sizeof(AlarmSetting)); + + const auto alarm_it = GetAlarmFromId(alarm_setting.alarm_setting_id); + if (alarm_it != alarms.end()) { + LOG_DEBUG(Service_NOTIF, "Alarm updated"); + *alarm_it = alarm_setting; + // TODO: Save application parameter data + } + + LOG_WARNING(Service_NOTIF, + "(STUBBED) called, application_parameter_size={}, setting_id={}, kind={}, muted={}", + application_parameter_size, alarm_setting.alarm_setting_id, alarm_setting.kind, + alarm_setting.muted); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); +} + void NOTIF_A::ListAlarmSettings(Kernel::HLERequestContext& ctx) { - // Returns an array of AlarmSetting - constexpr s32 alarm_count = 0; + LOG_INFO(Service_NOTIF, "called, alarm_count={}", alarms.size()); - LOG_WARNING(Service_NOTIF, "(STUBBED) called"); + // TODO: Only return alarms of this game id + ctx.WriteBuffer(alarms); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(alarm_count); + rb.Push(static_cast<u32>(alarms.size())); +} + +void NOTIF_A::LoadApplicationParameter(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; + + const auto alarm_it = GetAlarmFromId(alarm_setting_id); + if (alarm_it == alarms.end()) { + LOG_ERROR(Service_NOTIF, "Invalid alarm setting id={}", alarm_setting_id); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultUnknown); + return; + } + + // TODO: Read application parameter related to this setting id + ApplicationParameter application_parameter{}; + + LOG_WARNING(Service_NOTIF, "(STUBBED) called, alarm_setting_id={}", alarm_setting_id); + + ctx.WriteBuffer(application_parameter); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + rb.Push(static_cast<u32>(application_parameter.size())); +} + +void NOTIF_A::DeleteAlarmSetting(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto alarm_setting_id{rp.Pop<AlarmSettingId>()}; + + std::erase_if(alarms, [alarm_setting_id](const AlarmSetting& alarm) { + return alarm.alarm_setting_id == alarm_setting_id; + }); + + LOG_INFO(Service_NOTIF, "called, alarm_setting_id={}", alarm_setting_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); } void NOTIF_A::Initialize(Kernel::HLERequestContext& ctx) { + // TODO: Load previous alarms from config + LOG_WARNING(Service_NOTIF, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } +std::vector<NOTIF_A::AlarmSetting>::iterator NOTIF_A::GetAlarmFromId( + AlarmSettingId alarm_setting_id) { + return std::find_if(alarms.begin(), alarms.end(), + [alarm_setting_id](const AlarmSetting& alarm) { + return alarm.alarm_setting_id == alarm_setting_id; + }); +} + } // namespace Service::Glue diff --git a/src/core/hle/service/glue/notif.h b/src/core/hle/service/glue/notif.h index 7310d7f72..4467e1f35 100644 --- a/src/core/hle/service/glue/notif.h +++ b/src/core/hle/service/glue/notif.h @@ -3,6 +3,10 @@ #pragma once +#include <array> +#include <vector> + +#include "common/uuid.h" #include "core/hle/service/service.h" namespace Core { @@ -17,8 +21,52 @@ public: ~NOTIF_A() override; private: + static constexpr std::size_t max_alarms = 8; + + // This is nn::notification::AlarmSettingId + using AlarmSettingId = u16; + static_assert(sizeof(AlarmSettingId) == 0x2, "AlarmSettingId is an invalid size"); + + using ApplicationParameter = std::array<u8, 0x400>; + static_assert(sizeof(ApplicationParameter) == 0x400, "ApplicationParameter is an invalid size"); + + struct DailyAlarmSetting { + s8 hour; + s8 minute; + }; + static_assert(sizeof(DailyAlarmSetting) == 0x2, "DailyAlarmSetting is an invalid size"); + + struct WeeklyScheduleAlarmSetting { + INSERT_PADDING_BYTES(0xA); + std::array<DailyAlarmSetting, 0x7> day_of_week; + }; + static_assert(sizeof(WeeklyScheduleAlarmSetting) == 0x18, + "WeeklyScheduleAlarmSetting is an invalid size"); + + // This is nn::notification::AlarmSetting + struct AlarmSetting { + AlarmSettingId alarm_setting_id; + u8 kind; + u8 muted; + INSERT_PADDING_BYTES(0x4); + Common::UUID account_id; + u64 application_id; + INSERT_PADDING_BYTES(0x8); + WeeklyScheduleAlarmSetting schedule; + }; + static_assert(sizeof(AlarmSetting) == 0x40, "AlarmSetting is an invalid size"); + + void RegisterAlarmSetting(Kernel::HLERequestContext& ctx); + void UpdateAlarmSetting(Kernel::HLERequestContext& ctx); void ListAlarmSettings(Kernel::HLERequestContext& ctx); + void LoadApplicationParameter(Kernel::HLERequestContext& ctx); + void DeleteAlarmSetting(Kernel::HLERequestContext& ctx); void Initialize(Kernel::HLERequestContext& ctx); + + std::vector<AlarmSetting>::iterator GetAlarmFromId(AlarmSettingId alarm_setting_id); + + std::vector<AlarmSetting> alarms{}; + AlarmSettingId last_alarm_setting_id{}; }; } // namespace Service::Glue diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 705fefc83..527531f29 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -150,9 +150,9 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector event.event->GetWritableEvent().Clear(); if (events_interface.failed[event_id]) { { - auto lk = system.StallCPU(); + auto lk = system.StallProcesses(); gpu.WaitFence(params.syncpt_id, target_value); - system.UnstallCPU(); + system.UnstallProcesses(); } std::memcpy(output.data(), ¶ms, sizeof(params)); events_interface.failed[event_id] = false; diff --git a/src/input_common/CMakeLists.txt b/src/input_common/CMakeLists.txt index d4fa69a77..48e799cf5 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt @@ -44,7 +44,6 @@ else() -Werror -Werror=conversion -Werror=ignored-qualifiers - -Werror=shadow $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> -Werror=unused-variable diff --git a/src/shader_recompiler/CMakeLists.txt b/src/shader_recompiler/CMakeLists.txt index 4c76ce1ea..ae1dbe619 100644 --- a/src/shader_recompiler/CMakeLists.txt +++ b/src/shader_recompiler/CMakeLists.txt @@ -253,9 +253,6 @@ else() -Werror -Werror=conversion -Werror=ignored-qualifiers - -Werror=implicit-fallthrough - -Werror=shadow - -Werror=sign-compare $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter> $<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-variable> -Werror=unused-variable diff --git a/src/video_core/CMakeLists.txt b/src/video_core/CMakeLists.txt index 256695804..14de7bc89 100644 --- a/src/video_core/CMakeLists.txt +++ b/src/video_core/CMakeLists.txt @@ -258,10 +258,6 @@ if (MSVC) target_compile_options(video_core PRIVATE /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data /we4244 # 'conversion': conversion from 'type1' to 'type2', possible loss of data - /we4456 # Declaration of 'identifier' hides previous local declaration - /we4457 # Declaration of 'identifier' hides function parameter - /we4458 # Declaration of 'identifier' hides class member - /we4459 # Declaration of 'identifier' hides global declaration ) else() target_compile_options(video_core PRIVATE @@ -269,7 +265,6 @@ else() -Wno-error=sign-conversion -Werror=pessimizing-move -Werror=redundant-move - -Werror=shadow -Werror=type-limits $<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess> diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h index ad9fd5eff..be0ac2214 100644 --- a/src/video_core/gpu_thread.h +++ b/src/video_core/gpu_thread.h @@ -98,7 +98,7 @@ struct CommandDataContainer { struct SynchState final { using CommandQueue = Common::MPSCQueue<CommandDataContainer>; std::mutex write_lock; - CommandQueue queue{512}; // size must be 2^n + CommandQueue queue; u64 last_fence{}; std::atomic<u64> signaled_fence{}; std::condition_variable_any cv; diff --git a/src/video_core/renderer_vulkan/vk_compute_pass.cpp b/src/video_core/renderer_vulkan/vk_compute_pass.cpp index a3d478837..4cba777e6 100644 --- a/src/video_core/renderer_vulkan/vk_compute_pass.cpp +++ b/src/video_core/renderer_vulkan/vk_compute_pass.cpp @@ -328,31 +328,32 @@ void ASTCDecoderPass::Assemble(Image& image, const StagingBufferRef& map, const VkImageAspectFlags aspect_mask = image.AspectMask(); const VkImage vk_image = image.Handle(); const bool is_initialized = image.ExchangeInitialization(); - scheduler.Record( - [vk_pipeline, vk_image, aspect_mask, is_initialized](vk::CommandBuffer cmdbuf) { - const VkImageMemoryBarrier image_barrier{ - .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, - .pNext = nullptr, - .srcAccessMask = is_initialized ? VK_ACCESS_SHADER_WRITE_BIT : VK_ACCESS_NONE, - .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, - .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, - .newLayout = VK_IMAGE_LAYOUT_GENERAL, - .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, - .image = vk_image, - .subresourceRange{ - .aspectMask = aspect_mask, - .baseMipLevel = 0, - .levelCount = VK_REMAINING_MIP_LEVELS, - .baseArrayLayer = 0, - .layerCount = VK_REMAINING_ARRAY_LAYERS, - }, - }; - cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT - : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); - cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); - }); + scheduler.Record([vk_pipeline, vk_image, aspect_mask, + is_initialized](vk::CommandBuffer cmdbuf) { + const VkImageMemoryBarrier image_barrier{ + .sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, + .pNext = nullptr, + .srcAccessMask = static_cast<VkAccessFlags>(is_initialized ? VK_ACCESS_SHADER_WRITE_BIT + : VK_ACCESS_NONE), + .dstAccessMask = VK_ACCESS_SHADER_READ_BIT | VK_ACCESS_SHADER_WRITE_BIT, + .oldLayout = is_initialized ? VK_IMAGE_LAYOUT_GENERAL : VK_IMAGE_LAYOUT_UNDEFINED, + .newLayout = VK_IMAGE_LAYOUT_GENERAL, + .srcQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .dstQueueFamilyIndex = VK_QUEUE_FAMILY_IGNORED, + .image = vk_image, + .subresourceRange{ + .aspectMask = aspect_mask, + .baseMipLevel = 0, + .levelCount = VK_REMAINING_MIP_LEVELS, + .baseArrayLayer = 0, + .layerCount = VK_REMAINING_ARRAY_LAYERS, + }, + }; + cmdbuf.PipelineBarrier(is_initialized ? VK_PIPELINE_STAGE_ALL_COMMANDS_BIT + : VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, 0, image_barrier); + cmdbuf.BindPipeline(VK_PIPELINE_BIND_POINT_COMPUTE, vk_pipeline); + }); for (const VideoCommon::SwizzleParameters& swizzle : swizzles) { const size_t input_offset = swizzle.buffer_offset + map.offset; const u32 num_dispatches_x = Common::DivCeil(swizzle.num_tiles.width, 8U); diff --git a/src/web_service/telemetry_json.cpp b/src/web_service/telemetry_json.cpp index 6215c914f..46faddb61 100644 --- a/src/web_service/telemetry_json.cpp +++ b/src/web_service/telemetry_json.cpp @@ -13,8 +13,8 @@ namespace WebService { namespace Telemetry = Common::Telemetry; struct TelemetryJson::Impl { - Impl(std::string host, std::string username, std::string token) - : host{std::move(host)}, username{std::move(username)}, token{std::move(token)} {} + Impl(std::string host_, std::string username_, std::string token_) + : host{std::move(host_)}, username{std::move(username_)}, token{std::move(token_)} {} nlohmann::json& TopSection() { return sections[static_cast<u8>(Telemetry::FieldType::None)]; diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp index 58b0c2f10..dce9772fe 100644 --- a/src/web_service/web_backend.cpp +++ b/src/web_service/web_backend.cpp @@ -30,10 +30,10 @@ constexpr std::array<const char, 1> API_VERSION{'1'}; constexpr std::size_t TIMEOUT_SECONDS = 30; struct Client::Impl { - Impl(std::string host, std::string username, std::string token) - : host{std::move(host)}, username{std::move(username)}, token{std::move(token)} { + Impl(std::string host_, std::string username_, std::string token_) + : host{std::move(host_)}, username{std::move(username_)}, token{std::move(token_)} { std::scoped_lock lock{jwt_cache.mutex}; - if (this->username == jwt_cache.username && this->token == jwt_cache.token) { + if (username == jwt_cache.username && token == jwt_cache.token) { jwt = jwt_cache.jwt; } } @@ -69,8 +69,8 @@ struct Client::Impl { */ WebResult GenericRequest(const std::string& method, const std::string& path, const std::string& data, const std::string& accept, - const std::string& jwt = "", const std::string& username = "", - const std::string& token = "") { + const std::string& jwt_ = "", const std::string& username_ = "", + const std::string& token_ = "") { if (cli == nullptr) { cli = std::make_unique<httplib::Client>(host.c_str()); } @@ -85,14 +85,14 @@ struct Client::Impl { cli->set_write_timeout(TIMEOUT_SECONDS); httplib::Headers params; - if (!jwt.empty()) { + if (!jwt_.empty()) { params = { - {std::string("Authorization"), fmt::format("Bearer {}", jwt)}, + {std::string("Authorization"), fmt::format("Bearer {}", jwt_)}, }; - } else if (!username.empty()) { + } else if (!username_.empty()) { params = { - {std::string("x-username"), username}, - {std::string("x-token"), token}, + {std::string("x-username"), username_}, + {std::string("x-token"), token_}, }; } diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index bde465485..cbe4e2daa 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -127,7 +127,7 @@ void EmuThread::run() { class OpenGLSharedContext : public Core::Frontend::GraphicsContext { public: /// Create the original context that should be shared from - explicit OpenGLSharedContext(QSurface* surface) : surface(surface) { + explicit OpenGLSharedContext(QSurface* surface_) : surface{surface_} { QSurfaceFormat format; format.setVersion(4, 6); format.setProfile(QSurfaceFormat::CompatibilityProfile); @@ -364,9 +364,9 @@ void GRenderWindow::RestoreGeometry() { QWidget::restoreGeometry(geometry); } -void GRenderWindow::restoreGeometry(const QByteArray& geometry) { +void GRenderWindow::restoreGeometry(const QByteArray& geometry_) { // Make sure users of this class don't need to deal with backing up the geometry themselves - QWidget::restoreGeometry(geometry); + QWidget::restoreGeometry(geometry_); BackupGeometry(); } @@ -1014,8 +1014,8 @@ QStringList GRenderWindow::GetUnsupportedGLExtensions() const { return unsupported_ext; } -void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread) { - this->emu_thread = emu_thread; +void GRenderWindow::OnEmulationStarting(EmuThread* emu_thread_) { + emu_thread = emu_thread_; } void GRenderWindow::OnEmulationStopping() { diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index d01538039..81fe52c0e 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -56,12 +56,12 @@ public: /** * Sets whether the emulation thread is running or not - * @param running Boolean value, set the emulation thread to running if true + * @param running_ Boolean value, set the emulation thread to running if true * @note This function is thread-safe */ - void SetRunning(bool running) { + void SetRunning(bool running_) { std::unique_lock lock{running_mutex}; - this->running = running; + running = running_; lock.unlock(); running_cv.notify_all(); if (!running) { @@ -138,8 +138,8 @@ public: void BackupGeometry(); void RestoreGeometry(); - void restoreGeometry(const QByteArray& geometry); // overridden - QByteArray saveGeometry(); // overridden + void restoreGeometry(const QByteArray& geometry_); // overridden + QByteArray saveGeometry(); // overridden qreal windowPixelRatio() const; @@ -189,7 +189,7 @@ public: void Exit(); public slots: - void OnEmulationStarting(EmuThread* emu_thread); + void OnEmulationStarting(EmuThread* emu_thread_); void OnEmulationStopping(); void OnFramebufferSizeChanged(); diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index b415a1cc4..e99657bd6 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp @@ -27,12 +27,11 @@ #include "yuzu/hotkeys.h" #include "yuzu/uisettings.h" -ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, +ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, InputCommon::InputSubsystem* input_subsystem, Core::System& system_) - : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, - registry(registry), system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_, - this)}, + : QDialog(parent), ui{std::make_unique<Ui::ConfigureDialog>()}, registry{registry_}, + system{system_}, audio_tab{std::make_unique<ConfigureAudio>(system_, this)}, cpu_tab{std::make_unique<ConfigureCpu>(system_, this)}, debug_tab_tab{std::make_unique<ConfigureDebugTab>(system_, this)}, filesystem_tab{std::make_unique<ConfigureFilesystem>(this)}, diff --git a/src/yuzu/configuration/configure_dialog.h b/src/yuzu/configuration/configure_dialog.h index 32ddfd4e0..12cf25daf 100644 --- a/src/yuzu/configuration/configure_dialog.h +++ b/src/yuzu/configuration/configure_dialog.h @@ -40,7 +40,7 @@ class ConfigureDialog : public QDialog { Q_OBJECT public: - explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry, + explicit ConfigureDialog(QWidget* parent, HotkeyRegistry& registry_, InputCommon::InputSubsystem* input_subsystem, Core::System& system_); ~ConfigureDialog() override; diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 1c05dd0f3..f3be9a374 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -264,15 +264,16 @@ QString ConfigureInputPlayer::AnalogToText(const Common::ParamPackage& param, return QObject::tr("[unknown]"); } -ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index, - QWidget* bottom_row, +ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index_, + QWidget* bottom_row_, InputCommon::InputSubsystem* input_subsystem_, InputProfiles* profiles_, Core::HID::HIDCore& hid_core_, - bool is_powered_on_, bool debug) - : QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index(player_index), - debug(debug), is_powered_on{is_powered_on_}, input_subsystem{input_subsystem_}, - profiles(profiles_), timeout_timer(std::make_unique<QTimer>()), - poll_timer(std::make_unique<QTimer>()), bottom_row(bottom_row), hid_core{hid_core_} { + bool is_powered_on_, bool debug_) + : QWidget(parent), + ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index{player_index_}, debug{debug_}, + is_powered_on{is_powered_on_}, input_subsystem{input_subsystem_}, profiles(profiles_), + timeout_timer(std::make_unique<QTimer>()), + poll_timer(std::make_unique<QTimer>()), bottom_row{bottom_row_}, hid_core{hid_core_} { if (player_index == 0) { auto* emulated_controller_p1 = hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); @@ -696,39 +697,38 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i UpdateControllerEnabledButtons(); UpdateControllerButtonNames(); UpdateMotionButtons(); - connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), - [this, player_index](int) { - UpdateControllerAvailableButtons(); - UpdateControllerEnabledButtons(); - UpdateControllerButtonNames(); - UpdateMotionButtons(); - const Core::HID::NpadStyleIndex type = - GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); - - if (player_index == 0) { - auto* emulated_controller_p1 = - hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); - auto* emulated_controller_handheld = - hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); - bool is_connected = emulated_controller->IsConnected(true); - - emulated_controller_p1->SetNpadStyleIndex(type); - emulated_controller_handheld->SetNpadStyleIndex(type); - if (is_connected) { - if (type == Core::HID::NpadStyleIndex::Handheld) { - emulated_controller_p1->Disconnect(); - emulated_controller_handheld->Connect(true); - emulated_controller = emulated_controller_handheld; - } else { - emulated_controller_handheld->Disconnect(); - emulated_controller_p1->Connect(true); - emulated_controller = emulated_controller_p1; - } - } - ui->controllerFrame->SetController(emulated_controller); + connect(ui->comboControllerType, qOverload<int>(&QComboBox::currentIndexChanged), [this](int) { + UpdateControllerAvailableButtons(); + UpdateControllerEnabledButtons(); + UpdateControllerButtonNames(); + UpdateMotionButtons(); + const Core::HID::NpadStyleIndex type = + GetControllerTypeFromIndex(ui->comboControllerType->currentIndex()); + + if (player_index == 0) { + auto* emulated_controller_p1 = + hid_core.GetEmulatedController(Core::HID::NpadIdType::Player1); + auto* emulated_controller_handheld = + hid_core.GetEmulatedController(Core::HID::NpadIdType::Handheld); + bool is_connected = emulated_controller->IsConnected(true); + + emulated_controller_p1->SetNpadStyleIndex(type); + emulated_controller_handheld->SetNpadStyleIndex(type); + if (is_connected) { + if (type == Core::HID::NpadStyleIndex::Handheld) { + emulated_controller_p1->Disconnect(); + emulated_controller_handheld->Connect(true); + emulated_controller = emulated_controller_handheld; + } else { + emulated_controller_handheld->Disconnect(); + emulated_controller_p1->Connect(true); + emulated_controller = emulated_controller_p1; } - emulated_controller->SetNpadStyleIndex(type); - }); + } + ui->controllerFrame->SetController(emulated_controller); + } + emulated_controller->SetNpadStyleIndex(type); + }); connect(ui->comboDevices, qOverload<int>(&QComboBox::activated), this, &ConfigureInputPlayer::UpdateMappingWithDefaults); diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp index 54b3fe150..af8343b2e 100644 --- a/src/yuzu/configuration/configure_per_game.cpp +++ b/src/yuzu/configuration/configure_per_game.cpp @@ -35,10 +35,10 @@ #include "yuzu/uisettings.h" #include "yuzu/util/util.h" -ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id, const std::string& file_name, +ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, Core::System& system_) - : QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()), - title_id(title_id), system{system_} { + : QDialog(parent), + ui(std::make_unique<Ui::ConfigurePerGame>()), title_id{title_id_}, system{system_} { const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name)); const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename()) : fmt::format("{:016X}", title_id); @@ -116,8 +116,8 @@ void ConfigurePerGame::HandleApplyButtonClicked() { ApplyConfiguration(); } -void ConfigurePerGame::LoadFromFile(FileSys::VirtualFile file) { - this->file = std::move(file); +void ConfigurePerGame::LoadFromFile(FileSys::VirtualFile file_) { + file = std::move(file_); LoadConfiguration(); } diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h index e6dc05546..17a98a0f3 100644 --- a/src/yuzu/configuration/configure_per_game.h +++ b/src/yuzu/configuration/configure_per_game.h @@ -39,14 +39,14 @@ class ConfigurePerGame : public QDialog { public: // Cannot use std::filesystem::path due to https://bugreports.qt.io/browse/QTBUG-73263 - explicit ConfigurePerGame(QWidget* parent, u64 title_id, const std::string& file_name, + explicit ConfigurePerGame(QWidget* parent, u64 title_id_, const std::string& file_name, Core::System& system_); ~ConfigurePerGame() override; /// Save all button configurations to settings file void ApplyConfiguration(); - void LoadFromFile(FileSys::VirtualFile file); + void LoadFromFile(FileSys::VirtualFile file_); private: void changeEvent(QEvent* event) override; diff --git a/src/yuzu/configuration/configure_per_game_addons.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp index 7893a85bb..4906997ab 100644 --- a/src/yuzu/configuration/configure_per_game_addons.cpp +++ b/src/yuzu/configuration/configure_per_game_addons.cpp @@ -89,8 +89,8 @@ void ConfigurePerGameAddons::ApplyConfiguration() { Settings::values.disabled_addons[title_id] = disabled_addons; } -void ConfigurePerGameAddons::LoadFromFile(FileSys::VirtualFile file) { - this->file = std::move(file); +void ConfigurePerGameAddons::LoadFromFile(FileSys::VirtualFile file_) { + file = std::move(file_); LoadConfiguration(); } diff --git a/src/yuzu/configuration/configure_per_game_addons.h b/src/yuzu/configuration/configure_per_game_addons.h index 24b017494..14690fba8 100644 --- a/src/yuzu/configuration/configure_per_game_addons.h +++ b/src/yuzu/configuration/configure_per_game_addons.h @@ -35,7 +35,7 @@ public: /// Save all button configurations to settings file void ApplyConfiguration(); - void LoadFromFile(FileSys::VirtualFile file); + void LoadFromFile(FileSys::VirtualFile file_); void SetTitleId(u64 id); diff --git a/src/yuzu/configuration/configure_ringcon.cpp b/src/yuzu/configuration/configure_ringcon.cpp index 4fcc22b7a..688c2dd38 100644 --- a/src/yuzu/configuration/configure_ringcon.cpp +++ b/src/yuzu/configuration/configure_ringcon.cpp @@ -165,10 +165,10 @@ ConfigureRingController::ConfigureRingController(QWidget* parent, const std::string invert_str = invert_value ? "+" : "-"; param.Set("invert_x", invert_str); emulated_device->SetRingParam(param); - for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; - ++sub_button_id) { - analog_map_buttons[sub_button_id]->setText( - AnalogToText(param, analog_sub_buttons[sub_button_id])); + for (int sub_button_id2 = 0; sub_button_id2 < ANALOG_SUB_BUTTONS_NUM; + ++sub_button_id2) { + analog_map_buttons[sub_button_id2]->setText( + AnalogToText(param, analog_sub_buttons[sub_button_id2])); } }); context_menu.exec( diff --git a/src/yuzu/configuration/configure_touch_from_button.cpp b/src/yuzu/configuration/configure_touch_from_button.cpp index c17da6fd1..06cc452c3 100644 --- a/src/yuzu/configuration/configure_touch_from_button.cpp +++ b/src/yuzu/configuration/configure_touch_from_button.cpp @@ -68,10 +68,10 @@ static QString ButtonToText(const Common::ParamPackage& param) { } ConfigureTouchFromButton::ConfigureTouchFromButton( - QWidget* parent, const std::vector<Settings::TouchFromButtonMap>& touch_maps, + QWidget* parent, const std::vector<Settings::TouchFromButtonMap>& touch_maps_, InputCommon::InputSubsystem* input_subsystem_, const int default_index) : QDialog(parent), ui(std::make_unique<Ui::ConfigureTouchFromButton>()), - touch_maps(touch_maps), input_subsystem{input_subsystem_}, selected_index(default_index), + touch_maps{touch_maps_}, input_subsystem{input_subsystem_}, selected_index{default_index}, timeout_timer(std::make_unique<QTimer>()), poll_timer(std::make_unique<QTimer>()) { ui->setupUi(this); binding_list_model = new QStandardItemModel(0, 3, this); diff --git a/src/yuzu/configuration/configure_touch_from_button.h b/src/yuzu/configuration/configure_touch_from_button.h index e1400481a..b8c55db66 100644 --- a/src/yuzu/configuration/configure_touch_from_button.h +++ b/src/yuzu/configuration/configure_touch_from_button.h @@ -37,7 +37,7 @@ class ConfigureTouchFromButton : public QDialog { public: explicit ConfigureTouchFromButton(QWidget* parent, - const std::vector<Settings::TouchFromButtonMap>& touch_maps, + const std::vector<Settings::TouchFromButtonMap>& touch_maps_, InputCommon::InputSubsystem* input_subsystem_, int default_index = 0); ~ConfigureTouchFromButton() override; diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 8f486a131..0ea31cd33 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -113,9 +113,9 @@ QString WaitTreeText::GetText() const { return text; } -WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table, +WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address_, const Kernel::KHandleTable& handle_table, Core::System& system_) - : mutex_address(mutex_address), system{system_} { + : mutex_address{mutex_address_}, system{system_} { mutex_value = system.Memory().Read32(mutex_address); owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask); owner = handle_table.GetObject<Kernel::KThread>(owner_handle).GetPointerUnsafe(); @@ -140,8 +140,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() cons return list; } -WaitTreeCallstack::WaitTreeCallstack(const Kernel::KThread& thread, Core::System& system_) - : thread(thread), system{system_} {} +WaitTreeCallstack::WaitTreeCallstack(const Kernel::KThread& thread_, Core::System& system_) + : thread{thread_}, system{system_} {} WaitTreeCallstack::~WaitTreeCallstack() = default; QString WaitTreeCallstack::GetText() const { @@ -171,8 +171,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() cons } WaitTreeSynchronizationObject::WaitTreeSynchronizationObject( - const Kernel::KSynchronizationObject& o, Core::System& system_) - : object(o), system{system_} {} + const Kernel::KSynchronizationObject& object_, Core::System& system_) + : object{object_}, system{system_} {} WaitTreeSynchronizationObject::~WaitTreeSynchronizationObject() = default; WaitTreeExpandableItem::WaitTreeExpandableItem() = default; @@ -380,8 +380,8 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { return list; } -WaitTreeEvent::WaitTreeEvent(const Kernel::KReadableEvent& object, Core::System& system_) - : WaitTreeSynchronizationObject(object, system_) {} +WaitTreeEvent::WaitTreeEvent(const Kernel::KReadableEvent& object_, Core::System& system_) + : WaitTreeSynchronizationObject(object_, system_) {} WaitTreeEvent::~WaitTreeEvent() = default; WaitTreeThreadList::WaitTreeThreadList(std::vector<Kernel::KThread*>&& list, Core::System& system_) diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 4a36dfc48..f21b9f467 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -78,7 +78,7 @@ public: class WaitTreeMutexInfo : public WaitTreeExpandableItem { Q_OBJECT public: - explicit WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table, + explicit WaitTreeMutexInfo(VAddr mutex_address_, const Kernel::KHandleTable& handle_table, Core::System& system_); ~WaitTreeMutexInfo() override; @@ -97,7 +97,7 @@ private: class WaitTreeCallstack : public WaitTreeExpandableItem { Q_OBJECT public: - explicit WaitTreeCallstack(const Kernel::KThread& thread, Core::System& system_); + explicit WaitTreeCallstack(const Kernel::KThread& thread_, Core::System& system_); ~WaitTreeCallstack() override; QString GetText() const override; @@ -112,7 +112,7 @@ private: class WaitTreeSynchronizationObject : public WaitTreeExpandableItem { Q_OBJECT public: - explicit WaitTreeSynchronizationObject(const Kernel::KSynchronizationObject& object, + explicit WaitTreeSynchronizationObject(const Kernel::KSynchronizationObject& object_, Core::System& system_); ~WaitTreeSynchronizationObject() override; @@ -162,7 +162,7 @@ private: class WaitTreeEvent : public WaitTreeSynchronizationObject { Q_OBJECT public: - explicit WaitTreeEvent(const Kernel::KReadableEvent& object, Core::System& system_); + explicit WaitTreeEvent(const Kernel::KReadableEvent& object_, Core::System& system_); ~WaitTreeEvent() override; }; diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp index 6321afc83..05d309827 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp @@ -28,8 +28,8 @@ #include "yuzu/uisettings.h" #include "yuzu/util/controller_navigation.h" -GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist, QObject* parent) - : QObject(parent), gamelist{gamelist} {} +GameListSearchField::KeyReleaseEater::KeyReleaseEater(GameList* gamelist_, QObject* parent) + : QObject(parent), gamelist{gamelist_} {} // EventFilter in order to process systemkeys while editing the searchfield bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* event) { @@ -80,9 +80,9 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve return QObject::eventFilter(obj, event); } -void GameListSearchField::setFilterResult(int visible, int total) { - this->visible = visible; - this->total = total; +void GameListSearchField::setFilterResult(int visible_, int total_) { + visible = visible_; + total = total_; label_filter_result->setText(tr("%1 of %n result(s)", "", total).arg(visible)); } @@ -309,9 +309,9 @@ void GameList::OnFilterCloseClicked() { main_window->filterBarSetChecked(false); } -GameList::GameList(FileSys::VirtualFilesystem vfs, FileSys::ManualContentProvider* provider, +GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvider* provider_, Core::System& system_, GMainWindow* parent) - : QWidget{parent}, vfs(std::move(vfs)), provider(provider), system{system_} { + : QWidget{parent}, vfs{std::move(vfs_)}, provider{provider_}, system{system_} { watcher = new QFileSystemWatcher(this); connect(watcher, &QFileSystemWatcher::directoryChanged, this, &GameList::RefreshGameDirectory); diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h index 464da98ad..bc36d015a 100644 --- a/src/yuzu/game_list.h +++ b/src/yuzu/game_list.h @@ -67,8 +67,8 @@ public: COLUMN_COUNT, // Number of columns }; - explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs, - FileSys::ManualContentProvider* provider, Core::System& system_, + explicit GameList(std::shared_ptr<FileSys::VfsFilesystem> vfs_, + FileSys::ManualContentProvider* provider_, Core::System& system_, GMainWindow* parent = nullptr); ~GameList() override; diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h index f2a986ed8..cd7d63536 100644 --- a/src/yuzu/game_list_p.h +++ b/src/yuzu/game_list_p.h @@ -225,8 +225,8 @@ public: static constexpr int GameDirRole = Qt::UserRole + 2; explicit GameListDir(UISettings::GameDir& directory, - GameListItemType dir_type = GameListItemType::CustomDir) - : dir_type{dir_type} { + GameListItemType dir_type_ = GameListItemType::CustomDir) + : dir_type{dir_type_} { setData(type(), TypeRole); UISettings::GameDir* game_dir = &directory; @@ -348,7 +348,7 @@ public: explicit GameListSearchField(GameList* parent = nullptr); QString filterText() const; - void setFilterResult(int visible, int total); + void setFilterResult(int visible_, int total_); void clear(); void setFocus(); @@ -356,7 +356,7 @@ public: private: class KeyReleaseEater : public QObject { public: - explicit KeyReleaseEater(GameList* gamelist, QObject* parent = nullptr); + explicit KeyReleaseEater(GameList* gamelist_, QObject* parent = nullptr); private: GameList* gamelist = nullptr; diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp index ca1899b5c..63326968b 100644 --- a/src/yuzu/game_list_worker.cpp +++ b/src/yuzu/game_list_worker.cpp @@ -223,12 +223,12 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri } } // Anonymous namespace -GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs, - FileSys::ManualContentProvider* provider, - QVector<UISettings::GameDir>& game_dirs, - const CompatibilityList& compatibility_list, Core::System& system_) - : vfs(std::move(vfs)), provider(provider), game_dirs(game_dirs), - compatibility_list(compatibility_list), system{system_} {} +GameListWorker::GameListWorker(FileSys::VirtualFilesystem vfs_, + FileSys::ManualContentProvider* provider_, + QVector<UISettings::GameDir>& game_dirs_, + const CompatibilityList& compatibility_list_, Core::System& system_) + : vfs{std::move(vfs_)}, provider{provider_}, game_dirs{game_dirs_}, + compatibility_list{compatibility_list_}, system{system_} {} GameListWorker::~GameListWorker() = default; diff --git a/src/yuzu/game_list_worker.h b/src/yuzu/game_list_worker.h index 622d241fb..24a4e92c3 100644 --- a/src/yuzu/game_list_worker.h +++ b/src/yuzu/game_list_worker.h @@ -33,10 +33,10 @@ class GameListWorker : public QObject, public QRunnable { Q_OBJECT public: - explicit GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs, - FileSys::ManualContentProvider* provider, - QVector<UISettings::GameDir>& game_dirs, - const CompatibilityList& compatibility_list, Core::System& system_); + explicit GameListWorker(std::shared_ptr<FileSys::VfsFilesystem> vfs_, + FileSys::ManualContentProvider* provider_, + QVector<UISettings::GameDir>& game_dirs_, + const CompatibilityList& compatibility_list_, Core::System& system_); ~GameListWorker() override; /// Starts the processing of directory tree information. diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 33886e50e..b460020b1 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -934,8 +934,7 @@ void GMainWindow::InitializeWidgets() { Settings::values.renderer_backend.SetValue(Settings::RendererBackend::Vulkan); } else { Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL); - const auto filter = Settings::values.scaling_filter.GetValue(); - if (filter == Settings::ScalingFilter::Fsr) { + if (Settings::values.scaling_filter.GetValue() == Settings::ScalingFilter::Fsr) { Settings::values.scaling_filter.SetValue(Settings::ScalingFilter::NearestNeighbor); UpdateFilterText(); } @@ -1442,7 +1441,7 @@ bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t p } return false; } - game_path = filename; + current_game_path = filename; system->TelemetrySession().AddField(Common::Telemetry::FieldType::App, "Frontend", "Qt"); return true; @@ -1508,7 +1507,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t // Register an ExecuteProgram callback such that Core can execute a sub-program system->RegisterExecuteProgramCallback( - [this](std::size_t program_index) { render_window->ExecuteProgram(program_index); }); + [this](std::size_t program_index_) { render_window->ExecuteProgram(program_index_); }); // Register an Exit callback such that Core can exit the currently running application. system->RegisterExitCallback([this]() { render_window->Exit(); }); @@ -1641,7 +1640,7 @@ void GMainWindow::ShutdownGame() { emu_frametime_label->setVisible(false); renderer_status_button->setEnabled(!UISettings::values.has_broken_vulkan); - game_path.clear(); + current_game_path.clear(); // When closing the game, destroy the GLWindow to clear the context after the game is closed render_window->ReleaseRenderTarget(); @@ -2560,7 +2559,7 @@ void GMainWindow::OnRestartGame() { return; } // Make a copy since BootGame edits game_path - BootGame(QString(game_path)); + BootGame(QString(current_game_path)); } void GMainWindow::OnPauseGame() { @@ -2989,7 +2988,7 @@ void GMainWindow::OnToggleAdaptingFilter() { void GMainWindow::OnConfigurePerGame() { const u64 title_id = system->GetCurrentProcessProgramID(); - OpenPerGameConfiguration(title_id, game_path.toStdString()); + OpenPerGameConfiguration(title_id, current_game_path.toStdString()); } void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file_name) { diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 600647015..8cf224c9c 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -369,7 +369,7 @@ private: bool emulation_running = false; std::unique_ptr<EmuThread> emu_thread; // The path to the game currently running - QString game_path; + QString current_game_path; bool auto_paused = false; bool auto_muted = false; diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h index 9746585f5..58b885465 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h @@ -20,7 +20,7 @@ enum class MouseButton; class EmuWindow_SDL2 : public Core::Frontend::EmuWindow { public: - explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem, Core::System& system_); + explicit EmuWindow_SDL2(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_); ~EmuWindow_SDL2(); /// Whether the window is still open, and a close request hasn't yet been sent diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 8075c9082..9b660c13c 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp @@ -73,9 +73,9 @@ bool EmuWindow_SDL2_GL::SupportsRequiredGLExtensions() { return unsupported_ext.empty(); } -EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, +EmuWindow_SDL2_GL::EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) - : EmuWindow_SDL2{input_subsystem, system_} { + : EmuWindow_SDL2{input_subsystem_, system_} { SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 6); SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY); diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h index d159166fd..39346e704 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.h @@ -17,7 +17,7 @@ class InputSubsystem; class EmuWindow_SDL2_GL final : public EmuWindow_SDL2 { public: - explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem, Core::System& system_, + explicit EmuWindow_SDL2_GL(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen); ~EmuWindow_SDL2_GL(); diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp index d5fe35aa0..65455c86e 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.cpp @@ -21,9 +21,9 @@ #include <SDL.h> #include <SDL_syswm.h> -EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem, +EmuWindow_SDL2_VK::EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_, bool fullscreen) - : EmuWindow_SDL2{input_subsystem, system_} { + : EmuWindow_SDL2{input_subsystem_, system_} { const std::string window_title = fmt::format("yuzu {} | {}-{} (Vulkan)", Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc); render_window = diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h index d92e3aaab..e39ad754d 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_vk.h @@ -18,7 +18,7 @@ class InputSubsystem; class EmuWindow_SDL2_VK final : public EmuWindow_SDL2 { public: - explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem, Core::System& system, + explicit EmuWindow_SDL2_VK(InputCommon::InputSubsystem* input_subsystem_, Core::System& system, bool fullscreen); ~EmuWindow_SDL2_VK() override; diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 0dce5e274..e840732e2 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -138,6 +138,12 @@ int main(int argc, char** argv) { Config config{config_path}; + // apply the log_filter setting + // the logger was initialized before and doesn't pick up the filter on its own + Common::Log::Filter filter; + filter.ParseFilterString(Settings::values.log_filter.GetValue()); + Common::Log::SetGlobalFilter(filter); + if (!program_args.empty()) { Settings::values.program_args = program_args; } |