early-access version 2091
This commit is contained in:
		| @@ -29,16 +29,10 @@ option(YUZU_USE_BUNDLED_FFMPEG "Download/Build bundled FFmpeg" "${WIN32}") | ||||
|  | ||||
| option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF) | ||||
|  | ||||
| option(YUZU_ENABLE_BOXCAT "Enable the Boxcat service, a yuzu high-level implementation of BCAT" ON) | ||||
|  | ||||
| option(ENABLE_CUBEB "Enables the cubeb audio backend" ON) | ||||
|  | ||||
| option(USE_DISCORD_PRESENCE "Enables Discord Rich Presence" OFF) | ||||
|  | ||||
| if (NOT ENABLE_WEB_SERVICE) | ||||
|     set(YUZU_ENABLE_BOXCAT OFF) | ||||
| endif() | ||||
|  | ||||
| # Default to a Release build | ||||
| get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) | ||||
| if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE) | ||||
| @@ -422,11 +416,6 @@ if (CONAN_REQUIRED_LIBS) | ||||
|     endif() | ||||
|     include(${CMAKE_BINARY_DIR}/conan.cmake) | ||||
|  | ||||
|     set(CONAN_LIB_OPTIONS | ||||
|         libzip:with_openssl=False | ||||
|         libzip:enable_windows_crypto=False | ||||
|     ) | ||||
|  | ||||
|     conan_check(VERSION 1.24.0 REQUIRED) | ||||
|  | ||||
|     # Manually add iconv to fix a dep conflict between qt and sdl2 | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| yuzu emulator early access | ||||
| ============= | ||||
|  | ||||
| This is the source code for early-access 2090. | ||||
| This is the source code for early-access 2091. | ||||
|  | ||||
| ## Legal Notice | ||||
|  | ||||
|   | ||||
							
								
								
									
										7
									
								
								externals/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								externals/CMakeLists.txt
									
									
									
									
										vendored
									
									
								
							| @@ -93,13 +93,6 @@ endif() | ||||
