summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/CMakeLists.txt17
-rw-r--r--src/core/core.cpp114
-rw-r--r--src/core/core.h73
-rw-r--r--src/core/file_sys/program_metadata.cpp2
-rw-r--r--src/core/file_sys/vfs_libzip.cpp88
-rw-r--r--src/core/file_sys/vfs_libzip.h13
-rw-r--r--src/core/frontend/applets/profile_select.cpp3
-rw-r--r--src/core/hle/ipc_helpers.h3
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp1
-rw-r--r--src/core/hle/kernel/hle_ipc.h2
-rw-r--r--src/core/hle/kernel/k_auto_object_container.cpp2
-rw-r--r--src/core/hle/kernel/k_handle_table.cpp2
-rw-r--r--src/core/hle/kernel/k_priority_queue.h27
-rw-r--r--src/core/hle/kernel/k_process.cpp54
-rw-r--r--src/core/hle/kernel/k_process.h4
-rw-r--r--src/core/hle/kernel/k_scheduler.h2
-rw-r--r--src/core/hle/kernel/k_scoped_lock.h15
-rw-r--r--src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h2
-rw-r--r--src/core/hle/kernel/k_shared_memory_info.h46
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/svc.cpp14
-rw-r--r--src/core/hle/service/acc/acc.cpp3
-rw-r--r--src/core/hle/service/acc/async_context.cpp17
-rw-r--r--src/core/hle/service/acc/async_context.h7
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp9
-rw-r--r--src/core/hle/service/am/am.cpp123
-rw-r--r--src/core/hle/service/am/am.h32
-rw-r--r--src/core/hle/service/am/applet_ae.h2
-rw-r--r--src/core/hle/service/am/applet_oe.h2
-rw-r--r--src/core/hle/service/am/applets/applet_profile_select.cpp2
-rw-r--r--src/core/hle/service/am/applets/applet_web_browser.cpp10
-rw-r--r--src/core/hle/service/am/applets/applets.cpp41
-rw-r--r--src/core/hle/service/am/applets/applets.h10
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp31
-rw-r--r--src/core/hle/service/aoc/aoc_u.h6
-rw-r--r--src/core/hle/service/audio/audctl.cpp8
-rw-r--r--src/core/hle/service/audio/audin_u.cpp81
-rw-r--r--src/core/hle/service/audio/audin_u.h16
-rw-r--r--src/core/hle/service/audio/audout_u.cpp33
-rw-r--r--src/core/hle/service/audio/audren_u.cpp45
-rw-r--r--src/core/hle/service/audio/audren_u.h6
-rw-r--r--src/core/hle/service/audio/hwopus.cpp1
-rw-r--r--src/core/hle/service/bcat/backend/backend.cpp22
-rw-r--r--src/core/hle/service/bcat/backend/backend.h10
-rw-r--r--src/core/hle/service/bcat/backend/boxcat.cpp548
-rw-r--r--src/core/hle/service/bcat/backend/boxcat.h64
-rw-r--r--src/core/hle/service/bcat/bcat_module.cpp11
-rw-r--r--src/core/hle/service/btdrv/btdrv.cpp22
-rw-r--r--src/core/hle/service/btm/btm.cpp43
-rw-r--r--src/core/hle/service/caps/caps.h3
-rw-r--r--src/core/hle/service/caps/caps_ss.cpp1
-rw-r--r--src/core/hle/service/es/es.cpp6
-rw-r--r--src/core/hle/service/fgm/fgm.cpp1
-rw-r--r--src/core/hle/service/filesystem/fsp_ldr.cpp1
-rw-r--r--src/core/hle/service/filesystem/fsp_pr.cpp1
-rw-r--r--src/core/hle/service/friend/friend.cpp26
-rw-r--r--src/core/hle/service/glue/arp.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/npad.h1
-rw-r--r--src/core/hle/service/hid/hid.cpp15
-rw-r--r--src/core/hle/service/lbl/lbl.cpp2
-rw-r--r--src/core/hle/service/mii/mii.cpp1
-rw-r--r--src/core/hle/service/nfc/nfc.cpp1
-rw-r--r--src/core/hle/service/nfp/nfp.cpp49
-rw-r--r--src/core/hle/service/nfp/nfp.h11
-rw-r--r--src/core/hle/service/nifm/nifm.cpp32
-rw-r--r--src/core/hle/service/nim/nim.cpp25
-rw-r--r--src/core/hle/service/npns/npns.cpp1
-rw-r--r--src/core/hle/service/ns/ns.cpp1
-rw-r--r--src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp7
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp42
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp13
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h2
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp29
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h11
-rw-r--r--src/core/hle/service/olsc/olsc.cpp1
-rw-r--r--src/core/hle/service/ptm/psm.cpp24
-rw-r--r--src/core/hle/service/set/set_sys.cpp1
-rw-r--r--src/core/hle/service/sockets/bsd.cpp14
-rw-r--r--src/core/hle/service/sockets/bsd.h3
-rw-r--r--src/core/hle/service/sockets/sfdnsres.h1
-rw-r--r--src/core/hle/service/sockets/sockets.h6
-rw-r--r--src/core/hle/service/spl/spl_module.cpp2
-rw-r--r--src/core/hle/service/ssl/ssl.cpp1
-rw-r--r--src/core/hle/service/time/standard_user_system_clock_core.cpp14
-rw-r--r--src/core/hle/service/time/standard_user_system_clock_core.h7
-rw-r--r--src/core/hle/service/time/system_clock_context_update_callback.h1
-rw-r--r--src/core/hle/service/time/system_clock_core.cpp2
-rw-r--r--src/core/hle/service/time/system_clock_core.h2
-rw-r--r--src/core/hle/service/time/time.cpp2
-rw-r--r--src/core/hle/service/time/time.h1
-rw-r--r--src/core/hle/service/time/time_zone_service.cpp4
-rw-r--r--src/core/hle/service/usb/usb.cpp7
-rw-r--r--src/core/hle/service/vi/vi.cpp13
-rw-r--r--src/core/hle/service/vi/vi.h1
-rw-r--r--src/core/memory.cpp6
-rw-r--r--src/core/network/network.cpp2
96 files changed, 839 insertions, 1253 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 7140d0db8..9f0fbba2d 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -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)
diff --git a/src/core/core.cpp b/src/core/core.cpp
index b13350f6e..3042d611b 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -139,27 +139,47 @@ struct System::Impl {
: kernel{system}, fs_controller{system}, memory{system},
cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
- ResultStatus Run() {
- status = ResultStatus::Success;
+ SystemResultStatus Run() {
+ std::unique_lock<std::mutex> lk(suspend_guard);
+ status = SystemResultStatus::Success;
kernel.Suspend(false);
core_timing.SyncPause(false);
cpu_manager.Pause(false);
+ is_paused = false;
return status;
}
- ResultStatus Pause() {
- status = ResultStatus::Success;
+ SystemResultStatus Pause() {
+ std::unique_lock<std::mutex> lk(suspend_guard);
+ status = SystemResultStatus::Success;
core_timing.SyncPause(true);
kernel.Suspend(true);
cpu_manager.Pause(true);
+ is_paused = true;
return status;
}
- ResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
+ std::unique_lock<std::mutex> StallCPU() {
+ std::unique_lock<std::mutex> lk(suspend_guard);
+ kernel.Suspend(true);
+ core_timing.SyncPause(true);
+ cpu_manager.Pause(true);
+ return lk;
+ }
+
+ void UnstallCPU() {
+ if (!is_paused) {
+ core_timing.SyncPause(false);
+ kernel.Suspend(false);
+ cpu_manager.Pause(false);
+ }
+ }
+
+ SystemResultStatus Init(System& system, Frontend::EmuWindow& emu_window) {
LOG_DEBUG(Core, "initialized OK");
device_memory = std::make_unique<Core::DeviceMemory>();
@@ -197,7 +217,7 @@ struct System::Impl {
gpu_core = VideoCore::CreateGPU(emu_window, system);
if (!gpu_core) {
- return ResultStatus::ErrorVideoCore;
+ return SystemResultStatus::ErrorVideoCore;
}
service_manager = std::make_shared<Service::SM::ServiceManager>(kernel);
@@ -217,21 +237,22 @@ struct System::Impl {
LOG_DEBUG(Core, "Initialized OK");
- return ResultStatus::Success;
+ return SystemResultStatus::Success;
}
- ResultStatus Load(System& system, Frontend::EmuWindow& emu_window, const std::string& filepath,
- u64 program_id, std::size_t program_index) {
+ SystemResultStatus Load(System& system, Frontend::EmuWindow& emu_window,
+ const std::string& filepath, u64 program_id,
+ std::size_t program_index) {
app_loader = Loader::GetLoader(system, GetGameFileFromPath(virtual_filesystem, filepath),
program_id, program_index);
if (!app_loader) {
LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath);
- return ResultStatus::ErrorGetLoader;
+ return SystemResultStatus::ErrorGetLoader;
}
- ResultStatus init_result{Init(system, emu_window)};
- if (init_result != ResultStatus::Success) {
+ SystemResultStatus init_result{Init(system, emu_window)};
+ if (init_result != SystemResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to initialize system (Error {})!",
static_cast<int>(init_result));
Shutdown();
@@ -249,8 +270,8 @@ struct System::Impl {
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
Shutdown();
- return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) +
- static_cast<u32>(load_result));
+ return static_cast<SystemResultStatus>(
+ static_cast<u32>(SystemResultStatus::ErrorLoader) + static_cast<u32>(load_result));
}
AddGlueRegistrationForProcess(*app_loader, *main_process);
kernel.MakeCurrentProcess(main_process.get());
@@ -282,7 +303,7 @@ struct System::Impl {
GetAndResetPerfStats();
perf_stats->BeginSystemFrame();
- status = ResultStatus::Success;
+ status = SystemResultStatus::Success;
return status;
}
@@ -305,10 +326,6 @@ struct System::Impl {
is_powered_on = false;
exit_lock = false;
- if (gpu_core) {
- gpu_core->ShutDown();
- }
-
services.reset();
service_manager.reset();
cheat_engine.reset();
@@ -317,8 +334,8 @@ struct System::Impl {
time_manager.Shutdown();
core_timing.Shutdown();
app_loader.reset();
- gpu_core.reset();
perf_stats.reset();
+ gpu_core.reset();
kernel.Shutdown();
memory.Reset();
applet_manager.ClearAll();
@@ -359,7 +376,7 @@ struct System::Impl {
arp_manager.Register(launch.title_id, launch, std::move(nacp_data));
}
- void SetStatus(ResultStatus new_status, const char* details = nullptr) {
+ void SetStatus(SystemResultStatus new_status, const char* details = nullptr) {
status = new_status;
if (details) {
status_details = details;
@@ -370,6 +387,9 @@ struct System::Impl {
return perf_stats->GetAndResetStats(core_timing.GetGlobalTimeUs());
}
+ std::mutex suspend_guard;
+ bool is_paused{};
+
Timing::CoreTiming core_timing;
Kernel::KernelCore kernel;
/// RealVfsFilesystem instance
@@ -415,7 +435,7 @@ struct System::Impl {
/// Network instance
Network::NetworkInstance network_instance;
- ResultStatus status = ResultStatus::Success;
+ SystemResultStatus status = SystemResultStatus::Success;
std::string status_details = "";
std::unique_ptr<Core::PerfStats> perf_stats;
@@ -425,27 +445,15 @@ struct System::Impl {
bool is_async_gpu{};
ExecuteProgramCallback execute_program_callback;
+ ExitCallback exit_callback;
std::array<u64, Core::Hardware::NUM_CPU_CORES> dynarmic_ticks{};
std::array<MicroProfileToken, Core::Hardware::NUM_CPU_CORES> microprofile_dynarmic{};
};
System::System() : impl{std::make_unique<Impl>(*this)} {}
-System::~System() = default;
-
-System& System::GetInstance() {
- if (!s_instance) {
- throw std::runtime_error("Using System instance before its initialization");
- }
- return *s_instance;
-}
-void System::InitializeGlobalInstance() {
- if (s_instance) {
- throw std::runtime_error("Reinitializing Global System instance.");
- }
- s_instance = std::unique_ptr<System>(new System);
-}
+System::~System() = default;
CpuManager& System::GetCpuManager() {
return impl->cpu_manager;
@@ -455,16 +463,16 @@ const CpuManager& System::GetCpuManager() const {
return impl->cpu_manager;
}
-System::ResultStatus System::Run() {
+SystemResultStatus System::Run() {
return impl->Run();
}
-System::ResultStatus System::Pause() {
+SystemResultStatus System::Pause() {
return impl->Pause();
}
-System::ResultStatus System::SingleStep() {
- return ResultStatus::Success;
+SystemResultStatus System::SingleStep() {
+ return SystemResultStatus::Success;
}
void System::InvalidateCpuInstructionCaches() {
@@ -479,8 +487,16 @@ void System::Shutdown() {
impl->Shutdown();
}
-System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
- u64 program_id, std::size_t program_index) {
+std::unique_lock<std::mutex> System::StallCPU() {
+ return impl->StallCPU();
+}
+
+void System::UnstallCPU() {
+ impl->UnstallCPU();
+}
+
+SystemResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
+ u64 program_id, std::size_t program_index) {
return impl->Load(*this, emu_window, filepath, program_id, program_index);
}
@@ -640,7 +656,7 @@ Loader::ResultStatus System::GetGameName(std::string& out) const {
return impl->GetGameName(out);
}
-void System::SetStatus(ResultStatus new_status, const char* details) {
+void System::SetStatus(SystemResultStatus new_status, const char* details) {
impl->SetStatus(new_status, details);
}
@@ -802,6 +818,18 @@ void System::ExecuteProgram(std::size_t program_index) {
}
}
+void System::RegisterExitCallback(ExitCallback&& callback) {
+ impl->exit_callback = std::move(callback);
+}
+
+void System::Exit() {
+ if (impl->exit_callback) {
+ impl->exit_callback();
+ } else {
+ LOG_CRITICAL(Core, "exit_callback must be initialized by the frontend");
+ }
+}
+
void System::ApplySettings() {
if (IsPoweredOn()) {
Renderer().RefreshBaseSettings();
diff --git a/src/core/core.h b/src/core/core.h
index 715ab88e7..1cfe1bba6 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -7,6 +7,7 @@
#include <cstddef>
#include <functional>
#include <memory>
+#include <mutex>
#include <string>
#include <vector>
@@ -104,55 +105,49 @@ struct PerfStatsResults;
FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
const std::string& path);
+/// Enumeration representing the return values of the System Initialize and Load process.
+enum class SystemResultStatus : u32 {
+ Success, ///< Succeeded
+ ErrorNotInitialized, ///< Error trying to use core prior to initialization
+ ErrorGetLoader, ///< Error finding the correct application loader
+ ErrorSystemFiles, ///< Error in finding system files
+ ErrorSharedFont, ///< Error in finding shared font
+ ErrorVideoCore, ///< Error in the video core
+ ErrorUnknown, ///< Any other error
+ ErrorLoader, ///< The base for loader errors (too many to repeat)
+};
+
class System {
public:
using CurrentBuildProcessID = std::array<u8, 0x20>;
+ explicit System();
+
+ ~System();
+
System(const System&) = delete;
System& operator=(const System&) = delete;
System(System&&) = delete;
System& operator=(System&&) = delete;
- ~System();
-
- /**
- * Gets the instance of the System singleton class.
- * @returns Reference to the instance of the System singleton class.
- */
- [[deprecated("Use of the global system instance is deprecated")]] static System& GetInstance();
-
- static void InitializeGlobalInstance();
-
- /// Enumeration representing the return values of the System Initialize and Load process.
- enum class ResultStatus : u32 {
- Success, ///< Succeeded
- ErrorNotInitialized, ///< Error trying to use core prior to initialization
- ErrorGetLoader, ///< Error finding the correct application loader
- ErrorSystemFiles, ///< Error in finding system files
- ErrorSharedFont, ///< Error in finding shared font
- ErrorVideoCore, ///< Error in the video core
- ErrorUnknown, ///< Any other error
- ErrorLoader, ///< The base for loader errors (too many to repeat)
- };
-
/**
* Run the OS and Application
* This function will start emulation and run the relevant devices
*/
- [[nodiscard]] ResultStatus Run();
+ [[nodiscard]] SystemResultStatus Run();
/**
* Pause the OS and Application
* This function will pause emulation and stop the relevant devices
*/
- [[nodiscard]] ResultStatus Pause();
+ [[nodiscard]] SystemResultStatus Pause();
/**
* Step the CPU one instruction
* @return Result status, indicating whether or not the operation succeeded.
*/
- [[nodiscard]] ResultStatus SingleStep();
+ [[nodiscard]] SystemResultStatus SingleStep();
/**
* Invalidate the CPU instruction caches
@@ -166,16 +161,20 @@ public:
/// Shutdown the emulated system.
void Shutdown();
+ std::unique_lock<std::mutex> StallCPU();
+ void UnstallCPU();
+
/**
* Load an executable application.
* @param emu_window Reference to the host-system window used for video output and keyboard
* input.
* @param filepath String path to the executable application to load on the host file system.
* @param program_index Specifies the index within the container of the program to launch.
- * @returns ResultStatus code, indicating if the operation succeeded.
+ * @returns SystemResultStatus code, indicating if the operation succeeded.
*/
- [[nodiscard]] ResultStatus Load(Frontend::EmuWindow& emu_window, const std::string& filepath,
- u64 program_id = 0, std::size_t program_index = 0);
+ [[nodiscard]] SystemResultStatus Load(Frontend::EmuWindow& emu_window,
+ const std::string& filepath, u64 program_id = 0,
+ std::size_t program_index = 0);
/**
* Indicates if the emulated system is powered on (all subsystems initialized and able to run an
@@ -301,7 +300,7 @@ public:
/// Gets the name of the current game
[[nodiscard]] Loader::ResultStatus GetGameName(std::string& out) const;
- void SetStatus(ResultStatus new_status, const char* details);
+ void SetStatus(SystemResultStatus new_status, const char* details);
[[nodiscard]] const std::string& GetStatusDetails() const;
@@ -387,16 +386,24 @@ public:
*/
void ExecuteProgram(std::size_t program_index);
+ /// Type used for the frontend to designate a callback for System to exit the application.
+ using ExitCallback = std::function<void()>;
+
+ /**
+ * Registers a callback from the frontend for System to exit the application.
+ * @param callback Callback from the frontend to exit the application.
+ */
+ void RegisterExitCallback(ExitCallback&& callback);
+
+ /// Instructs the frontend to exit the application.
+ void Exit();
+
/// Applies any changes to settings to this core instance.
void ApplySettings();
private:
- System();
-
struct Impl;
std::unique_ptr<Impl> impl;
-
- inline static std::unique_ptr<System> s_instance{};
};
} // namespace Core
diff --git a/src/core/file_sys/program_metadata.cpp b/src/core/file_sys/program_metadata.cpp
index 01ae1a567..35a53d36c 100644
--- a/src/core/file_sys/program_metadata.cpp
+++ b/src/core/file_sys/program_metadata.cpp
@@ -77,7 +77,7 @@ void ProgramMetadata::LoadManual(bool is_64_bit, ProgramAddressSpaceType address
aci_header.title_id = title_id;
aci_file_access.permissions = filesystem_permissions;
npdm_header.system_resource_size = system_resource_size;
- aci_kernel_capabilities = std ::move(capabilities);
+ aci_kernel_capabilities = std::move(capabilities);
}
bool ProgramMetadata::Is64BitProgram() const {
diff --git a/src/core/file_sys/vfs_libzip.cpp b/src/core/file_sys/vfs_libzip.cpp
deleted file mode 100644
index 00e256779..000000000
--- a/src/core/file_sys/vfs_libzip.cpp
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2019 yuzu emulator team
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <string>
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
-#endif
-#include <zip.h>
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
-
-#include "common/fs/path_util.h"
-#include "core/file_sys/vfs.h"
-#include "core/file_sys/vfs_libzip.h"
-#include "core/file_sys/vfs_vector.h"
-
-namespace FileSys {
-
-VirtualDir ExtractZIP(VirtualFile file) {
- zip_error_t error{};
-
- const auto data = file->ReadAllBytes();
- std::unique_ptr<zip_source_t, decltype(&zip_source_close)> src{
- zip_source_buffer_create(data.data(), data.size(), 0, &error), zip_source_close};
- if (src == nullptr)
- return nullptr;
-
- std::unique_ptr<zip_t, decltype(&zip_close)> zip{zip_open_from_source(src.get(), 0, &error),
- zip_close};
- if (zip == nullptr)
- return nullptr;
-
- std::shared_ptr<VectorVfsDirectory> out = std::make_shared<VectorVfsDirectory>();
-
- const auto num_entries = static_cast<std::size_t>(zip_get_num_entries(zip.get(), 0));
-
- zip_stat_t stat{};
- zip_stat_init(&stat);
-
- for (std::size_t i = 0; i < num_entries; ++i) {
- const auto stat_res = zip_stat_index(zip.get(), i, 0, &stat);
- if (stat_res == -1)
- return nullptr;
-
- const std::string name(stat.name);
- if (name.empty())
- continue;
-
- if (name.back() != '/') {
- std::unique_ptr<zip_file_t, decltype(&zip_fclose)> file2{
- zip_fopen_index(zip.get(), i, 0), zip_fclose};
-
- std::vector<u8> buf(stat.size);
- if (zip_fread(file2.get(), buf.data(), buf.size()) != s64(buf.size()))
- return nullptr;
-
- const auto parts = Common::FS::SplitPathComponents(stat.name);
- const auto new_file = std::make_shared<VectorVfsFile>(buf, parts.back());
-
- std::shared_ptr<VectorVfsDirectory> dtrv = out;
- for (std::size_t j = 0; j < parts.size() - 1; ++j) {
- if (dtrv == nullptr)
- return nullptr;
- const auto subdir = dtrv->GetSubdirectory(parts[j]);
- if (subdir == nullptr) {
- const auto temp = std::make_shared<VectorVfsDirectory>(
- std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, parts[j]);
- dtrv->AddDirectory(temp);
- dtrv = temp;
- } else {
- dtrv = std::dynamic_pointer_cast<VectorVfsDirectory>(subdir);
- }
- }
-
- if (dtrv == nullptr)
- return nullptr;
- dtrv->AddFile(new_file);
- }
- }
-
- return out;
-}
-
-} // namespace FileSys
diff --git a/src/core/file_sys/vfs_libzip.h b/src/core/file_sys/vfs_libzip.h
deleted file mode 100644
index f68af576a..000000000
--- a/src/core/file_sys/vfs_libzip.h
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2019 yuzu emulator team
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include "core/file_sys/vfs_types.h"
-
-namespace FileSys {
-
-VirtualDir ExtractZIP(VirtualFile zip);
-
-} // namespace FileSys
diff --git a/src/core/frontend/applets/profile_select.cpp b/src/core/frontend/applets/profile_select.cpp
index 4c58c310f..3e4f90be2 100644
--- a/src/core/frontend/applets/profile_select.cpp
+++ b/src/core/frontend/applets/profile_select.cpp
@@ -13,7 +13,8 @@ ProfileSelectApplet::~ProfileSelectApplet() = default;
void DefaultProfileSelectApplet::SelectProfile(
std::function<void(std::optional<Common::UUID>)> callback) const {
Service::Account::ProfileManager manager;
- callback(manager.GetUser(Settings::values.current_user.GetValue()).value_or(Common::UUID{}));
+ callback(manager.GetUser(Settings::values.current_user.GetValue())
+ .value_or(Common::UUID{Common::INVALID_UUID}));
LOG_INFO(Service_ACC, "called, selecting current user instead of prompting...");
}
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index ceff2532d..cf204f570 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -4,17 +4,14 @@
#pragma once
-#include <array>
#include <cstring>
#include <memory>
-#include <tuple>
#include <type_traits>
#include <utility>
#include "common/assert.h"
#include "common/common_types.h"
#include "core/hle/ipc.h"
#include "core/hle/kernel/hle_ipc.h"
-#include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/k_session.h"
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index ca68fc325..cee96dd9b 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -15,6 +15,7 @@
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_readable_event.h"
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index a61870f8b..55e6fb9f7 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -17,7 +17,6 @@
#include "common/concepts.h"
#include "common/swap.h"
#include "core/hle/ipc.h"
-#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/svc_common.h"
union ResultCode;
@@ -38,6 +37,7 @@ namespace Kernel {
class Domain;
class HLERequestContext;
+class KAutoObject;
class KernelCore;
class KHandleTable;
class KProcess;
diff --git a/src/core/hle/kernel/k_auto_object_container.cpp b/src/core/hle/kernel/k_auto_object_container.cpp
index 010006bb7..d5f80d5b2 100644
--- a/src/core/hle/kernel/k_auto_object_container.cpp
+++ b/src/core/hle/kernel/k_auto_object_container.cpp
@@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <algorithm>
+
#include "core/hle/kernel/k_auto_object_container.h"
namespace Kernel {
diff --git a/src/core/hle/kernel/k_handle_table.cpp b/src/core/hle/kernel/k_handle_table.cpp
index 6a420d5b0..44d13169f 100644
--- a/src/core/hle/kernel/k_handle_table.cpp
+++ b/src/core/hle/kernel/k_handle_table.cpp
@@ -7,7 +7,7 @@
namespace Kernel {
KHandleTable::KHandleTable(KernelCore& kernel_) : kernel{kernel_} {}
-KHandleTable ::~KHandleTable() = default;
+KHandleTable::~KHandleTable() = default;
ResultCode KHandleTable::Finalize() {
// Get the table and clear our record of it.
diff --git a/src/core/hle/kernel/k_priority_queue.h b/src/core/hle/kernel/k_priority_queue.h
index 4aa669d95..f4d71ad7e 100644
--- a/src/core/hle/kernel/k_priority_queue.h
+++ b/src/core/hle/kernel/k_priority_queue.h
@@ -22,12 +22,10 @@ class KThread;
template <typename T>
concept KPriorityQueueAffinityMask = !std::is_reference_v<T> && requires(T & t) {
- { t.GetAffinityMask() }
- ->Common::ConvertibleTo<u64>;
+ { t.GetAffinityMask() } -> Common::ConvertibleTo<u64>;
{t.SetAffinityMask(0)};
- { t.GetAffinity(0) }
- ->std::same_as<bool>;
+ { t.GetAffinity(0) } -> std::same_as<bool>;
{t.SetAffinity(0, false)};
{t.SetAll()};
};
@@ -38,25 +36,20 @@ concept KPriorityQueueMember = !std::is_reference_v<T> && requires(T & t) {
{(typename T::QueueEntry()).Initialize()};
{(typename T::QueueEntry()).SetPrev(std::addressof(t))};
{(typename T::QueueEntry()).SetNext(std::addressof(t))};
- { (typename T::QueueEntry()).GetNext() }
- ->std::same_as<T*>;
- { (typename T::QueueEntry()).GetPrev() }
- ->std::same_as<T*>;
- { t.GetPriorityQueueEntry(0) }
- ->std::same_as<typename T::QueueEntry&>;
+ { (typename T::QueueEntry()).GetNext() } -> std::same_as<T*>;
+ { (typename T::QueueEntry()).GetPrev() } -> std::same_as<T*>;
+ { t.GetPriorityQueueEntry(0) } -> std::same_as<typename T::QueueEntry&>;
{t.GetAffinityMask()};
- { std::remove_cvref_t<decltype(t.GetAffinityMask())>() }
- ->KPriorityQueueAffinityMask;
+ { std::remove_cvref_t<decltype(t.GetAffinityMask())>() } -> KPriorityQueueAffinityMask;
- { t.GetActiveCore() }
- ->Common::ConvertibleTo<s32>;
- { t.GetPriority() }
- ->Common::ConvertibleTo<s32>;
+ { t.GetActiveCore() } -> Common::ConvertibleTo<s32>;
+ { t.GetPriority() } -> Common::ConvertibleTo<s32>;
};
template <typename Member, size_t NumCores_, int LowestPriority, int HighestPriority>
-requires KPriorityQueueMember<Member> class KPriorityQueue {
+requires KPriorityQueueMember<Member>
+class KPriorityQueue {
public:
using AffinityMaskType = std::remove_cv_t<
std::remove_reference_t<decltype(std::declval<Member>().GetAffinityMask())>>;
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 8ead1a769..211157ccc 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -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;
+ }
+
+ 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.
+ // 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();
}
diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h
index a03c074fb..1a53e2be7 100644
--- a/src/core/hle/kernel/k_process.h
+++ b/src/core/hle/kernel/k_process.h
@@ -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{};
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h
index 12cfae919..c8ccc1ae4 100644
--- a/src/core/hle/kernel/k_scheduler.h
+++ b/src/core/hle/kernel/k_scheduler.h
@@ -197,7 +197,7 @@ private:
class [[nodiscard]] KScopedSchedulerLock : KScopedLock<GlobalSchedulerContext::LockType> {
public:
- explicit KScopedSchedulerLock(KernelCore & kernel);
+ explicit KScopedSchedulerLock(KernelCore& kernel);
~KScopedSchedulerLock();
};
diff --git a/src/core/hle/kernel/k_scoped_lock.h b/src/core/hle/kernel/k_scoped_lock.h
index 72c3b0252..4fb180fc6 100644
--- a/src/core/hle/kernel/k_scoped_lock.h
+++ b/src/core/hle/kernel/k_scoped_lock.h
@@ -13,19 +13,18 @@ namespace Kernel {
template <typename T>
concept KLockable = !std::is_reference_v<T> && requires(T & t) {
- { t.Lock() }
- ->std::same_as<void>;
- { t.Unlock() }
- ->std::same_as<void>;
+ { t.Lock() } -> std::same_as<void>;
+ { t.Unlock() } -> std::same_as<void>;
};
template <typename T>
-requires KLockable<T> class [[nodiscard]] KScopedLock {
+requires KLockable<T>
+class [[nodiscard]] KScopedLock {
public:
- explicit KScopedLock(T * l) : lock_ptr(l) {
+ explicit KScopedLock(T* l) : lock_ptr(l) {
this->lock_ptr->Lock();
}
- explicit KScopedLock(T & l) : KScopedLock(std::addressof(l)) {}
+ explicit KScopedLock(T& l) : KScopedLock(std::addressof(l)) {}
~KScopedLock() {
this->lock_ptr->Unlock();
@@ -34,7 +33,7 @@ public:
KScopedLock(const KScopedLock&) = delete;
KScopedLock& operator=(const KScopedLock&) = delete;
- KScopedLock(KScopedLock &&) = delete;
+ KScopedLock(KScopedLock&&) = delete;
KScopedLock& operator=(KScopedLock&&) = delete;
private:
diff --git a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h
index a86af56dd..f6c75f2d9 100644
--- a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h
+++ b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h
@@ -17,7 +17,7 @@ namespace Kernel {
class [[nodiscard]] KScopedSchedulerLockAndSleep {
public:
- explicit KScopedSchedulerLockAndSleep(KernelCore & kernel_, KThread * t, s64 timeout)
+ explicit KScopedSchedulerLockAndSleep(KernelCore& kernel_, KThread* t, s64 timeout)
: kernel(kernel_), thread(t), timeout_tick(timeout) {
// Lock the scheduler.
kernel.GlobalSchedulerContext().scheduler_lock.Lock();
diff --git a/src/core/hle/kernel/k_shared_memory_info.h b/src/core/hle/kernel/k_shared_memory_info.h
new file mode 100644
index 000000000..bf97a0184
--- /dev/null
+++ b/src/core/hle/kernel/k_shared_memory_info.h
@@ -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
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 901d43da9..b6658b437 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -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;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 62fb06c45..f98f24a60 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -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{};
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 6d9ec0a8a..689b36056 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -929,8 +929,7 @@ void Module::Interface::TrySelectUserWithoutInteraction(Kernel::HLERequestContex
}
const auto user_list = profile_manager->GetAllUsers();
- if (std::all_of(user_list.begin(), user_list.end(),
- [](const auto& user) { return user.uuid == Common::INVALID_UUID; })) {
+ if (std::ranges::all_of(user_list, [](const auto& user) { return user.IsInvalid(); })) {
rb.Push(ResultUnknown); // TODO(ogniK): Find the correct error code
rb.PushRaw<u128>(Common::INVALID_UUID);
return;
diff --git a/src/core/hle/service/acc/async_context.cpp b/src/core/hle/service/acc/async_context.cpp
index 459323132..a49dfdec7 100644
--- a/src/core/hle/service/acc/async_context.cpp
+++ b/src/core/hle/service/acc/async_context.cpp
@@ -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
diff --git a/src/core/hle/service/acc/async_context.h b/src/core/hle/service/acc/async_context.h
index c694b4946..cc3a0a9fe 100644
--- a/src/core/hle/service/acc/async_context.h
+++ b/src/core/hle/service/acc/async_context.h
@@ -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
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp
index 24a1c9157..568303ced 100644
--- a/src/core/hle/service/acc/profile_manager.cpp
+++ b/src/core/hle/service/acc/profile_manager.cpp
@@ -208,9 +208,10 @@ bool ProfileManager::UserExists(UUID uuid) const {
}
bool ProfileManager::UserExistsIndex(std::size_t index) const {
- if (index >= MAX_USERS)
+ if (index >= MAX_USERS) {
return false;
- return profiles[index].user_uuid.uuid != Common::INVALID_UUID;
+ }
+ return profiles[index].user_uuid.IsValid();
}
/// Opens a specific user
@@ -304,7 +305,7 @@ bool ProfileManager::RemoveUser(UUID uuid) {
bool ProfileManager::SetProfileBase(UUID uuid, const ProfileBase& profile_new) {
const auto index = GetUserIndex(uuid);
- if (!index || profile_new.user_uuid == UUID(Common::INVALID_UUID)) {
+ if (!index || profile_new.user_uuid.IsInvalid()) {
return false;
}
@@ -346,7 +347,7 @@ void ProfileManager::ParseUserSaveFile() {
}
for (const auto& user : data.users) {
- if (user.uuid == UUID(Common::INVALID_UUID)) {
+ if (user.uuid.IsInvalid()) {
continue;
}
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index c3ac73131..eccdcc20d 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -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"},
@@ -275,12 +274,14 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
{18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
{19, &ISelfController::SetAlbumImageOrientation, "SetAlbumImageOrientation"},
{20, nullptr, "SetDesirableKeyboardLayout"},
+ {21, nullptr, "GetScreenShotProgramId"},
{40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
{41, nullptr, "IsSystemBufferSharingEnabled"},
{42, nullptr, "GetSystemSharedLayerHandle"},
{43, nullptr, "GetSystemSharedBufferHandle"},
{44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"},
{45, nullptr, "SetManagedDisplayLayerSeparationMode"},
+ {46, nullptr, "SetRecordingLayerCompositionEnabled"},
{50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
{51, nullptr, "ApproveToDisplay"},
{60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
@@ -302,15 +303,14 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
{100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"},
{110, nullptr, "SetApplicationAlbumUserData"},
{120, nullptr, "SaveCurrentScreenshot"},
+ {130, nullptr, "SetRecordVolumeMuted"},
{1000, nullptr, "GetDebugStorageChannel"},
};
// clang-format on
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
@@ -318,21 +318,23 @@ 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");
- system.Shutdown();
-
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
+
+ system.Exit();
}
void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
@@ -380,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) {
@@ -563,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) {
@@ -581,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;
}
@@ -634,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_,
@@ -683,6 +684,7 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system_,
{91, nullptr, "GetCurrentPerformanceConfiguration"},
{100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"},
{110, nullptr, "OpenMyGpuErrorHandler"},
+ {120, nullptr, "GetAppletLaunchedHistory"},
{200, nullptr, "GetOperationModeSystemInfo"},
{300, nullptr, "GetSettingsPlatformRegion"},
{400, nullptr, "ActivateMigrationService"},
@@ -1268,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"},
@@ -1339,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");
@@ -1747,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) {
@@ -1755,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(
@@ -1771,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) {
@@ -1779,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);
@@ -1797,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"},
@@ -1819,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");
@@ -1837,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_)
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h
index c13aa5787..202d20757 100644
--- a/src/core/hle/service/am/am.h
+++ b/src/core/hle/service/am/am.h
@@ -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> {
diff --git a/src/core/hle/service/am/applet_ae.h b/src/core/hle/service/am/applet_ae.h
index adb207349..f89f65649 100644
--- a/src/core/hle/service/am/applet_ae.h
+++ b/src/core/hle/service/am/applet_ae.h
@@ -5,7 +5,7 @@
#pragma once
#include <memory>
-#include "core/hle/kernel/hle_ipc.h"
+
#include "core/hle/service/service.h"
namespace Service {
diff --git a/src/core/hle/service/am/applet_oe.h b/src/core/hle/service/am/applet_oe.h
index 6c1aa255a..64b874ead 100644
--- a/src/core/hle/service/am/applet_oe.h
+++ b/src/core/hle/service/am/applet_oe.h
@@ -5,7 +5,7 @@
#pragma once
#include <memory>
-#include "core/hle/kernel/hle_ipc.h"
+
#include "core/hle/service/service.h"
namespace Service {
diff --git a/src/core/hle/service/am/applets/applet_profile_select.cpp b/src/core/hle/service/am/applets/applet_profile_select.cpp
index bdc21778e..a6e891944 100644
--- a/src/core/hle/service/am/applets/applet_profile_select.cpp
+++ b/src/core/hle/service/am/applets/applet_profile_select.cpp
@@ -60,7 +60,7 @@ void ProfileSelect::Execute() {
void ProfileSelect::SelectionComplete(std::optional<Common::UUID> uuid) {
UserSelectionOutput output{};
- if (uuid.has_value() && uuid->uuid != Common::INVALID_UUID) {
+ if (uuid.has_value() && uuid->IsValid()) {
output.result = 0;
output.uuid_selected = uuid->uuid;
} else {
diff --git a/src/core/hle/service/am/applets/applet_web_browser.cpp b/src/core/hle/service/am/applets/applet_web_browser.cpp
index 35f194961..927eeefff 100644
--- a/src/core/hle/service/am/applets/applet_web_browser.cpp
+++ b/src/core/hle/service/am/applets/applet_web_browser.cpp
@@ -24,6 +24,7 @@
#include "core/hle/service/am/applets/applet_web_browser.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/ns/pl_u.h"
+#include "core/loader/loader.h"
namespace Service::AM::Applets {
@@ -122,6 +123,15 @@ FileSys::VirtualFile GetOfflineRomFS(Core::System& system, u64 title_id,
const auto nca = system.GetContentProvider().GetEntry(title_id, nca_type);
if (nca == nullptr) {
+ if (nca_type == FileSys::ContentRecordType::HtmlDocument) {
+ LOG_WARNING(Service_AM, "Falling back to AppLoader to get the RomFS.");
+ FileSys::VirtualFile romfs;
+ system.GetAppLoader().ReadManualRomFS(romfs);
+ if (romfs != nullptr) {
+ return romfs;
+ }
+ }
+
LOG_ERROR(Service_AM,
"NCA of type={} with title_id={:016X} is not found in the ContentProvider!",
nca_type, title_id);
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 2b7685d42..7320b1c0f 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -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_)
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h
index 5c0b4b459..15eeb4ee1 100644
--- a/src/core/hle/service/am/applets/applets.h
+++ b/src/core/hle/service/am/applets/applets.h
@@ -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 {
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index dd945e058..4c54066c6 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -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) {
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h
index bb6ffb8eb..31d645be8 100644
--- a/src/core/hle/service/aoc/aoc_u.h
+++ b/src/core/hle/service/aoc/aoc_u.h
@@ -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.
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp
index 8c4c49b85..2e46e7161 100644
--- a/src/core/hle/service/audio/audctl.cpp
+++ b/src/core/hle/service/audio/audctl.cpp
@@ -41,6 +41,14 @@ AudCtl::AudCtl(Core::System& system_) : ServiceFramework{system_, "audctl"} {
{27, nullptr, "SetVolumeMappingTableForDev"},
{28, nullptr, "GetAudioOutputChannelCountForPlayReport"},
{29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
+ {30, nullptr, "Unknown30"},
+ {31, nullptr, "Unknown31"},
+ {32, nullptr, "Unknown32"},
+ {33, nullptr, "Unknown33"},
+ {34, nullptr, "Unknown34"},
+ {10000, nullptr, "Unknown10000"},
+ {10001, nullptr, "Unknown10001"},
+ {10002, nullptr, "Unknown10002"},
};
// clang-format on
diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp
index 3e7fd6024..34cc659ed 100644
--- a/src/core/hle/service/audio/audin_u.cpp
+++ b/src/core/hle/service/audio/audin_u.cpp
@@ -3,38 +3,65 @@
// Refer to the license.txt file included.
#include "common/logging/log.h"
+#include "core/core.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
+#include "core/hle/kernel/k_event.h"
#include "core/hle/service/audio/audin_u.h"
namespace Service::Audio {
-class IAudioIn final : public ServiceFramework<IAudioIn> {
-public:
- explicit IAudioIn(Core::System& system_) : ServiceFramework{system_, "IAudioIn"} {
- // clang-format off
- static const FunctionInfo functions[] = {
- {0, nullptr, "GetAudioInState"},
- {1, nullptr, "Start"},
- {2, nullptr, "Stop"},
- {3, nullptr, "AppendAudioInBuffer"},
- {4, nullptr, "RegisterBufferEvent"},
- {5, nullptr, "GetReleasedAudioInBuffer"},
- {6, nullptr, "ContainsAudioInBuffer"},
- {7, nullptr, "AppendUacInBuffer"},
- {8, nullptr, "AppendAudioInBufferAuto"},
- {9, nullptr, "GetReleasedAudioInBuffersAuto"},
- {10, nullptr, "AppendUacInBufferAuto"},
- {11, nullptr, "GetAudioInBufferCount"},
- {12, nullptr, "SetDeviceGain"},
- {13, nullptr, "GetDeviceGain"},
- {14, nullptr, "FlushAudioInBuffers"},
- };
- // clang-format on
-
- RegisterHandlers(functions);
- }
-};
+IAudioIn::IAudioIn(Core::System& system_)
+ : ServiceFramework{system_, "IAudioIn"}, service_context{system_, "IAudioIn"} {
+ // clang-format off
+ static const FunctionInfo functions[] = {
+ {0, nullptr, "GetAudioInState"},
+ {1, &IAudioIn::Start, "Start"},
+ {2, nullptr, "Stop"},
+ {3, nullptr, "AppendAudioInBuffer"},
+ {4, &IAudioIn::RegisterBufferEvent, "RegisterBufferEvent"},
+ {5, nullptr, "GetReleasedAudioInBuffer"},
+ {6, nullptr, "ContainsAudioInBuffer"},
+ {7, nullptr, "AppendUacInBuffer"},
+ {8, &IAudioIn::AppendAudioInBufferAuto, "AppendAudioInBufferAuto"},
+ {9, nullptr, "GetReleasedAudioInBuffersAuto"},
+ {10, nullptr, "AppendUacInBufferAuto"},
+ {11, nullptr, "GetAudioInBufferCount"},
+ {12, nullptr, "SetDeviceGain"},
+ {13, nullptr, "GetDeviceGain"},
+ {14, nullptr, "FlushAudioInBuffers"},
+ };
+ // clang-format on
+
+ RegisterHandlers(functions);
+
+ buffer_event = service_context.CreateEvent("IAudioIn:BufferEvent");
+}
+
+IAudioIn::~IAudioIn() {
+ service_context.CloseEvent(buffer_event);
+}
+
+void IAudioIn::Start(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_Audio, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
+
+void IAudioIn::RegisterBufferEvent(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_Audio, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2, 1};
+ rb.Push(ResultSuccess);
+ rb.PushCopyObjects(buffer_event->GetReadableEvent());
+}
+
+void IAudioIn::AppendAudioInBufferAuto(Kernel::HLERequestContext& ctx) {
+ LOG_WARNING(Service_Audio, "(STUBBED) called");
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ResultSuccess);
+}
AudInU::AudInU(Core::System& system_) : ServiceFramework{system_, "audin:u"} {
// clang-format off
diff --git a/src/core/hle/service/audio/audin_u.h b/src/core/hle/service/audio/audin_u.h
index 0d75ae5ac..bf3418613 100644
--- a/src/core/hle/service/audio/audin_u.h
+++ b/src/core/hle/service/audio/audin_u.h
@@ -4,6 +4,7 @@
#pragma once
+#include "core/hle/service/kernel_helpers.h"
#include "core/hle/service/service.h"
namespace Core {
@@ -16,6 +17,21 @@ class HLERequestContext;
namespace Service::Audio {
+class IAudioIn final : public ServiceFramework<IAudioIn> {
+public:
+ explicit IAudioIn(Core::System& system_);
+ ~IAudioIn() override;
+
+private:
+ void Start(Kernel::HLERequestContext& ctx);
+ void RegisterBufferEvent(Kernel::HLERequestContext& ctx);
+ void AppendAudioInBufferAuto(Kernel::HLERequestContext& ctx);
+
+ KernelHelpers::ServiceContext service_context;
+
+ Kernel::KEvent* buffer_event;
+};
+
class AudInU final : public ServiceFramework<AudInU> {
public:
explicit AudInU(Core::System& system_);
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 92d4510b1..81adbfe09 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -13,13 +13,11 @@
#include "common/swap.h"
#include "core/core.h"
#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 +39,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 +66,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 +128,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 +229,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"} {
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index b769fe959..cdb2a9521 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -15,10 +15,7 @@
#include "common/string_util.h"
#include "core/core.h"
#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 +27,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 +46,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 +130,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 +164,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[] = {
@@ -187,7 +189,8 @@ public:
{10, &IAudioDevice::GetActiveAudioDeviceName, "GetActiveAudioDeviceNameAuto"},
{11, &IAudioDevice::QueryAudioDeviceInputEvent, "QueryAudioDeviceInputEvent"},
{12, &IAudioDevice::QueryAudioDeviceOutputEvent, "QueryAudioDeviceOutputEvent"},
- {13, nullptr, "GetAudioSystemMasterVolumeSetting"},
+ {13, nullptr, "GetActiveAudioOutputDeviceName"},
+ {14, nullptr, "ListAudioOutputDeviceName"},
};
RegisterHandlers(functions);
}
@@ -278,11 +281,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) {
@@ -299,7 +302,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) {
@@ -307,16 +310,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"},
@@ -329,11 +331,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");
diff --git a/src/core/hle/service/audio/audren_u.h b/src/core/hle/service/audio/audren_u.h
index 0ee6f9542..5922b4b27 100644
--- a/src/core/hle/service/audio/audren_u.h
+++ b/src/core/hle/service/audio/audren_u.h
@@ -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.
diff --git a/src/core/hle/service/audio/hwopus.cpp b/src/core/hle/service/audio/hwopus.cpp
index 33a6dbbb6..7da1f2969 100644
--- a/src/core/hle/service/audio/hwopus.cpp
+++ b/src/core/hle/service/audio/hwopus.cpp
@@ -13,7 +13,6 @@
#include "common/assert.h"
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/audio/hwopus.h"
namespace Service::Audio {
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index a78544c88..4c7d3bb6e 100644
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -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();
}
}
diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h
index e79a9c2ad..749e046c7 100644
--- a/src/core/hle/service/bcat/backend/backend.h
+++ b/src/core/hle/service/bcat/backend/backend.h
@@ -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;
};
diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp
deleted file mode 100644
index 7ca7f2aac..000000000
--- a/src/core/hle/service/bcat/backend/boxcat.cpp
+++ /dev/null
@@ -1,548 +0,0 @@
-// Copyright 2019 yuzu emulator team
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#include <fmt/ostream.h>
-
-#ifdef __GNUC__
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wshadow"
-#ifndef __clang__
-#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
-#endif
-#endif
-#include <httplib.h>
-#include <mbedtls/sha256.h>
-#include <nlohmann/json.hpp>
-#ifdef __GNUC__
-#pragma GCC diagnostic pop
-#endif
-
-#include "common/fs/file.h"
-#include "common/fs/fs.h"
-#include "common/fs/path_util.h"
-#include "common/hex_util.h"
-#include "common/logging/log.h"
-#include "common/settings.h"
-#include "core/core.h"
-#include "core/file_sys/vfs.h"
-#include "core/file_sys/vfs_libzip.h"
-#include "core/file_sys/vfs_vector.h"
-#include "core/frontend/applets/error.h"
-#include "core/hle/service/am/applets/applets.h"
-#include "core/hle/service/bcat/backend/boxcat.h"
-
-namespace Service::BCAT {
-namespace {
-
-// Prevents conflicts with windows macro called CreateFile
-FileSys::VirtualFile VfsCreateFileWrap(FileSys::VirtualDir dir, std::string_view name) {
- return dir->CreateFile(name);
-}
-
-// Prevents conflicts with windows macro called DeleteFile
-bool VfsDeleteFileWrap(FileSys::VirtualDir dir, std::string_view name) {
- return dir->DeleteFile(name);
-}
-
-constexpr ResultCode ERROR_GENERAL_BCAT_FAILURE{ErrorModule::BCAT, 1};
-
-constexpr char BOXCAT_HOSTNAME[] = "api.yuzu-emu.org";
-
-// Formatted using fmt with arg[0] = hex title id
-constexpr char BOXCAT_PATHNAME_DATA[] = "/game-assets/{:016X}/boxcat";
-constexpr char BOXCAT_PATHNAME_LAUNCHPARAM[] = "/game-assets/{:016X}/launchparam";
-
-constexpr char BOXCAT_PATHNAME_EVENTS[] = "/game-assets/boxcat/events";
-
-constexpr char BOXCAT_API_VERSION[] = "1";
-constexpr char BOXCAT_CLIENT_TYPE[] = "yuzu";
-
-// HTTP status codes for Boxcat
-enum class ResponseStatus {
- Ok = 200, ///< Operation completed successfully.
- BadClientVersion = 301, ///< The Boxcat-Client-Version doesn't match the server.
- NoUpdate = 304, ///< The digest provided would match the new data, no need to update.
- NoMatchTitleId = 404, ///< The title ID provided doesn't have a boxcat implementation.
- NoMatchBuildId = 406, ///< The build ID provided is blacklisted (potentially because of format
- ///< issues or whatnot) and has no data.
-};
-
-enum class DownloadResult {
- Success = 0,
- NoResponse,
- GeneralWebError,
- NoMatchTitleId,
- NoMatchBuildId,
- InvalidContentType,
- GeneralFSError,
- BadClientVersion,
-};
-
-constexpr std::array<const char*, 8> DOWNLOAD_RESULT_LOG_MESSAGES{
- "Success",
- "There was no response from the server.",
- "There was a general web error code returned from the server.",
- "The title ID of the current game doesn't have a boxcat implementation. If you believe an "
- "implementation should be added, contact yuzu support.",
- "The build ID of the current version of the game is marked as incompatible with the current "
- "BCAT distribution. Try upgrading or downgrading your game version or contacting yuzu support.",
- "The content type of the web response was invalid.",
- "There was a general filesystem error while saving the zip file.",
- "The server is either too new or too old to serve the request. Try using the latest version of "
- "an official release of yuzu.",
-};
-
-std::ostream& operator<<(std::ostream& os, DownloadResult result) {
- return os << DOWNLOAD_RESULT_LOG_MESSAGES.at(static_cast<std::size_t>(result));
-}
-
-constexpr u32 PORT = 443;
-constexpr u32 TIMEOUT_SECONDS = 30;
-[[maybe_unused]] constexpr u64 VFS_COPY_BLOCK_SIZE = 1ULL << 24; // 4MB
-
-std::filesystem::path GetBINFilePath(u64 title_id) {
- return Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "bcat" /
- fmt::format("{:016X}/launchparam.bin", title_id);
-}
-
-std::filesystem::path GetZIPFilePath(u64 title_id) {
- return Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "bcat" /
- fmt::format("{:016X}/data.zip", title_id);
-}
-
-// If the error is something the user should know about (build ID mismatch, bad client version),
-// display an error.
-void HandleDownloadDisplayResult(const AM::Applets::AppletManager& applet_manager,
- DownloadResult res) {
- if (res == DownloadResult::Success || res == DownloadResult::NoResponse ||
- res == DownloadResult::GeneralWebError || res == DownloadResult::GeneralFSError ||
- res == DownloadResult::NoMatchTitleId || res == DownloadResult::InvalidContentType) {
- return;
- }
-
- const auto& frontend{applet_manager.GetAppletFrontendSet()};
- frontend.error->ShowCustomErrorText(
- ResultUnknown, "There was an error while attempting to use Boxcat.",
- DOWNLOAD_RESULT_LOG_MESSAGES[static_cast<std::size_t>(res)], [] {});
-}
-
-bool VfsRawCopyProgress(FileSys::VirtualFile src, FileSys::VirtualFile dest,
- std::string_view dir_name, ProgressServiceBackend& progress,
- std::size_t block_size = 0x1000) {
- if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable())
- return false;
- if (!dest->Resize(src->GetSize()))
- return false;
-
- progress.StartDownloadingFile(dir_name, src->GetName(), src->GetSize());
-
- std::vector<u8> temp(std::min(block_size, src->GetSize()));
- for (std::size_t i = 0; i < src->GetSize(); i += block_size) {
- const auto read = std::min(block_size, src->GetSize() - i);
-
- if (src->Read(temp.data(), read, i) != read) {
- return false;
- }
-
- if (dest->Write(temp.data(), read, i) != read) {
- return false;
- }
-
- progress.UpdateFileProgress(i);
- }
-
- progress.FinishDownloadingFile();
-
- return true;
-}
-
-bool VfsRawCopyDProgressSingle(FileSys::VirtualDir src, FileSys::VirtualDir dest,
- ProgressServiceBackend& progress, std::size_t block_size = 0x1000) {
- if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable())
- return false;
-
- for (const auto& file : src->GetFiles()) {
- const auto out_file = VfsCreateFileWrap(dest, file->GetName());
- if (!VfsRawCopyProgress(file, out_file, src->GetName(), progress, block_size)) {
- return false;
- }
- }
- progress.CommitDirectory(src->GetName());
-
- return true;
-}
-
-bool VfsRawCopyDProgress(FileSys::VirtualDir src, FileSys::VirtualDir dest,
- ProgressServiceBackend& progress, std::size_t block_size = 0x1000) {
- if (src == nullptr || dest == nullptr || !src->IsReadable() || !dest->IsWritable())
- return false;
-
- for (const auto& dir : src->GetSubdirectories()) {
- const auto out = dest->CreateSubdirectory(dir->GetName());
- if (!VfsRawCopyDProgressSingle(dir, out, progress, block_size)) {
- return false;
- }
- }
-
- return true;
-}
-
-} // Anonymous namespace
-
-class Boxcat::Client {
-public:
- Client(std::filesystem::path path_, u64 title_id_, u64 build_id_)
- : path(std::move(path_)), title_id(title_id_), build_id(build_id_) {}
-
- DownloadResult DownloadDataZip() {
- return DownloadInternal(fmt::format(BOXCAT_PATHNAME_DATA, title_id), TIMEOUT_SECONDS,
- "application/zip");
- }
-
- DownloadResult DownloadLaunchParam() {
- return DownloadInternal(fmt::format(BOXCAT_PATHNAME_LAUNCHPARAM, title_id),
- TIMEOUT_SECONDS / 3, "application/octet-stream");
- }
-
-private:
- DownloadResult DownloadInternal(const std::string& resolved_path, u32 timeout_seconds,
- const std::string& content_type_name) {
- if (client == nullptr) {
- client = std::make_unique<httplib::SSLClient>(BOXCAT_HOSTNAME, PORT);
- client->set_connection_timeout(timeout_seconds);
- client->set_read_timeout(timeout_seconds);
- client->set_write_timeout(timeout_seconds);
- }
-
- httplib::Headers headers{
- {std::string("Game-Assets-API-Version"), std::string(BOXCAT_API_VERSION)},
- {std::string("Boxcat-Client-Type"), std::string(BOXCAT_CLIENT_TYPE)},
- {std::string("Game-Build-Id"), fmt::format("{:016X}", build_id)},
- };
-
- if (Common::FS::Exists(path)) {
- Common::FS::IOFile file{path, Common::FS::FileAccessMode::Read,
- Common::FS::FileType::BinaryFile};
- if (file.IsOpen()) {
- std::vector<u8> bytes(file.GetSize());
- void(file.Read(bytes));
- const auto digest = DigestFile(bytes);
- headers.insert({std::string("If-None-Match"), Common::HexToString(digest, false)});
- }
- }
-
- const auto response = client->Get(resolved_path.c_str(), headers);
- if (response == nullptr)
- return DownloadResult::NoResponse;
-
- if (response->status == static_cast<int>(ResponseStatus::NoUpdate))
- return DownloadResult::Success;
- if (response->status == static_cast<int>(ResponseStatus::BadClientVersion))
- return DownloadResult::BadClientVersion;
- if (response->status == static_cast<int>(ResponseStatus::NoMatchTitleId))
- return DownloadResult::NoMatchTitleId;
- if (response->status == static_cast<int>(ResponseStatus::NoMatchBuildId))
- return DownloadResult::NoMatchBuildId;
- if (response->status != static_cast<int>(ResponseStatus::Ok))
- return DownloadResult::GeneralWebError;
-
- const auto content_type = response->headers.find("content-type");
- if (content_type == response->headers.end() ||
- content_type->second.find(content_type_name) == std::string::npos) {
- return DownloadResult::InvalidContentType;
- }
-
- if (!Common::FS::CreateDirs(path)) {
- return DownloadResult::GeneralFSError;
- }
-
- Common::FS::IOFile file{path, Common::FS::FileAccessMode::Append,
- Common::FS::FileType::BinaryFile};
- if (!file.IsOpen()) {
- return DownloadResult::GeneralFSError;
- }
-
- if (!file.SetSize(response->body.size())) {
- return DownloadResult::GeneralFSError;
- }
-
- if (file.Write(response->body) != response->body.size()) {
- return DownloadResult::GeneralFSError;
- }
-
- return DownloadResult::Success;
- }
-
- using Digest = std::array<u8, 0x20>;
- static Digest DigestFile(std::vector<u8> bytes) {
- Digest out{};
- mbedtls_sha256_ret(bytes.data(), bytes.size(), out.data(), 0);
- return out;
- }
-
- std::unique_ptr<httplib::SSLClient> client;
- std::filesystem::path path;
- u64 title_id;
- u64 build_id;
-};
-
-Boxcat::Boxcat(AM::Applets::AppletManager& applet_manager_, DirectoryGetter getter)
- : Backend(std::move(getter)), applet_manager{applet_manager_} {}
-
-Boxcat::~Boxcat() = default;
-
-void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGetter dir_getter,
- TitleIDVersion title, ProgressServiceBackend& progress,
- std::optional<std::string> dir_name = {}) {
- progress.SetNeedHLELock(true);
-
- if (Settings::values.bcat_boxcat_local) {
- LOG_INFO(Service_BCAT, "Boxcat using local data by override, skipping download.");
- const auto dir = dir_getter(title.title_id);
- if (dir)
- progress.SetTotalSize(dir->GetSize());
- progress.FinishDownload(ResultSuccess);
- return;
- }
-
- const auto zip_path = GetZIPFilePath(title.title_id);
- Boxcat::Client client{zip_path, title.title_id, title.build_id};
-
- progress.StartConnecting();
-
- const auto res = client.DownloadDataZip();
- if (res != DownloadResult::Success) {
- LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
-
- if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
- Common::FS::RemoveFile(zip_path);
- }
-
- HandleDownloadDisplayResult(applet_manager, res);
- progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE);
- return;
- }
-
- progress.StartProcessingDataList();
-
- Common::FS::IOFile zip{zip_path, Common::FS::FileAccessMode::Read,
- Common::FS::FileType::BinaryFile};
- const auto size = zip.GetSize();
- std::vector<u8> bytes(size);
- if (!zip.IsOpen() || size == 0 || zip.Read(bytes) != bytes.size()) {
- LOG_ERROR(Service_BCAT, "Boxcat failed to read ZIP file at path '{}'!",
- Common::FS::PathToUTF8String(zip_path));
- progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE);
- return;
- }
-
- const auto extracted = FileSys::ExtractZIP(std::make_shared<FileSys::VectorVfsFile>(bytes));
- if (extracted == nullptr) {
- LOG_ERROR(Service_BCAT, "Boxcat failed to extract ZIP file!");
- progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE);
- return;
- }
-
- if (dir_name == std::nullopt) {
- progress.SetTotalSize(extracted->GetSize());
-
- const auto target_dir = dir_getter(title.title_id);
- if (target_dir == nullptr || !VfsRawCopyDProgress(extracted, target_dir, progress)) {
- LOG_ERROR(Service_BCAT, "Boxcat failed to copy extracted ZIP to target directory!");
- progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE);
- return;
- }
- } else {
- const auto target_dir = dir_getter(title.title_id);
- if (target_dir == nullptr) {
- LOG_ERROR(Service_BCAT, "Boxcat failed to get directory for title ID!");
- progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE);
- return;
- }
-
- const auto target_sub = target_dir->GetSubdirectory(*dir_name);
- const auto source_sub = extracted->GetSubdirectory(*dir_name);
-
- progress.SetTotalSize(source_sub->GetSize());
-
- std::vector<std::string> filenames;
- {
- const auto files = target_sub->GetFiles();
- std::transform(files.begin(), files.end(), std::back_inserter(filenames),
- [](const auto& vfile) { return vfile->GetName(); });
- }
-
- for (const auto& filename : filenames) {
- VfsDeleteFileWrap(target_sub, filename);
- }
-
- if (target_sub == nullptr || source_sub == nullptr ||
- !VfsRawCopyDProgressSingle(source_sub, target_sub, progress)) {
- LOG_ERROR(Service_BCAT, "Boxcat failed to copy extracted ZIP to target directory!");
- progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE);
- return;
- }
- }
-
- progress.FinishDownload(ResultSuccess);
-}
-
-bool Boxcat::Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) {
- is_syncing.exchange(true);
-
- std::thread([this, title, &progress] {
- SynchronizeInternal(applet_manager, dir_getter, title, progress);
- }).detach();
-
- return true;
-}
-
-bool Boxcat::SynchronizeDirectory(TitleIDVersion title, std::string name,
- ProgressServiceBackend& progress) {
- is_syncing.exchange(true);
-
- std::thread([this, title, name, &progress] {
- SynchronizeInternal(applet_manager, dir_getter, title, progress, name);
- }).detach();
-
- return true;
-}
-
-bool Boxcat::Clear(u64 title_id) {
- if (Settings::values.bcat_boxcat_local) {
- LOG_INFO(Service_BCAT, "Boxcat using local data by override, skipping clear.");
- return true;
- }
-
- const auto dir = dir_getter(title_id);
-
- std::vector<std::string> dirnames;
-
- for (const auto& subdir : dir->GetSubdirectories())
- dirnames.push_back(subdir->GetName());
-
- for (const auto& subdir : dirnames) {
- if (!dir->DeleteSubdirectoryRecursive(subdir))
- return false;
- }
-
- return true;
-}
-
-void Boxcat::SetPassphrase(u64 title_id, const Passphrase& passphrase) {
- LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, passphrase={}", title_id,
- Common::HexToString(passphrase));
-}
-
-std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title) {
- const auto bin_file_path = GetBINFilePath(title.title_id);
-
- if (Settings::values.bcat_boxcat_local) {
- LOG_INFO(Service_BCAT, "Boxcat using local data by override, skipping download.");
- } else {
- Client launch_client{bin_file_path, title.title_id, title.build_id};
-
- const auto res = launch_client.DownloadLaunchParam();
- if (res != DownloadResult::Success) {
- LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
-
- if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
- Common::FS::RemoveFile(bin_file_path);
- }
-
- HandleDownloadDisplayResult(applet_manager, res);
- return std::nullopt;
- }
- }
-
- Common::FS::IOFile bin{bin_file_path, Common::FS::FileAccessMode::Read,
- Common::FS::FileType::BinaryFile};
- const auto size = bin.GetSize();
- std::vector<u8> bytes(size);
- if (!bin.IsOpen() || size == 0 || bin.Read(bytes) != bytes.size()) {
- LOG_ERROR(Service_BCAT, "Boxcat failed to read launch parameter binary at path '{}'!",
- Common::FS::PathToUTF8String(bin_file_path));
- return std::nullopt;
- }
-
- return bytes;
-}
-
-Boxcat::StatusResult Boxcat::GetStatus(std::optional<std::string>& global,
- std::map<std::string, EventStatus>& games) {
- httplib::SSLClient client{BOXCAT_HOSTNAME, static_cast<int>(PORT)};
- client.set_connection_timeout(static_cast<int>(TIMEOUT_SECONDS));
- client.set_read_timeout(static_cast<int>(TIMEOUT_SECONDS));
- client.set_write_timeout(static_cast<int>(TIMEOUT_SECONDS));
-
- httplib::Headers headers{
- {std::string("Game-Assets-API-Version"), std::string(BOXCAT_API_VERSION)},
- {std::string("Boxcat-Client-Type"), std::string(BOXCAT_CLIENT_TYPE)},
- };
-
- if (!client.is_valid()) {
- LOG_ERROR(Service_BCAT, "Client is invalid, going offline!");
- return StatusResult::Offline;
- }
-
- if (!client.is_socket_open()) {
- LOG_ERROR(Service_BCAT, "Failed to open socket, going offline!");
- return StatusResult::Offline;
- }
-
- const auto response = client.Get(BOXCAT_PATHNAME_EVENTS, headers);
- if (response == nullptr)
- return StatusResult::Offline;
-
- if (response->status == static_cast<int>(ResponseStatus::BadClientVersion))
- return StatusResult::BadClientVersion;
-
- try {
- nlohmann::json json = nlohmann::json::parse(response->body);
-
- if (!json["online"].get<bool>())
- return StatusResult::Offline;
-
- if (json["global"].is_null())
- global = std::nullopt;
- else
- global = json["global"].get<std::string>();
-
- if (json["games"].is_array()) {
- for (const auto& object : json["games"]) {
- if (object.is_object() && object.find("name") != object.end()) {
- EventStatus detail{};
- if (object["header"].is_string()) {
- detail.header = object["header"].get<std::string>();
- } else {
- detail.header = std::nullopt;
- }
-
- if (object["footer"].is_string()) {
- detail.footer = object["footer"].get<std::string>();
- } else {
- detail.footer = std::nullopt;
- }
-
- if (object["events"].is_array()) {
- for (const auto& event : object["events"]) {
- if (!event.is_string())
- continue;
- detail.events.push_back(event.get<std::string>());
- }
- }
-
- games.insert_or_assign(object["name"], std::move(detail));
- }
- }
- }
-
- return StatusResult::Success;
- } catch (const nlohmann::json::parse_error& error) {
- LOG_ERROR(Service_BCAT, "{}", error.what());
- return StatusResult::ParseError;
- }
-}
-
-} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/backend/boxcat.h b/src/core/hle/service/bcat/backend/boxcat.h
deleted file mode 100644
index d65b42e58..000000000
--- a/src/core/hle/service/bcat/backend/boxcat.h
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2019 yuzu emulator team
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-#pragma once
-
-#include <atomic>
-#include <map>
-#include <optional>
-#include "core/hle/service/bcat/backend/backend.h"
-
-namespace Service::AM::Applets {
-class AppletManager;
-}
-
-namespace Service::BCAT {
-
-struct EventStatus {
- std::optional<std::string> header;
- std::optional<std::string> footer;
- std::vector<std::string> events;
-};
-
-/// Boxcat is yuzu's custom backend implementation of Nintendo's BCAT service. It is free to use and
-/// doesn't require a switch or nintendo account. The content is controlled by the yuzu team.
-class Boxcat final : public Backend {
- friend void SynchronizeInternal(AM::Applets::AppletManager& applet_manager,
- DirectoryGetter dir_getter, TitleIDVersion title,
- ProgressServiceBackend& progress,
- std::optional<std::string> dir_name);
-
-public:
- explicit Boxcat(AM::Applets::AppletManager& applet_manager_, DirectoryGetter getter);
- ~Boxcat() override;
-
- bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) override;
- bool SynchronizeDirectory(TitleIDVersion title, std::string name,
- ProgressServiceBackend& progress) override;
-
- bool Clear(u64 title_id) override;
-
- void SetPassphrase(u64 title_id, const Passphrase& passphrase) override;
-
- std::optional<std::vector<u8>> GetLaunchParameter(TitleIDVersion title) override;
-
- enum class StatusResult {
- Success,
- Offline,
- ParseError,
- BadClientVersion,
- };
-
- static StatusResult GetStatus(std::optional<std::string>& global,
- std::map<std::string, EventStatus>& games);
-
-private:
- std::atomic_bool is_syncing{false};
-
- class Client;
- std::unique_ptr<Client> client;
- AM::Applets::AppletManager& applet_manager;
-};
-
-} // namespace Service::BCAT
diff --git a/src/core/hle/service/bcat/bcat_module.cpp b/src/core/hle/service/bcat/bcat_module.cpp
index 72294eb2e..27e9b8df8 100644
--- a/src/core/hle/service/bcat/bcat_module.cpp
+++ b/src/core/hle/service/bcat/bcat_module.cpp
@@ -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));
}
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
index 46da438ef..088a1a18a 100644
--- a/src/core/hle/service/btdrv/btdrv.cpp
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -5,11 +5,10 @@
#include "common/logging/log.h"
#include "core/core.h"
#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 +17,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 +34,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 +47,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> {
@@ -175,6 +179,10 @@ public:
{143, nullptr, "GetAudioControlInputState"},
{144, nullptr, "AcquireAudioConnectionStateChangedEvent"},
{145, nullptr, "GetConnectedAudioDevice"},
+ {146, nullptr, "CloseAudioControlInput"},
+ {147, nullptr, "RegisterAudioControlNotification"},
+ {148, nullptr, "SendAudioControlPassthroughCommand"},
+ {149, nullptr, "SendAudioControlSetAbsoluteVolumeCommand"},
{256, nullptr, "IsManufacturingMode"},
{257, nullptr, "EmulateBluetoothCrash"},
{258, nullptr, "GetBleChannelMap"},
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index 3ab29036a..7aabacc19 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -7,11 +7,10 @@
#include "common/logging/log.h"
#include "core/core.h"
#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 +18,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 +57,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 +76,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 +84,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 +92,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 +100,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> {
diff --git a/src/core/hle/service/caps/caps.h b/src/core/hle/service/caps/caps.h
index 3c4290c88..b18adcb9d 100644
--- a/src/core/hle/service/caps/caps.h
+++ b/src/core/hle/service/caps/caps.h
@@ -4,7 +4,8 @@
#pragma once
-#include "core/hle/service/service.h"
+#include "common/common_funcs.h"
+#include "common/common_types.h"
namespace Core {
class System;
diff --git a/src/core/hle/service/caps/caps_ss.cpp b/src/core/hle/service/caps/caps_ss.cpp
index 2b5314691..33a976ddf 100644
--- a/src/core/hle/service/caps/caps_ss.cpp
+++ b/src/core/hle/service/caps/caps_ss.cpp
@@ -15,6 +15,7 @@ CAPS_SS::CAPS_SS(Core::System& system_) : ServiceFramework{system_, "caps:ss"} {
{204, nullptr, "SaveEditedScreenShotEx0"},
{206, nullptr, "Unknown206"},
{208, nullptr, "SaveScreenShotOfMovieEx1"},
+ {1000, nullptr, "Unknown1000"},
};
// clang-format on
diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp
index 110c7cb1c..f6184acc9 100644
--- a/src/core/hle/service/es/es.cpp
+++ b/src/core/hle/service/es/es.cpp
@@ -55,6 +55,8 @@ public:
{36, nullptr, "DeleteAllInactiveELicenseRequiredPersonalizedTicket"},
{37, nullptr, "OwnTicket2"},
{38, nullptr, "OwnTicket3"},
+ {39, nullptr, "DeleteAllInactivePersonalizedTicket"},
+ {40, nullptr, "DeletePrepurchaseRecordByNintendoAccountId"},
{501, nullptr, "Unknown501"},
{502, nullptr, "Unknown502"},
{503, nullptr, "GetTitleKey"},
@@ -88,11 +90,15 @@ public:
{1503, nullptr, "Unknown1503"},
{1504, nullptr, "Unknown1504"},
{1505, nullptr, "Unknown1505"},
+ {1506, nullptr, "Unknown1506"},
{2000, nullptr, "Unknown2000"},
{2001, nullptr, "Unknown2001"},
+ {2002, nullptr, "Unknown2002"},
+ {2003, nullptr, "Unknown2003"},
{2100, nullptr, "Unknown2100"},
{2501, nullptr, "Unknown2501"},
{2502, nullptr, "Unknown2502"},
+ {2601, nullptr, "Unknown2601"},
{3001, nullptr, "Unknown3001"},
{3002, nullptr, "Unknown3002"},
};
diff --git a/src/core/hle/service/fgm/fgm.cpp b/src/core/hle/service/fgm/fgm.cpp
index 25c6c0194..d7a638f96 100644
--- a/src/core/hle/service/fgm/fgm.cpp
+++ b/src/core/hle/service/fgm/fgm.cpp
@@ -5,7 +5,6 @@
#include <memory>
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/fgm/fgm.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
diff --git a/src/core/hle/service/filesystem/fsp_ldr.cpp b/src/core/hle/service/filesystem/fsp_ldr.cpp
index 1f6c17ba5..f112ae9d0 100644
--- a/src/core/hle/service/filesystem/fsp_ldr.cpp
+++ b/src/core/hle/service/filesystem/fsp_ldr.cpp
@@ -3,7 +3,6 @@
// Refer to the license.txt file included.
#include "core/hle/service/filesystem/fsp_ldr.h"
-#include "core/hle/service/service.h"
namespace Service::FileSystem {
diff --git a/src/core/hle/service/filesystem/fsp_pr.cpp b/src/core/hle/service/filesystem/fsp_pr.cpp
index 00e4d1662..9b7f7d861 100644
--- a/src/core/hle/service/filesystem/fsp_pr.cpp
+++ b/src/core/hle/service/filesystem/fsp_pr.cpp
@@ -3,7 +3,6 @@
// Refer to the license.txt file included.
#include "core/hle/service/filesystem/fsp_pr.h"
-#include "core/hle/service/service.h"
namespace Service::FileSystem {
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index b58c152ce..68c9240ae 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -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_,
diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp
index 5a3b54cc1..70cd63c6b 100644
--- a/src/core/hle/service/glue/arp.cpp
+++ b/src/core/hle/service/glue/arp.cpp
@@ -8,13 +8,11 @@
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/glue/arp.h"
#include "core/hle/service/glue/errors.h"
#include "core/hle/service/glue/glue_manager.h"
-#include "core/hle/service/service.h"
namespace Service::Glue {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 4fcc6f93a..9ee146caf 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -507,6 +507,7 @@ private:
LarkNesRight = 18,
Lucia = 19,
Verification = 20,
+ Lagon = 21,
};
struct NPadEntry {
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index a1707a72a..043320d50 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -8,12 +8,9 @@
#include "common/settings.h"
#include "core/core.h"
#include "core/core_timing.h"
-#include "core/core_timing_util.h"
#include "core/frontend/emu_window.h"
#include "core/frontend/input.h"
-#include "core/hardware_properties.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/k_transfer_memory.h"
@@ -23,7 +20,6 @@
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/hid/irs.h"
#include "core/hle/service/hid/xcd.h"
-#include "core/hle/service/service.h"
#include "core/memory.h"
#include "core/hle/service/hid/controllers/console_sixaxis.h"
@@ -106,7 +102,7 @@ void IAppletResource::DeactivateController(HidController controller) {
controllers[static_cast<size_t>(controller)]->DeactivateController();
}
-IAppletResource ::~IAppletResource() {
+IAppletResource::~IAppletResource() {
system.CoreTiming().UnscheduleEvent(pad_update_event, 0);
system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
}
@@ -239,6 +235,12 @@ Hid::Hid(Core::System& system_)
{81, &Hid::ResetGyroscopeZeroDriftMode, "ResetGyroscopeZeroDriftMode"},
{82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
{83, &Hid::IsFirmwareUpdateAvailableForSixAxisSensor, "IsFirmwareUpdateAvailableForSixAxisSensor"},
+ {84, nullptr, "EnableSixAxisSensorUnalteredPassthrough"},
+ {85, nullptr, "IsSixAxisSensorUnalteredPassthroughEnabled"},
+ {86, nullptr, "StoreSixAxisSensorCalibrationParameter"},
+ {87, nullptr, "LoadSixAxisSensorCalibrationParameter"},
+ {88, nullptr, "GetSixAxisSensorIcInformation"},
+ {89, nullptr, "ResetIsSixAxisSensorDeviceNewlyAssigned"},
{91, &Hid::ActivateGesture, "ActivateGesture"},
{100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
{101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
@@ -1656,6 +1658,9 @@ public:
{12, nullptr, "UnsetTouchScreenAutoPilotState"},
{13, nullptr, "GetTouchScreenConfiguration"},
{14, nullptr, "ProcessTouchScreenAutoTune"},
+ {15, nullptr, "ForceStopTouchScreenManagement"},
+ {16, nullptr, "ForceRestartTouchScreenManagement"},
+ {17, nullptr, "IsTouchScreenManaged"},
{20, nullptr, "DeactivateMouse"},
{21, nullptr, "SetMouseAutoPilotState"},
{22, nullptr, "UnsetMouseAutoPilotState"},
diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp
index 24890c830..5c8ae029c 100644
--- a/src/core/hle/service/lbl/lbl.cpp
+++ b/src/core/hle/service/lbl/lbl.cpp
@@ -2,11 +2,11 @@
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
+#include <cmath>
#include <memory>
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/lbl/lbl.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp
index 9d863486a..0b907824d 100644
--- a/src/core/hle/service/mii/mii.cpp
+++ b/src/core/hle/service/mii/mii.cpp
@@ -6,7 +6,6 @@
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/mii/mii.h"
#include "core/hle/service/mii/mii_manager.h"
#include "core/hle/service/service.h"
diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp
index b014ea826..f77037842 100644
--- a/src/core/hle/service/nfc/nfc.cpp
+++ b/src/core/hle/service/nfc/nfc.cpp
@@ -7,7 +7,6 @@
#include "common/logging/log.h"
#include "common/settings.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/nfc/nfc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index 5f1ca029d..6791f20a5 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -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 {
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h
index 5e4e49bc6..95c127efb 100644
--- a/src/core/hle/service/nfp/nfp.h
+++ b/src/core/hle/service/nfp/nfp.h
@@ -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{};
};
};
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index 9decb9290..f13dc8b0d 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -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> {
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index 7447cc38f..30fb060b8 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -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");
}
-private:
- Kernel::KEvent finished_event;
+ ~IEnsureNetworkClockAvailabilityService() override {
+ service_context.CloseEvent(finished_event);
+ }
+private:
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> {
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp
index e4c703da4..32533cd94 100644
--- a/src/core/hle/service/npns/npns.cpp
+++ b/src/core/hle/service/npns/npns.cpp
@@ -31,6 +31,7 @@ public:
{24, nullptr, "DestroyTokenWithApplicationId"},
{25, nullptr, "QueryIsTokenValid"},
{26, nullptr, "ListenToMyApplicationId"},
+ {27, nullptr, "DestroyTokenAll"},
{31, nullptr, "UploadTokenToBaaS"},
{32, nullptr, "DestroyTokenForBaaS"},
{33, nullptr, "CreateTokenForBaaS"},
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index 8ce1f3296..931b48f72 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -9,7 +9,6 @@
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/vfs.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/ns/errors.h"
#include "core/hle/service/ns/language.h"
#include "core/hle/service/ns/ns.h"
diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
index a33e47d0b..4ee8c5733 100644
--- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp
@@ -16,7 +16,7 @@ namespace Service::Nvidia::Devices {
nvdisp_disp0::nvdisp_disp0(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_)
: nvdevice{system_}, nvmap_dev{std::move(nvmap_dev_)} {}
-nvdisp_disp0 ::~nvdisp_disp0() = default;
+nvdisp_disp0::~nvdisp_disp0() = default;
NvResult nvdisp_disp0::Ioctl1(DeviceFD fd, Ioctl command, const std::vector<u8>& input,
std::vector<u8>& output) {
@@ -48,8 +48,9 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3
addr, offset, width, height, stride, format);
const auto pixel_format = static_cast<Tegra::FramebufferConfig::PixelFormat>(format);
- const Tegra::FramebufferConfig framebuffer{addr, offset, width, height,
- stride, pixel_format, transform, crop_rect};
+ const auto transform_flags = static_cast<Tegra::FramebufferConfig::TransformFlags>(transform);
+ const Tegra::FramebufferConfig framebuffer{addr, offset, width, height,
+ stride, pixel_format, transform_flags, crop_rect};
system.GetPerfStats().EndSystemFrame();
system.GPU().SwapBuffers(&framebuffer);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 775e76330..f9b82b504 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -92,6 +92,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
if (syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) {
params.value = syncpoint_manager.GetSyncpointMin(params.syncpt_id);
std::memcpy(output.data(), &params, sizeof(params));
+ events_interface.failed[event_id] = false;
return NvResult::Success;
}
@@ -99,6 +100,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
syncpoint_manager.IsSyncpointExpired(params.syncpt_id, params.threshold)) {
params.value = new_value;
std::memcpy(output.data(), &params, sizeof(params));
+ events_interface.failed[event_id] = false;
return NvResult::Success;
}
@@ -111,13 +113,13 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
event.event->GetWritableEvent().Signal();
return NvResult::Success;
}
- auto lock = gpu.LockSync();
const u32 current_syncpoint_value = event.fence.value;
const s32 diff = current_syncpoint_value - params.threshold;
if (diff >= 0) {
event.event->GetWritableEvent().Signal();
params.value = current_syncpoint_value;
std::memcpy(output.data(), &params, sizeof(params));
+ events_interface.failed[event_id] = false;
return NvResult::Success;
}
const u32 target_value = current_syncpoint_value - diff;
@@ -132,23 +134,34 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
}
EventState status = events_interface.status[event_id];
- if (event_id < MaxNvEvents || status == EventState::Free || status == EventState::Registered) {
- events_interface.SetEventStatus(event_id, EventState::Waiting);
- events_interface.assigned_syncpt[event_id] = params.syncpt_id;
- events_interface.assigned_value[event_id] = target_value;
- if (is_async) {
- params.value = params.syncpt_id << 4;
- } else {
- params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
+ const bool bad_parameter = status != EventState::Free && status != EventState::Registered;
+ if (bad_parameter) {
+ std::memcpy(output.data(), &params, sizeof(params));
+ return NvResult::BadParameter;
+ }
+ events_interface.SetEventStatus(event_id, EventState::Waiting);
+ events_interface.assigned_syncpt[event_id] = params.syncpt_id;
+ events_interface.assigned_value[event_id] = target_value;
+ if (is_async) {
+ params.value = params.syncpt_id << 4;
+ } else {
+ params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
+ }
+ params.value |= event_id;
+ event.event->GetWritableEvent().Clear();
+ if (events_interface.failed[event_id]) {
+ {
+ auto lk = system.StallCPU();
+ gpu.WaitFence(params.syncpt_id, target_value);
+ system.UnstallCPU();
}
- params.value |= event_id;
- event.event->GetWritableEvent().Clear();
- gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
std::memcpy(output.data(), &params, sizeof(params));
- return NvResult::Timeout;
+ events_interface.failed[event_id] = false;
+ return NvResult::Success;
}
+ gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
std::memcpy(output.data(), &params, sizeof(params));
- return NvResult::BadParameter;
+ return NvResult::Timeout;
}
NvResult nvhost_ctrl::IocCtrlEventRegister(const std::vector<u8>& input, std::vector<u8>& output) {
@@ -201,6 +214,7 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::v
if (events_interface.status[event_id] == EventState::Waiting) {
events_interface.LiberateEvent(event_id);
}
+ events_interface.failed[event_id] = true;
syncpoint_manager.RefreshSyncpoint(events_interface.events[event_id].fence.id);
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
index c0a380088..54ac105d5 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp
@@ -13,6 +13,14 @@
#include "video_core/memory_manager.h"
namespace Service::Nvidia::Devices {
+namespace {
+Tegra::CommandHeader BuildFenceAction(Tegra::GPU::FenceOperation op, u32 syncpoint_id) {
+ Tegra::GPU::FenceAction result{};
+ result.op.Assign(op);
+ result.syncpoint_id.Assign(syncpoint_id);
+ return {result.raw};
+}
+} // namespace
nvhost_gpu::nvhost_gpu(Core::System& system_, std::shared_ptr<nvmap> nvmap_dev_,
SyncpointManager& syncpoint_manager_)
@@ -187,7 +195,7 @@ static std::vector<Tegra::CommandHeader> BuildWaitCommandList(Fence fence) {
{fence.value},
Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
Tegra::SubmissionMode::Increasing),
- Tegra::GPU::FenceAction::Build(Tegra::GPU::FenceOperation::Acquire, fence.id),
+ BuildFenceAction(Tegra::GPU::FenceOperation::Acquire, fence.id),
};
}
@@ -200,8 +208,7 @@ static std::vector<Tegra::CommandHeader> BuildIncrementCommandList(Fence fence,
for (u32 count = 0; count < add_increment; ++count) {
result.emplace_back(Tegra::BuildCommandHeader(Tegra::BufferMethods::FenceAction, 1,
Tegra::SubmissionMode::Increasing));
- result.emplace_back(
- Tegra::GPU::FenceAction::Build(Tegra::GPU::FenceOperation::Increment, fence.id));
+ result.emplace_back(BuildFenceAction(Tegra::GPU::FenceOperation::Increment, fence.id));
}
return result;
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h
index e2a1dde5b..a5af5b785 100644
--- a/src/core/hle/service/nvdrv/nvdrv.h
+++ b/src/core/hle/service/nvdrv/nvdrv.h
@@ -49,6 +49,8 @@ struct EventInterface {
std::array<EventState, MaxNvEvents> status{};
// Tells if an NVEvent is registered or not
std::array<bool, MaxNvEvents> registered{};
+ // Tells the NVEvent that it has failed.
+ std::array<bool, MaxNvEvents> failed{};
// When an NVEvent is waiting on GPU interrupt, this is the sync_point
// associated with it.
std::array<u32, MaxNvEvents> assigned_syncpt{};
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index 3ead813b0..a22811ec1 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -13,28 +13,20 @@
#include "common/thread.h"
#include "core/core.h"
#include "core/core_timing.h"
-#include "core/core_timing_util.h"
-#include "core/hardware_properties.h"
#include "core/hle/kernel/k_readable_event.h"
-#include "core/hle/kernel/kernel.h"
#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
#include "core/hle/service/nvdrv/nvdrv.h"
#include "core/hle/service/nvflinger/buffer_queue.h"
#include "core/hle/service/nvflinger/nvflinger.h"
#include "core/hle/service/vi/display/vi_display.h"
#include "core/hle/service/vi/layer/vi_layer.h"
-#include "core/perf_stats.h"
-#include "video_core/renderer_base.h"
+#include "video_core/gpu.h"
namespace Service::NVFlinger {
constexpr auto frame_ns = std::chrono::nanoseconds{1000000000 / 60};
-void NVFlinger::VSyncThread(NVFlinger& nv_flinger) {
- nv_flinger.SplitVSync();
-}
-
-void NVFlinger::SplitVSync() {
+void NVFlinger::SplitVSync(std::stop_token stop_token) {
system.RegisterHostThread();
std::string name = "yuzu:VSyncThread";
MicroProfileOnThreadCreate(name.c_str());
@@ -45,7 +37,7 @@ void NVFlinger::SplitVSync() {
Common::SetCurrentThreadName(name.c_str());
Common::SetCurrentThreadPriority(Common::ThreadPriority::High);
s64 delay = 0;
- while (is_running) {
+ while (!stop_token.stop_requested()) {
guard->lock();
const s64 time_start = system.CoreTiming().GetGlobalTimeNs().count();
Compose();
@@ -55,7 +47,7 @@ void NVFlinger::SplitVSync() {
const s64 next_time = std::max<s64>(0, ticks - time_passed - delay);
guard->unlock();
if (next_time > 0) {
- wait_event->WaitFor(std::chrono::nanoseconds{next_time});
+ std::this_thread::sleep_for(std::chrono::nanoseconds{next_time});
}
delay = (system.CoreTiming().GetGlobalTimeNs().count() - time_end) - next_time;
}
@@ -84,9 +76,7 @@ NVFlinger::NVFlinger(Core::System& system_)
});
if (system.IsMulticore()) {
- is_running = true;
- wait_event = std::make_unique<Common::Event>();
- vsync_thread = std::make_unique<std::thread>(VSyncThread, std::ref(*this));
+ vsync_thread = std::jthread([this](std::stop_token token) { SplitVSync(token); });
} else {
system.CoreTiming().ScheduleEvent(frame_ns, composition_event);
}
@@ -96,14 +86,7 @@ NVFlinger::~NVFlinger() {
for (auto& buffer_queue : buffer_queues) {
buffer_queue->Disconnect();
}
-
- if (system.IsMulticore()) {
- is_running = false;
- wait_event->Set();
- vsync_thread->join();
- vsync_thread.reset();
- wait_event.reset();
- } else {
+ if (!system.IsMulticore()) {
system.CoreTiming().UnscheduleEvent(composition_event, 0);
}
}
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index 6d84cafb4..7935cf773 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -4,13 +4,10 @@
#pragma once
-#include <atomic>
#include <list>
#include <memory>
#include <mutex>
#include <optional>
-#include <string>
-#include <string_view>
#include <thread>
#include <vector>
@@ -109,9 +106,7 @@ private:
/// Creates a layer with the specified layer ID in the desired display.
void CreateLayerAtId(VI::Display& display, u64 layer_id);
- static void VSyncThread(NVFlinger& nv_flinger);
-
- void SplitVSync();
+ void SplitVSync(std::stop_token stop_token);
std::shared_ptr<Nvidia::Module> nvdrv;
@@ -133,9 +128,7 @@ private:
Core::System& system;
- std::unique_ptr<std::thread> vsync_thread;
- std::unique_ptr<Common::Event> wait_event;
- std::atomic<bool> is_running{};
+ std::jthread vsync_thread;
KernelHelpers::ServiceContext service_context;
};
diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp
index 3bbe1bfe2..39a8031a5 100644
--- a/src/core/hle/service/olsc/olsc.cpp
+++ b/src/core/hle/service/olsc/olsc.cpp
@@ -3,7 +3,6 @@
// Refer to the license.txt file included.
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/olsc/olsc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp
index d9897c5c5..22ff5269c 100644
--- a/src/core/hle/service/ptm/psm.cpp
+++ b/src/core/hle/service/ptm/psm.cpp
@@ -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> {
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index 8299c6b68..286578b17 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -7,7 +7,6 @@
#include "core/file_sys/errors.h"
#include "core/file_sys/system_archive/system_version.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/k_client_port.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/set/set_sys.h"
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index 7d85ecb6a..b9e765f1d 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -415,6 +415,18 @@ void BSD::Write(Kernel::HLERequestContext& ctx) {
});
}
+void BSD::Read(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const s32 fd = rp.Pop<s32>();
+
+ LOG_WARNING(Service, "(STUBBED) called. fd={} len={}", fd, ctx.GetWriteBufferSize());
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(ResultSuccess);
+ rb.Push<u32>(0); // ret
+ rb.Push<u32>(0); // bsd errno
+}
+
void BSD::Close(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const s32 fd = rp.Pop<s32>();
@@ -855,7 +867,7 @@ BSD::BSD(Core::System& system_, const char* name) : ServiceFramework{system_, na
{22, &BSD::Shutdown, "Shutdown"},
{23, nullptr, "ShutdownAllSockets"},
{24, &BSD::Write, "Write"},
- {25, nullptr, "Read"},
+ {25, &BSD::Read, "Read"},
{26, &BSD::Close, "Close"},
{27, nullptr, "DuplicateSocket"},
{28, nullptr, "GetResourceStatistics"},
diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h
index 1d2df9c61..a387e50df 100644
--- a/src/core/hle/service/sockets/bsd.h
+++ b/src/core/hle/service/sockets/bsd.h
@@ -5,11 +5,9 @@
#pragma once
#include <memory>
-#include <string_view>
#include <vector>
#include "common/common_types.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sockets/sockets.h"
@@ -135,6 +133,7 @@ private:
void Send(Kernel::HLERequestContext& ctx);
void SendTo(Kernel::HLERequestContext& ctx);
void Write(Kernel::HLERequestContext& ctx);
+ void Read(Kernel::HLERequestContext& ctx);
void Close(Kernel::HLERequestContext& ctx);
void EventFd(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/sockets/sfdnsres.h b/src/core/hle/service/sockets/sfdnsres.h
index faa6b7d0d..5d3b4dc2d 100644
--- a/src/core/hle/service/sockets/sfdnsres.h
+++ b/src/core/hle/service/sockets/sfdnsres.h
@@ -4,7 +4,6 @@
#pragma once
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
namespace Core {
diff --git a/src/core/hle/service/sockets/sockets.h b/src/core/hle/service/sockets/sockets.h
index 5a65ed2a9..02dbbae40 100644
--- a/src/core/hle/service/sockets/sockets.h
+++ b/src/core/hle/service/sockets/sockets.h
@@ -4,13 +4,17 @@
#pragma once
+#include "common/common_funcs.h"
#include "common/common_types.h"
-#include "core/hle/service/service.h"
namespace Core {
class System;
}
+namespace Service::SM {
+class ServiceManager;
+}
+
namespace Service::Sockets {
enum class Errno : u32 {
diff --git a/src/core/hle/service/spl/spl_module.cpp b/src/core/hle/service/spl/spl_module.cpp
index 918633af5..ed4c06260 100644
--- a/src/core/hle/service/spl/spl_module.cpp
+++ b/src/core/hle/service/spl/spl_module.cpp
@@ -3,10 +3,8 @@
// Refer to the license.txt file included.
#include <algorithm>
-#include <chrono>
#include <cstdlib>
#include <ctime>
-#include <functional>
#include <vector>
#include "common/logging/log.h"
#include "common/settings.h"
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp
index 921f4d776..a81a595ea 100644
--- a/src/core/hle/service/ssl/ssl.cpp
+++ b/src/core/hle/service/ssl/ssl.cpp
@@ -3,7 +3,6 @@
// Refer to the license.txt file included.
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
#include "core/hle/service/ssl/ssl.h"
diff --git a/src/core/hle/service/time/standard_user_system_clock_core.cpp b/src/core/hle/service/time/standard_user_system_clock_core.cpp
index ef79ab917..e94220a44 100644
--- a/src/core/hle/service/time/standard_user_system_clock_core.cpp
+++ b/src/core/hle/service/time/standard_user_system_clock_core.cpp
@@ -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,
diff --git a/src/core/hle/service/time/standard_user_system_clock_core.h b/src/core/hle/service/time/standard_user_system_clock_core.h
index bf9ec5e42..b7cb2b045 100644
--- a/src/core/hle/service/time/standard_user_system_clock_core.h
+++ b/src/core/hle/service/time/standard_user_system_clock_core.h
@@ -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
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.h b/src/core/hle/service/time/system_clock_context_update_callback.h
index 797954958..6936397a5 100644
--- a/src/core/hle/service/time/system_clock_context_update_callback.h
+++ b/src/core/hle/service/time/system_clock_context_update_callback.h
@@ -4,6 +4,7 @@
#pragma once
+#include <memory>
#include <vector>
#include "core/hle/service/time/clock_types.h"
diff --git a/src/core/hle/service/time/system_clock_core.cpp b/src/core/hle/service/time/system_clock_core.cpp
index bd334bbef..5c2354cdd 100644
--- a/src/core/hle/service/time/system_clock_core.cpp
+++ b/src/core/hle/service/time/system_clock_core.cpp
@@ -13,7 +13,7 @@ SystemClockCore::SystemClockCore(SteadyClockCore& steady_clock_core_)
context.steady_time_point.clock_source_id = steady_clock_core.GetClockSourceId();
}
-SystemClockCore ::~SystemClockCore() = default;
+SystemClockCore::~SystemClockCore() = default;
ResultCode SystemClockCore::GetCurrentTime(Core::System& system, s64& posix_time) const {
posix_time = 0;
diff --git a/src/core/hle/service/time/system_clock_core.h b/src/core/hle/service/time/system_clock_core.h
index 83d0e5d62..b9237ad28 100644
--- a/src/core/hle/service/time/system_clock_core.h
+++ b/src/core/hle/service/time/system_clock_core.h
@@ -4,6 +4,8 @@
#pragma once
+#include <memory>
+
#include "common/common_types.h"
#include "core/hle/service/time/clock_types.h"
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index 8fdd5076f..d84a111c2 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -8,11 +8,11 @@
#include "core/core_timing_util.h"
#include "core/hardware_properties.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/k_client_port.h"
#include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/service/time/time.h"
#include "core/hle/service/time/time_interface.h"
+#include "core/hle/service/time/time_manager.h"
#include "core/hle/service/time/time_sharedmemory.h"
#include "core/hle/service/time/time_zone_service.h"
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index ce9c479c6..30e2cd369 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -6,7 +6,6 @@
#include "core/hle/service/service.h"
#include "core/hle/service/time/clock_types.h"
-#include "core/hle/service/time/time_manager.h"
namespace Core {
class System;
diff --git a/src/core/hle/service/time/time_zone_service.cpp b/src/core/hle/service/time/time_zone_service.cpp
index 5c3108768..3871e7316 100644
--- a/src/core/hle/service/time/time_zone_service.cpp
+++ b/src/core/hle/service/time/time_zone_service.cpp
@@ -10,8 +10,8 @@
namespace Service::Time {
-ITimeZoneService ::ITimeZoneService(Core::System& system_,
- TimeZone::TimeZoneContentManager& time_zone_manager_)
+ITimeZoneService::ITimeZoneService(Core::System& system_,
+ TimeZone::TimeZoneContentManager& time_zone_manager_)
: ServiceFramework{system_, "ITimeZoneService"}, time_zone_content_manager{time_zone_manager_} {
static const FunctionInfo functions[] = {
{0, &ITimeZoneService::GetDeviceLocationName, "GetDeviceLocationName"},
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp
index 7f436c3bb..502dfbb4a 100644
--- a/src/core/hle/service/usb/usb.cpp
+++ b/src/core/hle/service/usb/usb.cpp
@@ -6,7 +6,6 @@
#include "common/logging/log.h"
#include "core/hle/ipc_helpers.h"
-#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/service.h"
#include "core/hle/service/sm/sm.h"
#include "core/hle/service/usb/usb.h"
@@ -97,7 +96,7 @@ public:
{3, nullptr, "GetAlternateInterface"},
{4, nullptr, "GetCurrentFrame"},
{5, nullptr, "CtrlXferAsync"},
- {6, nullptr, "Unknown6"},
+ {6, nullptr, "GetCtrlXferCompletionEvent"},
{7, nullptr, "GetCtrlXferReport"},
{8, nullptr, "ResetDevice"},
{9, nullptr, "OpenUsbEp"},
@@ -183,8 +182,8 @@ public:
{4, nullptr, "GetHostPdcFirmwareRevision"},
{5, nullptr, "GetHostPdcManufactureId"},
{6, nullptr, "GetHostPdcDeviceId"},
- {7, nullptr, "AwakeCradle"},
- {8, nullptr, "SleepCradle"},
+ {7, nullptr, "EnableCradleRecovery"},
+ {8, nullptr, "DisableCradleRecovery"},
};
// clang-format on
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 8e8fc40ca..439e7e472 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -524,7 +524,9 @@ private:
Disconnect = 11,
AllocateBuffers = 13,
- SetPreallocatedBuffer = 14
+ SetPreallocatedBuffer = 14,
+
+ GetBufferHistory = 17
};
void TransactParcel(Kernel::HLERequestContext& ctx) {
@@ -641,6 +643,14 @@ private:
ctx.WriteBuffer(response.Serialize());
break;
}
+ case TransactionId::GetBufferHistory: {
+ LOG_WARNING(Service_VI, "(STUBBED) called, transaction=GetBufferHistory");
+ [[maybe_unused]] const auto buffer = ctx.ReadBuffer();
+
+ IGBPEmptyResponseParcel response{};
+ ctx.WriteBuffer(response.Serialize());
+ break;
+ }
default:
ASSERT_MSG(false, "Unimplemented");
}
@@ -831,6 +841,7 @@ public:
{6010, nullptr, "GetLayerPresentationAllFencesExpiredEvent"},
{6011, nullptr, "EnableLayerAutoClearTransitionBuffer"},
{6012, nullptr, "DisableLayerAutoClearTransitionBuffer"},
+ {6013, nullptr, "SetLayerOpacity"},
{7000, nullptr, "SetContentVisibility"},
{8000, nullptr, "SetConductorLayer"},
{8001, nullptr, "SetTimestampTracking"},
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h
index eec531d54..2fd7f8e61 100644
--- a/src/core/hle/service/vi/vi.h
+++ b/src/core/hle/service/vi/vi.h
@@ -4,7 +4,6 @@
#pragma once
-#include <memory>
#include "common/common_types.h"
namespace Core {
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index 51c4dea26..88d6ec908 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -587,7 +587,11 @@ void Memory::UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) {
bool Memory::IsValidVirtualAddress(const VAddr vaddr) const {
const Kernel::KProcess& process = *system.CurrentProcess();
const auto& page_table = process.PageTable().PageTableImpl();
- const auto [pointer, type] = page_table.pointers[vaddr >> PAGE_BITS].PointerType();
+ const size_t page = vaddr >> PAGE_BITS;
+ if (page >= page_table.pointers.size()) {
+ return false;
+ }
+ const auto [pointer, type] = page_table.pointers[page].PointerType();
return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory;
}
diff --git a/src/core/network/network.cpp b/src/core/network/network.cpp
index 72eea52f0..a3e0664b9 100644
--- a/src/core/network/network.cpp
+++ b/src/core/network/network.cpp
@@ -366,8 +366,6 @@ std::optional<IPv4Address> GetHostIPv4Address() {
if (res != network_interfaces.end()) {
char ip_addr[16] = {};
ASSERT(inet_ntop(AF_INET, &res->ip_address, ip_addr, sizeof(ip_addr)) != nullptr);
- LOG_INFO(Network, "IP address: {}", ip_addr);
-
return TranslateIPv4(res->ip_address);
} else {
LOG_ERROR(Network, "Couldn't find selected interface \"{}\"", selected_network_interface);