summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt19
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.cpp49
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic.h20
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_32.cpp5
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp5
-rw-r--r--src/core/core_timing.cpp48
-rw-r--r--src/core/core_timing.h27
-rw-r--r--src/core/file_sys/ips_layer.cpp7
-rw-r--r--src/core/hle/kernel/k_capabilities.cpp6
-rw-r--r--src/core/hle/kernel/k_hardware_timer.cpp19
-rw-r--r--src/core/hle/kernel/k_page_table_base.cpp26
-rw-r--r--src/core/hle/kernel/k_page_table_base.h3
-rw-r--r--src/core/hle/kernel/k_process.cpp6
-rw-r--r--src/core/hle/kernel/kernel.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/applet_resource.cpp18
-rw-r--r--src/core/hle/service/hid/controllers/applet_resource.h94
-rw-r--r--src/core/hle/service/hid/controllers/capture_button.cpp38
-rw-r--r--src/core/hle/service/hid/controllers/capture_button.h (renamed from src/core/hle/service/hid/controllers/stubbed.h)8
-rw-r--r--src/core/hle/service/hid/controllers/console_six_axis.cpp15
-rw-r--r--src/core/hle/service/hid/controllers/console_six_axis.h6
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.cpp5
-rw-r--r--src/core/hle/service/hid/controllers/controller_base.h8
-rw-r--r--src/core/hle/service/hid/controllers/debug_mouse.cpp63
-rw-r--r--src/core/hle/service/hid/controllers/debug_mouse.h34
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.cpp16
-rw-r--r--src/core/hle/service/hid/controllers/debug_pad.h6
-rw-r--r--src/core/hle/service/hid/controllers/digitizer.cpp38
-rw-r--r--src/core/hle/service/hid/controllers/digitizer.h27
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp41
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h5
-rw-r--r--src/core/hle/service/hid/controllers/home_button.cpp38
-rw-r--r--src/core/hle/service/hid/controllers/home_button.h27
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp16
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.h6
-rw-r--r--src/core/hle/service/hid/controllers/mouse.cpp15
-rw-r--r--src/core/hle/service/hid/controllers/mouse.h5
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp51
-rw-r--r--src/core/hle/service/hid/controllers/npad.h11
-rw-r--r--src/core/hle/service/hid/controllers/shared_memory_holder.cpp3
-rw-r--r--src/core/hle/service/hid/controllers/six_axis.cpp24
-rw-r--r--src/core/hle/service/hid/controllers/sleep_button.cpp38
-rw-r--r--src/core/hle/service/hid/controllers/sleep_button.h27
-rw-r--r--src/core/hle/service/hid/controllers/stubbed.cpp31
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp17
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.h4
-rw-r--r--src/core/hle/service/hid/controllers/types/shared_memory_format.h (renamed from src/core/hle/service/hid/controllers/shared_memory_format.h)0
-rw-r--r--src/core/hle/service/hid/controllers/unique_pad.cpp38
-rw-r--r--src/core/hle/service/hid/controllers/unique_pad.h27
-rw-r--r--src/core/hle/service/hid/hidbus.cpp8
-rw-r--r--src/core/hle/service/hid/hidbus.h2
-rw-r--r--src/core/hle/service/hid/resource_manager.cpp149
-rw-r--r--src/core/hle/service/hid/resource_manager.h26
-rw-r--r--src/core/hle/service/jit/jit.cpp59
-rw-r--r--src/core/hle/service/jit/jit_code_memory.cpp54
-rw-r--r--src/core/hle/service/jit/jit_code_memory.h49
-rw-r--r--src/core/hle/service/nvnflinger/nvnflinger.cpp8
-rw-r--r--src/core/memory.cpp86
-rw-r--r--src/core/memory.h7
-rw-r--r--src/core/memory/cheat_engine.cpp8
-rw-r--r--src/core/memory/cheat_engine.h2
-rw-r--r--src/core/tools/freezer.cpp17
-rw-r--r--src/core/tools/freezer.h2
62 files changed, 1134 insertions, 385 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 96ab39cb8..dfba79267 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -553,17 +553,26 @@ add_library(core STATIC
hle/service/hid/controllers/types/keyboard_types.h
hle/service/hid/controllers/types/mouse_types.h
hle/service/hid/controllers/types/npad_types.h
+ hle/service/hid/controllers/types/shared_memory_format.h
hle/service/hid/controllers/types/touch_types.h
hle/service/hid/controllers/applet_resource.cpp
hle/service/hid/controllers/applet_resource.h
+ hle/service/hid/controllers/capture_button.cpp
+ hle/service/hid/controllers/capture_button.h
hle/service/hid/controllers/console_six_axis.cpp
hle/service/hid/controllers/console_six_axis.h
hle/service/hid/controllers/controller_base.cpp
hle/service/hid/controllers/controller_base.h
+ hle/service/hid/controllers/debug_mouse.cpp
+ hle/service/hid/controllers/debug_mouse.h
hle/service/hid/controllers/debug_pad.cpp
hle/service/hid/controllers/debug_pad.h
+ hle/service/hid/controllers/digitizer.cpp
+ hle/service/hid/controllers/digitizer.h
hle/service/hid/controllers/gesture.cpp
hle/service/hid/controllers/gesture.h
+ hle/service/hid/controllers/home_button.cpp
+ hle/service/hid/controllers/home_button.h
hle/service/hid/controllers/keyboard.cpp
hle/service/hid/controllers/keyboard.h
hle/service/hid/controllers/mouse.cpp
@@ -574,15 +583,16 @@ add_library(core STATIC
hle/service/hid/controllers/palma.h
hle/service/hid/controllers/seven_six_axis.cpp
hle/service/hid/controllers/seven_six_axis.h
- hle/service/hid/controllers/shared_memory_format.h
hle/service/hid/controllers/shared_memory_holder.cpp
hle/service/hid/controllers/shared_memory_holder.h
hle/service/hid/controllers/six_axis.cpp
hle/service/hid/controllers/six_axis.h
- hle/service/hid/controllers/stubbed.cpp
- hle/service/hid/controllers/stubbed.h
+ hle/service/hid/controllers/sleep_button.cpp
+ hle/service/hid/controllers/sleep_button.h
hle/service/hid/controllers/touchscreen.cpp
hle/service/hid/controllers/touchscreen.h
+ hle/service/hid/controllers/unique_pad.cpp
+ hle/service/hid/controllers/unique_pad.h
hle/service/hid/hidbus/hidbus_base.cpp
hle/service/hid/hidbus/hidbus_base.h
hle/service/hid/hidbus/ringcon.cpp
@@ -978,6 +988,7 @@ endif()
if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
target_sources(core PRIVATE
+ arm/dynarmic/arm_dynarmic.cpp
arm/dynarmic/arm_dynarmic.h
arm/dynarmic/arm_dynarmic_64.cpp
arm/dynarmic/arm_dynarmic_64.h
@@ -987,6 +998,8 @@ if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
arm/dynarmic/dynarmic_cp15.h
arm/dynarmic/dynarmic_exclusive_monitor.cpp
arm/dynarmic/dynarmic_exclusive_monitor.h
+ hle/service/jit/jit_code_memory.cpp
+ hle/service/jit/jit_code_memory.h
hle/service/jit/jit_context.cpp
hle/service/jit/jit_context.h
hle/service/jit/jit.cpp
diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp
new file mode 100644
index 000000000..e6e9fc45b
--- /dev/null
+++ b/src/core/arm/dynarmic/arm_dynarmic.cpp
@@ -0,0 +1,49 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#ifdef __linux__
+
+#include "common/signal_chain.h"
+
+#include "core/arm/dynarmic/arm_dynarmic.h"
+#include "core/hle/kernel/k_process.h"
+#include "core/memory.h"
+
+namespace Core {
+
+namespace {
+
+thread_local Core::Memory::Memory* g_current_memory{};
+std::once_flag g_registered{};
+struct sigaction g_old_segv {};
+
+void HandleSigSegv(int sig, siginfo_t* info, void* ctx) {
+ if (g_current_memory && g_current_memory->InvalidateSeparateHeap(info->si_addr)) {
+ return;
+ }
+
+ return g_old_segv.sa_sigaction(sig, info, ctx);
+}
+
+} // namespace
+
+ScopedJitExecution::ScopedJitExecution(Kernel::KProcess* process) {
+ g_current_memory = std::addressof(process->GetMemory());
+}
+
+ScopedJitExecution::~ScopedJitExecution() {
+ g_current_memory = nullptr;
+}
+
+void ScopedJitExecution::RegisterHandler() {
+ std::call_once(g_registered, [] {
+ struct sigaction sa {};
+ sa.sa_sigaction = &HandleSigSegv;
+ sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
+ Common::SigAction(SIGSEGV, std::addressof(sa), std::addressof(g_old_segv));
+ });
+}
+
+} // namespace Core
+
+#endif
diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h
index eef7c3116..53dd18815 100644
--- a/src/core/arm/dynarmic/arm_dynarmic.h
+++ b/src/core/arm/dynarmic/arm_dynarmic.h
@@ -26,4 +26,24 @@ constexpr HaltReason TranslateHaltReason(Dynarmic::HaltReason hr) {
return static_cast<HaltReason>(hr);
}
+#ifdef __linux__
+
+class ScopedJitExecution {
+public:
+ explicit ScopedJitExecution(Kernel::KProcess* process);
+ ~ScopedJitExecution();
+ static void RegisterHandler();
+};
+
+#else
+
+class ScopedJitExecution {
+public:
+ explicit ScopedJitExecution(Kernel::KProcess* process) {}
+ ~ScopedJitExecution() {}
+ static void RegisterHandler() {}
+};
+
+#endif
+
} // namespace Core
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
index c78cfd528..36478f722 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp
@@ -331,11 +331,15 @@ bool ArmDynarmic32::IsInThumbMode() const {
}
HaltReason ArmDynarmic32::RunThread(Kernel::KThread* thread) {
+ ScopedJitExecution sj(thread->GetOwnerProcess());
+
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Run());
}
HaltReason ArmDynarmic32::StepThread(Kernel::KThread* thread) {
+ ScopedJitExecution sj(thread->GetOwnerProcess());
+
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Step());
}
@@ -377,6 +381,7 @@ ArmDynarmic32::ArmDynarmic32(System& system, bool uses_wall_clock, Kernel::KProc
m_cp15(std::make_shared<DynarmicCP15>(*this)), m_core_index{core_index} {
auto& page_table_impl = process->GetPageTable().GetBasePageTable().GetImpl();
m_jit = MakeJit(&page_table_impl);
+ ScopedJitExecution::RegisterHandler();
}
ArmDynarmic32::~ArmDynarmic32() = default;
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index f351b13d9..c811c8ad5 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -362,11 +362,15 @@ std::shared_ptr<Dynarmic::A64::Jit> ArmDynarmic64::MakeJit(Common::PageTable* pa
}
HaltReason ArmDynarmic64::RunThread(Kernel::KThread* thread) {
+ ScopedJitExecution sj(thread->GetOwnerProcess());
+
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Run());
}
HaltReason ArmDynarmic64::StepThread(Kernel::KThread* thread) {
+ ScopedJitExecution sj(thread->GetOwnerProcess());
+
m_jit->ClearExclusiveState();
return TranslateHaltReason(m_jit->Step());
}
@@ -406,6 +410,7 @@ ArmDynarmic64::ArmDynarmic64(System& system, bool uses_wall_clock, Kernel::KProc
auto& page_table = process->GetPageTable().GetBasePageTable();
auto& page_table_impl = page_table.GetImpl();
m_jit = MakeJit(&page_table_impl, page_table.GetAddressSpaceWidth());
+ ScopedJitExecution::RegisterHandler();
}
ArmDynarmic64::~ArmDynarmic64() = default;
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index d6b5abc68..fc536413b 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -29,7 +29,6 @@ std::shared_ptr<EventType> CreateEvent(std::string name, TimedCallback&& callbac
struct CoreTiming::Event {
s64 time;
u64 fifo_order;
- std::uintptr_t user_data;
std::weak_ptr<EventType> type;
s64 reschedule_time;
heap_t::handle_type handle{};
@@ -67,17 +66,15 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
event_fifo_id = 0;
shutting_down = false;
cpu_ticks = 0;
- const auto empty_timed_callback = [](std::uintptr_t, u64, std::chrono::nanoseconds)
- -> std::optional<std::chrono::nanoseconds> { return std::nullopt; };
- ev_lost = CreateEvent("_lost_event", empty_timed_callback);
if (is_multicore) {
timer_thread = std::make_unique<std::jthread>(ThreadEntry, std::ref(*this));
}
}
void CoreTiming::ClearPendingEvents() {
- std::scoped_lock lock{basic_lock};
+ std::scoped_lock lock{advance_lock, basic_lock};
event_queue.clear();
+ event.Set();
}
void CoreTiming::Pause(bool is_paused) {
@@ -119,14 +116,12 @@ bool CoreTiming::HasPendingEvents() const {
}
void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
- const std::shared_ptr<EventType>& event_type,
- std::uintptr_t user_data, bool absolute_time) {
+ const std::shared_ptr<EventType>& event_type, bool absolute_time) {
{
std::scoped_lock scope{basic_lock};
const auto next_time{absolute_time ? ns_into_future : GetGlobalTimeNs() + ns_into_future};
- auto h{event_queue.emplace(
- Event{next_time.count(), event_fifo_id++, user_data, event_type, 0})};
+ auto h{event_queue.emplace(Event{next_time.count(), event_fifo_id++, event_type, 0})};
(*h).handle = h;
}
@@ -136,13 +131,13 @@ void CoreTiming::ScheduleEvent(std::chrono::nanoseconds ns_into_future,
void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
std::chrono::nanoseconds resched_time,
const std::shared_ptr<EventType>& event_type,
- std::uintptr_t user_data, bool absolute_time) {
+ bool absolute_time) {
{
std::scoped_lock scope{basic_lock};
const auto next_time{absolute_time ? start_time : GetGlobalTimeNs() + start_time};
- auto h{event_queue.emplace(Event{next_time.count(), event_fifo_id++, user_data, event_type,
- resched_time.count()})};
+ auto h{event_queue.emplace(
+ Event{next_time.count(), event_fifo_id++, event_type, resched_time.count()})};
(*h).handle = h;
}
@@ -150,14 +145,14 @@ void CoreTiming::ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
}
void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
- std::uintptr_t user_data, bool wait) {
+ UnscheduleEventType type) {
{
std::scoped_lock lk{basic_lock};
std::vector<heap_t::handle_type> to_remove;
for (auto itr = event_queue.begin(); itr != event_queue.end(); itr++) {
const Event& e = *itr;
- if (e.type.lock().get() == event_type.get() && e.user_data == user_data) {
+ if (e.type.lock().get() == event_type.get()) {
to_remove.push_back(itr->handle);
}
}
@@ -165,10 +160,12 @@ void CoreTiming::UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
for (auto h : to_remove) {
event_queue.erase(h);
}
+
+ event_type->sequence_number++;
}
// Force any in-progress events to finish
- if (wait) {
+ if (type == UnscheduleEventType::Wait) {
std::scoped_lock lk{advance_lock};
}
}
@@ -208,28 +205,31 @@ std::optional<s64> CoreTiming::Advance() {
const Event& evt = event_queue.top();
if (const auto event_type{evt.type.lock()}) {
- if (evt.reschedule_time == 0) {
- const auto evt_user_data = evt.user_data;
- const auto evt_time = evt.time;
+ const auto evt_time = evt.time;
+ const auto evt_sequence_num = event_type->sequence_number;
+ if (evt.reschedule_time == 0) {
event_queue.pop();
basic_lock.unlock();
event_type->callback(
- evt_user_data, evt_time,
- std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time});
+ evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time});
basic_lock.lock();
} else {
basic_lock.unlock();
const auto new_schedule_time{event_type->callback(
- evt.user_data, evt.time,
- std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt.time})};
+ evt_time, std::chrono::nanoseconds{GetGlobalTimeNs().count() - evt_time})};
basic_lock.lock();
+ if (evt_sequence_num != event_type->sequence_number) {
+ // Heap handle is invalidated after external modification.
+ continue;
+ }
+
const auto next_schedule_time{new_schedule_time.has_value()
? new_schedule_time.value().count()
: evt.reschedule_time};
@@ -241,8 +241,8 @@ std::optional<s64> CoreTiming::Advance() {
next_time = pause_end_time + next_schedule_time;
}
- event_queue.update(evt.handle, Event{next_time, event_fifo_id++, evt.user_data,
- evt.type, next_schedule_time, evt.handle});
+ event_queue.update(evt.handle, Event{next_time, event_fifo_id++, evt.type,
+ next_schedule_time, evt.handle});
}
}
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 21548f0a9..7e4dff7f3 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -22,17 +22,25 @@ namespace Core::Timing {
/// A callback that may be scheduled for a particular core timing event.
using TimedCallback = std::function<std::optional<std::chrono::nanoseconds>(
- std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)>;
+ s64 time, std::chrono::nanoseconds ns_late)>;
/// Contains the characteristics of a particular event.
struct EventType {
explicit EventType(TimedCallback&& callback_, std::string&& name_)
- : callback{std::move(callback_)}, name{std::move(name_)} {}
+ : callback{std::move(callback_)}, name{std::move(name_)}, sequence_number{0} {}
/// The event's callback function.
TimedCallback callback;
/// A pointer to the name of the event.
const std::string name;
+ /// A monotonic sequence number, incremented when this event is
+ /// changed externally.
+ size_t sequence_number;
+};
+
+enum class UnscheduleEventType {
+ Wait,
+ NoWait,
};
/**
@@ -89,23 +97,17 @@ public:
/// Schedules an event in core timing
void ScheduleEvent(std::chrono::nanoseconds ns_into_future,
- const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data = 0,
- bool absolute_time = false);
+ const std::shared_ptr<EventType>& event_type, bool absolute_time = false);
/// Schedules an event which will automatically re-schedule itself with the given time, until
/// unscheduled
void ScheduleLoopingEvent(std::chrono::nanoseconds start_time,
std::chrono::nanoseconds resched_time,
const std::shared_ptr<EventType>& event_type,
- std::uintptr_t user_data = 0, bool absolute_time = false);
+ bool absolute_time = false);
- void UnscheduleEvent(const std::shared_ptr<EventType>& event_type, std::uintptr_t user_data,
- bool wait = true);
-
- void UnscheduleEventWithoutWait(const std::shared_ptr<EventType>& event_type,
- std::uintptr_t user_data) {
- UnscheduleEvent(event_type, user_data, false);
- }
+ void UnscheduleEvent(const std::shared_ptr<EventType>& event_type,
+ UnscheduleEventType type = UnscheduleEventType::Wait);
void AddTicks(u64 ticks_to_add);
@@ -158,7 +160,6 @@ private:
heap_t event_queue;
u64 event_fifo_id = 0;
- std::shared_ptr<EventType> ev_lost;
Common::Event event{};
Common::Event pause_event{};
mutable std::mutex basic_lock;
diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp
index 7be1322cc..31033634c 100644
--- a/src/core/file_sys/ips_layer.cpp
+++ b/src/core/file_sys/ips_layer.cpp
@@ -73,6 +73,9 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
return nullptr;
auto in_data = in->ReadAllBytes();
+ if (in_data.size() == 0) {
+ return nullptr;
+ }
std::vector<u8> temp(type == IPSFileType::IPS ? 3 : 4);
u64 offset = 5; // After header
@@ -88,6 +91,10 @@ VirtualFile PatchIPS(const VirtualFile& in, const VirtualFile& ips) {
else
real_offset = (temp[0] << 16) | (temp[1] << 8) | temp[2];
+ if (real_offset > in_data.size()) {
+ return nullptr;
+ }
+
u16 data_size{};
if (ips->ReadObject(&data_size, offset) != sizeof(u16))
return nullptr;
diff --git a/src/core/hle/kernel/k_capabilities.cpp b/src/core/hle/kernel/k_capabilities.cpp
index 274fee493..d2288c30d 100644
--- a/src/core/hle/kernel/k_capabilities.cpp
+++ b/src/core/hle/kernel/k_capabilities.cpp
@@ -185,6 +185,10 @@ Result KCapabilities::ProcessMapRegionCapability(const u32 cap, F f) {
case RegionType::NoMapping:
break;
case RegionType::KernelTraceBuffer:
+ if constexpr (!IsKTraceEnabled) {
+ break;
+ }
+ [[fallthrough]];
case RegionType::OnMemoryBootImage:
case RegionType::DTB:
R_TRY(f(MemoryRegions[static_cast<u32>(type)], perm));
@@ -330,8 +334,6 @@ Result KCapabilities::SetCapabilities(std::span<const u32> caps, KProcessPageTab
// Map the range.
R_TRY(this->MapRange_(cap, size_cap, page_table));
- } else if (GetCapabilityType(cap) == CapabilityType::MapRegion && !IsKTraceEnabled) {
- continue;
} else {
R_TRY(this->SetCapability(cap, set_flags, set_svc, page_table));
}
diff --git a/src/core/hle/kernel/k_hardware_timer.cpp b/src/core/hle/kernel/k_hardware_timer.cpp
index 8e2e40307..4e947dd6b 100644
--- a/src/core/hle/kernel/k_hardware_timer.cpp
+++ b/src/core/hle/kernel/k_hardware_timer.cpp
@@ -10,15 +10,15 @@ namespace Kernel {
void KHardwareTimer::Initialize() {
// Create the timing callback to register with CoreTiming.
- m_event_type = Core::Timing::CreateEvent(
- "KHardwareTimer::Callback", [](std::uintptr_t timer_handle, s64, std::chrono::nanoseconds) {
- reinterpret_cast<KHardwareTimer*>(timer_handle)->DoTask();
- return std::nullopt;
- });
+ m_event_type = Core::Timing::CreateEvent("KHardwareTimer::Callback",
+ [this](s64, std::chrono::nanoseconds) {
+ this->DoTask();
+ return std::nullopt;
+ });
}
void KHardwareTimer::Finalize() {
- m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type, reinterpret_cast<uintptr_t>(this));
+ m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type);
m_wakeup_time = std::numeric_limits<s64>::max();
m_event_type.reset();
}
@@ -57,13 +57,12 @@ void KHardwareTimer::EnableInterrupt(s64 wakeup_time) {
m_wakeup_time = wakeup_time;
m_kernel.System().CoreTiming().ScheduleEvent(std::chrono::nanoseconds{m_wakeup_time},
- m_event_type, reinterpret_cast<uintptr_t>(this),
- true);
+ m_event_type, true);
}
void KHardwareTimer::DisableInterrupt() {
- m_kernel.System().CoreTiming().UnscheduleEventWithoutWait(m_event_type,
- reinterpret_cast<uintptr_t>(this));
+ m_kernel.System().CoreTiming().UnscheduleEvent(m_event_type,
+ Core::Timing::UnscheduleEventType::NoWait);
m_wakeup_time = std::numeric_limits<s64>::max();
}
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp
index 423289145..8c1549559 100644
--- a/src/core/hle/kernel/k_page_table_base.cpp
+++ b/src/core/hle/kernel/k_page_table_base.cpp
@@ -434,7 +434,7 @@ Result KPageTableBase::InitializeForProcess(Svc::CreateProcessFlag as_type, bool
void KPageTableBase::Finalize() {
auto HostUnmapCallback = [&](KProcessAddress addr, u64 size) {
if (Settings::IsFastmemEnabled()) {
- m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size);
+ m_system.DeviceMemory().buffer.Unmap(GetInteger(addr), size, false);
}
};
@@ -5243,7 +5243,7 @@ Result KPageTableBase::MapPhysicalMemory(KProcessAddress address, size_t size) {
// Unmap.
R_ASSERT(this->Operate(updater.GetPageList(), cur_address,
cur_pages, 0, false, unmap_properties,
- OperationType::Unmap, true));
+ OperationType::UnmapPhysical, true));
}
// Check if we're done.
@@ -5326,7 +5326,7 @@ Result KPageTableBase::MapPhysicalMemory(KProcessAddress address, size_t size) {
// Map the papges.
R_TRY(this->Operate(updater.GetPageList(), cur_address, map_pages,
cur_pg, map_properties,
- OperationType::MapFirstGroup, false));
+ OperationType::MapFirstGroupPhysical, false));
}
}
@@ -5480,7 +5480,7 @@ Result KPageTableBase::UnmapPhysicalMemory(KProcessAddress address, size_t size)
// Unmap.
R_ASSERT(this->Operate(updater.GetPageList(), cur_address, cur_pages, 0, false,
- unmap_properties, OperationType::Unmap, false));
+ unmap_properties, OperationType::UnmapPhysical, false));
}
// Check if we're done.
@@ -5655,7 +5655,10 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
// or free them to the page list, and so it goes unused (along with page properties).
switch (operation) {
- case OperationType::Unmap: {
+ case OperationType::Unmap:
+ case OperationType::UnmapPhysical: {
+ const bool separate_heap = operation == OperationType::UnmapPhysical;
+
// Ensure that any pages we track are closed on exit.
KPageGroup pages_to_close(m_kernel, this->GetBlockInfoManager());
SCOPE_EXIT({ pages_to_close.CloseAndReset(); });
@@ -5664,7 +5667,7 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
this->MakePageGroup(pages_to_close, virt_addr, num_pages);
// Unmap.
- m_memory->UnmapRegion(*m_impl, virt_addr, num_pages * PageSize);
+ m_memory->UnmapRegion(*m_impl, virt_addr, num_pages * PageSize, separate_heap);
R_SUCCEED();
}
@@ -5672,7 +5675,7 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
ASSERT(virt_addr != 0);
ASSERT(Common::IsAligned(GetInteger(virt_addr), PageSize));
m_memory->MapMemoryRegion(*m_impl, virt_addr, num_pages * PageSize, phys_addr,
- ConvertToMemoryPermission(properties.perm));
+ ConvertToMemoryPermission(properties.perm), false);
// Open references to pages, if we should.
if (this->IsHeapPhysicalAddress(phys_addr)) {
@@ -5711,16 +5714,19 @@ Result KPageTableBase::Operate(PageLinkedList* page_list, KProcessAddress virt_a
switch (operation) {
case OperationType::MapGroup:
- case OperationType::MapFirstGroup: {
+ case OperationType::MapFirstGroup:
+ case OperationType::MapFirstGroupPhysical: {
+ const bool separate_heap = operation == OperationType::MapFirstGroupPhysical;
+
// We want to maintain a new reference to every page in the group.
- KScopedPageGroup spg(page_group, operation != OperationType::MapFirstGroup);
+ KScopedPageGroup spg(page_group, operation == OperationType::MapGroup);
for (const auto& node : page_group) {
const size_t size{node.GetNumPages() * PageSize};
// Map the pages.
m_memory->MapMemoryRegion(*m_impl, virt_addr, size, node.GetAddress(),
- ConvertToMemoryPermission(properties.perm));
+ ConvertToMemoryPermission(properties.perm), separate_heap);
virt_addr += size;
}
diff --git a/src/core/hle/kernel/k_page_table_base.h b/src/core/hle/kernel/k_page_table_base.h
index 556d230b3..077cafc96 100644
--- a/src/core/hle/kernel/k_page_table_base.h
+++ b/src/core/hle/kernel/k_page_table_base.h
@@ -104,6 +104,9 @@ protected:
ChangePermissionsAndRefresh = 5,
ChangePermissionsAndRefreshAndFlush = 6,
Separate = 7,
+
+ MapFirstGroupPhysical = 65000,
+ UnmapPhysical = 65001,
};
static constexpr size_t MaxPhysicalMapAlignment = 1_GiB;
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index d6869c228..068e71dff 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -1237,8 +1237,10 @@ void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) {
auto& buffer = m_kernel.System().DeviceMemory().buffer;
const auto& code = code_set.CodeSegment();
const auto& patch = code_set.PatchSegment();
- buffer.Protect(GetInteger(base_addr + code.addr), code.size, true, true, true);
- buffer.Protect(GetInteger(base_addr + patch.addr), patch.size, true, true, true);
+ buffer.Protect(GetInteger(base_addr + code.addr), code.size,
+ Common::MemoryPermission::Read | Common::MemoryPermission::Execute);
+ buffer.Protect(GetInteger(base_addr + patch.addr), patch.size,
+ Common::MemoryPermission::Read | Common::MemoryPermission::Execute);
ReprotectSegment(code_set.PatchSegment(), Svc::MemoryPermission::None);
}
#endif
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index c14d2d2f3..1030f0c12 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -238,7 +238,7 @@ struct KernelCore::Impl {
void InitializePreemption(KernelCore& kernel) {
preemption_event = Core::Timing::CreateEvent(
"PreemptionCallback",
- [this, &kernel](std::uintptr_t, s64 time,
+ [this, &kernel](s64 time,
std::chrono::nanoseconds) -> std::optional<std::chrono::nanoseconds> {
{
KScopedSchedulerLock lock(kernel);
diff --git a/src/core/hle/service/hid/controllers/applet_resource.cpp b/src/core/hle/service/hid/controllers/applet_resource.cpp
index c8e74c764..b4ff663c2 100644
--- a/src/core/hle/service/hid/controllers/applet_resource.cpp
+++ b/src/core/hle/service/hid/controllers/applet_resource.cpp
@@ -4,7 +4,7 @@
#include "core/core.h"
#include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/service/hid/controllers/applet_resource.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
#include "core/hle/service/hid/errors.h"
namespace Service::HID {
@@ -164,6 +164,22 @@ Result AppletResource::GetSharedMemoryFormat(SharedMemoryFormat** out_shared_mem
return ResultSuccess;
}
+AruidData* AppletResource::GetAruidData(u64 aruid) {
+ const u64 aruid_index = GetIndexFromAruid(aruid);
+ if (aruid_index == AruidIndexMax) {
+ return nullptr;
+ }
+ return &data[aruid_index];
+}
+
+AruidData* AppletResource::GetAruidDataByIndex(std::size_t aruid_index) {
+ return &data[aruid_index];
+}
+
+bool AppletResource::IsVibrationAruidActive(u64 aruid) const {
+ return aruid == 0 || aruid == active_vibration_aruid;
+}
+
u64 AppletResource::GetIndexFromAruid(u64 aruid) {
for (std::size_t i = 0; i < AruidIndexMax; i++) {
if (registration_list.flag[i] == RegistrationStatus::Initialized &&
diff --git a/src/core/hle/service/hid/controllers/applet_resource.h b/src/core/hle/service/hid/controllers/applet_resource.h
index e7991f93a..52cc4cf42 100644
--- a/src/core/hle/service/hid/controllers/applet_resource.h
+++ b/src/core/hle/service/hid/controllers/applet_resource.h
@@ -4,6 +4,7 @@
#pragma once
#include <array>
+#include <mutex>
#include "common/bit_field.h"
#include "common/common_types.h"
@@ -20,6 +21,59 @@ class KSharedMemory;
namespace Service::HID {
struct SharedMemoryFormat;
+class AppletResource;
+class NPadResource;
+
+static constexpr std::size_t AruidIndexMax = 0x20;
+
+enum class RegistrationStatus : u32 {
+ None,
+ Initialized,
+ PendingDelete,
+};
+
+struct DataStatusFlag {
+ union {
+ u32 raw{};
+
+ BitField<0, 1, u32> is_initialized;
+ BitField<1, 1, u32> is_assigned;
+ BitField<16, 1, u32> enable_pad_input;
+ BitField<17, 1, u32> enable_six_axis_sensor;
+ BitField<18, 1, u32> bit_18;
+ BitField<19, 1, u32> is_palma_connectable;
+ BitField<20, 1, u32> enable_palma_boost_mode;
+ BitField<21, 1, u32> enable_touchscreen;
+ };
+};
+
+struct AruidRegisterList {
+ std::array<RegistrationStatus, AruidIndexMax> flag{};
+ std::array<u64, AruidIndexMax> aruid{};
+};
+static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size");
+
+struct AruidData {
+ DataStatusFlag flag{};
+ u64 aruid{};
+ SharedMemoryFormat* shared_memory_format{nullptr};
+};
+
+struct HandheldConfig {
+ bool is_handheld_hid_enabled;
+ bool is_force_handheld;
+ bool is_joycon_rail_enabled;
+ bool is_force_handheld_style_vibration;
+};
+static_assert(sizeof(HandheldConfig) == 0x4, "HandheldConfig is an invalid size");
+
+struct AppletResourceHolder {
+ std::shared_ptr<AppletResource> applet_resource{nullptr};
+ std::recursive_mutex* shared_mutex{nullptr};
+ NPadResource* shared_npad_resource{nullptr};
+ std::shared_ptr<HandheldConfig> handheld_config{nullptr};
+ long* handle_1;
+};
class AppletResource {
public:
@@ -36,6 +90,10 @@ public:
u64 GetActiveAruid();
Result GetSharedMemoryHandle(Kernel::KSharedMemory** out_handle, u64 aruid);
Result GetSharedMemoryFormat(SharedMemoryFormat** out_shared_memory_format, u64 aruid);
+ AruidData* GetAruidData(u64 aruid);
+ AruidData* GetAruidDataByIndex(std::size_t aruid_index);
+
+ bool IsVibrationAruidActive(u64 aruid) const;
u64 GetIndexFromAruid(u64 aruid);
@@ -52,46 +110,12 @@ public:
Result UnregisterCoreAppletResource();
private:
- static constexpr std::size_t AruidIndexMax = 0x20;
-
- enum RegistrationStatus : u32 {
- None,
- Initialized,
- PendingDelete,
- };
-
- struct DataStatusFlag {
- union {
- u32 raw{};
-
- BitField<0, 1, u32> is_initialized;
- BitField<1, 1, u32> is_assigned;
- BitField<16, 1, u32> enable_pad_input;
- BitField<17, 1, u32> enable_six_axis_sensor;
- BitField<18, 1, u32> bit_18;
- BitField<19, 1, u32> is_palma_connectable;
- BitField<20, 1, u32> enable_palma_boost_mode;
- BitField<21, 1, u32> enable_touchscreen;
- };
- };
-
- struct AruidRegisterList {
- std::array<RegistrationStatus, AruidIndexMax> flag{};
- std::array<u64, AruidIndexMax> aruid{};
- };
- static_assert(sizeof(AruidRegisterList) == 0x180, "AruidRegisterList is an invalid size");
-
- struct AruidData {
- DataStatusFlag flag{};
- u64 aruid{};
- SharedMemoryFormat* shared_memory_format{nullptr};
- };
-
u64 active_aruid{};
AruidRegisterList registration_list{};
std::array<AruidData, AruidIndexMax> data{};
std::array<SharedMemoryHolder, AruidIndexMax> shared_memory_holder{};
s32 ref_counter{};
+ u64 active_vibration_aruid;
Core::System& system;
};
diff --git a/src/core/hle/service/hid/controllers/capture_button.cpp b/src/core/hle/service/hid/controllers/capture_button.cpp
new file mode 100644
index 000000000..8b486fcb5
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/capture_button.cpp
@@ -0,0 +1,38 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core_timing.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
+#include "core/hle/service/hid/controllers/capture_button.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
+
+namespace Service::HID {
+
+CaptureButton::CaptureButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
+
+CaptureButton::~CaptureButton() = default;
+
+void CaptureButton::OnInit() {}
+
+void CaptureButton::OnRelease() {}
+
+void CaptureButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ if (!smart_update) {
+ return;
+ }
+
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ auto& header = data->shared_memory_format->capture_button.header;
+ header.timestamp = core_timing.GetGlobalTimeNs().count();
+ header.total_entry_count = 17;
+ header.entry_count = 0;
+ header.last_entry_index = 0;
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/stubbed.h b/src/core/hle/service/hid/controllers/capture_button.h
index d2052fb17..dcc4715c5 100644
--- a/src/core/hle/service/hid/controllers/stubbed.h
+++ b/src/core/hle/service/hid/controllers/capture_button.h
@@ -6,12 +6,11 @@
#include "core/hle/service/hid/controllers/controller_base.h"
namespace Service::HID {
-struct CommonHeader;
-class Controller_Stubbed final : public ControllerBase {
+class CaptureButton final : public ControllerBase {
public:
- explicit Controller_Stubbed(Core::HID::HIDCore& hid_core_, CommonHeader& ring_lifo_header);
- ~Controller_Stubbed() override;
+ explicit CaptureButton(Core::HID::HIDCore& hid_core_);
+ ~CaptureButton() override;
// Called when the controller is initialized
void OnInit() override;
@@ -23,7 +22,6 @@ public:
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
private:
- CommonHeader& header;
bool smart_update{};
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.cpp b/src/core/hle/service/hid/controllers/console_six_axis.cpp
index 3961d2b5f..8eba2c292 100644
--- a/src/core/hle/service/hid/controllers/console_six_axis.cpp
+++ b/src/core/hle/service/hid/controllers/console_six_axis.cpp
@@ -5,13 +5,11 @@
#include "core/hid/emulated_console.h"
#include "core/hid/hid_core.h"
#include "core/hle/service/hid/controllers/console_six_axis.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
namespace Service::HID {
-ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_,
- ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory)
- : ControllerBase{hid_core_}, shared_memory{console_shared_memory} {
+ConsoleSixAxis::ConsoleSixAxis(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
console = hid_core.GetEmulatedConsole();
}
@@ -22,6 +20,15 @@ void ConsoleSixAxis::OnInit() {}
void ConsoleSixAxis::OnRelease() {}
void ConsoleSixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ ConsoleSixAxisSensorSharedMemoryFormat& shared_memory = data->shared_memory_format->console;
+
if (!IsControllerActivated()) {
return;
}
diff --git a/src/core/hle/service/hid/controllers/console_six_axis.h b/src/core/hle/service/hid/controllers/console_six_axis.h
index 3d1c9ce23..e3351f83c 100644
--- a/src/core/hle/service/hid/controllers/console_six_axis.h
+++ b/src/core/hle/service/hid/controllers/console_six_axis.h
@@ -10,12 +10,9 @@ class EmulatedConsole;
} // namespace Core::HID
namespace Service::HID {
-struct ConsoleSixAxisSensorSharedMemoryFormat;
-
class ConsoleSixAxis final : public ControllerBase {
public:
- explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_,
- ConsoleSixAxisSensorSharedMemoryFormat& console_shared_memory);
+ explicit ConsoleSixAxis(Core::HID::HIDCore& hid_core_);
~ConsoleSixAxis() override;
// Called when the controller is initialized
@@ -28,7 +25,6 @@ public:
void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
private:
- ConsoleSixAxisSensorSharedMemoryFormat& shared_memory;
Core::HID::EmulatedConsole* console = nullptr;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/controller_base.cpp b/src/core/hle/service/hid/controllers/controller_base.cpp
index 0bcd87062..2083ccfad 100644
--- a/src/core/hle/service/hid/controllers/controller_base.cpp
+++ b/src/core/hle/service/hid/controllers/controller_base.cpp
@@ -31,4 +31,9 @@ void ControllerBase::DeactivateController() {
bool ControllerBase::IsControllerActivated() const {
return is_activated;
}
+
+void ControllerBase::SetAppletResource(std::shared_ptr<AppletResource> resource) {
+ applet_resource = resource;
+}
+
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/controller_base.h b/src/core/hle/service/hid/controllers/controller_base.h
index 4326c7821..759ae0053 100644
--- a/src/core/hle/service/hid/controllers/controller_base.h
+++ b/src/core/hle/service/hid/controllers/controller_base.h
@@ -3,8 +3,11 @@
#pragma once
+#include <memory>
+
#include "common/common_types.h"
#include "core/hle/result.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
namespace Core::Timing {
class CoreTiming;
@@ -12,7 +15,7 @@ class CoreTiming;
namespace Core::HID {
class HIDCore;
-}
+} // namespace Core::HID
namespace Service::HID {
class ControllerBase {
@@ -39,8 +42,11 @@ public:
bool IsControllerActivated() const;
+ void SetAppletResource(std::shared_ptr<AppletResource> resource);
+
protected:
bool is_activated{false};
+ std::shared_ptr<AppletResource> applet_resource{nullptr};
Core::HID::HIDCore& hid_core;
};
diff --git a/src/core/hle/service/hid/controllers/debug_mouse.cpp b/src/core/hle/service/hid/controllers/debug_mouse.cpp
new file mode 100644
index 000000000..f2f1a27f8
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/debug_mouse.cpp
@@ -0,0 +1,63 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core_timing.h"
+#include "core/frontend/emu_window.h"
+#include "core/hid/emulated_devices.h"
+#include "core/hid/hid_core.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
+#include "core/hle/service/hid/controllers/debug_mouse.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
+
+namespace Service::HID {
+
+DebugMouse::DebugMouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
+ emulated_devices = hid_core.GetEmulatedDevices();
+}
+
+DebugMouse::~DebugMouse() = default;
+
+void DebugMouse::OnInit() {}
+void DebugMouse::OnRelease() {}
+
+void DebugMouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ MouseSharedMemoryFormat& shared_memory = data->shared_memory_format->debug_mouse;
+
+ if (!IsControllerActivated()) {
+ shared_memory.mouse_lifo.buffer_count = 0;
+ shared_memory.mouse_lifo.buffer_tail = 0;
+ return;
+ }
+
+ next_state = {};
+
+ const auto& last_entry = shared_memory.mouse_lifo.ReadCurrentEntry().state;
+ next_state.sampling_number = last_entry.sampling_number + 1;
+
+ if (Settings::values.mouse_enabled) {
+ const auto& mouse_button_state = emulated_devices->GetMouseButtons();
+ const auto& mouse_position_state = emulated_devices->GetMousePosition();
+ const auto& mouse_wheel_state = emulated_devices->GetMouseWheel();
+ next_state.attribute.is_connected.Assign(1);
+ next_state.x = static_cast<s32>(mouse_position_state.x * Layout::ScreenUndocked::Width);
+ next_state.y = static_cast<s32>(mouse_position_state.y * Layout::ScreenUndocked::Height);
+ next_state.delta_x = next_state.x - last_entry.x;
+ next_state.delta_y = next_state.y - last_entry.y;
+ next_state.delta_wheel_x = mouse_wheel_state.x - last_mouse_wheel_state.x;
+ next_state.delta_wheel_y = mouse_wheel_state.y - last_mouse_wheel_state.y;
+
+ last_mouse_wheel_state = mouse_wheel_state;
+ next_state.button = mouse_button_state;
+ }
+
+ shared_memory.mouse_lifo.WriteNextEntry(next_state);
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/debug_mouse.h b/src/core/hle/service/hid/controllers/debug_mouse.h
new file mode 100644
index 000000000..ec939fa9f
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/debug_mouse.h
@@ -0,0 +1,34 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/hid/controllers/controller_base.h"
+
+namespace Core::HID {
+class EmulatedDevices;
+struct MouseState;
+struct AnalogStickState;
+} // namespace Core::HID
+
+namespace Service::HID {
+class DebugMouse final : public ControllerBase {
+public:
+ explicit DebugMouse(Core::HID::HIDCore& hid_core_);
+ ~DebugMouse() override;
+
+ // Called when the controller is initialized
+ void OnInit() override;
+
+ // When the controller is released
+ void OnRelease() override;
+
+ // When the controller is requesting an update for the shared memory
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
+
+private:
+ Core::HID::MouseState next_state{};
+ Core::HID::AnalogStickState last_mouse_wheel_state{};
+ Core::HID::EmulatedDevices* emulated_devices = nullptr;
+};
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/debug_pad.cpp b/src/core/hle/service/hid/controllers/debug_pad.cpp
index 7d2370b4f..1811cf620 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.cpp
+++ b/src/core/hle/service/hid/controllers/debug_pad.cpp
@@ -6,14 +6,13 @@
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "core/hid/hid_types.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
#include "core/hle/service/hid/controllers/debug_pad.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
namespace Service::HID {
-DebugPad::DebugPad(Core::HID::HIDCore& hid_core_,
- DebugPadSharedMemoryFormat& debug_pad_shared_memory)
- : ControllerBase{hid_core_}, shared_memory{debug_pad_shared_memory} {
+DebugPad::DebugPad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
controller = hid_core.GetEmulatedController(Core::HID::NpadIdType::Other);
}
@@ -24,6 +23,15 @@ void DebugPad::OnInit() {}
void DebugPad::OnRelease() {}
void DebugPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ DebugPadSharedMemoryFormat& shared_memory = data->shared_memory_format->debug_pad;
+
if (!IsControllerActivated()) {
shared_memory.debug_pad_lifo.buffer_count = 0;
shared_memory.debug_pad_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/debug_pad.h b/src/core/hle/service/hid/controllers/debug_pad.h
index 8ab29eca8..dd00b2402 100644
--- a/src/core/hle/service/hid/controllers/debug_pad.h
+++ b/src/core/hle/service/hid/controllers/debug_pad.h
@@ -15,12 +15,9 @@ class CoreTiming;
}
namespace Service::HID {
-struct DebugPadSharedMemoryFormat;
-
class DebugPad final : public ControllerBase {
public:
- explicit DebugPad(Core::HID::HIDCore& hid_core_,
- DebugPadSharedMemoryFormat& debug_pad_shared_memory);
+ explicit DebugPad(Core::HID::HIDCore& hid_core_);
~DebugPad() override;
// Called when the controller is initialized
@@ -34,7 +31,6 @@ public:
private:
DebugPadState next_state{};
- DebugPadSharedMemoryFormat& shared_memory;
Core::HID::EmulatedController* controller = nullptr;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/digitizer.cpp b/src/core/hle/service/hid/controllers/digitizer.cpp
new file mode 100644
index 000000000..c01580fd6
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/digitizer.cpp
@@ -0,0 +1,38 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core_timing.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
+#include "core/hle/service/hid/controllers/digitizer.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
+
+namespace Service::HID {
+
+Digitizer::Digitizer(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
+
+Digitizer::~Digitizer() = default;
+
+void Digitizer::OnInit() {}
+
+void Digitizer::OnRelease() {}
+
+void Digitizer::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ if (!smart_update) {
+ return;
+ }
+
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ auto& header = data->shared_memory_format->digitizer.header;
+ header.timestamp = core_timing.GetGlobalTimeNs().count();
+ header.total_entry_count = 17;
+ header.entry_count = 0;
+ header.last_entry_index = 0;
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/digitizer.h b/src/core/hle/service/hid/controllers/digitizer.h
new file mode 100644
index 000000000..d81f814c3
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/digitizer.h
@@ -0,0 +1,27 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/hid/controllers/controller_base.h"
+
+namespace Service::HID {
+
+class Digitizer final : public ControllerBase {
+public:
+ explicit Digitizer(Core::HID::HIDCore& hid_core_);
+ ~Digitizer() override;
+
+ // Called when the controller is initialized
+ void OnInit() override;
+
+ // When the controller is released
+ void OnRelease() override;
+
+ // When the controller is requesting an update for the shared memory
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
+
+private:
+ bool smart_update{};
+};
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp
index f658005f6..6e686fe65 100644
--- a/src/core/hle/service/hid/controllers/gesture.cpp
+++ b/src/core/hle/service/hid/controllers/gesture.cpp
@@ -6,8 +6,9 @@
#include "core/frontend/emu_window.h"
#include "core/hid/emulated_console.h"
#include "core/hid/hid_core.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
#include "core/hle/service/hid/controllers/gesture.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
namespace Service::HID {
// HW is around 700, value is set to 400 to make it easier to trigger with mouse
@@ -21,24 +22,40 @@ constexpr f32 Square(s32 num) {
return static_cast<f32>(num * num);
}
-Gesture::Gesture(Core::HID::HIDCore& hid_core_, GestureSharedMemoryFormat& gesture_shared_memory)
- : ControllerBase(hid_core_), shared_memory{gesture_shared_memory} {
+Gesture::Gesture(Core::HID::HIDCore& hid_core_) : ControllerBase(hid_core_) {
console = hid_core.GetEmulatedConsole();
}
Gesture::~Gesture() = default;
void Gesture::OnInit() {
- shared_memory.gesture_lifo.buffer_count = 0;
- shared_memory.gesture_lifo.buffer_tail = 0;
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ shared_memory = &data->shared_memory_format->gesture;
+ shared_memory->gesture_lifo.buffer_count = 0;
+ shared_memory->gesture_lifo.buffer_tail = 0;
force_update = true;
}
void Gesture::OnRelease() {}
void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ shared_memory = &data->shared_memory_format->gesture;
+
if (!IsControllerActivated()) {
- shared_memory.gesture_lifo.buffer_count = 0;
- shared_memory.gesture_lifo.buffer_tail = 0;
+ shared_memory->gesture_lifo.buffer_count = 0;
+ shared_memory->gesture_lifo.buffer_tail = 0;
return;
}
@@ -46,7 +63,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
GestureProperties gesture = GetGestureProperties();
f32 time_difference =
- static_cast<f32>(shared_memory.gesture_lifo.timestamp - last_update_timestamp) /
+ static_cast<f32>(shared_memory->gesture_lifo.timestamp - last_update_timestamp) /
(1000 * 1000 * 1000);
// Only update if necessary
@@ -54,7 +71,7 @@ void Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
return;
}
- last_update_timestamp = shared_memory.gesture_lifo.timestamp;
+ last_update_timestamp = shared_memory->gesture_lifo.timestamp;
UpdateGestureSharedMemory(gesture, time_difference);
}
@@ -97,7 +114,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif
GestureType type = GestureType::Idle;
GestureAttribute attributes{};
- const auto& last_entry = shared_memory.gesture_lifo.ReadCurrentEntry().state;
+ const auto& last_entry = shared_memory->gesture_lifo.ReadCurrentEntry().state;
// Reset next state to default
next_state.sampling_number = last_entry.sampling_number + 1;
@@ -127,7 +144,7 @@ void Gesture::UpdateGestureSharedMemory(GestureProperties& gesture, f32 time_dif
next_state.points = gesture.points;
last_gesture = gesture;
- shared_memory.gesture_lifo.WriteNextEntry(next_state);
+ shared_memory->gesture_lifo.WriteNextEntry(next_state);
}
void Gesture::NewGesture(GestureProperties& gesture, GestureType& type,
@@ -300,7 +317,7 @@ void Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_
}
const GestureState& Gesture::GetLastGestureEntry() const {
- return shared_memory.gesture_lifo.ReadCurrentEntry().state;
+ return shared_memory->gesture_lifo.ReadCurrentEntry().state;
}
GestureProperties Gesture::GetGestureProperties() {
diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h
index 41fdfcd03..78da1552a 100644
--- a/src/core/hle/service/hid/controllers/gesture.h
+++ b/src/core/hle/service/hid/controllers/gesture.h
@@ -18,8 +18,7 @@ struct GestureSharedMemoryFormat;
class Gesture final : public ControllerBase {
public:
- explicit Gesture(Core::HID::HIDCore& hid_core_,
- GestureSharedMemoryFormat& gesture_shared_memory);
+ explicit Gesture(Core::HID::HIDCore& hid_core_);
~Gesture() override;
// Called when the controller is initialized
@@ -74,7 +73,7 @@ private:
GestureProperties GetGestureProperties();
GestureState next_state{};
- GestureSharedMemoryFormat& shared_memory;
+ GestureSharedMemoryFormat* shared_memory;
Core::HID::EmulatedConsole* console = nullptr;
std::array<Core::HID::TouchFinger, MAX_POINTS> fingers{};
diff --git a/src/core/hle/service/hid/controllers/home_button.cpp b/src/core/hle/service/hid/controllers/home_button.cpp
new file mode 100644
index 000000000..71dd9bc08
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/home_button.cpp
@@ -0,0 +1,38 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core_timing.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
+#include "core/hle/service/hid/controllers/home_button.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
+
+namespace Service::HID {
+
+HomeButton::HomeButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
+
+HomeButton::~HomeButton() = default;
+
+void HomeButton::OnInit() {}
+
+void HomeButton::OnRelease() {}
+
+void HomeButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ if (!smart_update) {
+ return;
+ }
+
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ auto& header = data->shared_memory_format->home_button.header;
+ header.timestamp = core_timing.GetGlobalTimeNs().count();
+ header.total_entry_count = 17;
+ header.entry_count = 0;
+ header.last_entry_index = 0;
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/home_button.h b/src/core/hle/service/hid/controllers/home_button.h
new file mode 100644
index 000000000..e91c2aa5d
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/home_button.h
@@ -0,0 +1,27 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/hid/controllers/controller_base.h"
+
+namespace Service::HID {
+
+class HomeButton final : public ControllerBase {
+public:
+ explicit HomeButton(Core::HID::HIDCore& hid_core_);
+ ~HomeButton() override;
+
+ // Called when the controller is initialized
+ void OnInit() override;
+
+ // When the controller is released
+ void OnRelease() override;
+
+ // When the controller is requesting an update for the shared memory
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
+
+private:
+ bool smart_update{};
+};
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index 871e5036a..c72b3e5ce 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -5,14 +5,13 @@
#include "core/core_timing.h"
#include "core/hid/emulated_devices.h"
#include "core/hid/hid_core.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
#include "core/hle/service/hid/controllers/keyboard.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
namespace Service::HID {
-Keyboard::Keyboard(Core::HID::HIDCore& hid_core_,
- KeyboardSharedMemoryFormat& keyboard_shared_memory)
- : ControllerBase{hid_core_}, shared_memory{keyboard_shared_memory} {
+Keyboard::Keyboard(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
emulated_devices = hid_core.GetEmulatedDevices();
}
@@ -23,6 +22,15 @@ void Keyboard::OnInit() {}
void Keyboard::OnRelease() {}
void Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ KeyboardSharedMemoryFormat& shared_memory = data->shared_memory_format->keyboard;
+
if (!IsControllerActivated()) {
shared_memory.keyboard_lifo.buffer_count = 0;
shared_memory.keyboard_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h
index 4d72171b9..e8ca326c6 100644
--- a/src/core/hle/service/hid/controllers/keyboard.h
+++ b/src/core/hle/service/hid/controllers/keyboard.h
@@ -7,12 +7,9 @@
#include "core/hle/service/hid/controllers/types/keyboard_types.h"
namespace Service::HID {
-struct KeyboardSharedMemoryFormat;
-
class Keyboard final : public ControllerBase {
public:
- explicit Keyboard(Core::HID::HIDCore& hid_core_,
- KeyboardSharedMemoryFormat& keyboard_shared_memory);
+ explicit Keyboard(Core::HID::HIDCore& hid_core_);
~Keyboard() override;
// Called when the controller is initialized
@@ -26,7 +23,6 @@ public:
private:
KeyboardState next_state{};
- KeyboardSharedMemoryFormat& shared_memory;
Core::HID::EmulatedDevices* emulated_devices = nullptr;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp
index de5b2c804..58deafbc5 100644
--- a/src/core/hle/service/hid/controllers/mouse.cpp
+++ b/src/core/hle/service/hid/controllers/mouse.cpp
@@ -5,13 +5,13 @@
#include "core/frontend/emu_window.h"
#include "core/hid/emulated_devices.h"
#include "core/hid/hid_core.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
#include "core/hle/service/hid/controllers/mouse.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
namespace Service::HID {
-Mouse::Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory)
- : ControllerBase{hid_core_}, shared_memory{mouse_shared_memory} {
+Mouse::Mouse(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {
emulated_devices = hid_core.GetEmulatedDevices();
}
@@ -21,6 +21,15 @@ void Mouse::OnInit() {}
void Mouse::OnRelease() {}
void Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ MouseSharedMemoryFormat& shared_memory = data->shared_memory_format->mouse;
+
if (!IsControllerActivated()) {
shared_memory.mouse_lifo.buffer_count = 0;
shared_memory.mouse_lifo.buffer_tail = 0;
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h
index 363f316a5..cefad956c 100644
--- a/src/core/hle/service/hid/controllers/mouse.h
+++ b/src/core/hle/service/hid/controllers/mouse.h
@@ -12,11 +12,9 @@ struct AnalogStickState;
} // namespace Core::HID
namespace Service::HID {
-struct MouseSharedMemoryFormat;
-
class Mouse final : public ControllerBase {
public:
- explicit Mouse(Core::HID::HIDCore& hid_core_, MouseSharedMemoryFormat& mouse_shared_memory);
+ explicit Mouse(Core::HID::HIDCore& hid_core_);
~Mouse() override;
// Called when the controller is initialized
@@ -31,7 +29,6 @@ public:
private:
Core::HID::MouseState next_state{};
Core::HID::AnalogStickState last_mouse_wheel_state{};
- MouseSharedMemoryFormat& shared_memory;
Core::HID::EmulatedDevices* emulated_devices = nullptr;
};
} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 53a737cf5..c7aa606bc 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -16,8 +16,9 @@
#include "core/hid/hid_core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_readable_event.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid_util.h"
#include "core/hle/service/kernel_helpers.h"
@@ -30,12 +31,10 @@ constexpr std::array<Core::HID::NpadIdType, 10> npad_id_list{
Core::HID::NpadIdType::Handheld,
};
-NPad::NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format,
- KernelHelpers::ServiceContext& service_context_)
+NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_)
: ControllerBase{hid_core_}, service_context{service_context_} {
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
- controller.shared_memory = &npad_shared_memory_format.npad_entry[i].internal_state;
controller.device = hid_core.GetEmulatedControllerByIndex(i);
controller.vibration[Core::HID::EmulatedDeviceIndex::LeftIndex].latest_vibration_value =
Core::HID::DEFAULT_VIBRATION_VALUE;
@@ -297,12 +296,20 @@ void NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
}
void NPad::OnInit() {
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
if (!IsControllerActivated()) {
return;
}
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
+ controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state;
controller.styleset_changed_event =
service_context.CreateEvent(fmt::format("npad:NpadStyleSetChanged_{}", i));
}
@@ -355,7 +362,9 @@ void NPad::OnRelease() {
is_controller_initialized = false;
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
- service_context.CloseEvent(controller.styleset_changed_event);
+ if (controller.styleset_changed_event) {
+ service_context.CloseEvent(controller.styleset_changed_event);
+ }
for (std::size_t device_idx = 0; device_idx < controller.vibration.size(); ++device_idx) {
VibrateControllerAtIndex(controller.device->GetNpadIdType(), device_idx, {});
}
@@ -432,12 +441,20 @@ void NPad::RequestPadStateUpdate(Core::HID::NpadIdType npad_id) {
}
void NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
if (!IsControllerActivated()) {
return;
}
for (std::size_t i = 0; i < controller_data.size(); ++i) {
auto& controller = controller_data[i];
+ controller.shared_memory = &data->shared_memory_format->npad.npad_entry[i].internal_state;
auto* npad = controller.shared_memory;
const auto& controller_type = controller.device->GetNpadStyleIndex();
@@ -976,30 +993,6 @@ Result NPad::ResetIsSixAxisSensorDeviceNewlyAssigned(
return ResultSuccess;
}
-NpadSixAxisSensorLifo& NPad::GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id) {
- return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_fullkey_lifo;
-}
-
-NpadSixAxisSensorLifo& NPad::GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id) {
- return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_handheld_lifo;
-}
-
-NpadSixAxisSensorLifo& NPad::GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id) {
- return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_left_lifo;
-}
-
-NpadSixAxisSensorLifo& NPad::GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id) {
- return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_dual_right_lifo;
-}
-
-NpadSixAxisSensorLifo& NPad::GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id) {
- return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_left_lifo;
-}
-
-NpadSixAxisSensorLifo& NPad::GetSixAxisRightLifo(Core::HID::NpadIdType npad_id) {
- return GetControllerFromNpadIdType(npad_id).shared_memory->sixaxis_right_lifo;
-}
-
Result NPad::MergeSingleJoyAsDualJoy(Core::HID::NpadIdType npad_id_1,
Core::HID::NpadIdType npad_id_2) {
if (!IsNpadIdValid(npad_id_1) || !IsNpadIdValid(npad_id_2)) {
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 4e2412356..80cfcb2bb 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -30,14 +30,14 @@ class ServiceContext;
union Result;
namespace Service::HID {
+class AppletResource;
struct NpadInternalState;
struct NpadSixAxisSensorLifo;
struct NpadSharedMemoryFormat;
class NPad final : public ControllerBase {
public:
- explicit NPad(Core::HID::HIDCore& hid_core_, NpadSharedMemoryFormat& npad_shared_memory_format,
- KernelHelpers::ServiceContext& service_context_);
+ explicit NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_);
~NPad() override;
// Called when the controller is initialized
@@ -106,13 +106,6 @@ public:
Result ResetIsSixAxisSensorDeviceNewlyAssigned(
const Core::HID::SixAxisSensorHandle& sixaxis_handle);
- NpadSixAxisSensorLifo& GetSixAxisFullkeyLifo(Core::HID::NpadIdType npad_id);
- NpadSixAxisSensorLifo& GetSixAxisHandheldLifo(Core::HID::NpadIdType npad_id);
- NpadSixAxisSensorLifo& GetSixAxisDualLeftLifo(Core::HID::NpadIdType npad_id);
- NpadSixAxisSensorLifo& GetSixAxisDualRightLifo(Core::HID::NpadIdType npad_id);
- NpadSixAxisSensorLifo& GetSixAxisLeftLifo(Core::HID::NpadIdType npad_id);
- NpadSixAxisSensorLifo& GetSixAxisRightLifo(Core::HID::NpadIdType npad_id);
-
Result GetLedPattern(Core::HID::NpadIdType npad_id, Core::HID::LedPattern& pattern) const;
Result IsUnintendedHomeButtonInputProtectionEnabled(Core::HID::NpadIdType npad_id,
bool& is_enabled) const;
diff --git a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp b/src/core/hle/service/hid/controllers/shared_memory_holder.cpp
index 51581188e..0bc5169c6 100644
--- a/src/core/hle/service/hid/controllers/shared_memory_holder.cpp
+++ b/src/core/hle/service/hid/controllers/shared_memory_holder.cpp
@@ -3,8 +3,9 @@
#include "core/core.h"
#include "core/hle/kernel/k_shared_memory.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
#include "core/hle/service/hid/controllers/shared_memory_holder.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
#include "core/hle/service/hid/errors.h"
namespace Service::HID {
diff --git a/src/core/hle/service/hid/controllers/six_axis.cpp b/src/core/hle/service/hid/controllers/six_axis.cpp
index 36b72f9ea..a5a67dea6 100644
--- a/src/core/hle/service/hid/controllers/six_axis.cpp
+++ b/src/core/hle/service/hid/controllers/six_axis.cpp
@@ -6,8 +6,8 @@
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "core/hle/service/hid/controllers/npad.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
#include "core/hle/service/hid/controllers/six_axis.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
#include "core/hle/service/hid/errors.h"
#include "core/hle/service/hid/hid_util.h"
@@ -27,14 +27,20 @@ void SixAxis::OnInit() {}
void SixAxis::OnRelease() {}
void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
if (!IsControllerActivated()) {
return;
}
for (std::size_t i = 0; i < controller_data.size(); ++i) {
+ NpadSharedMemoryEntry& shared_memory = data->shared_memory_format->npad.npad_entry[i];
auto& controller = controller_data[i];
-
- const auto npad_id = IndexToNpadIdType(i);
const auto& controller_type = controller.device->GetNpadStyleIndex();
if (controller_type == Core::HID::NpadStyleIndex::None ||
@@ -50,12 +56,12 @@ void SixAxis::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
auto& sixaxis_left_lifo_state = controller.sixaxis_left_lifo_state;
auto& sixaxis_right_lifo_state = controller.sixaxis_right_lifo_state;
- auto& sixaxis_fullkey_lifo = npad->GetSixAxisFullkeyLifo(npad_id);
- auto& sixaxis_handheld_lifo = npad->GetSixAxisHandheldLifo(npad_id);
- auto& sixaxis_dual_left_lifo = npad->GetSixAxisDualLeftLifo(npad_id);
- auto& sixaxis_dual_right_lifo = npad->GetSixAxisDualRightLifo(npad_id);
- auto& sixaxis_left_lifo = npad->GetSixAxisLeftLifo(npad_id);
- auto& sixaxis_right_lifo = npad->GetSixAxisRightLifo(npad_id);
+ auto& sixaxis_fullkey_lifo = shared_memory.internal_state.sixaxis_fullkey_lifo;
+ auto& sixaxis_handheld_lifo = shared_memory.internal_state.sixaxis_handheld_lifo;
+ auto& sixaxis_dual_left_lifo = shared_memory.internal_state.sixaxis_dual_left_lifo;
+ auto& sixaxis_dual_right_lifo = shared_memory.internal_state.sixaxis_dual_right_lifo;
+ auto& sixaxis_left_lifo = shared_memory.internal_state.sixaxis_left_lifo;
+ auto& sixaxis_right_lifo = shared_memory.internal_state.sixaxis_right_lifo;
// Clear previous state
sixaxis_fullkey_state = {};
diff --git a/src/core/hle/service/hid/controllers/sleep_button.cpp b/src/core/hle/service/hid/controllers/sleep_button.cpp
new file mode 100644
index 000000000..978dc4c1f
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/sleep_button.cpp
@@ -0,0 +1,38 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core_timing.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
+#include "core/hle/service/hid/controllers/sleep_button.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
+
+namespace Service::HID {
+
+SleepButton::SleepButton(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
+
+SleepButton::~SleepButton() = default;
+
+void SleepButton::OnInit() {}
+
+void SleepButton::OnRelease() {}
+
+void SleepButton::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ if (!smart_update) {
+ return;
+ }
+
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ auto& header = data->shared_memory_format->capture_button.header;
+ header.timestamp = core_timing.GetGlobalTimeNs().count();
+ header.total_entry_count = 17;
+ header.entry_count = 0;
+ header.last_entry_index = 0;
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/sleep_button.h b/src/core/hle/service/hid/controllers/sleep_button.h
new file mode 100644
index 000000000..59964bf63
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/sleep_button.h
@@ -0,0 +1,27 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/hid/controllers/controller_base.h"
+
+namespace Service::HID {
+
+class SleepButton final : public ControllerBase {
+public:
+ explicit SleepButton(Core::HID::HIDCore& hid_core_);
+ ~SleepButton() override;
+
+ // Called when the controller is initialized
+ void OnInit() override;
+
+ // When the controller is released
+ void OnRelease() override;
+
+ // When the controller is requesting an update for the shared memory
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
+
+private:
+ bool smart_update{};
+};
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/stubbed.cpp b/src/core/hle/service/hid/controllers/stubbed.cpp
deleted file mode 100644
index e2a5f5d79..000000000
--- a/src/core/hle/service/hid/controllers/stubbed.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "core/core_timing.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
-#include "core/hle/service/hid/controllers/stubbed.h"
-
-namespace Service::HID {
-
-Controller_Stubbed::Controller_Stubbed(Core::HID::HIDCore& hid_core_,
- CommonHeader& ring_lifo_header)
- : ControllerBase{hid_core_}, header{ring_lifo_header} {}
-
-Controller_Stubbed::~Controller_Stubbed() = default;
-
-void Controller_Stubbed::OnInit() {}
-
-void Controller_Stubbed::OnRelease() {}
-
-void Controller_Stubbed::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
- if (!smart_update) {
- return;
- }
-
- header.timestamp = core_timing.GetGlobalTimeNs().count();
- header.total_entry_count = 17;
- header.entry_count = 0;
- header.last_entry_index = 0;
-}
-
-} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp
index 469750006..291dc707e 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.cpp
+++ b/src/core/hle/service/hid/controllers/touchscreen.cpp
@@ -8,15 +8,14 @@
#include "core/frontend/emu_window.h"
#include "core/hid/emulated_console.h"
#include "core/hid/hid_core.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
#include "core/hle/service/hid/controllers/touchscreen.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
namespace Service::HID {
-TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_,
- TouchScreenSharedMemoryFormat& touch_shared_memory)
- : ControllerBase{hid_core_}, shared_memory{touch_shared_memory},
- touchscreen_width(Layout::ScreenUndocked::Width),
+TouchScreen::TouchScreen(Core::HID::HIDCore& hid_core_)
+ : ControllerBase{hid_core_}, touchscreen_width(Layout::ScreenUndocked::Width),
touchscreen_height(Layout::ScreenUndocked::Height) {
console = hid_core.GetEmulatedConsole();
}
@@ -28,6 +27,14 @@ void TouchScreen::OnInit() {}
void TouchScreen::OnRelease() {}
void TouchScreen::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ TouchScreenSharedMemoryFormat& shared_memory = data->shared_memory_format->touch_screen;
shared_memory.touch_screen_lifo.timestamp = core_timing.GetGlobalTimeNs().count();
if (!IsControllerActivated()) {
diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h
index 5b6305bfc..945d359be 100644
--- a/src/core/hle/service/hid/controllers/touchscreen.h
+++ b/src/core/hle/service/hid/controllers/touchscreen.h
@@ -18,8 +18,7 @@ struct TouchScreenSharedMemoryFormat;
class TouchScreen final : public ControllerBase {
public:
- explicit TouchScreen(Core::HID::HIDCore& hid_core_,
- TouchScreenSharedMemoryFormat& touch_shared_memory);
+ explicit TouchScreen(Core::HID::HIDCore& hid_core_);
~TouchScreen() override;
// Called when the controller is initialized
@@ -35,7 +34,6 @@ public:
private:
TouchScreenState next_state{};
- TouchScreenSharedMemoryFormat& shared_memory;
Core::HID::EmulatedConsole* console = nullptr;
std::array<Core::HID::TouchFinger, MAX_FINGERS> fingers{};
diff --git a/src/core/hle/service/hid/controllers/shared_memory_format.h b/src/core/hle/service/hid/controllers/types/shared_memory_format.h
index 2986c113e..2986c113e 100644
--- a/src/core/hle/service/hid/controllers/shared_memory_format.h
+++ b/src/core/hle/service/hid/controllers/types/shared_memory_format.h
diff --git a/src/core/hle/service/hid/controllers/unique_pad.cpp b/src/core/hle/service/hid/controllers/unique_pad.cpp
new file mode 100644
index 000000000..8230501a5
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/unique_pad.cpp
@@ -0,0 +1,38 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/core_timing.h"
+#include "core/hle/service/hid/controllers/applet_resource.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/unique_pad.h"
+
+namespace Service::HID {
+
+UniquePad::UniquePad(Core::HID::HIDCore& hid_core_) : ControllerBase{hid_core_} {}
+
+UniquePad::~UniquePad() = default;
+
+void UniquePad::OnInit() {}
+
+void UniquePad::OnRelease() {}
+
+void UniquePad::OnUpdate(const Core::Timing::CoreTiming& core_timing) {
+ if (!smart_update) {
+ return;
+ }
+
+ const u64 aruid = applet_resource->GetActiveAruid();
+ auto* data = applet_resource->GetAruidData(aruid);
+
+ if (data == nullptr) {
+ return;
+ }
+
+ auto& header = data->shared_memory_format->capture_button.header;
+ header.timestamp = core_timing.GetGlobalTimeNs().count();
+ header.total_entry_count = 17;
+ header.entry_count = 0;
+ header.last_entry_index = 0;
+}
+
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/unique_pad.h b/src/core/hle/service/hid/controllers/unique_pad.h
new file mode 100644
index 000000000..966368264
--- /dev/null
+++ b/src/core/hle/service/hid/controllers/unique_pad.h
@@ -0,0 +1,27 @@
+// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/hid/controllers/controller_base.h"
+
+namespace Service::HID {
+
+class UniquePad final : public ControllerBase {
+public:
+ explicit UniquePad(Core::HID::HIDCore& hid_core_);
+ ~UniquePad() override;
+
+ // Called when the controller is initialized
+ void OnInit() override;
+
+ // When the controller is released
+ void OnRelease() override;
+
+ // When the controller is requesting an update for the shared memory
+ void OnUpdate(const Core::Timing::CoreTiming& core_timing) override;
+
+private:
+ bool smart_update{};
+};
+} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hidbus.cpp b/src/core/hle/service/hid/hidbus.cpp
index d12f9beb0..ffa7e144d 100644
--- a/src/core/hle/service/hid/hidbus.cpp
+++ b/src/core/hle/service/hid/hidbus.cpp
@@ -49,10 +49,10 @@ HidBus::HidBus(Core::System& system_)
// Register update callbacks
hidbus_update_event = Core::Timing::CreateEvent(
"Hidbus::UpdateCallback",
- [this](std::uintptr_t user_data, s64 time,
+ [this](s64 time,
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService();
- UpdateHidbus(user_data, ns_late);
+ UpdateHidbus(ns_late);
return std::nullopt;
});
@@ -61,10 +61,10 @@ HidBus::HidBus(Core::System& system_)
}
HidBus::~HidBus() {
- system.CoreTiming().UnscheduleEvent(hidbus_update_event, 0);
+ system.CoreTiming().UnscheduleEvent(hidbus_update_event);
}
-void HidBus::UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+void HidBus::UpdateHidbus(std::chrono::nanoseconds ns_late) {
if (is_hidbus_enabled) {
for (std::size_t i = 0; i < devices.size(); ++i) {
if (!devices[i].is_device_initializated) {
diff --git a/src/core/hle/service/hid/hidbus.h b/src/core/hle/service/hid/hidbus.h
index c29b5e882..85a1df133 100644
--- a/src/core/hle/service/hid/hidbus.h
+++ b/src/core/hle/service/hid/hidbus.h
@@ -108,7 +108,7 @@ private:
void DisableJoyPollingReceiveMode(HLERequestContext& ctx);
void SetStatusManagerType(HLERequestContext& ctx);
- void UpdateHidbus(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+ void UpdateHidbus(std::chrono::nanoseconds ns_late);
std::optional<std::size_t> GetDeviceIndexFromHandle(BusHandle handle) const;
template <typename T>
diff --git a/src/core/hle/service/hid/resource_manager.cpp b/src/core/hle/service/hid/resource_manager.cpp
index 6c6cbd802..84b4be3ed 100644
--- a/src/core/hle/service/hid/resource_manager.cpp
+++ b/src/core/hle/service/hid/resource_manager.cpp
@@ -10,18 +10,23 @@
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/hid/controllers/applet_resource.h"
+#include "core/hle/service/hid/controllers/capture_button.h"
#include "core/hle/service/hid/controllers/console_six_axis.h"
+#include "core/hle/service/hid/controllers/debug_mouse.h"
#include "core/hle/service/hid/controllers/debug_pad.h"
+#include "core/hle/service/hid/controllers/digitizer.h"
#include "core/hle/service/hid/controllers/gesture.h"
+#include "core/hle/service/hid/controllers/home_button.h"
#include "core/hle/service/hid/controllers/keyboard.h"
#include "core/hle/service/hid/controllers/mouse.h"
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/controllers/palma.h"
#include "core/hle/service/hid/controllers/seven_six_axis.h"
-#include "core/hle/service/hid/controllers/shared_memory_format.h"
#include "core/hle/service/hid/controllers/six_axis.h"
-#include "core/hle/service/hid/controllers/stubbed.h"
+#include "core/hle/service/hid/controllers/sleep_button.h"
#include "core/hle/service/hid/controllers/touchscreen.h"
+#include "core/hle/service/hid/controllers/types/shared_memory_format.h"
+#include "core/hle/service/hid/controllers/unique_pad.h"
namespace Service::HID {
@@ -46,42 +51,13 @@ void ResourceManager::Initialize() {
}
system.HIDCore().ReloadInputDevices();
- is_initialized = true;
-}
-
-void ResourceManager::InitializeController(u64 aruid) {
- SharedMemoryFormat* shared_memory = nullptr;
- const auto result = applet_resource->GetSharedMemoryFormat(&shared_memory, aruid);
- if (result.IsError()) {
- return;
- }
-
- debug_pad = std::make_shared<DebugPad>(system.HIDCore(), shared_memory->debug_pad);
- mouse = std::make_shared<Mouse>(system.HIDCore(), shared_memory->mouse);
- debug_mouse = std::make_shared<DebugMouse>(system.HIDCore(), shared_memory->debug_mouse);
- keyboard = std::make_shared<Keyboard>(system.HIDCore(), shared_memory->keyboard);
- unique_pad = std::make_shared<UniquePad>(system.HIDCore(), shared_memory->unique_pad.header);
- npad = std::make_shared<NPad>(system.HIDCore(), shared_memory->npad, service_context);
- gesture = std::make_shared<Gesture>(system.HIDCore(), shared_memory->gesture);
- touch_screen = std::make_shared<TouchScreen>(system.HIDCore(), shared_memory->touch_screen);
- palma = std::make_shared<Palma>(system.HIDCore(), service_context);
+ InitializeHidCommonSampler();
+ InitializeTouchScreenSampler();
+ InitializeConsoleSixAxisSampler();
+ InitializeAHidSampler();
- home_button = std::make_shared<HomeButton>(system.HIDCore(), shared_memory->home_button.header);
- sleep_button =
- std::make_shared<SleepButton>(system.HIDCore(), shared_memory->sleep_button.header);
- capture_button =
- std::make_shared<CaptureButton>(system.HIDCore(), shared_memory->capture_button.header);
- digitizer = std::make_shared<Digitizer>(system.HIDCore(), shared_memory->digitizer.header);
-
- six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
- console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore(), shared_memory->console);
- seven_six_axis = std::make_shared<SevenSixAxis>(system);
-
- // Homebrew doesn't try to activate some controllers, so we activate them by default
- npad->Activate();
- six_axis->Activate();
- touch_screen->Activate();
+ is_initialized = true;
}
std::shared_ptr<AppletResource> ResourceManager::GetAppletResource() const {
@@ -165,16 +141,65 @@ Result ResourceManager::CreateAppletResource(u64 aruid) {
if (result.IsError()) {
return result;
}
+
+ // Homebrew doesn't try to activate some controllers, so we activate them by default
+ npad->Activate();
+ six_axis->Activate();
+ touch_screen->Activate();
+
return GetNpad()->Activate(aruid);
}
Result ResourceManager::CreateAppletResourceImpl(u64 aruid) {
std::scoped_lock lock{shared_mutex};
- const auto result = applet_resource->CreateAppletResource(aruid);
- if (result.IsSuccess()) {
- InitializeController(aruid);
- }
- return result;
+ return applet_resource->CreateAppletResource(aruid);
+}
+
+void ResourceManager::InitializeHidCommonSampler() {
+ debug_pad = std::make_shared<DebugPad>(system.HIDCore());
+ mouse = std::make_shared<Mouse>(system.HIDCore());
+ debug_mouse = std::make_shared<DebugMouse>(system.HIDCore());
+ keyboard = std::make_shared<Keyboard>(system.HIDCore());
+ unique_pad = std::make_shared<UniquePad>(system.HIDCore());
+ npad = std::make_shared<NPad>(system.HIDCore(), service_context);
+ gesture = std::make_shared<Gesture>(system.HIDCore());
+ home_button = std::make_shared<HomeButton>(system.HIDCore());
+ sleep_button = std::make_shared<SleepButton>(system.HIDCore());
+ capture_button = std::make_shared<CaptureButton>(system.HIDCore());
+ digitizer = std::make_shared<Digitizer>(system.HIDCore());
+
+ palma = std::make_shared<Palma>(system.HIDCore(), service_context);
+ six_axis = std::make_shared<SixAxis>(system.HIDCore(), npad);
+
+ debug_pad->SetAppletResource(applet_resource);
+ digitizer->SetAppletResource(applet_resource);
+ keyboard->SetAppletResource(applet_resource);
+ npad->SetAppletResource(applet_resource);
+ six_axis->SetAppletResource(applet_resource);
+ mouse->SetAppletResource(applet_resource);
+ debug_mouse->SetAppletResource(applet_resource);
+ home_button->SetAppletResource(applet_resource);
+ sleep_button->SetAppletResource(applet_resource);
+ capture_button->SetAppletResource(applet_resource);
+}
+
+void ResourceManager::InitializeTouchScreenSampler() {
+ gesture = std::make_shared<Gesture>(system.HIDCore());
+ touch_screen = std::make_shared<TouchScreen>(system.HIDCore());
+
+ touch_screen->SetAppletResource(applet_resource);
+ gesture->SetAppletResource(applet_resource);
+}
+
+void ResourceManager::InitializeConsoleSixAxisSampler() {
+ console_six_axis = std::make_shared<ConsoleSixAxis>(system.HIDCore());
+ seven_six_axis = std::make_shared<SevenSixAxis>(system);
+
+ console_six_axis->SetAppletResource(applet_resource);
+}
+
+void ResourceManager::InitializeAHidSampler() {
+ // TODO
}
Result ResourceManager::RegisterCoreAppletResource() {
@@ -227,8 +252,7 @@ void ResourceManager::EnableTouchScreen(u64 aruid, bool is_enabled) {
applet_resource->EnableTouchScreen(aruid, is_enabled);
}
-void ResourceManager::UpdateControllers(std::uintptr_t user_data,
- std::chrono::nanoseconds ns_late) {
+void ResourceManager::UpdateControllers(std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
debug_pad->OnUpdate(core_timing);
digitizer->OnUpdate(core_timing);
@@ -241,20 +265,19 @@ void ResourceManager::UpdateControllers(std::uintptr_t user_data,
capture_button->OnUpdate(core_timing);
}
-void ResourceManager::UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+void ResourceManager::UpdateNpad(std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
npad->OnUpdate(core_timing);
}
-void ResourceManager::UpdateMouseKeyboard(std::uintptr_t user_data,
- std::chrono::nanoseconds ns_late) {
+void ResourceManager::UpdateMouseKeyboard(std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
mouse->OnUpdate(core_timing);
debug_mouse->OnUpdate(core_timing);
keyboard->OnUpdate(core_timing);
}
-void ResourceManager::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) {
+void ResourceManager::UpdateMotion(std::chrono::nanoseconds ns_late) {
auto& core_timing = system.CoreTiming();
six_axis->OnUpdate(core_timing);
seven_six_axis->OnUpdate(core_timing);
@@ -273,34 +296,34 @@ IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<Resource
// Register update callbacks
npad_update_event = Core::Timing::CreateEvent(
"HID::UpdatePadCallback",
- [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
- -> std::optional<std::chrono::nanoseconds> {
+ [this, resource](
+ s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService();
- resource->UpdateNpad(user_data, ns_late);
+ resource->UpdateNpad(ns_late);
return std::nullopt;
});
default_update_event = Core::Timing::CreateEvent(
"HID::UpdateDefaultCallback",
- [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
- -> std::optional<std::chrono::nanoseconds> {
+ [this, resource](
+ s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService();
- resource->UpdateControllers(user_data, ns_late);
+ resource->UpdateControllers(ns_late);
return std::nullopt;
});
mouse_keyboard_update_event = Core::Timing::CreateEvent(
"HID::UpdateMouseKeyboardCallback",
- [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
- -> std::optional<std::chrono::nanoseconds> {
+ [this, resource](
+ s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService();
- resource->UpdateMouseKeyboard(user_data, ns_late);
+ resource->UpdateMouseKeyboard(ns_late);
return std::nullopt;
});
motion_update_event = Core::Timing::CreateEvent(
"HID::UpdateMotionCallback",
- [this, resource](std::uintptr_t user_data, s64 time, std::chrono::nanoseconds ns_late)
- -> std::optional<std::chrono::nanoseconds> {
+ [this, resource](
+ s64 time, std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto guard = LockService();
- resource->UpdateMotion(user_data, ns_late);
+ resource->UpdateMotion(ns_late);
return std::nullopt;
});
@@ -314,10 +337,10 @@ IAppletResource::IAppletResource(Core::System& system_, std::shared_ptr<Resource
}
IAppletResource::~IAppletResource() {
- system.CoreTiming().UnscheduleEvent(npad_update_event, 0);
- system.CoreTiming().UnscheduleEvent(default_update_event, 0);
- system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event, 0);
- system.CoreTiming().UnscheduleEvent(motion_update_event, 0);
+ system.CoreTiming().UnscheduleEvent(npad_update_event);
+ system.CoreTiming().UnscheduleEvent(default_update_event);
+ system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event);
+ system.CoreTiming().UnscheduleEvent(motion_update_event);
resource_manager->FreeAppletResourceId(aruid);
}
diff --git a/src/core/hle/service/hid/resource_manager.h b/src/core/hle/service/hid/resource_manager.h
index 5ad7cb564..70d9b6550 100644
--- a/src/core/hle/service/hid/resource_manager.h
+++ b/src/core/hle/service/hid/resource_manager.h
@@ -20,24 +20,23 @@ class KSharedMemory;
namespace Service::HID {
class AppletResource;
+class CaptureButton;
class Controller_Stubbed;
class ConsoleSixAxis;
+class DebugMouse;
class DebugPad;
+class Digitizer;
class Gesture;
+class HomeButton;
class Keyboard;
class Mouse;
class NPad;
class Palma;
class SevenSixAxis;
class SixAxis;
+class SleepButton;
class TouchScreen;
-
-using CaptureButton = Controller_Stubbed;
-using DebugMouse = Mouse;
-using Digitizer = Controller_Stubbed;
-using HomeButton = Controller_Stubbed;
-using SleepButton = Controller_Stubbed;
-using UniquePad = Controller_Stubbed;
+class UniquePad;
class ResourceManager {
@@ -46,7 +45,6 @@ public:
~ResourceManager();
void Initialize();
- void InitializeController(u64 aruid);
std::shared_ptr<AppletResource> GetAppletResource() const;
std::shared_ptr<CaptureButton> GetCaptureButton() const;
@@ -81,13 +79,17 @@ public:
void EnablePadInput(u64 aruid, bool is_enabled);
void EnableTouchScreen(u64 aruid, bool is_enabled);
- void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
- void UpdateNpad(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
- void UpdateMouseKeyboard(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
- void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+ void UpdateControllers(std::chrono::nanoseconds ns_late);
+ void UpdateNpad(std::chrono::nanoseconds ns_late);
+ void UpdateMouseKeyboard(std::chrono::nanoseconds ns_late);
+ void UpdateMotion(std::chrono::nanoseconds ns_late);
private:
Result CreateAppletResourceImpl(u64 aruid);
+ void InitializeHidCommonSampler();
+ void InitializeTouchScreenSampler();
+ void InitializeConsoleSixAxisSampler();
+ void InitializeAHidSampler();
bool is_initialized{false};
diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp
index a94d05e19..77aa6d7d1 100644
--- a/src/core/hle/service/jit/jit.cpp
+++ b/src/core/hle/service/jit/jit.cpp
@@ -4,11 +4,11 @@
#include "core/arm/debug.h"
#include "core/arm/symbols.h"
#include "core/core.h"
-#include "core/hle/kernel/k_code_memory.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/result.h"
#include "core/hle/service/ipc_helpers.h"
#include "core/hle/service/jit/jit.h"
+#include "core/hle/service/jit/jit_code_memory.h"
#include "core/hle/service/jit/jit_context.h"
#include "core/hle/service/server_manager.h"
#include "core/hle/service/service.h"
@@ -23,10 +23,12 @@ struct CodeRange {
class IJitEnvironment final : public ServiceFramework<IJitEnvironment> {
public:
- explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx,
- CodeRange user_ro)
- : ServiceFramework{system_, "IJitEnvironment"}, process{&process_},
- context{process->GetMemory()} {
+ explicit IJitEnvironment(Core::System& system_,
+ Kernel::KScopedAutoObject<Kernel::KProcess>&& process_,
+ CodeMemory&& user_rx_, CodeMemory&& user_ro_)
+ : ServiceFramework{system_, "IJitEnvironment"}, process{std::move(process_)},
+ user_rx{std::move(user_rx_)}, user_ro{std::move(user_ro_)},
+ context{system_.ApplicationMemory()} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &IJitEnvironment::GenerateCode, "GenerateCode"},
@@ -39,10 +41,13 @@ public:
RegisterHandlers(functions);
// Identity map user code range into sysmodule context
- configuration.user_ro_memory = user_ro;
- configuration.user_rx_memory = user_rx;
- configuration.sys_ro_memory = user_ro;
- configuration.sys_rx_memory = user_rx;
+ configuration.user_rx_memory.size = user_rx.GetSize();
+ configuration.user_rx_memory.offset = user_rx.GetAddress();
+ configuration.user_ro_memory.size = user_ro.GetSize();
+ configuration.user_ro_memory.offset = user_ro.GetAddress();
+
+ configuration.sys_rx_memory = configuration.user_rx_memory;
+ configuration.sys_ro_memory = configuration.user_ro_memory;
}
void GenerateCode(HLERequestContext& ctx) {
@@ -318,6 +323,8 @@ private:
}
Kernel::KScopedAutoObject<Kernel::KProcess> process;
+ CodeMemory user_rx;
+ CodeMemory user_ro;
GuestCallbacks callbacks;
JITConfiguration configuration;
JITContext context;
@@ -335,6 +342,7 @@ public:
RegisterHandlers(functions);
}
+private:
void CreateJitEnvironment(HLERequestContext& ctx) {
LOG_DEBUG(Service_JIT, "called");
@@ -380,20 +388,35 @@ public:
return;
}
- const CodeRange user_rx{
- .offset = GetInteger(rx_mem->GetSourceAddress()),
- .size = parameters.rx_size,
- };
+ CodeMemory rx, ro;
+ Result res;
- const CodeRange user_ro{
- .offset = GetInteger(ro_mem->GetSourceAddress()),
- .size = parameters.ro_size,
- };
+ res = rx.Initialize(*process, *rx_mem, parameters.rx_size,
+ Kernel::Svc::MemoryPermission::ReadExecute, generate_random);
+ if (R_FAILED(res)) {
+ LOG_ERROR(Service_JIT, "rx_mem could not be mapped for handle=0x{:08X}", rx_mem_handle);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(res);
+ return;
+ }
+
+ res = ro.Initialize(*process, *ro_mem, parameters.ro_size,
+ Kernel::Svc::MemoryPermission::Read, generate_random);
+ if (R_FAILED(res)) {
+ LOG_ERROR(Service_JIT, "ro_mem could not be mapped for handle=0x{:08X}", ro_mem_handle);
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(res);
+ return;
+ }
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
- rb.PushIpcInterface<IJitEnvironment>(system, *process, user_rx, user_ro);
+ rb.PushIpcInterface<IJitEnvironment>(system, std::move(process), std::move(rx),
+ std::move(ro));
}
+
+private:
+ std::mt19937_64 generate_random{};
};
void LoopProcess(Core::System& system) {
diff --git a/src/core/hle/service/jit/jit_code_memory.cpp b/src/core/hle/service/jit/jit_code_memory.cpp
new file mode 100644
index 000000000..2b480488a
--- /dev/null
+++ b/src/core/hle/service/jit/jit_code_memory.cpp
@@ -0,0 +1,54 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "core/hle/service/jit/jit_code_memory.h"
+
+namespace Service::JIT {
+
+Result CodeMemory::Initialize(Kernel::KProcess& process, Kernel::KCodeMemory& code_memory,
+ size_t size, Kernel::Svc::MemoryPermission perm,
+ std::mt19937_64& generate_random) {
+ auto& page_table = process.GetPageTable();
+ const u64 alias_code_start =
+ GetInteger(page_table.GetAliasCodeRegionStart()) / Kernel::PageSize;
+ const u64 alias_code_size = page_table.GetAliasCodeRegionSize() / Kernel::PageSize;
+
+ // NOTE: This will retry indefinitely until mapping the code memory succeeds.
+ while (true) {
+ // Generate a new trial address.
+ const u64 mapped_address =
+ (alias_code_start + (generate_random() % alias_code_size)) * Kernel::PageSize;
+
+ // Try to map the address
+ R_TRY_CATCH(code_memory.MapToOwner(mapped_address, size, perm)) {
+ R_CATCH(Kernel::ResultInvalidMemoryRegion) {
+ // If we could not map here, retry.
+ continue;
+ }
+ }
+ R_END_TRY_CATCH;
+
+ // Set members.
+ m_code_memory = std::addressof(code_memory);
+ m_size = size;
+ m_address = mapped_address;
+ m_perm = perm;
+
+ // Open a new reference to the code memory.
+ m_code_memory->Open();
+
+ // We succeeded.
+ R_SUCCEED();
+ }
+}
+
+void CodeMemory::Finalize() {
+ if (m_code_memory) {
+ R_ASSERT(m_code_memory->UnmapFromOwner(m_address, m_size));
+ m_code_memory->Close();
+ }
+
+ m_code_memory = nullptr;
+}
+
+} // namespace Service::JIT
diff --git a/src/core/hle/service/jit/jit_code_memory.h b/src/core/hle/service/jit/jit_code_memory.h
new file mode 100644
index 000000000..6376d4c4e
--- /dev/null
+++ b/src/core/hle/service/jit/jit_code_memory.h
@@ -0,0 +1,49 @@
+// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include <random>
+
+#include "core/hle/kernel/k_code_memory.h"
+
+namespace Service::JIT {
+
+class CodeMemory {
+public:
+ YUZU_NON_COPYABLE(CodeMemory);
+
+ explicit CodeMemory() = default;
+
+ CodeMemory(CodeMemory&& rhs) {
+ std::swap(m_code_memory, rhs.m_code_memory);
+ std::swap(m_size, rhs.m_size);
+ std::swap(m_address, rhs.m_address);
+ std::swap(m_perm, rhs.m_perm);
+ }
+
+ ~CodeMemory() {
+ this->Finalize();
+ }
+
+public:
+ Result Initialize(Kernel::KProcess& process, Kernel::KCodeMemory& code_memory, size_t size,
+ Kernel::Svc::MemoryPermission perm, std::mt19937_64& generate_random);
+ void Finalize();
+
+ size_t GetSize() const {
+ return m_size;
+ }
+
+ u64 GetAddress() const {
+ return m_address;
+ }
+
+private:
+ Kernel::KCodeMemory* m_code_memory{};
+ size_t m_size{};
+ u64 m_address{};
+ Kernel::Svc::MemoryPermission m_perm{};
+};
+
+} // namespace Service::JIT
diff --git a/src/core/hle/service/nvnflinger/nvnflinger.cpp b/src/core/hle/service/nvnflinger/nvnflinger.cpp
index 6352b09a9..aa8aaa2d9 100644
--- a/src/core/hle/service/nvnflinger/nvnflinger.cpp
+++ b/src/core/hle/service/nvnflinger/nvnflinger.cpp
@@ -67,7 +67,7 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
// Schedule the screen composition events
multi_composition_event = Core::Timing::CreateEvent(
"ScreenComposition",
- [this](std::uintptr_t, s64 time,
+ [this](s64 time,
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
vsync_signal.Set();
return std::chrono::nanoseconds(GetNextTicks());
@@ -75,7 +75,7 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
single_composition_event = Core::Timing::CreateEvent(
"ScreenComposition",
- [this](std::uintptr_t, s64 time,
+ [this](s64 time,
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
const auto lock_guard = Lock();
Compose();
@@ -93,11 +93,11 @@ Nvnflinger::Nvnflinger(Core::System& system_, HosBinderDriverServer& hos_binder_
Nvnflinger::~Nvnflinger() {
if (system.IsMulticore()) {
- system.CoreTiming().UnscheduleEvent(multi_composition_event, {});
+ system.CoreTiming().UnscheduleEvent(multi_composition_event);
vsync_thread.request_stop();
vsync_signal.Set();
} else {
- system.CoreTiming().UnscheduleEvent(single_composition_event, {});
+ system.CoreTiming().UnscheduleEvent(single_composition_event);
}
ShutdownLayers();
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index c7eb32c19..8176a41be 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -10,6 +10,7 @@
#include "common/assert.h"
#include "common/atomic_ops.h"
#include "common/common_types.h"
+#include "common/heap_tracker.h"
#include "common/logging/log.h"
#include "common/page_table.h"
#include "common/scope_exit.h"
@@ -52,10 +53,18 @@ struct Memory::Impl {
} else {
current_page_table->fastmem_arena = nullptr;
}
+
+#ifdef __linux__
+ heap_tracker.emplace(system.DeviceMemory().buffer);
+ buffer = std::addressof(*heap_tracker);
+#else
+ buffer = std::addressof(system.DeviceMemory().buffer);
+#endif
}
void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
- Common::PhysicalAddress target, Common::MemoryPermission perms) {
+ Common::PhysicalAddress target, Common::MemoryPermission perms,
+ bool separate_heap) {
ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
ASSERT_MSG(target >= DramMemoryMap::Base, "Out of bounds target: {:016X}",
@@ -64,19 +73,20 @@ struct Memory::Impl {
Common::PageType::Memory);
if (current_page_table->fastmem_arena) {
- system.DeviceMemory().buffer.Map(GetInteger(base),
- GetInteger(target) - DramMemoryMap::Base, size, perms);
+ buffer->Map(GetInteger(base), GetInteger(target) - DramMemoryMap::Base, size, perms,
+ separate_heap);
}
}
- void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size) {
+ void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
+ bool separate_heap) {
ASSERT_MSG((size & YUZU_PAGEMASK) == 0, "non-page aligned size: {:016X}", size);
ASSERT_MSG((base & YUZU_PAGEMASK) == 0, "non-page aligned base: {:016X}", GetInteger(base));
MapPages(page_table, base / YUZU_PAGESIZE, size / YUZU_PAGESIZE, 0,
Common::PageType::Unmapped);
if (current_page_table->fastmem_arena) {
- system.DeviceMemory().buffer.Unmap(GetInteger(base), size);
+ buffer->Unmap(GetInteger(base), size, separate_heap);
}
}
@@ -89,11 +99,6 @@ struct Memory::Impl {
return;
}
- const bool is_r = True(perms & Common::MemoryPermission::Read);
- const bool is_w = True(perms & Common::MemoryPermission::Write);
- const bool is_x =
- True(perms & Common::MemoryPermission::Execute) && Settings::IsNceEnabled();
-
u64 protect_bytes{};
u64 protect_begin{};
for (u64 addr = vaddr; addr < vaddr + size; addr += YUZU_PAGESIZE) {
@@ -102,8 +107,7 @@ struct Memory::Impl {
switch (page_type) {
case Common::PageType::RasterizerCachedMemory:
if (protect_bytes > 0) {
- system.DeviceMemory().buffer.Protect(protect_begin, protect_bytes, is_r, is_w,
- is_x);
+ buffer->Protect(protect_begin, protect_bytes, perms);
protect_bytes = 0;
}
break;
@@ -116,7 +120,7 @@ struct Memory::Impl {
}
if (protect_bytes > 0) {
- system.DeviceMemory().buffer.Protect(protect_begin, protect_bytes, is_r, is_w, is_x);
+ buffer->Protect(protect_begin, protect_bytes, perms);
}
}
@@ -486,7 +490,9 @@ struct Memory::Impl {
}
if (current_page_table->fastmem_arena) {
- system.DeviceMemory().buffer.Protect(vaddr, size, !debug, !debug);
+ const auto perm{debug ? Common::MemoryPermission{}
+ : Common::MemoryPermission::ReadWrite};
+ buffer->Protect(vaddr, size, perm);
}
// Iterate over a contiguous CPU address space, marking/unmarking the region.
@@ -543,9 +549,14 @@ struct Memory::Impl {
}
if (current_page_table->fastmem_arena) {
- const bool is_read_enable =
- !Settings::values.use_reactive_flushing.GetValue() || !cached;
- system.DeviceMemory().buffer.Protect(vaddr, size, is_read_enable, !cached);
+ Common::MemoryPermission perm{};
+ if (!Settings::values.use_reactive_flushing.GetValue() || !cached) {
+ perm |= Common::MemoryPermission::Read;
+ }
+ if (!cached) {
+ perm |= Common::MemoryPermission::Write;
+ }
+ buffer->Protect(vaddr, size, perm);
}
// Iterate over a contiguous CPU address space, which corresponds to the specified GPU
@@ -856,6 +867,13 @@ struct Memory::Impl {
std::array<GPUDirtyState, Core::Hardware::NUM_CPU_CORES> rasterizer_write_areas{};
std::span<Core::GPUDirtyMemoryManager> gpu_dirty_managers;
std::mutex sys_core_guard;
+
+ std::optional<Common::HeapTracker> heap_tracker;
+#ifdef __linux__
+ Common::HeapTracker* buffer{};
+#else
+ Common::HostMemory* buffer{};
+#endif
};
Memory::Memory(Core::System& system_) : system{system_} {
@@ -873,12 +891,14 @@ void Memory::SetCurrentPageTable(Kernel::KProcess& process) {
}
void Memory::MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
- Common::PhysicalAddress target, Common::MemoryPermission perms) {
- impl->MapMemoryRegion(page_table, base, size, target, perms);
+ Common::PhysicalAddress target, Common::MemoryPermission perms,
+ bool separate_heap) {
+ impl->MapMemoryRegion(page_table, base, size, target, perms, separate_heap);
}
-void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size) {
- impl->UnmapRegion(page_table, base, size);
+void Memory::UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
+ bool separate_heap) {
+ impl->UnmapRegion(page_table, base, size, separate_heap);
}
void Memory::ProtectRegion(Common::PageTable& page_table, Common::ProcessAddress vaddr, u64 size,
@@ -1048,7 +1068,9 @@ void Memory::FlushRegion(Common::ProcessAddress dest_addr, size_t size) {
}
bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) {
- bool mapped = true;
+ [[maybe_unused]] bool mapped = true;
+ [[maybe_unused]] bool rasterizer = false;
+
u8* const ptr = impl->GetPointerImpl(
GetInteger(vaddr),
[&] {
@@ -1056,8 +1078,26 @@ bool Memory::InvalidateNCE(Common::ProcessAddress vaddr, size_t size) {
GetInteger(vaddr));
mapped = false;
},
- [&] { impl->system.GPU().InvalidateRegion(GetInteger(vaddr), size); });
+ [&] {
+ impl->system.GPU().InvalidateRegion(GetInteger(vaddr), size);
+ rasterizer = true;
+ });
+
+#ifdef __linux__
+ if (!rasterizer && mapped) {
+ impl->buffer->DeferredMapSeparateHeap(GetInteger(vaddr));
+ }
+#endif
+
return mapped && ptr != nullptr;
}
+bool Memory::InvalidateSeparateHeap(void* fault_address) {
+#ifdef __linux__
+ return impl->buffer->DeferredMapSeparateHeap(static_cast<u8*>(fault_address));
+#else
+ return false;
+#endif
+}
+
} // namespace Core::Memory
diff --git a/src/core/memory.h b/src/core/memory.h
index e325dd613..dddfaf4a4 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -86,7 +86,8 @@ public:
* @param perms The permissions to map the memory with.
*/
void MapMemoryRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
- Common::PhysicalAddress target, Common::MemoryPermission perms);
+ Common::PhysicalAddress target, Common::MemoryPermission perms,
+ bool separate_heap);
/**
* Unmaps a region of the emulated process address space.
@@ -95,7 +96,8 @@ public:
* @param base The address to begin unmapping at.
* @param size The amount of bytes to unmap.
*/
- void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size);
+ void UnmapRegion(Common::PageTable& page_table, Common::ProcessAddress base, u64 size,
+ bool separate_heap);
/**
* Protects a region of the emulated process address space with the new permissions.
@@ -486,6 +488,7 @@ public:
void SetGPUDirtyManagers(std::span<Core::GPUDirtyMemoryManager> managers);
void InvalidateRegion(Common::ProcessAddress dest_addr, size_t size);
bool InvalidateNCE(Common::ProcessAddress vaddr, size_t size);
+ bool InvalidateSeparateHeap(void* fault_address);
void FlushRegion(Common::ProcessAddress dest_addr, size_t size);
private:
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 3fc4024dc..7bc5b5ae5 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -190,15 +190,15 @@ CheatEngine::CheatEngine(System& system_, std::vector<CheatEntry> cheats_,
}
CheatEngine::~CheatEngine() {
- core_timing.UnscheduleEvent(event, 0);
+ core_timing.UnscheduleEvent(event);
}
void CheatEngine::Initialize() {
event = Core::Timing::CreateEvent(
"CheatEngine::FrameCallback::" + Common::HexToString(metadata.main_nso_build_id),
- [this](std::uintptr_t user_data, s64 time,
+ [this](s64 time,
std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
- FrameCallback(user_data, ns_late);
+ FrameCallback(ns_late);
return std::nullopt;
});
core_timing.ScheduleLoopingEvent(CHEAT_ENGINE_NS, CHEAT_ENGINE_NS, event);
@@ -239,7 +239,7 @@ void CheatEngine::Reload(std::vector<CheatEntry> reload_cheats) {
MICROPROFILE_DEFINE(Cheat_Engine, "Add-Ons", "Cheat Engine", MP_RGB(70, 200, 70));
-void CheatEngine::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) {
+void CheatEngine::FrameCallback(std::chrono::nanoseconds ns_late) {
if (is_pending_reload.exchange(false)) {
vm.LoadProgram(cheats);
}
diff --git a/src/core/memory/cheat_engine.h b/src/core/memory/cheat_engine.h
index 284abdd28..ced2168d1 100644
--- a/src/core/memory/cheat_engine.h
+++ b/src/core/memory/cheat_engine.h
@@ -70,7 +70,7 @@ public:
void Reload(std::vector<CheatEntry> reload_cheats);
private:
- void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+ void FrameCallback(std::chrono::nanoseconds ns_late);
DmntCheatVm vm;
CheatProcessMetadata metadata;
diff --git a/src/core/tools/freezer.cpp b/src/core/tools/freezer.cpp
index 98ebbbf32..9d42c726e 100644
--- a/src/core/tools/freezer.cpp
+++ b/src/core/tools/freezer.cpp
@@ -51,18 +51,17 @@ void MemoryWriteWidth(Core::Memory::Memory& memory, u32 width, VAddr addr, u64 v
Freezer::Freezer(Core::Timing::CoreTiming& core_timing_, Core::Memory::Memory& memory_)
: core_timing{core_timing_}, memory{memory_} {
- event = Core::Timing::CreateEvent(
- "MemoryFreezer::FrameCallback",
- [this](std::uintptr_t user_data, s64 time,
- std::chrono::nanoseconds ns_late) -> std::optional<std::chrono::nanoseconds> {
- FrameCallback(user_data, ns_late);
- return std::nullopt;
- });
+ event = Core::Timing::CreateEvent("MemoryFreezer::FrameCallback",
+ [this](s64 time, std::chrono::nanoseconds ns_late)
+ -> std::optional<std::chrono::nanoseconds> {
+ FrameCallback(ns_late);
+ return std::nullopt;
+ });
core_timing.ScheduleEvent(memory_freezer_ns, event);
}
Freezer::~Freezer() {
- core_timing.UnscheduleEvent(event, 0);
+ core_timing.UnscheduleEvent(event);
}
void Freezer::SetActive(bool is_active) {
@@ -159,7 +158,7 @@ Freezer::Entries::const_iterator Freezer::FindEntry(VAddr address) const {
[address](const Entry& entry) { return entry.address == address; });
}
-void Freezer::FrameCallback(std::uintptr_t, std::chrono::nanoseconds ns_late) {
+void Freezer::FrameCallback(std::chrono::nanoseconds ns_late) {
if (!IsActive()) {
LOG_DEBUG(Common_Memory, "Memory freezer has been deactivated, ending callback events.");
return;
diff --git a/src/core/tools/freezer.h b/src/core/tools/freezer.h
index 0d6df5217..2efbc11f3 100644
--- a/src/core/tools/freezer.h
+++ b/src/core/tools/freezer.h
@@ -77,7 +77,7 @@ private:
Entries::iterator FindEntry(VAddr address);
Entries::const_iterator FindEntry(VAddr address) const;
- void FrameCallback(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
+ void FrameCallback(std::chrono::nanoseconds ns_late);
void FillEntryReads();
std::atomic_bool active{false};