| # Sirit | ||||
| add_subdirectory(sirit) | ||||
|  | ||||
| # libzip | ||||
| find_package(libzip 1.5) | ||||
| if (NOT libzip_FOUND) | ||||
|     message(STATUS "libzip 1.5 or newer not found, falling back to externals") | ||||
|     add_subdirectory(libzip EXCLUDE_FROM_ALL) | ||||
| endif() | ||||
|  | ||||
| if (ENABLE_WEB_SERVICE) | ||||
|     find_package(OpenSSL 1.1) | ||||
|     if (OPENSSL_FOUND) | ||||
|   | ||||
| @@ -314,8 +314,8 @@ private: | ||||
|     } | ||||
|  | ||||
|     void UntrackPlaceholder(boost::icl::separate_interval_set<size_t>::iterator it) { | ||||
|         placeholders.erase(it); | ||||
|         placeholder_host_pointers.erase(it->lower()); | ||||
|         placeholders.erase(it); | ||||
|     } | ||||
|  | ||||
|     /// Return true when a given memory region is a "nieche" and the placeholders don't have to be | ||||
|   | ||||
| @@ -69,8 +69,6 @@ void LogSettings() { | ||||
|     log_path("DataStorage_NANDDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir)); | ||||
|     log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir)); | ||||
|     log_setting("Debugging_ProgramArgs", values.program_args.GetValue()); | ||||
|     log_setting("Services_BCATBackend", values.bcat_backend.GetValue()); | ||||
|     log_setting("Services_BCATBoxcatLocal", values.bcat_boxcat_local.GetValue()); | ||||
|     log_setting("Input_EnableMotion", values.motion_enabled.GetValue()); | ||||
|     log_setting("Input_EnableVibration", values.vibration_enabled.GetValue()); | ||||
|     log_setting("Input_EnableRawInput", values.enable_raw_input.GetValue()); | ||||
|   | ||||
| @@ -568,8 +568,6 @@ struct Values { | ||||
|     BasicSetting<bool> use_dev_keys{false, "use_dev_keys"}; | ||||
|  | ||||
|     // Network | ||||
|     BasicSetting<std::string> bcat_backend{"none", "bcat_backend"}; | ||||
|     BasicSetting<bool> bcat_boxcat_local{false, "bcat_boxcat_local"}; | ||||
|     BasicSetting<std::string> network_interface{std::string(), "network_interface"}; | ||||
|  | ||||
|     // WebService | ||||
|   | ||||
| @@ -106,8 +106,6 @@ add_library(core STATIC | ||||
|     file_sys/vfs_concat.h | ||||
|     file_sys/vfs_layered.cpp | ||||
|     file_sys/vfs_layered.h | ||||
|     file_sys/vfs_libzip.cpp | ||||
|     file_sys/vfs_libzip.h | ||||
|     file_sys/vfs_offset.cpp | ||||
|     file_sys/vfs_offset.h | ||||
|     file_sys/vfs_real.cpp | ||||
| @@ -218,6 +216,7 @@ add_library(core STATIC | ||||
|     hle/kernel/k_session.h | ||||
|     hle/kernel/k_shared_memory.cpp | ||||
|     hle/kernel/k_shared_memory.h | ||||
|     hle/kernel/k_shared_memory_info.h | ||||
|     hle/kernel/k_slab_heap.h | ||||
|     hle/kernel/k_spin_lock.cpp | ||||
|     hle/kernel/k_spin_lock.h | ||||
| @@ -653,13 +652,6 @@ add_library(core STATIC | ||||
|     tools/freezer.h | ||||
| ) | ||||
|  | ||||
| if (YUZU_ENABLE_BOXCAT) | ||||
|     target_sources(core PRIVATE | ||||
|         hle/service/bcat/backend/boxcat.cpp | ||||
|         hle/service/bcat/backend/boxcat.h | ||||
|     ) | ||||
| endif() | ||||
|  | ||||
| if (MSVC) | ||||
|     target_compile_options(core PRIVATE | ||||
|         /we4242 # 'identifier': conversion from 'type1' to 'type2', possible loss of data | ||||
| @@ -690,12 +682,7 @@ endif() | ||||
| create_target_directory_groups(core) | ||||
|  | ||||
| target_link_libraries(core PUBLIC common PRIVATE audio_core video_core) | ||||
| target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::Opus zip) | ||||
|  | ||||
| if (YUZU_ENABLE_BOXCAT) | ||||
|     target_compile_definitions(core PRIVATE -DYUZU_ENABLE_BOXCAT) | ||||
|     target_link_libraries(core PRIVATE httplib nlohmann_json::nlohmann_json) | ||||
| endif() | ||||
| target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt::fmt nlohmann_json::nlohmann_json mbedtls Opus::Opus) | ||||
|  | ||||
| if (ENABLE_WEB_SERVICE) | ||||
|     target_compile_definitions(core PRIVATE -DENABLE_WEB_SERVICE) | ||||
|   | ||||
| @@ -23,6 +23,7 @@ | ||||
| #include "core/hle/kernel/k_scheduler.h" | ||||
| #include "core/hle/kernel/k_scoped_resource_reservation.h" | ||||
| #include "core/hle/kernel/k_shared_memory.h" | ||||
| #include "core/hle/kernel/k_shared_memory_info.h" | ||||
| #include "core/hle/kernel/k_slab_heap.h" | ||||
| #include "core/hle/kernel/k_thread.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| @@ -254,10 +255,26 @@ ResultCode KProcess::AddSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAdd | ||||
|     // Lock ourselves, to prevent concurrent access. | ||||
|     KScopedLightLock lk(state_lock); | ||||
|  | ||||
|     // TODO(bunnei): Manage KSharedMemoryInfo list here. | ||||
|     // Try to find an existing info for the memory. | ||||
|     KSharedMemoryInfo* shemen_info = nullptr; | ||||
|     const auto iter = std::find_if( | ||||
|         shared_memory_list.begin(), shared_memory_list.end(), | ||||
|         [shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; }); | ||||
|     if (iter != shared_memory_list.end()) { | ||||
|         shemen_info = *iter; | ||||
|     } | ||||
|  | ||||
|     // Open a reference to the shared memory. | ||||
|     if (shemen_info == nullptr) { | ||||
|         shemen_info = KSharedMemoryInfo::Allocate(kernel); | ||||
|         R_UNLESS(shemen_info != nullptr, ResultOutOfMemory); | ||||
|  | ||||
|         shemen_info->Initialize(shmem); | ||||
|         shared_memory_list.push_back(shemen_info); | ||||
|     } | ||||
|  | ||||
|     // Open a reference to the shared memory and its info. | ||||
|     shmem->Open(); | ||||
|     shemen_info->Open(); | ||||
|  | ||||
|     return ResultSuccess; | ||||
| } | ||||
| @@ -267,7 +284,20 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, [[maybe_unused]] VAddr a | ||||
|     // Lock ourselves, to prevent concurrent access. | ||||
|     KScopedLightLock lk(state_lock); | ||||
|  | ||||
|     // TODO(bunnei): Manage KSharedMemoryInfo list here. | ||||
|     KSharedMemoryInfo* shemen_info = nullptr; | ||||
|     const auto iter = std::find_if( | ||||
|         shared_memory_list.begin(), shared_memory_list.end(), | ||||
|         [shmem](const KSharedMemoryInfo* info) { return info->GetSharedMemory() == shmem; }); | ||||
|     if (iter != shared_memory_list.end()) { | ||||
|         shemen_info = *iter; | ||||
|     } | ||||
|  | ||||
|     ASSERT(shemen_info != nullptr); | ||||
|  | ||||
|     if (shemen_info->Close()) { | ||||
|         shared_memory_list.erase(iter); | ||||
|         KSharedMemoryInfo::Free(kernel, shemen_info); | ||||
|     } | ||||
|  | ||||
|     // Close a reference to the shared memory. | ||||
|     shmem->Close(); | ||||
| @@ -412,6 +442,24 @@ void KProcess::Finalize() { | ||||
|     // Finalize the handle table and close any open handles. | ||||
|     handle_table.Finalize(); | ||||
|  | ||||
|     // Free all shared memory infos. | ||||
|     { | ||||
|         auto it = shared_memory_list.begin(); | ||||
|         while (it != shared_memory_list.end()) { | ||||
|             KSharedMemoryInfo* info = *it; | ||||
|             KSharedMemory* shmem = info->GetSharedMemory(); | ||||
|  | ||||
|             while (!info->Close()) { | ||||
|                 shmem->Close(); | ||||
|             } | ||||
|  | ||||
|             shmem->Close(); | ||||
|  | ||||
|             it = shared_memory_list.erase(it); | ||||
|             KSharedMemoryInfo::Free(kernel, info); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // Perform inherited finalization. | ||||
|     KAutoObjectWithSlabHeapAndContainer<KProcess, KSynchronizationObject>::Finalize(); | ||||
| } | ||||
|   | ||||
| @@ -34,6 +34,7 @@ class KernelCore; | ||||
| class KPageTable; | ||||
| class KResourceLimit; | ||||
| class KThread; | ||||
| class KSharedMemoryInfo; | ||||
| class TLSPage; | ||||
|  | ||||
| struct CodeSet; | ||||
| @@ -448,6 +449,9 @@ private: | ||||
|     /// List of threads that are running with this process as their owner. | ||||
|     std::list<const KThread*> thread_list; | ||||
|  | ||||
|     /// List of shared memory that are running with this process as their owner. | ||||
|     std::list<KSharedMemoryInfo*> shared_memory_list; | ||||
|  | ||||
|     /// Address of the top of the main thread's stack | ||||
|     VAddr main_thread_stack_top{}; | ||||
|  | ||||
|   | ||||
							
								
								
									
										46
									
								
								src/core/hle/kernel/k_shared_memory_info.h
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										46
									
								
								src/core/hle/kernel/k_shared_memory_info.h
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| // Copyright 2021 yuzu Emulator Project | ||||
| // Licensed under GPLv2 or any later version | ||||
| // Refer to the license.txt file included. | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <memory> | ||||
| #include <string> | ||||
|  | ||||
| #include <boost/intrusive/list.hpp> | ||||
|  | ||||
| #include "common/assert.h" | ||||
| #include "core/hle/kernel/slab_helpers.h" | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| class KSharedMemory; | ||||
|  | ||||
| class KSharedMemoryInfo final : public KSlabAllocated<KSharedMemoryInfo>, | ||||
|                                 public boost::intrusive::list_base_hook<> { | ||||
|  | ||||
| public: | ||||
|     explicit KSharedMemoryInfo() = default; | ||||
|  | ||||
|     constexpr void Initialize(KSharedMemory* shmem) { | ||||
|         shared_memory = shmem; | ||||
|     } | ||||
|  | ||||
|     constexpr KSharedMemory* GetSharedMemory() const { | ||||
|         return shared_memory; | ||||
|     } | ||||
|  | ||||
|     constexpr void Open() { | ||||
|         ++reference_count; | ||||
|     } | ||||
|  | ||||
|     constexpr bool Close() { | ||||
|         return (--reference_count) == 0; | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     KSharedMemory* shared_memory{}; | ||||
|     size_t reference_count{}; | ||||
| }; | ||||
|  | ||||
| } // namespace Kernel | ||||
| @@ -49,6 +49,7 @@ class KScheduler; | ||||
| class KServerSession; | ||||
| class KSession; | ||||
| class KSharedMemory; | ||||
| class KSharedMemoryInfo; | ||||
| class KThread; | ||||
| class KTransferMemory; | ||||
| class KWritableEvent; | ||||
| @@ -309,6 +310,8 @@ public: | ||||
|             return slab_heap_container->session; | ||||
|         } else if constexpr (std::is_same_v<T, KSharedMemory>) { | ||||
|             return slab_heap_container->shared_memory; | ||||
|         } else if constexpr (std::is_same_v<T, KSharedMemoryInfo>) { | ||||
|             return slab_heap_container->shared_memory_info; | ||||
|         } else if constexpr (std::is_same_v<T, KThread>) { | ||||
|             return slab_heap_container->thread; | ||||
|         } else if constexpr (std::is_same_v<T, KTransferMemory>) { | ||||
| @@ -362,6 +365,7 @@ private: | ||||
|         KSlabHeap<KResourceLimit> resource_limit; | ||||
|         KSlabHeap<KSession> session; | ||||
|         KSlabHeap<KSharedMemory> shared_memory; | ||||
|         KSlabHeap<KSharedMemoryInfo> shared_memory_info; | ||||
|         KSlabHeap<KThread> thread; | ||||
|         KSlabHeap<KTransferMemory> transfer_memory; | ||||
|         KSlabHeap<KWritableEvent> writeable_event; | ||||
|   | ||||
| @@ -320,17 +320,19 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | ||||
|  | ||||
|     auto& kernel = system.Kernel(); | ||||
|  | ||||
|     KScopedAutoObject session = | ||||
|         kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle); | ||||
|     R_UNLESS(session.IsNotNull(), ResultInvalidHandle); | ||||
|     LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); | ||||
|  | ||||
|     auto thread = kernel.CurrentScheduler()->GetCurrentThread(); | ||||
|     { | ||||
|         KScopedSchedulerLock lock(kernel); | ||||
|         thread->SetState(ThreadState::Waiting); | ||||
|         thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); | ||||
|         session->SendSyncRequest(thread, system.Memory(), system.CoreTiming()); | ||||
|  | ||||
|         { | ||||
|             KScopedAutoObject session = | ||||
|                 kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle); | ||||
|             R_UNLESS(session.IsNotNull(), ResultInvalidHandle); | ||||
|             LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); | ||||
|             session->SendSyncRequest(thread, system.Memory(), system.CoreTiming()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     KSynchronizationObject* dummy{}; | ||||
|   | ||||
| @@ -4,15 +4,12 @@ | ||||
|  | ||||
| #include "core/core.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/acc/async_context.h" | ||||
|  | ||||
| namespace Service::Account { | ||||
| IAsyncContext::IAsyncContext(Core::System& system_) | ||||
|     : ServiceFramework{system_, "IAsyncContext"}, compeletion_event{system_.Kernel()} { | ||||
|  | ||||
|     Kernel::KAutoObject::Create(std::addressof(compeletion_event)); | ||||
|     compeletion_event.Initialize("IAsyncContext:CompletionEvent"); | ||||
|  | ||||
|     : ServiceFramework{system_, "IAsyncContext"}, service_context{system_, "IAsyncContext"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0, &IAsyncContext::GetSystemEvent, "GetSystemEvent"}, | ||||
| @@ -23,6 +20,12 @@ IAsyncContext::IAsyncContext(Core::System& system_) | ||||
|     // clang-format on | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
|  | ||||
|     completion_event = service_context.CreateEvent("IAsyncContext:CompletionEvent"); | ||||
| } | ||||
|  | ||||
| IAsyncContext::~IAsyncContext() { | ||||
|     service_context.CloseEvent(completion_event); | ||||
| } | ||||
|  | ||||
| void IAsyncContext::GetSystemEvent(Kernel::HLERequestContext& ctx) { | ||||
| @@ -30,7 +33,7 @@ void IAsyncContext::GetSystemEvent(Kernel::HLERequestContext& ctx) { | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(compeletion_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(completion_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void IAsyncContext::Cancel(Kernel::HLERequestContext& ctx) { | ||||
| @@ -62,7 +65,7 @@ void IAsyncContext::GetResult(Kernel::HLERequestContext& ctx) { | ||||
|  | ||||
| void IAsyncContext::MarkComplete() { | ||||
|     is_complete.store(true); | ||||
|     compeletion_event.GetWritableEvent().Signal(); | ||||
|     completion_event->GetWritableEvent().Signal(); | ||||
| } | ||||
|  | ||||
| } // namespace Service::Account | ||||
|   | ||||
| @@ -5,7 +5,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <atomic> | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Core { | ||||
| @@ -17,6 +17,7 @@ namespace Service::Account { | ||||
| class IAsyncContext : public ServiceFramework<IAsyncContext> { | ||||
| public: | ||||
|     explicit IAsyncContext(Core::System& system_); | ||||
|     ~IAsyncContext() override; | ||||
|  | ||||
|     void GetSystemEvent(Kernel::HLERequestContext& ctx); | ||||
|     void Cancel(Kernel::HLERequestContext& ctx); | ||||
| @@ -30,8 +31,10 @@ protected: | ||||
|  | ||||
|     void MarkComplete(); | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     std::atomic<bool> is_complete{false}; | ||||
|     Kernel::KEvent compeletion_event; | ||||
|     Kernel::KEvent* completion_event; | ||||
| }; | ||||
|  | ||||
| } // namespace Service::Account | ||||
|   | ||||
| @@ -16,9 +16,7 @@ | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_process.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/k_transfer_memory.h" | ||||
| #include "core/hle/kernel/k_writable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/acc/profile_manager.h" | ||||
| #include "core/hle/service/am/am.h" | ||||
| @@ -254,8 +252,9 @@ IDebugFunctions::IDebugFunctions(Core::System& system_) | ||||
| IDebugFunctions::~IDebugFunctions() = default; | ||||
|  | ||||
| ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_) | ||||
|     : ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_}, | ||||
|       launchable_event{system.Kernel()}, accumulated_suspended_tick_changed_event{system.Kernel()} { | ||||
|     : ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_}, service_context{ | ||||
|                                                                                system, | ||||
|                                                                                "ISelfController"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0, &ISelfController::Exit, "Exit"}, | ||||
| @@ -311,9 +310,7 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
|  | ||||
|     Kernel::KAutoObject::Create(std::addressof(launchable_event)); | ||||
|  | ||||
|     launchable_event.Initialize("ISelfController:LaunchableEvent"); | ||||
|     launchable_event = service_context.CreateEvent("ISelfController:LaunchableEvent"); | ||||
|  | ||||
|     // This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is | ||||
|     // called. Yuzu can just create it unconditionally, since it doesn't need to support multiple | ||||
| @@ -321,13 +318,15 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv | ||||
|     // suspended if the event has previously been created by a call to | ||||
|     // GetAccumulatedSuspendedTickChangedEvent. | ||||
|  | ||||
|     Kernel::KAutoObject::Create(std::addressof(accumulated_suspended_tick_changed_event)); | ||||
|     accumulated_suspended_tick_changed_event.Initialize( | ||||
|         "ISelfController:AccumulatedSuspendedTickChangedEvent"); | ||||
|     accumulated_suspended_tick_changed_event.GetWritableEvent().Signal(); | ||||
|     accumulated_suspended_tick_changed_event = | ||||
|         service_context.CreateEvent("ISelfController:AccumulatedSuspendedTickChangedEvent"); | ||||
|     accumulated_suspended_tick_changed_event->GetWritableEvent().Signal(); | ||||
| } | ||||
|  | ||||
| ISelfController::~ISelfController() = default; | ||||
| ISelfController::~ISelfController() { | ||||
|     service_context.CloseEvent(launchable_event); | ||||
|     service_context.CloseEvent(accumulated_suspended_tick_changed_event); | ||||
| } | ||||
|  | ||||
| void ISelfController::Exit(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_AM, "called"); | ||||
| @@ -383,11 +382,11 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) { | ||||
| void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
|  | ||||
|     launchable_event.GetWritableEvent().Signal(); | ||||
|     launchable_event->GetWritableEvent().Signal(); | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(launchable_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(launchable_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { | ||||
| @@ -566,7 +565,7 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(accumulated_suspended_tick_changed_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx) { | ||||
| @@ -584,40 +583,39 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestCo | ||||
|     rb.Push(ResultSuccess); | ||||
| } | ||||
|  | ||||
| AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) | ||||
|     : on_new_message{kernel}, on_operation_mode_changed{kernel} { | ||||
|  | ||||
|     Kernel::KAutoObject::Create(std::addressof(on_new_message)); | ||||
|     Kernel::KAutoObject::Create(std::addressof(on_operation_mode_changed)); | ||||
|  | ||||
|     on_new_message.Initialize("AMMessageQueue:OnMessageReceived"); | ||||
|     on_operation_mode_changed.Initialize("AMMessageQueue:OperationModeChanged"); | ||||
| AppletMessageQueue::AppletMessageQueue(Core::System& system) | ||||
|     : service_context{system, "AppletMessageQueue"} { | ||||
|     on_new_message = service_context.CreateEvent("AMMessageQueue:OnMessageReceived"); | ||||
|     on_operation_mode_changed = service_context.CreateEvent("AMMessageQueue:OperationModeChanged"); | ||||
| } | ||||
|  | ||||
| AppletMessageQueue::~AppletMessageQueue() = default; | ||||
| AppletMessageQueue::~AppletMessageQueue() { | ||||
|     service_context.CloseEvent(on_new_message); | ||||
|     service_context.CloseEvent(on_operation_mode_changed); | ||||
| } | ||||
|  | ||||
| Kernel::KReadableEvent& AppletMessageQueue::GetMessageReceiveEvent() { | ||||
|     return on_new_message.GetReadableEvent(); | ||||
|     return on_new_message->GetReadableEvent(); | ||||
| } | ||||
|  | ||||
| Kernel::KReadableEvent& AppletMessageQueue::GetOperationModeChangedEvent() { | ||||
|     return on_operation_mode_changed.GetReadableEvent(); | ||||
|     return on_operation_mode_changed->GetReadableEvent(); | ||||
| } | ||||
|  | ||||
| void AppletMessageQueue::PushMessage(AppletMessage msg) { | ||||
|     messages.push(msg); | ||||
|     on_new_message.GetWritableEvent().Signal(); | ||||
|     on_new_message->GetWritableEvent().Signal(); | ||||
| } | ||||
|  | ||||
| AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { | ||||
|     if (messages.empty()) { | ||||
|         on_new_message.GetWritableEvent().Clear(); | ||||
|         on_new_message->GetWritableEvent().Clear(); | ||||
|         return AppletMessage::NoMessage; | ||||
|     } | ||||
|     auto msg = messages.front(); | ||||
|     messages.pop(); | ||||
|     if (messages.empty()) { | ||||
|         on_new_message.GetWritableEvent().Clear(); | ||||
|         on_new_message->GetWritableEvent().Clear(); | ||||
|     } | ||||
|     return msg; | ||||
| } | ||||
| @@ -637,7 +635,7 @@ void AppletMessageQueue::FocusStateChanged() { | ||||
| void AppletMessageQueue::OperationModeChanged() { | ||||
|     PushMessage(AppletMessage::OperationModeChanged); | ||||
|     PushMessage(AppletMessage::PerformanceModeChanged); | ||||
|     on_operation_mode_changed.GetWritableEvent().Signal(); | ||||
|     on_operation_mode_changed->GetWritableEvent().Signal(); | ||||
| } | ||||
|  | ||||
| ICommonStateGetter::ICommonStateGetter(Core::System& system_, | ||||
| @@ -1272,10 +1270,8 @@ void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) | ||||
| } | ||||
|  | ||||
| IApplicationFunctions::IApplicationFunctions(Core::System& system_) | ||||
|     : ServiceFramework{system_, "IApplicationFunctions"}, gpu_error_detected_event{system.Kernel()}, | ||||
|       friend_invitation_storage_channel_event{system.Kernel()}, | ||||
|       notification_storage_channel_event{system.Kernel()}, health_warning_disappeared_system_event{ | ||||
|                                                                system.Kernel()} { | ||||
|     : ServiceFramework{system_, "IApplicationFunctions"}, service_context{system, | ||||
|                                                                           "IApplicationFunctions"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"}, | ||||
| @@ -1343,21 +1339,22 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
|  | ||||
|     Kernel::KAutoObject::Create(std::addressof(gpu_error_detected_event)); | ||||
|     Kernel::KAutoObject::Create(std::addressof(friend_invitation_storage_channel_event)); | ||||
|     Kernel::KAutoObject::Create(std::addressof(notification_storage_channel_event)); | ||||
|     Kernel::KAutoObject::Create(std::addressof(health_warning_disappeared_system_event)); | ||||
|  | ||||
|     gpu_error_detected_event.Initialize("IApplicationFunctions:GpuErrorDetectedSystemEvent"); | ||||
|     friend_invitation_storage_channel_event.Initialize( | ||||
|         "IApplicationFunctions:FriendInvitationStorageChannelEvent"); | ||||
|     notification_storage_channel_event.Initialize( | ||||
|         "IApplicationFunctions:NotificationStorageChannelEvent"); | ||||
|     health_warning_disappeared_system_event.Initialize( | ||||
|         "IApplicationFunctions:HealthWarningDisappearedSystemEvent"); | ||||
|     gpu_error_detected_event = | ||||
|         service_context.CreateEvent("IApplicationFunctions:GpuErrorDetectedSystemEvent"); | ||||
|     friend_invitation_storage_channel_event = | ||||
|         service_context.CreateEvent("IApplicationFunctions:FriendInvitationStorageChannelEvent"); | ||||
|     notification_storage_channel_event = | ||||
|         service_context.CreateEvent("IApplicationFunctions:NotificationStorageChannelEvent"); | ||||
|     health_warning_disappeared_system_event = | ||||
|         service_context.CreateEvent("IApplicationFunctions:HealthWarningDisappearedSystemEvent"); | ||||
| } | ||||
|  | ||||
| IApplicationFunctions::~IApplicationFunctions() = default; | ||||
| IApplicationFunctions::~IApplicationFunctions() { | ||||
|     service_context.CloseEvent(gpu_error_detected_event); | ||||
|     service_context.CloseEvent(friend_invitation_storage_channel_event); | ||||
|     service_context.CloseEvent(notification_storage_channel_event); | ||||
|     service_context.CloseEvent(health_warning_disappeared_system_event); | ||||
| } | ||||
|  | ||||
| void IApplicationFunctions::EnableApplicationCrashReport(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
| @@ -1751,7 +1748,7 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(gpu_error_detected_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) { | ||||
| @@ -1759,7 +1756,7 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(friend_invitation_storage_channel_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel( | ||||
| @@ -1775,7 +1772,7 @@ void IApplicationFunctions::GetNotificationStorageChannelEvent(Kernel::HLEReques | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(notification_storage_channel_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(notification_storage_channel_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERequestContext& ctx) { | ||||
| @@ -1783,12 +1780,12 @@ void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERe | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(health_warning_disappeared_system_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(health_warning_disappeared_system_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, | ||||
|                        Core::System& system) { | ||||
|     auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel()); | ||||
|     auto message_queue = std::make_shared<AppletMessageQueue>(system); | ||||
|     // Needed on game boot | ||||
|     message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); | ||||
|  | ||||
| @@ -1801,8 +1798,8 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger | ||||
| } | ||||
|  | ||||
| IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) | ||||
|     : ServiceFramework{system_, "IHomeMenuFunctions"}, pop_from_general_channel_event{ | ||||
|                                                            system.Kernel()} { | ||||
|     : ServiceFramework{system_, "IHomeMenuFunctions"}, service_context{system, | ||||
|                                                                        "IHomeMenuFunctions"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"}, | ||||
| @@ -1823,11 +1820,13 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
|  | ||||
|     Kernel::KAutoObject::Create(std::addressof(pop_from_general_channel_event)); | ||||
|     pop_from_general_channel_event.Initialize("IHomeMenuFunctions:PopFromGeneralChannelEvent"); | ||||
|     pop_from_general_channel_event = | ||||
|         service_context.CreateEvent("IHomeMenuFunctions:PopFromGeneralChannelEvent"); | ||||
| } | ||||
|  | ||||
| IHomeMenuFunctions::~IHomeMenuFunctions() = default; | ||||
| IHomeMenuFunctions::~IHomeMenuFunctions() { | ||||
|     service_context.CloseEvent(pop_from_general_channel_event); | ||||
| } | ||||
|  | ||||
| void IHomeMenuFunctions::RequestToGetForeground(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_AM, "(STUBBED) called"); | ||||
| @@ -1841,7 +1840,7 @@ void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(pop_from_general_channel_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(pop_from_general_channel_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| IGlobalStateController::IGlobalStateController(Core::System& system_) | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| #include <memory> | ||||
| #include <queue> | ||||
|  | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Kernel { | ||||
| @@ -53,7 +53,7 @@ public: | ||||
|         PerformanceModeChanged = 31, | ||||
|     }; | ||||
|  | ||||
|     explicit AppletMessageQueue(Kernel::KernelCore& kernel); | ||||
|     explicit AppletMessageQueue(Core::System& system); | ||||
|     ~AppletMessageQueue(); | ||||
|  | ||||
|     Kernel::KReadableEvent& GetMessageReceiveEvent(); | ||||
| @@ -66,9 +66,12 @@ public: | ||||
|     void OperationModeChanged(); | ||||
|  | ||||
| private: | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* on_new_message; | ||||
|     Kernel::KEvent* on_operation_mode_changed; | ||||
|  | ||||
|     std::queue<AppletMessage> messages; | ||||
|     Kernel::KEvent on_new_message; | ||||
|     Kernel::KEvent on_operation_mode_changed; | ||||
| }; | ||||
|  | ||||
| class IWindowController final : public ServiceFramework<IWindowController> { | ||||
| @@ -156,8 +159,11 @@ private: | ||||
|     }; | ||||
|  | ||||
|     NVFlinger::NVFlinger& nvflinger; | ||||
|     Kernel::KEvent launchable_event; | ||||
|     Kernel::KEvent accumulated_suspended_tick_changed_event; | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* launchable_event; | ||||
|     Kernel::KEvent* accumulated_suspended_tick_changed_event; | ||||
|  | ||||
|     u32 idle_time_detection_extension = 0; | ||||
|     u64 num_fatal_sections_entered = 0; | ||||
| @@ -298,13 +304,15 @@ private: | ||||
|     void GetNotificationStorageChannelEvent(Kernel::HLERequestContext& ctx); | ||||
|     void GetHealthWarningDisappearedSystemEvent(Kernel::HLERequestContext& ctx); | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     bool launch_popped_application_specific = false; | ||||
|     bool launch_popped_account_preselect = false; | ||||
|     s32 previous_program_index{-1}; | ||||
|     Kernel::KEvent gpu_error_detected_event; | ||||
|     Kernel::KEvent friend_invitation_storage_channel_event; | ||||
|     Kernel::KEvent notification_storage_channel_event; | ||||
|     Kernel::KEvent health_warning_disappeared_system_event; | ||||
|     Kernel::KEvent* gpu_error_detected_event; | ||||
|     Kernel::KEvent* friend_invitation_storage_channel_event; | ||||
|     Kernel::KEvent* notification_storage_channel_event; | ||||
|     Kernel::KEvent* health_warning_disappeared_system_event; | ||||
| }; | ||||
|  | ||||
| class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { | ||||
| @@ -316,7 +324,9 @@ private: | ||||
|     void RequestToGetForeground(Kernel::HLERequestContext& ctx); | ||||
|     void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx); | ||||
|  | ||||
|     Kernel::KEvent pop_from_general_channel_event; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* pop_from_general_channel_event; | ||||
| }; | ||||
|  | ||||
| class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { | ||||
|   | ||||
| @@ -12,8 +12,7 @@ | ||||
| #include "core/frontend/applets/profile_select.h" | ||||
| #include "core/frontend/applets/software_keyboard.h" | ||||
| #include "core/frontend/applets/web_browser.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/k_writable_event.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/am/am.h" | ||||
| #include "core/hle/service/am/applet_ae.h" | ||||
| #include "core/hle/service/am/applet_oe.h" | ||||
| @@ -29,19 +28,19 @@ | ||||
| namespace Service::AM::Applets { | ||||
|  | ||||
| AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_) | ||||
|     : system{system_}, applet_mode{applet_mode_}, state_changed_event{system.Kernel()}, | ||||
|       pop_out_data_event{system.Kernel()}, pop_interactive_out_data_event{system.Kernel()} { | ||||
|  | ||||
|     Kernel::KAutoObject::Create(std::addressof(state_changed_event)); | ||||
|     Kernel::KAutoObject::Create(std::addressof(pop_out_data_event)); | ||||
|     Kernel::KAutoObject::Create(std::addressof(pop_interactive_out_data_event)); | ||||
|  | ||||
|     state_changed_event.Initialize("ILibraryAppletAccessor:StateChangedEvent"); | ||||
|     pop_out_data_event.Initialize("ILibraryAppletAccessor:PopDataOutEvent"); | ||||
|     pop_interactive_out_data_event.Initialize("ILibraryAppletAccessor:PopInteractiveDataOutEvent"); | ||||
|     : system{system_}, applet_mode{applet_mode_}, service_context{system, | ||||
|                                                                   "ILibraryAppletAccessor"} { | ||||
|     state_changed_event = service_context.CreateEvent("ILibraryAppletAccessor:StateChangedEvent"); | ||||
|     pop_out_data_event = service_context.CreateEvent("ILibraryAppletAccessor:PopDataOutEvent"); | ||||
|     pop_interactive_out_data_event = | ||||
|         service_context.CreateEvent("ILibraryAppletAccessor:PopInteractiveDataOutEvent"); | ||||
| } | ||||
|  | ||||
| AppletDataBroker::~AppletDataBroker() = default; | ||||
| AppletDataBroker::~AppletDataBroker() { | ||||
|     service_context.CloseEvent(state_changed_event); | ||||
|     service_context.CloseEvent(pop_out_data_event); | ||||
|     service_context.CloseEvent(pop_interactive_out_data_event); | ||||
| } | ||||
|  | ||||
| AppletDataBroker::RawChannelData AppletDataBroker::PeekDataToAppletForDebug() const { | ||||
|     std::vector<std::vector<u8>> out_normal; | ||||
| @@ -65,7 +64,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() { | ||||
|  | ||||
|     auto out = std::move(out_channel.front()); | ||||
|     out_channel.pop_front(); | ||||
|     pop_out_data_event.GetWritableEvent().Clear(); | ||||
|     pop_out_data_event->GetWritableEvent().Clear(); | ||||
|     return out; | ||||
| } | ||||
|  | ||||
| @@ -84,7 +83,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() { | ||||
|  | ||||
|     auto out = std::move(out_interactive_channel.front()); | ||||
|     out_interactive_channel.pop_front(); | ||||
|     pop_interactive_out_data_event.GetWritableEvent().Clear(); | ||||
|     pop_interactive_out_data_event->GetWritableEvent().Clear(); | ||||
|     return out; | ||||
| } | ||||
|  | ||||
| @@ -103,7 +102,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storag | ||||
|  | ||||
| void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) { | ||||
|     out_channel.emplace_back(std::move(storage)); | ||||
|     pop_out_data_event.GetWritableEvent().Signal(); | ||||
|     pop_out_data_event->GetWritableEvent().Signal(); | ||||
| } | ||||
|  | ||||
| void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) { | ||||
| @@ -112,11 +111,11 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& s | ||||
|  | ||||
| void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) { | ||||
|     out_interactive_channel.emplace_back(std::move(storage)); | ||||
|     pop_interactive_out_data_event.GetWritableEvent().Signal(); | ||||
|     pop_interactive_out_data_event->GetWritableEvent().Signal(); | ||||
| } | ||||
|  | ||||
| void AppletDataBroker::SignalStateChanged() { | ||||
|     state_changed_event.GetWritableEvent().Signal(); | ||||
|     state_changed_event->GetWritableEvent().Signal(); | ||||
|  | ||||
|     switch (applet_mode) { | ||||
|     case LibraryAppletMode::AllForeground: | ||||
| @@ -141,15 +140,15 @@ void AppletDataBroker::SignalStateChanged() { | ||||
| } | ||||
|  | ||||
| Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() { | ||||
|     return pop_out_data_event.GetReadableEvent(); | ||||
|     return pop_out_data_event->GetReadableEvent(); | ||||
| } | ||||
|  | ||||
| Kernel::KReadableEvent& AppletDataBroker::GetInteractiveDataEvent() { | ||||
|     return pop_interactive_out_data_event.GetReadableEvent(); | ||||
|     return pop_interactive_out_data_event->GetReadableEvent(); | ||||
| } | ||||
|  | ||||
| Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() { | ||||
|     return state_changed_event.GetReadableEvent(); | ||||
|     return state_changed_event->GetReadableEvent(); | ||||
| } | ||||
|  | ||||
| Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_) | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
| #include <queue> | ||||
|  | ||||
| #include "common/swap.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
|  | ||||
| union ResultCode; | ||||
|  | ||||
| @@ -105,6 +105,8 @@ private: | ||||
|     Core::System& system; | ||||
|     LibraryAppletMode applet_mode; | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     // Queues are named from applet's perspective | ||||
|  | ||||
|     // PopNormalDataToApplet and PushNormalDataFromGame | ||||
| @@ -119,13 +121,13 @@ private: | ||||
|     // PopInteractiveDataToGame and PushInteractiveDataFromApplet | ||||
|     std::deque<std::shared_ptr<IStorage>> out_interactive_channel; | ||||
|  | ||||
|     Kernel::KEvent state_changed_event; | ||||
|     Kernel::KEvent* state_changed_event; | ||||
|  | ||||
|     // Signaled on PushNormalDataFromApplet | ||||
|     Kernel::KEvent pop_out_data_event; | ||||
|     Kernel::KEvent* pop_out_data_event; | ||||
|  | ||||
|     // Signaled on PushInteractiveDataFromApplet | ||||
|     Kernel::KEvent pop_interactive_out_data_event; | ||||
|     Kernel::KEvent* pop_interactive_out_data_event; | ||||
| }; | ||||
|  | ||||
| class Applet { | ||||
|   | ||||
| @@ -16,8 +16,8 @@ | ||||
| #include "core/file_sys/patch_manager.h" | ||||
| #include "core/file_sys/registered_cache.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_process.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/aoc/aoc_u.h" | ||||
| #include "core/loader/loader.h" | ||||
| @@ -49,7 +49,8 @@ static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) { | ||||
| class IPurchaseEventManager final : public ServiceFramework<IPurchaseEventManager> { | ||||
| public: | ||||
|     explicit IPurchaseEventManager(Core::System& system_) | ||||
|         : ServiceFramework{system_, "IPurchaseEventManager"}, purchased_event{system.Kernel()} { | ||||
|         : ServiceFramework{system_, "IPurchaseEventManager"}, service_context{ | ||||
|                                                                   system, "IPurchaseEventManager"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &IPurchaseEventManager::SetDefaultDeliveryTarget, "SetDefaultDeliveryTarget"}, | ||||
| @@ -62,8 +63,11 @@ public: | ||||
|  | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         Kernel::KAutoObject::Create(std::addressof(purchased_event)); | ||||
|         purchased_event.Initialize("IPurchaseEventManager:PurchasedEvent"); | ||||
|         purchased_event = service_context.CreateEvent("IPurchaseEventManager:PurchasedEvent"); | ||||
|     } | ||||
|  | ||||
|     ~IPurchaseEventManager() override { | ||||
|         service_context.CloseEvent(purchased_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
| @@ -96,15 +100,17 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(purchased_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(purchased_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     Kernel::KEvent purchased_event; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* purchased_event; | ||||
| }; | ||||
|  | ||||
| AOC_U::AOC_U(Core::System& system_) | ||||
|     : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)}, | ||||
|       aoc_change_event{system.Kernel()} { | ||||
|       service_context{system_, "aoc:u"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0, nullptr, "CountAddOnContentByApplicationId"}, | ||||
| @@ -126,11 +132,12 @@ AOC_U::AOC_U(Core::System& system_) | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
|  | ||||
|     Kernel::KAutoObject::Create(std::addressof(aoc_change_event)); | ||||
|     aoc_change_event.Initialize("GetAddOnContentListChanged:Event"); | ||||
|     aoc_change_event = service_context.CreateEvent("GetAddOnContentListChanged:Event"); | ||||
| } | ||||
|  | ||||
| AOC_U::~AOC_U() = default; | ||||
| AOC_U::~AOC_U() { | ||||
|     service_context.CloseEvent(aoc_change_event); | ||||
| } | ||||
|  | ||||
| void AOC_U::CountAddOnContent(Kernel::HLERequestContext& ctx) { | ||||
|     struct Parameters { | ||||
| @@ -254,7 +261,7 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) { | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(aoc_change_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(aoc_change_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void AOC_U::GetAddOnContentListChangedEventWithProcessId(Kernel::HLERequestContext& ctx) { | ||||
| @@ -262,7 +269,7 @@ void AOC_U::GetAddOnContentListChangedEventWithProcessId(Kernel::HLERequestConte | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(aoc_change_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(aoc_change_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) { | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Core { | ||||
| @@ -33,7 +33,9 @@ private: | ||||
|     void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx); | ||||
|  | ||||
|     std::vector<u64> add_on_content; | ||||
|     Kernel::KEvent aoc_change_event; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* aoc_change_event; | ||||
| }; | ||||
|  | ||||
| /// Registers all AOC services with the specified service manager. | ||||
|   | ||||
| @@ -12,7 +12,7 @@ | ||||
| namespace Service::Audio { | ||||
|  | ||||
| IAudioIn::IAudioIn(Core::System& system_) | ||||
|     : ServiceFramework{system_, "IAudioIn"}, buffer_event{system_.Kernel()} { | ||||
|     : ServiceFramework{system_, "IAudioIn"}, service_context{system_, "IAudioIn"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0, nullptr, "GetAudioInState"}, | ||||
| @@ -35,11 +35,12 @@ IAudioIn::IAudioIn(Core::System& system_) | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
|  | ||||
|     Kernel::KAutoObject::Create(std::addressof(buffer_event)); | ||||
|     buffer_event.Initialize("IAudioIn:BufferEvent"); | ||||
|     buffer_event = service_context.CreateEvent("IAudioIn:BufferEvent"); | ||||
| } | ||||
|  | ||||
| IAudioIn::~IAudioIn() = default; | ||||
| IAudioIn::~IAudioIn() { | ||||
|     service_context.CloseEvent(buffer_event); | ||||
| } | ||||
|  | ||||
| void IAudioIn::Start(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_WARNING(Service_Audio, "(STUBBED) called"); | ||||
| @@ -53,7 +54,7 @@ void IAudioIn::RegisterBufferEvent(Kernel::HLERequestContext& ctx) { | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushCopyObjects(buffer_event.GetReadableEvent()); | ||||
|     rb.PushCopyObjects(buffer_event->GetReadableEvent()); | ||||
| } | ||||
|  | ||||
| void IAudioIn::AppendAudioInBufferAuto(Kernel::HLERequestContext& ctx) { | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Core { | ||||
| @@ -27,7 +27,9 @@ private: | ||||
|     void RegisterBufferEvent(Kernel::HLERequestContext& ctx); | ||||
|     void AppendAudioInBufferAuto(Kernel::HLERequestContext& ctx); | ||||
|  | ||||
|     Kernel::KEvent buffer_event; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* buffer_event; | ||||
| }; | ||||
|  | ||||
| class AudInU final : public ServiceFramework<AudInU> { | ||||
|   | ||||
| @@ -15,11 +15,10 @@ | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/hle_ipc.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/k_writable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/audio/audout_u.h" | ||||
| #include "core/hle/service/audio/errors.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/memory.h" | ||||
|  | ||||
| namespace Service::Audio { | ||||
| @@ -41,11 +40,12 @@ enum class AudioState : u32 { | ||||
|  | ||||
| class IAudioOut final : public ServiceFramework<IAudioOut> { | ||||
| public: | ||||
|     IAudioOut(Core::System& system_, AudoutParams audio_params_, AudioCore::AudioOut& audio_core_, | ||||
|               std::string&& device_name_, std::string&& unique_name) | ||||
|         : ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_}, device_name{std::move( | ||||
|                                                                                device_name_)}, | ||||
|           audio_params{audio_params_}, buffer_event{system.Kernel()}, main_memory{system.Memory()} { | ||||
|     explicit IAudioOut(Core::System& system_, AudoutParams audio_params_, | ||||
|                        AudioCore::AudioOut& audio_core_, std::string&& device_name_, | ||||
|                        std::string&& unique_name) | ||||
|         : ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_}, | ||||
|           device_name{std::move(device_name_)}, audio_params{audio_params_}, | ||||
|           main_memory{system.Memory()}, service_context{system_, "IAudioOut"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, | ||||
| @@ -67,16 +67,19 @@ public: | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         // This is the event handle used to check if the audio buffer was released | ||||
|         Kernel::KAutoObject::Create(std::addressof(buffer_event)); | ||||
|         buffer_event.Initialize("IAudioOutBufferReleased"); | ||||
|         buffer_event = service_context.CreateEvent("IAudioOutBufferReleased"); | ||||
|  | ||||
|         stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate, | ||||
|                                        audio_params.channel_count, std::move(unique_name), [this] { | ||||
|                                            const auto guard = LockService(); | ||||
|                                            buffer_event.GetWritableEvent().Signal(); | ||||
|                                            buffer_event->GetWritableEvent().Signal(); | ||||
|                                        }); | ||||
|     } | ||||
|  | ||||
|     ~IAudioOut() override { | ||||
|         service_context.CloseEvent(buffer_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     struct AudioBuffer { | ||||
|         u64_le next; | ||||
| @@ -126,7 +129,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(buffer_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(buffer_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { | ||||
| @@ -227,9 +230,12 @@ private: | ||||
|  | ||||
|     [[maybe_unused]] AudoutParams audio_params{}; | ||||
|  | ||||
|     /// This is the event handle used to check if the audio buffer was released | ||||
|     Kernel::KEvent buffer_event; | ||||
|     Core::Memory::Memory& main_memory; | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     /// This is the event handle used to check if the audio buffer was released | ||||
|     Kernel::KEvent* buffer_event; | ||||
| }; | ||||
|  | ||||
| AudOutU::AudOutU(Core::System& system_) : ServiceFramework{system_, "audout:u"} { | ||||
|   | ||||
| @@ -17,8 +17,6 @@ | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/hle_ipc.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/k_writable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/audio/audren_u.h" | ||||
| #include "core/hle/service/audio/errors.h" | ||||
| @@ -30,7 +28,7 @@ public: | ||||
|     explicit IAudioRenderer(Core::System& system_, | ||||
|                             const AudioCommon::AudioRendererParameter& audren_params, | ||||
|                             const std::size_t instance_number) | ||||
|         : ServiceFramework{system_, "IAudioRenderer"}, system_event{system.Kernel()} { | ||||
|         : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, | ||||
| @@ -49,17 +47,20 @@ public: | ||||
|         // clang-format on | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         Kernel::KAutoObject::Create(std::addressof(system_event)); | ||||
|         system_event.Initialize("IAudioRenderer:SystemEvent"); | ||||
|         system_event = service_context.CreateEvent("IAudioRenderer:SystemEvent"); | ||||
|         renderer = std::make_unique<AudioCore::AudioRenderer>( | ||||
|             system.CoreTiming(), system.Memory(), audren_params, | ||||
|             [this]() { | ||||
|                 const auto guard = LockService(); | ||||
|                 system_event.GetWritableEvent().Signal(); | ||||
|                 system_event->GetWritableEvent().Signal(); | ||||
|             }, | ||||
|             instance_number); | ||||
|     } | ||||
|  | ||||
|     ~IAudioRenderer() override { | ||||
|         service_context.CloseEvent(system_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     void GetSampleRate(Kernel::HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_Audio, "called"); | ||||
| @@ -130,7 +131,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(system_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(system_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) { | ||||
| @@ -164,14 +165,16 @@ private: | ||||
|         rb.Push(ERR_NOT_SUPPORTED); | ||||
|     } | ||||
|  | ||||
|     Kernel::KEvent system_event; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* system_event; | ||||
|     std::unique_ptr<AudioCore::AudioRenderer> renderer; | ||||
|     u32 rendering_time_limit_percent = 100; | ||||
| }; | ||||
|  | ||||
| class IAudioDevice final : public ServiceFramework<IAudioDevice> { | ||||
| public: | ||||
|     explicit IAudioDevice(Core::System& system_, Kernel::KEvent& buffer_event_, u32_le revision_) | ||||
|     explicit IAudioDevice(Core::System& system_, Kernel::KEvent* buffer_event_, u32_le revision_) | ||||
|         : ServiceFramework{system_, "IAudioDevice"}, buffer_event{buffer_event_}, revision{ | ||||
|                                                                                       revision_} { | ||||
|         static const FunctionInfo functions[] = { | ||||
| @@ -279,11 +282,11 @@ private: | ||||
|     void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { | ||||
|         LOG_WARNING(Service_Audio, "(STUBBED) called"); | ||||
|  | ||||
|         buffer_event.GetWritableEvent().Signal(); | ||||
|         buffer_event->GetWritableEvent().Signal(); | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(buffer_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(buffer_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { | ||||
| @@ -300,7 +303,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(buffer_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(buffer_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void QueryAudioDeviceOutputEvent(Kernel::HLERequestContext& ctx) { | ||||
| @@ -308,16 +311,15 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(buffer_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(buffer_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     Kernel::KEvent& buffer_event; | ||||
|     Kernel::KEvent* buffer_event; | ||||
|     u32_le revision = 0; | ||||
| }; | ||||
|  | ||||
| AudRenU::AudRenU(Core::System& system_) | ||||
|     : ServiceFramework{system_, "audren:u"}, buffer_event{system.Kernel()} { | ||||
|  | ||||
|     : ServiceFramework{system_, "audren:u"}, service_context{system_, "audren:u"} { | ||||
|     // clang-format off | ||||
|     static const FunctionInfo functions[] = { | ||||
|         {0, &AudRenU::OpenAudioRenderer, "OpenAudioRenderer"}, | ||||
| @@ -330,11 +332,12 @@ AudRenU::AudRenU(Core::System& system_) | ||||
|  | ||||
|     RegisterHandlers(functions); | ||||
|  | ||||
|     Kernel::KAutoObject::Create(std::addressof(buffer_event)); | ||||
|     buffer_event.Initialize("IAudioOutBufferReleasedEvent"); | ||||
|     buffer_event = service_context.CreateEvent("IAudioOutBufferReleasedEvent"); | ||||
| } | ||||
|  | ||||
| AudRenU::~AudRenU() = default; | ||||
| AudRenU::~AudRenU() { | ||||
|     service_context.CloseEvent(buffer_event); | ||||
| } | ||||
|  | ||||
| void AudRenU::OpenAudioRenderer(Kernel::HLERequestContext& ctx) { | ||||
|     LOG_DEBUG(Service_Audio, "called"); | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Core { | ||||
| @@ -31,8 +31,10 @@ private: | ||||
|  | ||||
|     void OpenAudioRendererImpl(Kernel::HLERequestContext& ctx); | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     std::size_t audren_instance_count = 0; | ||||
|     Kernel::KEvent buffer_event; | ||||
|     Kernel::KEvent* buffer_event; | ||||
| }; | ||||
|  | ||||
| // Describes a particular audio feature that may be supported in a particular revision. | ||||
|   | ||||
| @@ -5,22 +5,24 @@ | ||||
| #include "common/hex_util.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/k_writable_event.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/lock.h" | ||||
| #include "core/hle/service/bcat/backend/backend.h" | ||||
|  | ||||
| namespace Service::BCAT { | ||||
|  | ||||
| ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel, | ||||
|                                                std::string_view event_name) | ||||
|     : update_event{kernel} { | ||||
|     Kernel::KAutoObject::Create(std::addressof(update_event)); | ||||
|     update_event.Initialize("ProgressServiceBackend:UpdateEvent:" + std::string(event_name)); | ||||
| ProgressServiceBackend::ProgressServiceBackend(Core::System& system, std::string_view event_name) | ||||
|     : service_context{system, "ProgressServiceBackend"} { | ||||
|     update_event = service_context.CreateEvent("ProgressServiceBackend:UpdateEvent:" + | ||||
|                                                std::string(event_name)); | ||||
| } | ||||
|  | ||||
| ProgressServiceBackend::~ProgressServiceBackend() { | ||||
|     service_context.CloseEvent(update_event); | ||||
| } | ||||
|  | ||||
| Kernel::KReadableEvent& ProgressServiceBackend::GetEvent() { | ||||
|     return update_event.GetReadableEvent(); | ||||
|     return update_event->GetReadableEvent(); | ||||
| } | ||||
|  | ||||
| DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() { | ||||
| @@ -88,9 +90,9 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) { | ||||
| void ProgressServiceBackend::SignalUpdate() { | ||||
|     if (need_hle_lock) { | ||||
|         std::lock_guard lock(HLE::g_hle_lock); | ||||
|         update_event.GetWritableEvent().Signal(); | ||||
|         update_event->GetWritableEvent().Signal(); | ||||
|     } else { | ||||
|         update_event.GetWritableEvent().Signal(); | ||||
|         update_event->GetWritableEvent().Signal(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -11,8 +11,8 @@ | ||||
|  | ||||
| #include "common/common_types.h" | ||||
| #include "core/file_sys/vfs_types.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/result.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
|  | ||||
| namespace Core { | ||||
| class System; | ||||
| @@ -70,6 +70,8 @@ class ProgressServiceBackend { | ||||
|     friend class IBcatService; | ||||
|  | ||||
| public: | ||||
|     ~ProgressServiceBackend(); | ||||
|  | ||||
|     // Clients should call this with true if any of the functions are going to be called from a | ||||
|     // non-HLE thread and this class need to lock the hle mutex. (default is false) | ||||
|     void SetNeedHLELock(bool need); | ||||
| @@ -97,15 +99,17 @@ public: | ||||
|     void FinishDownload(ResultCode result); | ||||
|  | ||||
| private: | ||||
|     explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name); | ||||
|     explicit ProgressServiceBackend(Core::System& system, std::string_view event_name); | ||||
|  | ||||
|     Kernel::KReadableEvent& GetEvent(); | ||||
|     DeliveryCacheProgressImpl& GetImpl(); | ||||
|  | ||||
|     void SignalUpdate(); | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     DeliveryCacheProgressImpl impl{}; | ||||
|     Kernel::KEvent update_event; | ||||
|     Kernel::KEvent* update_event; | ||||
|     bool need_hle_lock = false; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -4,7 +4,6 @@ | ||||
|  | ||||
| #include <cctype> | ||||
| #include <mbedtls/md5.h> | ||||
| #include "backend/boxcat.h" | ||||
| #include "common/hex_util.h" | ||||
| #include "common/logging/log.h" | ||||
| #include "common/settings.h" | ||||
| @@ -128,8 +127,8 @@ public: | ||||
|     explicit IBcatService(Core::System& system_, Backend& backend_) | ||||
|         : ServiceFramework{system_, "IBcatService"}, backend{backend_}, | ||||
|           progress{{ | ||||
|               ProgressServiceBackend{system_.Kernel(), "Normal"}, | ||||
|               ProgressServiceBackend{system_.Kernel(), "Directory"}, | ||||
|               ProgressServiceBackend{system_, "Normal"}, | ||||
|               ProgressServiceBackend{system_, "Directory"}, | ||||
|           }} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
| @@ -578,12 +577,6 @@ void Module::Interface::CreateDeliveryCacheStorageServiceWithApplicationId( | ||||
|  | ||||
| std::unique_ptr<Backend> CreateBackendFromSettings([[maybe_unused]] Core::System& system, | ||||
|                                                    DirectoryGetter getter) { | ||||
| #ifdef YUZU_ENABLE_BOXCAT | ||||
|     if (Settings::values.bcat_backend.GetValue() == "boxcat") { | ||||
|         return std::make_unique<Boxcat>(system.GetAppletManager(), std::move(getter)); | ||||
|     } | ||||
| #endif | ||||
|  | ||||
|     return std::make_unique<NullBackend>(std::move(getter)); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -7,9 +7,9 @@ | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/hle_ipc.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/btdrv/btdrv.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
|  | ||||
| @@ -18,7 +18,7 @@ namespace Service::BtDrv { | ||||
| class Bt final : public ServiceFramework<Bt> { | ||||
| public: | ||||
|     explicit Bt(Core::System& system_) | ||||
|         : ServiceFramework{system_, "bt"}, register_event{system.Kernel()} { | ||||
|         : ServiceFramework{system_, "bt"}, service_context{system_, "bt"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, nullptr, "LeClientReadCharacteristic"}, | ||||
| @@ -35,8 +35,11 @@ public: | ||||
|         // clang-format on | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         Kernel::KAutoObject::Create(std::addressof(register_event)); | ||||
|         register_event.Initialize("BT:RegisterEvent"); | ||||
|         register_event = service_context.CreateEvent("BT:RegisterEvent"); | ||||
|     } | ||||
|  | ||||
|     ~Bt() override { | ||||
|         service_context.CloseEvent(register_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
| @@ -45,10 +48,12 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(register_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(register_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     Kernel::KEvent register_event; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* register_event; | ||||
| }; | ||||
|  | ||||
| class BtDrv final : public ServiceFramework<BtDrv> { | ||||
|   | ||||
| @@ -9,9 +9,9 @@ | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/hle_ipc.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/btm/btm.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Service::BTM { | ||||
| @@ -19,9 +19,7 @@ namespace Service::BTM { | ||||
| class IBtmUserCore final : public ServiceFramework<IBtmUserCore> { | ||||
| public: | ||||
|     explicit IBtmUserCore(Core::System& system_) | ||||
|         : ServiceFramework{system_, "IBtmUserCore"}, scan_event{system.Kernel()}, | ||||
|           connection_event{system.Kernel()}, service_discovery{system.Kernel()}, | ||||
|           config_event{system.Kernel()} { | ||||
|         : ServiceFramework{system_, "IBtmUserCore"}, service_context{system_, "IBtmUserCore"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"}, | ||||
| @@ -60,15 +58,17 @@ public: | ||||
|         // clang-format on | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         Kernel::KAutoObject::Create(std::addressof(scan_event)); | ||||
|         Kernel::KAutoObject::Create(std::addressof(connection_event)); | ||||
|         Kernel::KAutoObject::Create(std::addressof(service_discovery)); | ||||
|         Kernel::KAutoObject::Create(std::addressof(config_event)); | ||||
|         scan_event = service_context.CreateEvent("IBtmUserCore:ScanEvent"); | ||||
|         connection_event = service_context.CreateEvent("IBtmUserCore:ConnectionEvent"); | ||||
|         service_discovery_event = service_context.CreateEvent("IBtmUserCore:DiscoveryEvent"); | ||||
|         config_event = service_context.CreateEvent("IBtmUserCore:ConfigEvent"); | ||||
|     } | ||||
|  | ||||
|         scan_event.Initialize("IBtmUserCore:ScanEvent"); | ||||
|         connection_event.Initialize("IBtmUserCore:ConnectionEvent"); | ||||
|         service_discovery.Initialize("IBtmUserCore:Discovery"); | ||||
|         config_event.Initialize("IBtmUserCore:ConfigEvent"); | ||||
|     ~IBtmUserCore() override { | ||||
|         service_context.CloseEvent(scan_event); | ||||
|         service_context.CloseEvent(connection_event); | ||||
|         service_context.CloseEvent(service_discovery_event); | ||||
|         service_context.CloseEvent(config_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
| @@ -77,7 +77,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(scan_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(scan_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) { | ||||
| @@ -85,7 +85,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(connection_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(connection_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) { | ||||
| @@ -93,7 +93,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(service_discovery.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(service_discovery_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) { | ||||
| @@ -101,13 +101,15 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(config_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(config_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     Kernel::KEvent scan_event; | ||||
|     Kernel::KEvent connection_event; | ||||
|     Kernel::KEvent service_discovery; | ||||
|     Kernel::KEvent config_event; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* scan_event; | ||||
|     Kernel::KEvent* connection_event; | ||||
|     Kernel::KEvent* service_discovery_event; | ||||
|     Kernel::KEvent* config_event; | ||||
| }; | ||||
|  | ||||
| class BTM_USR final : public ServiceFramework<BTM_USR> { | ||||
|   | ||||
| @@ -8,11 +8,10 @@ | ||||
| #include "core/core.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/k_writable_event.h" | ||||
| #include "core/hle/service/friend/errors.h" | ||||
| #include "core/hle/service/friend/friend.h" | ||||
| #include "core/hle/service/friend/friend_interface.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
|  | ||||
| namespace Service::Friend { | ||||
|  | ||||
| @@ -184,9 +183,9 @@ private: | ||||
|  | ||||
| class INotificationService final : public ServiceFramework<INotificationService> { | ||||
| public: | ||||
|     explicit INotificationService(Common::UUID uuid_, Core::System& system_) | ||||
|         : ServiceFramework{system_, "INotificationService"}, uuid{uuid_}, notification_event{ | ||||
|                                                                               system.Kernel()} { | ||||
|     explicit INotificationService(Core::System& system_, Common::UUID uuid_) | ||||
|         : ServiceFramework{system_, "INotificationService"}, uuid{uuid_}, | ||||
|           service_context{system_, "INotificationService"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &INotificationService::GetEvent, "GetEvent"}, | ||||
| @@ -197,8 +196,11 @@ public: | ||||
|  | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         Kernel::KAutoObject::Create(std::addressof(notification_event)); | ||||
|         notification_event.Initialize("INotificationService:NotifyEvent"); | ||||
|         notification_event = service_context.CreateEvent("INotificationService:NotifyEvent"); | ||||
|     } | ||||
|  | ||||
|     ~INotificationService() override { | ||||
|         service_context.CloseEvent(notification_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
| @@ -207,7 +209,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(notification_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(notification_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void Clear(Kernel::HLERequestContext& ctx) { | ||||
| @@ -272,8 +274,10 @@ private: | ||||
|         bool has_received_friend_request; | ||||
|     }; | ||||
|  | ||||
|     Common::UUID uuid{Common::INVALID_UUID}; | ||||
|     Kernel::KEvent notification_event; | ||||
|     Common::UUID uuid; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* notification_event; | ||||
|     std::queue<SizedNotificationInfo> notifications; | ||||
|     States states{}; | ||||
| }; | ||||
| @@ -293,7 +297,7 @@ void Module::Interface::CreateNotificationService(Kernel::HLERequestContext& ctx | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushIpcInterface<INotificationService>(uuid, system); | ||||
|     rb.PushIpcInterface<INotificationService>(system, uuid); | ||||
| } | ||||
|  | ||||
| Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_, | ||||
|   | ||||
| @@ -8,9 +8,8 @@ | ||||
| #include "common/logging/log.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_thread.h" | ||||
| #include "core/hle/kernel/k_writable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/lock.h" | ||||
| #include "core/hle/service/nfp/nfp.h" | ||||
| @@ -23,18 +22,21 @@ constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152); | ||||
|  | ||||
| Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_, | ||||
|                              const char* name) | ||||
|     : ServiceFramework{system_, name}, nfc_tag_load{system.Kernel()}, module{std::move(module_)} { | ||||
|     Kernel::KAutoObject::Create(std::addressof(nfc_tag_load)); | ||||
|     nfc_tag_load.Initialize("IUser:NFCTagDetected"); | ||||
|     : ServiceFramework{system_, name}, module{std::move(module_)}, service_context{system_, | ||||
|                                                                                    "NFP::IUser"} { | ||||
|     nfc_tag_load = service_context.CreateEvent("NFP::IUser:NFCTagDetected"); | ||||
| } | ||||
|  | ||||
| Module::Interface::~Interface() = default; | ||||
| Module::Interface::~Interface() { | ||||
|     service_context.CloseEvent(nfc_tag_load); | ||||
| } | ||||
|  | ||||
| class IUser final : public ServiceFramework<IUser> { | ||||
| public: | ||||
|     explicit IUser(Module::Interface& nfp_interface_, Core::System& system_) | ||||
|     explicit IUser(Module::Interface& nfp_interface_, Core::System& system_, | ||||
|                    KernelHelpers::ServiceContext& service_context_) | ||||
|         : ServiceFramework{system_, "NFP::IUser"}, nfp_interface{nfp_interface_}, | ||||
|           deactivate_event{system.Kernel()}, availability_change_event{system.Kernel()} { | ||||
|           service_context{service_context_} { | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &IUser::Initialize, "Initialize"}, | ||||
|             {1, &IUser::Finalize, "Finalize"}, | ||||
| @@ -64,11 +66,14 @@ public: | ||||
|         }; | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         Kernel::KAutoObject::Create(std::addressof(deactivate_event)); | ||||
|         Kernel::KAutoObject::Create(std::addressof(availability_change_event)); | ||||
|         deactivate_event = service_context.CreateEvent("NFP::IUser:DeactivateEvent"); | ||||
|         availability_change_event = | ||||
|             service_context.CreateEvent("NFP::IUser:AvailabilityChangeEvent"); | ||||
|     } | ||||
|  | ||||
|         deactivate_event.Initialize("IUser:DeactivateEvent"); | ||||
|         availability_change_event.Initialize("IUser:AvailabilityChangeEvent"); | ||||
|     ~IUser() override { | ||||
|         service_context.CloseEvent(deactivate_event); | ||||
|         service_context.CloseEvent(availability_change_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
| @@ -166,7 +171,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(deactivate_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(deactivate_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void StopDetection(Kernel::HLERequestContext& ctx) { | ||||
| @@ -175,7 +180,7 @@ private: | ||||
|         switch (device_state) { | ||||
|         case DeviceState::TagFound: | ||||
|         case DeviceState::TagNearby: | ||||
|             deactivate_event.GetWritableEvent().Signal(); | ||||
|             deactivate_event->GetWritableEvent().Signal(); | ||||
|             device_state = DeviceState::Initialized; | ||||
|             break; | ||||
|         case DeviceState::SearchingForTag: | ||||
| @@ -264,7 +269,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(availability_change_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(availability_change_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void GetRegisterInfo(Kernel::HLERequestContext& ctx) { | ||||
| @@ -313,14 +318,16 @@ private: | ||||
|         rb.PushRaw<u32>(0); // This is from the GetCommonInfo stub | ||||
|     } | ||||
|  | ||||
|     Module::Interface& nfp_interface; | ||||
|     KernelHelpers::ServiceContext& service_context; | ||||
|  | ||||
|     bool has_attached_handle{}; | ||||
|     const u64 device_handle{0}; // Npad device 1 | ||||
|     const u32 npad_id{0};       // Player 1 controller | ||||
|     State state{State::NonInitialized}; | ||||
|     DeviceState device_state{DeviceState::Initialized}; | ||||
|     Module::Interface& nfp_interface; | ||||
|     Kernel::KEvent deactivate_event; | ||||
|     Kernel::KEvent availability_change_event; | ||||
|     Kernel::KEvent* deactivate_event; | ||||
|     Kernel::KEvent* availability_change_event; | ||||
| }; | ||||
|  | ||||
| void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) { | ||||
| @@ -328,7 +335,7 @@ void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) { | ||||
|  | ||||
|     IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||||
|     rb.Push(ResultSuccess); | ||||
|     rb.PushIpcInterface<IUser>(*this, system); | ||||
|     rb.PushIpcInterface<IUser>(*this, system, service_context); | ||||
| } | ||||
|  | ||||
| bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) { | ||||
| @@ -338,12 +345,12 @@ bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) { | ||||
|     } | ||||
|  | ||||
|     std::memcpy(&amiibo, buffer.data(), sizeof(amiibo)); | ||||
|     nfc_tag_load.GetWritableEvent().Signal(); | ||||
|     nfc_tag_load->GetWritableEvent().Signal(); | ||||
|     return true; | ||||
| } | ||||
|  | ||||
| Kernel::KReadableEvent& Module::Interface::GetNFCEvent() { | ||||
|     return nfc_tag_load.GetReadableEvent(); | ||||
|     return nfc_tag_load->GetReadableEvent(); | ||||
| } | ||||
|  | ||||
| const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const { | ||||
|   | ||||
| @@ -7,7 +7,7 @@ | ||||
| #include <array> | ||||
| #include <vector> | ||||
|  | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace Kernel { | ||||
| @@ -42,12 +42,13 @@ public: | ||||
|         Kernel::KReadableEvent& GetNFCEvent(); | ||||
|         const AmiiboFile& GetAmiiboBuffer() const; | ||||
|  | ||||
|     private: | ||||
|         Kernel::KEvent nfc_tag_load; | ||||
|         AmiiboFile amiibo{}; | ||||
|  | ||||
|     protected: | ||||
|         std::shared_ptr<Module> module; | ||||
|  | ||||
|     private: | ||||
|         KernelHelpers::ServiceContext service_context; | ||||
|         Kernel::KEvent* nfc_tag_load; | ||||
|         AmiiboFile amiibo{}; | ||||
|     }; | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -6,10 +6,21 @@ | ||||
| #include "core/core.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/nifm/nifm.h" | ||||
| #include "core/hle/service/service.h" | ||||
|  | ||||
| namespace { | ||||
|  | ||||
| // Avoids name conflict with Windows' CreateEvent macro. | ||||
| [[nodiscard]] Kernel::KEvent* CreateKEvent(Service::KernelHelpers::ServiceContext& service_context, | ||||
|                                            std::string&& name) { | ||||
|     return service_context.CreateEvent(std::move(name)); | ||||
| } | ||||
|  | ||||
| } // Anonymous namespace | ||||
|  | ||||
| #include "core/network/network.h" | ||||
| #include "core/network/network_interface.h" | ||||
|  | ||||
| @@ -129,7 +140,7 @@ public: | ||||
| class IRequest final : public ServiceFramework<IRequest> { | ||||
| public: | ||||
|     explicit IRequest(Core::System& system_) | ||||
|         : ServiceFramework{system_, "IRequest"}, event1{system.Kernel()}, event2{system.Kernel()} { | ||||
|         : ServiceFramework{system_, "IRequest"}, service_context{system_, "IRequest"} { | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &IRequest::GetRequestState, "GetRequestState"}, | ||||
|             {1, &IRequest::GetResult, "GetResult"}, | ||||
| @@ -159,11 +170,13 @@ public: | ||||
|         }; | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         Kernel::KAutoObject::Create(std::addressof(event1)); | ||||
|         Kernel::KAutoObject::Create(std::addressof(event2)); | ||||
|         event1 = CreateKEvent(service_context, "IRequest:Event1"); | ||||
|         event2 = CreateKEvent(service_context, "IRequest:Event2"); | ||||
|     } | ||||
|  | ||||
|         event1.Initialize("IRequest:Event1"); | ||||
|         event2.Initialize("IRequest:Event2"); | ||||
|     ~IRequest() override { | ||||
|         service_context.CloseEvent(event1); | ||||
|         service_context.CloseEvent(event2); | ||||
|     } | ||||
|  | ||||
| private: | ||||
| @@ -199,7 +212,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(event1.GetReadableEvent(), event2.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(event1->GetReadableEvent(), event2->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void Cancel(Kernel::HLERequestContext& ctx) { | ||||
| @@ -230,7 +243,10 @@ private: | ||||
|         rb.Push<u32>(0); | ||||
|     } | ||||
|  | ||||
|     Kernel::KEvent event1, event2; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* event1; | ||||
|     Kernel::KEvent* event2; | ||||
| }; | ||||
|  | ||||
| class INetworkProfile final : public ServiceFramework<INetworkProfile> { | ||||
|   | ||||
| @@ -7,9 +7,8 @@ | ||||
| #include "core/core.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/k_writable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/nim/nim.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
| @@ -301,7 +300,7 @@ class IEnsureNetworkClockAvailabilityService final | ||||
| public: | ||||
|     explicit IEnsureNetworkClockAvailabilityService(Core::System& system_) | ||||
|         : ServiceFramework{system_, "IEnsureNetworkClockAvailabilityService"}, | ||||
|           finished_event{system.Kernel()} { | ||||
|           service_context{system_, "IEnsureNetworkClockAvailabilityService"} { | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"}, | ||||
|             {1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent, | ||||
| @@ -313,17 +312,19 @@ public: | ||||
|         }; | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         Kernel::KAutoObject::Create(std::addressof(finished_event)); | ||||
|         finished_event.Initialize("IEnsureNetworkClockAvailabilityService:FinishEvent"); | ||||
|         finished_event = | ||||
|             service_context.CreateEvent("IEnsureNetworkClockAvailabilityService:FinishEvent"); | ||||
|     } | ||||
|  | ||||
|     ~IEnsureNetworkClockAvailabilityService() override { | ||||
|         service_context.CloseEvent(finished_event); | ||||
|     } | ||||
|  | ||||
| private: | ||||
|     Kernel::KEvent finished_event; | ||||
|  | ||||
|     void StartTask(Kernel::HLERequestContext& ctx) { | ||||
|         // No need to connect to the internet, just finish the task straight away. | ||||
|         LOG_DEBUG(Service_NIM, "called"); | ||||
|         finished_event.GetWritableEvent().Signal(); | ||||
|         finished_event->GetWritableEvent().Signal(); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
| @@ -333,7 +334,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(finished_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(finished_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void GetResult(Kernel::HLERequestContext& ctx) { | ||||
| @@ -345,7 +346,7 @@ private: | ||||
|  | ||||
|     void Cancel(Kernel::HLERequestContext& ctx) { | ||||
|         LOG_DEBUG(Service_NIM, "called"); | ||||
|         finished_event.GetWritableEvent().Clear(); | ||||
|         finished_event->GetWritableEvent().Clear(); | ||||
|         IPC::ResponseBuilder rb{ctx, 2}; | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
| @@ -368,6 +369,10 @@ private: | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushRaw<s64>(server_time); | ||||
|     } | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     Kernel::KEvent* finished_event; | ||||
| }; | ||||
|  | ||||
| class NTC final : public ServiceFramework<NTC> { | ||||
|   | ||||
| @@ -8,9 +8,8 @@ | ||||
| #include "core/core.h" | ||||
| #include "core/hle/ipc_helpers.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/kernel/k_readable_event.h" | ||||
| #include "core/hle/kernel/k_writable_event.h" | ||||
| #include "core/hle/kernel/kernel.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/ptm/psm.h" | ||||
| #include "core/hle/service/service.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
| @@ -20,7 +19,7 @@ namespace Service::PSM { | ||||
| class IPsmSession final : public ServiceFramework<IPsmSession> { | ||||
| public: | ||||
|     explicit IPsmSession(Core::System& system_) | ||||
|         : ServiceFramework{system_, "IPsmSession"}, state_change_event{system.Kernel()} { | ||||
|         : ServiceFramework{system_, "IPsmSession"}, service_context{system_, "IPsmSession"} { | ||||
|         // clang-format off | ||||
|         static const FunctionInfo functions[] = { | ||||
|             {0, &IPsmSession::BindStateChangeEvent, "BindStateChangeEvent"}, | ||||
| @@ -33,27 +32,28 @@ public: | ||||
|  | ||||
|         RegisterHandlers(functions); | ||||
|  | ||||
|         Kernel::KAutoObject::Create(std::addressof(state_change_event)); | ||||
|         state_change_event.Initialize("IPsmSession::state_change_event"); | ||||
|         state_change_event = service_context.CreateEvent("IPsmSession::state_change_event"); | ||||
|     } | ||||
|  | ||||
|     ~IPsmSession() override = default; | ||||
|     ~IPsmSession() override { | ||||
|         service_context.CloseEvent(state_change_event); | ||||
|     } | ||||
|  | ||||
|     void SignalChargerTypeChanged() { | ||||
|         if (should_signal && should_signal_charger_type) { | ||||
|             state_change_event.GetWritableEvent().Signal(); | ||||
|             state_change_event->GetWritableEvent().Signal(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void SignalPowerSupplyChanged() { | ||||
|         if (should_signal && should_signal_power_supply) { | ||||
|             state_change_event.GetWritableEvent().Signal(); | ||||
|             state_change_event->GetWritableEvent().Signal(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void SignalBatteryVoltageStateChanged() { | ||||
|         if (should_signal && should_signal_battery_voltage) { | ||||
|             state_change_event.GetWritableEvent().Signal(); | ||||
|             state_change_event->GetWritableEvent().Signal(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -65,7 +65,7 @@ private: | ||||
|  | ||||
|         IPC::ResponseBuilder rb{ctx, 2, 1}; | ||||
|         rb.Push(ResultSuccess); | ||||
|         rb.PushCopyObjects(state_change_event.GetReadableEvent()); | ||||
|         rb.PushCopyObjects(state_change_event->GetReadableEvent()); | ||||
|     } | ||||
|  | ||||
|     void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) { | ||||
| @@ -110,11 +110,13 @@ private: | ||||
|         rb.Push(ResultSuccess); | ||||
|     } | ||||
|  | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|  | ||||
|     bool should_signal_charger_type{}; | ||||
|     bool should_signal_power_supply{}; | ||||
|     bool should_signal_battery_voltage{}; | ||||
|     bool should_signal{}; | ||||
|     Kernel::KEvent state_change_event; | ||||
|     Kernel::KEvent* state_change_event; | ||||
| }; | ||||
|  | ||||
| class PSM final : public ServiceFramework<PSM> { | ||||
|   | ||||
| @@ -4,6 +4,7 @@ | ||||
|  | ||||
| #include "common/assert.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/time/standard_local_system_clock_core.h" | ||||
| #include "core/hle/service/time/standard_network_system_clock_core.h" | ||||
| #include "core/hle/service/time/standard_user_system_clock_core.h" | ||||
| @@ -16,10 +17,15 @@ StandardUserSystemClockCore::StandardUserSystemClockCore( | ||||
|     : SystemClockCore(local_system_clock_core_.GetSteadyClockCore()), | ||||
|       local_system_clock_core{local_system_clock_core_}, | ||||
|       network_system_clock_core{network_system_clock_core_}, | ||||
|       auto_correction_time{SteadyClockTimePoint::GetRandom()}, auto_correction_event{ | ||||
|                                                                    system_.Kernel()} { | ||||
|     Kernel::KAutoObject::Create(std::addressof(auto_correction_event)); | ||||
|     auto_correction_event.Initialize("StandardUserSystemClockCore:AutoCorrectionEvent"); | ||||
|       auto_correction_time{SteadyClockTimePoint::GetRandom()}, service_context{ | ||||
|                                                                    system_, | ||||
|                                                                    "StandardUserSystemClockCore"} { | ||||
|     auto_correction_event = | ||||
|         service_context.CreateEvent("StandardUserSystemClockCore:AutoCorrectionEvent"); | ||||
| } | ||||
|  | ||||
| StandardUserSystemClockCore::~StandardUserSystemClockCore() { | ||||
|     service_context.CloseEvent(auto_correction_event); | ||||
| } | ||||
|  | ||||
| ResultCode StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::System& system, | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "core/hle/kernel/k_event.h" | ||||
| #include "core/hle/service/kernel_helpers.h" | ||||
| #include "core/hle/service/time/clock_types.h" | ||||
| #include "core/hle/service/time/system_clock_core.h" | ||||
|  | ||||
| @@ -27,6 +27,8 @@ public: | ||||
|                                 StandardNetworkSystemClockCore& network_system_clock_core_, | ||||
|                                 Core::System& system_); | ||||
|  | ||||
|     ~StandardUserSystemClockCore() override; | ||||
|  | ||||
|     ResultCode SetAutomaticCorrectionEnabled(Core::System& system, bool value); | ||||
|  | ||||
|     ResultCode GetClockContext(Core::System& system, SystemClockContext& ctx) const override; | ||||
| @@ -55,7 +57,8 @@ private: | ||||
|     StandardNetworkSystemClockCore& network_system_clock_core; | ||||
|     bool auto_correction_enabled{}; | ||||
|     SteadyClockTimePoint auto_correction_time; | ||||
|     Kernel::KEvent auto_correction_event; | ||||
|     KernelHelpers::ServiceContext service_context; | ||||
|     Kernel::KEvent* auto_correction_event; | ||||
| }; | ||||
|  | ||||
| } // namespace Service::Time::Clock | ||||
|   | ||||
| @@ -290,10 +290,6 @@ if (YUZU_USE_QT_WEB_ENGINE) | ||||
|     target_compile_definitions(yuzu PRIVATE -DYUZU_USE_QT_WEB_ENGINE) | ||||
| endif () | ||||
|  | ||||
| if (YUZU_ENABLE_BOXCAT) | ||||
|     target_compile_definitions(yuzu PRIVATE -DYUZU_ENABLE_BOXCAT) | ||||
| endif () | ||||
|  | ||||
| if(UNIX AND NOT APPLE) | ||||
|     install(TARGETS yuzu RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") | ||||
| endif() | ||||
|   | ||||
| @@ -709,8 +709,6 @@ void Config::ReadDebuggingValues() { | ||||
|  | ||||
| void Config::ReadServiceValues() { | ||||
|     qt_config->beginGroup(QStringLiteral("Services")); | ||||
|     ReadBasicSetting(Settings::values.bcat_backend); | ||||
|     ReadBasicSetting(Settings::values.bcat_boxcat_local); | ||||
|     ReadBasicSetting(Settings::values.network_interface); | ||||
|     qt_config->endGroup(); | ||||
| } | ||||
| @@ -1269,8 +1267,6 @@ void Config::SaveDebuggingValues() { | ||||
| void Config::SaveNetworkValues() { | ||||
|     qt_config->beginGroup(QStringLiteral("Services")); | ||||
|  | ||||
|     WriteBasicSetting(Settings::values.bcat_backend); | ||||
|     WriteBasicSetting(Settings::values.bcat_boxcat_local); | ||||
|     WriteBasicSetting(Settings::values.network_interface); | ||||
|  | ||||
|     qt_config->endGroup(); | ||||
|   | ||||
| @@ -6,64 +6,25 @@ | ||||
| #include <QtConcurrent/QtConcurrent> | ||||
| #include "common/settings.h" | ||||
| #include "core/core.h" | ||||
| #include "core/hle/service/bcat/backend/boxcat.h" | ||||
| #include "core/network/network_interface.h" | ||||
| #include "ui_configure_network.h" | ||||
| #include "yuzu/configuration/configure_network.h" | ||||
|  | ||||
| #ifdef YUZU_ENABLE_BOXCAT | ||||
| namespace { | ||||
| QString FormatEventStatusString(const Service::BCAT::EventStatus& status) { | ||||
|     QString out; | ||||
|  | ||||
|     if (status.header.has_value()) { | ||||
|         out += QStringLiteral("<i>%1</i><br>").arg(QString::fromStdString(*status.header)); | ||||
|     } | ||||
|  | ||||
|     if (status.events.size() == 1) { | ||||
|         out += QStringLiteral("%1<br>").arg(QString::fromStdString(status.events.front())); | ||||
|     } else { | ||||
|         for (const auto& event : status.events) { | ||||
|             out += QStringLiteral("- %1<br>").arg(QString::fromStdString(event)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (status.footer.has_value()) { | ||||
|         out += QStringLiteral("<i>%1</i><br>").arg(QString::fromStdString(*status.footer)); | ||||
|     } | ||||
|  | ||||
|     return out; | ||||
| } | ||||
| } // Anonymous namespace | ||||
| #endif | ||||
|  | ||||
| ConfigureNetwork::ConfigureNetwork(QWidget* parent) | ||||
|     : QWidget(parent), ui(std::make_unique<Ui::ConfigureNetwork>()) { | ||||
|     ui->setupUi(this); | ||||
|  | ||||
|     ui->bcat_source->addItem(QStringLiteral("None")); | ||||
|     ui->bcat_empty_label->setHidden(true); | ||||
|     ui->bcat_empty_header->setHidden(true); | ||||
|  | ||||
| #ifdef YUZU_ENABLE_BOXCAT | ||||
|     ui->bcat_source->addItem(QStringLiteral("Boxcat"), QStringLiteral("boxcat")); | ||||
| #endif | ||||
|  | ||||
|     ui->network_interface->addItem(tr("None")); | ||||
|     for (const auto& iface : Network::GetAvailableNetworkInterfaces()) { | ||||
|         ui->network_interface->addItem(QString::fromStdString(iface.name)); | ||||
|     } | ||||
|  | ||||
|     connect(ui->bcat_source, QOverload<int>::of(&QComboBox::currentIndexChanged), this, | ||||
|             &ConfigureNetwork::OnBCATImplChanged); | ||||
|  | ||||
|     this->SetConfiguration(); | ||||
| } | ||||
|  | ||||
| ConfigureNetwork::~ConfigureNetwork() = default; | ||||
|  | ||||
| void ConfigureNetwork::ApplyConfiguration() { | ||||
|     Settings::values.bcat_backend = ui->bcat_source->currentText().toLower().toStdString(); | ||||
|     Settings::values.network_interface = ui->network_interface->currentText().toStdString(); | ||||
| } | ||||
|  | ||||
| @@ -74,86 +35,8 @@ void ConfigureNetwork::RetranslateUi() { | ||||
| void ConfigureNetwork::SetConfiguration() { | ||||
|     const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); | ||||
|  | ||||
|     const int index = | ||||
|         ui->bcat_source->findData(QString::fromStdString(Settings::values.bcat_backend.GetValue())); | ||||
|     ui->bcat_source->setCurrentIndex(index == -1 ? 0 : index); | ||||
|  | ||||
|     const std::string& network_interface = Settings::values.network_interface.GetValue(); | ||||
|  | ||||
|     ui->network_interface->setCurrentText(QString::fromStdString(network_interface)); | ||||
|     ui->network_interface->setEnabled(runtime_lock); | ||||
| } | ||||
|  | ||||
| std::pair<QString, QString> ConfigureNetwork::BCATDownloadEvents() { | ||||
| #ifdef YUZU_ENABLE_BOXCAT | ||||
|     std::optional<std::string> global; | ||||
|     std::map<std::string, Service::BCAT::EventStatus> map; | ||||
|     const auto res = Service::BCAT::Boxcat::GetStatus(global, map); | ||||
|  | ||||
|     switch (res) { | ||||
|     case Service::BCAT::Boxcat::StatusResult::Success: | ||||
|         break; | ||||
|     case Service::BCAT::Boxcat::StatusResult::Offline: | ||||
|         return {QString{}, | ||||
|                 tr("The boxcat service is offline or you are not connected to the internet.")}; | ||||
|     case Service::BCAT::Boxcat::StatusResult::ParseError: | ||||
|         return {QString{}, | ||||
|                 tr("There was an error while processing the boxcat event data. Contact the yuzu " | ||||
|                    "developers.")}; | ||||
|     case Service::BCAT::Boxcat::StatusResult::BadClientVersion: | ||||
|         return {QString{}, | ||||
|                 tr("The version of yuzu you are using is either too new or too old for the server. " | ||||
|                    "Try updating to the latest official release of yuzu.")}; | ||||
|     } | ||||
|  | ||||
|     if (map.empty()) { | ||||
|         return {QStringLiteral("Current Boxcat Events"), | ||||
|                 tr("There are currently no events on boxcat.")}; | ||||
|     } | ||||
|  | ||||
|     QString out; | ||||
|  | ||||
|     if (global.has_value()) { | ||||
|         out += QStringLiteral("%1<br>").arg(QString::fromStdString(*global)); | ||||
|     } | ||||
|  | ||||
|     for (const auto& [key, value] : map) { | ||||
|         out += QStringLiteral("%1<b>%2</b><br>%3") | ||||
|                    .arg(out.isEmpty() ? QString{} : QStringLiteral("<br>")) | ||||
|                    .arg(QString::fromStdString(key)) | ||||
|                    .arg(FormatEventStatusString(value)); | ||||
|     } | ||||
|     return {tr("Current Boxcat Events"), std::move(out)}; | ||||
| #else | ||||
|     return {tr("Current Boxcat Events"), tr("There are currently no events on boxcat.")}; | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void ConfigureNetwork::OnBCATImplChanged() { | ||||
| #ifdef YUZU_ENABLE_BOXCAT | ||||
|     const auto boxcat = ui->bcat_source->currentText() == QStringLiteral("Boxcat"); | ||||
|     ui->bcat_empty_header->setHidden(!boxcat); | ||||
|     ui->bcat_empty_label->setHidden(!boxcat); | ||||
|     ui->bcat_empty_header->setText(QString{}); | ||||
|     ui->bcat_empty_label->setText(tr("Yuzu is retrieving the latest boxcat status...")); | ||||
|  | ||||
|     if (!boxcat) | ||||
|         return; | ||||
|  | ||||
|     const auto future = QtConcurrent::run([this] { return BCATDownloadEvents(); }); | ||||
|  | ||||
|     watcher.setFuture(future); | ||||
|     connect(&watcher, &QFutureWatcher<std::pair<QString, QString>>::finished, this, | ||||
|             [this] { OnUpdateBCATEmptyLabel(watcher.result()); }); | ||||
| #endif | ||||
| } | ||||
|  | ||||
| void ConfigureNetwork::OnUpdateBCATEmptyLabel(std::pair<QString, QString> string) { | ||||
| #ifdef YUZU_ENABLE_BOXCAT | ||||
|     const auto boxcat = ui->bcat_source->currentText() == QStringLiteral("Boxcat"); | ||||
|     if (boxcat) { | ||||
|         ui->bcat_empty_header->setText(string.first); | ||||
|         ui->bcat_empty_label->setText(string.second); | ||||
|     } | ||||
| #endif | ||||
| } | ||||
|   | ||||
| @@ -25,10 +25,5 @@ public: | ||||
| private: | ||||
|     void SetConfiguration(); | ||||
|  | ||||
|     std::pair<QString, QString> BCATDownloadEvents(); | ||||
|     void OnBCATImplChanged(); | ||||
|     void OnUpdateBCATEmptyLabel(std::pair<QString, QString> string); | ||||
|  | ||||
|     std::unique_ptr<Ui::ConfigureNetwork> ui; | ||||
|     QFutureWatcher<std::pair<QString, QString>> watcher{this}; | ||||
| }; | ||||
|   | ||||
| @@ -35,92 +35,6 @@ | ||||
|        </layout> | ||||
|       </widget> | ||||
|      </item> | ||||
|      <item> | ||||
|       <widget class="QGroupBox" name="groupBox"> | ||||
|        <property name="title"> | ||||
|         <string>BCAT</string> | ||||
|        </property> | ||||
|        <layout class="QGridLayout" name="gridLayout"> | ||||
|         <item row="3" column="0"> | ||||
|          <widget class="QLabel" name="bcat_empty_header"> | ||||
|           <property name="text"> | ||||
|            <string/> | ||||
|           </property> | ||||
|           <property name="alignment"> | ||||
|            <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> | ||||
|           </property> | ||||
|           <property name="wordWrap"> | ||||
|            <bool>true</bool> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item row="0" column="0"> | ||||
|          <widget class="QLabel" name="label"> | ||||
|           <property name="maximumSize"> | ||||
|            <size> | ||||
|             <width>16777215</width> | ||||
|             <height>16777215</height> | ||||
|            </size> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string>BCAT Backend</string> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item row="1" column="1" colspan="2"> | ||||
|          <widget class="QLabel" name="label_2"> | ||||
|           <property name="maximumSize"> | ||||
|            <size> | ||||
|             <width>260</width> | ||||
|             <height>16777215</height> | ||||
|            </size> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string>BCAT is Nintendo's way of sending data to games to engage its community and unlock additional content.</string> | ||||
|           </property> | ||||
|           <property name="wordWrap"> | ||||
|            <bool>true</bool> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item row="2" column="1" colspan="2"> | ||||
|          <widget class="QLabel" name="label_3"> | ||||
|           <property name="text"> | ||||
|            <string><html><head/><body><p><a href="https://yuzu-emu.org/help/feature/boxcat"><span style=" text-decoration: underline; color:#0000ff;">Learn more about BCAT, Boxcat, and Current Events</span></a></p></body></html></string> | ||||
|           </property> | ||||
|           <property name="openExternalLinks"> | ||||
|            <bool>true</bool> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|         <item row="0" column="1" colspan="2"> | ||||
|          <widget class="QComboBox" name="bcat_source"/> | ||||
|         </item> | ||||
|         <item row="3" column="1" colspan="2"> | ||||
|          <widget class="QLabel" name="bcat_empty_label"> | ||||
|           <property name="enabled"> | ||||
|            <bool>true</bool> | ||||
|           </property> | ||||
|           <property name="maximumSize"> | ||||
|            <size> | ||||
|             <width>260</width> | ||||
|             <height>16777215</height> | ||||
|            </size> | ||||
|           </property> | ||||
|           <property name="text"> | ||||
|            <string/> | ||||
|           </property> | ||||
|           <property name="alignment"> | ||||
|            <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> | ||||
|           </property> | ||||
|           <property name="wordWrap"> | ||||
|            <bool>true</bool> | ||||
|           </property> | ||||
|          </widget> | ||||
|         </item> | ||||
|        </layout> | ||||
|       </widget> | ||||
|      </item> | ||||
|     </layout> | ||||
|    </item> | ||||
|    <item> | ||||
|   | ||||
| @@ -518,10 +518,6 @@ void Config::ReadValues() { | ||||
|     ReadSetting("WebService", Settings::values.web_api_url); | ||||
|     ReadSetting("WebService", Settings::values.yuzu_username); | ||||
|     ReadSetting("WebService", Settings::values.yuzu_token); | ||||
|  | ||||
|     // Services | ||||
|     ReadSetting("Services", Settings::values.bcat_backend); | ||||
|     ReadSetting("Services", Settings::values.bcat_boxcat_local); | ||||
| } | ||||
|  | ||||
| void Config::Reload() { | ||||
|   | ||||
| @@ -428,11 +428,6 @@ web_api_url = https://api.yuzu-emu.org | ||||
| yuzu_username = | ||||
| yuzu_token = | ||||
|  | ||||
| [Services] | ||||
| # The name of the backend to use for BCAT | ||||
| # If this is set to 'boxcat' boxcat will be used, otherwise a null implementation will be used | ||||
| bcat_backend = | ||||
|  | ||||
| [AddOns] | ||||
| # Used to disable add-ons | ||||
| # List of title IDs of games that will have add-ons disabled (separated by '|'): | ||||
|   | ||||
		Reference in New Issue
	
	Block a user