diff --git a/README.md b/README.md index 291256d6f..aa6cc055d 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 4084. +This is the source code for early-access 4085. ## Legal Notice diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index 3f0a39d33..1dd86fb3c 100755 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp @@ -69,9 +69,14 @@ public: }; template -void InvalidateInstructionCache(KernelCore& kernel, AddressType addr, u64 size) { +void InvalidateInstructionCache(KernelCore& kernel, KPageTableBase* table, AddressType addr, + u64 size) { // TODO: lock the process list for (auto& process : kernel.GetProcessList()) { + if (std::addressof(process->GetPageTable().GetBasePageTable()) != table) { + continue; + } + for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { auto* interface = process->GetArmInterface(i); if (interface) { @@ -1302,7 +1307,7 @@ Result KPageTableBase::UnmapCodeMemory(KProcessAddress dst_address, KProcessAddr bool reprotected_pages = false; SCOPE_EXIT({ if (reprotected_pages && any_code_pages) { - InvalidateInstructionCache(m_kernel, dst_address, size); + InvalidateInstructionCache(m_kernel, this, dst_address, size); } }); @@ -2036,7 +2041,7 @@ Result KPageTableBase::SetProcessMemoryPermission(KProcessAddress addr, size_t s for (const auto& block : pg) { StoreDataCache(GetHeapVirtualPointer(m_kernel, block.GetAddress()), block.GetSize()); } - InvalidateInstructionCache(m_kernel, addr, size); + InvalidateInstructionCache(m_kernel, this, addr, size); } R_SUCCEED(); @@ -3277,7 +3282,7 @@ Result KPageTableBase::WriteDebugMemory(KProcessAddress dst_address, KProcessAdd R_TRY(PerformCopy()); // Invalidate the instruction cache, as this svc allows modifying executable pages. - InvalidateInstructionCache(m_kernel, dst_address, size); + InvalidateInstructionCache(m_kernel, this, dst_address, size); R_SUCCEED(); } diff --git a/src/core/hle/service/nvdrv/core/container.cpp b/src/core/hle/service/nvdrv/core/container.cpp index a30af20e7..679d83d90 100755 --- a/src/core/hle/service/nvdrv/core/container.cpp +++ b/src/core/hle/service/nvdrv/core/container.cpp @@ -112,6 +112,7 @@ SessionId Container::OpenSession(Kernel::KProcess* process) { void Container::CloseSession(SessionId session_id) { std::scoped_lock lk(impl->session_guard); + impl->file.UnmapAllHandles(session_id); auto& session = impl->sessions[session_id.id]; auto& smmu = impl->host1x.MemoryManager(); if (session.has_preallocated_area) { diff --git a/src/core/hle/service/nvdrv/core/nvmap.cpp b/src/core/hle/service/nvdrv/core/nvmap.cpp index e45a06ccb..dc5455231 100755 --- a/src/core/hle/service/nvdrv/core/nvmap.cpp +++ b/src/core/hle/service/nvdrv/core/nvmap.cpp @@ -326,4 +326,17 @@ std::optional NvMap::FreeHandle(Handle::Id handle, bool interna return freeInfo; } +void NvMap::UnmapAllHandles(NvCore::SessionId session_id) { + auto handles_copy = [&] { + std::scoped_lock lk{handles_lock}; + return handles; + }(); + + for (auto& [id, handle] : handles_copy) { + if (handle->session_id.id == session_id.id) { + FreeHandle(id, false); + } + } +} + } // namespace Service::Nvidia::NvCore diff --git a/src/core/hle/service/nvdrv/core/nvmap.h b/src/core/hle/service/nvdrv/core/nvmap.h index 44cd4afd2..fd48541fd 100755 --- a/src/core/hle/service/nvdrv/core/nvmap.h +++ b/src/core/hle/service/nvdrv/core/nvmap.h @@ -152,6 +152,8 @@ public: */ std::optional FreeHandle(Handle::Id handle, bool internal_session); + void UnmapAllHandles(NvCore::SessionId session_id); + private: std::list> unmap_queue{}; std::mutex unmap_queue_lock{}; //!< Protects access to `unmap_queue` diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp index 5fa7598b1..ff0d010ee 100755 --- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp @@ -4,6 +4,7 @@ #include "common/logging/log.h" #include "common/scope_exit.h" +#include "common/string_util.h" #include "core/core.h" #include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_process.h" @@ -29,7 +30,7 @@ void NVDRV::Open(HLERequestContext& ctx) { } const auto& buffer = ctx.ReadBuffer(); - const std::string device_name(buffer.begin(), buffer.end()); + const std::string device_name(Common::StringFromBuffer(buffer)); if (device_name == "/dev/nvhost-prof-gpu") { rb.Push(0); diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index e8015bd50..f40a1c8f3 100755 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -709,12 +709,12 @@ void ISystemSettingsServer::GetSettingsItemValueSize(HLERequestContext& ctx) { // The category of the setting. This corresponds to the top-level keys of // system_settings.ini. const auto setting_category_buf{ctx.ReadBuffer(0)}; - const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()}; + const std::string setting_category{Common::StringFromBuffer(setting_category_buf)}; // The name of the setting. This corresponds to the second-level keys of // system_settings.ini. const auto setting_name_buf{ctx.ReadBuffer(1)}; - const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()}; + const std::string setting_name{Common::StringFromBuffer(setting_name_buf)}; auto settings{GetSettings()}; u64 response_size{0}; @@ -732,12 +732,12 @@ void ISystemSettingsServer::GetSettingsItemValue(HLERequestContext& ctx) { // The category of the setting. This corresponds to the top-level keys of // system_settings.ini. const auto setting_category_buf{ctx.ReadBuffer(0)}; - const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()}; + const std::string setting_category{Common::StringFromBuffer(setting_category_buf)}; // The name of the setting. This corresponds to the second-level keys of // system_settings.ini. const auto setting_name_buf{ctx.ReadBuffer(1)}; - const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()}; + const std::string setting_name{Common::StringFromBuffer(setting_name_buf)}; std::vector value; auto response = GetSettingsItemValue(value, setting_category, setting_name); diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index d71e9b966..cfa076c6d 100755 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -15,6 +15,7 @@ #include "common/logging/log.h" #include "common/math_util.h" #include "common/settings.h" +#include "common/string_util.h" #include "common/swap.h" #include "core/core_timing.h" #include "core/hle/kernel/k_readable_event.h" @@ -694,9 +695,7 @@ private: void OpenLayer(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto name_buf = rp.PopRaw>(); - const auto end = std::find(name_buf.begin(), name_buf.end(), '\0'); - - const std::string display_name(name_buf.begin(), end); + const std::string display_name(Common::StringFromBuffer(name_buf)); const u64 layer_id = rp.Pop(); const u64 aruid = rp.Pop(); diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index e7b2bbfc9..76a589d9b 100755 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -10,6 +10,7 @@ #include "core/file_sys/nca_metadata.h" #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" +#include "core/file_sys/romfs_factory.h" #include "core/file_sys/submission_package.h" #include "core/hle/kernel/k_process.h" #include "core/hle/service/filesystem/filesystem.h" @@ -109,6 +110,13 @@ AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::KProcess& process, Core::S return result; } + if (nsp->IsExtractedType()) { + system.GetFileSystemController().RegisterProcess( + process.GetProcessId(), {}, + std::make_shared(*this, system.GetContentProvider(), + system.GetFileSystemController())); + } + FileSys::VirtualFile update_raw; if (ReadUpdateRaw(update_raw) == ResultStatus::Success && update_raw != nullptr) { system.GetFileSystemController().SetPackedUpdate(process.GetProcessId(), diff --git a/src/hid_core/frontend/emulated_controller.cpp b/src/hid_core/frontend/emulated_controller.cpp index e12e5a77e..819460eb5 100755 --- a/src/hid_core/frontend/emulated_controller.cpp +++ b/src/hid_core/frontend/emulated_controller.cpp @@ -110,7 +110,11 @@ void EmulatedController::ReloadFromSettings() { original_npad_type = npad_type; } - SetPollingMode(EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::Active); + // Disable special features before disconnecting + if (controller.right_polling_mode != Common::Input::PollingMode::Active) { + SetPollingMode(EmulatedDeviceIndex::RightIndex, Common::Input::PollingMode::Active); + } + Disconnect(); if (player.connected) { Connect(); @@ -1241,7 +1245,12 @@ bool EmulatedController::SetVibration(DeviceIndex device_index, const VibrationV return false; } - last_vibration_value = vibration; + // Skip duplicated vibrations + if (last_vibration_value[index] == vibration) { + return Settings::values.vibration_enabled.GetValue(); + } + + last_vibration_value[index] = vibration; if (!Settings::values.vibration_enabled) { return false; @@ -1272,7 +1281,10 @@ bool EmulatedController::SetVibration(DeviceIndex device_index, const VibrationV } VibrationValue EmulatedController::GetActualVibrationValue(DeviceIndex device_index) const { - return last_vibration_value; + if (device_index >= DeviceIndex::MaxDeviceIndex) { + return Core::HID::DEFAULT_VIBRATION_VALUE; + } + return last_vibration_value[static_cast(device_index)]; } bool EmulatedController::IsVibrationEnabled(std::size_t device_index) { diff --git a/src/hid_core/frontend/emulated_controller.h b/src/hid_core/frontend/emulated_controller.h index 168abe089..701b38300 100755 --- a/src/hid_core/frontend/emulated_controller.h +++ b/src/hid_core/frontend/emulated_controller.h @@ -581,7 +581,8 @@ private: f32 motion_sensitivity{Core::HID::MotionInput::IsAtRestStandard}; u32 turbo_button_state{0}; std::size_t nfc_handles{0}; - VibrationValue last_vibration_value{DEFAULT_VIBRATION_VALUE}; + std::array last_vibration_value{DEFAULT_VIBRATION_VALUE, + DEFAULT_VIBRATION_VALUE}; // Temporary values to avoid doing changes while the controller is in configuring mode NpadStyleIndex tmp_npad_type{NpadStyleIndex::None}; diff --git a/src/hid_core/hid_types.h b/src/hid_core/hid_types.h index 2c3f02f34..a01292a70 100755 --- a/src/hid_core/hid_types.h +++ b/src/hid_core/hid_types.h @@ -639,6 +639,15 @@ struct VibrationValue { f32 low_frequency{}; f32 high_amplitude{}; f32 high_frequency{}; + bool operator==(const VibrationValue& b) { + if (low_amplitude != b.low_amplitude || high_amplitude != b.high_amplitude) { + return false; + } + if (low_frequency != b.low_amplitude || high_frequency != b.high_frequency) { + return false; + } + return true; + } }; static_assert(sizeof(VibrationValue) == 0x10, "VibrationValue has incorrect size.");