From 330eac9be6b76856c254122d565c58f4b326ac99 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 21 May 2026 18:10:18 +0000 Subject: [PATCH 01/19] [hle, core/loader] remove hbl.nsp specific workaround Signed-off-by: lizzie --- src/core/hle/kernel/k_process.cpp | 4 +--- src/core/hle/kernel/k_process.h | 8 +------- src/core/hle/kernel/svc/svc_exception.cpp | 7 ++++--- src/core/loader/deconstructed_rom_directory.cpp | 17 ++++++++++------- src/core/loader/deconstructed_rom_directory.h | 12 +++++------- src/core/loader/kip.cpp | 2 +- src/core/loader/nro.cpp | 2 +- src/core/loader/nsp.cpp | 3 +-- src/yuzu/main_window.cpp | 2 +- 9 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 70e578f22a..364f44849b 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -1174,8 +1174,7 @@ KProcess::KProcess(KernelCore& kernel) KProcess::~KProcess() = default; -Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, - KProcessAddress aslr_space_start, size_t aslr_space_offset, bool is_hbl) { +Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, KProcessAddress aslr_space_start, size_t aslr_space_offset) { // Create a resource limit for the process. const auto pool = static_cast(metadata.GetPoolPartition()); const auto physical_memory_size = m_kernel.MemoryManager().GetSize(pool); @@ -1247,7 +1246,6 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std: aslr_space_start)); // Assign remaining properties. - m_is_hbl = is_hbl; m_ideal_core_id = metadata.GetMainThreadCore(); // Set up emulation context. diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 975448f0dd..b3922444cc 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -133,7 +133,6 @@ private: bool m_is_initialized : 1 = false; bool m_is_application : 1 = false; bool m_is_default_application_system_resource : 1 = false; - bool m_is_hbl : 1 = false; bool m_is_suspended : 1 = false; bool m_is_immortal : 1 = false; bool m_is_handle_table_initialized : 1 = false; @@ -277,10 +276,6 @@ public: return m_capabilities.CanForceDebug(); } - bool IsHbl() const { - return m_is_hbl; - } - u32 GetAllocateOption() const { return m_page_table.GetAllocateOption(); } @@ -514,8 +509,7 @@ public: } public: - Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, - KProcessAddress aslr_space_start, size_t aslr_space_offset, bool is_hbl); + Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, KProcessAddress aslr_space_start, size_t aslr_space_offset); void LoadModule(CodeSet code_set, KProcessAddress base_addr); diff --git a/src/core/hle/kernel/svc/svc_exception.cpp b/src/core/hle/kernel/svc/svc_exception.cpp index 47b7568288..bf09641bad 100644 --- a/src/core/hle/kernel/svc/svc_exception.cpp +++ b/src/core/hle/kernel/svc/svc_exception.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -106,9 +109,7 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) { system.CurrentPhysicalCore().LogBacktrace(); } - const bool is_hbl = GetCurrentProcess(system.Kernel()).IsHbl(); - const bool should_break = is_hbl || !notification_only; - + const bool should_break = !notification_only; if (system.DebuggerEnabled() && should_break) { auto* thread = system.Kernel().GetCurrentEmuThread(); system.GetDebugger().NotifyThreadStopped(thread); diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index afa5cdbc36..74b2ff7018 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -71,9 +71,10 @@ struct PatchCollection { std::array module_patcher_indices{}; }; -AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_, - bool override_update_) - : AppLoader(std::move(file_)), override_update(override_update_), is_hbl(false) { +AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_, bool override_update_) + : AppLoader(std::move(file_)) + , override_update(override_update_) +{ const auto file_dir = file->GetContainingDirectory(); // Title ID @@ -124,9 +125,11 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys } AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory( - FileSys::VirtualDir directory, bool override_update_, bool is_hbl_) - : AppLoader(directory->GetFile("main")), dir(std::move(directory)), - override_update(override_update_), is_hbl(is_hbl_) {} + FileSys::VirtualDir directory, bool override_update_) + : AppLoader(directory->GetFile("main")) + , dir(std::move(directory)) + , override_update(override_update_) +{} FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& dir_file) { if (FileSys::IsDirectoryExeFS(dir_file->GetContainingDirectory())) { @@ -232,7 +235,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect ? ::Settings::values.rng_seed.GetValue() : Common::Random::Random64(0)) << 12) & 0xfff000; // Setup the process code layout - if (process.LoadFromMetadata(metadata, code_size, fastmem_base, aslr_offset, is_hbl).IsError()) { + if (process.LoadFromMetadata(metadata, code_size, fastmem_base, aslr_offset).IsError()) { return {ResultStatus::ErrorUnableToParseKernelMetadata, {}}; } diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index 1e9f765c9d..7283db0662 100644 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -22,13 +25,9 @@ namespace Loader { */ class AppLoader_DeconstructedRomDirectory final : public AppLoader { public: - explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file, - bool override_update_ = false); - + explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file, bool override_update_ = false); // Overload to accept exefs directory. Must contain 'main' and 'main.npdm' - explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory, - bool override_update_ = false, - bool is_hbl_ = false); + explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory, bool override_update_ = false); /** * Identifies whether or not the given file is a deconstructed ROM directory. @@ -63,7 +62,6 @@ private: std::string name; u64 title_id{}; bool override_update; - bool is_hbl; Modules modules; }; diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp index 978ffed2b9..fdfbac0a20 100644 --- a/src/core/loader/kip.cpp +++ b/src/core/loader/kip.cpp @@ -93,7 +93,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process, ? ::Settings::values.rng_seed.GetValue() : Common::Random::Random64(0)) << 12) & 0xfff000; // Setup the process code layout - if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), codeset.memory.size(), 0, aslr_offset, false).IsError()) { + if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), codeset.memory.size(), 0, aslr_offset).IsError()) { return {ResultStatus::ErrorNotInitialized, {}}; } const VAddr base_address = GetInteger(process.GetEntryPoint()); diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 738d805149..866059286a 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -247,7 +247,7 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process, // Setup the process code layout if (process - .LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), image_size, fastmem_base, aslr_offset, false) + .LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), image_size, fastmem_base, aslr_offset) .IsError()) { return false; } diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 4333acb70c..726bb428f6 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -34,8 +34,7 @@ AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file_, } if (nsp->IsExtractedType()) { - secondary_loader = std::make_unique( - nsp->GetExeFS(), false, file->GetName() == "hbl.nsp"); + secondary_loader = std::make_unique(nsp->GetExeFS(), false); } else { const auto control_nca = nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Control); diff --git a/src/yuzu/main_window.cpp b/src/yuzu/main_window.cpp index 4d5a3c43f9..eb93b5b628 100644 --- a/src/yuzu/main_window.cpp +++ b/src/yuzu/main_window.cpp @@ -581,7 +581,7 @@ MainWindow::MainWindow(bool has_broken_vulkan) } else if (should_launch_hlaunch) { std::filesystem::path const sd_dir = Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir); auto const hbl_path = (sd_dir / "atmosphere" / "hbl.nsp").string(); - BootGame(QString::fromStdString(hbl_path), ApplicationAppletParameters()); + BootGame(QString::fromStdString(hbl_path), LibraryAppletParameters(0x010000000000100Dull, Service::AM::AppletId::QLaunch)); } } } From e3adbde518e4d72411a51ad47bd88ea8765f4133 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 21 May 2026 21:02:59 +0000 Subject: [PATCH 02/19] implement stubs for i2c + gpio Signed-off-by: lizzie --- src/core/CMakeLists.txt | 4 +++ src/core/hle/service/apm/apm.cpp | 4 +++ src/core/hle/service/gpio/gpio.cpp | 33 +++++++++++++++++++++ src/core/hle/service/gpio/gpio.h | 15 ++++++++++ src/core/hle/service/i2c/i2c.cpp | 33 +++++++++++++++++++++ src/core/hle/service/i2c/i2c.h | 15 ++++++++++ src/core/hle/service/ptm/psm.cpp | 46 +++++++++++++++++++++++++++++- src/core/hle/service/ptm/psm.h | 4 +-- src/core/hle/service/services.cpp | 8 ++++-- 9 files changed, 157 insertions(+), 5 deletions(-) create mode 100644 src/core/hle/service/gpio/gpio.cpp create mode 100644 src/core/hle/service/gpio/gpio.h create mode 100644 src/core/hle/service/i2c/i2c.cpp create mode 100644 src/core/hle/service/i2c/i2c.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 39aebd5f48..949fde8e06 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1121,6 +1121,10 @@ add_library(core STATIC hle/service/vi/vi_types.h hle/service/vi/vsync_manager.cpp hle/service/vi/vsync_manager.h + hle/service/gpio/gpio.cpp + hle/service/gpio/gpio.h + hle/service/i2c/i2c.cpp + hle/service/i2c/i2c.h internal_network/emu_net_state.cpp internal_network/emu_net_state.h internal_network/network.cpp diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index c23ff293d3..71f895d0e6 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -21,6 +24,7 @@ void LoopProcess(Core::System& system) { "apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); server_manager->RegisterNamedService( "apm:sys", std::make_shared(system, system.GetAPMController())); + ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/gpio/gpio.cpp b/src/core/hle/service/gpio/gpio.cpp new file mode 100644 index 0000000000..fad0d1695b --- /dev/null +++ b/src/core/hle/service/gpio/gpio.cpp @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/core.h" +#include "core/hle/service/i2c/i2c.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::GPIO { + +class GPIO final : public ServiceFramework { +public: + explicit GPIO(Core::System& system_) + : ServiceFramework{system_, "gpio"} + { + static const FunctionInfo functions[] = { + {0, nullptr, "Cmd0"}, + }; + RegisterHandlers(functions); + } + ~GPIO() override = default; +}; + +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + server_manager->RegisterNamedService("gpio", std::make_shared(system)); + ServerManager::RunServer(std::move(server_manager)); +} + +} // namespace Service::GPIO diff --git a/src/core/hle/service/gpio/gpio.h b/src/core/hle/service/gpio/gpio.h new file mode 100644 index 0000000000..57f9a64e56 --- /dev/null +++ b/src/core/hle/service/gpio/gpio.h @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +namespace Core { +class System; +} + +namespace Service::GPIO { +void LoopProcess(Core::System& system); +} // namespace Service::GPIO diff --git a/src/core/hle/service/i2c/i2c.cpp b/src/core/hle/service/i2c/i2c.cpp new file mode 100644 index 0000000000..99decb37f9 --- /dev/null +++ b/src/core/hle/service/i2c/i2c.cpp @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/core.h" +#include "core/hle/service/i2c/i2c.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::I2C { + +class I2C final : public ServiceFramework { +public: + explicit I2C(Core::System& system_) + : ServiceFramework{system_, "i2c"} + { + static const FunctionInfo functions[] = { + {0, nullptr, "Cmd0"}, + }; + RegisterHandlers(functions); + } + ~I2C() override = default; +}; + +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + server_manager->RegisterNamedService("i2c", std::make_shared(system)); + ServerManager::RunServer(std::move(server_manager)); +} + +} // namespace Service::I2C diff --git a/src/core/hle/service/i2c/i2c.h b/src/core/hle/service/i2c/i2c.h new file mode 100644 index 0000000000..c26df8e86f --- /dev/null +++ b/src/core/hle/service/i2c/i2c.h @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +namespace Core { +class System; +} + +namespace Service::I2C { +void LoopProcess(Core::System& system); +} // namespace Service::I2C diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp index f144b8e497..ace11dd501 100644 --- a/src/core/hle/service/ptm/psm.cpp +++ b/src/core/hle/service/ptm/psm.cpp @@ -6,10 +6,12 @@ #include +#include "common/common_funcs.h" #include "common/device_power_state.h" #include "common/logging.h" #include "core/core.h" #include "core/hle/kernel/k_event.h" +#include "core/hle/result.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/ptm/psm.h" @@ -139,7 +141,7 @@ PSM::PSM(Core::System& system_) : ServiceFramework{system_, "psm"} { {14, nullptr, "IsEnoughPowerSupplied"}, {15, nullptr, "GetBatteryAgePercentage"}, {16, nullptr, "GetBatteryChargeInfoEvent"}, - {17, nullptr, "GetBatteryChargeInfoFields"}, + {17, &PSM::GetBatteryChargeInfoFields, "GetBatteryChargeInfoFields"}, {18, nullptr, "GetBatteryChargeCalibratedEvent"}, }; // clang-format on @@ -187,4 +189,46 @@ void PSM::OpenSession(HLERequestContext& ctx) { rb.PushIpcInterface(system); } +struct BatteryChargeInfoFields { + u32 input_current_limit; //mA + u32 boost_mode_current_limit; + u32 fast_charge_current_limit; + u32 charge_voltage_limit; + u32 charger_type; + u8 hi2_mode; + u8 battery_charging; + INSERT_PADDING_BYTES_NOINIT(2); + u32 vdd50_state; + u32 temperature_celcius; + u32 battery_charge_percentage; + u32 battery_charge_milli_voltage; + u32 battery_age_percentage; + u32 usb_power_role; + u32 usb_charger_type; + u32 charger_input_voltage_limit; + u32 charger_input_current_limit; + u8 fast_battery_charging; + u8 controller_power_supply; + u8 otg_request; + INSERT_PADDING_BYTES_NOINIT(1); + INSERT_PADDING_BYTES_NOINIT(0x14); //[+17.0.0] +}; +static_assert(sizeof(struct BatteryChargeInfoFields) == 0x54); + +void PSM::GetBatteryChargeInfoFields(HLERequestContext& ctx) { + LOG_DEBUG(Service_PTM, "called"); + Common::PowerStatus power_status = Common::GetPowerStatus(); + + BatteryChargeInfoFields r{}; + r.battery_charge_percentage = power_status.percentage; //100% + r.battery_age_percentage = power_status.percentage; //100% + r.battery_charging = power_status.charging ? 1 : 0; + r.charger_type = u32(power_status.has_battery && power_status.charging + ? ChargerType::RegularCharger : ChargerType::Unplugged); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushRaw(r); +} + } // namespace Service::PTM diff --git a/src/core/hle/service/ptm/psm.h b/src/core/hle/service/ptm/psm.h index 2853a45753..1e4aa72dee 100644 --- a/src/core/hle/service/ptm/psm.h +++ b/src/core/hle/service/ptm/psm.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project @@ -22,10 +22,10 @@ private: LowPowerCharger = 2, Unknown = 3, }; - void GetBatteryChargePercentage(HLERequestContext& ctx); void GetChargerType(HLERequestContext& ctx); void OpenSession(HLERequestContext& ctx); + void GetBatteryChargeInfoFields(HLERequestContext& ctx); }; } // namespace Service::PTM diff --git a/src/core/hle/service/services.cpp b/src/core/hle/service/services.cpp index 636f54ad49..4dfdf9068f 100644 --- a/src/core/hle/service/services.cpp +++ b/src/core/hle/service/services.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project @@ -25,8 +25,10 @@ #include "core/hle/service/friend/friend.h" #include "core/hle/service/glue/glue.h" #include "core/hle/service/grc/grc.h" +#include "core/hle/service/gpio/gpio.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/i2c/i2c.h" #include "core/hle/service/jit/jit.h" #include "core/hle/service/lbl/lbl.h" #include "core/hle/service/ldn/ldn.h" @@ -144,7 +146,9 @@ Services::Services(std::shared_ptr& sm, Core::System& system {"ro", &RO::LoopProcess}, {"spl", &SPL::LoopProcess}, {"ssl", &SSL::LoopProcess}, - {"usb", &USB::LoopProcess} + {"usb", &USB::LoopProcess}, + {"i2c", &I2C::LoopProcess}, + {"gpio", &GPIO::LoopProcess}, }) kernel.RunOnGuestCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); }); } From 8b6bbee7491daa2472c1a11ab79f7fb9c3d36782 Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 20 May 2026 08:39:07 +0000 Subject: [PATCH 03/19] + stubbed services --- src/core/hle/service/btm/btm_system_core.cpp | 7 ++- src/core/hle/service/btm/btm_system_core.h | 5 +- .../service/set/system_settings_server.cpp | 55 ++++++++++++++++--- .../hle/service/set/system_settings_server.h | 6 ++ 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/core/hle/service/btm/btm_system_core.cpp b/src/core/hle/service/btm/btm_system_core.cpp index f1e623be16..318657fc32 100644 --- a/src/core/hle/service/btm/btm_system_core.cpp +++ b/src/core/hle/service/btm/btm_system_core.cpp @@ -29,7 +29,7 @@ IBtmSystemCore::IBtmSystemCore(Core::System& system_) {10, nullptr, "StartAudioDeviceDiscovery"}, {11, nullptr, "StopAudioDeviceDiscovery"}, {12, nullptr, "IsDiscoveryingAudioDevice"}, - {13, nullptr, "GetDiscoveredAudioDevice"}, + {13, C<&IBtmSystemCore::GetDiscoveredAudioDevice>, "GetDiscoveredAudioDevice"}, {14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"}, {15, nullptr, "ConnectAudioDevice"}, {16, nullptr, "IsConnectingAudioDevice"}, @@ -93,6 +93,11 @@ Result IBtmSystemCore::AcquireRadioEvent(Out out_is_valid, R_SUCCEED(); } +Result IBtmSystemCore::GetDiscoveredAudioDevice(OutArray, BufferAttr_HipcPointer> out_audio_devices, s32 count, Out out_total) { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + R_SUCCEED(); +} + Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent( OutCopyHandle out_event) { LOG_WARNING(Service_BTM, "(STUBBED) called"); diff --git a/src/core/hle/service/btm/btm_system_core.h b/src/core/hle/service/btm/btm_system_core.h index 06498b21ea..c390627f28 100644 --- a/src/core/hle/service/btm/btm_system_core.h +++ b/src/core/hle/service/btm/btm_system_core.h @@ -34,9 +34,8 @@ private: Result DisableRadio(); Result IsRadioEnabled(Out out_is_enabled); - Result AcquireRadioEvent(Out out_is_valid, - OutCopyHandle out_event); - + Result AcquireRadioEvent(Out out_is_valid, OutCopyHandle out_event); + Result GetDiscoveredAudioDevice(OutArray, BufferAttr_HipcPointer> out_audio_devices, s32 count, Out out_total); Result AcquireAudioDeviceConnectionEvent(OutCopyHandle out_event); Result GetConnectedAudioDevices( diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index 0ed6d28dd4..7fa74e6689 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -142,10 +142,10 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {22, C<&ISystemSettingsServer::SetEulaVersions>, "SetEulaVersions"}, {23, C<&ISystemSettingsServer::GetColorSetId>, "GetColorSetId"}, {24, C<&ISystemSettingsServer::SetColorSetId>, "SetColorSetId"}, - {25, nullptr, "GetConsoleInformationUploadFlag"}, - {26, nullptr, "SetConsoleInformationUploadFlag"}, - {27, nullptr, "GetAutomaticApplicationDownloadFlag"}, - {28, nullptr, "SetAutomaticApplicationDownloadFlag"}, + {25, C<&ISystemSettingsServer::GetConsoleInformationUploadFlag>, "GetConsoleInformationUploadFlag"}, + {26, C<&ISystemSettingsServer::SetConsoleInformationUploadFlag>, "SetConsoleInformationUploadFlag"}, + {27, C<&ISystemSettingsServer::GetAutomaticApplicationDownloadFlag>, "GetAutomaticApplicationDownloadFlag"}, + {28, C<&ISystemSettingsServer::SetAutomaticApplicationDownloadFlag>, "SetAutomaticApplicationDownloadFlag"}, {29, C<&ISystemSettingsServer::GetNotificationSettings>, "GetNotificationSettings"}, {30, C<&ISystemSettingsServer::SetNotificationSettings>, "SetNotificationSettings"}, {31, C<&ISystemSettingsServer::GetAccountNotificationSettings>, "GetAccountNotificationSettings"}, @@ -160,8 +160,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {42, nullptr, "SetEdid"}, {43, C<&ISystemSettingsServer::GetAudioOutputMode>, "GetAudioOutputMode"}, {44, C<&ISystemSettingsServer::SetAudioOutputMode>, "SetAudioOutputMode"}, - {45, C<&ISystemSettingsServer::GetSpeakerAutoMuteFlag> , "GetSpeakerAutoMuteFlag"}, - {46, C<&ISystemSettingsServer::SetSpeakerAutoMuteFlag> , "SetSpeakerAutoMuteFlag"}, + {45, C<&ISystemSettingsServer::GetSpeakerAutoMuteFlag>, "GetSpeakerAutoMuteFlag"}, + {46, C<&ISystemSettingsServer::SetSpeakerAutoMuteFlag>, "SetSpeakerAutoMuteFlag"}, {47, C<&ISystemSettingsServer::GetQuestFlag>, "GetQuestFlag"}, {48, C<&ISystemSettingsServer::SetQuestFlag>, "SetQuestFlag"}, {49, nullptr, "GetDataDeletionSettings"}, @@ -180,8 +180,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {62, C<&ISystemSettingsServer::GetDebugModeFlag>, "GetDebugModeFlag"}, {63, C<&ISystemSettingsServer::GetPrimaryAlbumStorage>, "GetPrimaryAlbumStorage"}, {64, C<&ISystemSettingsServer::SetPrimaryAlbumStorage>, "SetPrimaryAlbumStorage"}, - {65, nullptr, "GetUsb30EnableFlag"}, - {66, nullptr, "SetUsb30EnableFlag"}, + {65, C<&ISystemSettingsServer::GetUsb30EnableFlag>, "GetUsb30EnableFlag"}, + {66, C<&ISystemSettingsServer::SetUsb30EnableFlag>, "SetUsb30EnableFlag"}, {67, C<&ISystemSettingsServer::GetBatteryLot>, "GetBatteryLot"}, {68, C<&ISystemSettingsServer::GetSerialNumber>, "GetSerialNumber"}, {69, C<&ISystemSettingsServer::GetNfcEnableFlag>, "GetNfcEnableFlag"}, @@ -1074,6 +1074,45 @@ Result ISystemSettingsServer::SetNfcEnableFlag(bool nfc_enable_flag) { R_SUCCEED(); } +Result ISystemSettingsServer::GetConsoleInformationUploadFlag(Out out_flag) { + LOG_INFO(Service_SET, "called {}", m_system_settings.console_information_upload_flag); + *out_flag = m_system_settings.console_information_upload_flag; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetConsoleInformationUploadFlag(bool flag) { + LOG_INFO(Service_SET, "called {}", flag); + m_system_settings.usb_30_enable_flag = flag; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetAutomaticApplicationDownloadFlag(Out out_flag) { + LOG_INFO(Service_SET, "called {}", m_system_settings.usb_30_enable_flag); + *out_flag = m_system_settings.automatic_application_download_flag; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetAutomaticApplicationDownloadFlag(bool flag) { + LOG_INFO(Service_SET, "called {}", flag); + m_system_settings.automatic_application_download_flag = flag; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetUsb30EnableFlag(Out out_usb30_enable_flag) { + LOG_INFO(Service_SET, "called, usb30_enable_flag={}", m_system_settings.usb_30_enable_flag); + *out_usb30_enable_flag = m_system_settings.usb_30_enable_flag; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetUsb30EnableFlag(bool usb30_enable_flag) { + LOG_INFO(Service_SET, "called, usb30_enable_flag={}", usb30_enable_flag); + m_system_settings.usb_30_enable_flag = usb30_enable_flag; + SetSaveNeeded(); + R_SUCCEED(); +} + Result ISystemSettingsServer::GetSleepSettings(Out out_sleep_settings) { LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}", m_system_settings.sleep_settings.flags.raw, diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h index 2a160dfc6b..1d56e61f88 100644 --- a/src/core/hle/service/set/system_settings_server.h +++ b/src/core/hle/service/set/system_settings_server.h @@ -109,6 +109,12 @@ public: Result SetPrimaryAlbumStorage(PrimaryAlbumStorage primary_album_storage); Result GetBatteryLot(Out out_battery_lot); Result GetSerialNumber(Out out_console_serial); + Result GetConsoleInformationUploadFlag(Out out_flag); + Result SetConsoleInformationUploadFlag(bool flag); + Result GetAutomaticApplicationDownloadFlag(Out out_flag); + Result SetAutomaticApplicationDownloadFlag(bool flag); + Result GetUsb30EnableFlag(Out out_usb30_enable_flag); + Result SetUsb30EnableFlag(bool usb30_enable_flag); Result GetNfcEnableFlag(Out out_nfc_enable_flag); Result SetNfcEnableFlag(bool nfc_enable_flag); Result GetSleepSettings(Out out_sleep_settings); From aba37aa510ba7eebf0eb3c48d301366f2b7eb529 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 21 May 2026 21:30:41 +0000 Subject: [PATCH 04/19] extra battery states --- src/core/hle/service/btm/btm_system_core.h | 3 ++ src/core/hle/service/ptm/psm.cpp | 32 +++++++++++++++++----- src/core/hle/service/ptm/psm.h | 2 ++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/core/hle/service/btm/btm_system_core.h b/src/core/hle/service/btm/btm_system_core.h index c390627f28..3fc4c0d56c 100644 --- a/src/core/hle/service/btm/btm_system_core.h +++ b/src/core/hle/service/btm/btm_system_core.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp index ace11dd501..06396bbb4c 100644 --- a/src/core/hle/service/ptm/psm.cpp +++ b/src/core/hle/service/ptm/psm.cpp @@ -136,10 +136,10 @@ PSM::PSM(Core::System& system_) : ServiceFramework{system_, "psm"} { {9, nullptr, "DisableEnoughPowerChargeEmulation"}, {10, nullptr, "EnableFastBatteryCharging"}, {11, nullptr, "DisableFastBatteryCharging"}, - {12, nullptr, "GetBatteryVoltageState"}, + {12, &PSM::GetBatteryVoltageState, "GetBatteryVoltageState"}, {13, nullptr, "GetRawBatteryChargePercentage"}, {14, nullptr, "IsEnoughPowerSupplied"}, - {15, nullptr, "GetBatteryAgePercentage"}, + {15, &PSM::GetBatteryAgePercentage, "GetBatteryAgePercentage"}, {16, nullptr, "GetBatteryChargeInfoEvent"}, {17, &PSM::GetBatteryChargeInfoFields, "GetBatteryChargeInfoFields"}, {18, nullptr, "GetBatteryChargeCalibratedEvent"}, @@ -189,6 +189,20 @@ void PSM::OpenSession(HLERequestContext& ctx) { rb.PushIpcInterface(system); } +void PSM::GetBatteryVoltageState(HLERequestContext& ctx) { + LOG_DEBUG(Service_PTM, "(stubbed)"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushRaw(0); // +} + +void PSM::GetBatteryAgePercentage(HLERequestContext& ctx) { + LOG_DEBUG(Service_PTM, "(stubbed)"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushRaw(1.f); +} + struct BatteryChargeInfoFields { u32 input_current_limit; //mA u32 boost_mode_current_limit; @@ -200,9 +214,9 @@ struct BatteryChargeInfoFields { INSERT_PADDING_BYTES_NOINIT(2); u32 vdd50_state; u32 temperature_celcius; - u32 battery_charge_percentage; + f32 battery_charge_percentage; u32 battery_charge_milli_voltage; - u32 battery_age_percentage; + f32 battery_age_percentage; u32 usb_power_role; u32 usb_charger_type; u32 charger_input_voltage_limit; @@ -214,17 +228,21 @@ struct BatteryChargeInfoFields { INSERT_PADDING_BYTES_NOINIT(0x14); //[+17.0.0] }; static_assert(sizeof(struct BatteryChargeInfoFields) == 0x54); - void PSM::GetBatteryChargeInfoFields(HLERequestContext& ctx) { LOG_DEBUG(Service_PTM, "called"); Common::PowerStatus power_status = Common::GetPowerStatus(); BatteryChargeInfoFields r{}; - r.battery_charge_percentage = power_status.percentage; //100% - r.battery_age_percentage = power_status.percentage; //100% + r.battery_charge_percentage = f32(power_status.percentage); //100% + r.battery_age_percentage = f32(power_status.percentage); //100% r.battery_charging = power_status.charging ? 1 : 0; r.charger_type = u32(power_status.has_battery && power_status.charging ? ChargerType::RegularCharger : ChargerType::Unplugged); + r.charger_input_voltage_limit = 100; + r.charger_input_voltage_limit = 100; + r.input_current_limit = 100; + r.boost_mode_current_limit = 100; + r.fast_charge_current_limit = 100; IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); diff --git a/src/core/hle/service/ptm/psm.h b/src/core/hle/service/ptm/psm.h index 1e4aa72dee..77c38d1f9b 100644 --- a/src/core/hle/service/ptm/psm.h +++ b/src/core/hle/service/ptm/psm.h @@ -25,6 +25,8 @@ private: void GetBatteryChargePercentage(HLERequestContext& ctx); void GetChargerType(HLERequestContext& ctx); void OpenSession(HLERequestContext& ctx); + void GetBatteryVoltageState(HLERequestContext& ctx); + void GetBatteryAgePercentage(HLERequestContext& ctx); void GetBatteryChargeInfoFields(HLERequestContext& ctx); }; From bb075c1331d0efb8104f95afc9d621cf7cb70f58 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 21 May 2026 21:30:47 +0000 Subject: [PATCH 05/19] apm:p --- src/core/hle/service/apm/apm.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 71f895d0e6..2496b132ad 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -18,12 +18,10 @@ void LoopProcess(Core::System& system) { auto module = std::make_shared(); auto server_manager = std::make_unique(system); - server_manager->RegisterNamedService( - "apm", std::make_shared(system, module, system.GetAPMController(), "apm")); - server_manager->RegisterNamedService( - "apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); - server_manager->RegisterNamedService( - "apm:sys", std::make_shared(system, system.GetAPMController())); + server_manager->RegisterNamedService("apm", std::make_shared(system, module, system.GetAPMController(), "apm")); + server_manager->RegisterNamedService("apm:p", std::make_shared(system, module, system.GetAPMController(), "apm:p")); + server_manager->RegisterNamedService("apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); + server_manager->RegisterNamedService("apm:sys", std::make_shared(system, system.GetAPMController())); ServerManager::RunServer(std::move(server_manager)); } From f9d5e6bac0d48408711de705f9febd72c406542d Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 19 May 2026 06:50:54 +0000 Subject: [PATCH 06/19] [hle/service{nvdrv,apm}] fixes for TetrisSwitch Signed-off-by: lizzie --- src/core/hle/service/apm/apm.cpp | 4 +-- .../service/nvdrv/devices/nvdisp_disp0.cpp | 4 ++- src/core/hle/service/nvnflinger/ui/fence.h | 8 ++--- src/hid_core/resources/npad/npad.cpp | 5 +++ src/video_core/gpu.cpp | 35 +++++++++---------- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 2496b132ad..d73d08cb72 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -19,10 +19,10 @@ void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); server_manager->RegisterNamedService("apm", std::make_shared(system, module, system.GetAPMController(), "apm")); - server_manager->RegisterNamedService("apm:p", std::make_shared(system, module, system.GetAPMController(), "apm:p")); server_manager->RegisterNamedService("apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); + // Removed on [+8.0.0] but kept for compatibility + server_manager->RegisterNamedService("apm:p", std::make_shared(system, module, system.GetAPMController(), "apm:p")); server_manager->RegisterNamedService("apm:sys", std::make_shared(system, system.GetAPMController())); - ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index f26f5347eb..bdbb16ed04 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -79,7 +79,9 @@ void nvdisp_disp0::Composite(std::span sorted_layers }); for (size_t i = 0; i < layer.acquire_fence.num_fences; i++) { - output_fences.push_back(layer.acquire_fence.fences[i]); + if (layer.acquire_fence.fences[i].id >= 0) { + output_fences.push_back(layer.acquire_fence.fences[i]); + } } } diff --git a/src/core/hle/service/nvnflinger/ui/fence.h b/src/core/hle/service/nvnflinger/ui/fence.h index 177aed7580..261eb51669 100644 --- a/src/core/hle/service/nvnflinger/ui/fence.h +++ b/src/core/hle/service/nvnflinger/ui/fence.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2012 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -15,10 +18,8 @@ namespace Service::android { class Fence { public: - constexpr Fence() = default; - static constexpr Fence NoFence() { - Fence fence; + Fence fence{}; fence.fences[0].id = -1; fence.fences[1].id = -1; fence.fences[2].id = -1; @@ -26,7 +27,6 @@ public: return fence; } -public: u32 num_fences{}; std::array fences{}; }; diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp index 3a191f4539..4710342848 100644 --- a/src/hid_core/resources/npad/npad.cpp +++ b/src/hid_core/resources/npad/npad.cpp @@ -712,6 +712,11 @@ bool NPad::SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID: } auto& controller = GetControllerFromNpadIdType(aruid, npad_id); + if (!controller.shared_memory) { + LOG_WARNING(Service_HID, "shared_memory is null for npad_id={}", npad_id); + return false; + } + if (controller.shared_memory->assignment_mode != assignment_mode) { controller.shared_memory->assignment_mode = assignment_mode; } diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 5f4054212f..391ca4ef5f 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -303,26 +303,25 @@ struct GPU::Impl { free_swap_counters.pop_front(); } } - const auto wait_fence = - RequestSyncOperation([this, current_request_counter, &layers, &fences, num_fences] { - auto& syncpoint_manager = host1x.GetSyncpointManager(); - if (num_fences == 0) { - renderer->Composite(layers); - } - const auto executer = [this, current_request_counter, layers_copy = layers]() { - { - std::unique_lock lk(request_swap_mutex); - if (--request_swap_counters[current_request_counter] != 0) { - return; - } - free_swap_counters.push_back(current_request_counter); + const auto wait_fence = RequestSyncOperation([this, current_request_counter, &layers, &fences, num_fences] { + auto& syncpoint_manager = host1x.GetSyncpointManager(); + if (num_fences == 0) { + renderer->Composite(layers); + } + const auto executer = [this, current_request_counter, layers_copy = layers]() { + { + std::unique_lock lk(request_swap_mutex); + if (--request_swap_counters[current_request_counter] != 0) { + return; } - renderer->Composite(layers_copy); - }; - for (size_t i = 0; i < num_fences; i++) { - syncpoint_manager.RegisterGuestAction(fences[i].id, fences[i].value, executer); + free_swap_counters.push_back(current_request_counter); } - }); + renderer->Composite(layers_copy); + }; + for (size_t i = 0; i < num_fences; i++) { + syncpoint_manager.RegisterGuestAction(fences[i].id, fences[i].value, executer); + } + }); gpu_thread.TickGPU(); WaitForSyncOperation(wait_fence); } From 61739b1359d06b86533be38c7510ffb52efb47d8 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 22 May 2026 00:34:25 +0000 Subject: [PATCH 07/19] i2c --- src/core/hle/service/i2c/i2c.cpp | 45 +++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/i2c/i2c.cpp b/src/core/hle/service/i2c/i2c.cpp index 99decb37f9..d000487246 100644 --- a/src/core/hle/service/i2c/i2c.cpp +++ b/src/core/hle/service/i2c/i2c.cpp @@ -5,23 +5,66 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/core.h" +#include "core/hle/result.h" #include "core/hle/service/i2c/i2c.h" #include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" +#include "core/hle/service/server_manager.h" namespace Service::I2C { +class I2CSession final : public ServiceFramework { +public: + explicit I2CSession(Core::System& system_) + : ServiceFramework{system_, "I2CSession"} + { + static const FunctionInfo functions[] = { + {0, nullptr, "SendOld"}, + {1, nullptr, "ReceiveOld"}, + {2, nullptr, "ExecuteCommandListOld"}, + {10, C<&I2CSession::Send>, "Send"}, + {11, nullptr, "Receive"}, + {12, nullptr, "ExecuteCommandList"}, + {13, nullptr, "SetRetryPolicy"}, + }; + RegisterHandlers(functions); + } + ~I2CSession() override = default; + + Result Send(InBuffer in_data, u32 transaction_option) { + LOG_WARNING(Service, "(stubbed) topt={}", transaction_option); + R_THROW(ResultUnknown); + } +}; + +enum class I2CDevice : u32 { + ClassicController, + Ftm3bd56, +}; + class I2C final : public ServiceFramework { public: explicit I2C(Core::System& system_) : ServiceFramework{system_, "i2c"} { static const FunctionInfo functions[] = { - {0, nullptr, "Cmd0"}, + {0, nullptr, "OpenSessionForDev"}, + {1, C<&I2C::OpenSession>, "OpenSession"}, + {2, nullptr, "HasDevice"}, + {3, nullptr, "HasDeviceForDev"}, + {4, nullptr, "OpenSession2"}, }; RegisterHandlers(functions); } ~I2C() override = default; + + Result OpenSession(I2CDevice device, OutInterface out_session) { + LOG_DEBUG(Service, "(stubbed)"); + *out_session = std::make_shared(system); + R_SUCCEED(); + } }; void LoopProcess(Core::System& system) { From 04c18b3f89fd0ce181569ca125972c6ed353d380 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 22 May 2026 01:22:10 +0000 Subject: [PATCH 08/19] fx --- src/core/hle/service/am/applet.h | 3 ++- .../hle/service/am/service/application_functions.cpp | 10 +++++++++- .../hle/service/am/service/application_functions.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h index a693a47d7a..1121fe221e 100644 --- a/src/core/hle/service/am/applet.h +++ b/src/core/hle/service/am/applet.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project @@ -83,6 +83,7 @@ struct Applet { // Application functions bool game_play_recording_supported{}; + bool media_playback_state{}; GamePlayRecordingState game_play_recording_state{GamePlayRecordingState::Disabled}; bool jit_service_launched{}; bool application_crash_report_enabled{}; diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index 9ab343e59e..787c88f52d 100644 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp @@ -11,6 +11,7 @@ #include "core/file_sys/registered_cache.h" #include "core/file_sys/savedata_factory.h" #include "core/hle/kernel/k_transfer_memory.h" +#include "core/hle/result.h" #include "core/hle/service/am/am_results.h" #include "core/hle/service/am/applet.h" #include "core/hle/service/am/service/application_functions.h" @@ -56,7 +57,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ {37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"}, {40, D<&IApplicationFunctions::NotifyRunning>, "NotifyRunning"}, {50, D<&IApplicationFunctions::GetPseudoDeviceId>, "GetPseudoDeviceId"}, - {60, nullptr, "SetMediaPlaybackStateForApplication"}, + {60, D<&IApplicationFunctions::SetMediaPlaybackStateForApplication>, "SetMediaPlaybackStateForApplication"}, {65, D<&IApplicationFunctions::IsGamePlayRecordingSupported>, "IsGamePlayRecordingSupported"}, {66, D<&IApplicationFunctions::InitializeGamePlayRecording>, "InitializeGamePlayRecording"}, {67, D<&IApplicationFunctions::SetGamePlayRecordingState>, "SetGamePlayRecordingState"}, @@ -364,6 +365,13 @@ Result IApplicationFunctions::InitializeGamePlayRecording( R_SUCCEED(); } +Result IApplicationFunctions::SetMediaPlaybackStateForApplication(bool enabled) { + LOG_WARNING(Service_AM, "(stubbed) {}", enabled); + std::scoped_lock lk{m_applet->lock}; + m_applet->media_playback_state = enabled; + R_SUCCEED(); +} + Result IApplicationFunctions::SetGamePlayRecordingState( GamePlayRecordingState game_play_recording_state) { LOG_WARNING(Service_AM, "(STUBBED) called"); diff --git a/src/core/hle/service/am/service/application_functions.h b/src/core/hle/service/am/service/application_functions.h index abee2f9d47..b97ed7e25e 100644 --- a/src/core/hle/service/am/service/application_functions.h +++ b/src/core/hle/service/am/service/application_functions.h @@ -53,6 +53,7 @@ private: Result IsGamePlayRecordingSupported(Out out_is_game_play_recording_supported); Result InitializeGamePlayRecording( u64 transfer_memory_size, InCopyHandle transfer_memory_handle); + Result SetMediaPlaybackStateForApplication(bool enabled); Result SetGamePlayRecordingState(GamePlayRecordingState game_play_recording_state); Result EnableApplicationCrashReport(bool enabled); Result InitializeApplicationCopyrightFrameBuffer( From ef03f2c3bbd2d99f0be33549835cc9e92b22c74a Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 22 May 2026 04:05:53 +0000 Subject: [PATCH 09/19] stub nv ctrl-gpu and nvdec debug stuff --- .../hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 8 ++++++++ .../hle/service/nvdrv/devices/nvhost_ctrl_gpu.h | 8 +++++++- .../hle/service/nvdrv/devices/nvhost_nvdec.cpp | 14 ++++++++------ .../service/nvdrv/devices/nvhost_nvdec_common.cpp | 7 +++++++ .../service/nvdrv/devices/nvhost_nvdec_common.h | 7 +++++++ 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index ace1f7e8f7..b621e5d70d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -47,6 +47,8 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span return WrapFixed(this, &nvhost_ctrl_gpu::FlushL2, input, output); case 0x14: return WrapFixed(this, &nvhost_ctrl_gpu::GetActiveSlotMask, input, output); + case 0x15: + return WrapFixed(this, &nvhost_ctrl_gpu::PmuGetGpuLoad, input, output); case 0x1c: return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuTime, input, output); default: @@ -234,6 +236,12 @@ NvResult nvhost_ctrl_gpu::GetActiveSlotMask(IoctlActiveSlotMask& params) { return NvResult::Success; } +NvResult nvhost_ctrl_gpu::PmuGetGpuLoad(IoctlPmuGetLoad& params) { + LOG_WARNING(Service_NVDRV, "(stubbed) called"); + params.pmu_gpu_load = 100; + return NvResult::Success; +} + NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(IoctlZcullGetCtxSize& params) { LOG_DEBUG(Service_NVDRV, "called"); params.size = 0x1; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index e0603f9a71..80b7abd6a1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project @@ -184,6 +184,11 @@ private: }; static_assert(sizeof(IoctlGetCpuTimeCorrelationInfo) == 264); + struct IoctlPmuGetLoad { + u32 pmu_gpu_load; + }; + static_assert(sizeof(IoctlPmuGetLoad) == 4); + NvResult GetCharacteristics1(IoctlCharacteristics& params); NvResult GetCharacteristics3(IoctlCharacteristics& params, std::span gpu_characteristics); @@ -192,6 +197,7 @@ private: NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span tpc_mask); NvResult GetActiveSlotMask(IoctlActiveSlotMask& params); + NvResult PmuGetGpuLoad(IoctlPmuGetLoad& params); NvResult ZCullGetCtxSize(IoctlZcullGetCtxSize& params); NvResult ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params); NvResult ZBCSetTable(IoctlZbcSetTable& params); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index d64658bddc..7ac3dfaa46 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -25,18 +25,20 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span in switch (command.group) { case 0x0: switch (command.cmd) { - case 0x1: + case 0x01: return WrapFixedVariable(this, &nvhost_nvdec::Submit, input, output, fd); - case 0x2: + case 0x02: return WrapFixed(this, &nvhost_nvdec::GetSyncpoint, input, output); - case 0x3: + case 0x03: return WrapFixed(this, &nvhost_nvdec::GetWaitbase, input, output); - case 0x7: + case 0x07: return WrapFixed(this, &nvhost_nvdec::SetSubmitTimeout, input, output); - case 0x9: + case 0x09: return WrapFixedVariable(this, &nvhost_nvdec::MapBuffer, input, output, fd); - case 0xa: + case 0x0a: return WrapFixedVariable(this, &nvhost_nvdec::UnmapBuffer, input, output); + case 0x23: + return WrapFixed(this, &nvhost_nvdec::GetClkRate, input, output); default: break; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index c726d6f93e..698712e152 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -168,6 +168,13 @@ NvResult nvhost_nvdec_common::SetSubmitTimeout(u32 timeout) { return NvResult::Success; } +NvResult nvhost_nvdec_common::GetClkRate(IoctlGetClkRate& params) { + LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + params.clk_rate = 614400000; + params.module_id = 0; + return NvResult::Success; +} + Kernel::KEvent* nvhost_nvdec_common::QueryEvent(u32 event_id) { LOG_CRITICAL(Service_NVDRV, "Unknown HOSTX1 Event {}", event_id); return nullptr; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h index 6b66a0d28d..8b3b7ee285 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h @@ -111,6 +111,12 @@ protected: }; static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size"); + struct IoctlGetClkRate { + u32_le clk_rate{}; + u32_le module_id{}; + }; + static_assert(sizeof(IoctlGetClkRate) == 8); + /// Ioctl command implementations NvResult SetNVMAPfd(IoctlSetNvmapFD&); NvResult Submit(IoctlSubmit& params, std::span input, DeviceFD fd); @@ -119,6 +125,7 @@ protected: NvResult MapBuffer(IoctlMapBuffer& params, std::span entries, DeviceFD fd); NvResult UnmapBuffer(IoctlMapBuffer& params, std::span entries); NvResult SetSubmitTimeout(u32 timeout); + NvResult GetClkRate(IoctlGetClkRate& params); Kernel::KEvent* QueryEvent(u32 event_id) override; From 9b18d0b1113fb2b73acc539d2e4dfae85e511cd4 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 22 May 2026 21:15:31 +0200 Subject: [PATCH 10/19] [tools] refactor, use #!/bin/sh, update license files (#3998) Signed-off-by: lizzie Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3998 Reviewed-by: crueter Reviewed-by: MaranBr --- .ci/license-header.sh | 11 ++++++----- .ci/source.sh | 22 ---------------------- docs/Caveats.md | 2 +- docs/user/SteamROM.md | 2 +- docs/user/ThirdParty.md | 1 + externals/nx_tzdb/tzdb_template.h.in | 3 +++ hooks/pre-commit | 13 +++++++------ shell.nix | 4 ++++ tools/README.md | 2 +- tools/clang-format.sh | 2 +- tools/dtrace-tool.pl | 5 +++-- tools/lanczos-gen.pl | 4 ++-- tools/llvmpipe-run.sh | 5 +++-- tools/optimize-assets.sh | 2 +- tools/stale-translations.sh | 2 +- tools/svc_generator.py | 20 ++++++++++---------- tools/translations/qt-source.sh | 4 ++-- tools/translations/update-translations.sh | 4 ++-- tools/unused-strings.sh | 2 +- tools/windows/install-vulkan-sdk.sh | 2 +- 20 files changed, 51 insertions(+), 61 deletions(-) delete mode 100755 .ci/source.sh mode change 100644 => 100755 shell.nix mode change 100644 => 100755 tools/lanczos-gen.pl diff --git a/.ci/license-header.sh b/.ci/license-header.sh index 6b19f91185..fcc2c1f583 100755 --- a/.ci/license-header.sh +++ b/.ci/license-header.sh @@ -7,7 +7,7 @@ EXCLUDE_FILES="CPM.cmake CPMUtil.cmake GetSCMRev.cmake renderdoc_app.h tools/cpm tools/shellcheck.sh tools/update-cpm.sh tools/windows/vcvarsall.sh externals/stb externals/glad externals/getopt externals/gamemode externals/FidelityFX-FSR externals/demangle externals/bc_decoder externals/cmake-modules" # license header constants, please change when needed :)))) -YEAR=2026 +YEAR=$(date "+%Y") HOLDER="Eden Emulator Project" LICENSE="GPL-3.0-or-later" @@ -112,10 +112,10 @@ for file in $FILES; do [ "$excluded" = "true" ] && continue case "$file" in - *.cmake|*.sh|*CMakeLists.txt) + *.cmake|*.sh|*.ps1|*.py|*.rb|*.perl|*.pl|*.nix|*CMakeLists.txt) begin="#" ;; - *.kt*|*.cpp|*.h|*.qml) + *.kt|*.kts|*.cpp|*.h|*.qml|*.c|*.hpp|*.hxx|*.cxx|*.h.in|*.inc) begin="//" ;; *) @@ -185,11 +185,12 @@ if [ "$UPDATE" = "true" ]; then for file in $SRC_FILES $OTHER_FILES; do case $(basename -- "$file") in - *.cmake|*CMakeLists.txt) + # Windows Powershell wont use shebangs + *.cmake|*.ps1|*CMakeLists.txt) begin="#" shell="false" ;; - *.sh) + *.sh|*.py|*.rb|*.perl|*.pl|*.nix) begin="#" shell=true ;; diff --git a/.ci/source.sh b/.ci/source.sh deleted file mode 100755 index cbdacd1cd7..0000000000 --- a/.ci/source.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash -ex - -# git-archive-all -export PATH="$PATH:/home/$USER/.local/bin" - -GITDATE="`git show -s --date=short --format='%ad' | sed 's/-//g'`" -GITREV="`git show -s --format='%h'`" -REV_NAME="eden-unified-source-${GITDATE}-${GITREV}" - -COMPAT_LIST='dist/compatibility_list/compatibility_list.json' - -mkdir artifacts - -touch "${COMPAT_LIST}" -git describe --abbrev=0 --always HEAD > GIT-COMMIT -git describe --tags HEAD > GIT-TAG || echo 'unknown' > GIT-TAG -git-archive-all --include "${COMPAT_LIST}" --include GIT-COMMIT --include GIT-TAG --force-submodules artifacts/"${REV_NAME}.tar" - -cd artifacts/ -xz -T0 -9 "${REV_NAME}.tar" -sha256sum "${REV_NAME}.tar.xz" > "${REV_NAME}.tar.xz.sha256sum" -cd .. diff --git a/docs/Caveats.md b/docs/Caveats.md index fb86437737..c5b925f4cd 100644 --- a/docs/Caveats.md +++ b/docs/Caveats.md @@ -46,7 +46,7 @@ Qt Widgets appears to be broken. For now, add `-DENABLE_QT=OFF` to your configur This is needed for some dependencies that call cc directly (tz): ```sh -echo '#!/bin/sh' >cc +echo '#!/bin/sh -e' >cc echo 'gcc $@' >>cc chmod +x cc export PATH="$PATH:$PWD" diff --git a/docs/user/SteamROM.md b/docs/user/SteamROM.md index a782b51969..2ea069bf09 100644 --- a/docs/user/SteamROM.md +++ b/docs/user/SteamROM.md @@ -59,7 +59,7 @@ EmuDeck will automatically create an *Emulators - Emulators* parser for ***Steam 4. Paste the following code into the contents of the file, save and close the file. ```bash - #!/bin/bash + #!/bin/sh -e emuName="eden" #parameterize me . "$HOME/.config/EmuDeck/backend/functions/all.sh" diff --git a/docs/user/ThirdParty.md b/docs/user/ThirdParty.md index 5bd72ebe72..1dd359cec3 100644 --- a/docs/user/ThirdParty.md +++ b/docs/user/ThirdParty.md @@ -13,6 +13,7 @@ The main origin repository is always at https://git.eden-emu.dev/eden-emu/eden. - https://github.com/eden-emulator/mirror - https://git.crueter.xyz/mirror/eden +- https://codeberg.org/eden-emu/eden - https://collective.taymaerz.de/eden/eden Other mirrors obviously exist on the internet, but we can't guarantee their reliability and/or availability. diff --git a/externals/nx_tzdb/tzdb_template.h.in b/externals/nx_tzdb/tzdb_template.h.in index d7907b846d..c349a143d5 100644 --- a/externals/nx_tzdb/tzdb_template.h.in +++ b/externals/nx_tzdb/tzdb_template.h.in @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later diff --git a/hooks/pre-commit b/hooks/pre-commit index 484eef1762..b543ff36ab 100755 --- a/hooks/pre-commit +++ b/hooks/pre-commit @@ -1,5 +1,7 @@ -#!/bin/sh +#!/bin/sh -e +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later # SPDX-FileCopyrightText: 2015 Citra Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later @@ -10,20 +12,19 @@ paths_to_check="src/ CMakeLists.txt" # If there are whitespace errors, print the offending file names and fail. if ! git diff --cached --check -- $paths_to_check ; then - cat<` (for `.py`, `.rb`, or `.perl`). Keep scripts POSIX compliant (i.e not require hard `bash` to run, just plain old `sh`). ## Third-Party diff --git a/tools/clang-format.sh b/tools/clang-format.sh index e2857d9723..ca5e6fce39 100755 --- a/tools/clang-format.sh +++ b/tools/clang-format.sh @@ -1,4 +1,4 @@ -#! /bin/sh +#!/bin/sh -e # SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later diff --git a/tools/dtrace-tool.pl b/tools/dtrace-tool.pl index d143d36f3e..693a9e7507 100755 --- a/tools/dtrace-tool.pl +++ b/tools/dtrace-tool.pl @@ -1,5 +1,6 @@ -#!/usr/bin/perl -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +#!/usr/bin/env perl + +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later # Basic script to run dtrace sampling over the program (requires Flamegraph) # Usage is either running as: ./dtrace-tool.sh pid (then input the pid of the process) diff --git a/tools/lanczos-gen.pl b/tools/lanczos-gen.pl old mode 100644 new mode 100755 index 2e26c8c6b9..3eab5cdb10 --- a/tools/lanczos-gen.pl +++ b/tools/lanczos-gen.pl @@ -1,5 +1,5 @@ -#!/usr/bin/perl -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +#!/usr/bin/env perl +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later use strict; use warnings; diff --git a/tools/llvmpipe-run.sh b/tools/llvmpipe-run.sh index c3a5a85d41..f09fe87ef4 100755 --- a/tools/llvmpipe-run.sh +++ b/tools/llvmpipe-run.sh @@ -1,5 +1,6 @@ -#!/bin/sh -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +#!/bin/sh -e + +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later # This script basically allows you to "dirtily" use llvmpipe in any configuration diff --git a/tools/optimize-assets.sh b/tools/optimize-assets.sh index 70fa2375a5..a9b2888648 100755 --- a/tools/optimize-assets.sh +++ b/tools/optimize-assets.sh @@ -1,6 +1,6 @@ #!/bin/sh -e -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later which optipng || exit diff --git a/tools/stale-translations.sh b/tools/stale-translations.sh index 3a9362a252..63ea87b19a 100755 --- a/tools/stale-translations.sh +++ b/tools/stale-translations.sh @@ -1,6 +1,6 @@ #!/bin/sh -e -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later ANDROID=src/android/app/src/main diff --git a/tools/svc_generator.py b/tools/svc_generator.py index d00fe0ba63..9a99c3ba51 100755 --- a/tools/svc_generator.py +++ b/tools/svc_generator.py @@ -1,5 +1,5 @@ -#!/usr/bin/python3 -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +#!/usr/bin/env python3 +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later # SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later @@ -212,7 +212,7 @@ def emit_size_check(): if type != "void": lines.append(f"static_assert(sizeof({type}) == {size});") - return "\n".join(lines) + return f"\n{lines}" # Replaces a type with an arch-specific one, if it exists. @@ -423,7 +423,7 @@ def emit_lines(lines, indent=' '): output_lines.append(line) first = False - return "\n".join(output_lines) + return f"\n{output_lines}" # Emit a C++ function to wrap a guest SVC. @@ -601,7 +601,7 @@ def emit_call(bitness, names, suffix): lines.append(f"{indent}}}") lines.append("}") - return "\n".join(lines) + return f"\n{lines}" def build_fn_declaration(return_type, name, arguments): @@ -623,7 +623,7 @@ def build_enum_declarations(): lines.append(f"{indent}{name} = {hex(imm)},") lines.append("};") - return "\n".join(lines) + return f"\n{lines}" def main(): @@ -665,11 +665,11 @@ def main(): with open("src/core/hle/kernel/svc.h", "w") as f: f.write(COPYRIGHT) f.write(PROLOGUE_H) - f.write("\n".join(svc_fw_declarations)) + f.write(f"\n{svc_fw_declarations}") f.write("\n\n") - f.write("\n".join(arch_fw_declarations[BIT_32])) + f.write(f"\n{arch_fw_declarations[BIT_32]}") f.write("\n\n") - f.write("\n".join(arch_fw_declarations[BIT_64])) + f.write(f"\n{arch_fw_declarations[BIT_64]}") f.write("\n\n") f.write(enum_decls) f.write(EPILOGUE_H) @@ -679,7 +679,7 @@ def main(): f.write(PROLOGUE_CPP) f.write(emit_size_check()) f.write("\n\n") - f.write("\n\n".join(wrapper_fns)) + f.write(f"\n\n{wrapper_fns}") f.write("\n\n") f.write(call_32) f.write("\n\n") diff --git a/tools/translations/qt-source.sh b/tools/translations/qt-source.sh index 89c881d8c0..707ec2783c 100755 --- a/tools/translations/qt-source.sh +++ b/tools/translations/qt-source.sh @@ -1,6 +1,6 @@ -#!/bin/sh +#!/bin/sh -e -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later SOURCES=$(find src/yuzu src/qt_common -type f \( -name "*.ui" -o -name "*.cpp" -o -name "*.h" -o -name "*.plist" \)) diff --git a/tools/translations/update-translations.sh b/tools/translations/update-translations.sh index 8bcd79142f..6ed740140d 100755 --- a/tools/translations/update-translations.sh +++ b/tools/translations/update-translations.sh @@ -1,6 +1,6 @@ -#!/bin/sh +#!/bin/sh -e -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later command -v tx-cli && COMMAND=tx-cli diff --git a/tools/unused-strings.sh b/tools/unused-strings.sh index 1165a203aa..10f6a63565 100755 --- a/tools/unused-strings.sh +++ b/tools/unused-strings.sh @@ -1,6 +1,6 @@ #!/bin/sh -e -# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later ANDROID=src/android/app/src/main diff --git a/tools/windows/install-vulkan-sdk.sh b/tools/windows/install-vulkan-sdk.sh index 0f136748cf..2151363793 100644 --- a/tools/windows/install-vulkan-sdk.sh +++ b/tools/windows/install-vulkan-sdk.sh @@ -1,4 +1,4 @@ -#!/usr/bin/sh +#!/bin/sh -e # SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project # SPDX-License-Identifier: GPL-3.0-or-later From b515dbd5ce347cefe6db723185ae434aeb2e83dd Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 21 May 2026 18:10:18 +0000 Subject: [PATCH 11/19] [hle, core/loader] remove hbl.nsp specific workaround Signed-off-by: lizzie --- src/core/hle/kernel/k_process.cpp | 4 +--- src/core/hle/kernel/k_process.h | 8 +------- src/core/hle/kernel/svc/svc_exception.cpp | 7 ++++--- src/core/loader/deconstructed_rom_directory.cpp | 17 ++++++++++------- src/core/loader/deconstructed_rom_directory.h | 12 +++++------- src/core/loader/kip.cpp | 2 +- src/core/loader/nro.cpp | 2 +- src/core/loader/nsp.cpp | 3 +-- src/yuzu/main_window.cpp | 2 +- 9 files changed, 25 insertions(+), 32 deletions(-) diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 70e578f22a..364f44849b 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -1174,8 +1174,7 @@ KProcess::KProcess(KernelCore& kernel) KProcess::~KProcess() = default; -Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, - KProcessAddress aslr_space_start, size_t aslr_space_offset, bool is_hbl) { +Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, KProcessAddress aslr_space_start, size_t aslr_space_offset) { // Create a resource limit for the process. const auto pool = static_cast(metadata.GetPoolPartition()); const auto physical_memory_size = m_kernel.MemoryManager().GetSize(pool); @@ -1247,7 +1246,6 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std: aslr_space_start)); // Assign remaining properties. - m_is_hbl = is_hbl; m_ideal_core_id = metadata.GetMainThreadCore(); // Set up emulation context. diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 975448f0dd..b3922444cc 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -133,7 +133,6 @@ private: bool m_is_initialized : 1 = false; bool m_is_application : 1 = false; bool m_is_default_application_system_resource : 1 = false; - bool m_is_hbl : 1 = false; bool m_is_suspended : 1 = false; bool m_is_immortal : 1 = false; bool m_is_handle_table_initialized : 1 = false; @@ -277,10 +276,6 @@ public: return m_capabilities.CanForceDebug(); } - bool IsHbl() const { - return m_is_hbl; - } - u32 GetAllocateOption() const { return m_page_table.GetAllocateOption(); } @@ -514,8 +509,7 @@ public: } public: - Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, - KProcessAddress aslr_space_start, size_t aslr_space_offset, bool is_hbl); + Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, KProcessAddress aslr_space_start, size_t aslr_space_offset); void LoadModule(CodeSet code_set, KProcessAddress base_addr); diff --git a/src/core/hle/kernel/svc/svc_exception.cpp b/src/core/hle/kernel/svc/svc_exception.cpp index 47b7568288..bf09641bad 100644 --- a/src/core/hle/kernel/svc/svc_exception.cpp +++ b/src/core/hle/kernel/svc/svc_exception.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -106,9 +109,7 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) { system.CurrentPhysicalCore().LogBacktrace(); } - const bool is_hbl = GetCurrentProcess(system.Kernel()).IsHbl(); - const bool should_break = is_hbl || !notification_only; - + const bool should_break = !notification_only; if (system.DebuggerEnabled() && should_break) { auto* thread = system.Kernel().GetCurrentEmuThread(); system.GetDebugger().NotifyThreadStopped(thread); diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index afa5cdbc36..74b2ff7018 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -71,9 +71,10 @@ struct PatchCollection { std::array module_patcher_indices{}; }; -AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_, - bool override_update_) - : AppLoader(std::move(file_)), override_update(override_update_), is_hbl(false) { +AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile file_, bool override_update_) + : AppLoader(std::move(file_)) + , override_update(override_update_) +{ const auto file_dir = file->GetContainingDirectory(); // Title ID @@ -124,9 +125,11 @@ AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory(FileSys } AppLoader_DeconstructedRomDirectory::AppLoader_DeconstructedRomDirectory( - FileSys::VirtualDir directory, bool override_update_, bool is_hbl_) - : AppLoader(directory->GetFile("main")), dir(std::move(directory)), - override_update(override_update_), is_hbl(is_hbl_) {} + FileSys::VirtualDir directory, bool override_update_) + : AppLoader(directory->GetFile("main")) + , dir(std::move(directory)) + , override_update(override_update_) +{} FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::VirtualFile& dir_file) { if (FileSys::IsDirectoryExeFS(dir_file->GetContainingDirectory())) { @@ -232,7 +235,7 @@ AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirect ? ::Settings::values.rng_seed.GetValue() : Common::Random::Random64(0)) << 12) & 0xfff000; // Setup the process code layout - if (process.LoadFromMetadata(metadata, code_size, fastmem_base, aslr_offset, is_hbl).IsError()) { + if (process.LoadFromMetadata(metadata, code_size, fastmem_base, aslr_offset).IsError()) { return {ResultStatus::ErrorUnableToParseKernelMetadata, {}}; } diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index 1e9f765c9d..7283db0662 100644 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -22,13 +25,9 @@ namespace Loader { */ class AppLoader_DeconstructedRomDirectory final : public AppLoader { public: - explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file, - bool override_update_ = false); - + explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualFile main_file, bool override_update_ = false); // Overload to accept exefs directory. Must contain 'main' and 'main.npdm' - explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory, - bool override_update_ = false, - bool is_hbl_ = false); + explicit AppLoader_DeconstructedRomDirectory(FileSys::VirtualDir directory, bool override_update_ = false); /** * Identifies whether or not the given file is a deconstructed ROM directory. @@ -63,7 +62,6 @@ private: std::string name; u64 title_id{}; bool override_update; - bool is_hbl; Modules modules; }; diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp index 978ffed2b9..fdfbac0a20 100644 --- a/src/core/loader/kip.cpp +++ b/src/core/loader/kip.cpp @@ -93,7 +93,7 @@ AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process, ? ::Settings::values.rng_seed.GetValue() : Common::Random::Random64(0)) << 12) & 0xfff000; // Setup the process code layout - if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), codeset.memory.size(), 0, aslr_offset, false).IsError()) { + if (process.LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), codeset.memory.size(), 0, aslr_offset).IsError()) { return {ResultStatus::ErrorNotInitialized, {}}; } const VAddr base_address = GetInteger(process.GetEntryPoint()); diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 738d805149..866059286a 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -247,7 +247,7 @@ static bool LoadNroImpl(Core::System& system, Kernel::KProcess& process, // Setup the process code layout if (process - .LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), image_size, fastmem_base, aslr_offset, false) + .LoadFromMetadata(FileSys::ProgramMetadata::GetDefault(), image_size, fastmem_base, aslr_offset) .IsError()) { return false; } diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index 4333acb70c..726bb428f6 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -34,8 +34,7 @@ AppLoader_NSP::AppLoader_NSP(FileSys::VirtualFile file_, } if (nsp->IsExtractedType()) { - secondary_loader = std::make_unique( - nsp->GetExeFS(), false, file->GetName() == "hbl.nsp"); + secondary_loader = std::make_unique(nsp->GetExeFS(), false); } else { const auto control_nca = nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Control); diff --git a/src/yuzu/main_window.cpp b/src/yuzu/main_window.cpp index 4d5a3c43f9..eb93b5b628 100644 --- a/src/yuzu/main_window.cpp +++ b/src/yuzu/main_window.cpp @@ -581,7 +581,7 @@ MainWindow::MainWindow(bool has_broken_vulkan) } else if (should_launch_hlaunch) { std::filesystem::path const sd_dir = Common::FS::GetEdenPathString(Common::FS::EdenPath::SDMCDir); auto const hbl_path = (sd_dir / "atmosphere" / "hbl.nsp").string(); - BootGame(QString::fromStdString(hbl_path), ApplicationAppletParameters()); + BootGame(QString::fromStdString(hbl_path), LibraryAppletParameters(0x010000000000100Dull, Service::AM::AppletId::QLaunch)); } } } From 6337aff0c4a7a02987f86b9cf3ff1fd2ca151d53 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 21 May 2026 21:02:59 +0000 Subject: [PATCH 12/19] implement stubs for i2c + gpio Signed-off-by: lizzie --- src/core/CMakeLists.txt | 4 +++ src/core/hle/service/apm/apm.cpp | 4 +++ src/core/hle/service/gpio/gpio.cpp | 33 +++++++++++++++++++++ src/core/hle/service/gpio/gpio.h | 15 ++++++++++ src/core/hle/service/i2c/i2c.cpp | 33 +++++++++++++++++++++ src/core/hle/service/i2c/i2c.h | 15 ++++++++++ src/core/hle/service/ptm/psm.cpp | 46 +++++++++++++++++++++++++++++- src/core/hle/service/ptm/psm.h | 4 +-- src/core/hle/service/services.cpp | 8 ++++-- 9 files changed, 157 insertions(+), 5 deletions(-) create mode 100644 src/core/hle/service/gpio/gpio.cpp create mode 100644 src/core/hle/service/gpio/gpio.h create mode 100644 src/core/hle/service/i2c/i2c.cpp create mode 100644 src/core/hle/service/i2c/i2c.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 39aebd5f48..949fde8e06 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1121,6 +1121,10 @@ add_library(core STATIC hle/service/vi/vi_types.h hle/service/vi/vsync_manager.cpp hle/service/vi/vsync_manager.h + hle/service/gpio/gpio.cpp + hle/service/gpio/gpio.h + hle/service/i2c/i2c.cpp + hle/service/i2c/i2c.h internal_network/emu_net_state.cpp internal_network/emu_net_state.h internal_network/network.cpp diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index c23ff293d3..71f895d0e6 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -21,6 +24,7 @@ void LoopProcess(Core::System& system) { "apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); server_manager->RegisterNamedService( "apm:sys", std::make_shared(system, system.GetAPMController())); + ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/gpio/gpio.cpp b/src/core/hle/service/gpio/gpio.cpp new file mode 100644 index 0000000000..fad0d1695b --- /dev/null +++ b/src/core/hle/service/gpio/gpio.cpp @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/core.h" +#include "core/hle/service/i2c/i2c.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::GPIO { + +class GPIO final : public ServiceFramework { +public: + explicit GPIO(Core::System& system_) + : ServiceFramework{system_, "gpio"} + { + static const FunctionInfo functions[] = { + {0, nullptr, "Cmd0"}, + }; + RegisterHandlers(functions); + } + ~GPIO() override = default; +}; + +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + server_manager->RegisterNamedService("gpio", std::make_shared(system)); + ServerManager::RunServer(std::move(server_manager)); +} + +} // namespace Service::GPIO diff --git a/src/core/hle/service/gpio/gpio.h b/src/core/hle/service/gpio/gpio.h new file mode 100644 index 0000000000..57f9a64e56 --- /dev/null +++ b/src/core/hle/service/gpio/gpio.h @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +namespace Core { +class System; +} + +namespace Service::GPIO { +void LoopProcess(Core::System& system); +} // namespace Service::GPIO diff --git a/src/core/hle/service/i2c/i2c.cpp b/src/core/hle/service/i2c/i2c.cpp new file mode 100644 index 0000000000..99decb37f9 --- /dev/null +++ b/src/core/hle/service/i2c/i2c.cpp @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/core.h" +#include "core/hle/service/i2c/i2c.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/service.h" + +namespace Service::I2C { + +class I2C final : public ServiceFramework { +public: + explicit I2C(Core::System& system_) + : ServiceFramework{system_, "i2c"} + { + static const FunctionInfo functions[] = { + {0, nullptr, "Cmd0"}, + }; + RegisterHandlers(functions); + } + ~I2C() override = default; +}; + +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + server_manager->RegisterNamedService("i2c", std::make_shared(system)); + ServerManager::RunServer(std::move(server_manager)); +} + +} // namespace Service::I2C diff --git a/src/core/hle/service/i2c/i2c.h b/src/core/hle/service/i2c/i2c.h new file mode 100644 index 0000000000..c26df8e86f --- /dev/null +++ b/src/core/hle/service/i2c/i2c.h @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +namespace Core { +class System; +} + +namespace Service::I2C { +void LoopProcess(Core::System& system); +} // namespace Service::I2C diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp index f144b8e497..ace11dd501 100644 --- a/src/core/hle/service/ptm/psm.cpp +++ b/src/core/hle/service/ptm/psm.cpp @@ -6,10 +6,12 @@ #include +#include "common/common_funcs.h" #include "common/device_power_state.h" #include "common/logging.h" #include "core/core.h" #include "core/hle/kernel/k_event.h" +#include "core/hle/result.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/ptm/psm.h" @@ -139,7 +141,7 @@ PSM::PSM(Core::System& system_) : ServiceFramework{system_, "psm"} { {14, nullptr, "IsEnoughPowerSupplied"}, {15, nullptr, "GetBatteryAgePercentage"}, {16, nullptr, "GetBatteryChargeInfoEvent"}, - {17, nullptr, "GetBatteryChargeInfoFields"}, + {17, &PSM::GetBatteryChargeInfoFields, "GetBatteryChargeInfoFields"}, {18, nullptr, "GetBatteryChargeCalibratedEvent"}, }; // clang-format on @@ -187,4 +189,46 @@ void PSM::OpenSession(HLERequestContext& ctx) { rb.PushIpcInterface(system); } +struct BatteryChargeInfoFields { + u32 input_current_limit; //mA + u32 boost_mode_current_limit; + u32 fast_charge_current_limit; + u32 charge_voltage_limit; + u32 charger_type; + u8 hi2_mode; + u8 battery_charging; + INSERT_PADDING_BYTES_NOINIT(2); + u32 vdd50_state; + u32 temperature_celcius; + u32 battery_charge_percentage; + u32 battery_charge_milli_voltage; + u32 battery_age_percentage; + u32 usb_power_role; + u32 usb_charger_type; + u32 charger_input_voltage_limit; + u32 charger_input_current_limit; + u8 fast_battery_charging; + u8 controller_power_supply; + u8 otg_request; + INSERT_PADDING_BYTES_NOINIT(1); + INSERT_PADDING_BYTES_NOINIT(0x14); //[+17.0.0] +}; +static_assert(sizeof(struct BatteryChargeInfoFields) == 0x54); + +void PSM::GetBatteryChargeInfoFields(HLERequestContext& ctx) { + LOG_DEBUG(Service_PTM, "called"); + Common::PowerStatus power_status = Common::GetPowerStatus(); + + BatteryChargeInfoFields r{}; + r.battery_charge_percentage = power_status.percentage; //100% + r.battery_age_percentage = power_status.percentage; //100% + r.battery_charging = power_status.charging ? 1 : 0; + r.charger_type = u32(power_status.has_battery && power_status.charging + ? ChargerType::RegularCharger : ChargerType::Unplugged); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushRaw(r); +} + } // namespace Service::PTM diff --git a/src/core/hle/service/ptm/psm.h b/src/core/hle/service/ptm/psm.h index 2853a45753..1e4aa72dee 100644 --- a/src/core/hle/service/ptm/psm.h +++ b/src/core/hle/service/ptm/psm.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project @@ -22,10 +22,10 @@ private: LowPowerCharger = 2, Unknown = 3, }; - void GetBatteryChargePercentage(HLERequestContext& ctx); void GetChargerType(HLERequestContext& ctx); void OpenSession(HLERequestContext& ctx); + void GetBatteryChargeInfoFields(HLERequestContext& ctx); }; } // namespace Service::PTM diff --git a/src/core/hle/service/services.cpp b/src/core/hle/service/services.cpp index 636f54ad49..4dfdf9068f 100644 --- a/src/core/hle/service/services.cpp +++ b/src/core/hle/service/services.cpp @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project @@ -25,8 +25,10 @@ #include "core/hle/service/friend/friend.h" #include "core/hle/service/glue/glue.h" #include "core/hle/service/grc/grc.h" +#include "core/hle/service/gpio/gpio.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/i2c/i2c.h" #include "core/hle/service/jit/jit.h" #include "core/hle/service/lbl/lbl.h" #include "core/hle/service/ldn/ldn.h" @@ -144,7 +146,9 @@ Services::Services(std::shared_ptr& sm, Core::System& system {"ro", &RO::LoopProcess}, {"spl", &SPL::LoopProcess}, {"ssl", &SSL::LoopProcess}, - {"usb", &USB::LoopProcess} + {"usb", &USB::LoopProcess}, + {"i2c", &I2C::LoopProcess}, + {"gpio", &GPIO::LoopProcess}, }) kernel.RunOnGuestCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); }); } From 37df681a2c0eed54ddea07a572b2f46377a651ea Mon Sep 17 00:00:00 2001 From: lizzie Date: Wed, 20 May 2026 08:39:07 +0000 Subject: [PATCH 13/19] + stubbed services --- src/core/hle/service/btm/btm_system_core.cpp | 7 ++- src/core/hle/service/btm/btm_system_core.h | 5 +- .../service/set/system_settings_server.cpp | 55 ++++++++++++++++--- .../hle/service/set/system_settings_server.h | 6 ++ 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/core/hle/service/btm/btm_system_core.cpp b/src/core/hle/service/btm/btm_system_core.cpp index f1e623be16..318657fc32 100644 --- a/src/core/hle/service/btm/btm_system_core.cpp +++ b/src/core/hle/service/btm/btm_system_core.cpp @@ -29,7 +29,7 @@ IBtmSystemCore::IBtmSystemCore(Core::System& system_) {10, nullptr, "StartAudioDeviceDiscovery"}, {11, nullptr, "StopAudioDeviceDiscovery"}, {12, nullptr, "IsDiscoveryingAudioDevice"}, - {13, nullptr, "GetDiscoveredAudioDevice"}, + {13, C<&IBtmSystemCore::GetDiscoveredAudioDevice>, "GetDiscoveredAudioDevice"}, {14, C<&IBtmSystemCore::AcquireAudioDeviceConnectionEvent>, "AcquireAudioDeviceConnectionEvent"}, {15, nullptr, "ConnectAudioDevice"}, {16, nullptr, "IsConnectingAudioDevice"}, @@ -93,6 +93,11 @@ Result IBtmSystemCore::AcquireRadioEvent(Out out_is_valid, R_SUCCEED(); } +Result IBtmSystemCore::GetDiscoveredAudioDevice(OutArray, BufferAttr_HipcPointer> out_audio_devices, s32 count, Out out_total) { + LOG_WARNING(Service_BTM, "(STUBBED) called"); + R_SUCCEED(); +} + Result IBtmSystemCore::AcquireAudioDeviceConnectionEvent( OutCopyHandle out_event) { LOG_WARNING(Service_BTM, "(STUBBED) called"); diff --git a/src/core/hle/service/btm/btm_system_core.h b/src/core/hle/service/btm/btm_system_core.h index 06498b21ea..c390627f28 100644 --- a/src/core/hle/service/btm/btm_system_core.h +++ b/src/core/hle/service/btm/btm_system_core.h @@ -34,9 +34,8 @@ private: Result DisableRadio(); Result IsRadioEnabled(Out out_is_enabled); - Result AcquireRadioEvent(Out out_is_valid, - OutCopyHandle out_event); - + Result AcquireRadioEvent(Out out_is_valid, OutCopyHandle out_event); + Result GetDiscoveredAudioDevice(OutArray, BufferAttr_HipcPointer> out_audio_devices, s32 count, Out out_total); Result AcquireAudioDeviceConnectionEvent(OutCopyHandle out_event); Result GetConnectedAudioDevices( diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index 0ed6d28dd4..7fa74e6689 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -142,10 +142,10 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {22, C<&ISystemSettingsServer::SetEulaVersions>, "SetEulaVersions"}, {23, C<&ISystemSettingsServer::GetColorSetId>, "GetColorSetId"}, {24, C<&ISystemSettingsServer::SetColorSetId>, "SetColorSetId"}, - {25, nullptr, "GetConsoleInformationUploadFlag"}, - {26, nullptr, "SetConsoleInformationUploadFlag"}, - {27, nullptr, "GetAutomaticApplicationDownloadFlag"}, - {28, nullptr, "SetAutomaticApplicationDownloadFlag"}, + {25, C<&ISystemSettingsServer::GetConsoleInformationUploadFlag>, "GetConsoleInformationUploadFlag"}, + {26, C<&ISystemSettingsServer::SetConsoleInformationUploadFlag>, "SetConsoleInformationUploadFlag"}, + {27, C<&ISystemSettingsServer::GetAutomaticApplicationDownloadFlag>, "GetAutomaticApplicationDownloadFlag"}, + {28, C<&ISystemSettingsServer::SetAutomaticApplicationDownloadFlag>, "SetAutomaticApplicationDownloadFlag"}, {29, C<&ISystemSettingsServer::GetNotificationSettings>, "GetNotificationSettings"}, {30, C<&ISystemSettingsServer::SetNotificationSettings>, "SetNotificationSettings"}, {31, C<&ISystemSettingsServer::GetAccountNotificationSettings>, "GetAccountNotificationSettings"}, @@ -160,8 +160,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {42, nullptr, "SetEdid"}, {43, C<&ISystemSettingsServer::GetAudioOutputMode>, "GetAudioOutputMode"}, {44, C<&ISystemSettingsServer::SetAudioOutputMode>, "SetAudioOutputMode"}, - {45, C<&ISystemSettingsServer::GetSpeakerAutoMuteFlag> , "GetSpeakerAutoMuteFlag"}, - {46, C<&ISystemSettingsServer::SetSpeakerAutoMuteFlag> , "SetSpeakerAutoMuteFlag"}, + {45, C<&ISystemSettingsServer::GetSpeakerAutoMuteFlag>, "GetSpeakerAutoMuteFlag"}, + {46, C<&ISystemSettingsServer::SetSpeakerAutoMuteFlag>, "SetSpeakerAutoMuteFlag"}, {47, C<&ISystemSettingsServer::GetQuestFlag>, "GetQuestFlag"}, {48, C<&ISystemSettingsServer::SetQuestFlag>, "SetQuestFlag"}, {49, nullptr, "GetDataDeletionSettings"}, @@ -180,8 +180,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {62, C<&ISystemSettingsServer::GetDebugModeFlag>, "GetDebugModeFlag"}, {63, C<&ISystemSettingsServer::GetPrimaryAlbumStorage>, "GetPrimaryAlbumStorage"}, {64, C<&ISystemSettingsServer::SetPrimaryAlbumStorage>, "SetPrimaryAlbumStorage"}, - {65, nullptr, "GetUsb30EnableFlag"}, - {66, nullptr, "SetUsb30EnableFlag"}, + {65, C<&ISystemSettingsServer::GetUsb30EnableFlag>, "GetUsb30EnableFlag"}, + {66, C<&ISystemSettingsServer::SetUsb30EnableFlag>, "SetUsb30EnableFlag"}, {67, C<&ISystemSettingsServer::GetBatteryLot>, "GetBatteryLot"}, {68, C<&ISystemSettingsServer::GetSerialNumber>, "GetSerialNumber"}, {69, C<&ISystemSettingsServer::GetNfcEnableFlag>, "GetNfcEnableFlag"}, @@ -1074,6 +1074,45 @@ Result ISystemSettingsServer::SetNfcEnableFlag(bool nfc_enable_flag) { R_SUCCEED(); } +Result ISystemSettingsServer::GetConsoleInformationUploadFlag(Out out_flag) { + LOG_INFO(Service_SET, "called {}", m_system_settings.console_information_upload_flag); + *out_flag = m_system_settings.console_information_upload_flag; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetConsoleInformationUploadFlag(bool flag) { + LOG_INFO(Service_SET, "called {}", flag); + m_system_settings.usb_30_enable_flag = flag; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetAutomaticApplicationDownloadFlag(Out out_flag) { + LOG_INFO(Service_SET, "called {}", m_system_settings.usb_30_enable_flag); + *out_flag = m_system_settings.automatic_application_download_flag; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetAutomaticApplicationDownloadFlag(bool flag) { + LOG_INFO(Service_SET, "called {}", flag); + m_system_settings.automatic_application_download_flag = flag; + SetSaveNeeded(); + R_SUCCEED(); +} + +Result ISystemSettingsServer::GetUsb30EnableFlag(Out out_usb30_enable_flag) { + LOG_INFO(Service_SET, "called, usb30_enable_flag={}", m_system_settings.usb_30_enable_flag); + *out_usb30_enable_flag = m_system_settings.usb_30_enable_flag; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetUsb30EnableFlag(bool usb30_enable_flag) { + LOG_INFO(Service_SET, "called, usb30_enable_flag={}", usb30_enable_flag); + m_system_settings.usb_30_enable_flag = usb30_enable_flag; + SetSaveNeeded(); + R_SUCCEED(); +} + Result ISystemSettingsServer::GetSleepSettings(Out out_sleep_settings) { LOG_INFO(Service_SET, "called, flags={}, handheld_sleep_plan={}, console_sleep_plan={}", m_system_settings.sleep_settings.flags.raw, diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h index 2a160dfc6b..1d56e61f88 100644 --- a/src/core/hle/service/set/system_settings_server.h +++ b/src/core/hle/service/set/system_settings_server.h @@ -109,6 +109,12 @@ public: Result SetPrimaryAlbumStorage(PrimaryAlbumStorage primary_album_storage); Result GetBatteryLot(Out out_battery_lot); Result GetSerialNumber(Out out_console_serial); + Result GetConsoleInformationUploadFlag(Out out_flag); + Result SetConsoleInformationUploadFlag(bool flag); + Result GetAutomaticApplicationDownloadFlag(Out out_flag); + Result SetAutomaticApplicationDownloadFlag(bool flag); + Result GetUsb30EnableFlag(Out out_usb30_enable_flag); + Result SetUsb30EnableFlag(bool usb30_enable_flag); Result GetNfcEnableFlag(Out out_nfc_enable_flag); Result SetNfcEnableFlag(bool nfc_enable_flag); Result GetSleepSettings(Out out_sleep_settings); From a280373f8e72ffab531e15267bfe4dc7353d4cbb Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 21 May 2026 21:30:41 +0000 Subject: [PATCH 14/19] extra battery states --- src/core/hle/service/btm/btm_system_core.h | 3 ++ src/core/hle/service/ptm/psm.cpp | 32 +++++++++++++++++----- src/core/hle/service/ptm/psm.h | 2 ++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/core/hle/service/btm/btm_system_core.h b/src/core/hle/service/btm/btm_system_core.h index c390627f28..3fc4c0d56c 100644 --- a/src/core/hle/service/btm/btm_system_core.h +++ b/src/core/hle/service/btm/btm_system_core.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp index ace11dd501..06396bbb4c 100644 --- a/src/core/hle/service/ptm/psm.cpp +++ b/src/core/hle/service/ptm/psm.cpp @@ -136,10 +136,10 @@ PSM::PSM(Core::System& system_) : ServiceFramework{system_, "psm"} { {9, nullptr, "DisableEnoughPowerChargeEmulation"}, {10, nullptr, "EnableFastBatteryCharging"}, {11, nullptr, "DisableFastBatteryCharging"}, - {12, nullptr, "GetBatteryVoltageState"}, + {12, &PSM::GetBatteryVoltageState, "GetBatteryVoltageState"}, {13, nullptr, "GetRawBatteryChargePercentage"}, {14, nullptr, "IsEnoughPowerSupplied"}, - {15, nullptr, "GetBatteryAgePercentage"}, + {15, &PSM::GetBatteryAgePercentage, "GetBatteryAgePercentage"}, {16, nullptr, "GetBatteryChargeInfoEvent"}, {17, &PSM::GetBatteryChargeInfoFields, "GetBatteryChargeInfoFields"}, {18, nullptr, "GetBatteryChargeCalibratedEvent"}, @@ -189,6 +189,20 @@ void PSM::OpenSession(HLERequestContext& ctx) { rb.PushIpcInterface(system); } +void PSM::GetBatteryVoltageState(HLERequestContext& ctx) { + LOG_DEBUG(Service_PTM, "(stubbed)"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushRaw(0); // +} + +void PSM::GetBatteryAgePercentage(HLERequestContext& ctx) { + LOG_DEBUG(Service_PTM, "(stubbed)"); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.PushRaw(1.f); +} + struct BatteryChargeInfoFields { u32 input_current_limit; //mA u32 boost_mode_current_limit; @@ -200,9 +214,9 @@ struct BatteryChargeInfoFields { INSERT_PADDING_BYTES_NOINIT(2); u32 vdd50_state; u32 temperature_celcius; - u32 battery_charge_percentage; + f32 battery_charge_percentage; u32 battery_charge_milli_voltage; - u32 battery_age_percentage; + f32 battery_age_percentage; u32 usb_power_role; u32 usb_charger_type; u32 charger_input_voltage_limit; @@ -214,17 +228,21 @@ struct BatteryChargeInfoFields { INSERT_PADDING_BYTES_NOINIT(0x14); //[+17.0.0] }; static_assert(sizeof(struct BatteryChargeInfoFields) == 0x54); - void PSM::GetBatteryChargeInfoFields(HLERequestContext& ctx) { LOG_DEBUG(Service_PTM, "called"); Common::PowerStatus power_status = Common::GetPowerStatus(); BatteryChargeInfoFields r{}; - r.battery_charge_percentage = power_status.percentage; //100% - r.battery_age_percentage = power_status.percentage; //100% + r.battery_charge_percentage = f32(power_status.percentage); //100% + r.battery_age_percentage = f32(power_status.percentage); //100% r.battery_charging = power_status.charging ? 1 : 0; r.charger_type = u32(power_status.has_battery && power_status.charging ? ChargerType::RegularCharger : ChargerType::Unplugged); + r.charger_input_voltage_limit = 100; + r.charger_input_voltage_limit = 100; + r.input_current_limit = 100; + r.boost_mode_current_limit = 100; + r.fast_charge_current_limit = 100; IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); diff --git a/src/core/hle/service/ptm/psm.h b/src/core/hle/service/ptm/psm.h index 1e4aa72dee..77c38d1f9b 100644 --- a/src/core/hle/service/ptm/psm.h +++ b/src/core/hle/service/ptm/psm.h @@ -25,6 +25,8 @@ private: void GetBatteryChargePercentage(HLERequestContext& ctx); void GetChargerType(HLERequestContext& ctx); void OpenSession(HLERequestContext& ctx); + void GetBatteryVoltageState(HLERequestContext& ctx); + void GetBatteryAgePercentage(HLERequestContext& ctx); void GetBatteryChargeInfoFields(HLERequestContext& ctx); }; From 5a5219da6fd3ca3573613159630e95b3721ce1c6 Mon Sep 17 00:00:00 2001 From: lizzie Date: Thu, 21 May 2026 21:30:47 +0000 Subject: [PATCH 15/19] apm:p --- src/core/hle/service/apm/apm.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 71f895d0e6..2496b132ad 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -18,12 +18,10 @@ void LoopProcess(Core::System& system) { auto module = std::make_shared(); auto server_manager = std::make_unique(system); - server_manager->RegisterNamedService( - "apm", std::make_shared(system, module, system.GetAPMController(), "apm")); - server_manager->RegisterNamedService( - "apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); - server_manager->RegisterNamedService( - "apm:sys", std::make_shared(system, system.GetAPMController())); + server_manager->RegisterNamedService("apm", std::make_shared(system, module, system.GetAPMController(), "apm")); + server_manager->RegisterNamedService("apm:p", std::make_shared(system, module, system.GetAPMController(), "apm:p")); + server_manager->RegisterNamedService("apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); + server_manager->RegisterNamedService("apm:sys", std::make_shared(system, system.GetAPMController())); ServerManager::RunServer(std::move(server_manager)); } From f8b1f5738dd61ce335e24c477a10a21dcf7eb8e7 Mon Sep 17 00:00:00 2001 From: lizzie Date: Tue, 19 May 2026 06:50:54 +0000 Subject: [PATCH 16/19] [hle/service{nvdrv,apm}] fixes for TetrisSwitch Signed-off-by: lizzie --- src/core/hle/service/apm/apm.cpp | 4 +-- .../service/nvdrv/devices/nvdisp_disp0.cpp | 4 ++- src/core/hle/service/nvnflinger/ui/fence.h | 8 ++--- src/hid_core/resources/npad/npad.cpp | 5 +++ src/video_core/gpu.cpp | 35 +++++++++---------- 5 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 2496b132ad..d73d08cb72 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -19,10 +19,10 @@ void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); server_manager->RegisterNamedService("apm", std::make_shared(system, module, system.GetAPMController(), "apm")); - server_manager->RegisterNamedService("apm:p", std::make_shared(system, module, system.GetAPMController(), "apm:p")); server_manager->RegisterNamedService("apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); + // Removed on [+8.0.0] but kept for compatibility + server_manager->RegisterNamedService("apm:p", std::make_shared(system, module, system.GetAPMController(), "apm:p")); server_manager->RegisterNamedService("apm:sys", std::make_shared(system, system.GetAPMController())); - ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp index f26f5347eb..bdbb16ed04 100644 --- a/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp +++ b/src/core/hle/service/nvdrv/devices/nvdisp_disp0.cpp @@ -79,7 +79,9 @@ void nvdisp_disp0::Composite(std::span sorted_layers }); for (size_t i = 0; i < layer.acquire_fence.num_fences; i++) { - output_fences.push_back(layer.acquire_fence.fences[i]); + if (layer.acquire_fence.fences[i].id >= 0) { + output_fences.push_back(layer.acquire_fence.fences[i]); + } } } diff --git a/src/core/hle/service/nvnflinger/ui/fence.h b/src/core/hle/service/nvnflinger/ui/fence.h index 177aed7580..261eb51669 100644 --- a/src/core/hle/service/nvnflinger/ui/fence.h +++ b/src/core/hle/service/nvnflinger/ui/fence.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2012 The Android Open Source Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -15,10 +18,8 @@ namespace Service::android { class Fence { public: - constexpr Fence() = default; - static constexpr Fence NoFence() { - Fence fence; + Fence fence{}; fence.fences[0].id = -1; fence.fences[1].id = -1; fence.fences[2].id = -1; @@ -26,7 +27,6 @@ public: return fence; } -public: u32 num_fences{}; std::array fences{}; }; diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp index 3a191f4539..4710342848 100644 --- a/src/hid_core/resources/npad/npad.cpp +++ b/src/hid_core/resources/npad/npad.cpp @@ -712,6 +712,11 @@ bool NPad::SetNpadMode(u64 aruid, Core::HID::NpadIdType& new_npad_id, Core::HID: } auto& controller = GetControllerFromNpadIdType(aruid, npad_id); + if (!controller.shared_memory) { + LOG_WARNING(Service_HID, "shared_memory is null for npad_id={}", npad_id); + return false; + } + if (controller.shared_memory->assignment_mode != assignment_mode) { controller.shared_memory->assignment_mode = assignment_mode; } diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 5f4054212f..391ca4ef5f 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp @@ -303,26 +303,25 @@ struct GPU::Impl { free_swap_counters.pop_front(); } } - const auto wait_fence = - RequestSyncOperation([this, current_request_counter, &layers, &fences, num_fences] { - auto& syncpoint_manager = host1x.GetSyncpointManager(); - if (num_fences == 0) { - renderer->Composite(layers); - } - const auto executer = [this, current_request_counter, layers_copy = layers]() { - { - std::unique_lock lk(request_swap_mutex); - if (--request_swap_counters[current_request_counter] != 0) { - return; - } - free_swap_counters.push_back(current_request_counter); + const auto wait_fence = RequestSyncOperation([this, current_request_counter, &layers, &fences, num_fences] { + auto& syncpoint_manager = host1x.GetSyncpointManager(); + if (num_fences == 0) { + renderer->Composite(layers); + } + const auto executer = [this, current_request_counter, layers_copy = layers]() { + { + std::unique_lock lk(request_swap_mutex); + if (--request_swap_counters[current_request_counter] != 0) { + return; } - renderer->Composite(layers_copy); - }; - for (size_t i = 0; i < num_fences; i++) { - syncpoint_manager.RegisterGuestAction(fences[i].id, fences[i].value, executer); + free_swap_counters.push_back(current_request_counter); } - }); + renderer->Composite(layers_copy); + }; + for (size_t i = 0; i < num_fences; i++) { + syncpoint_manager.RegisterGuestAction(fences[i].id, fences[i].value, executer); + } + }); gpu_thread.TickGPU(); WaitForSyncOperation(wait_fence); } From acb38a3123cb04b66d54ac474d900b694af2f0db Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 22 May 2026 00:34:25 +0000 Subject: [PATCH 17/19] i2c --- src/core/hle/service/i2c/i2c.cpp | 45 +++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/src/core/hle/service/i2c/i2c.cpp b/src/core/hle/service/i2c/i2c.cpp index 99decb37f9..d000487246 100644 --- a/src/core/hle/service/i2c/i2c.cpp +++ b/src/core/hle/service/i2c/i2c.cpp @@ -5,23 +5,66 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/core.h" +#include "core/hle/result.h" #include "core/hle/service/i2c/i2c.h" #include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/cmif_types.h" #include "core/hle/service/service.h" +#include "core/hle/service/server_manager.h" namespace Service::I2C { +class I2CSession final : public ServiceFramework { +public: + explicit I2CSession(Core::System& system_) + : ServiceFramework{system_, "I2CSession"} + { + static const FunctionInfo functions[] = { + {0, nullptr, "SendOld"}, + {1, nullptr, "ReceiveOld"}, + {2, nullptr, "ExecuteCommandListOld"}, + {10, C<&I2CSession::Send>, "Send"}, + {11, nullptr, "Receive"}, + {12, nullptr, "ExecuteCommandList"}, + {13, nullptr, "SetRetryPolicy"}, + }; + RegisterHandlers(functions); + } + ~I2CSession() override = default; + + Result Send(InBuffer in_data, u32 transaction_option) { + LOG_WARNING(Service, "(stubbed) topt={}", transaction_option); + R_THROW(ResultUnknown); + } +}; + +enum class I2CDevice : u32 { + ClassicController, + Ftm3bd56, +}; + class I2C final : public ServiceFramework { public: explicit I2C(Core::System& system_) : ServiceFramework{system_, "i2c"} { static const FunctionInfo functions[] = { - {0, nullptr, "Cmd0"}, + {0, nullptr, "OpenSessionForDev"}, + {1, C<&I2C::OpenSession>, "OpenSession"}, + {2, nullptr, "HasDevice"}, + {3, nullptr, "HasDeviceForDev"}, + {4, nullptr, "OpenSession2"}, }; RegisterHandlers(functions); } ~I2C() override = default; + + Result OpenSession(I2CDevice device, OutInterface out_session) { + LOG_DEBUG(Service, "(stubbed)"); + *out_session = std::make_shared(system); + R_SUCCEED(); + } }; void LoopProcess(Core::System& system) { From b09d0734975da4b2be66e699cd7313d455282300 Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 22 May 2026 01:22:10 +0000 Subject: [PATCH 18/19] fx --- src/core/hle/service/am/applet.h | 3 ++- .../hle/service/am/service/application_functions.cpp | 10 +++++++++- .../hle/service/am/service/application_functions.h | 1 + 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/core/hle/service/am/applet.h b/src/core/hle/service/am/applet.h index a693a47d7a..1121fe221e 100644 --- a/src/core/hle/service/am/applet.h +++ b/src/core/hle/service/am/applet.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project @@ -83,6 +83,7 @@ struct Applet { // Application functions bool game_play_recording_supported{}; + bool media_playback_state{}; GamePlayRecordingState game_play_recording_state{GamePlayRecordingState::Disabled}; bool jit_service_launched{}; bool application_crash_report_enabled{}; diff --git a/src/core/hle/service/am/service/application_functions.cpp b/src/core/hle/service/am/service/application_functions.cpp index 9ab343e59e..787c88f52d 100644 --- a/src/core/hle/service/am/service/application_functions.cpp +++ b/src/core/hle/service/am/service/application_functions.cpp @@ -11,6 +11,7 @@ #include "core/file_sys/registered_cache.h" #include "core/file_sys/savedata_factory.h" #include "core/hle/kernel/k_transfer_memory.h" +#include "core/hle/result.h" #include "core/hle/service/am/am_results.h" #include "core/hle/service/am/applet.h" #include "core/hle/service/am/service/application_functions.h" @@ -56,7 +57,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_, std::shared_ {37, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"}, {40, D<&IApplicationFunctions::NotifyRunning>, "NotifyRunning"}, {50, D<&IApplicationFunctions::GetPseudoDeviceId>, "GetPseudoDeviceId"}, - {60, nullptr, "SetMediaPlaybackStateForApplication"}, + {60, D<&IApplicationFunctions::SetMediaPlaybackStateForApplication>, "SetMediaPlaybackStateForApplication"}, {65, D<&IApplicationFunctions::IsGamePlayRecordingSupported>, "IsGamePlayRecordingSupported"}, {66, D<&IApplicationFunctions::InitializeGamePlayRecording>, "InitializeGamePlayRecording"}, {67, D<&IApplicationFunctions::SetGamePlayRecordingState>, "SetGamePlayRecordingState"}, @@ -364,6 +365,13 @@ Result IApplicationFunctions::InitializeGamePlayRecording( R_SUCCEED(); } +Result IApplicationFunctions::SetMediaPlaybackStateForApplication(bool enabled) { + LOG_WARNING(Service_AM, "(stubbed) {}", enabled); + std::scoped_lock lk{m_applet->lock}; + m_applet->media_playback_state = enabled; + R_SUCCEED(); +} + Result IApplicationFunctions::SetGamePlayRecordingState( GamePlayRecordingState game_play_recording_state) { LOG_WARNING(Service_AM, "(STUBBED) called"); diff --git a/src/core/hle/service/am/service/application_functions.h b/src/core/hle/service/am/service/application_functions.h index abee2f9d47..b97ed7e25e 100644 --- a/src/core/hle/service/am/service/application_functions.h +++ b/src/core/hle/service/am/service/application_functions.h @@ -53,6 +53,7 @@ private: Result IsGamePlayRecordingSupported(Out out_is_game_play_recording_supported); Result InitializeGamePlayRecording( u64 transfer_memory_size, InCopyHandle transfer_memory_handle); + Result SetMediaPlaybackStateForApplication(bool enabled); Result SetGamePlayRecordingState(GamePlayRecordingState game_play_recording_state); Result EnableApplicationCrashReport(bool enabled); Result InitializeApplicationCopyrightFrameBuffer( From c3ec6f62edda391b2593d64e36e0c0affe799dbe Mon Sep 17 00:00:00 2001 From: lizzie Date: Fri, 22 May 2026 04:05:53 +0000 Subject: [PATCH 19/19] stub nv ctrl-gpu and nvdec debug stuff --- .../hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp | 8 ++++++++ .../hle/service/nvdrv/devices/nvhost_ctrl_gpu.h | 8 +++++++- .../hle/service/nvdrv/devices/nvhost_nvdec.cpp | 14 ++++++++------ .../service/nvdrv/devices/nvhost_nvdec_common.cpp | 7 +++++++ .../service/nvdrv/devices/nvhost_nvdec_common.h | 7 +++++++ 5 files changed, 37 insertions(+), 7 deletions(-) diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp index ace1f7e8f7..b621e5d70d 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -47,6 +47,8 @@ NvResult nvhost_ctrl_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span return WrapFixed(this, &nvhost_ctrl_gpu::FlushL2, input, output); case 0x14: return WrapFixed(this, &nvhost_ctrl_gpu::GetActiveSlotMask, input, output); + case 0x15: + return WrapFixed(this, &nvhost_ctrl_gpu::PmuGetGpuLoad, input, output); case 0x1c: return WrapFixed(this, &nvhost_ctrl_gpu::GetGpuTime, input, output); default: @@ -234,6 +236,12 @@ NvResult nvhost_ctrl_gpu::GetActiveSlotMask(IoctlActiveSlotMask& params) { return NvResult::Success; } +NvResult nvhost_ctrl_gpu::PmuGetGpuLoad(IoctlPmuGetLoad& params) { + LOG_WARNING(Service_NVDRV, "(stubbed) called"); + params.pmu_gpu_load = 100; + return NvResult::Success; +} + NvResult nvhost_ctrl_gpu::ZCullGetCtxSize(IoctlZcullGetCtxSize& params) { LOG_DEBUG(Service_NVDRV, "called"); params.size = 0x1; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h index e0603f9a71..80b7abd6a1 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl_gpu.h @@ -1,4 +1,4 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project @@ -184,6 +184,11 @@ private: }; static_assert(sizeof(IoctlGetCpuTimeCorrelationInfo) == 264); + struct IoctlPmuGetLoad { + u32 pmu_gpu_load; + }; + static_assert(sizeof(IoctlPmuGetLoad) == 4); + NvResult GetCharacteristics1(IoctlCharacteristics& params); NvResult GetCharacteristics3(IoctlCharacteristics& params, std::span gpu_characteristics); @@ -192,6 +197,7 @@ private: NvResult GetTPCMasks3(IoctlGpuGetTpcMasksArgs& params, std::span tpc_mask); NvResult GetActiveSlotMask(IoctlActiveSlotMask& params); + NvResult PmuGetGpuLoad(IoctlPmuGetLoad& params); NvResult ZCullGetCtxSize(IoctlZcullGetCtxSize& params); NvResult ZCullGetInfo(IoctlNvgpuGpuZcullGetInfoArgs& params); NvResult ZBCSetTable(IoctlZbcSetTable& params); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp index d64658bddc..7ac3dfaa46 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec.cpp @@ -25,18 +25,20 @@ NvResult nvhost_nvdec::Ioctl1(DeviceFD fd, Ioctl command, std::span in switch (command.group) { case 0x0: switch (command.cmd) { - case 0x1: + case 0x01: return WrapFixedVariable(this, &nvhost_nvdec::Submit, input, output, fd); - case 0x2: + case 0x02: return WrapFixed(this, &nvhost_nvdec::GetSyncpoint, input, output); - case 0x3: + case 0x03: return WrapFixed(this, &nvhost_nvdec::GetWaitbase, input, output); - case 0x7: + case 0x07: return WrapFixed(this, &nvhost_nvdec::SetSubmitTimeout, input, output); - case 0x9: + case 0x09: return WrapFixedVariable(this, &nvhost_nvdec::MapBuffer, input, output, fd); - case 0xa: + case 0x0a: return WrapFixedVariable(this, &nvhost_nvdec::UnmapBuffer, input, output); + case 0x23: + return WrapFixed(this, &nvhost_nvdec::GetClkRate, input, output); default: break; } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp index c726d6f93e..698712e152 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp @@ -168,6 +168,13 @@ NvResult nvhost_nvdec_common::SetSubmitTimeout(u32 timeout) { return NvResult::Success; } +NvResult nvhost_nvdec_common::GetClkRate(IoctlGetClkRate& params) { + LOG_WARNING(Service_NVDRV, "(STUBBED) called"); + params.clk_rate = 614400000; + params.module_id = 0; + return NvResult::Success; +} + Kernel::KEvent* nvhost_nvdec_common::QueryEvent(u32 event_id) { LOG_CRITICAL(Service_NVDRV, "Unknown HOSTX1 Event {}", event_id); return nullptr; diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h index 6b66a0d28d..8b3b7ee285 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h @@ -111,6 +111,12 @@ protected: }; static_assert(sizeof(IoctlMapBuffer) == 0x0C, "IoctlMapBuffer is incorrect size"); + struct IoctlGetClkRate { + u32_le clk_rate{}; + u32_le module_id{}; + }; + static_assert(sizeof(IoctlGetClkRate) == 8); + /// Ioctl command implementations NvResult SetNVMAPfd(IoctlSetNvmapFD&); NvResult Submit(IoctlSubmit& params, std::span input, DeviceFD fd); @@ -119,6 +125,7 @@ protected: NvResult MapBuffer(IoctlMapBuffer& params, std::span entries, DeviceFD fd); NvResult UnmapBuffer(IoctlMapBuffer& params, std::span entries); NvResult SetSubmitTimeout(u32 timeout); + NvResult GetClkRate(IoctlGetClkRate& params); Kernel::KEvent* QueryEvent(u32 event_id) override;