diff options
88 files changed, 1587 insertions, 1036 deletions
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index a4a9a757d..5b1065520 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp | |||
| @@ -383,11 +383,14 @@ void CommandGenerator::GenerateI3dl2ReverbEffectCommand(s32 mix_buffer_offset, E | |||
| 383 | const auto channel_count = params.channel_count; | 383 | const auto channel_count = params.channel_count; |
| 384 | for (s32 i = 0; i < channel_count; i++) { | 384 | for (s32 i = 0; i < channel_count; i++) { |
| 385 | // TODO(ogniK): Actually implement reverb | 385 | // TODO(ogniK): Actually implement reverb |
| 386 | /* | ||
| 386 | if (params.input[i] != params.output[i]) { | 387 | if (params.input[i] != params.output[i]) { |
| 387 | const auto* input = GetMixBuffer(mix_buffer_offset + params.input[i]); | 388 | const auto* input = GetMixBuffer(mix_buffer_offset + params.input[i]); |
| 388 | auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]); | 389 | auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]); |
| 389 | ApplyMix<1>(output, input, 32768, worker_params.sample_count); | 390 | ApplyMix<1>(output, input, 32768, worker_params.sample_count); |
| 390 | } | 391 | }*/ |
| 392 | auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]); | ||
| 393 | std::memset(output, 0, worker_params.sample_count * sizeof(s32)); | ||
| 391 | } | 394 | } |
| 392 | } | 395 | } |
| 393 | 396 | ||
diff --git a/src/common/scope_exit.h b/src/common/scope_exit.h index fa46cb394..35dac3a8f 100644 --- a/src/common/scope_exit.h +++ b/src/common/scope_exit.h | |||
| @@ -49,3 +49,9 @@ ScopeExitHelper<Func> ScopeExit(Func&& func) { | |||
| 49 | * \endcode | 49 | * \endcode |
| 50 | */ | 50 | */ |
| 51 | #define SCOPE_EXIT(body) auto CONCAT2(scope_exit_helper_, __LINE__) = detail::ScopeExit([&]() body) | 51 | #define SCOPE_EXIT(body) auto CONCAT2(scope_exit_helper_, __LINE__) = detail::ScopeExit([&]() body) |
| 52 | |||
| 53 | /** | ||
| 54 | * This macro is similar to SCOPE_EXIT, except the object is caller managed. This is intended to be | ||
| 55 | * used when the caller might want to cancel the ScopeExit. | ||
| 56 | */ | ||
| 57 | #define SCOPE_GUARD(body) detail::ScopeExit([&]() body) | ||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 397cc028f..386d7bddf 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -160,9 +160,16 @@ add_library(core STATIC | |||
| 160 | hle/kernel/k_affinity_mask.h | 160 | hle/kernel/k_affinity_mask.h |
| 161 | hle/kernel/k_condition_variable.cpp | 161 | hle/kernel/k_condition_variable.cpp |
| 162 | hle/kernel/k_condition_variable.h | 162 | hle/kernel/k_condition_variable.h |
| 163 | hle/kernel/k_event.cpp | ||
| 164 | hle/kernel/k_event.h | ||
| 165 | hle/kernel/k_light_condition_variable.h | ||
| 163 | hle/kernel/k_light_lock.cpp | 166 | hle/kernel/k_light_lock.cpp |
| 164 | hle/kernel/k_light_lock.h | 167 | hle/kernel/k_light_lock.h |
| 165 | hle/kernel/k_priority_queue.h | 168 | hle/kernel/k_priority_queue.h |
| 169 | hle/kernel/k_readable_event.cpp | ||
| 170 | hle/kernel/k_readable_event.h | ||
| 171 | hle/kernel/k_resource_limit.cpp | ||
| 172 | hle/kernel/k_resource_limit.h | ||
| 166 | hle/kernel/k_scheduler.cpp | 173 | hle/kernel/k_scheduler.cpp |
| 167 | hle/kernel/k_scheduler.h | 174 | hle/kernel/k_scheduler.h |
| 168 | hle/kernel/k_scheduler_lock.h | 175 | hle/kernel/k_scheduler_lock.h |
| @@ -173,6 +180,8 @@ add_library(core STATIC | |||
| 173 | hle/kernel/k_thread.cpp | 180 | hle/kernel/k_thread.cpp |
| 174 | hle/kernel/k_thread.h | 181 | hle/kernel/k_thread.h |
| 175 | hle/kernel/k_thread_queue.h | 182 | hle/kernel/k_thread_queue.h |
| 183 | hle/kernel/k_writable_event.cpp | ||
| 184 | hle/kernel/k_writable_event.h | ||
| 176 | hle/kernel/kernel.cpp | 185 | hle/kernel/kernel.cpp |
| 177 | hle/kernel/kernel.h | 186 | hle/kernel/kernel.h |
| 178 | hle/kernel/memory/address_space_info.cpp | 187 | hle/kernel/memory/address_space_info.cpp |
| @@ -201,10 +210,6 @@ add_library(core STATIC | |||
| 201 | hle/kernel/process.h | 210 | hle/kernel/process.h |
| 202 | hle/kernel/process_capability.cpp | 211 | hle/kernel/process_capability.cpp |
| 203 | hle/kernel/process_capability.h | 212 | hle/kernel/process_capability.h |
| 204 | hle/kernel/readable_event.cpp | ||
| 205 | hle/kernel/readable_event.h | ||
| 206 | hle/kernel/resource_limit.cpp | ||
| 207 | hle/kernel/resource_limit.h | ||
| 208 | hle/kernel/server_port.cpp | 213 | hle/kernel/server_port.cpp |
| 209 | hle/kernel/server_port.h | 214 | hle/kernel/server_port.h |
| 210 | hle/kernel/server_session.cpp | 215 | hle/kernel/server_session.cpp |
| @@ -225,8 +230,6 @@ add_library(core STATIC | |||
| 225 | hle/kernel/time_manager.h | 230 | hle/kernel/time_manager.h |
| 226 | hle/kernel/transfer_memory.cpp | 231 | hle/kernel/transfer_memory.cpp |
| 227 | hle/kernel/transfer_memory.h | 232 | hle/kernel/transfer_memory.h |
| 228 | hle/kernel/writable_event.cpp | ||
| 229 | hle/kernel/writable_event.h | ||
| 230 | hle/lock.cpp | 233 | hle/lock.cpp |
| 231 | hle/lock.h | 234 | hle/lock.h |
| 232 | hle/result.h | 235 | hle/result.h |
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index cebe2ce37..ad116dcc0 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -568,6 +568,11 @@ KeyManager::KeyManager() { | |||
| 568 | // Initialize keys | 568 | // Initialize keys |
| 569 | const std::string hactool_keys_dir = Common::FS::GetHactoolConfigurationPath(); | 569 | const std::string hactool_keys_dir = Common::FS::GetHactoolConfigurationPath(); |
| 570 | const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir); | 570 | const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir); |
| 571 | |||
| 572 | if (!Common::FS::Exists(yuzu_keys_dir)) { | ||
| 573 | Common::FS::CreateDir(yuzu_keys_dir); | ||
| 574 | } | ||
| 575 | |||
| 571 | if (Settings::values.use_dev_keys) { | 576 | if (Settings::values.use_dev_keys) { |
| 572 | dev_mode = true; | 577 | dev_mode = true; |
| 573 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false); | 578 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false); |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index c7b10ca7a..7ec62cf18 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -17,16 +17,16 @@ | |||
| 17 | #include "core/hle/kernel/errors.h" | 17 | #include "core/hle/kernel/errors.h" |
| 18 | #include "core/hle/kernel/handle_table.h" | 18 | #include "core/hle/kernel/handle_table.h" |
| 19 | #include "core/hle/kernel/hle_ipc.h" | 19 | #include "core/hle/kernel/hle_ipc.h" |
| 20 | #include "core/hle/kernel/k_readable_event.h" | ||
| 20 | #include "core/hle/kernel/k_scheduler.h" | 21 | #include "core/hle/kernel/k_scheduler.h" |
| 21 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | 22 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" |
| 22 | #include "core/hle/kernel/k_thread.h" | 23 | #include "core/hle/kernel/k_thread.h" |
| 24 | #include "core/hle/kernel/k_writable_event.h" | ||
| 23 | #include "core/hle/kernel/kernel.h" | 25 | #include "core/hle/kernel/kernel.h" |
| 24 | #include "core/hle/kernel/object.h" | 26 | #include "core/hle/kernel/object.h" |
| 25 | #include "core/hle/kernel/process.h" | 27 | #include "core/hle/kernel/process.h" |
| 26 | #include "core/hle/kernel/readable_event.h" | ||
| 27 | #include "core/hle/kernel/server_session.h" | 28 | #include "core/hle/kernel/server_session.h" |
| 28 | #include "core/hle/kernel/time_manager.h" | 29 | #include "core/hle/kernel/time_manager.h" |
| 29 | #include "core/hle/kernel/writable_event.h" | ||
| 30 | #include "core/memory.h" | 30 | #include "core/memory.h" |
| 31 | 31 | ||
| 32 | namespace Kernel { | 32 | namespace Kernel { |
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 9f764c79a..9a769781b 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -41,8 +41,8 @@ class KernelCore; | |||
| 41 | class Process; | 41 | class Process; |
| 42 | class ServerSession; | 42 | class ServerSession; |
| 43 | class KThread; | 43 | class KThread; |
| 44 | class ReadableEvent; | 44 | class KReadableEvent; |
| 45 | class WritableEvent; | 45 | class KWritableEvent; |
| 46 | 46 | ||
| 47 | enum class ThreadWakeupReason; | 47 | enum class ThreadWakeupReason; |
| 48 | 48 | ||
diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index 1685d25bb..d0e90fd60 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp | |||
| @@ -118,9 +118,13 @@ ResultCode KAddressArbiter::SignalAndIncrementIfEqual(VAddr addr, s32 value, s32 | |||
| 118 | 118 | ||
| 119 | // Check the userspace value. | 119 | // Check the userspace value. |
| 120 | s32 user_value{}; | 120 | s32 user_value{}; |
| 121 | R_UNLESS(UpdateIfEqual(system, std::addressof(user_value), addr, value, value + 1), | 121 | if (!UpdateIfEqual(system, &user_value, addr, value, value + 1)) { |
| 122 | Svc::ResultInvalidCurrentMemory); | 122 | LOG_ERROR(Kernel, "Invalid current memory!"); |
| 123 | R_UNLESS(user_value == value, Svc::ResultInvalidState); | 123 | return Svc::ResultInvalidCurrentMemory; |
| 124 | } | ||
| 125 | if (user_value != value) { | ||
| 126 | return Svc::ResultInvalidState; | ||
| 127 | } | ||
| 124 | 128 | ||
| 125 | auto it = thread_tree.nfind_light({addr, -1}); | 129 | auto it = thread_tree.nfind_light({addr, -1}); |
| 126 | while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && | 130 | while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && |
| @@ -143,61 +147,34 @@ ResultCode KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 | |||
| 143 | // Perform signaling. | 147 | // Perform signaling. |
| 144 | s32 num_waiters{}; | 148 | s32 num_waiters{}; |
| 145 | { | 149 | { |
| 146 | KScopedSchedulerLock sl(kernel); | 150 | [[maybe_unused]] const KScopedSchedulerLock sl(kernel); |
| 147 | 151 | ||
| 148 | auto it = thread_tree.nfind_light({addr, -1}); | 152 | auto it = thread_tree.nfind_light({addr, -1}); |
| 149 | // Determine the updated value. | 153 | // Determine the updated value. |
| 150 | s32 new_value{}; | 154 | s32 new_value{}; |
| 151 | if (/*GetTargetFirmware() >= TargetFirmware_7_0_0*/ true) { | 155 | if (count <= 0) { |
| 152 | if (count <= 0) { | 156 | if (it != thread_tree.end() && it->GetAddressArbiterKey() == addr) { |
| 153 | if ((it != thread_tree.end()) && (it->GetAddressArbiterKey() == addr)) { | 157 | new_value = value - 2; |
| 154 | new_value = value - 2; | ||
| 155 | } else { | ||
| 156 | new_value = value + 1; | ||
| 157 | } | ||
| 158 | } else { | 158 | } else { |
| 159 | if ((it != thread_tree.end()) && (it->GetAddressArbiterKey() == addr)) { | 159 | new_value = value + 1; |
| 160 | auto tmp_it = it; | ||
| 161 | s32 tmp_num_waiters{}; | ||
| 162 | while ((++tmp_it != thread_tree.end()) && | ||
| 163 | (tmp_it->GetAddressArbiterKey() == addr)) { | ||
| 164 | if ((tmp_num_waiters++) >= count) { | ||
| 165 | break; | ||
| 166 | } | ||
| 167 | } | ||
| 168 | |||
| 169 | if (tmp_num_waiters < count) { | ||
| 170 | new_value = value - 1; | ||
| 171 | } else { | ||
| 172 | new_value = value; | ||
| 173 | } | ||
| 174 | } else { | ||
| 175 | new_value = value + 1; | ||
| 176 | } | ||
| 177 | } | 160 | } |
| 178 | } else { | 161 | } else { |
| 179 | if (count <= 0) { | 162 | if (it != thread_tree.end() && it->GetAddressArbiterKey() == addr) { |
| 180 | if ((it != thread_tree.end()) && (it->GetAddressArbiterKey() == addr)) { | ||
| 181 | new_value = value - 1; | ||
| 182 | } else { | ||
| 183 | new_value = value + 1; | ||
| 184 | } | ||
| 185 | } else { | ||
| 186 | auto tmp_it = it; | 163 | auto tmp_it = it; |
| 187 | s32 tmp_num_waiters{}; | 164 | s32 tmp_num_waiters{}; |
| 188 | while ((tmp_it != thread_tree.end()) && (tmp_it->GetAddressArbiterKey() == addr) && | 165 | while (++tmp_it != thread_tree.end() && tmp_it->GetAddressArbiterKey() == addr) { |
| 189 | (tmp_num_waiters < count + 1)) { | 166 | if (tmp_num_waiters++ >= count) { |
| 190 | ++tmp_num_waiters; | 167 | break; |
| 191 | ++tmp_it; | 168 | } |
| 192 | } | 169 | } |
| 193 | 170 | ||
| 194 | if (tmp_num_waiters == 0) { | 171 | if (tmp_num_waiters < count) { |
| 195 | new_value = value + 1; | ||
| 196 | } else if (tmp_num_waiters <= count) { | ||
| 197 | new_value = value - 1; | 172 | new_value = value - 1; |
| 198 | } else { | 173 | } else { |
| 199 | new_value = value; | 174 | new_value = value; |
| 200 | } | 175 | } |
| 176 | } else { | ||
| 177 | new_value = value + 1; | ||
| 201 | } | 178 | } |
| 202 | } | 179 | } |
| 203 | 180 | ||
| @@ -205,13 +182,18 @@ ResultCode KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(VAddr addr, s32 | |||
| 205 | s32 user_value{}; | 182 | s32 user_value{}; |
| 206 | bool succeeded{}; | 183 | bool succeeded{}; |
| 207 | if (value != new_value) { | 184 | if (value != new_value) { |
| 208 | succeeded = UpdateIfEqual(system, std::addressof(user_value), addr, value, new_value); | 185 | succeeded = UpdateIfEqual(system, &user_value, addr, value, new_value); |
| 209 | } else { | 186 | } else { |
| 210 | succeeded = ReadFromUser(system, std::addressof(user_value), addr); | 187 | succeeded = ReadFromUser(system, &user_value, addr); |
| 211 | } | 188 | } |
| 212 | 189 | ||
| 213 | R_UNLESS(succeeded, Svc::ResultInvalidCurrentMemory); | 190 | if (!succeeded) { |
| 214 | R_UNLESS(user_value == value, Svc::ResultInvalidState); | 191 | LOG_ERROR(Kernel, "Invalid current memory!"); |
| 192 | return Svc::ResultInvalidCurrentMemory; | ||
| 193 | } | ||
| 194 | if (user_value != value) { | ||
| 195 | return Svc::ResultInvalidState; | ||
| 196 | } | ||
| 215 | 197 | ||
| 216 | while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && | 198 | while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && |
| 217 | (it->GetAddressArbiterKey() == addr)) { | 199 | (it->GetAddressArbiterKey() == addr)) { |
| @@ -249,9 +231,9 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement | |||
| 249 | s32 user_value{}; | 231 | s32 user_value{}; |
| 250 | bool succeeded{}; | 232 | bool succeeded{}; |
| 251 | if (decrement) { | 233 | if (decrement) { |
| 252 | succeeded = DecrementIfLessThan(system, std::addressof(user_value), addr, value); | 234 | succeeded = DecrementIfLessThan(system, &user_value, addr, value); |
| 253 | } else { | 235 | } else { |
| 254 | succeeded = ReadFromUser(system, std::addressof(user_value), addr); | 236 | succeeded = ReadFromUser(system, &user_value, addr); |
| 255 | } | 237 | } |
| 256 | 238 | ||
| 257 | if (!succeeded) { | 239 | if (!succeeded) { |
| @@ -272,7 +254,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement | |||
| 272 | } | 254 | } |
| 273 | 255 | ||
| 274 | // Set the arbiter. | 256 | // Set the arbiter. |
| 275 | cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr); | 257 | cur_thread->SetAddressArbiter(&thread_tree, addr); |
| 276 | thread_tree.insert(*cur_thread); | 258 | thread_tree.insert(*cur_thread); |
| 277 | cur_thread->SetState(ThreadState::Waiting); | 259 | cur_thread->SetState(ThreadState::Waiting); |
| 278 | cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); | 260 | cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); |
| @@ -293,7 +275,7 @@ ResultCode KAddressArbiter::WaitIfLessThan(VAddr addr, s32 value, bool decrement | |||
| 293 | 275 | ||
| 294 | // Get the result. | 276 | // Get the result. |
| 295 | KSynchronizationObject* dummy{}; | 277 | KSynchronizationObject* dummy{}; |
| 296 | return cur_thread->GetWaitResult(std::addressof(dummy)); | 278 | return cur_thread->GetWaitResult(&dummy); |
| 297 | } | 279 | } |
| 298 | 280 | ||
| 299 | ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { | 281 | ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { |
| @@ -314,7 +296,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { | |||
| 314 | 296 | ||
| 315 | // Read the value from userspace. | 297 | // Read the value from userspace. |
| 316 | s32 user_value{}; | 298 | s32 user_value{}; |
| 317 | if (!ReadFromUser(system, std::addressof(user_value), addr)) { | 299 | if (!ReadFromUser(system, &user_value, addr)) { |
| 318 | slp.CancelSleep(); | 300 | slp.CancelSleep(); |
| 319 | return Svc::ResultInvalidCurrentMemory; | 301 | return Svc::ResultInvalidCurrentMemory; |
| 320 | } | 302 | } |
| @@ -332,7 +314,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { | |||
| 332 | } | 314 | } |
| 333 | 315 | ||
| 334 | // Set the arbiter. | 316 | // Set the arbiter. |
| 335 | cur_thread->SetAddressArbiter(std::addressof(thread_tree), addr); | 317 | cur_thread->SetAddressArbiter(&thread_tree, addr); |
| 336 | thread_tree.insert(*cur_thread); | 318 | thread_tree.insert(*cur_thread); |
| 337 | cur_thread->SetState(ThreadState::Waiting); | 319 | cur_thread->SetState(ThreadState::Waiting); |
| 338 | cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); | 320 | cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); |
| @@ -353,7 +335,7 @@ ResultCode KAddressArbiter::WaitIfEqual(VAddr addr, s32 value, s64 timeout) { | |||
| 353 | 335 | ||
| 354 | // Get the result. | 336 | // Get the result. |
| 355 | KSynchronizationObject* dummy{}; | 337 | KSynchronizationObject* dummy{}; |
| 356 | return cur_thread->GetWaitResult(std::addressof(dummy)); | 338 | return cur_thread->GetWaitResult(&dummy); |
| 357 | } | 339 | } |
| 358 | 340 | ||
| 359 | } // namespace Kernel | 341 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_affinity_mask.h b/src/core/hle/kernel/k_affinity_mask.h index dd73781cd..b906895fc 100644 --- a/src/core/hle/kernel/k_affinity_mask.h +++ b/src/core/hle/kernel/k_affinity_mask.h | |||
| @@ -27,7 +27,7 @@ public: | |||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | [[nodiscard]] constexpr bool GetAffinity(s32 core) const { | 29 | [[nodiscard]] constexpr bool GetAffinity(s32 core) const { |
| 30 | return this->mask & GetCoreBit(core); | 30 | return (this->mask & GetCoreBit(core)) != 0; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | constexpr void SetAffinity(s32 core, bool set) { | 33 | constexpr void SetAffinity(s32 core, bool set) { |
diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp new file mode 100644 index 000000000..bb2fa4ad5 --- /dev/null +++ b/src/core/hle/kernel/k_event.cpp | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/kernel/k_event.h" | ||
| 6 | #include "core/hle/kernel/k_readable_event.h" | ||
| 7 | #include "core/hle/kernel/k_writable_event.h" | ||
| 8 | |||
| 9 | namespace Kernel { | ||
| 10 | |||
| 11 | KEvent::KEvent(KernelCore& kernel, std::string&& name) : Object{kernel, std::move(name)} {} | ||
| 12 | |||
| 13 | KEvent::~KEvent() = default; | ||
| 14 | |||
| 15 | std::shared_ptr<KEvent> KEvent::Create(KernelCore& kernel, std::string&& name) { | ||
| 16 | return std::make_shared<KEvent>(kernel, std::move(name)); | ||
| 17 | } | ||
| 18 | |||
| 19 | void KEvent::Initialize() { | ||
| 20 | // Create our sub events. | ||
| 21 | readable_event = std::make_shared<KReadableEvent>(kernel, GetName() + ":Readable"); | ||
| 22 | writable_event = std::make_shared<KWritableEvent>(kernel, GetName() + ":Writable"); | ||
| 23 | |||
| 24 | // Initialize our sub sessions. | ||
| 25 | readable_event->Initialize(this); | ||
| 26 | writable_event->Initialize(this); | ||
| 27 | |||
| 28 | // Mark initialized. | ||
| 29 | initialized = true; | ||
| 30 | } | ||
| 31 | |||
| 32 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h new file mode 100644 index 000000000..2fb887129 --- /dev/null +++ b/src/core/hle/kernel/k_event.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/kernel/object.h" | ||
| 8 | |||
| 9 | namespace Kernel { | ||
| 10 | |||
| 11 | class KernelCore; | ||
| 12 | class KReadableEvent; | ||
| 13 | class KWritableEvent; | ||
| 14 | |||
| 15 | class KEvent final : public Object { | ||
| 16 | public: | ||
| 17 | explicit KEvent(KernelCore& kernel, std::string&& name); | ||
| 18 | ~KEvent() override; | ||
| 19 | |||
| 20 | static std::shared_ptr<KEvent> Create(KernelCore& kernel, std::string&& name); | ||
| 21 | |||
| 22 | void Initialize(); | ||
| 23 | |||
| 24 | void Finalize() override {} | ||
| 25 | |||
| 26 | std::string GetTypeName() const override { | ||
| 27 | return "KEvent"; | ||
| 28 | } | ||
| 29 | |||
| 30 | static constexpr HandleType HANDLE_TYPE = HandleType::Event; | ||
| 31 | HandleType GetHandleType() const override { | ||
| 32 | return HANDLE_TYPE; | ||
| 33 | } | ||
| 34 | |||
| 35 | std::shared_ptr<KReadableEvent>& GetReadableEvent() { | ||
| 36 | return readable_event; | ||
| 37 | } | ||
| 38 | |||
| 39 | std::shared_ptr<KWritableEvent>& GetWritableEvent() { | ||
| 40 | return writable_event; | ||
| 41 | } | ||
| 42 | |||
| 43 | const std::shared_ptr<KReadableEvent>& GetReadableEvent() const { | ||
| 44 | return readable_event; | ||
| 45 | } | ||
| 46 | |||
| 47 | const std::shared_ptr<KWritableEvent>& GetWritableEvent() const { | ||
| 48 | return writable_event; | ||
| 49 | } | ||
| 50 | |||
| 51 | private: | ||
| 52 | std::shared_ptr<KReadableEvent> readable_event; | ||
| 53 | std::shared_ptr<KWritableEvent> writable_event; | ||
| 54 | bool initialized{}; | ||
| 55 | }; | ||
| 56 | |||
| 57 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_light_condition_variable.h b/src/core/hle/kernel/k_light_condition_variable.h new file mode 100644 index 000000000..362d0db28 --- /dev/null +++ b/src/core/hle/kernel/k_light_condition_variable.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
| 6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
| 7 | |||
| 8 | #pragma once | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | #include "core/hle/kernel/k_scheduler.h" | ||
| 12 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | ||
| 13 | #include "core/hle/kernel/k_thread_queue.h" | ||
| 14 | #include "core/hle/kernel/time_manager.h" | ||
| 15 | |||
| 16 | namespace Kernel { | ||
| 17 | class KernelCore; | ||
| 18 | |||
| 19 | class KLightConditionVariable { | ||
| 20 | public: | ||
| 21 | explicit KLightConditionVariable(KernelCore& kernel) : thread_queue(kernel), kernel(kernel) {} | ||
| 22 | |||
| 23 | void Wait(KLightLock* lock, s64 timeout = -1) { | ||
| 24 | WaitImpl(lock, timeout); | ||
| 25 | lock->Lock(); | ||
| 26 | } | ||
| 27 | |||
| 28 | void Broadcast() { | ||
| 29 | KScopedSchedulerLock lk{kernel}; | ||
| 30 | while (thread_queue.WakeupFrontThread() != nullptr) { | ||
| 31 | // We want to signal all threads, and so should continue waking up until there's nothing | ||
| 32 | // to wake. | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | private: | ||
| 37 | void WaitImpl(KLightLock* lock, s64 timeout) { | ||
| 38 | KThread* owner = GetCurrentThreadPointer(kernel); | ||
| 39 | |||
| 40 | // Sleep the thread. | ||
| 41 | { | ||
| 42 | KScopedSchedulerLockAndSleep lk(kernel, owner, timeout); | ||
| 43 | lock->Unlock(); | ||
| 44 | |||
| 45 | if (!thread_queue.SleepThread(owner)) { | ||
| 46 | lk.CancelSleep(); | ||
| 47 | return; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | // Cancel the task that the sleep setup. | ||
| 52 | kernel.TimeManager().UnscheduleTimeEvent(owner); | ||
| 53 | } | ||
| 54 | KThreadQueue thread_queue; | ||
| 55 | KernelCore& kernel; | ||
| 56 | }; | ||
| 57 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_priority_queue.h b/src/core/hle/kernel/k_priority_queue.h index 13d628b85..4aa669d95 100644 --- a/src/core/hle/kernel/k_priority_queue.h +++ b/src/core/hle/kernel/k_priority_queue.h | |||
| @@ -24,11 +24,11 @@ template <typename T> | |||
| 24 | concept KPriorityQueueAffinityMask = !std::is_reference_v<T> && requires(T & t) { | 24 | concept KPriorityQueueAffinityMask = !std::is_reference_v<T> && requires(T & t) { |
| 25 | { t.GetAffinityMask() } | 25 | { t.GetAffinityMask() } |
| 26 | ->Common::ConvertibleTo<u64>; | 26 | ->Common::ConvertibleTo<u64>; |
| 27 | {t.SetAffinityMask(std::declval<u64>())}; | 27 | {t.SetAffinityMask(0)}; |
| 28 | 28 | ||
| 29 | { t.GetAffinity(std::declval<int32_t>()) } | 29 | { t.GetAffinity(0) } |
| 30 | ->std::same_as<bool>; | 30 | ->std::same_as<bool>; |
| 31 | {t.SetAffinity(std::declval<int32_t>(), std::declval<bool>())}; | 31 | {t.SetAffinity(0, false)}; |
| 32 | {t.SetAll()}; | 32 | {t.SetAll()}; |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| @@ -42,11 +42,11 @@ concept KPriorityQueueMember = !std::is_reference_v<T> && requires(T & t) { | |||
| 42 | ->std::same_as<T*>; | 42 | ->std::same_as<T*>; |
| 43 | { (typename T::QueueEntry()).GetPrev() } | 43 | { (typename T::QueueEntry()).GetPrev() } |
| 44 | ->std::same_as<T*>; | 44 | ->std::same_as<T*>; |
| 45 | { t.GetPriorityQueueEntry(std::declval<s32>()) } | 45 | { t.GetPriorityQueueEntry(0) } |
| 46 | ->std::same_as<typename T::QueueEntry&>; | 46 | ->std::same_as<typename T::QueueEntry&>; |
| 47 | 47 | ||
| 48 | {t.GetAffinityMask()}; | 48 | {t.GetAffinityMask()}; |
| 49 | { typename std::remove_cvref<decltype(t.GetAffinityMask())>::type() } | 49 | { std::remove_cvref_t<decltype(t.GetAffinityMask())>() } |
| 50 | ->KPriorityQueueAffinityMask; | 50 | ->KPriorityQueueAffinityMask; |
| 51 | 51 | ||
| 52 | { t.GetActiveCore() } | 52 | { t.GetActiveCore() } |
| @@ -55,17 +55,17 @@ concept KPriorityQueueMember = !std::is_reference_v<T> && requires(T & t) { | |||
| 55 | ->Common::ConvertibleTo<s32>; | 55 | ->Common::ConvertibleTo<s32>; |
| 56 | }; | 56 | }; |
| 57 | 57 | ||
| 58 | template <typename Member, size_t _NumCores, int LowestPriority, int HighestPriority> | 58 | template <typename Member, size_t NumCores_, int LowestPriority, int HighestPriority> |
| 59 | requires KPriorityQueueMember<Member> class KPriorityQueue { | 59 | requires KPriorityQueueMember<Member> class KPriorityQueue { |
| 60 | public: | 60 | public: |
| 61 | using AffinityMaskType = typename std::remove_cv_t< | 61 | using AffinityMaskType = std::remove_cv_t< |
| 62 | typename std::remove_reference<decltype(std::declval<Member>().GetAffinityMask())>::type>; | 62 | std::remove_reference_t<decltype(std::declval<Member>().GetAffinityMask())>>; |
| 63 | 63 | ||
| 64 | static_assert(LowestPriority >= 0); | 64 | static_assert(LowestPriority >= 0); |
| 65 | static_assert(HighestPriority >= 0); | 65 | static_assert(HighestPriority >= 0); |
| 66 | static_assert(LowestPriority >= HighestPriority); | 66 | static_assert(LowestPriority >= HighestPriority); |
| 67 | static constexpr size_t NumPriority = LowestPriority - HighestPriority + 1; | 67 | static constexpr size_t NumPriority = LowestPriority - HighestPriority + 1; |
| 68 | static constexpr size_t NumCores = _NumCores; | 68 | static constexpr size_t NumCores = NumCores_; |
| 69 | 69 | ||
| 70 | static constexpr bool IsValidCore(s32 core) { | 70 | static constexpr bool IsValidCore(s32 core) { |
| 71 | return 0 <= core && core < static_cast<s32>(NumCores); | 71 | return 0 <= core && core < static_cast<s32>(NumCores); |
diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp new file mode 100644 index 000000000..d8a42dbaf --- /dev/null +++ b/src/core/hle/kernel/k_readable_event.cpp | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include "common/assert.h" | ||
| 7 | #include "common/common_funcs.h" | ||
| 8 | #include "common/logging/log.h" | ||
| 9 | #include "core/hle/kernel/errors.h" | ||
| 10 | #include "core/hle/kernel/k_readable_event.h" | ||
| 11 | #include "core/hle/kernel/k_scheduler.h" | ||
| 12 | #include "core/hle/kernel/k_thread.h" | ||
| 13 | #include "core/hle/kernel/kernel.h" | ||
| 14 | #include "core/hle/kernel/object.h" | ||
| 15 | #include "core/hle/kernel/svc_results.h" | ||
| 16 | |||
| 17 | namespace Kernel { | ||
| 18 | |||
| 19 | KReadableEvent::KReadableEvent(KernelCore& kernel, std::string&& name) | ||
| 20 | : KSynchronizationObject{kernel, std::move(name)} {} | ||
| 21 | KReadableEvent::~KReadableEvent() = default; | ||
| 22 | |||
| 23 | bool KReadableEvent::IsSignaled() const { | ||
| 24 | ASSERT(kernel.GlobalSchedulerContext().IsLocked()); | ||
| 25 | |||
| 26 | return is_signaled; | ||
| 27 | } | ||
| 28 | |||
| 29 | ResultCode KReadableEvent::Signal() { | ||
| 30 | KScopedSchedulerLock lk{kernel}; | ||
| 31 | |||
| 32 | if (!is_signaled) { | ||
| 33 | is_signaled = true; | ||
| 34 | NotifyAvailable(); | ||
| 35 | } | ||
| 36 | |||
| 37 | return RESULT_SUCCESS; | ||
| 38 | } | ||
| 39 | |||
| 40 | ResultCode KReadableEvent::Clear() { | ||
| 41 | Reset(); | ||
| 42 | |||
| 43 | return RESULT_SUCCESS; | ||
| 44 | } | ||
| 45 | |||
| 46 | ResultCode KReadableEvent::Reset() { | ||
| 47 | KScopedSchedulerLock lk{kernel}; | ||
| 48 | |||
| 49 | if (!is_signaled) { | ||
| 50 | return Svc::ResultInvalidState; | ||
| 51 | } | ||
| 52 | |||
| 53 | is_signaled = false; | ||
| 54 | return RESULT_SUCCESS; | ||
| 55 | } | ||
| 56 | |||
| 57 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h new file mode 100644 index 000000000..e6f0fd900 --- /dev/null +++ b/src/core/hle/kernel/k_readable_event.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/kernel/k_synchronization_object.h" | ||
| 8 | #include "core/hle/kernel/object.h" | ||
| 9 | #include "core/hle/result.h" | ||
| 10 | |||
| 11 | namespace Kernel { | ||
| 12 | |||
| 13 | class KernelCore; | ||
| 14 | class KEvent; | ||
| 15 | |||
| 16 | class KReadableEvent final : public KSynchronizationObject { | ||
| 17 | public: | ||
| 18 | explicit KReadableEvent(KernelCore& kernel, std::string&& name); | ||
| 19 | ~KReadableEvent() override; | ||
| 20 | |||
| 21 | std::string GetTypeName() const override { | ||
| 22 | return "KReadableEvent"; | ||
| 23 | } | ||
| 24 | |||
| 25 | static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent; | ||
| 26 | HandleType GetHandleType() const override { | ||
| 27 | return HANDLE_TYPE; | ||
| 28 | } | ||
| 29 | |||
| 30 | KEvent* GetParent() const { | ||
| 31 | return parent; | ||
| 32 | } | ||
| 33 | |||
| 34 | void Initialize(KEvent* parent_) { | ||
| 35 | is_signaled = false; | ||
| 36 | parent = parent_; | ||
| 37 | } | ||
| 38 | |||
| 39 | bool IsSignaled() const override; | ||
| 40 | void Finalize() override {} | ||
| 41 | |||
| 42 | ResultCode Signal(); | ||
| 43 | ResultCode Clear(); | ||
| 44 | ResultCode Reset(); | ||
| 45 | |||
| 46 | private: | ||
| 47 | bool is_signaled{}; | ||
| 48 | KEvent* parent{}; | ||
| 49 | }; | ||
| 50 | |||
| 51 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp new file mode 100644 index 000000000..ab2ab683f --- /dev/null +++ b/src/core/hle/kernel/k_resource_limit.cpp | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
| 6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
| 7 | |||
| 8 | #include "common/assert.h" | ||
| 9 | #include "core/core.h" | ||
| 10 | #include "core/core_timing.h" | ||
| 11 | #include "core/core_timing_util.h" | ||
| 12 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 13 | #include "core/hle/kernel/svc_results.h" | ||
| 14 | |||
| 15 | namespace Kernel { | ||
| 16 | constexpr s64 DefaultTimeout = 10000000000; // 10 seconds | ||
| 17 | |||
| 18 | KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system) | ||
| 19 | : Object{kernel}, lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {} | ||
| 20 | KResourceLimit::~KResourceLimit() = default; | ||
| 21 | |||
| 22 | s64 KResourceLimit::GetLimitValue(LimitableResource which) const { | ||
| 23 | const auto index = static_cast<std::size_t>(which); | ||
| 24 | s64 value{}; | ||
| 25 | { | ||
| 26 | KScopedLightLock lk{lock}; | ||
| 27 | value = limit_values[index]; | ||
| 28 | ASSERT(value >= 0); | ||
| 29 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 30 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 31 | } | ||
| 32 | return value; | ||
| 33 | } | ||
| 34 | |||
| 35 | s64 KResourceLimit::GetCurrentValue(LimitableResource which) const { | ||
| 36 | const auto index = static_cast<std::size_t>(which); | ||
| 37 | s64 value{}; | ||
| 38 | { | ||
| 39 | KScopedLightLock lk{lock}; | ||
| 40 | value = current_values[index]; | ||
| 41 | ASSERT(value >= 0); | ||
| 42 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 43 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 44 | } | ||
| 45 | return value; | ||
| 46 | } | ||
| 47 | |||
| 48 | s64 KResourceLimit::GetPeakValue(LimitableResource which) const { | ||
| 49 | const auto index = static_cast<std::size_t>(which); | ||
| 50 | s64 value{}; | ||
| 51 | { | ||
| 52 | KScopedLightLock lk{lock}; | ||
| 53 | value = peak_values[index]; | ||
| 54 | ASSERT(value >= 0); | ||
| 55 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 56 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 57 | } | ||
| 58 | return value; | ||
| 59 | } | ||
| 60 | |||
| 61 | s64 KResourceLimit::GetFreeValue(LimitableResource which) const { | ||
| 62 | const auto index = static_cast<std::size_t>(which); | ||
| 63 | s64 value{}; | ||
| 64 | { | ||
| 65 | KScopedLightLock lk(lock); | ||
| 66 | ASSERT(current_values[index] >= 0); | ||
| 67 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 68 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 69 | value = limit_values[index] - current_values[index]; | ||
| 70 | } | ||
| 71 | |||
| 72 | return value; | ||
| 73 | } | ||
| 74 | |||
| 75 | ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { | ||
| 76 | const auto index = static_cast<std::size_t>(which); | ||
| 77 | KScopedLightLock lk(lock); | ||
| 78 | R_UNLESS(current_values[index] <= value, Svc::ResultInvalidState); | ||
| 79 | |||
| 80 | limit_values[index] = value; | ||
| 81 | |||
| 82 | return RESULT_SUCCESS; | ||
| 83 | } | ||
| 84 | |||
| 85 | bool KResourceLimit::Reserve(LimitableResource which, s64 value) { | ||
| 86 | return Reserve(which, value, system.CoreTiming().GetGlobalTimeNs().count() + DefaultTimeout); | ||
| 87 | } | ||
| 88 | |||
| 89 | bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { | ||
| 90 | ASSERT(value >= 0); | ||
| 91 | const auto index = static_cast<std::size_t>(which); | ||
| 92 | KScopedLightLock lk(lock); | ||
| 93 | |||
| 94 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 95 | if (current_hints[index] >= limit_values[index]) { | ||
| 96 | return false; | ||
| 97 | } | ||
| 98 | |||
| 99 | // Loop until we reserve or run out of time. | ||
| 100 | while (true) { | ||
| 101 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 102 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 103 | |||
| 104 | // If we would overflow, don't allow to succeed. | ||
| 105 | if (current_values[index] + value <= current_values[index]) { | ||
| 106 | break; | ||
| 107 | } | ||
| 108 | |||
| 109 | if (current_values[index] + value <= limit_values[index]) { | ||
| 110 | current_values[index] += value; | ||
| 111 | current_hints[index] += value; | ||
| 112 | peak_values[index] = std::max(peak_values[index], current_values[index]); | ||
| 113 | return true; | ||
| 114 | } | ||
| 115 | |||
| 116 | if (current_hints[index] + value <= limit_values[index] && | ||
| 117 | (timeout < 0 || system.CoreTiming().GetGlobalTimeNs().count() < timeout)) { | ||
| 118 | waiter_count++; | ||
| 119 | cond_var.Wait(&lock, timeout); | ||
| 120 | waiter_count--; | ||
| 121 | } else { | ||
| 122 | break; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | return false; | ||
| 127 | } | ||
| 128 | |||
| 129 | void KResourceLimit::Release(LimitableResource which, s64 value) { | ||
| 130 | Release(which, value, value); | ||
| 131 | } | ||
| 132 | |||
| 133 | void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) { | ||
| 134 | ASSERT(value >= 0); | ||
| 135 | ASSERT(hint >= 0); | ||
| 136 | |||
| 137 | const auto index = static_cast<std::size_t>(which); | ||
| 138 | KScopedLightLock lk(lock); | ||
| 139 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 140 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 141 | ASSERT(value <= current_values[index]); | ||
| 142 | ASSERT(hint <= current_hints[index]); | ||
| 143 | |||
| 144 | current_values[index] -= value; | ||
| 145 | current_hints[index] -= hint; | ||
| 146 | |||
| 147 | if (waiter_count != 0) { | ||
| 148 | cond_var.Broadcast(); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h new file mode 100644 index 000000000..58ae456f1 --- /dev/null +++ b/src/core/hle/kernel/k_resource_limit.h | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
| 6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
| 7 | |||
| 8 | #pragma once | ||
| 9 | |||
| 10 | #include <array> | ||
| 11 | #include "common/common_types.h" | ||
| 12 | #include "core/hle/kernel/k_light_condition_variable.h" | ||
| 13 | #include "core/hle/kernel/k_light_lock.h" | ||
| 14 | #include "core/hle/kernel/object.h" | ||
| 15 | |||
| 16 | union ResultCode; | ||
| 17 | |||
| 18 | namespace Core { | ||
| 19 | class System; | ||
| 20 | } | ||
| 21 | |||
| 22 | namespace Kernel { | ||
| 23 | class KernelCore; | ||
| 24 | enum class LimitableResource : u32 { | ||
| 25 | PhysicalMemory = 0, | ||
| 26 | Threads = 1, | ||
| 27 | Events = 2, | ||
| 28 | TransferMemory = 3, | ||
| 29 | Sessions = 4, | ||
| 30 | |||
| 31 | Count, | ||
| 32 | }; | ||
| 33 | |||
| 34 | constexpr bool IsValidResourceType(LimitableResource type) { | ||
| 35 | return type < LimitableResource::Count; | ||
| 36 | } | ||
| 37 | |||
| 38 | class KResourceLimit final : public Object { | ||
| 39 | public: | ||
| 40 | explicit KResourceLimit(KernelCore& kernel, Core::System& system); | ||
| 41 | ~KResourceLimit(); | ||
| 42 | |||
| 43 | s64 GetLimitValue(LimitableResource which) const; | ||
| 44 | s64 GetCurrentValue(LimitableResource which) const; | ||
| 45 | s64 GetPeakValue(LimitableResource which) const; | ||
| 46 | s64 GetFreeValue(LimitableResource which) const; | ||
| 47 | |||
| 48 | ResultCode SetLimitValue(LimitableResource which, s64 value); | ||
| 49 | |||
| 50 | bool Reserve(LimitableResource which, s64 value); | ||
| 51 | bool Reserve(LimitableResource which, s64 value, s64 timeout); | ||
| 52 | void Release(LimitableResource which, s64 value); | ||
| 53 | void Release(LimitableResource which, s64 value, s64 hint); | ||
| 54 | |||
| 55 | std::string GetTypeName() const override { | ||
| 56 | return "KResourceLimit"; | ||
| 57 | } | ||
| 58 | std::string GetName() const override { | ||
| 59 | return GetTypeName(); | ||
| 60 | } | ||
| 61 | |||
| 62 | static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit; | ||
| 63 | HandleType GetHandleType() const override { | ||
| 64 | return HANDLE_TYPE; | ||
| 65 | } | ||
| 66 | |||
| 67 | virtual void Finalize() override {} | ||
| 68 | |||
| 69 | private: | ||
| 70 | using ResourceArray = std::array<s64, static_cast<std::size_t>(LimitableResource::Count)>; | ||
| 71 | ResourceArray limit_values{}; | ||
| 72 | ResourceArray current_values{}; | ||
| 73 | ResourceArray current_hints{}; | ||
| 74 | ResourceArray peak_values{}; | ||
| 75 | mutable KLightLock lock; | ||
| 76 | s32 waiter_count{}; | ||
| 77 | KLightConditionVariable cond_var; | ||
| 78 | KernelCore& kernel; | ||
| 79 | Core::System& system; | ||
| 80 | }; | ||
| 81 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp index a3b34f82f..140cc46a7 100644 --- a/src/core/hle/kernel/k_synchronization_object.cpp +++ b/src/core/hle/kernel/k_synchronization_object.cpp | |||
| @@ -132,6 +132,9 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, | |||
| 132 | 132 | ||
| 133 | KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : Object{kernel} {} | 133 | KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : Object{kernel} {} |
| 134 | 134 | ||
| 135 | KSynchronizationObject::KSynchronizationObject(KernelCore& kernel, std::string&& name) | ||
| 136 | : Object{kernel, std::move(name)} {} | ||
| 137 | |||
| 135 | KSynchronizationObject::~KSynchronizationObject() = default; | 138 | KSynchronizationObject::~KSynchronizationObject() = default; |
| 136 | 139 | ||
| 137 | void KSynchronizationObject::NotifyAvailable(ResultCode result) { | 140 | void KSynchronizationObject::NotifyAvailable(ResultCode result) { |
diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h index f65c71c28..5803718fd 100644 --- a/src/core/hle/kernel/k_synchronization_object.h +++ b/src/core/hle/kernel/k_synchronization_object.h | |||
| @@ -33,6 +33,7 @@ public: | |||
| 33 | 33 | ||
| 34 | protected: | 34 | protected: |
| 35 | explicit KSynchronizationObject(KernelCore& kernel); | 35 | explicit KSynchronizationObject(KernelCore& kernel); |
| 36 | explicit KSynchronizationObject(KernelCore& kernel, std::string&& name); | ||
| 36 | virtual ~KSynchronizationObject(); | 37 | virtual ~KSynchronizationObject(); |
| 37 | 38 | ||
| 38 | void NotifyAvailable(ResultCode result); | 39 | void NotifyAvailable(ResultCode result); |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index aa100e139..b59259c4f 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include "core/hle/kernel/errors.h" | 21 | #include "core/hle/kernel/errors.h" |
| 22 | #include "core/hle/kernel/handle_table.h" | 22 | #include "core/hle/kernel/handle_table.h" |
| 23 | #include "core/hle/kernel/k_condition_variable.h" | 23 | #include "core/hle/kernel/k_condition_variable.h" |
| 24 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 24 | #include "core/hle/kernel/k_scheduler.h" | 25 | #include "core/hle/kernel/k_scheduler.h" |
| 25 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | 26 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" |
| 26 | #include "core/hle/kernel/k_thread.h" | 27 | #include "core/hle/kernel/k_thread.h" |
| @@ -29,7 +30,6 @@ | |||
| 29 | #include "core/hle/kernel/memory/memory_layout.h" | 30 | #include "core/hle/kernel/memory/memory_layout.h" |
| 30 | #include "core/hle/kernel/object.h" | 31 | #include "core/hle/kernel/object.h" |
| 31 | #include "core/hle/kernel/process.h" | 32 | #include "core/hle/kernel/process.h" |
| 32 | #include "core/hle/kernel/resource_limit.h" | ||
| 33 | #include "core/hle/kernel/svc_results.h" | 33 | #include "core/hle/kernel/svc_results.h" |
| 34 | #include "core/hle/kernel/time_manager.h" | 34 | #include "core/hle/kernel/time_manager.h" |
| 35 | #include "core/hle/result.h" | 35 | #include "core/hle/result.h" |
| @@ -247,7 +247,7 @@ void KThread::Finalize() { | |||
| 247 | // Decrement the parent process's thread count. | 247 | // Decrement the parent process's thread count. |
| 248 | if (parent != nullptr) { | 248 | if (parent != nullptr) { |
| 249 | parent->DecrementThreadCount(); | 249 | parent->DecrementThreadCount(); |
| 250 | parent->GetResourceLimit()->Release(ResourceType::Threads, 1); | 250 | parent->GetResourceLimit()->Release(LimitableResource::Threads, 1); |
| 251 | } | 251 | } |
| 252 | } | 252 | } |
| 253 | 253 | ||
diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp new file mode 100644 index 000000000..25c52edb2 --- /dev/null +++ b/src/core/hle/kernel/k_writable_event.cpp | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/kernel/k_event.h" | ||
| 6 | #include "core/hle/kernel/k_readable_event.h" | ||
| 7 | #include "core/hle/kernel/k_writable_event.h" | ||
| 8 | |||
| 9 | namespace Kernel { | ||
| 10 | |||
| 11 | KWritableEvent::KWritableEvent(KernelCore& kernel, std::string&& name) | ||
| 12 | : Object{kernel, std::move(name)} {} | ||
| 13 | KWritableEvent::~KWritableEvent() = default; | ||
| 14 | |||
| 15 | void KWritableEvent::Initialize(KEvent* parent_) { | ||
| 16 | parent = parent_; | ||
| 17 | } | ||
| 18 | |||
| 19 | ResultCode KWritableEvent::Signal() { | ||
| 20 | return parent->GetReadableEvent()->Signal(); | ||
| 21 | } | ||
| 22 | |||
| 23 | ResultCode KWritableEvent::Clear() { | ||
| 24 | return parent->GetReadableEvent()->Clear(); | ||
| 25 | } | ||
| 26 | |||
| 27 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h new file mode 100644 index 000000000..518f5448d --- /dev/null +++ b/src/core/hle/kernel/k_writable_event.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | // Copyright 2021 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/kernel/object.h" | ||
| 8 | #include "core/hle/result.h" | ||
| 9 | |||
| 10 | namespace Kernel { | ||
| 11 | |||
| 12 | class KernelCore; | ||
| 13 | class KEvent; | ||
| 14 | |||
| 15 | class KWritableEvent final : public Object { | ||
| 16 | public: | ||
| 17 | explicit KWritableEvent(KernelCore& kernel, std::string&& name); | ||
| 18 | ~KWritableEvent() override; | ||
| 19 | |||
| 20 | std::string GetTypeName() const override { | ||
| 21 | return "KWritableEvent"; | ||
| 22 | } | ||
| 23 | |||
| 24 | static constexpr HandleType HANDLE_TYPE = HandleType::WritableEvent; | ||
| 25 | HandleType GetHandleType() const override { | ||
| 26 | return HANDLE_TYPE; | ||
| 27 | } | ||
| 28 | |||
| 29 | void Initialize(KEvent* parent_); | ||
| 30 | |||
| 31 | void Finalize() override {} | ||
| 32 | |||
| 33 | ResultCode Signal(); | ||
| 34 | ResultCode Clear(); | ||
| 35 | |||
| 36 | KEvent* GetParent() const { | ||
| 37 | return parent; | ||
| 38 | } | ||
| 39 | |||
| 40 | private: | ||
| 41 | KEvent* parent{}; | ||
| 42 | }; | ||
| 43 | |||
| 44 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index df309d523..b20c2d13a 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include "core/hle/kernel/client_port.h" | 28 | #include "core/hle/kernel/client_port.h" |
| 29 | #include "core/hle/kernel/errors.h" | 29 | #include "core/hle/kernel/errors.h" |
| 30 | #include "core/hle/kernel/handle_table.h" | 30 | #include "core/hle/kernel/handle_table.h" |
| 31 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 31 | #include "core/hle/kernel/k_scheduler.h" | 32 | #include "core/hle/kernel/k_scheduler.h" |
| 32 | #include "core/hle/kernel/k_thread.h" | 33 | #include "core/hle/kernel/k_thread.h" |
| 33 | #include "core/hle/kernel/kernel.h" | 34 | #include "core/hle/kernel/kernel.h" |
| @@ -36,7 +37,6 @@ | |||
| 36 | #include "core/hle/kernel/memory/slab_heap.h" | 37 | #include "core/hle/kernel/memory/slab_heap.h" |
| 37 | #include "core/hle/kernel/physical_core.h" | 38 | #include "core/hle/kernel/physical_core.h" |
| 38 | #include "core/hle/kernel/process.h" | 39 | #include "core/hle/kernel/process.h" |
| 39 | #include "core/hle/kernel/resource_limit.h" | ||
| 40 | #include "core/hle/kernel/service_thread.h" | 40 | #include "core/hle/kernel/service_thread.h" |
| 41 | #include "core/hle/kernel/shared_memory.h" | 41 | #include "core/hle/kernel/shared_memory.h" |
| 42 | #include "core/hle/kernel/time_manager.h" | 42 | #include "core/hle/kernel/time_manager.h" |
| @@ -66,7 +66,7 @@ struct KernelCore::Impl { | |||
| 66 | is_phantom_mode_for_singlecore = false; | 66 | is_phantom_mode_for_singlecore = false; |
| 67 | 67 | ||
| 68 | InitializePhysicalCores(); | 68 | InitializePhysicalCores(); |
| 69 | InitializeSystemResourceLimit(kernel); | 69 | InitializeSystemResourceLimit(kernel, system); |
| 70 | InitializeMemoryLayout(); | 70 | InitializeMemoryLayout(); |
| 71 | InitializePreemption(kernel); | 71 | InitializePreemption(kernel); |
| 72 | InitializeSchedulers(); | 72 | InitializeSchedulers(); |
| @@ -131,19 +131,19 @@ struct KernelCore::Impl { | |||
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | // Creates the default system resource limit | 133 | // Creates the default system resource limit |
| 134 | void InitializeSystemResourceLimit(KernelCore& kernel) { | 134 | void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) { |
| 135 | system_resource_limit = ResourceLimit::Create(kernel); | 135 | system_resource_limit = std::make_shared<KResourceLimit>(kernel, system); |
| 136 | 136 | ||
| 137 | // If setting the default system values fails, then something seriously wrong has occurred. | 137 | // If setting the default system values fails, then something seriously wrong has occurred. |
| 138 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::PhysicalMemory, 0x100000000) | 138 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000) |
| 139 | .IsSuccess()); | 139 | .IsSuccess()); |
| 140 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::Threads, 800).IsSuccess()); | 140 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); |
| 141 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::Events, 700).IsSuccess()); | 141 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 700).IsSuccess()); |
| 142 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::TransferMemory, 200).IsSuccess()); | 142 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) |
| 143 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess()); | 143 | .IsSuccess()); |
| 144 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 900).IsSuccess()); | ||
| 144 | 145 | ||
| 145 | if (!system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0) || | 146 | if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, 0x60000)) { |
| 146 | !system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0x60000)) { | ||
| 147 | UNREACHABLE(); | 147 | UNREACHABLE(); |
| 148 | } | 148 | } |
| 149 | } | 149 | } |
| @@ -320,7 +320,7 @@ struct KernelCore::Impl { | |||
| 320 | std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; | 320 | std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; |
| 321 | Kernel::TimeManager time_manager; | 321 | Kernel::TimeManager time_manager; |
| 322 | 322 | ||
| 323 | std::shared_ptr<ResourceLimit> system_resource_limit; | 323 | std::shared_ptr<KResourceLimit> system_resource_limit; |
| 324 | 324 | ||
| 325 | std::shared_ptr<Core::Timing::EventType> preemption_event; | 325 | std::shared_ptr<Core::Timing::EventType> preemption_event; |
| 326 | 326 | ||
| @@ -390,7 +390,7 @@ void KernelCore::Shutdown() { | |||
| 390 | impl->Shutdown(); | 390 | impl->Shutdown(); |
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | std::shared_ptr<ResourceLimit> KernelCore::GetSystemResourceLimit() const { | 393 | std::shared_ptr<KResourceLimit> KernelCore::GetSystemResourceLimit() const { |
| 394 | return impl->system_resource_limit; | 394 | return impl->system_resource_limit; |
| 395 | } | 395 | } |
| 396 | 396 | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index e7c77727b..806a0d986 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -38,7 +38,7 @@ class GlobalSchedulerContext; | |||
| 38 | class HandleTable; | 38 | class HandleTable; |
| 39 | class PhysicalCore; | 39 | class PhysicalCore; |
| 40 | class Process; | 40 | class Process; |
| 41 | class ResourceLimit; | 41 | class KResourceLimit; |
| 42 | class KScheduler; | 42 | class KScheduler; |
| 43 | class SharedMemory; | 43 | class SharedMemory; |
| 44 | class ServiceThread; | 44 | class ServiceThread; |
| @@ -85,7 +85,7 @@ public: | |||
| 85 | void Shutdown(); | 85 | void Shutdown(); |
| 86 | 86 | ||
| 87 | /// Retrieves a shared pointer to the system resource limit instance. | 87 | /// Retrieves a shared pointer to the system resource limit instance. |
| 88 | std::shared_ptr<ResourceLimit> GetSystemResourceLimit() const; | 88 | std::shared_ptr<KResourceLimit> GetSystemResourceLimit() const; |
| 89 | 89 | ||
| 90 | /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. | 90 | /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. |
| 91 | std::shared_ptr<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const; | 91 | std::shared_ptr<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const; |
diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index 080886554..7de91c768 100644 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include "common/scope_exit.h" | 7 | #include "common/scope_exit.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/kernel/errors.h" | 9 | #include "core/hle/kernel/errors.h" |
| 10 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 10 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/kernel.h" |
| 11 | #include "core/hle/kernel/memory/address_space_info.h" | 12 | #include "core/hle/kernel/memory/address_space_info.h" |
| 12 | #include "core/hle/kernel/memory/memory_block.h" | 13 | #include "core/hle/kernel/memory/memory_block.h" |
| @@ -15,7 +16,6 @@ | |||
| 15 | #include "core/hle/kernel/memory/page_table.h" | 16 | #include "core/hle/kernel/memory/page_table.h" |
| 16 | #include "core/hle/kernel/memory/system_control.h" | 17 | #include "core/hle/kernel/memory/system_control.h" |
| 17 | #include "core/hle/kernel/process.h" | 18 | #include "core/hle/kernel/process.h" |
| 18 | #include "core/hle/kernel/resource_limit.h" | ||
| 19 | #include "core/memory.h" | 19 | #include "core/memory.h" |
| 20 | 20 | ||
| 21 | namespace Kernel::Memory { | 21 | namespace Kernel::Memory { |
| @@ -414,7 +414,7 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 414 | const std::size_t remaining_pages{remaining_size / PageSize}; | 414 | const std::size_t remaining_pages{remaining_size / PageSize}; |
| 415 | 415 | ||
| 416 | if (process->GetResourceLimit() && | 416 | if (process->GetResourceLimit() && |
| 417 | !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, remaining_size)) { | 417 | !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemory, remaining_size)) { |
| 418 | return ERR_RESOURCE_LIMIT_EXCEEDED; | 418 | return ERR_RESOURCE_LIMIT_EXCEEDED; |
| 419 | } | 419 | } |
| 420 | 420 | ||
| @@ -422,7 +422,7 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 422 | { | 422 | { |
| 423 | auto block_guard = detail::ScopeExit([&] { | 423 | auto block_guard = detail::ScopeExit([&] { |
| 424 | system.Kernel().MemoryManager().Free(page_linked_list, remaining_pages, memory_pool); | 424 | system.Kernel().MemoryManager().Free(page_linked_list, remaining_pages, memory_pool); |
| 425 | process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, remaining_size); | 425 | process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, remaining_size); |
| 426 | }); | 426 | }); |
| 427 | 427 | ||
| 428 | CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, | 428 | CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, |
| @@ -474,7 +474,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 474 | CASCADE_CODE(UnmapMemory(addr, size)); | 474 | CASCADE_CODE(UnmapMemory(addr, size)); |
| 475 | 475 | ||
| 476 | auto process{system.Kernel().CurrentProcess()}; | 476 | auto process{system.Kernel().CurrentProcess()}; |
| 477 | process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, mapped_size); | 477 | process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, mapped_size); |
| 478 | physical_memory_usage -= mapped_size; | 478 | physical_memory_usage -= mapped_size; |
| 479 | 479 | ||
| 480 | return RESULT_SUCCESS; | 480 | return RESULT_SUCCESS; |
| @@ -783,7 +783,7 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) { | |||
| 783 | 783 | ||
| 784 | auto process{system.Kernel().CurrentProcess()}; | 784 | auto process{system.Kernel().CurrentProcess()}; |
| 785 | if (process->GetResourceLimit() && delta != 0 && | 785 | if (process->GetResourceLimit() && delta != 0 && |
| 786 | !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, delta)) { | 786 | !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemory, delta)) { |
| 787 | return ERR_RESOURCE_LIMIT_EXCEEDED; | 787 | return ERR_RESOURCE_LIMIT_EXCEEDED; |
| 788 | } | 788 | } |
| 789 | 789 | ||
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp index 2c571792b..d7f40c403 100644 --- a/src/core/hle/kernel/object.cpp +++ b/src/core/hle/kernel/object.cpp | |||
| @@ -8,7 +8,10 @@ | |||
| 8 | 8 | ||
| 9 | namespace Kernel { | 9 | namespace Kernel { |
| 10 | 10 | ||
| 11 | Object::Object(KernelCore& kernel) : kernel{kernel}, object_id{kernel.CreateNewObjectID()} {} | 11 | Object::Object(KernelCore& kernel_) |
| 12 | : kernel{kernel_}, object_id{kernel_.CreateNewObjectID()}, name{"[UNKNOWN KERNEL OBJECT]"} {} | ||
| 13 | Object::Object(KernelCore& kernel_, std::string&& name_) | ||
| 14 | : kernel{kernel_}, object_id{kernel_.CreateNewObjectID()}, name{std::move(name_)} {} | ||
| 12 | Object::~Object() = default; | 15 | Object::~Object() = default; |
| 13 | 16 | ||
| 14 | bool Object::IsWaitable() const { | 17 | bool Object::IsWaitable() const { |
| @@ -21,6 +24,7 @@ bool Object::IsWaitable() const { | |||
| 21 | return true; | 24 | return true; |
| 22 | 25 | ||
| 23 | case HandleType::Unknown: | 26 | case HandleType::Unknown: |
| 27 | case HandleType::Event: | ||
| 24 | case HandleType::WritableEvent: | 28 | case HandleType::WritableEvent: |
| 25 | case HandleType::SharedMemory: | 29 | case HandleType::SharedMemory: |
| 26 | case HandleType::TransferMemory: | 30 | case HandleType::TransferMemory: |
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index be7fcb5fb..501e58b33 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h | |||
| @@ -18,6 +18,7 @@ using Handle = u32; | |||
| 18 | 18 | ||
| 19 | enum class HandleType : u32 { | 19 | enum class HandleType : u32 { |
| 20 | Unknown, | 20 | Unknown, |
| 21 | Event, | ||
| 21 | WritableEvent, | 22 | WritableEvent, |
| 22 | ReadableEvent, | 23 | ReadableEvent, |
| 23 | SharedMemory, | 24 | SharedMemory, |
| @@ -34,7 +35,8 @@ enum class HandleType : u32 { | |||
| 34 | 35 | ||
| 35 | class Object : NonCopyable, public std::enable_shared_from_this<Object> { | 36 | class Object : NonCopyable, public std::enable_shared_from_this<Object> { |
| 36 | public: | 37 | public: |
| 37 | explicit Object(KernelCore& kernel); | 38 | explicit Object(KernelCore& kernel_); |
| 39 | explicit Object(KernelCore& kernel_, std::string&& name_); | ||
| 38 | virtual ~Object(); | 40 | virtual ~Object(); |
| 39 | 41 | ||
| 40 | /// Returns a unique identifier for the object. For debugging purposes only. | 42 | /// Returns a unique identifier for the object. For debugging purposes only. |
| @@ -46,7 +48,7 @@ public: | |||
| 46 | return "[BAD KERNEL OBJECT TYPE]"; | 48 | return "[BAD KERNEL OBJECT TYPE]"; |
| 47 | } | 49 | } |
| 48 | virtual std::string GetName() const { | 50 | virtual std::string GetName() const { |
| 49 | return "[UNKNOWN KERNEL OBJECT]"; | 51 | return name; |
| 50 | } | 52 | } |
| 51 | virtual HandleType GetHandleType() const = 0; | 53 | virtual HandleType GetHandleType() const = 0; |
| 52 | 54 | ||
| @@ -69,6 +71,7 @@ protected: | |||
| 69 | 71 | ||
| 70 | private: | 72 | private: |
| 71 | std::atomic<u32> object_id{0}; | 73 | std::atomic<u32> object_id{0}; |
| 74 | std::string name; | ||
| 72 | }; | 75 | }; |
| 73 | 76 | ||
| 74 | template <typename T> | 77 | template <typename T> |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 0edbfc4cc..2286b292d 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "core/file_sys/program_metadata.h" | 15 | #include "core/file_sys/program_metadata.h" |
| 16 | #include "core/hle/kernel/code_set.h" | 16 | #include "core/hle/kernel/code_set.h" |
| 17 | #include "core/hle/kernel/errors.h" | 17 | #include "core/hle/kernel/errors.h" |
| 18 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 18 | #include "core/hle/kernel/k_scheduler.h" | 19 | #include "core/hle/kernel/k_scheduler.h" |
| 19 | #include "core/hle/kernel/k_thread.h" | 20 | #include "core/hle/kernel/k_thread.h" |
| 20 | #include "core/hle/kernel/kernel.h" | 21 | #include "core/hle/kernel/kernel.h" |
| @@ -22,7 +23,7 @@ | |||
| 22 | #include "core/hle/kernel/memory/page_table.h" | 23 | #include "core/hle/kernel/memory/page_table.h" |
| 23 | #include "core/hle/kernel/memory/slab_heap.h" | 24 | #include "core/hle/kernel/memory/slab_heap.h" |
| 24 | #include "core/hle/kernel/process.h" | 25 | #include "core/hle/kernel/process.h" |
| 25 | #include "core/hle/kernel/resource_limit.h" | 26 | #include "core/hle/kernel/svc_results.h" |
| 26 | #include "core/hle/lock.h" | 27 | #include "core/hle/lock.h" |
| 27 | #include "core/memory.h" | 28 | #include "core/memory.h" |
| 28 | #include "core/settings.h" | 29 | #include "core/settings.h" |
| @@ -116,7 +117,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, | |||
| 116 | 117 | ||
| 117 | std::shared_ptr<Process> process = std::make_shared<Process>(system); | 118 | std::shared_ptr<Process> process = std::make_shared<Process>(system); |
| 118 | process->name = std::move(name); | 119 | process->name = std::move(name); |
| 119 | process->resource_limit = ResourceLimit::Create(kernel); | 120 | process->resource_limit = std::make_shared<KResourceLimit>(kernel, system); |
| 120 | process->status = ProcessStatus::Created; | 121 | process->status = ProcessStatus::Created; |
| 121 | process->program_id = 0; | 122 | process->program_id = 0; |
| 122 | process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() | 123 | process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() |
| @@ -132,7 +133,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, | |||
| 132 | return process; | 133 | return process; |
| 133 | } | 134 | } |
| 134 | 135 | ||
| 135 | std::shared_ptr<ResourceLimit> Process::GetResourceLimit() const { | 136 | std::shared_ptr<KResourceLimit> Process::GetResourceLimit() const { |
| 136 | return resource_limit; | 137 | return resource_limit; |
| 137 | } | 138 | } |
| 138 | 139 | ||
| @@ -154,7 +155,7 @@ void Process::DecrementThreadCount() { | |||
| 154 | } | 155 | } |
| 155 | 156 | ||
| 156 | u64 Process::GetTotalPhysicalMemoryAvailable() const { | 157 | u64 Process::GetTotalPhysicalMemoryAvailable() const { |
| 157 | const u64 capacity{resource_limit->GetCurrentResourceValue(ResourceType::PhysicalMemory) + | 158 | const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + |
| 158 | page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + | 159 | page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + |
| 159 | main_thread_stack_size}; | 160 | main_thread_stack_size}; |
| 160 | 161 | ||
| @@ -241,18 +242,16 @@ void Process::UnregisterThread(const KThread* thread) { | |||
| 241 | thread_list.remove(thread); | 242 | thread_list.remove(thread); |
| 242 | } | 243 | } |
| 243 | 244 | ||
| 244 | ResultCode Process::ClearSignalState() { | 245 | ResultCode Process::Reset() { |
| 245 | KScopedSchedulerLock lock(system.Kernel()); | 246 | // Lock the process and the scheduler. |
| 246 | if (status == ProcessStatus::Exited) { | 247 | KScopedLightLock lk(state_lock); |
| 247 | LOG_ERROR(Kernel, "called on a terminated process instance."); | 248 | KScopedSchedulerLock sl{kernel}; |
| 248 | return ERR_INVALID_STATE; | ||
| 249 | } | ||
| 250 | 249 | ||
| 251 | if (!is_signaled) { | 250 | // Validate that we're in a state that we can reset. |
| 252 | LOG_ERROR(Kernel, "called on a process instance that isn't signaled."); | 251 | R_UNLESS(status != ProcessStatus::Exited, Svc::ResultInvalidState); |
| 253 | return ERR_INVALID_STATE; | 252 | R_UNLESS(is_signaled, Svc::ResultInvalidState); |
| 254 | } | ||
| 255 | 253 | ||
| 254 | // Clear signaled. | ||
| 256 | is_signaled = false; | 255 | is_signaled = false; |
| 257 | return RESULT_SUCCESS; | 256 | return RESULT_SUCCESS; |
| 258 | } | 257 | } |
| @@ -308,13 +307,13 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 308 | 307 | ||
| 309 | // Set initial resource limits | 308 | // Set initial resource limits |
| 310 | resource_limit->SetLimitValue( | 309 | resource_limit->SetLimitValue( |
| 311 | ResourceType::PhysicalMemory, | 310 | LimitableResource::PhysicalMemory, |
| 312 | kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); | 311 | kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); |
| 313 | resource_limit->SetLimitValue(ResourceType::Threads, 608); | 312 | resource_limit->SetLimitValue(LimitableResource::Threads, 608); |
| 314 | resource_limit->SetLimitValue(ResourceType::Events, 700); | 313 | resource_limit->SetLimitValue(LimitableResource::Events, 700); |
| 315 | resource_limit->SetLimitValue(ResourceType::TransferMemory, 128); | 314 | resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128); |
| 316 | resource_limit->SetLimitValue(ResourceType::Sessions, 894); | 315 | resource_limit->SetLimitValue(LimitableResource::Sessions, 894); |
| 317 | ASSERT(resource_limit->Reserve(ResourceType::PhysicalMemory, code_size)); | 316 | ASSERT(resource_limit->Reserve(LimitableResource::PhysicalMemory, code_size)); |
| 318 | 317 | ||
| 319 | // Create TLS region | 318 | // Create TLS region |
| 320 | tls_region_address = CreateTLSRegion(); | 319 | tls_region_address = CreateTLSRegion(); |
| @@ -331,8 +330,8 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) { | |||
| 331 | ChangeStatus(ProcessStatus::Running); | 330 | ChangeStatus(ProcessStatus::Running); |
| 332 | 331 | ||
| 333 | SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); | 332 | SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); |
| 334 | resource_limit->Reserve(ResourceType::Threads, 1); | 333 | resource_limit->Reserve(LimitableResource::Threads, 1); |
| 335 | resource_limit->Reserve(ResourceType::PhysicalMemory, main_thread_stack_size); | 334 | resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size); |
| 336 | } | 335 | } |
| 337 | 336 | ||
| 338 | void Process::PrepareForTermination() { | 337 | void Process::PrepareForTermination() { |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 26e647743..320b0f347 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -29,7 +29,7 @@ class ProgramMetadata; | |||
| 29 | namespace Kernel { | 29 | namespace Kernel { |
| 30 | 30 | ||
| 31 | class KernelCore; | 31 | class KernelCore; |
| 32 | class ResourceLimit; | 32 | class KResourceLimit; |
| 33 | class KThread; | 33 | class KThread; |
| 34 | class TLSPage; | 34 | class TLSPage; |
| 35 | 35 | ||
| @@ -170,7 +170,7 @@ public: | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | /// Gets the resource limit descriptor for this process | 172 | /// Gets the resource limit descriptor for this process |
| 173 | std::shared_ptr<ResourceLimit> GetResourceLimit() const; | 173 | std::shared_ptr<KResourceLimit> GetResourceLimit() const; |
| 174 | 174 | ||
| 175 | /// Gets the ideal CPU core ID for this process | 175 | /// Gets the ideal CPU core ID for this process |
| 176 | u8 GetIdealCoreId() const { | 176 | u8 GetIdealCoreId() const { |
| @@ -312,7 +312,7 @@ public: | |||
| 312 | /// @pre The process must be in a signaled state. If this is called on a | 312 | /// @pre The process must be in a signaled state. If this is called on a |
| 313 | /// process instance that is not signaled, ERR_INVALID_STATE will be | 313 | /// process instance that is not signaled, ERR_INVALID_STATE will be |
| 314 | /// returned. | 314 | /// returned. |
| 315 | ResultCode ClearSignalState(); | 315 | ResultCode Reset(); |
| 316 | 316 | ||
| 317 | /** | 317 | /** |
| 318 | * Loads process-specifics configuration info with metadata provided | 318 | * Loads process-specifics configuration info with metadata provided |
| @@ -402,7 +402,7 @@ private: | |||
| 402 | u32 system_resource_size = 0; | 402 | u32 system_resource_size = 0; |
| 403 | 403 | ||
| 404 | /// Resource limit descriptor for this process | 404 | /// Resource limit descriptor for this process |
| 405 | std::shared_ptr<ResourceLimit> resource_limit; | 405 | std::shared_ptr<KResourceLimit> resource_limit; |
| 406 | 406 | ||
| 407 | /// The ideal CPU core for this process, threads are scheduled on this core by default. | 407 | /// The ideal CPU core for this process, threads are scheduled on this core by default. |
| 408 | u8 ideal_core = 0; | 408 | u8 ideal_core = 0; |
diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp deleted file mode 100644 index 596d01479..000000000 --- a/src/core/hle/kernel/readable_event.cpp +++ /dev/null | |||
| @@ -1,52 +0,0 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include "common/assert.h" | ||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/hle/kernel/errors.h" | ||
| 9 | #include "core/hle/kernel/k_scheduler.h" | ||
| 10 | #include "core/hle/kernel/k_thread.h" | ||
| 11 | #include "core/hle/kernel/kernel.h" | ||
| 12 | #include "core/hle/kernel/object.h" | ||
| 13 | #include "core/hle/kernel/readable_event.h" | ||
| 14 | |||
| 15 | namespace Kernel { | ||
| 16 | |||
| 17 | ReadableEvent::ReadableEvent(KernelCore& kernel) : KSynchronizationObject{kernel} {} | ||
| 18 | ReadableEvent::~ReadableEvent() = default; | ||
| 19 | |||
| 20 | void ReadableEvent::Signal() { | ||
| 21 | if (is_signaled) { | ||
| 22 | return; | ||
| 23 | } | ||
| 24 | |||
| 25 | is_signaled = true; | ||
| 26 | NotifyAvailable(); | ||
| 27 | } | ||
| 28 | |||
| 29 | bool ReadableEvent::IsSignaled() const { | ||
| 30 | ASSERT(kernel.GlobalSchedulerContext().IsLocked()); | ||
| 31 | |||
| 32 | return is_signaled; | ||
| 33 | } | ||
| 34 | |||
| 35 | void ReadableEvent::Clear() { | ||
| 36 | is_signaled = false; | ||
| 37 | } | ||
| 38 | |||
| 39 | ResultCode ReadableEvent::Reset() { | ||
| 40 | KScopedSchedulerLock lock(kernel); | ||
| 41 | if (!is_signaled) { | ||
| 42 | LOG_TRACE(Kernel, "Handle is not signaled! object_id={}, object_type={}, object_name={}", | ||
| 43 | GetObjectId(), GetTypeName(), GetName()); | ||
| 44 | return ERR_INVALID_STATE; | ||
| 45 | } | ||
| 46 | |||
| 47 | Clear(); | ||
| 48 | |||
| 49 | return RESULT_SUCCESS; | ||
| 50 | } | ||
| 51 | |||
| 52 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h deleted file mode 100644 index 2195710c2..000000000 --- a/src/core/hle/kernel/readable_event.h +++ /dev/null | |||
| @@ -1,59 +0,0 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/kernel/k_synchronization_object.h" | ||
| 8 | #include "core/hle/kernel/object.h" | ||
| 9 | |||
| 10 | union ResultCode; | ||
| 11 | |||
| 12 | namespace Kernel { | ||
| 13 | |||
| 14 | class KernelCore; | ||
| 15 | class WritableEvent; | ||
| 16 | |||
| 17 | class ReadableEvent final : public KSynchronizationObject { | ||
| 18 | friend class WritableEvent; | ||
| 19 | |||
| 20 | public: | ||
| 21 | ~ReadableEvent() override; | ||
| 22 | |||
| 23 | std::string GetTypeName() const override { | ||
| 24 | return "ReadableEvent"; | ||
| 25 | } | ||
| 26 | std::string GetName() const override { | ||
| 27 | return name; | ||
| 28 | } | ||
| 29 | |||
| 30 | static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent; | ||
| 31 | HandleType GetHandleType() const override { | ||
| 32 | return HANDLE_TYPE; | ||
| 33 | } | ||
| 34 | |||
| 35 | /// Unconditionally clears the readable event's state. | ||
| 36 | void Clear(); | ||
| 37 | |||
| 38 | /// Clears the readable event's state if and only if it | ||
| 39 | /// has already been signaled. | ||
| 40 | /// | ||
| 41 | /// @pre The event must be in a signaled state. If this event | ||
| 42 | /// is in an unsignaled state and this function is called, | ||
| 43 | /// then ERR_INVALID_STATE will be returned. | ||
| 44 | ResultCode Reset(); | ||
| 45 | |||
| 46 | void Signal(); | ||
| 47 | |||
| 48 | bool IsSignaled() const override; | ||
| 49 | |||
| 50 | void Finalize() override {} | ||
| 51 | |||
| 52 | private: | ||
| 53 | explicit ReadableEvent(KernelCore& kernel); | ||
| 54 | |||
| 55 | bool is_signaled{}; | ||
| 56 | std::string name; ///< Name of event (optional) | ||
| 57 | }; | ||
| 58 | |||
| 59 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp deleted file mode 100644 index 7bf50339d..000000000 --- a/src/core/hle/kernel/resource_limit.cpp +++ /dev/null | |||
| @@ -1,73 +0,0 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/kernel/errors.h" | ||
| 6 | #include "core/hle/kernel/resource_limit.h" | ||
| 7 | #include "core/hle/result.h" | ||
| 8 | |||
| 9 | namespace Kernel { | ||
| 10 | namespace { | ||
| 11 | constexpr std::size_t ResourceTypeToIndex(ResourceType type) { | ||
| 12 | return static_cast<std::size_t>(type); | ||
| 13 | } | ||
| 14 | } // Anonymous namespace | ||
| 15 | |||
| 16 | ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {} | ||
| 17 | ResourceLimit::~ResourceLimit() = default; | ||
| 18 | |||
| 19 | bool ResourceLimit::Reserve(ResourceType resource, s64 amount) { | ||
| 20 | return Reserve(resource, amount, 10000000000); | ||
| 21 | } | ||
| 22 | |||
| 23 | bool ResourceLimit::Reserve(ResourceType resource, s64 amount, u64 timeout) { | ||
| 24 | const std::size_t index{ResourceTypeToIndex(resource)}; | ||
| 25 | |||
| 26 | s64 new_value = current[index] + amount; | ||
| 27 | if (new_value > limit[index] && available[index] + amount <= limit[index]) { | ||
| 28 | // TODO(bunnei): This is wrong for multicore, we should wait the calling thread for timeout | ||
| 29 | new_value = current[index] + amount; | ||
| 30 | } | ||
| 31 | |||
| 32 | if (new_value <= limit[index]) { | ||
| 33 | current[index] = new_value; | ||
| 34 | return true; | ||
| 35 | } | ||
| 36 | return false; | ||
| 37 | } | ||
| 38 | |||
| 39 | void ResourceLimit::Release(ResourceType resource, u64 amount) { | ||
| 40 | Release(resource, amount, amount); | ||
| 41 | } | ||
| 42 | |||
| 43 | void ResourceLimit::Release(ResourceType resource, u64 used_amount, u64 available_amount) { | ||
| 44 | const std::size_t index{ResourceTypeToIndex(resource)}; | ||
| 45 | |||
| 46 | current[index] -= used_amount; | ||
| 47 | available[index] -= available_amount; | ||
| 48 | } | ||
| 49 | |||
| 50 | std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) { | ||
| 51 | return std::make_shared<ResourceLimit>(kernel); | ||
| 52 | } | ||
| 53 | |||
| 54 | s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const { | ||
| 55 | return limit.at(ResourceTypeToIndex(resource)) - current.at(ResourceTypeToIndex(resource)); | ||
| 56 | } | ||
| 57 | |||
| 58 | s64 ResourceLimit::GetMaxResourceValue(ResourceType resource) const { | ||
| 59 | return limit.at(ResourceTypeToIndex(resource)); | ||
| 60 | } | ||
| 61 | |||
| 62 | ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) { | ||
| 63 | const std::size_t index{ResourceTypeToIndex(resource)}; | ||
| 64 | if (current[index] <= value) { | ||
| 65 | limit[index] = value; | ||
| 66 | return RESULT_SUCCESS; | ||
| 67 | } else { | ||
| 68 | LOG_ERROR(Kernel, "Limit value is too large! resource={}, value={}, index={}", resource, | ||
| 69 | value, index); | ||
| 70 | return ERR_INVALID_STATE; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h deleted file mode 100644 index 464d4f2a6..000000000 --- a/src/core/hle/kernel/resource_limit.h +++ /dev/null | |||
| @@ -1,106 +0,0 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <memory> | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | #include "core/hle/kernel/object.h" | ||
| 12 | |||
| 13 | union ResultCode; | ||
| 14 | |||
| 15 | namespace Kernel { | ||
| 16 | |||
| 17 | class KernelCore; | ||
| 18 | |||
| 19 | enum class ResourceType : u32 { | ||
| 20 | PhysicalMemory, | ||
| 21 | Threads, | ||
| 22 | Events, | ||
| 23 | TransferMemory, | ||
| 24 | Sessions, | ||
| 25 | |||
| 26 | // Used as a count, not an actual type. | ||
| 27 | ResourceTypeCount | ||
| 28 | }; | ||
| 29 | |||
| 30 | constexpr bool IsValidResourceType(ResourceType type) { | ||
| 31 | return type < ResourceType::ResourceTypeCount; | ||
| 32 | } | ||
| 33 | |||
| 34 | class ResourceLimit final : public Object { | ||
| 35 | public: | ||
| 36 | explicit ResourceLimit(KernelCore& kernel); | ||
| 37 | ~ResourceLimit() override; | ||
| 38 | |||
| 39 | /// Creates a resource limit object. | ||
| 40 | static std::shared_ptr<ResourceLimit> Create(KernelCore& kernel); | ||
| 41 | |||
| 42 | std::string GetTypeName() const override { | ||
| 43 | return "ResourceLimit"; | ||
| 44 | } | ||
| 45 | std::string GetName() const override { | ||
| 46 | return GetTypeName(); | ||
| 47 | } | ||
| 48 | |||
| 49 | static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit; | ||
| 50 | HandleType GetHandleType() const override { | ||
| 51 | return HANDLE_TYPE; | ||
| 52 | } | ||
| 53 | |||
| 54 | bool Reserve(ResourceType resource, s64 amount); | ||
| 55 | bool Reserve(ResourceType resource, s64 amount, u64 timeout); | ||
| 56 | void Release(ResourceType resource, u64 amount); | ||
| 57 | void Release(ResourceType resource, u64 used_amount, u64 available_amount); | ||
| 58 | |||
| 59 | /** | ||
| 60 | * Gets the current value for the specified resource. | ||
| 61 | * @param resource Requested resource type | ||
| 62 | * @returns The current value of the resource type | ||
| 63 | */ | ||
| 64 | s64 GetCurrentResourceValue(ResourceType resource) const; | ||
| 65 | |||
| 66 | /** | ||
| 67 | * Gets the max value for the specified resource. | ||
| 68 | * @param resource Requested resource type | ||
| 69 | * @returns The max value of the resource type | ||
| 70 | */ | ||
| 71 | s64 GetMaxResourceValue(ResourceType resource) const; | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Sets the limit value for a given resource type. | ||
| 75 | * | ||
| 76 | * @param resource The resource type to apply the limit to. | ||
| 77 | * @param value The limit to apply to the given resource type. | ||
| 78 | * | ||
| 79 | * @return A result code indicating if setting the limit value | ||
| 80 | * was successful or not. | ||
| 81 | * | ||
| 82 | * @note The supplied limit value *must* be greater than or equal to | ||
| 83 | * the current resource value for the given resource type, | ||
| 84 | * otherwise ERR_INVALID_STATE will be returned. | ||
| 85 | */ | ||
| 86 | ResultCode SetLimitValue(ResourceType resource, s64 value); | ||
| 87 | |||
| 88 | void Finalize() override {} | ||
| 89 | |||
| 90 | private: | ||
| 91 | // TODO(Subv): Increment resource limit current values in their respective Kernel::T::Create | ||
| 92 | // functions | ||
| 93 | // | ||
| 94 | // Currently we have no way of distinguishing if a Create was called by the running application, | ||
| 95 | // or by a service module. Approach this once we have separated the service modules into their | ||
| 96 | // own processes | ||
| 97 | |||
| 98 | using ResourceArray = | ||
| 99 | std::array<s64, static_cast<std::size_t>(ResourceType::ResourceTypeCount)>; | ||
| 100 | |||
| 101 | ResourceArray limit{}; | ||
| 102 | ResourceArray current{}; | ||
| 103 | ResourceArray available{}; | ||
| 104 | }; | ||
| 105 | |||
| 106 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 7fd514e9d..edf208eff 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "common/fiber.h" | 14 | #include "common/fiber.h" |
| 15 | #include "common/logging/log.h" | 15 | #include "common/logging/log.h" |
| 16 | #include "common/microprofile.h" | 16 | #include "common/microprofile.h" |
| 17 | #include "common/scope_exit.h" | ||
| 17 | #include "common/string_util.h" | 18 | #include "common/string_util.h" |
| 18 | #include "core/arm/exclusive_monitor.h" | 19 | #include "core/arm/exclusive_monitor.h" |
| 19 | #include "core/core.h" | 20 | #include "core/core.h" |
| @@ -26,18 +27,20 @@ | |||
| 26 | #include "core/hle/kernel/handle_table.h" | 27 | #include "core/hle/kernel/handle_table.h" |
| 27 | #include "core/hle/kernel/k_address_arbiter.h" | 28 | #include "core/hle/kernel/k_address_arbiter.h" |
| 28 | #include "core/hle/kernel/k_condition_variable.h" | 29 | #include "core/hle/kernel/k_condition_variable.h" |
| 30 | #include "core/hle/kernel/k_event.h" | ||
| 31 | #include "core/hle/kernel/k_readable_event.h" | ||
| 32 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 29 | #include "core/hle/kernel/k_scheduler.h" | 33 | #include "core/hle/kernel/k_scheduler.h" |
| 30 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | 34 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" |
| 31 | #include "core/hle/kernel/k_synchronization_object.h" | 35 | #include "core/hle/kernel/k_synchronization_object.h" |
| 32 | #include "core/hle/kernel/k_thread.h" | 36 | #include "core/hle/kernel/k_thread.h" |
| 37 | #include "core/hle/kernel/k_writable_event.h" | ||
| 33 | #include "core/hle/kernel/kernel.h" | 38 | #include "core/hle/kernel/kernel.h" |
| 34 | #include "core/hle/kernel/memory/memory_block.h" | 39 | #include "core/hle/kernel/memory/memory_block.h" |
| 35 | #include "core/hle/kernel/memory/memory_layout.h" | 40 | #include "core/hle/kernel/memory/memory_layout.h" |
| 36 | #include "core/hle/kernel/memory/page_table.h" | 41 | #include "core/hle/kernel/memory/page_table.h" |
| 37 | #include "core/hle/kernel/physical_core.h" | 42 | #include "core/hle/kernel/physical_core.h" |
| 38 | #include "core/hle/kernel/process.h" | 43 | #include "core/hle/kernel/process.h" |
| 39 | #include "core/hle/kernel/readable_event.h" | ||
| 40 | #include "core/hle/kernel/resource_limit.h" | ||
| 41 | #include "core/hle/kernel/shared_memory.h" | 44 | #include "core/hle/kernel/shared_memory.h" |
| 42 | #include "core/hle/kernel/svc.h" | 45 | #include "core/hle/kernel/svc.h" |
| 43 | #include "core/hle/kernel/svc_results.h" | 46 | #include "core/hle/kernel/svc_results.h" |
| @@ -45,7 +48,6 @@ | |||
| 45 | #include "core/hle/kernel/svc_wrap.h" | 48 | #include "core/hle/kernel/svc_wrap.h" |
| 46 | #include "core/hle/kernel/time_manager.h" | 49 | #include "core/hle/kernel/time_manager.h" |
| 47 | #include "core/hle/kernel/transfer_memory.h" | 50 | #include "core/hle/kernel/transfer_memory.h" |
| 48 | #include "core/hle/kernel/writable_event.h" | ||
| 49 | #include "core/hle/lock.h" | 51 | #include "core/hle/lock.h" |
| 50 | #include "core/hle/result.h" | 52 | #include "core/hle/result.h" |
| 51 | #include "core/hle/service/service.h" | 53 | #include "core/hle/service/service.h" |
| @@ -141,7 +143,7 @@ enum class ResourceLimitValueType { | |||
| 141 | ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, | 143 | ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, |
| 142 | u32 resource_type, ResourceLimitValueType value_type) { | 144 | u32 resource_type, ResourceLimitValueType value_type) { |
| 143 | std::lock_guard lock{HLE::g_hle_lock}; | 145 | std::lock_guard lock{HLE::g_hle_lock}; |
| 144 | const auto type = static_cast<ResourceType>(resource_type); | 146 | const auto type = static_cast<LimitableResource>(resource_type); |
| 145 | if (!IsValidResourceType(type)) { | 147 | if (!IsValidResourceType(type)) { |
| 146 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); | 148 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); |
| 147 | return ERR_INVALID_ENUM_VALUE; | 149 | return ERR_INVALID_ENUM_VALUE; |
| @@ -151,7 +153,7 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_ | |||
| 151 | ASSERT(current_process != nullptr); | 153 | ASSERT(current_process != nullptr); |
| 152 | 154 | ||
| 153 | const auto resource_limit_object = | 155 | const auto resource_limit_object = |
| 154 | current_process->GetHandleTable().Get<ResourceLimit>(resource_limit); | 156 | current_process->GetHandleTable().Get<KResourceLimit>(resource_limit); |
| 155 | if (!resource_limit_object) { | 157 | if (!resource_limit_object) { |
| 156 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", | 158 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", |
| 157 | resource_limit); | 159 | resource_limit); |
| @@ -159,10 +161,10 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_ | |||
| 159 | } | 161 | } |
| 160 | 162 | ||
| 161 | if (value_type == ResourceLimitValueType::CurrentValue) { | 163 | if (value_type == ResourceLimitValueType::CurrentValue) { |
| 162 | return MakeResult(resource_limit_object->GetCurrentResourceValue(type)); | 164 | return MakeResult(resource_limit_object->GetCurrentValue(type)); |
| 163 | } | 165 | } |
| 164 | 166 | ||
| 165 | return MakeResult(resource_limit_object->GetMaxResourceValue(type)); | 167 | return MakeResult(resource_limit_object->GetLimitValue(type)); |
| 166 | } | 168 | } |
| 167 | } // Anonymous namespace | 169 | } // Anonymous namespace |
| 168 | 170 | ||
| @@ -312,7 +314,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | |||
| 312 | return ERR_NOT_FOUND; | 314 | return ERR_NOT_FOUND; |
| 313 | } | 315 | } |
| 314 | 316 | ||
| 315 | ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(ResourceType::Sessions, 1)); | 317 | ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::Sessions, 1)); |
| 316 | 318 | ||
| 317 | auto client_port = it->second; | 319 | auto client_port = it->second; |
| 318 | 320 | ||
| @@ -1450,7 +1452,8 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1450 | Svc::ResultInvalidPriority); | 1452 | Svc::ResultInvalidPriority); |
| 1451 | R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority); | 1453 | R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority); |
| 1452 | 1454 | ||
| 1453 | ASSERT(process.GetResourceLimit()->Reserve(ResourceType::Threads, 1)); | 1455 | ASSERT(process.GetResourceLimit()->Reserve( |
| 1456 | LimitableResource::Threads, 1, system.CoreTiming().GetGlobalTimeNs().count() + 100000000)); | ||
| 1454 | 1457 | ||
| 1455 | std::shared_ptr<KThread> thread; | 1458 | std::shared_ptr<KThread> thread; |
| 1456 | { | 1459 | { |
| @@ -1724,20 +1727,28 @@ static ResultCode CloseHandle32(Core::System& system, Handle handle) { | |||
| 1724 | static ResultCode ResetSignal(Core::System& system, Handle handle) { | 1727 | static ResultCode ResetSignal(Core::System& system, Handle handle) { |
| 1725 | LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); | 1728 | LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); |
| 1726 | 1729 | ||
| 1730 | // Get the current handle table. | ||
| 1727 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1731 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1728 | 1732 | ||
| 1729 | auto event = handle_table.Get<ReadableEvent>(handle); | 1733 | // Try to reset as readable event. |
| 1730 | if (event) { | 1734 | { |
| 1731 | return event->Reset(); | 1735 | auto readable_event = handle_table.Get<KReadableEvent>(handle); |
| 1736 | if (readable_event) { | ||
| 1737 | return readable_event->Reset(); | ||
| 1738 | } | ||
| 1732 | } | 1739 | } |
| 1733 | 1740 | ||
| 1734 | auto process = handle_table.Get<Process>(handle); | 1741 | // Try to reset as process. |
| 1735 | if (process) { | 1742 | { |
| 1736 | return process->ClearSignalState(); | 1743 | auto process = handle_table.Get<Process>(handle); |
| 1744 | if (process) { | ||
| 1745 | return process->Reset(); | ||
| 1746 | } | ||
| 1737 | } | 1747 | } |
| 1738 | 1748 | ||
| 1739 | LOG_ERROR(Kernel_SVC, "Invalid handle (0x{:08X})", handle); | 1749 | LOG_ERROR(Kernel_SVC, "invalid handle (0x{:08X})", handle); |
| 1740 | return ERR_INVALID_HANDLE; | 1750 | |
| 1751 | return Svc::ResultInvalidHandle; | ||
| 1741 | } | 1752 | } |
| 1742 | 1753 | ||
| 1743 | static ResultCode ResetSignal32(Core::System& system, Handle handle) { | 1754 | static ResultCode ResetSignal32(Core::System& system, Handle handle) { |
| @@ -1865,80 +1876,92 @@ static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle | |||
| 1865 | return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask); | 1876 | return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask); |
| 1866 | } | 1877 | } |
| 1867 | 1878 | ||
| 1868 | static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) { | 1879 | static ResultCode SignalEvent(Core::System& system, Handle event_handle) { |
| 1869 | LOG_DEBUG(Kernel_SVC, "called"); | 1880 | LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); |
| 1870 | 1881 | ||
| 1871 | auto& kernel = system.Kernel(); | 1882 | // Get the current handle table. |
| 1872 | const auto [readable_event, writable_event] = | 1883 | const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1873 | WritableEvent::CreateEventPair(kernel, "CreateEvent"); | ||
| 1874 | 1884 | ||
| 1875 | HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); | 1885 | // Get the writable event. |
| 1886 | auto writable_event = handle_table.Get<KWritableEvent>(event_handle); | ||
| 1887 | R_UNLESS(writable_event, Svc::ResultInvalidHandle); | ||
| 1876 | 1888 | ||
| 1877 | const auto write_create_result = handle_table.Create(writable_event); | 1889 | return writable_event->Signal(); |
| 1878 | if (write_create_result.Failed()) { | ||
| 1879 | return write_create_result.Code(); | ||
| 1880 | } | ||
| 1881 | *write_handle = *write_create_result; | ||
| 1882 | |||
| 1883 | const auto read_create_result = handle_table.Create(readable_event); | ||
| 1884 | if (read_create_result.Failed()) { | ||
| 1885 | handle_table.Close(*write_create_result); | ||
| 1886 | return read_create_result.Code(); | ||
| 1887 | } | ||
| 1888 | *read_handle = *read_create_result; | ||
| 1889 | |||
| 1890 | LOG_DEBUG(Kernel_SVC, | ||
| 1891 | "successful. Writable event handle=0x{:08X}, Readable event handle=0x{:08X}", | ||
| 1892 | *write_create_result, *read_create_result); | ||
| 1893 | return RESULT_SUCCESS; | ||
| 1894 | } | 1890 | } |
| 1895 | 1891 | ||
| 1896 | static ResultCode CreateEvent32(Core::System& system, Handle* write_handle, Handle* read_handle) { | 1892 | static ResultCode SignalEvent32(Core::System& system, Handle event_handle) { |
| 1897 | return CreateEvent(system, write_handle, read_handle); | 1893 | return SignalEvent(system, event_handle); |
| 1898 | } | 1894 | } |
| 1899 | 1895 | ||
| 1900 | static ResultCode ClearEvent(Core::System& system, Handle handle) { | 1896 | static ResultCode ClearEvent(Core::System& system, Handle event_handle) { |
| 1901 | LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); | 1897 | LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); |
| 1902 | 1898 | ||
| 1899 | // Get the current handle table. | ||
| 1903 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1900 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1904 | 1901 | ||
| 1905 | auto writable_event = handle_table.Get<WritableEvent>(handle); | 1902 | // Try to clear the writable event. |
| 1906 | if (writable_event) { | 1903 | { |
| 1907 | writable_event->Clear(); | 1904 | auto writable_event = handle_table.Get<KWritableEvent>(event_handle); |
| 1908 | return RESULT_SUCCESS; | 1905 | if (writable_event) { |
| 1906 | return writable_event->Clear(); | ||
| 1907 | } | ||
| 1909 | } | 1908 | } |
| 1910 | 1909 | ||
| 1911 | auto readable_event = handle_table.Get<ReadableEvent>(handle); | 1910 | // Try to clear the readable event. |
| 1912 | if (readable_event) { | 1911 | { |
| 1913 | readable_event->Clear(); | 1912 | auto readable_event = handle_table.Get<KReadableEvent>(event_handle); |
| 1914 | return RESULT_SUCCESS; | 1913 | if (readable_event) { |
| 1914 | return readable_event->Clear(); | ||
| 1915 | } | ||
| 1915 | } | 1916 | } |
| 1916 | 1917 | ||
| 1917 | LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle); | 1918 | LOG_ERROR(Kernel_SVC, "Event handle does not exist, event_handle=0x{:08X}", event_handle); |
| 1918 | return ERR_INVALID_HANDLE; | 1919 | |
| 1920 | return Svc::ResultInvalidHandle; | ||
| 1919 | } | 1921 | } |
| 1920 | 1922 | ||
| 1921 | static ResultCode ClearEvent32(Core::System& system, Handle handle) { | 1923 | static ResultCode ClearEvent32(Core::System& system, Handle event_handle) { |
| 1922 | return ClearEvent(system, handle); | 1924 | return ClearEvent(system, event_handle); |
| 1923 | } | 1925 | } |
| 1924 | 1926 | ||
| 1925 | static ResultCode SignalEvent(Core::System& system, Handle handle) { | 1927 | static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { |
| 1926 | LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle); | 1928 | LOG_DEBUG(Kernel_SVC, "called"); |
| 1929 | |||
| 1930 | // Get the kernel reference and handle table. | ||
| 1931 | auto& kernel = system.Kernel(); | ||
| 1932 | HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); | ||
| 1933 | |||
| 1934 | // Create a new event. | ||
| 1935 | const auto event = KEvent::Create(kernel, "CreateEvent"); | ||
| 1936 | R_UNLESS(event != nullptr, Svc::ResultOutOfResource); | ||
| 1927 | 1937 | ||
| 1928 | HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1938 | // Initialize the event. |
| 1929 | auto writable_event = handle_table.Get<WritableEvent>(handle); | 1939 | event->Initialize(); |
| 1930 | 1940 | ||
| 1931 | if (!writable_event) { | 1941 | // Add the writable event to the handle table. |
| 1932 | LOG_ERROR(Kernel_SVC, "Non-existent writable event handle used (0x{:08X})", handle); | 1942 | const auto write_create_result = handle_table.Create(event->GetWritableEvent()); |
| 1933 | return ERR_INVALID_HANDLE; | 1943 | if (write_create_result.Failed()) { |
| 1944 | return write_create_result.Code(); | ||
| 1945 | } | ||
| 1946 | *out_write = *write_create_result; | ||
| 1947 | |||
| 1948 | // Add the writable event to the handle table. | ||
| 1949 | auto handle_guard = SCOPE_GUARD({ handle_table.Close(*write_create_result); }); | ||
| 1950 | |||
| 1951 | // Add the readable event to the handle table. | ||
| 1952 | const auto read_create_result = handle_table.Create(event->GetReadableEvent()); | ||
| 1953 | if (read_create_result.Failed()) { | ||
| 1954 | return read_create_result.Code(); | ||
| 1934 | } | 1955 | } |
| 1956 | *out_read = *read_create_result; | ||
| 1935 | 1957 | ||
| 1936 | writable_event->Signal(); | 1958 | // We succeeded. |
| 1959 | handle_guard.Cancel(); | ||
| 1937 | return RESULT_SUCCESS; | 1960 | return RESULT_SUCCESS; |
| 1938 | } | 1961 | } |
| 1939 | 1962 | ||
| 1940 | static ResultCode SignalEvent32(Core::System& system, Handle handle) { | 1963 | static ResultCode CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) { |
| 1941 | return SignalEvent(system, handle); | 1964 | return CreateEvent(system, out_write, out_read); |
| 1942 | } | 1965 | } |
| 1943 | 1966 | ||
| 1944 | static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { | 1967 | static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { |
| @@ -1972,7 +1995,7 @@ static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) | |||
| 1972 | LOG_DEBUG(Kernel_SVC, "called"); | 1995 | LOG_DEBUG(Kernel_SVC, "called"); |
| 1973 | 1996 | ||
| 1974 | auto& kernel = system.Kernel(); | 1997 | auto& kernel = system.Kernel(); |
| 1975 | auto resource_limit = ResourceLimit::Create(kernel); | 1998 | auto resource_limit = std::make_shared<KResourceLimit>(kernel, system); |
| 1976 | 1999 | ||
| 1977 | auto* const current_process = kernel.CurrentProcess(); | 2000 | auto* const current_process = kernel.CurrentProcess(); |
| 1978 | ASSERT(current_process != nullptr); | 2001 | ASSERT(current_process != nullptr); |
| @@ -2019,7 +2042,7 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour | |||
| 2019 | LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, | 2042 | LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, |
| 2020 | resource_type, value); | 2043 | resource_type, value); |
| 2021 | 2044 | ||
| 2022 | const auto type = static_cast<ResourceType>(resource_type); | 2045 | const auto type = static_cast<LimitableResource>(resource_type); |
| 2023 | if (!IsValidResourceType(type)) { | 2046 | if (!IsValidResourceType(type)) { |
| 2024 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); | 2047 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); |
| 2025 | return ERR_INVALID_ENUM_VALUE; | 2048 | return ERR_INVALID_ENUM_VALUE; |
| @@ -2029,7 +2052,7 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour | |||
| 2029 | ASSERT(current_process != nullptr); | 2052 | ASSERT(current_process != nullptr); |
| 2030 | 2053 | ||
| 2031 | auto resource_limit_object = | 2054 | auto resource_limit_object = |
| 2032 | current_process->GetHandleTable().Get<ResourceLimit>(resource_limit); | 2055 | current_process->GetHandleTable().Get<KResourceLimit>(resource_limit); |
| 2033 | if (!resource_limit_object) { | 2056 | if (!resource_limit_object) { |
| 2034 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", | 2057 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", |
| 2035 | resource_limit); | 2058 | resource_limit); |
| @@ -2041,8 +2064,8 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour | |||
| 2041 | LOG_ERROR( | 2064 | LOG_ERROR( |
| 2042 | Kernel_SVC, | 2065 | Kernel_SVC, |
| 2043 | "Attempted to lower resource limit ({}) for category '{}' below its current value ({})", | 2066 | "Attempted to lower resource limit ({}) for category '{}' below its current value ({})", |
| 2044 | resource_limit_object->GetMaxResourceValue(type), resource_type, | 2067 | resource_limit_object->GetLimitValue(type), resource_type, |
| 2045 | resource_limit_object->GetCurrentResourceValue(type)); | 2068 | resource_limit_object->GetCurrentValue(type)); |
| 2046 | return set_result; | 2069 | return set_result; |
| 2047 | } | 2070 | } |
| 2048 | 2071 | ||
diff --git a/src/core/hle/kernel/svc_results.h b/src/core/hle/kernel/svc_results.h index 7b897fbce..204cd989d 100644 --- a/src/core/hle/kernel/svc_results.h +++ b/src/core/hle/kernel/svc_results.h | |||
| @@ -11,6 +11,7 @@ namespace Kernel::Svc { | |||
| 11 | constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; | 11 | constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; |
| 12 | constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59}; | 12 | constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59}; |
| 13 | constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102}; | 13 | constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102}; |
| 14 | constexpr ResultCode ResultOutOfResource{ErrorModule::Kernel, 103}; | ||
| 14 | constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106}; | 15 | constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106}; |
| 15 | constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112}; | 16 | constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112}; |
| 16 | constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113}; | 17 | constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113}; |
diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp deleted file mode 100644 index 142212ee4..000000000 --- a/src/core/hle/kernel/writable_event.cpp +++ /dev/null | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include "common/assert.h" | ||
| 7 | #include "core/hle/kernel/k_thread.h" | ||
| 8 | #include "core/hle/kernel/kernel.h" | ||
| 9 | #include "core/hle/kernel/object.h" | ||
| 10 | #include "core/hle/kernel/readable_event.h" | ||
| 11 | #include "core/hle/kernel/writable_event.h" | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | |||
| 15 | WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {} | ||
| 16 | WritableEvent::~WritableEvent() = default; | ||
| 17 | |||
| 18 | EventPair WritableEvent::CreateEventPair(KernelCore& kernel, std::string name) { | ||
| 19 | std::shared_ptr<WritableEvent> writable_event(new WritableEvent(kernel)); | ||
| 20 | std::shared_ptr<ReadableEvent> readable_event(new ReadableEvent(kernel)); | ||
| 21 | |||
| 22 | writable_event->name = name + ":Writable"; | ||
| 23 | writable_event->readable = readable_event; | ||
| 24 | readable_event->name = name + ":Readable"; | ||
| 25 | |||
| 26 | return {std::move(readable_event), std::move(writable_event)}; | ||
| 27 | } | ||
| 28 | |||
| 29 | std::shared_ptr<ReadableEvent> WritableEvent::GetReadableEvent() const { | ||
| 30 | return readable; | ||
| 31 | } | ||
| 32 | |||
| 33 | void WritableEvent::Signal() { | ||
| 34 | readable->Signal(); | ||
| 35 | } | ||
| 36 | |||
| 37 | void WritableEvent::Clear() { | ||
| 38 | readable->Clear(); | ||
| 39 | } | ||
| 40 | |||
| 41 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/writable_event.h b/src/core/hle/kernel/writable_event.h deleted file mode 100644 index 467eb2c21..000000000 --- a/src/core/hle/kernel/writable_event.h +++ /dev/null | |||
| @@ -1,60 +0,0 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | |||
| 9 | #include "core/hle/kernel/object.h" | ||
| 10 | |||
| 11 | namespace Kernel { | ||
| 12 | |||
| 13 | class KernelCore; | ||
| 14 | class ReadableEvent; | ||
| 15 | class WritableEvent; | ||
| 16 | |||
| 17 | struct EventPair { | ||
| 18 | std::shared_ptr<ReadableEvent> readable; | ||
| 19 | std::shared_ptr<WritableEvent> writable; | ||
| 20 | }; | ||
| 21 | |||
| 22 | class WritableEvent final : public Object { | ||
| 23 | public: | ||
| 24 | ~WritableEvent() override; | ||
| 25 | |||
| 26 | /** | ||
| 27 | * Creates an event | ||
| 28 | * @param kernel The kernel instance to create this event under. | ||
| 29 | * @param name Optional name of event | ||
| 30 | */ | ||
| 31 | static EventPair CreateEventPair(KernelCore& kernel, std::string name = "Unknown"); | ||
| 32 | |||
| 33 | std::string GetTypeName() const override { | ||
| 34 | return "WritableEvent"; | ||
| 35 | } | ||
| 36 | std::string GetName() const override { | ||
| 37 | return name; | ||
| 38 | } | ||
| 39 | |||
| 40 | static constexpr HandleType HANDLE_TYPE = HandleType::WritableEvent; | ||
| 41 | HandleType GetHandleType() const override { | ||
| 42 | return HANDLE_TYPE; | ||
| 43 | } | ||
| 44 | |||
| 45 | std::shared_ptr<ReadableEvent> GetReadableEvent() const; | ||
| 46 | |||
| 47 | void Signal(); | ||
| 48 | void Clear(); | ||
| 49 | |||
| 50 | void Finalize() override {} | ||
| 51 | |||
| 52 | private: | ||
| 53 | explicit WritableEvent(KernelCore& kernel); | ||
| 54 | |||
| 55 | std::shared_ptr<ReadableEvent> readable; | ||
| 56 | |||
| 57 | std::string name; ///< Name of event (optional) | ||
| 58 | }; | ||
| 59 | |||
| 60 | } // namespace Kernel | ||
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index d9865d56f..50b2c58e2 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp | |||
| @@ -41,12 +41,18 @@ constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "/system/save/8000000000000010/su/ | |||
| 41 | ProfileManager::ProfileManager() { | 41 | ProfileManager::ProfileManager() { |
| 42 | ParseUserSaveFile(); | 42 | ParseUserSaveFile(); |
| 43 | 43 | ||
| 44 | if (user_count == 0) | 44 | // Create an user if none are present |
| 45 | if (user_count == 0) { | ||
| 45 | CreateNewUser(UUID::Generate(), "yuzu"); | 46 | CreateNewUser(UUID::Generate(), "yuzu"); |
| 47 | } | ||
| 46 | 48 | ||
| 47 | auto current = std::clamp<int>(Settings::values.current_user, 0, MAX_USERS - 1); | 49 | auto current = std::clamp<int>(Settings::values.current_user, 0, MAX_USERS - 1); |
| 48 | if (UserExistsIndex(current)) | 50 | |
| 51 | // If user index don't exist. Load the first user and change the active user | ||
| 52 | if (!UserExistsIndex(current)) { | ||
| 49 | current = 0; | 53 | current = 0; |
| 54 | Settings::values.current_user = 0; | ||
| 55 | } | ||
| 50 | 56 | ||
| 51 | OpenUser(*GetUser(current)); | 57 | OpenUser(*GetUser(current)); |
| 52 | } | 58 | } |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index d42236a3a..bb77c2569 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -13,11 +13,12 @@ | |||
| 13 | #include "core/file_sys/registered_cache.h" | 13 | #include "core/file_sys/registered_cache.h" |
| 14 | #include "core/file_sys/savedata_factory.h" | 14 | #include "core/file_sys/savedata_factory.h" |
| 15 | #include "core/hle/ipc_helpers.h" | 15 | #include "core/hle/ipc_helpers.h" |
| 16 | #include "core/hle/kernel/k_event.h" | ||
| 17 | #include "core/hle/kernel/k_readable_event.h" | ||
| 18 | #include "core/hle/kernel/k_writable_event.h" | ||
| 16 | #include "core/hle/kernel/kernel.h" | 19 | #include "core/hle/kernel/kernel.h" |
| 17 | #include "core/hle/kernel/process.h" | 20 | #include "core/hle/kernel/process.h" |
| 18 | #include "core/hle/kernel/readable_event.h" | ||
| 19 | #include "core/hle/kernel/transfer_memory.h" | 21 | #include "core/hle/kernel/transfer_memory.h" |
| 20 | #include "core/hle/kernel/writable_event.h" | ||
| 21 | #include "core/hle/service/acc/profile_manager.h" | 22 | #include "core/hle/service/acc/profile_manager.h" |
| 22 | #include "core/hle/service/am/am.h" | 23 | #include "core/hle/service/am/am.h" |
| 23 | #include "core/hle/service/am/applet_ae.h" | 24 | #include "core/hle/service/am/applet_ae.h" |
| @@ -303,17 +304,18 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv | |||
| 303 | RegisterHandlers(functions); | 304 | RegisterHandlers(functions); |
| 304 | 305 | ||
| 305 | auto& kernel = system.Kernel(); | 306 | auto& kernel = system.Kernel(); |
| 306 | launchable_event = | 307 | launchable_event = Kernel::KEvent::Create(kernel, "ISelfController:LaunchableEvent"); |
| 307 | Kernel::WritableEvent::CreateEventPair(kernel, "ISelfController:LaunchableEvent"); | 308 | launchable_event->Initialize(); |
| 308 | 309 | ||
| 309 | // This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is | 310 | // This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is |
| 310 | // called. Yuzu can just create it unconditionally, since it doesn't need to support multiple | 311 | // called. Yuzu can just create it unconditionally, since it doesn't need to support multiple |
| 311 | // ISelfControllers. The event is signaled on creation, and on transition from suspended -> not | 312 | // ISelfControllers. The event is signaled on creation, and on transition from suspended -> not |
| 312 | // suspended if the event has previously been created by a call to | 313 | // suspended if the event has previously been created by a call to |
| 313 | // GetAccumulatedSuspendedTickChangedEvent. | 314 | // GetAccumulatedSuspendedTickChangedEvent. |
| 314 | accumulated_suspended_tick_changed_event = Kernel::WritableEvent::CreateEventPair( | 315 | accumulated_suspended_tick_changed_event = |
| 315 | kernel, "ISelfController:AccumulatedSuspendedTickChangedEvent"); | 316 | Kernel::KEvent::Create(kernel, "ISelfController:AccumulatedSuspendedTickChangedEvent"); |
| 316 | accumulated_suspended_tick_changed_event.writable->Signal(); | 317 | accumulated_suspended_tick_changed_event->Initialize(); |
| 318 | accumulated_suspended_tick_changed_event->GetWritableEvent()->Signal(); | ||
| 317 | } | 319 | } |
| 318 | 320 | ||
| 319 | ISelfController::~ISelfController() = default; | 321 | ISelfController::~ISelfController() = default; |
| @@ -372,11 +374,11 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) { | |||
| 372 | void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { | 374 | void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { |
| 373 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 375 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 374 | 376 | ||
| 375 | launchable_event.writable->Signal(); | 377 | launchable_event->GetWritableEvent()->Signal(); |
| 376 | 378 | ||
| 377 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 379 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 378 | rb.Push(RESULT_SUCCESS); | 380 | rb.Push(RESULT_SUCCESS); |
| 379 | rb.PushCopyObjects(launchable_event.readable); | 381 | rb.PushCopyObjects(launchable_event->GetReadableEvent()); |
| 380 | } | 382 | } |
| 381 | 383 | ||
| 382 | void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { | 384 | void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { |
| @@ -555,41 +557,42 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest | |||
| 555 | 557 | ||
| 556 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 558 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 557 | rb.Push(RESULT_SUCCESS); | 559 | rb.Push(RESULT_SUCCESS); |
| 558 | rb.PushCopyObjects(accumulated_suspended_tick_changed_event.readable); | 560 | rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent()); |
| 559 | } | 561 | } |
| 560 | 562 | ||
| 561 | AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) { | 563 | AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) { |
| 562 | on_new_message = | 564 | on_new_message = Kernel::KEvent::Create(kernel, "AMMessageQueue:OnMessageReceived"); |
| 563 | Kernel::WritableEvent::CreateEventPair(kernel, "AMMessageQueue:OnMessageReceived"); | 565 | on_new_message->Initialize(); |
| 564 | on_operation_mode_changed = | 566 | on_operation_mode_changed = |
| 565 | Kernel::WritableEvent::CreateEventPair(kernel, "AMMessageQueue:OperationModeChanged"); | 567 | Kernel::KEvent::Create(kernel, "AMMessageQueue:OperationModeChanged"); |
| 568 | on_operation_mode_changed->Initialize(); | ||
| 566 | } | 569 | } |
| 567 | 570 | ||
| 568 | AppletMessageQueue::~AppletMessageQueue() = default; | 571 | AppletMessageQueue::~AppletMessageQueue() = default; |
| 569 | 572 | ||
| 570 | const std::shared_ptr<Kernel::ReadableEvent>& AppletMessageQueue::GetMessageReceiveEvent() const { | 573 | const std::shared_ptr<Kernel::KReadableEvent>& AppletMessageQueue::GetMessageReceiveEvent() const { |
| 571 | return on_new_message.readable; | 574 | return on_new_message->GetReadableEvent(); |
| 572 | } | 575 | } |
| 573 | 576 | ||
| 574 | const std::shared_ptr<Kernel::ReadableEvent>& AppletMessageQueue::GetOperationModeChangedEvent() | 577 | const std::shared_ptr<Kernel::KReadableEvent>& AppletMessageQueue::GetOperationModeChangedEvent() |
| 575 | const { | 578 | const { |
| 576 | return on_operation_mode_changed.readable; | 579 | return on_operation_mode_changed->GetReadableEvent(); |
| 577 | } | 580 | } |
| 578 | 581 | ||
| 579 | void AppletMessageQueue::PushMessage(AppletMessage msg) { | 582 | void AppletMessageQueue::PushMessage(AppletMessage msg) { |
| 580 | messages.push(msg); | 583 | messages.push(msg); |
| 581 | on_new_message.writable->Signal(); | 584 | on_new_message->GetWritableEvent()->Signal(); |
| 582 | } | 585 | } |
| 583 | 586 | ||
| 584 | AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { | 587 | AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { |
| 585 | if (messages.empty()) { | 588 | if (messages.empty()) { |
| 586 | on_new_message.writable->Clear(); | 589 | on_new_message->GetWritableEvent()->Clear(); |
| 587 | return AppletMessage::NoMessage; | 590 | return AppletMessage::NoMessage; |
| 588 | } | 591 | } |
| 589 | auto msg = messages.front(); | 592 | auto msg = messages.front(); |
| 590 | messages.pop(); | 593 | messages.pop(); |
| 591 | if (messages.empty()) { | 594 | if (messages.empty()) { |
| 592 | on_new_message.writable->Clear(); | 595 | on_new_message->GetWritableEvent()->Clear(); |
| 593 | } | 596 | } |
| 594 | return msg; | 597 | return msg; |
| 595 | } | 598 | } |
| @@ -601,7 +604,7 @@ std::size_t AppletMessageQueue::GetMessageCount() const { | |||
| 601 | void AppletMessageQueue::OperationModeChanged() { | 604 | void AppletMessageQueue::OperationModeChanged() { |
| 602 | PushMessage(AppletMessage::OperationModeChanged); | 605 | PushMessage(AppletMessage::OperationModeChanged); |
| 603 | PushMessage(AppletMessage::PerformanceModeChanged); | 606 | PushMessage(AppletMessage::PerformanceModeChanged); |
| 604 | on_operation_mode_changed.writable->Signal(); | 607 | on_operation_mode_changed->GetWritableEvent()->Signal(); |
| 605 | } | 608 | } |
| 606 | 609 | ||
| 607 | void AppletMessageQueue::RequestExit() { | 610 | void AppletMessageQueue::RequestExit() { |
| @@ -1216,7 +1219,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | |||
| 1216 | {141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"}, | 1219 | {141, &IApplicationFunctions::TryPopFromFriendInvitationStorageChannel, "TryPopFromFriendInvitationStorageChannel"}, |
| 1217 | {150, nullptr, "GetNotificationStorageChannelEvent"}, | 1220 | {150, nullptr, "GetNotificationStorageChannelEvent"}, |
| 1218 | {151, nullptr, "TryPopFromNotificationStorageChannel"}, | 1221 | {151, nullptr, "TryPopFromNotificationStorageChannel"}, |
| 1219 | {160, nullptr, "GetHealthWarningDisappearedSystemEvent"}, | 1222 | {160, &IApplicationFunctions::GetHealthWarningDisappearedSystemEvent, "GetHealthWarningDisappearedSystemEvent"}, |
| 1220 | {170, nullptr, "SetHdcpAuthenticationActivated"}, | 1223 | {170, nullptr, "SetHdcpAuthenticationActivated"}, |
| 1221 | {180, nullptr, "GetLaunchRequiredVersion"}, | 1224 | {180, nullptr, "GetLaunchRequiredVersion"}, |
| 1222 | {181, nullptr, "UpgradeLaunchRequiredVersion"}, | 1225 | {181, nullptr, "UpgradeLaunchRequiredVersion"}, |
| @@ -1229,11 +1232,15 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) | |||
| 1229 | RegisterHandlers(functions); | 1232 | RegisterHandlers(functions); |
| 1230 | 1233 | ||
| 1231 | auto& kernel = system.Kernel(); | 1234 | auto& kernel = system.Kernel(); |
| 1232 | gpu_error_detected_event = Kernel::WritableEvent::CreateEventPair( | 1235 | gpu_error_detected_event = |
| 1233 | kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent"); | 1236 | Kernel::KEvent::Create(kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent"); |
| 1234 | 1237 | gpu_error_detected_event->Initialize(); | |
| 1235 | friend_invitation_storage_channel_event = Kernel::WritableEvent::CreateEventPair( | 1238 | friend_invitation_storage_channel_event = |
| 1236 | kernel, "IApplicationFunctions:FriendInvitationStorageChannelEvent"); | 1239 | Kernel::KEvent::Create(kernel, "IApplicationFunctions:FriendInvitationStorageChannelEvent"); |
| 1240 | friend_invitation_storage_channel_event->Initialize(); | ||
| 1241 | health_warning_disappeared_system_event = | ||
| 1242 | Kernel::KEvent::Create(kernel, "IApplicationFunctions:HealthWarningDisappearedSystemEvent"); | ||
| 1243 | health_warning_disappeared_system_event->Initialize(); | ||
| 1237 | } | 1244 | } |
| 1238 | 1245 | ||
| 1239 | IApplicationFunctions::~IApplicationFunctions() = default; | 1246 | IApplicationFunctions::~IApplicationFunctions() = default; |
| @@ -1630,7 +1637,7 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon | |||
| 1630 | 1637 | ||
| 1631 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 1638 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 1632 | rb.Push(RESULT_SUCCESS); | 1639 | rb.Push(RESULT_SUCCESS); |
| 1633 | rb.PushCopyObjects(gpu_error_detected_event.readable); | 1640 | rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent()); |
| 1634 | } | 1641 | } |
| 1635 | 1642 | ||
| 1636 | void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) { | 1643 | void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) { |
| @@ -1638,7 +1645,7 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe | |||
| 1638 | 1645 | ||
| 1639 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 1646 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 1640 | rb.Push(RESULT_SUCCESS); | 1647 | rb.Push(RESULT_SUCCESS); |
| 1641 | rb.PushCopyObjects(friend_invitation_storage_channel_event.readable); | 1648 | rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent()); |
| 1642 | } | 1649 | } |
| 1643 | 1650 | ||
| 1644 | void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel( | 1651 | void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel( |
| @@ -1649,6 +1656,14 @@ void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel( | |||
| 1649 | rb.Push(ERR_NO_DATA_IN_CHANNEL); | 1656 | rb.Push(ERR_NO_DATA_IN_CHANNEL); |
| 1650 | } | 1657 | } |
| 1651 | 1658 | ||
| 1659 | void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERequestContext& ctx) { | ||
| 1660 | LOG_DEBUG(Service_AM, "called"); | ||
| 1661 | |||
| 1662 | IPC::ResponseBuilder rb{ctx, 2, 1}; | ||
| 1663 | rb.Push(RESULT_SUCCESS); | ||
| 1664 | rb.PushCopyObjects(health_warning_disappeared_system_event->GetReadableEvent()); | ||
| 1665 | } | ||
| 1666 | |||
| 1652 | void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, | 1667 | void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, |
| 1653 | Core::System& system) { | 1668 | Core::System& system) { |
| 1654 | auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel()); | 1669 | auto message_queue = std::make_shared<AppletMessageQueue>(system.Kernel()); |
| @@ -1682,8 +1697,9 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) | |||
| 1682 | 1697 | ||
| 1683 | RegisterHandlers(functions); | 1698 | RegisterHandlers(functions); |
| 1684 | 1699 | ||
| 1685 | pop_from_general_channel_event = Kernel::WritableEvent::CreateEventPair( | 1700 | pop_from_general_channel_event = |
| 1686 | system.Kernel(), "IHomeMenuFunctions:PopFromGeneralChannelEvent"); | 1701 | Kernel::KEvent::Create(system.Kernel(), "IHomeMenuFunctions:PopFromGeneralChannelEvent"); |
| 1702 | pop_from_general_channel_event->Initialize(); | ||
| 1687 | } | 1703 | } |
| 1688 | 1704 | ||
| 1689 | IHomeMenuFunctions::~IHomeMenuFunctions() = default; | 1705 | IHomeMenuFunctions::~IHomeMenuFunctions() = default; |
| @@ -1700,7 +1716,7 @@ void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext | |||
| 1700 | 1716 | ||
| 1701 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 1717 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 1702 | rb.Push(RESULT_SUCCESS); | 1718 | rb.Push(RESULT_SUCCESS); |
| 1703 | rb.PushCopyObjects(pop_from_general_channel_event.readable); | 1719 | rb.PushCopyObjects(pop_from_general_channel_event->GetReadableEvent()); |
| 1704 | } | 1720 | } |
| 1705 | 1721 | ||
| 1706 | IGlobalStateController::IGlobalStateController(Core::System& system_) | 1722 | IGlobalStateController::IGlobalStateController(Core::System& system_) |
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index f5db41ac8..6911f0d6e 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -7,11 +7,12 @@ | |||
| 7 | #include <chrono> | 7 | #include <chrono> |
| 8 | #include <memory> | 8 | #include <memory> |
| 9 | #include <queue> | 9 | #include <queue> |
| 10 | #include "core/hle/kernel/writable_event.h" | 10 | |
| 11 | #include "core/hle/service/service.h" | 11 | #include "core/hle/service/service.h" |
| 12 | 12 | ||
| 13 | namespace Kernel { | 13 | namespace Kernel { |
| 14 | class KernelCore; | 14 | class KernelCore; |
| 15 | class KEvent; | ||
| 15 | class TransferMemory; | 16 | class TransferMemory; |
| 16 | } // namespace Kernel | 17 | } // namespace Kernel |
| 17 | 18 | ||
| @@ -55,8 +56,8 @@ public: | |||
| 55 | explicit AppletMessageQueue(Kernel::KernelCore& kernel); | 56 | explicit AppletMessageQueue(Kernel::KernelCore& kernel); |
| 56 | ~AppletMessageQueue(); | 57 | ~AppletMessageQueue(); |
| 57 | 58 | ||
| 58 | const std::shared_ptr<Kernel::ReadableEvent>& GetMessageReceiveEvent() const; | 59 | const std::shared_ptr<Kernel::KReadableEvent>& GetMessageReceiveEvent() const; |
| 59 | const std::shared_ptr<Kernel::ReadableEvent>& GetOperationModeChangedEvent() const; | 60 | const std::shared_ptr<Kernel::KReadableEvent>& GetOperationModeChangedEvent() const; |
| 60 | void PushMessage(AppletMessage msg); | 61 | void PushMessage(AppletMessage msg); |
| 61 | AppletMessage PopMessage(); | 62 | AppletMessage PopMessage(); |
| 62 | std::size_t GetMessageCount() const; | 63 | std::size_t GetMessageCount() const; |
| @@ -65,8 +66,8 @@ public: | |||
| 65 | 66 | ||
| 66 | private: | 67 | private: |
| 67 | std::queue<AppletMessage> messages; | 68 | std::queue<AppletMessage> messages; |
| 68 | Kernel::EventPair on_new_message; | 69 | std::shared_ptr<Kernel::KEvent> on_new_message; |
| 69 | Kernel::EventPair on_operation_mode_changed; | 70 | std::shared_ptr<Kernel::KEvent> on_operation_mode_changed; |
| 70 | }; | 71 | }; |
| 71 | 72 | ||
| 72 | class IWindowController final : public ServiceFramework<IWindowController> { | 73 | class IWindowController final : public ServiceFramework<IWindowController> { |
| @@ -153,8 +154,8 @@ private: | |||
| 153 | }; | 154 | }; |
| 154 | 155 | ||
| 155 | NVFlinger::NVFlinger& nvflinger; | 156 | NVFlinger::NVFlinger& nvflinger; |
| 156 | Kernel::EventPair launchable_event; | 157 | std::shared_ptr<Kernel::KEvent> launchable_event; |
| 157 | Kernel::EventPair accumulated_suspended_tick_changed_event; | 158 | std::shared_ptr<Kernel::KEvent> accumulated_suspended_tick_changed_event; |
| 158 | 159 | ||
| 159 | u32 idle_time_detection_extension = 0; | 160 | u32 idle_time_detection_extension = 0; |
| 160 | u64 num_fatal_sections_entered = 0; | 161 | u64 num_fatal_sections_entered = 0; |
| @@ -290,12 +291,14 @@ private: | |||
| 290 | void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); | 291 | void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); |
| 291 | void GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx); | 292 | void GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx); |
| 292 | void TryPopFromFriendInvitationStorageChannel(Kernel::HLERequestContext& ctx); | 293 | void TryPopFromFriendInvitationStorageChannel(Kernel::HLERequestContext& ctx); |
| 294 | void GetHealthWarningDisappearedSystemEvent(Kernel::HLERequestContext& ctx); | ||
| 293 | 295 | ||
| 294 | bool launch_popped_application_specific = false; | 296 | bool launch_popped_application_specific = false; |
| 295 | bool launch_popped_account_preselect = false; | 297 | bool launch_popped_account_preselect = false; |
| 296 | s32 previous_program_index{-1}; | 298 | s32 previous_program_index{-1}; |
| 297 | Kernel::EventPair gpu_error_detected_event; | 299 | std::shared_ptr<Kernel::KEvent> gpu_error_detected_event; |
| 298 | Kernel::EventPair friend_invitation_storage_channel_event; | 300 | std::shared_ptr<Kernel::KEvent> friend_invitation_storage_channel_event; |
| 301 | std::shared_ptr<Kernel::KEvent> health_warning_disappeared_system_event; | ||
| 299 | }; | 302 | }; |
| 300 | 303 | ||
| 301 | class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { | 304 | class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { |
| @@ -307,7 +310,7 @@ private: | |||
| 307 | void RequestToGetForeground(Kernel::HLERequestContext& ctx); | 310 | void RequestToGetForeground(Kernel::HLERequestContext& ctx); |
| 308 | void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx); | 311 | void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx); |
| 309 | 312 | ||
| 310 | Kernel::EventPair pop_from_general_channel_event; | 313 | std::shared_ptr<Kernel::KEvent> pop_from_general_channel_event; |
| 311 | }; | 314 | }; |
| 312 | 315 | ||
| 313 | class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { | 316 | class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { |
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index 08676c3fc..e2f3b7563 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <cstring> | 5 | #include <cstring> |
| 6 | |||
| 6 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 7 | #include "core/core.h" | 8 | #include "core/core.h" |
| 8 | #include "core/frontend/applets/controller.h" | 9 | #include "core/frontend/applets/controller.h" |
| @@ -11,9 +12,10 @@ | |||
| 11 | #include "core/frontend/applets/profile_select.h" | 12 | #include "core/frontend/applets/profile_select.h" |
| 12 | #include "core/frontend/applets/software_keyboard.h" | 13 | #include "core/frontend/applets/software_keyboard.h" |
| 13 | #include "core/frontend/applets/web_browser.h" | 14 | #include "core/frontend/applets/web_browser.h" |
| 14 | #include "core/hle/kernel/readable_event.h" | 15 | #include "core/hle/kernel/k_event.h" |
| 16 | #include "core/hle/kernel/k_readable_event.h" | ||
| 17 | #include "core/hle/kernel/k_writable_event.h" | ||
| 15 | #include "core/hle/kernel/server_session.h" | 18 | #include "core/hle/kernel/server_session.h" |
| 16 | #include "core/hle/kernel/writable_event.h" | ||
| 17 | #include "core/hle/service/am/am.h" | 19 | #include "core/hle/service/am/am.h" |
| 18 | #include "core/hle/service/am/applets/applets.h" | 20 | #include "core/hle/service/am/applets/applets.h" |
| 19 | #include "core/hle/service/am/applets/controller.h" | 21 | #include "core/hle/service/am/applets/controller.h" |
| @@ -27,11 +29,13 @@ namespace Service::AM::Applets { | |||
| 27 | 29 | ||
| 28 | AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) { | 30 | AppletDataBroker::AppletDataBroker(Kernel::KernelCore& kernel) { |
| 29 | state_changed_event = | 31 | state_changed_event = |
| 30 | Kernel::WritableEvent::CreateEventPair(kernel, "ILibraryAppletAccessor:StateChangedEvent"); | 32 | Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:StateChangedEvent"); |
| 31 | pop_out_data_event = | 33 | state_changed_event->Initialize(); |
| 32 | Kernel::WritableEvent::CreateEventPair(kernel, "ILibraryAppletAccessor:PopDataOutEvent"); | 34 | pop_out_data_event = Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:PopDataOutEvent"); |
| 33 | pop_interactive_out_data_event = Kernel::WritableEvent::CreateEventPair( | 35 | pop_out_data_event->Initialize(); |
| 34 | kernel, "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); | 36 | pop_interactive_out_data_event = |
| 37 | Kernel::KEvent::Create(kernel, "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); | ||
| 38 | pop_interactive_out_data_event->Initialize(); | ||
| 35 | } | 39 | } |
| 36 | 40 | ||
| 37 | AppletDataBroker::~AppletDataBroker() = default; | 41 | AppletDataBroker::~AppletDataBroker() = default; |
| @@ -58,7 +62,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() { | |||
| 58 | 62 | ||
| 59 | auto out = std::move(out_channel.front()); | 63 | auto out = std::move(out_channel.front()); |
| 60 | out_channel.pop_front(); | 64 | out_channel.pop_front(); |
| 61 | pop_out_data_event.writable->Clear(); | 65 | pop_out_data_event->GetWritableEvent()->Clear(); |
| 62 | return out; | 66 | return out; |
| 63 | } | 67 | } |
| 64 | 68 | ||
| @@ -77,7 +81,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() { | |||
| 77 | 81 | ||
| 78 | auto out = std::move(out_interactive_channel.front()); | 82 | auto out = std::move(out_interactive_channel.front()); |
| 79 | out_interactive_channel.pop_front(); | 83 | out_interactive_channel.pop_front(); |
| 80 | pop_interactive_out_data_event.writable->Clear(); | 84 | pop_interactive_out_data_event->GetWritableEvent()->Clear(); |
| 81 | return out; | 85 | return out; |
| 82 | } | 86 | } |
| 83 | 87 | ||
| @@ -96,7 +100,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storag | |||
| 96 | 100 | ||
| 97 | void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) { | 101 | void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) { |
| 98 | out_channel.emplace_back(std::move(storage)); | 102 | out_channel.emplace_back(std::move(storage)); |
| 99 | pop_out_data_event.writable->Signal(); | 103 | pop_out_data_event->GetWritableEvent()->Signal(); |
| 100 | } | 104 | } |
| 101 | 105 | ||
| 102 | void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) { | 106 | void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) { |
| @@ -105,23 +109,23 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& s | |||
| 105 | 109 | ||
| 106 | void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) { | 110 | void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) { |
| 107 | out_interactive_channel.emplace_back(std::move(storage)); | 111 | out_interactive_channel.emplace_back(std::move(storage)); |
| 108 | pop_interactive_out_data_event.writable->Signal(); | 112 | pop_interactive_out_data_event->GetWritableEvent()->Signal(); |
| 109 | } | 113 | } |
| 110 | 114 | ||
| 111 | void AppletDataBroker::SignalStateChanged() const { | 115 | void AppletDataBroker::SignalStateChanged() const { |
| 112 | state_changed_event.writable->Signal(); | 116 | state_changed_event->GetWritableEvent()->Signal(); |
| 113 | } | 117 | } |
| 114 | 118 | ||
| 115 | std::shared_ptr<Kernel::ReadableEvent> AppletDataBroker::GetNormalDataEvent() const { | 119 | std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetNormalDataEvent() const { |
| 116 | return pop_out_data_event.readable; | 120 | return pop_out_data_event->GetReadableEvent(); |
| 117 | } | 121 | } |
| 118 | 122 | ||
| 119 | std::shared_ptr<Kernel::ReadableEvent> AppletDataBroker::GetInteractiveDataEvent() const { | 123 | std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetInteractiveDataEvent() const { |
| 120 | return pop_interactive_out_data_event.readable; | 124 | return pop_interactive_out_data_event->GetReadableEvent(); |
| 121 | } | 125 | } |
| 122 | 126 | ||
| 123 | std::shared_ptr<Kernel::ReadableEvent> AppletDataBroker::GetStateChangedEvent() const { | 127 | std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetStateChangedEvent() const { |
| 124 | return state_changed_event.readable; | 128 | return state_changed_event->GetReadableEvent(); |
| 125 | } | 129 | } |
| 126 | 130 | ||
| 127 | Applet::Applet(Kernel::KernelCore& kernel_) : broker{kernel_} {} | 131 | Applet::Applet(Kernel::KernelCore& kernel_) : broker{kernel_} {} |
diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 4fd792c05..b9a006317 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h | |||
| @@ -6,9 +6,9 @@ | |||
| 6 | 6 | ||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <queue> | 8 | #include <queue> |
| 9 | |||
| 9 | #include "common/swap.h" | 10 | #include "common/swap.h" |
| 10 | #include "core/hle/kernel/object.h" | 11 | #include "core/hle/kernel/object.h" |
| 11 | #include "core/hle/kernel/writable_event.h" | ||
| 12 | 12 | ||
| 13 | union ResultCode; | 13 | union ResultCode; |
| 14 | 14 | ||
| @@ -29,7 +29,9 @@ class WebBrowserApplet; | |||
| 29 | 29 | ||
| 30 | namespace Kernel { | 30 | namespace Kernel { |
| 31 | class KernelCore; | 31 | class KernelCore; |
| 32 | } | 32 | class KEvent; |
| 33 | class KReadableEvent; | ||
| 34 | } // namespace Kernel | ||
| 33 | 35 | ||
| 34 | namespace Service::AM { | 36 | namespace Service::AM { |
| 35 | 37 | ||
| @@ -87,9 +89,9 @@ public: | |||
| 87 | 89 | ||
| 88 | void SignalStateChanged() const; | 90 | void SignalStateChanged() const; |
| 89 | 91 | ||
| 90 | std::shared_ptr<Kernel::ReadableEvent> GetNormalDataEvent() const; | 92 | std::shared_ptr<Kernel::KReadableEvent> GetNormalDataEvent() const; |
| 91 | std::shared_ptr<Kernel::ReadableEvent> GetInteractiveDataEvent() const; | 93 | std::shared_ptr<Kernel::KReadableEvent> GetInteractiveDataEvent() const; |
| 92 | std::shared_ptr<Kernel::ReadableEvent> GetStateChangedEvent() const; | 94 | std::shared_ptr<Kernel::KReadableEvent> GetStateChangedEvent() const; |
| 93 | 95 | ||
| 94 | private: | 96 | private: |
| 95 | // Queues are named from applet's perspective | 97 | // Queues are named from applet's perspective |
| @@ -106,13 +108,13 @@ private: | |||
| 106 | // PopInteractiveDataToGame and PushInteractiveDataFromApplet | 108 | // PopInteractiveDataToGame and PushInteractiveDataFromApplet |
| 107 | std::deque<std::shared_ptr<IStorage>> out_interactive_channel; | 109 | std::deque<std::shared_ptr<IStorage>> out_interactive_channel; |
| 108 | 110 | ||
| 109 | Kernel::EventPair state_changed_event; | 111 | std::shared_ptr<Kernel::KEvent> state_changed_event; |
| 110 | 112 | ||
| 111 | // Signaled on PushNormalDataFromApplet | 113 | // Signaled on PushNormalDataFromApplet |
| 112 | Kernel::EventPair pop_out_data_event; | 114 | std::shared_ptr<Kernel::KEvent> pop_out_data_event; |
| 113 | 115 | ||
| 114 | // Signaled on PushInteractiveDataFromApplet | 116 | // Signaled on PushInteractiveDataFromApplet |
| 115 | Kernel::EventPair pop_interactive_out_data_event; | 117 | std::shared_ptr<Kernel::KEvent> pop_interactive_out_data_event; |
| 116 | }; | 118 | }; |
| 117 | 119 | ||
| 118 | class Applet { | 120 | class Applet { |
diff --git a/src/core/hle/service/am/applets/controller.cpp b/src/core/hle/service/am/applets/controller.cpp index 7edfca64e..d7d3ee99a 100644 --- a/src/core/hle/service/am/applets/controller.cpp +++ b/src/core/hle/service/am/applets/controller.cpp | |||
| @@ -37,7 +37,7 @@ static Core::Frontend::ControllerParameters ConvertToFrontendParameters( | |||
| 37 | .border_colors = std::move(identification_colors), | 37 | .border_colors = std::move(identification_colors), |
| 38 | .enable_explain_text = enable_text, | 38 | .enable_explain_text = enable_text, |
| 39 | .explain_text = std::move(text), | 39 | .explain_text = std::move(text), |
| 40 | .allow_pro_controller = npad_style_set.pro_controller == 1, | 40 | .allow_pro_controller = npad_style_set.fullkey == 1, |
| 41 | .allow_handheld = npad_style_set.handheld == 1, | 41 | .allow_handheld = npad_style_set.handheld == 1, |
| 42 | .allow_dual_joycons = npad_style_set.joycon_dual == 1, | 42 | .allow_dual_joycons = npad_style_set.joycon_dual == 1, |
| 43 | .allow_left_joycon = npad_style_set.joycon_left == 1, | 43 | .allow_left_joycon = npad_style_set.joycon_left == 1, |
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 23e28565b..8d657c0bf 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <numeric> | 6 | #include <numeric> |
| 7 | #include <vector> | 7 | #include <vector> |
| 8 | |||
| 8 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 9 | #include "core/core.h" | 10 | #include "core/core.h" |
| 10 | #include "core/file_sys/common_funcs.h" | 11 | #include "core/file_sys/common_funcs.h" |
| @@ -14,10 +15,10 @@ | |||
| 14 | #include "core/file_sys/patch_manager.h" | 15 | #include "core/file_sys/patch_manager.h" |
| 15 | #include "core/file_sys/registered_cache.h" | 16 | #include "core/file_sys/registered_cache.h" |
| 16 | #include "core/hle/ipc_helpers.h" | 17 | #include "core/hle/ipc_helpers.h" |
| 18 | #include "core/hle/kernel/k_event.h" | ||
| 19 | #include "core/hle/kernel/k_readable_event.h" | ||
| 17 | #include "core/hle/kernel/kernel.h" | 20 | #include "core/hle/kernel/kernel.h" |
| 18 | #include "core/hle/kernel/process.h" | 21 | #include "core/hle/kernel/process.h" |
| 19 | #include "core/hle/kernel/readable_event.h" | ||
| 20 | #include "core/hle/kernel/writable_event.h" | ||
| 21 | #include "core/hle/service/aoc/aoc_u.h" | 22 | #include "core/hle/service/aoc/aoc_u.h" |
| 22 | #include "core/loader/loader.h" | 23 | #include "core/loader/loader.h" |
| 23 | #include "core/settings.h" | 24 | #include "core/settings.h" |
| @@ -62,8 +63,9 @@ public: | |||
| 62 | 63 | ||
| 63 | RegisterHandlers(functions); | 64 | RegisterHandlers(functions); |
| 64 | 65 | ||
| 65 | purchased_event = Kernel::WritableEvent::CreateEventPair( | 66 | purchased_event = |
| 66 | system.Kernel(), "IPurchaseEventManager:PurchasedEvent"); | 67 | Kernel::KEvent::Create(system.Kernel(), "IPurchaseEventManager:PurchasedEvent"); |
| 68 | purchased_event->Initialize(); | ||
| 67 | } | 69 | } |
| 68 | 70 | ||
| 69 | private: | 71 | private: |
| @@ -96,10 +98,10 @@ private: | |||
| 96 | 98 | ||
| 97 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 99 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 98 | rb.Push(RESULT_SUCCESS); | 100 | rb.Push(RESULT_SUCCESS); |
| 99 | rb.PushCopyObjects(purchased_event.readable); | 101 | rb.PushCopyObjects(purchased_event->GetReadableEvent()); |
| 100 | } | 102 | } |
| 101 | 103 | ||
| 102 | Kernel::EventPair purchased_event; | 104 | std::shared_ptr<Kernel::KEvent> purchased_event; |
| 103 | }; | 105 | }; |
| 104 | 106 | ||
| 105 | AOC_U::AOC_U(Core::System& system_) | 107 | AOC_U::AOC_U(Core::System& system_) |
| @@ -124,8 +126,8 @@ AOC_U::AOC_U(Core::System& system_) | |||
| 124 | RegisterHandlers(functions); | 126 | RegisterHandlers(functions); |
| 125 | 127 | ||
| 126 | auto& kernel = system.Kernel(); | 128 | auto& kernel = system.Kernel(); |
| 127 | aoc_change_event = | 129 | aoc_change_event = Kernel::KEvent::Create(kernel, "GetAddOnContentListChanged:Event"); |
| 128 | Kernel::WritableEvent::CreateEventPair(kernel, "GetAddOnContentListChanged:Event"); | 130 | aoc_change_event->Initialize(); |
| 129 | } | 131 | } |
| 130 | 132 | ||
| 131 | AOC_U::~AOC_U() = default; | 133 | AOC_U::~AOC_U() = default; |
| @@ -252,7 +254,7 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) { | |||
| 252 | 254 | ||
| 253 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 255 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 254 | rb.Push(RESULT_SUCCESS); | 256 | rb.Push(RESULT_SUCCESS); |
| 255 | rb.PushCopyObjects(aoc_change_event.readable); | 257 | rb.PushCopyObjects(aoc_change_event->GetReadableEvent()); |
| 256 | } | 258 | } |
| 257 | 259 | ||
| 258 | void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) { | 260 | void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h index 26ee51be0..1aa23529e 100644 --- a/src/core/hle/service/aoc/aoc_u.h +++ b/src/core/hle/service/aoc/aoc_u.h | |||
| @@ -11,7 +11,7 @@ class System; | |||
| 11 | } | 11 | } |
| 12 | 12 | ||
| 13 | namespace Kernel { | 13 | namespace Kernel { |
| 14 | class WritableEvent; | 14 | class KEvent; |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | namespace Service::AOC { | 17 | namespace Service::AOC { |
| @@ -31,7 +31,7 @@ private: | |||
| 31 | void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx); | 31 | void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx); |
| 32 | 32 | ||
| 33 | std::vector<u64> add_on_content; | 33 | std::vector<u64> add_on_content; |
| 34 | Kernel::EventPair aoc_change_event; | 34 | std::shared_ptr<Kernel::KEvent> aoc_change_event; |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | /// Registers all AOC services with the specified service manager. | 37 | /// Registers all AOC services with the specified service manager. |
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 273a46265..5ed9cb20e 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp | |||
| @@ -14,9 +14,10 @@ | |||
| 14 | #include "core/core.h" | 14 | #include "core/core.h" |
| 15 | #include "core/hle/ipc_helpers.h" | 15 | #include "core/hle/ipc_helpers.h" |
| 16 | #include "core/hle/kernel/hle_ipc.h" | 16 | #include "core/hle/kernel/hle_ipc.h" |
| 17 | #include "core/hle/kernel/k_event.h" | ||
| 18 | #include "core/hle/kernel/k_readable_event.h" | ||
| 19 | #include "core/hle/kernel/k_writable_event.h" | ||
| 17 | #include "core/hle/kernel/kernel.h" | 20 | #include "core/hle/kernel/kernel.h" |
| 18 | #include "core/hle/kernel/readable_event.h" | ||
| 19 | #include "core/hle/kernel/writable_event.h" | ||
| 20 | #include "core/hle/service/audio/audout_u.h" | 21 | #include "core/hle/service/audio/audout_u.h" |
| 21 | #include "core/hle/service/audio/errors.h" | 22 | #include "core/hle/service/audio/errors.h" |
| 22 | #include "core/memory.h" | 23 | #include "core/memory.h" |
| @@ -66,13 +67,13 @@ public: | |||
| 66 | RegisterHandlers(functions); | 67 | RegisterHandlers(functions); |
| 67 | 68 | ||
| 68 | // This is the event handle used to check if the audio buffer was released | 69 | // This is the event handle used to check if the audio buffer was released |
| 69 | buffer_event = | 70 | buffer_event = Kernel::KEvent::Create(system.Kernel(), "IAudioOutBufferReleased"); |
| 70 | Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioOutBufferReleased"); | 71 | buffer_event->Initialize(); |
| 71 | 72 | ||
| 72 | stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate, | 73 | stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate, |
| 73 | audio_params.channel_count, std::move(unique_name), [this] { | 74 | audio_params.channel_count, std::move(unique_name), [this] { |
| 74 | const auto guard = LockService(); | 75 | const auto guard = LockService(); |
| 75 | buffer_event.writable->Signal(); | 76 | buffer_event->GetWritableEvent()->Signal(); |
| 76 | }); | 77 | }); |
| 77 | } | 78 | } |
| 78 | 79 | ||
| @@ -125,7 +126,7 @@ private: | |||
| 125 | 126 | ||
| 126 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 127 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 127 | rb.Push(RESULT_SUCCESS); | 128 | rb.Push(RESULT_SUCCESS); |
| 128 | rb.PushCopyObjects(buffer_event.readable); | 129 | rb.PushCopyObjects(buffer_event->GetReadableEvent()); |
| 129 | } | 130 | } |
| 130 | 131 | ||
| 131 | void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { | 132 | void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { |
| @@ -219,7 +220,7 @@ private: | |||
| 219 | [[maybe_unused]] AudoutParams audio_params{}; | 220 | [[maybe_unused]] AudoutParams audio_params{}; |
| 220 | 221 | ||
| 221 | /// This is the event handle used to check if the audio buffer was released | 222 | /// This is the event handle used to check if the audio buffer was released |
| 222 | Kernel::EventPair buffer_event; | 223 | std::shared_ptr<Kernel::KEvent> buffer_event; |
| 223 | Core::Memory::Memory& main_memory; | 224 | Core::Memory::Memory& main_memory; |
| 224 | }; | 225 | }; |
| 225 | 226 | ||
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index c5c22d053..b2b2ffc5a 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp | |||
| @@ -16,9 +16,10 @@ | |||
| 16 | #include "core/core.h" | 16 | #include "core/core.h" |
| 17 | #include "core/hle/ipc_helpers.h" | 17 | #include "core/hle/ipc_helpers.h" |
| 18 | #include "core/hle/kernel/hle_ipc.h" | 18 | #include "core/hle/kernel/hle_ipc.h" |
| 19 | #include "core/hle/kernel/k_event.h" | ||
| 20 | #include "core/hle/kernel/k_readable_event.h" | ||
| 21 | #include "core/hle/kernel/k_writable_event.h" | ||
| 19 | #include "core/hle/kernel/kernel.h" | 22 | #include "core/hle/kernel/kernel.h" |
| 20 | #include "core/hle/kernel/readable_event.h" | ||
| 21 | #include "core/hle/kernel/writable_event.h" | ||
| 22 | #include "core/hle/service/audio/audren_u.h" | 23 | #include "core/hle/service/audio/audren_u.h" |
| 23 | #include "core/hle/service/audio/errors.h" | 24 | #include "core/hle/service/audio/errors.h" |
| 24 | 25 | ||
| @@ -47,13 +48,13 @@ public: | |||
| 47 | // clang-format on | 48 | // clang-format on |
| 48 | RegisterHandlers(functions); | 49 | RegisterHandlers(functions); |
| 49 | 50 | ||
| 50 | system_event = | 51 | system_event = Kernel::KEvent::Create(system.Kernel(), "IAudioRenderer:SystemEvent"); |
| 51 | Kernel::WritableEvent::CreateEventPair(system.Kernel(), "IAudioRenderer:SystemEvent"); | 52 | system_event->Initialize(); |
| 52 | renderer = std::make_unique<AudioCore::AudioRenderer>( | 53 | renderer = std::make_unique<AudioCore::AudioRenderer>( |
| 53 | system.CoreTiming(), system.Memory(), audren_params, | 54 | system.CoreTiming(), system.Memory(), audren_params, |
| 54 | [this]() { | 55 | [this]() { |
| 55 | const auto guard = LockService(); | 56 | const auto guard = LockService(); |
| 56 | system_event.writable->Signal(); | 57 | system_event->GetWritableEvent()->Signal(); |
| 57 | }, | 58 | }, |
| 58 | instance_number); | 59 | instance_number); |
| 59 | } | 60 | } |
| @@ -126,7 +127,7 @@ private: | |||
| 126 | 127 | ||
| 127 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 128 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 128 | rb.Push(RESULT_SUCCESS); | 129 | rb.Push(RESULT_SUCCESS); |
| 129 | rb.PushCopyObjects(system_event.readable); | 130 | rb.PushCopyObjects(system_event->GetReadableEvent()); |
| 130 | } | 131 | } |
| 131 | 132 | ||
| 132 | void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) { | 133 | void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) { |
| @@ -160,7 +161,7 @@ private: | |||
| 160 | rb.Push(ERR_NOT_SUPPORTED); | 161 | rb.Push(ERR_NOT_SUPPORTED); |
| 161 | } | 162 | } |
| 162 | 163 | ||
| 163 | Kernel::EventPair system_event; | 164 | std::shared_ptr<Kernel::KEvent> system_event; |
| 164 | std::unique_ptr<AudioCore::AudioRenderer> renderer; | 165 | std::unique_ptr<AudioCore::AudioRenderer> renderer; |
| 165 | u32 rendering_time_limit_percent = 100; | 166 | u32 rendering_time_limit_percent = 100; |
| 166 | }; | 167 | }; |
| @@ -187,17 +188,19 @@ public: | |||
| 187 | RegisterHandlers(functions); | 188 | RegisterHandlers(functions); |
| 188 | 189 | ||
| 189 | auto& kernel = system.Kernel(); | 190 | auto& kernel = system.Kernel(); |
| 190 | buffer_event = | 191 | buffer_event = Kernel::KEvent::Create(kernel, "IAudioOutBufferReleasedEvent"); |
| 191 | Kernel::WritableEvent::CreateEventPair(kernel, "IAudioOutBufferReleasedEvent"); | 192 | buffer_event->Initialize(); |
| 192 | 193 | ||
| 193 | // Should be similar to audio_output_device_switch_event | 194 | // Should be similar to audio_output_device_switch_event |
| 194 | audio_input_device_switch_event = Kernel::WritableEvent::CreateEventPair( | 195 | audio_input_device_switch_event = |
| 195 | kernel, "IAudioDevice:AudioInputDeviceSwitchedEvent"); | 196 | Kernel::KEvent::Create(kernel, "IAudioDevice:AudioInputDeviceSwitchedEvent"); |
| 197 | audio_input_device_switch_event->Initialize(); | ||
| 196 | 198 | ||
| 197 | // Should only be signalled when an audio output device has been changed, example: speaker | 199 | // Should only be signalled when an audio output device has been changed, example: speaker |
| 198 | // to headset | 200 | // to headset |
| 199 | audio_output_device_switch_event = Kernel::WritableEvent::CreateEventPair( | 201 | audio_output_device_switch_event = |
| 200 | kernel, "IAudioDevice:AudioOutputDeviceSwitchedEvent"); | 202 | Kernel::KEvent::Create(kernel, "IAudioDevice:AudioOutputDeviceSwitchedEvent"); |
| 203 | audio_output_device_switch_event->Initialize(); | ||
| 201 | } | 204 | } |
| 202 | 205 | ||
| 203 | private: | 206 | private: |
| @@ -286,11 +289,11 @@ private: | |||
| 286 | void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { | 289 | void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { |
| 287 | LOG_WARNING(Service_Audio, "(STUBBED) called"); | 290 | LOG_WARNING(Service_Audio, "(STUBBED) called"); |
| 288 | 291 | ||
| 289 | buffer_event.writable->Signal(); | 292 | buffer_event->GetWritableEvent()->Signal(); |
| 290 | 293 | ||
| 291 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 294 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 292 | rb.Push(RESULT_SUCCESS); | 295 | rb.Push(RESULT_SUCCESS); |
| 293 | rb.PushCopyObjects(buffer_event.readable); | 296 | rb.PushCopyObjects(buffer_event->GetReadableEvent()); |
| 294 | } | 297 | } |
| 295 | 298 | ||
| 296 | void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { | 299 | void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { |
| @@ -307,7 +310,7 @@ private: | |||
| 307 | 310 | ||
| 308 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 311 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 309 | rb.Push(RESULT_SUCCESS); | 312 | rb.Push(RESULT_SUCCESS); |
| 310 | rb.PushCopyObjects(audio_input_device_switch_event.readable); | 313 | rb.PushCopyObjects(audio_input_device_switch_event->GetReadableEvent()); |
| 311 | } | 314 | } |
| 312 | 315 | ||
| 313 | void QueryAudioDeviceOutputEvent(Kernel::HLERequestContext& ctx) { | 316 | void QueryAudioDeviceOutputEvent(Kernel::HLERequestContext& ctx) { |
| @@ -315,13 +318,13 @@ private: | |||
| 315 | 318 | ||
| 316 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 319 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 317 | rb.Push(RESULT_SUCCESS); | 320 | rb.Push(RESULT_SUCCESS); |
| 318 | rb.PushCopyObjects(audio_output_device_switch_event.readable); | 321 | rb.PushCopyObjects(audio_output_device_switch_event->GetReadableEvent()); |
| 319 | } | 322 | } |
| 320 | 323 | ||
| 321 | u32_le revision = 0; | 324 | u32_le revision = 0; |
| 322 | Kernel::EventPair buffer_event; | 325 | std::shared_ptr<Kernel::KEvent> buffer_event; |
| 323 | Kernel::EventPair audio_input_device_switch_event; | 326 | std::shared_ptr<Kernel::KEvent> audio_input_device_switch_event; |
| 324 | Kernel::EventPair audio_output_device_switch_event; | 327 | std::shared_ptr<Kernel::KEvent> audio_output_device_switch_event; |
| 325 | 328 | ||
| 326 | }; // namespace Audio | 329 | }; // namespace Audio |
| 327 | 330 | ||
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp index 174388445..92d25dbe4 100644 --- a/src/core/hle/service/bcat/backend/backend.cpp +++ b/src/core/hle/service/bcat/backend/backend.cpp | |||
| @@ -5,6 +5,9 @@ | |||
| 5 | #include "common/hex_util.h" | 5 | #include "common/hex_util.h" |
| 6 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/kernel/k_event.h" | ||
| 9 | #include "core/hle/kernel/k_readable_event.h" | ||
| 10 | #include "core/hle/kernel/k_writable_event.h" | ||
| 8 | #include "core/hle/lock.h" | 11 | #include "core/hle/lock.h" |
| 9 | #include "core/hle/service/bcat/backend/backend.h" | 12 | #include "core/hle/service/bcat/backend/backend.h" |
| 10 | 13 | ||
| @@ -12,12 +15,13 @@ namespace Service::BCAT { | |||
| 12 | 15 | ||
| 13 | ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel, | 16 | ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel, |
| 14 | std::string_view event_name) { | 17 | std::string_view event_name) { |
| 15 | event = Kernel::WritableEvent::CreateEventPair( | 18 | event = Kernel::KEvent::Create(kernel, |
| 16 | kernel, std::string("ProgressServiceBackend:UpdateEvent:").append(event_name)); | 19 | "ProgressServiceBackend:UpdateEvent:" + std::string(event_name)); |
| 20 | event->Initialize(); | ||
| 17 | } | 21 | } |
| 18 | 22 | ||
| 19 | std::shared_ptr<Kernel::ReadableEvent> ProgressServiceBackend::GetEvent() const { | 23 | std::shared_ptr<Kernel::KReadableEvent> ProgressServiceBackend::GetEvent() const { |
| 20 | return event.readable; | 24 | return event->GetReadableEvent(); |
| 21 | } | 25 | } |
| 22 | 26 | ||
| 23 | DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() { | 27 | DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() { |
| @@ -85,9 +89,9 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) { | |||
| 85 | void ProgressServiceBackend::SignalUpdate() const { | 89 | void ProgressServiceBackend::SignalUpdate() const { |
| 86 | if (need_hle_lock) { | 90 | if (need_hle_lock) { |
| 87 | std::lock_guard lock(HLE::g_hle_lock); | 91 | std::lock_guard lock(HLE::g_hle_lock); |
| 88 | event.writable->Signal(); | 92 | event->GetWritableEvent()->Signal(); |
| 89 | } else { | 93 | } else { |
| 90 | event.writable->Signal(); | 94 | event->GetWritableEvent()->Signal(); |
| 91 | } | 95 | } |
| 92 | } | 96 | } |
| 93 | 97 | ||
diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h index 48bbbe66f..db585b069 100644 --- a/src/core/hle/service/bcat/backend/backend.h +++ b/src/core/hle/service/bcat/backend/backend.h | |||
| @@ -11,8 +11,6 @@ | |||
| 11 | 11 | ||
| 12 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 13 | #include "core/file_sys/vfs_types.h" | 13 | #include "core/file_sys/vfs_types.h" |
| 14 | #include "core/hle/kernel/readable_event.h" | ||
| 15 | #include "core/hle/kernel/writable_event.h" | ||
| 16 | #include "core/hle/result.h" | 14 | #include "core/hle/result.h" |
| 17 | 15 | ||
| 18 | namespace Core { | 16 | namespace Core { |
| @@ -21,7 +19,9 @@ class System; | |||
| 21 | 19 | ||
| 22 | namespace Kernel { | 20 | namespace Kernel { |
| 23 | class KernelCore; | 21 | class KernelCore; |
| 24 | } | 22 | class KEvent; |
| 23 | class KReadableEvent; | ||
| 24 | } // namespace Kernel | ||
| 25 | 25 | ||
| 26 | namespace Service::BCAT { | 26 | namespace Service::BCAT { |
| 27 | 27 | ||
| @@ -98,13 +98,13 @@ public: | |||
| 98 | private: | 98 | private: |
| 99 | explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name); | 99 | explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name); |
| 100 | 100 | ||
| 101 | std::shared_ptr<Kernel::ReadableEvent> GetEvent() const; | 101 | std::shared_ptr<Kernel::KReadableEvent> GetEvent() const; |
| 102 | DeliveryCacheProgressImpl& GetImpl(); | 102 | DeliveryCacheProgressImpl& GetImpl(); |
| 103 | 103 | ||
| 104 | void SignalUpdate() const; | 104 | void SignalUpdate() const; |
| 105 | 105 | ||
| 106 | DeliveryCacheProgressImpl impl{}; | 106 | DeliveryCacheProgressImpl impl{}; |
| 107 | Kernel::EventPair event; | 107 | std::shared_ptr<Kernel::KEvent> event; |
| 108 | bool need_hle_lock = false; | 108 | bool need_hle_lock = false; |
| 109 | }; | 109 | }; |
| 110 | 110 | ||
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp index b8696a395..503109fdd 100644 --- a/src/core/hle/service/bcat/module.cpp +++ b/src/core/hle/service/bcat/module.cpp | |||
| @@ -11,9 +11,9 @@ | |||
| 11 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/file_sys/vfs.h" | 12 | #include "core/file_sys/vfs.h" |
| 13 | #include "core/hle/ipc_helpers.h" | 13 | #include "core/hle/ipc_helpers.h" |
| 14 | #include "core/hle/kernel/k_readable_event.h" | ||
| 15 | #include "core/hle/kernel/k_writable_event.h" | ||
| 14 | #include "core/hle/kernel/process.h" | 16 | #include "core/hle/kernel/process.h" |
| 15 | #include "core/hle/kernel/readable_event.h" | ||
| 16 | #include "core/hle/kernel/writable_event.h" | ||
| 17 | #include "core/hle/service/bcat/backend/backend.h" | 17 | #include "core/hle/service/bcat/backend/backend.h" |
| 18 | #include "core/hle/service/bcat/bcat.h" | 18 | #include "core/hle/service/bcat/bcat.h" |
| 19 | #include "core/hle/service/bcat/module.h" | 19 | #include "core/hle/service/bcat/module.h" |
| @@ -89,7 +89,7 @@ struct DeliveryCacheDirectoryEntry { | |||
| 89 | class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> { | 89 | class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> { |
| 90 | public: | 90 | public: |
| 91 | explicit IDeliveryCacheProgressService(Core::System& system_, | 91 | explicit IDeliveryCacheProgressService(Core::System& system_, |
| 92 | std::shared_ptr<Kernel::ReadableEvent> event_, | 92 | std::shared_ptr<Kernel::KReadableEvent> event_, |
| 93 | const DeliveryCacheProgressImpl& impl_) | 93 | const DeliveryCacheProgressImpl& impl_) |
| 94 | : ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{std::move(event_)}, | 94 | : ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{std::move(event_)}, |
| 95 | impl{impl_} { | 95 | impl{impl_} { |
| @@ -121,7 +121,7 @@ private: | |||
| 121 | rb.Push(RESULT_SUCCESS); | 121 | rb.Push(RESULT_SUCCESS); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | std::shared_ptr<Kernel::ReadableEvent> event; | 124 | std::shared_ptr<Kernel::KReadableEvent> event; |
| 125 | const DeliveryCacheProgressImpl& impl; | 125 | const DeliveryCacheProgressImpl& impl; |
| 126 | }; | 126 | }; |
| 127 | 127 | ||
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp index 2de86f1f1..17a2ac899 100644 --- a/src/core/hle/service/btdrv/btdrv.cpp +++ b/src/core/hle/service/btdrv/btdrv.cpp | |||
| @@ -6,9 +6,9 @@ | |||
| 6 | #include "core/core.h" | 6 | #include "core/core.h" |
| 7 | #include "core/hle/ipc_helpers.h" | 7 | #include "core/hle/ipc_helpers.h" |
| 8 | #include "core/hle/kernel/hle_ipc.h" | 8 | #include "core/hle/kernel/hle_ipc.h" |
| 9 | #include "core/hle/kernel/k_event.h" | ||
| 10 | #include "core/hle/kernel/k_readable_event.h" | ||
| 9 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/kernel.h" |
| 10 | #include "core/hle/kernel/readable_event.h" | ||
| 11 | #include "core/hle/kernel/writable_event.h" | ||
| 12 | #include "core/hle/service/btdrv/btdrv.h" | 12 | #include "core/hle/service/btdrv/btdrv.h" |
| 13 | #include "core/hle/service/service.h" | 13 | #include "core/hle/service/service.h" |
| 14 | #include "core/hle/service/sm/sm.h" | 14 | #include "core/hle/service/sm/sm.h" |
| @@ -35,7 +35,8 @@ public: | |||
| 35 | RegisterHandlers(functions); | 35 | RegisterHandlers(functions); |
| 36 | 36 | ||
| 37 | auto& kernel = system.Kernel(); | 37 | auto& kernel = system.Kernel(); |
| 38 | register_event = Kernel::WritableEvent::CreateEventPair(kernel, "BT:RegisterEvent"); | 38 | register_event = Kernel::KEvent::Create(kernel, "BT:RegisterEvent"); |
| 39 | register_event->Initialize(); | ||
| 39 | } | 40 | } |
| 40 | 41 | ||
| 41 | private: | 42 | private: |
| @@ -44,10 +45,10 @@ private: | |||
| 44 | 45 | ||
| 45 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 46 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 46 | rb.Push(RESULT_SUCCESS); | 47 | rb.Push(RESULT_SUCCESS); |
| 47 | rb.PushCopyObjects(register_event.readable); | 48 | rb.PushCopyObjects(register_event->GetReadableEvent()); |
| 48 | } | 49 | } |
| 49 | 50 | ||
| 50 | Kernel::EventPair register_event; | 51 | std::shared_ptr<Kernel::KEvent> register_event; |
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 53 | class BtDrv final : public ServiceFramework<BtDrv> { | 54 | class BtDrv final : public ServiceFramework<BtDrv> { |
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp index 38b55300e..9cf2ee92a 100644 --- a/src/core/hle/service/btm/btm.cpp +++ b/src/core/hle/service/btm/btm.cpp | |||
| @@ -8,9 +8,9 @@ | |||
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| 10 | #include "core/hle/kernel/hle_ipc.h" | 10 | #include "core/hle/kernel/hle_ipc.h" |
| 11 | #include "core/hle/kernel/k_event.h" | ||
| 12 | #include "core/hle/kernel/k_readable_event.h" | ||
| 11 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 12 | #include "core/hle/kernel/readable_event.h" | ||
| 13 | #include "core/hle/kernel/writable_event.h" | ||
| 14 | #include "core/hle/service/btm/btm.h" | 14 | #include "core/hle/service/btm/btm.h" |
| 15 | #include "core/hle/service/service.h" | 15 | #include "core/hle/service/service.h" |
| 16 | 16 | ||
| @@ -58,12 +58,14 @@ public: | |||
| 58 | RegisterHandlers(functions); | 58 | RegisterHandlers(functions); |
| 59 | 59 | ||
| 60 | auto& kernel = system.Kernel(); | 60 | auto& kernel = system.Kernel(); |
| 61 | scan_event = Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ScanEvent"); | 61 | scan_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ScanEvent"); |
| 62 | connection_event = | 62 | scan_event->Initialize(); |
| 63 | Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ConnectionEvent"); | 63 | connection_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ConnectionEvent"); |
| 64 | service_discovery = | 64 | connection_event->Initialize(); |
| 65 | Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:Discovery"); | 65 | service_discovery = Kernel::KEvent::Create(kernel, "IBtmUserCore:Discovery"); |
| 66 | config_event = Kernel::WritableEvent::CreateEventPair(kernel, "IBtmUserCore:ConfigEvent"); | 66 | service_discovery->Initialize(); |
| 67 | config_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ConfigEvent"); | ||
| 68 | config_event->Initialize(); | ||
| 67 | } | 69 | } |
| 68 | 70 | ||
| 69 | private: | 71 | private: |
| @@ -72,7 +74,7 @@ private: | |||
| 72 | 74 | ||
| 73 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 75 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 74 | rb.Push(RESULT_SUCCESS); | 76 | rb.Push(RESULT_SUCCESS); |
| 75 | rb.PushCopyObjects(scan_event.readable); | 77 | rb.PushCopyObjects(scan_event->GetReadableEvent()); |
| 76 | } | 78 | } |
| 77 | 79 | ||
| 78 | void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) { | 80 | void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) { |
| @@ -80,7 +82,7 @@ private: | |||
| 80 | 82 | ||
| 81 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 83 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 82 | rb.Push(RESULT_SUCCESS); | 84 | rb.Push(RESULT_SUCCESS); |
| 83 | rb.PushCopyObjects(connection_event.readable); | 85 | rb.PushCopyObjects(connection_event->GetReadableEvent()); |
| 84 | } | 86 | } |
| 85 | 87 | ||
| 86 | void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) { | 88 | void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) { |
| @@ -88,7 +90,7 @@ private: | |||
| 88 | 90 | ||
| 89 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 91 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 90 | rb.Push(RESULT_SUCCESS); | 92 | rb.Push(RESULT_SUCCESS); |
| 91 | rb.PushCopyObjects(service_discovery.readable); | 93 | rb.PushCopyObjects(service_discovery->GetReadableEvent()); |
| 92 | } | 94 | } |
| 93 | 95 | ||
| 94 | void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) { | 96 | void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) { |
| @@ -96,13 +98,13 @@ private: | |||
| 96 | 98 | ||
| 97 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 99 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 98 | rb.Push(RESULT_SUCCESS); | 100 | rb.Push(RESULT_SUCCESS); |
| 99 | rb.PushCopyObjects(config_event.readable); | 101 | rb.PushCopyObjects(config_event->GetReadableEvent()); |
| 100 | } | 102 | } |
| 101 | 103 | ||
| 102 | Kernel::EventPair scan_event; | 104 | std::shared_ptr<Kernel::KEvent> scan_event; |
| 103 | Kernel::EventPair connection_event; | 105 | std::shared_ptr<Kernel::KEvent> connection_event; |
| 104 | Kernel::EventPair service_discovery; | 106 | std::shared_ptr<Kernel::KEvent> service_discovery; |
| 105 | Kernel::EventPair config_event; | 107 | std::shared_ptr<Kernel::KEvent> config_event; |
| 106 | }; | 108 | }; |
| 107 | 109 | ||
| 108 | class BTM_USR final : public ServiceFramework<BTM_USR> { | 110 | class BTM_USR final : public ServiceFramework<BTM_USR> { |
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index c5b053c31..72a877d68 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp | |||
| @@ -7,8 +7,9 @@ | |||
| 7 | #include "common/uuid.h" | 7 | #include "common/uuid.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| 10 | #include "core/hle/kernel/readable_event.h" | 10 | #include "core/hle/kernel/k_event.h" |
| 11 | #include "core/hle/kernel/writable_event.h" | 11 | #include "core/hle/kernel/k_readable_event.h" |
| 12 | #include "core/hle/kernel/k_writable_event.h" | ||
| 12 | #include "core/hle/service/friend/errors.h" | 13 | #include "core/hle/service/friend/errors.h" |
| 13 | #include "core/hle/service/friend/friend.h" | 14 | #include "core/hle/service/friend/friend.h" |
| 14 | #include "core/hle/service/friend/interface.h" | 15 | #include "core/hle/service/friend/interface.h" |
| @@ -183,8 +184,9 @@ public: | |||
| 183 | 184 | ||
| 184 | RegisterHandlers(functions); | 185 | RegisterHandlers(functions); |
| 185 | 186 | ||
| 186 | notification_event = Kernel::WritableEvent::CreateEventPair( | 187 | notification_event = |
| 187 | system.Kernel(), "INotificationService:NotifyEvent"); | 188 | Kernel::KEvent::Create(system.Kernel(), "INotificationService:NotifyEvent"); |
| 189 | notification_event->Initialize(); | ||
| 188 | } | 190 | } |
| 189 | 191 | ||
| 190 | private: | 192 | private: |
| @@ -193,7 +195,7 @@ private: | |||
| 193 | 195 | ||
| 194 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 196 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 195 | rb.Push(RESULT_SUCCESS); | 197 | rb.Push(RESULT_SUCCESS); |
| 196 | rb.PushCopyObjects(notification_event.readable); | 198 | rb.PushCopyObjects(notification_event->GetReadableEvent()); |
| 197 | } | 199 | } |
| 198 | 200 | ||
| 199 | void Clear(Kernel::HLERequestContext& ctx) { | 201 | void Clear(Kernel::HLERequestContext& ctx) { |
| @@ -258,7 +260,7 @@ private: | |||
| 258 | }; | 260 | }; |
| 259 | 261 | ||
| 260 | Common::UUID uuid{Common::INVALID_UUID}; | 262 | Common::UUID uuid{Common::INVALID_UUID}; |
| 261 | Kernel::EventPair notification_event; | 263 | std::shared_ptr<Kernel::KEvent> notification_event; |
| 262 | std::queue<SizedNotificationInfo> notifications; | 264 | std::queue<SizedNotificationInfo> notifications; |
| 263 | States states{}; | 265 | States states{}; |
| 264 | }; | 266 | }; |
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp index 59b694cd4..c4a59147d 100644 --- a/src/core/hle/service/hid/controllers/keyboard.cpp +++ b/src/core/hle/service/hid/controllers/keyboard.cpp | |||
| @@ -39,16 +39,25 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing, | |||
| 39 | cur_entry.sampling_number2 = cur_entry.sampling_number; | 39 | cur_entry.sampling_number2 = cur_entry.sampling_number; |
| 40 | 40 | ||
| 41 | cur_entry.key.fill(0); | 41 | cur_entry.key.fill(0); |
| 42 | cur_entry.modifier = 0; | ||
| 43 | if (Settings::values.keyboard_enabled) { | 42 | if (Settings::values.keyboard_enabled) { |
| 44 | for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { | 43 | for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { |
| 45 | auto& entry = cur_entry.key[i / KEYS_PER_BYTE]; | 44 | auto& entry = cur_entry.key[i / KEYS_PER_BYTE]; |
| 46 | entry = static_cast<u8>(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE))); | 45 | entry = static_cast<u8>(entry | (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE))); |
| 47 | } | 46 | } |
| 48 | 47 | ||
| 49 | for (std::size_t i = 0; i < keyboard_mods.size(); ++i) { | 48 | using namespace Settings::NativeKeyboard; |
| 50 | cur_entry.modifier |= (keyboard_mods[i]->GetStatus() << i); | 49 | |
| 51 | } | 50 | // TODO: Assign the correct key to all modifiers |
| 51 | cur_entry.modifier.control.Assign(keyboard_mods[LeftControl]->GetStatus()); | ||
| 52 | cur_entry.modifier.shift.Assign(keyboard_mods[LeftShift]->GetStatus()); | ||
| 53 | cur_entry.modifier.left_alt.Assign(keyboard_mods[LeftAlt]->GetStatus()); | ||
| 54 | cur_entry.modifier.right_alt.Assign(keyboard_mods[RightAlt]->GetStatus()); | ||
| 55 | cur_entry.modifier.gui.Assign(0); | ||
| 56 | cur_entry.modifier.caps_lock.Assign(keyboard_mods[CapsLock]->GetStatus()); | ||
| 57 | cur_entry.modifier.scroll_lock.Assign(keyboard_mods[ScrollLock]->GetStatus()); | ||
| 58 | cur_entry.modifier.num_lock.Assign(keyboard_mods[NumLock]->GetStatus()); | ||
| 59 | cur_entry.modifier.katakana.Assign(0); | ||
| 60 | cur_entry.modifier.hiragana.Assign(0); | ||
| 52 | } | 61 | } |
| 53 | std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); | 62 | std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); |
| 54 | } | 63 | } |
diff --git a/src/core/hle/service/hid/controllers/keyboard.h b/src/core/hle/service/hid/controllers/keyboard.h index f3eef5936..b5b281752 100644 --- a/src/core/hle/service/hid/controllers/keyboard.h +++ b/src/core/hle/service/hid/controllers/keyboard.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include "common/bit_field.h" | ||
| 8 | #include "common/common_funcs.h" | 9 | #include "common/common_funcs.h" |
| 9 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 10 | #include "common/swap.h" | 11 | #include "common/swap.h" |
| @@ -31,12 +32,28 @@ public: | |||
| 31 | void OnLoadInputDevices() override; | 32 | void OnLoadInputDevices() override; |
| 32 | 33 | ||
| 33 | private: | 34 | private: |
| 35 | struct Modifiers { | ||
| 36 | union { | ||
| 37 | u32_le raw{}; | ||
| 38 | BitField<0, 1, u32> control; | ||
| 39 | BitField<1, 1, u32> shift; | ||
| 40 | BitField<2, 1, u32> left_alt; | ||
| 41 | BitField<3, 1, u32> right_alt; | ||
| 42 | BitField<4, 1, u32> gui; | ||
| 43 | BitField<8, 1, u32> caps_lock; | ||
| 44 | BitField<9, 1, u32> scroll_lock; | ||
| 45 | BitField<10, 1, u32> num_lock; | ||
| 46 | BitField<11, 1, u32> katakana; | ||
| 47 | BitField<12, 1, u32> hiragana; | ||
| 48 | }; | ||
| 49 | }; | ||
| 50 | static_assert(sizeof(Modifiers) == 0x4, "Modifiers is an invalid size"); | ||
| 51 | |||
| 34 | struct KeyboardState { | 52 | struct KeyboardState { |
| 35 | s64_le sampling_number; | 53 | s64_le sampling_number; |
| 36 | s64_le sampling_number2; | 54 | s64_le sampling_number2; |
| 37 | 55 | ||
| 38 | s32_le modifier; | 56 | Modifiers modifier; |
| 39 | s32_le attribute; | ||
| 40 | std::array<u8, 32> key; | 57 | std::array<u8, 32> key; |
| 41 | }; | 58 | }; |
| 42 | static_assert(sizeof(KeyboardState) == 0x38, "KeyboardState is an invalid size"); | 59 | static_assert(sizeof(KeyboardState) == 0x38, "KeyboardState is an invalid size"); |
diff --git a/src/core/hle/service/hid/controllers/mouse.cpp b/src/core/hle/service/hid/controllers/mouse.cpp index ac40989c5..2e7457604 100644 --- a/src/core/hle/service/hid/controllers/mouse.cpp +++ b/src/core/hle/service/hid/controllers/mouse.cpp | |||
| @@ -36,6 +36,7 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 36 | cur_entry.sampling_number = last_entry.sampling_number + 1; | 36 | cur_entry.sampling_number = last_entry.sampling_number + 1; |
| 37 | cur_entry.sampling_number2 = cur_entry.sampling_number; | 37 | cur_entry.sampling_number2 = cur_entry.sampling_number; |
| 38 | 38 | ||
| 39 | cur_entry.attribute.raw = 0; | ||
| 39 | if (Settings::values.mouse_enabled) { | 40 | if (Settings::values.mouse_enabled) { |
| 40 | const auto [px, py, sx, sy] = mouse_device->GetStatus(); | 41 | const auto [px, py, sx, sy] = mouse_device->GetStatus(); |
| 41 | const auto x = static_cast<s32>(px * Layout::ScreenUndocked::Width); | 42 | const auto x = static_cast<s32>(px * Layout::ScreenUndocked::Width); |
| @@ -46,10 +47,14 @@ void Controller_Mouse::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 46 | cur_entry.delta_y = y - last_entry.y; | 47 | cur_entry.delta_y = y - last_entry.y; |
| 47 | cur_entry.mouse_wheel_x = sx; | 48 | cur_entry.mouse_wheel_x = sx; |
| 48 | cur_entry.mouse_wheel_y = sy; | 49 | cur_entry.mouse_wheel_y = sy; |
| 50 | cur_entry.attribute.is_connected.Assign(1); | ||
| 49 | 51 | ||
| 50 | for (std::size_t i = 0; i < mouse_button_devices.size(); ++i) { | 52 | using namespace Settings::NativeMouseButton; |
| 51 | cur_entry.button |= (mouse_button_devices[i]->GetStatus() << i); | 53 | cur_entry.button.left.Assign(mouse_button_devices[Left]->GetStatus()); |
| 52 | } | 54 | cur_entry.button.right.Assign(mouse_button_devices[Right]->GetStatus()); |
| 55 | cur_entry.button.middle.Assign(mouse_button_devices[Middle]->GetStatus()); | ||
| 56 | cur_entry.button.forward.Assign(mouse_button_devices[Forward]->GetStatus()); | ||
| 57 | cur_entry.button.back.Assign(mouse_button_devices[Back]->GetStatus()); | ||
| 53 | } | 58 | } |
| 54 | 59 | ||
| 55 | std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); | 60 | std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); |
diff --git a/src/core/hle/service/hid/controllers/mouse.h b/src/core/hle/service/hid/controllers/mouse.h index 357ab7107..3b432a36e 100644 --- a/src/core/hle/service/hid/controllers/mouse.h +++ b/src/core/hle/service/hid/controllers/mouse.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include "common/bit_field.h" | ||
| 8 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 9 | #include "common/swap.h" | 10 | #include "common/swap.h" |
| 10 | #include "core/frontend/input.h" | 11 | #include "core/frontend/input.h" |
| @@ -30,6 +31,27 @@ public: | |||
| 30 | void OnLoadInputDevices() override; | 31 | void OnLoadInputDevices() override; |
| 31 | 32 | ||
| 32 | private: | 33 | private: |
| 34 | struct Buttons { | ||
| 35 | union { | ||
| 36 | u32_le raw{}; | ||
| 37 | BitField<0, 1, u32> left; | ||
| 38 | BitField<1, 1, u32> right; | ||
| 39 | BitField<2, 1, u32> middle; | ||
| 40 | BitField<3, 1, u32> forward; | ||
| 41 | BitField<4, 1, u32> back; | ||
| 42 | }; | ||
| 43 | }; | ||
| 44 | static_assert(sizeof(Buttons) == 0x4, "Buttons is an invalid size"); | ||
| 45 | |||
| 46 | struct Attributes { | ||
| 47 | union { | ||
| 48 | u32_le raw{}; | ||
| 49 | BitField<0, 1, u32> transferable; | ||
| 50 | BitField<1, 1, u32> is_connected; | ||
| 51 | }; | ||
| 52 | }; | ||
| 53 | static_assert(sizeof(Attributes) == 0x4, "Attributes is an invalid size"); | ||
| 54 | |||
| 33 | struct MouseState { | 55 | struct MouseState { |
| 34 | s64_le sampling_number; | 56 | s64_le sampling_number; |
| 35 | s64_le sampling_number2; | 57 | s64_le sampling_number2; |
| @@ -39,8 +61,8 @@ private: | |||
| 39 | s32_le delta_y; | 61 | s32_le delta_y; |
| 40 | s32_le mouse_wheel_x; | 62 | s32_le mouse_wheel_x; |
| 41 | s32_le mouse_wheel_y; | 63 | s32_le mouse_wheel_y; |
| 42 | s32_le button; | 64 | Buttons button; |
| 43 | s32_le attribute; | 65 | Attributes attribute; |
| 44 | }; | 66 | }; |
| 45 | static_assert(sizeof(MouseState) == 0x30, "MouseState is an invalid size"); | 67 | static_assert(sizeof(MouseState) == 0x30, "MouseState is an invalid size"); |
| 46 | 68 | ||
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 0c227b135..dbf198345 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp | |||
| @@ -12,9 +12,10 @@ | |||
| 12 | #include "core/core.h" | 12 | #include "core/core.h" |
| 13 | #include "core/core_timing.h" | 13 | #include "core/core_timing.h" |
| 14 | #include "core/frontend/input.h" | 14 | #include "core/frontend/input.h" |
| 15 | #include "core/hle/kernel/k_event.h" | ||
| 16 | #include "core/hle/kernel/k_readable_event.h" | ||
| 17 | #include "core/hle/kernel/k_writable_event.h" | ||
| 15 | #include "core/hle/kernel/kernel.h" | 18 | #include "core/hle/kernel/kernel.h" |
| 16 | #include "core/hle/kernel/readable_event.h" | ||
| 17 | #include "core/hle/kernel/writable_event.h" | ||
| 18 | #include "core/hle/service/hid/controllers/npad.h" | 19 | #include "core/hle/service/hid/controllers/npad.h" |
| 19 | #include "core/settings.h" | 20 | #include "core/settings.h" |
| 20 | 21 | ||
| @@ -153,79 +154,86 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { | |||
| 153 | const auto controller_type = connected_controllers[controller_idx].type; | 154 | const auto controller_type = connected_controllers[controller_idx].type; |
| 154 | auto& controller = shared_memory_entries[controller_idx]; | 155 | auto& controller = shared_memory_entries[controller_idx]; |
| 155 | if (controller_type == NPadControllerType::None) { | 156 | if (controller_type == NPadControllerType::None) { |
| 156 | styleset_changed_events[controller_idx].writable->Signal(); | 157 | styleset_changed_events[controller_idx]->GetWritableEvent()->Signal(); |
| 157 | return; | 158 | return; |
| 158 | } | 159 | } |
| 159 | controller.joy_styles.raw = 0; // Zero out | 160 | controller.style_set.raw = 0; // Zero out |
| 160 | controller.device_type.raw = 0; | 161 | controller.device_type.raw = 0; |
| 161 | controller.properties.raw = 0; | 162 | controller.system_properties.raw = 0; |
| 162 | switch (controller_type) { | 163 | switch (controller_type) { |
| 163 | case NPadControllerType::None: | 164 | case NPadControllerType::None: |
| 164 | UNREACHABLE(); | 165 | UNREACHABLE(); |
| 165 | break; | 166 | break; |
| 166 | case NPadControllerType::ProController: | 167 | case NPadControllerType::ProController: |
| 167 | controller.joy_styles.pro_controller.Assign(1); | 168 | controller.style_set.fullkey.Assign(1); |
| 168 | controller.device_type.pro_controller.Assign(1); | 169 | controller.device_type.fullkey.Assign(1); |
| 169 | controller.properties.is_vertical.Assign(1); | 170 | controller.system_properties.is_vertical.Assign(1); |
| 170 | controller.properties.use_plus.Assign(1); | 171 | controller.system_properties.use_plus.Assign(1); |
| 171 | controller.properties.use_minus.Assign(1); | 172 | controller.system_properties.use_minus.Assign(1); |
| 172 | controller.pad_assignment = NpadAssignments::Single; | 173 | controller.assignment_mode = NpadAssignments::Single; |
| 174 | controller.footer_type = AppletFooterUiType::SwitchProController; | ||
| 173 | break; | 175 | break; |
| 174 | case NPadControllerType::Handheld: | 176 | case NPadControllerType::Handheld: |
| 175 | controller.joy_styles.handheld.Assign(1); | 177 | controller.style_set.handheld.Assign(1); |
| 176 | controller.device_type.handheld.Assign(1); | 178 | controller.device_type.handheld_left.Assign(1); |
| 177 | controller.properties.is_vertical.Assign(1); | 179 | controller.device_type.handheld_right.Assign(1); |
| 178 | controller.properties.use_plus.Assign(1); | 180 | controller.system_properties.is_vertical.Assign(1); |
| 179 | controller.properties.use_minus.Assign(1); | 181 | controller.system_properties.use_plus.Assign(1); |
| 180 | controller.pad_assignment = NpadAssignments::Dual; | 182 | controller.system_properties.use_minus.Assign(1); |
| 183 | controller.assignment_mode = NpadAssignments::Dual; | ||
| 184 | controller.footer_type = AppletFooterUiType::HandheldJoyConLeftJoyConRight; | ||
| 181 | break; | 185 | break; |
| 182 | case NPadControllerType::JoyDual: | 186 | case NPadControllerType::JoyDual: |
| 183 | controller.joy_styles.joycon_dual.Assign(1); | 187 | controller.style_set.joycon_dual.Assign(1); |
| 184 | controller.device_type.joycon_left.Assign(1); | 188 | controller.device_type.joycon_left.Assign(1); |
| 185 | controller.device_type.joycon_right.Assign(1); | 189 | controller.device_type.joycon_right.Assign(1); |
| 186 | controller.properties.is_vertical.Assign(1); | 190 | controller.system_properties.is_vertical.Assign(1); |
| 187 | controller.properties.use_plus.Assign(1); | 191 | controller.system_properties.use_plus.Assign(1); |
| 188 | controller.properties.use_minus.Assign(1); | 192 | controller.system_properties.use_minus.Assign(1); |
| 189 | controller.pad_assignment = NpadAssignments::Dual; | 193 | controller.assignment_mode = NpadAssignments::Dual; |
| 194 | controller.footer_type = AppletFooterUiType::JoyDual; | ||
| 190 | break; | 195 | break; |
| 191 | case NPadControllerType::JoyLeft: | 196 | case NPadControllerType::JoyLeft: |
| 192 | controller.joy_styles.joycon_left.Assign(1); | 197 | controller.style_set.joycon_left.Assign(1); |
| 193 | controller.device_type.joycon_left.Assign(1); | 198 | controller.device_type.joycon_left.Assign(1); |
| 194 | controller.properties.is_horizontal.Assign(1); | 199 | controller.system_properties.is_horizontal.Assign(1); |
| 195 | controller.properties.use_minus.Assign(1); | 200 | controller.system_properties.use_minus.Assign(1); |
| 196 | controller.pad_assignment = NpadAssignments::Single; | 201 | controller.assignment_mode = NpadAssignments::Single; |
| 202 | controller.footer_type = AppletFooterUiType::JoyLeftHorizontal; | ||
| 197 | break; | 203 | break; |
| 198 | case NPadControllerType::JoyRight: | 204 | case NPadControllerType::JoyRight: |
| 199 | controller.joy_styles.joycon_right.Assign(1); | 205 | controller.style_set.joycon_right.Assign(1); |
| 200 | controller.device_type.joycon_right.Assign(1); | 206 | controller.device_type.joycon_right.Assign(1); |
| 201 | controller.properties.is_horizontal.Assign(1); | 207 | controller.system_properties.is_horizontal.Assign(1); |
| 202 | controller.properties.use_plus.Assign(1); | 208 | controller.system_properties.use_plus.Assign(1); |
| 203 | controller.pad_assignment = NpadAssignments::Single; | 209 | controller.assignment_mode = NpadAssignments::Single; |
| 210 | controller.footer_type = AppletFooterUiType::JoyRightHorizontal; | ||
| 204 | break; | 211 | break; |
| 205 | case NPadControllerType::Pokeball: | 212 | case NPadControllerType::Pokeball: |
| 206 | controller.joy_styles.pokeball.Assign(1); | 213 | controller.style_set.palma.Assign(1); |
| 207 | controller.device_type.pokeball.Assign(1); | 214 | controller.device_type.palma.Assign(1); |
| 208 | controller.pad_assignment = NpadAssignments::Single; | 215 | controller.assignment_mode = NpadAssignments::Single; |
| 209 | break; | 216 | break; |
| 210 | } | 217 | } |
| 211 | 218 | ||
| 212 | controller.single_color_error = ColorReadError::ReadOk; | 219 | controller.fullkey_color.attribute = ColorAttributes::Ok; |
| 213 | controller.single_color.body_color = 0; | 220 | controller.fullkey_color.fullkey.body = 0; |
| 214 | controller.single_color.button_color = 0; | 221 | controller.fullkey_color.fullkey.button = 0; |
| 215 | 222 | ||
| 216 | controller.dual_color_error = ColorReadError::ReadOk; | 223 | controller.joycon_color.attribute = ColorAttributes::Ok; |
| 217 | controller.left_color.body_color = | 224 | controller.joycon_color.left.body = |
| 218 | Settings::values.players.GetValue()[controller_idx].body_color_left; | 225 | Settings::values.players.GetValue()[controller_idx].body_color_left; |
| 219 | controller.left_color.button_color = | 226 | controller.joycon_color.left.button = |
| 220 | Settings::values.players.GetValue()[controller_idx].button_color_left; | 227 | Settings::values.players.GetValue()[controller_idx].button_color_left; |
| 221 | controller.right_color.body_color = | 228 | controller.joycon_color.right.body = |
| 222 | Settings::values.players.GetValue()[controller_idx].body_color_right; | 229 | Settings::values.players.GetValue()[controller_idx].body_color_right; |
| 223 | controller.right_color.button_color = | 230 | controller.joycon_color.right.button = |
| 224 | Settings::values.players.GetValue()[controller_idx].button_color_right; | 231 | Settings::values.players.GetValue()[controller_idx].button_color_right; |
| 225 | 232 | ||
| 226 | controller.battery_level[0] = BATTERY_FULL; | 233 | // TODO: Investigate when we should report all batery types |
| 227 | controller.battery_level[1] = BATTERY_FULL; | 234 | controller.battery_level_dual = BATTERY_FULL; |
| 228 | controller.battery_level[2] = BATTERY_FULL; | 235 | controller.battery_level_left = BATTERY_FULL; |
| 236 | controller.battery_level_right = BATTERY_FULL; | ||
| 229 | 237 | ||
| 230 | SignalStyleSetChangedEvent(IndexToNPad(controller_idx)); | 238 | SignalStyleSetChangedEvent(IndexToNPad(controller_idx)); |
| 231 | } | 239 | } |
| @@ -233,8 +241,9 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { | |||
| 233 | void Controller_NPad::OnInit() { | 241 | void Controller_NPad::OnInit() { |
| 234 | auto& kernel = system.Kernel(); | 242 | auto& kernel = system.Kernel(); |
| 235 | for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { | 243 | for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { |
| 236 | styleset_changed_events[i] = Kernel::WritableEvent::CreateEventPair( | 244 | styleset_changed_events[i] = |
| 237 | kernel, fmt::format("npad:NpadStyleSetChanged_{}", i)); | 245 | Kernel::KEvent::Create(kernel, fmt::format("npad:NpadStyleSetChanged_{}", i)); |
| 246 | styleset_changed_events[i]->Initialize(); | ||
| 238 | } | 247 | } |
| 239 | 248 | ||
| 240 | if (!IsControllerActivated()) { | 249 | if (!IsControllerActivated()) { |
| @@ -249,8 +258,8 @@ void Controller_NPad::OnInit() { | |||
| 249 | style.joycon_left.Assign(1); | 258 | style.joycon_left.Assign(1); |
| 250 | style.joycon_right.Assign(1); | 259 | style.joycon_right.Assign(1); |
| 251 | style.joycon_dual.Assign(1); | 260 | style.joycon_dual.Assign(1); |
| 252 | style.pro_controller.Assign(1); | 261 | style.fullkey.Assign(1); |
| 253 | style.pokeball.Assign(1); | 262 | style.palma.Assign(1); |
| 254 | } | 263 | } |
| 255 | 264 | ||
| 256 | std::transform(Settings::values.players.GetValue().begin(), | 265 | std::transform(Settings::values.players.GetValue().begin(), |
| @@ -404,13 +413,10 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 404 | } | 413 | } |
| 405 | for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) { | 414 | for (std::size_t i = 0; i < shared_memory_entries.size(); ++i) { |
| 406 | auto& npad = shared_memory_entries[i]; | 415 | auto& npad = shared_memory_entries[i]; |
| 407 | const std::array<NPadGeneric*, 7> controller_npads{&npad.main_controller_states, | 416 | const std::array<NPadGeneric*, 7> controller_npads{ |
| 408 | &npad.handheld_states, | 417 | &npad.fullkey_states, &npad.handheld_states, &npad.joy_dual_states, |
| 409 | &npad.dual_states, | 418 | &npad.joy_left_states, &npad.joy_right_states, &npad.palma_states, |
| 410 | &npad.left_joy_states, | 419 | &npad.system_ext_states}; |
| 411 | &npad.right_joy_states, | ||
| 412 | &npad.pokeball_states, | ||
| 413 | &npad.libnx}; | ||
| 414 | 420 | ||
| 415 | for (auto* main_controller : controller_npads) { | 421 | for (auto* main_controller : controller_npads) { |
| 416 | main_controller->common.entry_count = 16; | 422 | main_controller->common.entry_count = 16; |
| @@ -440,19 +446,19 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 440 | auto& pad_state = npad_pad_states[npad_index]; | 446 | auto& pad_state = npad_pad_states[npad_index]; |
| 441 | 447 | ||
| 442 | auto& main_controller = | 448 | auto& main_controller = |
| 443 | npad.main_controller_states.npad[npad.main_controller_states.common.last_entry_index]; | 449 | npad.fullkey_states.npad[npad.fullkey_states.common.last_entry_index]; |
| 444 | auto& handheld_entry = | 450 | auto& handheld_entry = |
| 445 | npad.handheld_states.npad[npad.handheld_states.common.last_entry_index]; | 451 | npad.handheld_states.npad[npad.handheld_states.common.last_entry_index]; |
| 446 | auto& dual_entry = npad.dual_states.npad[npad.dual_states.common.last_entry_index]; | 452 | auto& dual_entry = npad.joy_dual_states.npad[npad.joy_dual_states.common.last_entry_index]; |
| 447 | auto& left_entry = npad.left_joy_states.npad[npad.left_joy_states.common.last_entry_index]; | 453 | auto& left_entry = npad.joy_left_states.npad[npad.joy_left_states.common.last_entry_index]; |
| 448 | auto& right_entry = | 454 | auto& right_entry = |
| 449 | npad.right_joy_states.npad[npad.right_joy_states.common.last_entry_index]; | 455 | npad.joy_right_states.npad[npad.joy_right_states.common.last_entry_index]; |
| 450 | auto& pokeball_entry = | 456 | auto& pokeball_entry = npad.palma_states.npad[npad.palma_states.common.last_entry_index]; |
| 451 | npad.pokeball_states.npad[npad.pokeball_states.common.last_entry_index]; | 457 | auto& libnx_entry = |
| 452 | auto& libnx_entry = npad.libnx.npad[npad.libnx.common.last_entry_index]; | 458 | npad.system_ext_states.npad[npad.system_ext_states.common.last_entry_index]; |
| 453 | 459 | ||
| 454 | libnx_entry.connection_status.raw = 0; | 460 | libnx_entry.connection_status.raw = 0; |
| 455 | libnx_entry.connection_status.IsConnected.Assign(1); | 461 | libnx_entry.connection_status.is_connected.Assign(1); |
| 456 | 462 | ||
| 457 | switch (controller_type) { | 463 | switch (controller_type) { |
| 458 | case NPadControllerType::None: | 464 | case NPadControllerType::None: |
| @@ -460,67 +466,67 @@ void Controller_NPad::OnUpdate(const Core::Timing::CoreTiming& core_timing, u8* | |||
| 460 | break; | 466 | break; |
| 461 | case NPadControllerType::ProController: | 467 | case NPadControllerType::ProController: |
| 462 | main_controller.connection_status.raw = 0; | 468 | main_controller.connection_status.raw = 0; |
| 463 | main_controller.connection_status.IsConnected.Assign(1); | 469 | main_controller.connection_status.is_connected.Assign(1); |
| 464 | main_controller.connection_status.IsWired.Assign(1); | 470 | main_controller.connection_status.is_wired.Assign(1); |
| 465 | main_controller.pad.pad_states.raw = pad_state.pad_states.raw; | 471 | main_controller.pad.pad_states.raw = pad_state.pad_states.raw; |
| 466 | main_controller.pad.l_stick = pad_state.l_stick; | 472 | main_controller.pad.l_stick = pad_state.l_stick; |
| 467 | main_controller.pad.r_stick = pad_state.r_stick; | 473 | main_controller.pad.r_stick = pad_state.r_stick; |
| 468 | 474 | ||
| 469 | libnx_entry.connection_status.IsWired.Assign(1); | 475 | libnx_entry.connection_status.is_wired.Assign(1); |
| 470 | break; | 476 | break; |
| 471 | case NPadControllerType::Handheld: | 477 | case NPadControllerType::Handheld: |
| 472 | handheld_entry.connection_status.raw = 0; | 478 | handheld_entry.connection_status.raw = 0; |
| 473 | handheld_entry.connection_status.IsConnected.Assign(1); | 479 | handheld_entry.connection_status.is_connected.Assign(1); |
| 474 | handheld_entry.connection_status.IsWired.Assign(1); | 480 | handheld_entry.connection_status.is_wired.Assign(1); |
| 475 | handheld_entry.connection_status.IsLeftJoyConnected.Assign(1); | 481 | handheld_entry.connection_status.is_left_connected.Assign(1); |
| 476 | handheld_entry.connection_status.IsRightJoyConnected.Assign(1); | 482 | handheld_entry.connection_status.is_right_connected.Assign(1); |
| 477 | handheld_entry.connection_status.IsLeftJoyWired.Assign(1); | 483 | handheld_entry.connection_status.is_left_wired.Assign(1); |
| 478 | handheld_entry.connection_status.IsRightJoyWired.Assign(1); | 484 | handheld_entry.connection_status.is_right_wired.Assign(1); |
| 479 | handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; | 485 | handheld_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 480 | handheld_entry.pad.l_stick = pad_state.l_stick; | 486 | handheld_entry.pad.l_stick = pad_state.l_stick; |
| 481 | handheld_entry.pad.r_stick = pad_state.r_stick; | 487 | handheld_entry.pad.r_stick = pad_state.r_stick; |
| 482 | 488 | ||
| 483 | libnx_entry.connection_status.IsWired.Assign(1); | 489 | libnx_entry.connection_status.is_wired.Assign(1); |
| 484 | libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); | 490 | libnx_entry.connection_status.is_left_connected.Assign(1); |
| 485 | libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | 491 | libnx_entry.connection_status.is_right_connected.Assign(1); |
| 486 | libnx_entry.connection_status.IsLeftJoyWired.Assign(1); | 492 | libnx_entry.connection_status.is_left_wired.Assign(1); |
| 487 | libnx_entry.connection_status.IsRightJoyWired.Assign(1); | 493 | libnx_entry.connection_status.is_right_wired.Assign(1); |
| 488 | break; | 494 | break; |
| 489 | case NPadControllerType::JoyDual: | 495 | case NPadControllerType::JoyDual: |
| 490 | dual_entry.connection_status.raw = 0; | 496 | dual_entry.connection_status.raw = 0; |
| 491 | dual_entry.connection_status.IsConnected.Assign(1); | 497 | dual_entry.connection_status.is_connected.Assign(1); |
| 492 | dual_entry.connection_status.IsLeftJoyConnected.Assign(1); | 498 | dual_entry.connection_status.is_left_connected.Assign(1); |
| 493 | dual_entry.connection_status.IsRightJoyConnected.Assign(1); | 499 | dual_entry.connection_status.is_right_connected.Assign(1); |
| 494 | dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; | 500 | dual_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 495 | dual_entry.pad.l_stick = pad_state.l_stick; | 501 | dual_entry.pad.l_stick = pad_state.l_stick; |
| 496 | dual_entry.pad.r_stick = pad_state.r_stick; | 502 | dual_entry.pad.r_stick = pad_state.r_stick; |
| 497 | 503 | ||
| 498 | libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); | 504 | libnx_entry.connection_status.is_left_connected.Assign(1); |
| 499 | libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | 505 | libnx_entry.connection_status.is_right_connected.Assign(1); |
| 500 | break; | 506 | break; |
| 501 | case NPadControllerType::JoyLeft: | 507 | case NPadControllerType::JoyLeft: |
| 502 | left_entry.connection_status.raw = 0; | 508 | left_entry.connection_status.raw = 0; |
| 503 | left_entry.connection_status.IsConnected.Assign(1); | 509 | left_entry.connection_status.is_connected.Assign(1); |
| 504 | left_entry.connection_status.IsLeftJoyConnected.Assign(1); | 510 | left_entry.connection_status.is_left_connected.Assign(1); |
| 505 | left_entry.pad.pad_states.raw = pad_state.pad_states.raw; | 511 | left_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 506 | left_entry.pad.l_stick = pad_state.l_stick; | 512 | left_entry.pad.l_stick = pad_state.l_stick; |
| 507 | left_entry.pad.r_stick = pad_state.r_stick; | 513 | left_entry.pad.r_stick = pad_state.r_stick; |
| 508 | 514 | ||
| 509 | libnx_entry.connection_status.IsLeftJoyConnected.Assign(1); | 515 | libnx_entry.connection_status.is_left_connected.Assign(1); |
| 510 | break; | 516 | break; |
| 511 | case NPadControllerType::JoyRight: | 517 | case NPadControllerType::JoyRight: |
| 512 | right_entry.connection_status.raw = 0; | 518 | right_entry.connection_status.raw = 0; |
| 513 | right_entry.connection_status.IsConnected.Assign(1); | 519 | right_entry.connection_status.is_connected.Assign(1); |
| 514 | right_entry.connection_status.IsRightJoyConnected.Assign(1); | 520 | right_entry.connection_status.is_right_connected.Assign(1); |
| 515 | right_entry.pad.pad_states.raw = pad_state.pad_states.raw; | 521 | right_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 516 | right_entry.pad.l_stick = pad_state.l_stick; | 522 | right_entry.pad.l_stick = pad_state.l_stick; |
| 517 | right_entry.pad.r_stick = pad_state.r_stick; | 523 | right_entry.pad.r_stick = pad_state.r_stick; |
| 518 | 524 | ||
| 519 | libnx_entry.connection_status.IsRightJoyConnected.Assign(1); | 525 | libnx_entry.connection_status.is_right_connected.Assign(1); |
| 520 | break; | 526 | break; |
| 521 | case NPadControllerType::Pokeball: | 527 | case NPadControllerType::Pokeball: |
| 522 | pokeball_entry.connection_status.raw = 0; | 528 | pokeball_entry.connection_status.raw = 0; |
| 523 | pokeball_entry.connection_status.IsConnected.Assign(1); | 529 | pokeball_entry.connection_status.is_connected.Assign(1); |
| 524 | pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; | 530 | pokeball_entry.pad.pad_states.raw = pad_state.pad_states.raw; |
| 525 | pokeball_entry.pad.l_stick = pad_state.l_stick; | 531 | pokeball_entry.pad.l_stick = pad_state.l_stick; |
| 526 | pokeball_entry.pad.r_stick = pad_state.r_stick; | 532 | pokeball_entry.pad.r_stick = pad_state.r_stick; |
| @@ -554,7 +560,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 554 | } | 560 | } |
| 555 | 561 | ||
| 556 | const std::array<SixAxisGeneric*, 6> controller_sixaxes{ | 562 | const std::array<SixAxisGeneric*, 6> controller_sixaxes{ |
| 557 | &npad.sixaxis_full, &npad.sixaxis_handheld, &npad.sixaxis_dual_left, | 563 | &npad.sixaxis_fullkey, &npad.sixaxis_handheld, &npad.sixaxis_dual_left, |
| 558 | &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right, | 564 | &npad.sixaxis_dual_right, &npad.sixaxis_left, &npad.sixaxis_right, |
| 559 | }; | 565 | }; |
| 560 | 566 | ||
| @@ -592,7 +598,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 592 | } | 598 | } |
| 593 | 599 | ||
| 594 | auto& full_sixaxis_entry = | 600 | auto& full_sixaxis_entry = |
| 595 | npad.sixaxis_full.sixaxis[npad.sixaxis_full.common.last_entry_index]; | 601 | npad.sixaxis_fullkey.sixaxis[npad.sixaxis_fullkey.common.last_entry_index]; |
| 596 | auto& handheld_sixaxis_entry = | 602 | auto& handheld_sixaxis_entry = |
| 597 | npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index]; | 603 | npad.sixaxis_handheld.sixaxis[npad.sixaxis_handheld.common.last_entry_index]; |
| 598 | auto& dual_left_sixaxis_entry = | 604 | auto& dual_left_sixaxis_entry = |
| @@ -609,7 +615,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 609 | UNREACHABLE(); | 615 | UNREACHABLE(); |
| 610 | break; | 616 | break; |
| 611 | case NPadControllerType::ProController: | 617 | case NPadControllerType::ProController: |
| 618 | full_sixaxis_entry.attribute.raw = 0; | ||
| 612 | if (sixaxis_sensors_enabled && motions[i][0]) { | 619 | if (sixaxis_sensors_enabled && motions[i][0]) { |
| 620 | full_sixaxis_entry.attribute.is_connected.Assign(1); | ||
| 613 | full_sixaxis_entry.accel = motion_devices[0].accel; | 621 | full_sixaxis_entry.accel = motion_devices[0].accel; |
| 614 | full_sixaxis_entry.gyro = motion_devices[0].gyro; | 622 | full_sixaxis_entry.gyro = motion_devices[0].gyro; |
| 615 | full_sixaxis_entry.rotation = motion_devices[0].rotation; | 623 | full_sixaxis_entry.rotation = motion_devices[0].rotation; |
| @@ -617,7 +625,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 617 | } | 625 | } |
| 618 | break; | 626 | break; |
| 619 | case NPadControllerType::Handheld: | 627 | case NPadControllerType::Handheld: |
| 628 | handheld_sixaxis_entry.attribute.raw = 0; | ||
| 620 | if (sixaxis_sensors_enabled && motions[i][0]) { | 629 | if (sixaxis_sensors_enabled && motions[i][0]) { |
| 630 | handheld_sixaxis_entry.attribute.is_connected.Assign(1); | ||
| 621 | handheld_sixaxis_entry.accel = motion_devices[0].accel; | 631 | handheld_sixaxis_entry.accel = motion_devices[0].accel; |
| 622 | handheld_sixaxis_entry.gyro = motion_devices[0].gyro; | 632 | handheld_sixaxis_entry.gyro = motion_devices[0].gyro; |
| 623 | handheld_sixaxis_entry.rotation = motion_devices[0].rotation; | 633 | handheld_sixaxis_entry.rotation = motion_devices[0].rotation; |
| @@ -625,8 +635,11 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 625 | } | 635 | } |
| 626 | break; | 636 | break; |
| 627 | case NPadControllerType::JoyDual: | 637 | case NPadControllerType::JoyDual: |
| 638 | dual_left_sixaxis_entry.attribute.raw = 0; | ||
| 639 | dual_right_sixaxis_entry.attribute.raw = 0; | ||
| 628 | if (sixaxis_sensors_enabled && motions[i][0]) { | 640 | if (sixaxis_sensors_enabled && motions[i][0]) { |
| 629 | // Set motion for the left joycon | 641 | // Set motion for the left joycon |
| 642 | dual_left_sixaxis_entry.attribute.is_connected.Assign(1); | ||
| 630 | dual_left_sixaxis_entry.accel = motion_devices[0].accel; | 643 | dual_left_sixaxis_entry.accel = motion_devices[0].accel; |
| 631 | dual_left_sixaxis_entry.gyro = motion_devices[0].gyro; | 644 | dual_left_sixaxis_entry.gyro = motion_devices[0].gyro; |
| 632 | dual_left_sixaxis_entry.rotation = motion_devices[0].rotation; | 645 | dual_left_sixaxis_entry.rotation = motion_devices[0].rotation; |
| @@ -634,6 +647,7 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 634 | } | 647 | } |
| 635 | if (sixaxis_sensors_enabled && motions[i][1]) { | 648 | if (sixaxis_sensors_enabled && motions[i][1]) { |
| 636 | // Set motion for the right joycon | 649 | // Set motion for the right joycon |
| 650 | dual_right_sixaxis_entry.attribute.is_connected.Assign(1); | ||
| 637 | dual_right_sixaxis_entry.accel = motion_devices[1].accel; | 651 | dual_right_sixaxis_entry.accel = motion_devices[1].accel; |
| 638 | dual_right_sixaxis_entry.gyro = motion_devices[1].gyro; | 652 | dual_right_sixaxis_entry.gyro = motion_devices[1].gyro; |
| 639 | dual_right_sixaxis_entry.rotation = motion_devices[1].rotation; | 653 | dual_right_sixaxis_entry.rotation = motion_devices[1].rotation; |
| @@ -641,7 +655,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 641 | } | 655 | } |
| 642 | break; | 656 | break; |
| 643 | case NPadControllerType::JoyLeft: | 657 | case NPadControllerType::JoyLeft: |
| 658 | left_sixaxis_entry.attribute.raw = 0; | ||
| 644 | if (sixaxis_sensors_enabled && motions[i][0]) { | 659 | if (sixaxis_sensors_enabled && motions[i][0]) { |
| 660 | left_sixaxis_entry.attribute.is_connected.Assign(1); | ||
| 645 | left_sixaxis_entry.accel = motion_devices[0].accel; | 661 | left_sixaxis_entry.accel = motion_devices[0].accel; |
| 646 | left_sixaxis_entry.gyro = motion_devices[0].gyro; | 662 | left_sixaxis_entry.gyro = motion_devices[0].gyro; |
| 647 | left_sixaxis_entry.rotation = motion_devices[0].rotation; | 663 | left_sixaxis_entry.rotation = motion_devices[0].rotation; |
| @@ -649,7 +665,9 @@ void Controller_NPad::OnMotionUpdate(const Core::Timing::CoreTiming& core_timing | |||
| 649 | } | 665 | } |
| 650 | break; | 666 | break; |
| 651 | case NPadControllerType::JoyRight: | 667 | case NPadControllerType::JoyRight: |
| 668 | right_sixaxis_entry.attribute.raw = 0; | ||
| 652 | if (sixaxis_sensors_enabled && motions[i][1]) { | 669 | if (sixaxis_sensors_enabled && motions[i][1]) { |
| 670 | right_sixaxis_entry.attribute.is_connected.Assign(1); | ||
| 653 | right_sixaxis_entry.accel = motion_devices[1].accel; | 671 | right_sixaxis_entry.accel = motion_devices[1].accel; |
| 654 | right_sixaxis_entry.gyro = motion_devices[1].gyro; | 672 | right_sixaxis_entry.gyro = motion_devices[1].gyro; |
| 655 | right_sixaxis_entry.rotation = motion_devices[1].rotation; | 673 | right_sixaxis_entry.rotation = motion_devices[1].rotation; |
| @@ -715,8 +733,8 @@ Controller_NPad::NpadCommunicationMode Controller_NPad::GetNpadCommunicationMode | |||
| 715 | void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) { | 733 | void Controller_NPad::SetNpadMode(u32 npad_id, NpadAssignments assignment_mode) { |
| 716 | const std::size_t npad_index = NPadIdToIndex(npad_id); | 734 | const std::size_t npad_index = NPadIdToIndex(npad_id); |
| 717 | ASSERT(npad_index < shared_memory_entries.size()); | 735 | ASSERT(npad_index < shared_memory_entries.size()); |
| 718 | if (shared_memory_entries[npad_index].pad_assignment != assignment_mode) { | 736 | if (shared_memory_entries[npad_index].assignment_mode != assignment_mode) { |
| 719 | shared_memory_entries[npad_index].pad_assignment = assignment_mode; | 737 | shared_memory_entries[npad_index].assignment_mode = assignment_mode; |
| 720 | } | 738 | } |
| 721 | } | 739 | } |
| 722 | 740 | ||
| @@ -872,13 +890,14 @@ bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_dev | |||
| 872 | return vibration_devices_mounted[npad_index][device_index]; | 890 | return vibration_devices_mounted[npad_index][device_index]; |
| 873 | } | 891 | } |
| 874 | 892 | ||
| 875 | std::shared_ptr<Kernel::ReadableEvent> Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) const { | 893 | std::shared_ptr<Kernel::KReadableEvent> Controller_NPad::GetStyleSetChangedEvent( |
| 894 | u32 npad_id) const { | ||
| 876 | const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)]; | 895 | const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)]; |
| 877 | return styleset_event.readable; | 896 | return styleset_event->GetReadableEvent(); |
| 878 | } | 897 | } |
| 879 | 898 | ||
| 880 | void Controller_NPad::SignalStyleSetChangedEvent(u32 npad_id) const { | 899 | void Controller_NPad::SignalStyleSetChangedEvent(u32 npad_id) const { |
| 881 | styleset_changed_events[NPadIdToIndex(npad_id)].writable->Signal(); | 900 | styleset_changed_events[NPadIdToIndex(npad_id)]->GetWritableEvent()->Signal(); |
| 882 | } | 901 | } |
| 883 | 902 | ||
| 884 | void Controller_NPad::AddNewControllerAt(NPadControllerType controller, std::size_t npad_index) { | 903 | void Controller_NPad::AddNewControllerAt(NPadControllerType controller, std::size_t npad_index) { |
| @@ -923,9 +942,17 @@ void Controller_NPad::DisconnectNpadAtIndex(std::size_t npad_index) { | |||
| 923 | connected_controllers[npad_index].is_connected = false; | 942 | connected_controllers[npad_index].is_connected = false; |
| 924 | 943 | ||
| 925 | auto& controller = shared_memory_entries[npad_index]; | 944 | auto& controller = shared_memory_entries[npad_index]; |
| 926 | controller.joy_styles.raw = 0; // Zero out | 945 | controller.style_set.raw = 0; // Zero out |
| 927 | controller.device_type.raw = 0; | 946 | controller.device_type.raw = 0; |
| 928 | controller.properties.raw = 0; | 947 | controller.system_properties.raw = 0; |
| 948 | controller.button_properties.raw = 0; | ||
| 949 | controller.battery_level_dual = 0; | ||
| 950 | controller.battery_level_left = 0; | ||
| 951 | controller.battery_level_right = 0; | ||
| 952 | controller.fullkey_color = {}; | ||
| 953 | controller.joycon_color = {}; | ||
| 954 | controller.assignment_mode = NpadAssignments::Dual; | ||
| 955 | controller.footer_type = AppletFooterUiType::None; | ||
| 929 | 956 | ||
| 930 | SignalStyleSetChangedEvent(IndexToNPad(npad_index)); | 957 | SignalStyleSetChangedEvent(IndexToNPad(npad_index)); |
| 931 | } | 958 | } |
| @@ -1101,7 +1128,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const | |||
| 1101 | [](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) { | 1128 | [](u32 npad_id) { return npad_id <= MAX_NPAD_ID; })) { |
| 1102 | switch (controller) { | 1129 | switch (controller) { |
| 1103 | case NPadControllerType::ProController: | 1130 | case NPadControllerType::ProController: |
| 1104 | return style.pro_controller; | 1131 | return style.fullkey; |
| 1105 | case NPadControllerType::JoyDual: | 1132 | case NPadControllerType::JoyDual: |
| 1106 | return style.joycon_dual; | 1133 | return style.joycon_dual; |
| 1107 | case NPadControllerType::JoyLeft: | 1134 | case NPadControllerType::JoyLeft: |
| @@ -1109,7 +1136,7 @@ bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const | |||
| 1109 | case NPadControllerType::JoyRight: | 1136 | case NPadControllerType::JoyRight: |
| 1110 | return style.joycon_right; | 1137 | return style.joycon_right; |
| 1111 | case NPadControllerType::Pokeball: | 1138 | case NPadControllerType::Pokeball: |
| 1112 | return style.pokeball; | 1139 | return style.palma; |
| 1113 | default: | 1140 | default: |
| 1114 | return false; | 1141 | return false; |
| 1115 | } | 1142 | } |
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 2e13922b9..48bab988c 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h | |||
| @@ -10,10 +10,14 @@ | |||
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/frontend/input.h" | 11 | #include "core/frontend/input.h" |
| 12 | #include "core/hle/kernel/object.h" | 12 | #include "core/hle/kernel/object.h" |
| 13 | #include "core/hle/kernel/writable_event.h" | ||
| 14 | #include "core/hle/service/hid/controllers/controller_base.h" | 13 | #include "core/hle/service/hid/controllers/controller_base.h" |
| 15 | #include "core/settings.h" | 14 | #include "core/settings.h" |
| 16 | 15 | ||
| 16 | namespace Kernel { | ||
| 17 | class KEvent; | ||
| 18 | class KReadableEvent; | ||
| 19 | } // namespace Kernel | ||
| 20 | |||
| 17 | namespace Service::HID { | 21 | namespace Service::HID { |
| 18 | 22 | ||
| 19 | constexpr u32 NPAD_HANDHELD = 32; | 23 | constexpr u32 NPAD_HANDHELD = 32; |
| @@ -90,10 +94,10 @@ public: | |||
| 90 | }; | 94 | }; |
| 91 | 95 | ||
| 92 | enum class NpadCommunicationMode : u64 { | 96 | enum class NpadCommunicationMode : u64 { |
| 93 | Unknown0 = 0, | 97 | Mode_5ms = 0, |
| 94 | Unknown1 = 1, | 98 | Mode_10ms = 1, |
| 95 | Unknown2 = 2, | 99 | Mode_15ms = 2, |
| 96 | Unknown3 = 3, | 100 | Default = 3, |
| 97 | }; | 101 | }; |
| 98 | 102 | ||
| 99 | struct DeviceHandle { | 103 | struct DeviceHandle { |
| @@ -108,13 +112,18 @@ public: | |||
| 108 | union { | 112 | union { |
| 109 | u32_le raw{}; | 113 | u32_le raw{}; |
| 110 | 114 | ||
| 111 | BitField<0, 1, u32> pro_controller; | 115 | BitField<0, 1, u32> fullkey; |
| 112 | BitField<1, 1, u32> handheld; | 116 | BitField<1, 1, u32> handheld; |
| 113 | BitField<2, 1, u32> joycon_dual; | 117 | BitField<2, 1, u32> joycon_dual; |
| 114 | BitField<3, 1, u32> joycon_left; | 118 | BitField<3, 1, u32> joycon_left; |
| 115 | BitField<4, 1, u32> joycon_right; | 119 | BitField<4, 1, u32> joycon_right; |
| 116 | 120 | BitField<5, 1, u32> gamecube; | |
| 117 | BitField<6, 1, u32> pokeball; // TODO(ogniK): Confirm when possible | 121 | BitField<6, 1, u32> palma; |
| 122 | BitField<7, 1, u32> lark; | ||
| 123 | BitField<8, 1, u32> handheld_lark; | ||
| 124 | BitField<9, 1, u32> lucia; | ||
| 125 | BitField<29, 1, u32> system_ext; | ||
| 126 | BitField<30, 1, u32> system; | ||
| 118 | }; | 127 | }; |
| 119 | }; | 128 | }; |
| 120 | static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size"); | 129 | static_assert(sizeof(NpadStyleSet) == 4, "NpadStyleSet is an invalid size"); |
| @@ -187,7 +196,7 @@ public: | |||
| 187 | 196 | ||
| 188 | bool IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const; | 197 | bool IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const; |
| 189 | 198 | ||
| 190 | std::shared_ptr<Kernel::ReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const; | 199 | std::shared_ptr<Kernel::KReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const; |
| 191 | void SignalStyleSetChangedEvent(u32 npad_id) const; | 200 | void SignalStyleSetChangedEvent(u32 npad_id) const; |
| 192 | 201 | ||
| 193 | // Adds a new controller at an index. | 202 | // Adds a new controller at an index. |
| @@ -238,12 +247,32 @@ private: | |||
| 238 | }; | 247 | }; |
| 239 | static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); | 248 | static_assert(sizeof(CommonHeader) == 0x20, "CommonHeader is an invalid size"); |
| 240 | 249 | ||
| 250 | enum class ColorAttributes : u32_le { | ||
| 251 | Ok = 0, | ||
| 252 | ReadError = 1, | ||
| 253 | NoController = 2, | ||
| 254 | }; | ||
| 255 | static_assert(sizeof(ColorAttributes) == 4, "ColorAttributes is an invalid size"); | ||
| 256 | |||
| 241 | struct ControllerColor { | 257 | struct ControllerColor { |
| 242 | u32_le body_color; | 258 | u32_le body; |
| 243 | u32_le button_color; | 259 | u32_le button; |
| 244 | }; | 260 | }; |
| 245 | static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size"); | 261 | static_assert(sizeof(ControllerColor) == 8, "ControllerColor is an invalid size"); |
| 246 | 262 | ||
| 263 | struct FullKeyColor { | ||
| 264 | ColorAttributes attribute; | ||
| 265 | ControllerColor fullkey; | ||
| 266 | }; | ||
| 267 | static_assert(sizeof(FullKeyColor) == 0xC, "FullKeyColor is an invalid size"); | ||
| 268 | |||
| 269 | struct JoyconColor { | ||
| 270 | ColorAttributes attribute; | ||
| 271 | ControllerColor left; | ||
| 272 | ControllerColor right; | ||
| 273 | }; | ||
| 274 | static_assert(sizeof(JoyconColor) == 0x14, "JoyconColor is an invalid size"); | ||
| 275 | |||
| 247 | struct ControllerPadState { | 276 | struct ControllerPadState { |
| 248 | union { | 277 | union { |
| 249 | u64_le raw{}; | 278 | u64_le raw{}; |
| @@ -285,6 +314,9 @@ private: | |||
| 285 | 314 | ||
| 286 | BitField<26, 1, u64> right_sl; | 315 | BitField<26, 1, u64> right_sl; |
| 287 | BitField<27, 1, u64> right_sr; | 316 | BitField<27, 1, u64> right_sr; |
| 317 | |||
| 318 | BitField<28, 1, u64> palma; | ||
| 319 | BitField<30, 1, u64> handheld_left_b; | ||
| 288 | }; | 320 | }; |
| 289 | }; | 321 | }; |
| 290 | static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size"); | 322 | static_assert(sizeof(ControllerPadState) == 8, "ControllerPadState is an invalid size"); |
| @@ -298,12 +330,12 @@ private: | |||
| 298 | struct ConnectionState { | 330 | struct ConnectionState { |
| 299 | union { | 331 | union { |
| 300 | u32_le raw{}; | 332 | u32_le raw{}; |
| 301 | BitField<0, 1, u32> IsConnected; | 333 | BitField<0, 1, u32> is_connected; |
| 302 | BitField<1, 1, u32> IsWired; | 334 | BitField<1, 1, u32> is_wired; |
| 303 | BitField<2, 1, u32> IsLeftJoyConnected; | 335 | BitField<2, 1, u32> is_left_connected; |
| 304 | BitField<3, 1, u32> IsLeftJoyWired; | 336 | BitField<3, 1, u32> is_left_wired; |
| 305 | BitField<4, 1, u32> IsRightJoyConnected; | 337 | BitField<4, 1, u32> is_right_connected; |
| 306 | BitField<5, 1, u32> IsRightJoyWired; | 338 | BitField<5, 1, u32> is_right_wired; |
| 307 | }; | 339 | }; |
| 308 | }; | 340 | }; |
| 309 | static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); | 341 | static_assert(sizeof(ConnectionState) == 4, "ConnectionState is an invalid size"); |
| @@ -329,6 +361,15 @@ private: | |||
| 329 | }; | 361 | }; |
| 330 | static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size"); | 362 | static_assert(sizeof(NPadGeneric) == 0x350, "NPadGeneric is an invalid size"); |
| 331 | 363 | ||
| 364 | struct SixAxisAttributes { | ||
| 365 | union { | ||
| 366 | u32_le raw{}; | ||
| 367 | BitField<0, 1, u32> is_connected; | ||
| 368 | BitField<1, 1, u32> is_interpolated; | ||
| 369 | }; | ||
| 370 | }; | ||
| 371 | static_assert(sizeof(SixAxisAttributes) == 4, "SixAxisAttributes is an invalid size"); | ||
| 372 | |||
| 332 | struct SixAxisStates { | 373 | struct SixAxisStates { |
| 333 | s64_le timestamp{}; | 374 | s64_le timestamp{}; |
| 334 | INSERT_PADDING_WORDS(2); | 375 | INSERT_PADDING_WORDS(2); |
| @@ -337,7 +378,8 @@ private: | |||
| 337 | Common::Vec3f gyro{}; | 378 | Common::Vec3f gyro{}; |
| 338 | Common::Vec3f rotation{}; | 379 | Common::Vec3f rotation{}; |
| 339 | std::array<Common::Vec3f, 3> orientation{}; | 380 | std::array<Common::Vec3f, 3> orientation{}; |
| 340 | s64_le always_one{1}; | 381 | SixAxisAttributes attribute; |
| 382 | INSERT_PADDING_BYTES(4); // Reserved | ||
| 341 | }; | 383 | }; |
| 342 | static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size"); | 384 | static_assert(sizeof(SixAxisStates) == 0x68, "SixAxisStates is an invalid size"); |
| 343 | 385 | ||
| @@ -347,32 +389,54 @@ private: | |||
| 347 | }; | 389 | }; |
| 348 | static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size"); | 390 | static_assert(sizeof(SixAxisGeneric) == 0x708, "SixAxisGeneric is an invalid size"); |
| 349 | 391 | ||
| 350 | enum class ColorReadError : u32_le { | 392 | struct NPadSystemProperties { |
| 351 | ReadOk = 0, | ||
| 352 | ColorDoesntExist = 1, | ||
| 353 | NoController = 2, | ||
| 354 | }; | ||
| 355 | |||
| 356 | struct NPadProperties { | ||
| 357 | union { | 393 | union { |
| 358 | s64_le raw{}; | 394 | s64_le raw{}; |
| 395 | BitField<0, 1, s64> is_charging_joy_dual; | ||
| 396 | BitField<1, 1, s64> is_charging_joy_left; | ||
| 397 | BitField<2, 1, s64> is_charging_joy_right; | ||
| 398 | BitField<3, 1, s64> is_powered_joy_dual; | ||
| 399 | BitField<4, 1, s64> is_powered_joy_left; | ||
| 400 | BitField<5, 1, s64> is_powered_joy_right; | ||
| 401 | BitField<9, 1, s64> is_system_unsupported_button; | ||
| 402 | BitField<10, 1, s64> is_system_ext_unsupported_button; | ||
| 359 | BitField<11, 1, s64> is_vertical; | 403 | BitField<11, 1, s64> is_vertical; |
| 360 | BitField<12, 1, s64> is_horizontal; | 404 | BitField<12, 1, s64> is_horizontal; |
| 361 | BitField<13, 1, s64> use_plus; | 405 | BitField<13, 1, s64> use_plus; |
| 362 | BitField<14, 1, s64> use_minus; | 406 | BitField<14, 1, s64> use_minus; |
| 407 | BitField<15, 1, s64> use_directional_buttons; | ||
| 408 | }; | ||
| 409 | }; | ||
| 410 | static_assert(sizeof(NPadSystemProperties) == 0x8, "NPadSystemProperties is an invalid size"); | ||
| 411 | |||
| 412 | struct NPadButtonProperties { | ||
| 413 | union { | ||
| 414 | s32_le raw{}; | ||
| 415 | BitField<0, 1, s32> is_home_button_protection_enabled; | ||
| 363 | }; | 416 | }; |
| 364 | }; | 417 | }; |
| 418 | static_assert(sizeof(NPadButtonProperties) == 0x4, "NPadButtonProperties is an invalid size"); | ||
| 365 | 419 | ||
| 366 | struct NPadDevice { | 420 | struct NPadDevice { |
| 367 | union { | 421 | union { |
| 368 | u32_le raw{}; | 422 | u32_le raw{}; |
| 369 | BitField<0, 1, s32> pro_controller; | 423 | BitField<0, 1, s32> fullkey; |
| 370 | BitField<1, 1, s32> handheld; | 424 | BitField<1, 1, s32> debug_pad; |
| 371 | BitField<2, 1, s32> handheld_left; | 425 | BitField<2, 1, s32> handheld_left; |
| 372 | BitField<3, 1, s32> handheld_right; | 426 | BitField<3, 1, s32> handheld_right; |
| 373 | BitField<4, 1, s32> joycon_left; | 427 | BitField<4, 1, s32> joycon_left; |
| 374 | BitField<5, 1, s32> joycon_right; | 428 | BitField<5, 1, s32> joycon_right; |
| 375 | BitField<6, 1, s32> pokeball; | 429 | BitField<6, 1, s32> palma; |
| 430 | BitField<7, 1, s32> lark_hvc_left; | ||
| 431 | BitField<8, 1, s32> lark_hvc_right; | ||
| 432 | BitField<9, 1, s32> lark_nes_left; | ||
| 433 | BitField<10, 1, s32> lark_nes_right; | ||
| 434 | BitField<11, 1, s32> handheld_lark_hvc_left; | ||
| 435 | BitField<12, 1, s32> handheld_lark_hvc_right; | ||
| 436 | BitField<13, 1, s32> handheld_lark_nes_left; | ||
| 437 | BitField<14, 1, s32> handheld_lark_nes_right; | ||
| 438 | BitField<15, 1, s32> lucia; | ||
| 439 | BitField<31, 1, s32> system; | ||
| 376 | }; | 440 | }; |
| 377 | }; | 441 | }; |
| 378 | 442 | ||
| @@ -383,37 +447,69 @@ private: | |||
| 383 | std::array<Common::Vec3f, 3> orientation; | 447 | std::array<Common::Vec3f, 3> orientation; |
| 384 | }; | 448 | }; |
| 385 | 449 | ||
| 386 | struct NPadEntry { | 450 | struct NfcXcdHandle { |
| 387 | NpadStyleSet joy_styles; | 451 | INSERT_PADDING_BYTES(0x60); |
| 388 | NpadAssignments pad_assignment; | 452 | }; |
| 389 | 453 | ||
| 390 | ColorReadError single_color_error; | 454 | struct AppletFooterUiAttributes { |
| 391 | ControllerColor single_color; | 455 | INSERT_PADDING_BYTES(0x4); |
| 456 | }; | ||
| 392 | 457 | ||
| 393 | ColorReadError dual_color_error; | 458 | enum class AppletFooterUiType : u8 { |
| 394 | ControllerColor left_color; | 459 | None = 0, |
| 395 | ControllerColor right_color; | 460 | HandheldNone = 1, |
| 461 | HandheldJoyConLeftOnly = 1, | ||
| 462 | HandheldJoyConRightOnly = 3, | ||
| 463 | HandheldJoyConLeftJoyConRight = 4, | ||
| 464 | JoyDual = 5, | ||
| 465 | JoyDualLeftOnly = 6, | ||
| 466 | JoyDualRightOnly = 7, | ||
| 467 | JoyLeftHorizontal = 8, | ||
| 468 | JoyLeftVertical = 9, | ||
| 469 | JoyRightHorizontal = 10, | ||
| 470 | JoyRightVertical = 11, | ||
| 471 | SwitchProController = 12, | ||
| 472 | CompatibleProController = 13, | ||
| 473 | CompatibleJoyCon = 14, | ||
| 474 | LarkHvc1 = 15, | ||
| 475 | LarkHvc2 = 16, | ||
| 476 | LarkNesLeft = 17, | ||
| 477 | LarkNesRight = 18, | ||
| 478 | Lucia = 19, | ||
| 479 | Verification = 20, | ||
| 480 | }; | ||
| 481 | |||
| 482 | struct NPadEntry { | ||
| 483 | NpadStyleSet style_set; | ||
| 484 | NpadAssignments assignment_mode; | ||
| 485 | FullKeyColor fullkey_color; | ||
| 486 | JoyconColor joycon_color; | ||
| 396 | 487 | ||
| 397 | NPadGeneric main_controller_states; | 488 | NPadGeneric fullkey_states; |
| 398 | NPadGeneric handheld_states; | 489 | NPadGeneric handheld_states; |
| 399 | NPadGeneric dual_states; | 490 | NPadGeneric joy_dual_states; |
| 400 | NPadGeneric left_joy_states; | 491 | NPadGeneric joy_left_states; |
| 401 | NPadGeneric right_joy_states; | 492 | NPadGeneric joy_right_states; |
| 402 | NPadGeneric pokeball_states; | 493 | NPadGeneric palma_states; |
| 403 | NPadGeneric libnx; // TODO(ogniK): Find out what this actually is, libnx seems to only be | 494 | NPadGeneric system_ext_states; |
| 404 | // relying on this for the time being | 495 | SixAxisGeneric sixaxis_fullkey; |
| 405 | SixAxisGeneric sixaxis_full; | ||
| 406 | SixAxisGeneric sixaxis_handheld; | 496 | SixAxisGeneric sixaxis_handheld; |
| 407 | SixAxisGeneric sixaxis_dual_left; | 497 | SixAxisGeneric sixaxis_dual_left; |
| 408 | SixAxisGeneric sixaxis_dual_right; | 498 | SixAxisGeneric sixaxis_dual_right; |
| 409 | SixAxisGeneric sixaxis_left; | 499 | SixAxisGeneric sixaxis_left; |
| 410 | SixAxisGeneric sixaxis_right; | 500 | SixAxisGeneric sixaxis_right; |
| 411 | NPadDevice device_type; | 501 | NPadDevice device_type; |
| 412 | NPadProperties properties; | 502 | INSERT_PADDING_BYTES(0x4); // reserved |
| 413 | INSERT_PADDING_WORDS(1); | 503 | NPadSystemProperties system_properties; |
| 414 | std::array<u32, 3> battery_level; | 504 | NPadButtonProperties button_properties; |
| 415 | INSERT_PADDING_BYTES(0x5c); | 505 | u32 battery_level_dual; |
| 416 | INSERT_PADDING_BYTES(0xdf8); | 506 | u32 battery_level_left; |
| 507 | u32 battery_level_right; | ||
| 508 | AppletFooterUiAttributes footer_attributes; | ||
| 509 | AppletFooterUiType footer_type; | ||
| 510 | // nfc_states needs to be checked switchbrew does not match with HW | ||
| 511 | NfcXcdHandle nfc_states; | ||
| 512 | INSERT_PADDING_BYTES(0xdef); | ||
| 417 | }; | 513 | }; |
| 418 | static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); | 514 | static_assert(sizeof(NPadEntry) == 0x5000, "NPadEntry is an invalid size"); |
| 419 | 515 | ||
| @@ -449,10 +545,9 @@ private: | |||
| 449 | std::vector<u32> supported_npad_id_types{}; | 545 | std::vector<u32> supported_npad_id_types{}; |
| 450 | NpadHoldType hold_type{NpadHoldType::Vertical}; | 546 | NpadHoldType hold_type{NpadHoldType::Vertical}; |
| 451 | NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; | 547 | NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; |
| 452 | // NpadCommunicationMode is unknown, default value is 1 | 548 | NpadCommunicationMode communication_mode{NpadCommunicationMode::Default}; |
| 453 | NpadCommunicationMode communication_mode{NpadCommunicationMode::Unknown1}; | ||
| 454 | // Each controller should have their own styleset changed event | 549 | // Each controller should have their own styleset changed event |
| 455 | std::array<Kernel::EventPair, 10> styleset_changed_events; | 550 | std::array<std::shared_ptr<Kernel::KEvent>, 10> styleset_changed_events; |
| 456 | std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints; | 551 | std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints; |
| 457 | std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{}; | 552 | std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{}; |
| 458 | bool permit_vibration_session_enabled{false}; | 553 | bool permit_vibration_session_enabled{false}; |
diff --git a/src/core/hle/service/hid/controllers/xpad.h b/src/core/hle/service/hid/controllers/xpad.h index ad229787c..5b59961bd 100644 --- a/src/core/hle/service/hid/controllers/xpad.h +++ b/src/core/hle/service/hid/controllers/xpad.h | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "common/bit_field.h" | ||
| 7 | #include "common/common_funcs.h" | 8 | #include "common/common_funcs.h" |
| 8 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 9 | #include "common/swap.h" | 10 | #include "common/swap.h" |
| @@ -28,6 +29,67 @@ public: | |||
| 28 | void OnLoadInputDevices() override; | 29 | void OnLoadInputDevices() override; |
| 29 | 30 | ||
| 30 | private: | 31 | private: |
| 32 | struct Attributes { | ||
| 33 | union { | ||
| 34 | u32_le raw{}; | ||
| 35 | BitField<0, 1, u32> is_connected; | ||
| 36 | BitField<1, 1, u32> is_wired; | ||
| 37 | BitField<2, 1, u32> is_left_connected; | ||
| 38 | BitField<3, 1, u32> is_left_wired; | ||
| 39 | BitField<4, 1, u32> is_right_connected; | ||
| 40 | BitField<5, 1, u32> is_right_wired; | ||
| 41 | }; | ||
| 42 | }; | ||
| 43 | static_assert(sizeof(Attributes) == 4, "Attributes is an invalid size"); | ||
| 44 | |||
| 45 | struct Buttons { | ||
| 46 | union { | ||
| 47 | u32_le raw{}; | ||
| 48 | // Button states | ||
| 49 | BitField<0, 1, u32> a; | ||
| 50 | BitField<1, 1, u32> b; | ||
| 51 | BitField<2, 1, u32> x; | ||
| 52 | BitField<3, 1, u32> y; | ||
| 53 | BitField<4, 1, u32> l_stick; | ||
| 54 | BitField<5, 1, u32> r_stick; | ||
| 55 | BitField<6, 1, u32> l; | ||
| 56 | BitField<7, 1, u32> r; | ||
| 57 | BitField<8, 1, u32> zl; | ||
| 58 | BitField<9, 1, u32> zr; | ||
| 59 | BitField<10, 1, u32> plus; | ||
| 60 | BitField<11, 1, u32> minus; | ||
| 61 | |||
| 62 | // D-Pad | ||
| 63 | BitField<12, 1, u32> d_left; | ||
| 64 | BitField<13, 1, u32> d_up; | ||
| 65 | BitField<14, 1, u32> d_right; | ||
| 66 | BitField<15, 1, u32> d_down; | ||
| 67 | |||
| 68 | // Left JoyStick | ||
| 69 | BitField<16, 1, u32> l_stick_left; | ||
| 70 | BitField<17, 1, u32> l_stick_up; | ||
| 71 | BitField<18, 1, u32> l_stick_right; | ||
| 72 | BitField<19, 1, u32> l_stick_down; | ||
| 73 | |||
| 74 | // Right JoyStick | ||
| 75 | BitField<20, 1, u32> r_stick_left; | ||
| 76 | BitField<21, 1, u32> r_stick_up; | ||
| 77 | BitField<22, 1, u32> r_stick_right; | ||
| 78 | BitField<23, 1, u32> r_stick_down; | ||
| 79 | |||
| 80 | // Not always active? | ||
| 81 | BitField<24, 1, u32> left_sl; | ||
| 82 | BitField<25, 1, u32> left_sr; | ||
| 83 | |||
| 84 | BitField<26, 1, u32> right_sl; | ||
| 85 | BitField<27, 1, u32> right_sr; | ||
| 86 | |||
| 87 | BitField<28, 1, u32> palma; | ||
| 88 | BitField<30, 1, u32> handheld_left_b; | ||
| 89 | }; | ||
| 90 | }; | ||
| 91 | static_assert(sizeof(Buttons) == 4, "Buttons is an invalid size"); | ||
| 92 | |||
| 31 | struct AnalogStick { | 93 | struct AnalogStick { |
| 32 | s32_le x; | 94 | s32_le x; |
| 33 | s32_le y; | 95 | s32_le y; |
| @@ -37,10 +99,10 @@ private: | |||
| 37 | struct XPadState { | 99 | struct XPadState { |
| 38 | s64_le sampling_number; | 100 | s64_le sampling_number; |
| 39 | s64_le sampling_number2; | 101 | s64_le sampling_number2; |
| 40 | s32_le attributes; | 102 | Attributes attributes; |
| 41 | u32_le pad_states; | 103 | Buttons pad_states; |
| 42 | AnalogStick x_stick; | 104 | AnalogStick l_stick; |
| 43 | AnalogStick y_stick; | 105 | AnalogStick r_stick; |
| 44 | }; | 106 | }; |
| 45 | static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size"); | 107 | static_assert(sizeof(XPadState) == 0x28, "XPadState is an invalid size"); |
| 46 | 108 | ||
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 5efc1237e..51a010a55 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -14,10 +14,10 @@ | |||
| 14 | #include "core/hle/ipc_helpers.h" | 14 | #include "core/hle/ipc_helpers.h" |
| 15 | #include "core/hle/kernel/client_port.h" | 15 | #include "core/hle/kernel/client_port.h" |
| 16 | #include "core/hle/kernel/client_session.h" | 16 | #include "core/hle/kernel/client_session.h" |
| 17 | #include "core/hle/kernel/k_readable_event.h" | ||
| 18 | #include "core/hle/kernel/k_writable_event.h" | ||
| 17 | #include "core/hle/kernel/kernel.h" | 19 | #include "core/hle/kernel/kernel.h" |
| 18 | #include "core/hle/kernel/readable_event.h" | ||
| 19 | #include "core/hle/kernel/shared_memory.h" | 20 | #include "core/hle/kernel/shared_memory.h" |
| 20 | #include "core/hle/kernel/writable_event.h" | ||
| 21 | #include "core/hle/service/hid/errors.h" | 21 | #include "core/hle/service/hid/errors.h" |
| 22 | #include "core/hle/service/hid/hid.h" | 22 | #include "core/hle/service/hid/hid.h" |
| 23 | #include "core/hle/service/hid/irs.h" | 23 | #include "core/hle/service/hid/irs.h" |
| @@ -59,20 +59,26 @@ IAppletResource::IAppletResource(Core::System& system_) | |||
| 59 | MakeController<Controller_Mouse>(HidController::Mouse); | 59 | MakeController<Controller_Mouse>(HidController::Mouse); |
| 60 | MakeController<Controller_Keyboard>(HidController::Keyboard); | 60 | MakeController<Controller_Keyboard>(HidController::Keyboard); |
| 61 | MakeController<Controller_XPad>(HidController::XPad); | 61 | MakeController<Controller_XPad>(HidController::XPad); |
| 62 | MakeController<Controller_Stubbed>(HidController::Unknown1); | 62 | MakeController<Controller_Stubbed>(HidController::HomeButton); |
| 63 | MakeController<Controller_Stubbed>(HidController::Unknown2); | 63 | MakeController<Controller_Stubbed>(HidController::SleepButton); |
| 64 | MakeController<Controller_Stubbed>(HidController::Unknown3); | 64 | MakeController<Controller_Stubbed>(HidController::CaptureButton); |
| 65 | MakeController<Controller_Stubbed>(HidController::SixAxisSensor); | 65 | MakeController<Controller_Stubbed>(HidController::InputDetector); |
| 66 | MakeController<Controller_Stubbed>(HidController::UniquePad); | ||
| 66 | MakeController<Controller_NPad>(HidController::NPad); | 67 | MakeController<Controller_NPad>(HidController::NPad); |
| 67 | MakeController<Controller_Gesture>(HidController::Gesture); | 68 | MakeController<Controller_Gesture>(HidController::Gesture); |
| 69 | MakeController<Controller_Stubbed>(HidController::ConsoleSixAxisSensor); | ||
| 68 | 70 | ||
| 69 | // Homebrew doesn't try to activate some controllers, so we activate them by default | 71 | // Homebrew doesn't try to activate some controllers, so we activate them by default |
| 70 | GetController<Controller_NPad>(HidController::NPad).ActivateController(); | 72 | GetController<Controller_NPad>(HidController::NPad).ActivateController(); |
| 71 | GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController(); | 73 | GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController(); |
| 72 | 74 | ||
| 73 | GetController<Controller_Stubbed>(HidController::Unknown1).SetCommonHeaderOffset(0x4c00); | 75 | GetController<Controller_Stubbed>(HidController::HomeButton).SetCommonHeaderOffset(0x4C00); |
| 74 | GetController<Controller_Stubbed>(HidController::Unknown2).SetCommonHeaderOffset(0x4e00); | 76 | GetController<Controller_Stubbed>(HidController::SleepButton).SetCommonHeaderOffset(0x4E00); |
| 75 | GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000); | 77 | GetController<Controller_Stubbed>(HidController::CaptureButton).SetCommonHeaderOffset(0x5000); |
| 78 | GetController<Controller_Stubbed>(HidController::InputDetector).SetCommonHeaderOffset(0x5200); | ||
| 79 | GetController<Controller_Stubbed>(HidController::UniquePad).SetCommonHeaderOffset(0x5A00); | ||
| 80 | GetController<Controller_Stubbed>(HidController::ConsoleSixAxisSensor) | ||
| 81 | .SetCommonHeaderOffset(0x3C200); | ||
| 76 | 82 | ||
| 77 | // Register update callbacks | 83 | // Register update callbacks |
| 78 | pad_update_event = Core::Timing::CreateEvent( | 84 | pad_update_event = Core::Timing::CreateEvent( |
| @@ -126,14 +132,23 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data, | |||
| 126 | controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); | 132 | controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); |
| 127 | } | 133 | } |
| 128 | 134 | ||
| 135 | // If ns_late is higher than the update rate ignore the delay | ||
| 136 | if (ns_late > motion_update_ns) { | ||
| 137 | ns_late = {}; | ||
| 138 | } | ||
| 139 | |||
| 129 | core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); | 140 | core_timing.ScheduleEvent(pad_update_ns - ns_late, pad_update_event); |
| 130 | } | 141 | } |
| 131 | 142 | ||
| 132 | void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { | 143 | void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late) { |
| 133 | auto& core_timing = system.CoreTiming(); | 144 | auto& core_timing = system.CoreTiming(); |
| 134 | 145 | ||
| 135 | for (const auto& controller : controllers) { | 146 | controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate( |
| 136 | controller->OnMotionUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); | 147 | core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); |
| 148 | |||
| 149 | // If ns_late is higher than the update rate ignore the delay | ||
| 150 | if (ns_late > motion_update_ns) { | ||
| 151 | ns_late = {}; | ||
| 137 | } | 152 | } |
| 138 | 153 | ||
| 139 | core_timing.ScheduleEvent(motion_update_ns - ns_late, motion_update_event); | 154 | core_timing.ScheduleEvent(motion_update_ns - ns_late, motion_update_event); |
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index d991bd721..7cc0433e2 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h | |||
| @@ -29,12 +29,14 @@ enum class HidController : std::size_t { | |||
| 29 | Mouse, | 29 | Mouse, |
| 30 | Keyboard, | 30 | Keyboard, |
| 31 | XPad, | 31 | XPad, |
| 32 | Unknown1, | 32 | HomeButton, |
| 33 | Unknown2, | 33 | SleepButton, |
| 34 | Unknown3, | 34 | CaptureButton, |
| 35 | SixAxisSensor, | 35 | InputDetector, |
| 36 | UniquePad, | ||
| 36 | NPad, | 37 | NPad, |
| 37 | Gesture, | 38 | Gesture, |
| 39 | ConsoleSixAxisSensor, | ||
| 38 | 40 | ||
| 39 | MaxControllers, | 41 | MaxControllers, |
| 40 | }; | 42 | }; |
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index a515fdc60..5d6d25696 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp | |||
| @@ -8,10 +8,11 @@ | |||
| 8 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/ipc_helpers.h" | 10 | #include "core/hle/ipc_helpers.h" |
| 11 | #include "core/hle/kernel/k_event.h" | ||
| 12 | #include "core/hle/kernel/k_readable_event.h" | ||
| 11 | #include "core/hle/kernel/k_thread.h" | 13 | #include "core/hle/kernel/k_thread.h" |
| 14 | #include "core/hle/kernel/k_writable_event.h" | ||
| 12 | #include "core/hle/kernel/kernel.h" | 15 | #include "core/hle/kernel/kernel.h" |
| 13 | #include "core/hle/kernel/readable_event.h" | ||
| 14 | #include "core/hle/kernel/writable_event.h" | ||
| 15 | #include "core/hle/lock.h" | 16 | #include "core/hle/lock.h" |
| 16 | #include "core/hle/service/nfp/nfp.h" | 17 | #include "core/hle/service/nfp/nfp.h" |
| 17 | #include "core/hle/service/nfp/nfp_user.h" | 18 | #include "core/hle/service/nfp/nfp_user.h" |
| @@ -25,7 +26,8 @@ Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& syst | |||
| 25 | const char* name) | 26 | const char* name) |
| 26 | : ServiceFramework{system_, name}, module{std::move(module_)} { | 27 | : ServiceFramework{system_, name}, module{std::move(module_)} { |
| 27 | auto& kernel = system.Kernel(); | 28 | auto& kernel = system.Kernel(); |
| 28 | nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, "IUser:NFCTagDetected"); | 29 | nfc_tag_load = Kernel::KEvent::Create(kernel, "IUser:NFCTagDetected"); |
| 30 | nfc_tag_load->Initialize(); | ||
| 29 | } | 31 | } |
| 30 | 32 | ||
| 31 | Module::Interface::~Interface() = default; | 33 | Module::Interface::~Interface() = default; |
| @@ -64,9 +66,10 @@ public: | |||
| 64 | RegisterHandlers(functions); | 66 | RegisterHandlers(functions); |
| 65 | 67 | ||
| 66 | auto& kernel = system.Kernel(); | 68 | auto& kernel = system.Kernel(); |
| 67 | deactivate_event = Kernel::WritableEvent::CreateEventPair(kernel, "IUser:DeactivateEvent"); | 69 | deactivate_event = Kernel::KEvent::Create(kernel, "IUser:DeactivateEvent"); |
| 68 | availability_change_event = | 70 | deactivate_event->Initialize(); |
| 69 | Kernel::WritableEvent::CreateEventPair(kernel, "IUser:AvailabilityChangeEvent"); | 71 | availability_change_event = Kernel::KEvent::Create(kernel, "IUser:AvailabilityChangeEvent"); |
| 72 | availability_change_event->Initialize(); | ||
| 70 | } | 73 | } |
| 71 | 74 | ||
| 72 | private: | 75 | private: |
| @@ -164,7 +167,7 @@ private: | |||
| 164 | 167 | ||
| 165 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 168 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 166 | rb.Push(RESULT_SUCCESS); | 169 | rb.Push(RESULT_SUCCESS); |
| 167 | rb.PushCopyObjects(deactivate_event.readable); | 170 | rb.PushCopyObjects(deactivate_event->GetReadableEvent()); |
| 168 | } | 171 | } |
| 169 | 172 | ||
| 170 | void StopDetection(Kernel::HLERequestContext& ctx) { | 173 | void StopDetection(Kernel::HLERequestContext& ctx) { |
| @@ -173,7 +176,7 @@ private: | |||
| 173 | switch (device_state) { | 176 | switch (device_state) { |
| 174 | case DeviceState::TagFound: | 177 | case DeviceState::TagFound: |
| 175 | case DeviceState::TagNearby: | 178 | case DeviceState::TagNearby: |
| 176 | deactivate_event.writable->Signal(); | 179 | deactivate_event->GetWritableEvent()->Signal(); |
| 177 | device_state = DeviceState::Initialized; | 180 | device_state = DeviceState::Initialized; |
| 178 | break; | 181 | break; |
| 179 | case DeviceState::SearchingForTag: | 182 | case DeviceState::SearchingForTag: |
| @@ -262,7 +265,7 @@ private: | |||
| 262 | 265 | ||
| 263 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 266 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 264 | rb.Push(RESULT_SUCCESS); | 267 | rb.Push(RESULT_SUCCESS); |
| 265 | rb.PushCopyObjects(availability_change_event.readable); | 268 | rb.PushCopyObjects(availability_change_event->GetReadableEvent()); |
| 266 | } | 269 | } |
| 267 | 270 | ||
| 268 | void GetRegisterInfo(Kernel::HLERequestContext& ctx) { | 271 | void GetRegisterInfo(Kernel::HLERequestContext& ctx) { |
| @@ -316,8 +319,8 @@ private: | |||
| 316 | const u32 npad_id{0}; // Player 1 controller | 319 | const u32 npad_id{0}; // Player 1 controller |
| 317 | State state{State::NonInitialized}; | 320 | State state{State::NonInitialized}; |
| 318 | DeviceState device_state{DeviceState::Initialized}; | 321 | DeviceState device_state{DeviceState::Initialized}; |
| 319 | Kernel::EventPair deactivate_event; | 322 | std::shared_ptr<Kernel::KEvent> deactivate_event; |
| 320 | Kernel::EventPair availability_change_event; | 323 | std::shared_ptr<Kernel::KEvent> availability_change_event; |
| 321 | const Module::Interface& nfp_interface; | 324 | const Module::Interface& nfp_interface; |
| 322 | }; | 325 | }; |
| 323 | 326 | ||
| @@ -336,12 +339,12 @@ bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) { | |||
| 336 | } | 339 | } |
| 337 | 340 | ||
| 338 | std::memcpy(&amiibo, buffer.data(), sizeof(amiibo)); | 341 | std::memcpy(&amiibo, buffer.data(), sizeof(amiibo)); |
| 339 | nfc_tag_load.writable->Signal(); | 342 | nfc_tag_load->GetWritableEvent()->Signal(); |
| 340 | return true; | 343 | return true; |
| 341 | } | 344 | } |
| 342 | 345 | ||
| 343 | const std::shared_ptr<Kernel::ReadableEvent>& Module::Interface::GetNFCEvent() const { | 346 | const std::shared_ptr<Kernel::KReadableEvent>& Module::Interface::GetNFCEvent() const { |
| 344 | return nfc_tag_load.readable; | 347 | return nfc_tag_load->GetReadableEvent(); |
| 345 | } | 348 | } |
| 346 | 349 | ||
| 347 | const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const { | 350 | const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const { |
diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h index 295de535b..c46551760 100644 --- a/src/core/hle/service/nfp/nfp.h +++ b/src/core/hle/service/nfp/nfp.h | |||
| @@ -6,10 +6,13 @@ | |||
| 6 | 6 | ||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | #include "core/hle/kernel/readable_event.h" | 9 | |
| 10 | #include "core/hle/kernel/writable_event.h" | ||
| 11 | #include "core/hle/service/service.h" | 10 | #include "core/hle/service/service.h" |
| 12 | 11 | ||
| 12 | namespace Kernel { | ||
| 13 | class KEvent; | ||
| 14 | } | ||
| 15 | |||
| 13 | namespace Service::NFP { | 16 | namespace Service::NFP { |
| 14 | 17 | ||
| 15 | class Module final { | 18 | class Module final { |
| @@ -35,11 +38,11 @@ public: | |||
| 35 | 38 | ||
| 36 | void CreateUserInterface(Kernel::HLERequestContext& ctx); | 39 | void CreateUserInterface(Kernel::HLERequestContext& ctx); |
| 37 | bool LoadAmiibo(const std::vector<u8>& buffer); | 40 | bool LoadAmiibo(const std::vector<u8>& buffer); |
| 38 | const std::shared_ptr<Kernel::ReadableEvent>& GetNFCEvent() const; | 41 | const std::shared_ptr<Kernel::KReadableEvent>& GetNFCEvent() const; |
| 39 | const AmiiboFile& GetAmiiboBuffer() const; | 42 | const AmiiboFile& GetAmiiboBuffer() const; |
| 40 | 43 | ||
| 41 | private: | 44 | private: |
| 42 | Kernel::EventPair nfc_tag_load{}; | 45 | std::shared_ptr<Kernel::KEvent> nfc_tag_load; |
| 43 | AmiiboFile amiibo{}; | 46 | AmiiboFile amiibo{}; |
| 44 | 47 | ||
| 45 | protected: | 48 | protected: |
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index 8372e170c..afb3342d6 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp | |||
| @@ -4,9 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #include "core/core.h" | 5 | #include "core/core.h" |
| 6 | #include "core/hle/ipc_helpers.h" | 6 | #include "core/hle/ipc_helpers.h" |
| 7 | #include "core/hle/kernel/k_event.h" | ||
| 8 | #include "core/hle/kernel/k_readable_event.h" | ||
| 7 | #include "core/hle/kernel/kernel.h" | 9 | #include "core/hle/kernel/kernel.h" |
| 8 | #include "core/hle/kernel/readable_event.h" | ||
| 9 | #include "core/hle/kernel/writable_event.h" | ||
| 10 | #include "core/hle/service/nifm/nifm.h" | 10 | #include "core/hle/service/nifm/nifm.h" |
| 11 | #include "core/hle/service/service.h" | 11 | #include "core/hle/service/service.h" |
| 12 | #include "core/network/network.h" | 12 | #include "core/network/network.h" |
| @@ -158,8 +158,11 @@ public: | |||
| 158 | RegisterHandlers(functions); | 158 | RegisterHandlers(functions); |
| 159 | 159 | ||
| 160 | auto& kernel = system.Kernel(); | 160 | auto& kernel = system.Kernel(); |
| 161 | event1 = Kernel::WritableEvent::CreateEventPair(kernel, "IRequest:Event1"); | 161 | |
| 162 | event2 = Kernel::WritableEvent::CreateEventPair(kernel, "IRequest:Event2"); | 162 | event1 = Kernel::KEvent::Create(kernel, "IRequest:Event1"); |
| 163 | event1->Initialize(); | ||
| 164 | event2 = Kernel::KEvent::Create(kernel, "IRequest:Event2"); | ||
| 165 | event2->Initialize(); | ||
| 163 | } | 166 | } |
| 164 | 167 | ||
| 165 | private: | 168 | private: |
| @@ -195,7 +198,7 @@ private: | |||
| 195 | 198 | ||
| 196 | IPC::ResponseBuilder rb{ctx, 2, 2}; | 199 | IPC::ResponseBuilder rb{ctx, 2, 2}; |
| 197 | rb.Push(RESULT_SUCCESS); | 200 | rb.Push(RESULT_SUCCESS); |
| 198 | rb.PushCopyObjects(event1.readable, event2.readable); | 201 | rb.PushCopyObjects(event1->GetReadableEvent(), event2->GetReadableEvent()); |
| 199 | } | 202 | } |
| 200 | 203 | ||
| 201 | void Cancel(Kernel::HLERequestContext& ctx) { | 204 | void Cancel(Kernel::HLERequestContext& ctx) { |
| @@ -226,7 +229,7 @@ private: | |||
| 226 | rb.Push<u32>(0); | 229 | rb.Push<u32>(0); |
| 227 | } | 230 | } |
| 228 | 231 | ||
| 229 | Kernel::EventPair event1, event2; | 232 | std::shared_ptr<Kernel::KEvent> event1, event2; |
| 230 | }; | 233 | }; |
| 231 | 234 | ||
| 232 | class INetworkProfile final : public ServiceFramework<INetworkProfile> { | 235 | class INetworkProfile final : public ServiceFramework<INetworkProfile> { |
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index d16223064..f3be0b878 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp | |||
| @@ -6,9 +6,10 @@ | |||
| 6 | #include <ctime> | 6 | #include <ctime> |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/ipc_helpers.h" | 8 | #include "core/hle/ipc_helpers.h" |
| 9 | #include "core/hle/kernel/k_event.h" | ||
| 10 | #include "core/hle/kernel/k_readable_event.h" | ||
| 11 | #include "core/hle/kernel/k_writable_event.h" | ||
| 9 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| 10 | #include "core/hle/kernel/readable_event.h" | ||
| 11 | #include "core/hle/kernel/writable_event.h" | ||
| 12 | #include "core/hle/service/nim/nim.h" | 13 | #include "core/hle/service/nim/nim.h" |
| 13 | #include "core/hle/service/service.h" | 14 | #include "core/hle/service/service.h" |
| 14 | #include "core/hle/service/sm/sm.h" | 15 | #include "core/hle/service/sm/sm.h" |
| @@ -301,17 +302,18 @@ public: | |||
| 301 | RegisterHandlers(functions); | 302 | RegisterHandlers(functions); |
| 302 | 303 | ||
| 303 | auto& kernel = system.Kernel(); | 304 | auto& kernel = system.Kernel(); |
| 304 | finished_event = Kernel::WritableEvent::CreateEventPair( | 305 | finished_event = |
| 305 | kernel, "IEnsureNetworkClockAvailabilityService:FinishEvent"); | 306 | Kernel::KEvent::Create(kernel, "IEnsureNetworkClockAvailabilityService:FinishEvent"); |
| 307 | finished_event->Initialize(); | ||
| 306 | } | 308 | } |
| 307 | 309 | ||
| 308 | private: | 310 | private: |
| 309 | Kernel::EventPair finished_event; | 311 | std::shared_ptr<Kernel::KEvent> finished_event; |
| 310 | 312 | ||
| 311 | void StartTask(Kernel::HLERequestContext& ctx) { | 313 | void StartTask(Kernel::HLERequestContext& ctx) { |
| 312 | // No need to connect to the internet, just finish the task straight away. | 314 | // No need to connect to the internet, just finish the task straight away. |
| 313 | LOG_DEBUG(Service_NIM, "called"); | 315 | LOG_DEBUG(Service_NIM, "called"); |
| 314 | finished_event.writable->Signal(); | 316 | finished_event->GetWritableEvent()->Signal(); |
| 315 | IPC::ResponseBuilder rb{ctx, 2}; | 317 | IPC::ResponseBuilder rb{ctx, 2}; |
| 316 | rb.Push(RESULT_SUCCESS); | 318 | rb.Push(RESULT_SUCCESS); |
| 317 | } | 319 | } |
| @@ -321,7 +323,7 @@ private: | |||
| 321 | 323 | ||
| 322 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 324 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 323 | rb.Push(RESULT_SUCCESS); | 325 | rb.Push(RESULT_SUCCESS); |
| 324 | rb.PushCopyObjects(finished_event.readable); | 326 | rb.PushCopyObjects(finished_event->GetReadableEvent()); |
| 325 | } | 327 | } |
| 326 | 328 | ||
| 327 | void GetResult(Kernel::HLERequestContext& ctx) { | 329 | void GetResult(Kernel::HLERequestContext& ctx) { |
| @@ -333,7 +335,7 @@ private: | |||
| 333 | 335 | ||
| 334 | void Cancel(Kernel::HLERequestContext& ctx) { | 336 | void Cancel(Kernel::HLERequestContext& ctx) { |
| 335 | LOG_DEBUG(Service_NIM, "called"); | 337 | LOG_DEBUG(Service_NIM, "called"); |
| 336 | finished_event.writable->Clear(); | 338 | finished_event->GetWritableEvent()->Clear(); |
| 337 | IPC::ResponseBuilder rb{ctx, 2}; | 339 | IPC::ResponseBuilder rb{ctx, 2}; |
| 338 | rb.Push(RESULT_SUCCESS); | 340 | rb.Push(RESULT_SUCCESS); |
| 339 | } | 341 | } |
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 060599bab..f6129ef10 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp | |||
| @@ -8,8 +8,8 @@ | |||
| 8 | #include "common/assert.h" | 8 | #include "common/assert.h" |
| 9 | #include "common/logging/log.h" | 9 | #include "common/logging/log.h" |
| 10 | #include "core/core.h" | 10 | #include "core/core.h" |
| 11 | #include "core/hle/kernel/readable_event.h" | 11 | #include "core/hle/kernel/k_event.h" |
| 12 | #include "core/hle/kernel/writable_event.h" | 12 | #include "core/hle/kernel/k_writable_event.h" |
| 13 | #include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" | 13 | #include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" |
| 14 | #include "video_core/gpu.h" | 14 | #include "video_core/gpu.h" |
| 15 | 15 | ||
| @@ -103,14 +103,14 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector | |||
| 103 | // This is mostly to take into account unimplemented features. As synced | 103 | // This is mostly to take into account unimplemented features. As synced |
| 104 | // gpu is always synced. | 104 | // gpu is always synced. |
| 105 | if (!gpu.IsAsync()) { | 105 | if (!gpu.IsAsync()) { |
| 106 | event.event.writable->Signal(); | 106 | event.event->GetWritableEvent()->Signal(); |
| 107 | return NvResult::Success; | 107 | return NvResult::Success; |
| 108 | } | 108 | } |
| 109 | auto lock = gpu.LockSync(); | 109 | auto lock = gpu.LockSync(); |
| 110 | const u32 current_syncpoint_value = event.fence.value; | 110 | const u32 current_syncpoint_value = event.fence.value; |
| 111 | const s32 diff = current_syncpoint_value - params.threshold; | 111 | const s32 diff = current_syncpoint_value - params.threshold; |
| 112 | if (diff >= 0) { | 112 | if (diff >= 0) { |
| 113 | event.event.writable->Signal(); | 113 | event.event->GetWritableEvent()->Signal(); |
| 114 | params.value = current_syncpoint_value; | 114 | params.value = current_syncpoint_value; |
| 115 | std::memcpy(output.data(), ¶ms, sizeof(params)); | 115 | std::memcpy(output.data(), ¶ms, sizeof(params)); |
| 116 | return NvResult::Success; | 116 | return NvResult::Success; |
| @@ -137,7 +137,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector | |||
| 137 | params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000; | 137 | params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000; |
| 138 | } | 138 | } |
| 139 | params.value |= event_id; | 139 | params.value |= event_id; |
| 140 | event.event.writable->Clear(); | 140 | event.event->GetWritableEvent()->Clear(); |
| 141 | gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value); | 141 | gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value); |
| 142 | std::memcpy(output.data(), ¶ms, sizeof(params)); | 142 | std::memcpy(output.data(), ¶ms, sizeof(params)); |
| 143 | return NvResult::Timeout; | 143 | return NvResult::Timeout; |
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index 1328b64d0..2e1150867 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp | |||
| @@ -6,10 +6,10 @@ | |||
| 6 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/ipc_helpers.h" | 8 | #include "core/hle/ipc_helpers.h" |
| 9 | #include "core/hle/kernel/k_readable_event.h" | ||
| 9 | #include "core/hle/kernel/k_thread.h" | 10 | #include "core/hle/kernel/k_thread.h" |
| 11 | #include "core/hle/kernel/k_writable_event.h" | ||
| 10 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| 11 | #include "core/hle/kernel/readable_event.h" | ||
| 12 | #include "core/hle/kernel/writable_event.h" | ||
| 13 | #include "core/hle/service/nvdrv/interface.h" | 13 | #include "core/hle/service/nvdrv/interface.h" |
| 14 | #include "core/hle/service/nvdrv/nvdata.h" | 14 | #include "core/hle/service/nvdrv/nvdata.h" |
| 15 | #include "core/hle/service/nvdrv/nvdrv.h" | 15 | #include "core/hle/service/nvdrv/nvdrv.h" |
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h index 5c777c59b..0e764c53f 100644 --- a/src/core/hle/service/nvdrv/interface.h +++ b/src/core/hle/service/nvdrv/interface.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "core/hle/service/service.h" | 9 | #include "core/hle/service/service.h" |
| 10 | 10 | ||
| 11 | namespace Kernel { | 11 | namespace Kernel { |
| 12 | class WritableEvent; | 12 | class KWritableEvent; |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | namespace Service::Nvidia { | 15 | namespace Service::Nvidia { |
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 620c18728..abba80112 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp | |||
| @@ -7,8 +7,9 @@ | |||
| 7 | #include <fmt/format.h> | 7 | #include <fmt/format.h> |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| 10 | #include "core/hle/kernel/readable_event.h" | 10 | #include "core/hle/kernel/k_event.h" |
| 11 | #include "core/hle/kernel/writable_event.h" | 11 | #include "core/hle/kernel/k_readable_event.h" |
| 12 | #include "core/hle/kernel/k_writable_event.h" | ||
| 12 | #include "core/hle/service/nvdrv/devices/nvdevice.h" | 13 | #include "core/hle/service/nvdrv/devices/nvdevice.h" |
| 13 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | 14 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" |
| 14 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" | 15 | #include "core/hle/service/nvdrv/devices/nvhost_as_gpu.h" |
| @@ -42,7 +43,8 @@ Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} { | |||
| 42 | auto& kernel = system.Kernel(); | 43 | auto& kernel = system.Kernel(); |
| 43 | for (u32 i = 0; i < MaxNvEvents; i++) { | 44 | for (u32 i = 0; i < MaxNvEvents; i++) { |
| 44 | std::string event_label = fmt::format("NVDRV::NvEvent_{}", i); | 45 | std::string event_label = fmt::format("NVDRV::NvEvent_{}", i); |
| 45 | events_interface.events[i] = {Kernel::WritableEvent::CreateEventPair(kernel, event_label)}; | 46 | events_interface.events[i] = {Kernel::KEvent::Create(kernel, std::move(event_label))}; |
| 47 | events_interface.events[i].event->Initialize(); | ||
| 46 | events_interface.status[i] = EventState::Free; | 48 | events_interface.status[i] = EventState::Free; |
| 47 | events_interface.registered[i] = false; | 49 | events_interface.registered[i] = false; |
| 48 | } | 50 | } |
| @@ -166,17 +168,17 @@ void Module::SignalSyncpt(const u32 syncpoint_id, const u32 value) { | |||
| 166 | if (events_interface.assigned_syncpt[i] == syncpoint_id && | 168 | if (events_interface.assigned_syncpt[i] == syncpoint_id && |
| 167 | events_interface.assigned_value[i] == value) { | 169 | events_interface.assigned_value[i] == value) { |
| 168 | events_interface.LiberateEvent(i); | 170 | events_interface.LiberateEvent(i); |
| 169 | events_interface.events[i].event.writable->Signal(); | 171 | events_interface.events[i].event->GetWritableEvent()->Signal(); |
| 170 | } | 172 | } |
| 171 | } | 173 | } |
| 172 | } | 174 | } |
| 173 | 175 | ||
| 174 | std::shared_ptr<Kernel::ReadableEvent> Module::GetEvent(const u32 event_id) const { | 176 | std::shared_ptr<Kernel::KReadableEvent> Module::GetEvent(const u32 event_id) const { |
| 175 | return events_interface.events[event_id].event.readable; | 177 | return events_interface.events[event_id].event->GetReadableEvent(); |
| 176 | } | 178 | } |
| 177 | 179 | ||
| 178 | std::shared_ptr<Kernel::WritableEvent> Module::GetEventWriteable(const u32 event_id) const { | 180 | std::shared_ptr<Kernel::KWritableEvent> Module::GetEventWriteable(const u32 event_id) const { |
| 179 | return events_interface.events[event_id].event.writable; | 181 | return events_interface.events[event_id].event->GetWritableEvent(); |
| 180 | } | 182 | } |
| 181 | 183 | ||
| 182 | } // namespace Service::Nvidia | 184 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index 144e657e5..53719aadd 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h | |||
| @@ -7,8 +7,8 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <unordered_map> | 8 | #include <unordered_map> |
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | |||
| 10 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 11 | #include "core/hle/kernel/writable_event.h" | ||
| 12 | #include "core/hle/service/nvdrv/nvdata.h" | 12 | #include "core/hle/service/nvdrv/nvdata.h" |
| 13 | #include "core/hle/service/nvdrv/syncpoint_manager.h" | 13 | #include "core/hle/service/nvdrv/syncpoint_manager.h" |
| 14 | #include "core/hle/service/service.h" | 14 | #include "core/hle/service/service.h" |
| @@ -17,6 +17,10 @@ namespace Core { | |||
| 17 | class System; | 17 | class System; |
| 18 | } | 18 | } |
| 19 | 19 | ||
| 20 | namespace Kernel { | ||
| 21 | class KEvent; | ||
| 22 | } | ||
| 23 | |||
| 20 | namespace Service::NVFlinger { | 24 | namespace Service::NVFlinger { |
| 21 | class NVFlinger; | 25 | class NVFlinger; |
| 22 | } | 26 | } |
| @@ -31,7 +35,7 @@ class nvdevice; | |||
| 31 | 35 | ||
| 32 | /// Represents an Nvidia event | 36 | /// Represents an Nvidia event |
| 33 | struct NvEvent { | 37 | struct NvEvent { |
| 34 | Kernel::EventPair event; | 38 | std::shared_ptr<Kernel::KEvent> event; |
| 35 | Fence fence{}; | 39 | Fence fence{}; |
| 36 | }; | 40 | }; |
| 37 | 41 | ||
| @@ -132,9 +136,9 @@ public: | |||
| 132 | 136 | ||
| 133 | void SignalSyncpt(const u32 syncpoint_id, const u32 value); | 137 | void SignalSyncpt(const u32 syncpoint_id, const u32 value); |
| 134 | 138 | ||
| 135 | std::shared_ptr<Kernel::ReadableEvent> GetEvent(u32 event_id) const; | 139 | std::shared_ptr<Kernel::KReadableEvent> GetEvent(u32 event_id) const; |
| 136 | 140 | ||
| 137 | std::shared_ptr<Kernel::WritableEvent> GetEventWriteable(u32 event_id) const; | 141 | std::shared_ptr<Kernel::KWritableEvent> GetEventWriteable(u32 event_id) const; |
| 138 | 142 | ||
| 139 | private: | 143 | private: |
| 140 | /// Manages syncpoints on the host | 144 | /// Manages syncpoints on the host |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 5578181a4..7842a82ed 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp | |||
| @@ -7,16 +7,17 @@ | |||
| 7 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 9 | #include "core/core.h" | 9 | #include "core/core.h" |
| 10 | #include "core/hle/kernel/k_event.h" | ||
| 11 | #include "core/hle/kernel/k_writable_event.h" | ||
| 10 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| 11 | #include "core/hle/kernel/readable_event.h" | ||
| 12 | #include "core/hle/kernel/writable_event.h" | ||
| 13 | #include "core/hle/service/nvflinger/buffer_queue.h" | 13 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| 14 | 14 | ||
| 15 | namespace Service::NVFlinger { | 15 | namespace Service::NVFlinger { |
| 16 | 16 | ||
| 17 | BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id) | 17 | BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id) |
| 18 | : id(id), layer_id(layer_id) { | 18 | : id(id), layer_id(layer_id) { |
| 19 | buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, "BufferQueue NativeHandle"); | 19 | buffer_wait_event = Kernel::KEvent::Create(kernel, "BufferQueue:WaitEvent"); |
| 20 | buffer_wait_event->Initialize(); | ||
| 20 | } | 21 | } |
| 21 | 22 | ||
| 22 | BufferQueue::~BufferQueue() = default; | 23 | BufferQueue::~BufferQueue() = default; |
| @@ -41,7 +42,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) | |||
| 41 | .multi_fence = {}, | 42 | .multi_fence = {}, |
| 42 | }; | 43 | }; |
| 43 | 44 | ||
| 44 | buffer_wait_event.writable->Signal(); | 45 | buffer_wait_event->GetWritableEvent()->Signal(); |
| 45 | } | 46 | } |
| 46 | 47 | ||
| 47 | std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width, | 48 | std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width, |
| @@ -119,7 +120,7 @@ void BufferQueue::CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& mult | |||
| 119 | } | 120 | } |
| 120 | free_buffers_condition.notify_one(); | 121 | free_buffers_condition.notify_one(); |
| 121 | 122 | ||
| 122 | buffer_wait_event.writable->Signal(); | 123 | buffer_wait_event->GetWritableEvent()->Signal(); |
| 123 | } | 124 | } |
| 124 | 125 | ||
| 125 | std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { | 126 | std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { |
| @@ -154,7 +155,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) { | |||
| 154 | } | 155 | } |
| 155 | free_buffers_condition.notify_one(); | 156 | free_buffers_condition.notify_one(); |
| 156 | 157 | ||
| 157 | buffer_wait_event.writable->Signal(); | 158 | buffer_wait_event->GetWritableEvent()->Signal(); |
| 158 | } | 159 | } |
| 159 | 160 | ||
| 160 | void BufferQueue::Connect() { | 161 | void BufferQueue::Connect() { |
| @@ -169,7 +170,7 @@ void BufferQueue::Disconnect() { | |||
| 169 | std::unique_lock lock{queue_sequence_mutex}; | 170 | std::unique_lock lock{queue_sequence_mutex}; |
| 170 | queue_sequence.clear(); | 171 | queue_sequence.clear(); |
| 171 | } | 172 | } |
| 172 | buffer_wait_event.writable->Signal(); | 173 | buffer_wait_event->GetWritableEvent()->Signal(); |
| 173 | is_connect = false; | 174 | is_connect = false; |
| 174 | free_buffers_condition.notify_one(); | 175 | free_buffers_condition.notify_one(); |
| 175 | } | 176 | } |
| @@ -188,12 +189,12 @@ u32 BufferQueue::Query(QueryType type) { | |||
| 188 | return 0; | 189 | return 0; |
| 189 | } | 190 | } |
| 190 | 191 | ||
| 191 | std::shared_ptr<Kernel::WritableEvent> BufferQueue::GetWritableBufferWaitEvent() const { | 192 | std::shared_ptr<Kernel::KWritableEvent> BufferQueue::GetWritableBufferWaitEvent() const { |
| 192 | return buffer_wait_event.writable; | 193 | return buffer_wait_event->GetWritableEvent(); |
| 193 | } | 194 | } |
| 194 | 195 | ||
| 195 | std::shared_ptr<Kernel::ReadableEvent> BufferQueue::GetBufferWaitEvent() const { | 196 | std::shared_ptr<Kernel::KReadableEvent> BufferQueue::GetBufferWaitEvent() const { |
| 196 | return buffer_wait_event.readable; | 197 | return buffer_wait_event->GetReadableEvent(); |
| 197 | } | 198 | } |
| 198 | 199 | ||
| 199 | } // namespace Service::NVFlinger | 200 | } // namespace Service::NVFlinger |
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index ad7469277..163fa4c54 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h | |||
| @@ -14,12 +14,14 @@ | |||
| 14 | #include "common/math_util.h" | 14 | #include "common/math_util.h" |
| 15 | #include "common/swap.h" | 15 | #include "common/swap.h" |
| 16 | #include "core/hle/kernel/object.h" | 16 | #include "core/hle/kernel/object.h" |
| 17 | #include "core/hle/kernel/writable_event.h" | ||
| 18 | #include "core/hle/service/nvdrv/nvdata.h" | 17 | #include "core/hle/service/nvdrv/nvdata.h" |
| 19 | 18 | ||
| 20 | namespace Kernel { | 19 | namespace Kernel { |
| 21 | class KernelCore; | 20 | class KernelCore; |
| 22 | } | 21 | class KEvent; |
| 22 | class KReadableEvent; | ||
| 23 | class KWritableEvent; | ||
| 24 | } // namespace Kernel | ||
| 23 | 25 | ||
| 24 | namespace Service::NVFlinger { | 26 | namespace Service::NVFlinger { |
| 25 | 27 | ||
| @@ -113,9 +115,9 @@ public: | |||
| 113 | return is_connect; | 115 | return is_connect; |
| 114 | } | 116 | } |
| 115 | 117 | ||
| 116 | std::shared_ptr<Kernel::WritableEvent> GetWritableBufferWaitEvent() const; | 118 | std::shared_ptr<Kernel::KWritableEvent> GetWritableBufferWaitEvent() const; |
| 117 | 119 | ||
| 118 | std::shared_ptr<Kernel::ReadableEvent> GetBufferWaitEvent() const; | 120 | std::shared_ptr<Kernel::KReadableEvent> GetBufferWaitEvent() const; |
| 119 | 121 | ||
| 120 | private: | 122 | private: |
| 121 | BufferQueue(const BufferQueue&) = delete; | 123 | BufferQueue(const BufferQueue&) = delete; |
| @@ -127,7 +129,7 @@ private: | |||
| 127 | std::list<u32> free_buffers; | 129 | std::list<u32> free_buffers; |
| 128 | std::array<Buffer, buffer_slots> buffers; | 130 | std::array<Buffer, buffer_slots> buffers; |
| 129 | std::list<u32> queue_sequence; | 131 | std::list<u32> queue_sequence; |
| 130 | Kernel::EventPair buffer_wait_event; | 132 | std::shared_ptr<Kernel::KEvent> buffer_wait_event; |
| 131 | 133 | ||
| 132 | std::mutex free_buffers_mutex; | 134 | std::mutex free_buffers_mutex; |
| 133 | std::condition_variable free_buffers_condition; | 135 | std::condition_variable free_buffers_condition; |
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index ceaa93d28..ac2906e5b 100644 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp | |||
| @@ -14,8 +14,8 @@ | |||
| 14 | #include "core/core_timing.h" | 14 | #include "core/core_timing.h" |
| 15 | #include "core/core_timing_util.h" | 15 | #include "core/core_timing_util.h" |
| 16 | #include "core/hardware_properties.h" | 16 | #include "core/hardware_properties.h" |
| 17 | #include "core/hle/kernel/k_readable_event.h" | ||
| 17 | #include "core/hle/kernel/kernel.h" | 18 | #include "core/hle/kernel/kernel.h" |
| 18 | #include "core/hle/kernel/readable_event.h" | ||
| 19 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" | 19 | #include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" |
| 20 | #include "core/hle/service/nvdrv/nvdrv.h" | 20 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 21 | #include "core/hle/service/nvflinger/buffer_queue.h" | 21 | #include "core/hle/service/nvflinger/buffer_queue.h" |
| @@ -165,7 +165,7 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) co | |||
| 165 | return layer->GetBufferQueue().GetId(); | 165 | return layer->GetBufferQueue().GetId(); |
| 166 | } | 166 | } |
| 167 | 167 | ||
| 168 | std::shared_ptr<Kernel::ReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const { | 168 | std::shared_ptr<Kernel::KReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const { |
| 169 | const auto guard = Lock(); | 169 | const auto guard = Lock(); |
| 170 | auto* const display = FindDisplay(display_id); | 170 | auto* const display = FindDisplay(display_id); |
| 171 | 171 | ||
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index c6765259f..6fe2c7f2a 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h | |||
| @@ -26,8 +26,8 @@ struct EventType; | |||
| 26 | } // namespace Core::Timing | 26 | } // namespace Core::Timing |
| 27 | 27 | ||
| 28 | namespace Kernel { | 28 | namespace Kernel { |
| 29 | class ReadableEvent; | 29 | class KReadableEvent; |
| 30 | class WritableEvent; | 30 | class KWritableEvent; |
| 31 | } // namespace Kernel | 31 | } // namespace Kernel |
| 32 | 32 | ||
| 33 | namespace Service::Nvidia { | 33 | namespace Service::Nvidia { |
| @@ -72,7 +72,7 @@ public: | |||
| 72 | /// Gets the vsync event for the specified display. | 72 | /// Gets the vsync event for the specified display. |
| 73 | /// | 73 | /// |
| 74 | /// If an invalid display ID is provided, then nullptr is returned. | 74 | /// If an invalid display ID is provided, then nullptr is returned. |
| 75 | [[nodiscard]] std::shared_ptr<Kernel::ReadableEvent> FindVsyncEvent(u64 display_id) const; | 75 | [[nodiscard]] std::shared_ptr<Kernel::KReadableEvent> FindVsyncEvent(u64 display_id) const; |
| 76 | 76 | ||
| 77 | /// Obtains a buffer queue identified by the ID. | 77 | /// Obtains a buffer queue identified by the ID. |
| 78 | [[nodiscard]] BufferQueue* FindBufferQueue(u32 id); | 78 | [[nodiscard]] BufferQueue* FindBufferQueue(u32 id); |
diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp index a7cfccda3..26ed52273 100644 --- a/src/core/hle/service/ptm/psm.cpp +++ b/src/core/hle/service/ptm/psm.cpp | |||
| @@ -7,9 +7,10 @@ | |||
| 7 | #include "common/logging/log.h" | 7 | #include "common/logging/log.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/ipc_helpers.h" | 9 | #include "core/hle/ipc_helpers.h" |
| 10 | #include "core/hle/kernel/k_event.h" | ||
| 11 | #include "core/hle/kernel/k_readable_event.h" | ||
| 12 | #include "core/hle/kernel/k_writable_event.h" | ||
| 10 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 11 | #include "core/hle/kernel/readable_event.h" | ||
| 12 | #include "core/hle/kernel/writable_event.h" | ||
| 13 | #include "core/hle/service/ptm/psm.h" | 14 | #include "core/hle/service/ptm/psm.h" |
| 14 | #include "core/hle/service/service.h" | 15 | #include "core/hle/service/service.h" |
| 15 | #include "core/hle/service/sm/sm.h" | 16 | #include "core/hle/service/sm/sm.h" |
| @@ -31,27 +32,28 @@ public: | |||
| 31 | 32 | ||
| 32 | RegisterHandlers(functions); | 33 | RegisterHandlers(functions); |
| 33 | 34 | ||
| 34 | state_change_event = Kernel::WritableEvent::CreateEventPair( | 35 | state_change_event = |
| 35 | system_.Kernel(), "IPsmSession::state_change_event"); | 36 | Kernel::KEvent::Create(system_.Kernel(), "IPsmSession::state_change_event"); |
| 37 | state_change_event->Initialize(); | ||
| 36 | } | 38 | } |
| 37 | 39 | ||
| 38 | ~IPsmSession() override = default; | 40 | ~IPsmSession() override = default; |
| 39 | 41 | ||
| 40 | void SignalChargerTypeChanged() { | 42 | void SignalChargerTypeChanged() { |
| 41 | if (should_signal && should_signal_charger_type) { | 43 | if (should_signal && should_signal_charger_type) { |
| 42 | state_change_event.writable->Signal(); | 44 | state_change_event->GetWritableEvent()->Signal(); |
| 43 | } | 45 | } |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | void SignalPowerSupplyChanged() { | 48 | void SignalPowerSupplyChanged() { |
| 47 | if (should_signal && should_signal_power_supply) { | 49 | if (should_signal && should_signal_power_supply) { |
| 48 | state_change_event.writable->Signal(); | 50 | state_change_event->GetWritableEvent()->Signal(); |
| 49 | } | 51 | } |
| 50 | } | 52 | } |
| 51 | 53 | ||
| 52 | void SignalBatteryVoltageStateChanged() { | 54 | void SignalBatteryVoltageStateChanged() { |
| 53 | if (should_signal && should_signal_battery_voltage) { | 55 | if (should_signal && should_signal_battery_voltage) { |
| 54 | state_change_event.writable->Signal(); | 56 | state_change_event->GetWritableEvent()->Signal(); |
| 55 | } | 57 | } |
| 56 | } | 58 | } |
| 57 | 59 | ||
| @@ -63,7 +65,7 @@ private: | |||
| 63 | 65 | ||
| 64 | IPC::ResponseBuilder rb{ctx, 2, 1}; | 66 | IPC::ResponseBuilder rb{ctx, 2, 1}; |
| 65 | rb.Push(RESULT_SUCCESS); | 67 | rb.Push(RESULT_SUCCESS); |
| 66 | rb.PushCopyObjects(state_change_event.readable); | 68 | rb.PushCopyObjects(state_change_event->GetReadableEvent()); |
| 67 | } | 69 | } |
| 68 | 70 | ||
| 69 | void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) { | 71 | void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) { |
| @@ -112,7 +114,7 @@ private: | |||
| 112 | bool should_signal_power_supply{}; | 114 | bool should_signal_power_supply{}; |
| 113 | bool should_signal_battery_voltage{}; | 115 | bool should_signal_battery_voltage{}; |
| 114 | bool should_signal{}; | 116 | bool should_signal{}; |
| 115 | Kernel::EventPair state_change_event; | 117 | std::shared_ptr<Kernel::KEvent> state_change_event; |
| 116 | }; | 118 | }; |
| 117 | 119 | ||
| 118 | class PSM final : public ServiceFramework<PSM> { | 120 | class PSM final : public ServiceFramework<PSM> { |
diff --git a/src/core/hle/service/time/standard_user_system_clock_core.cpp b/src/core/hle/service/time/standard_user_system_clock_core.cpp index 8af17091c..b9faa474e 100644 --- a/src/core/hle/service/time/standard_user_system_clock_core.cpp +++ b/src/core/hle/service/time/standard_user_system_clock_core.cpp | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include "common/assert.h" | 5 | #include "common/assert.h" |
| 6 | #include "core/core.h" | 6 | #include "core/core.h" |
| 7 | #include "core/hle/kernel/writable_event.h" | 7 | #include "core/hle/kernel/k_event.h" |
| 8 | #include "core/hle/service/time/standard_local_system_clock_core.h" | 8 | #include "core/hle/service/time/standard_local_system_clock_core.h" |
| 9 | #include "core/hle/service/time/standard_network_system_clock_core.h" | 9 | #include "core/hle/service/time/standard_network_system_clock_core.h" |
| 10 | #include "core/hle/service/time/standard_user_system_clock_core.h" | 10 | #include "core/hle/service/time/standard_user_system_clock_core.h" |
| @@ -18,8 +18,10 @@ StandardUserSystemClockCore::StandardUserSystemClockCore( | |||
| 18 | local_system_clock_core{local_system_clock_core}, | 18 | local_system_clock_core{local_system_clock_core}, |
| 19 | network_system_clock_core{network_system_clock_core}, auto_correction_enabled{}, | 19 | network_system_clock_core{network_system_clock_core}, auto_correction_enabled{}, |
| 20 | auto_correction_time{SteadyClockTimePoint::GetRandom()}, | 20 | auto_correction_time{SteadyClockTimePoint::GetRandom()}, |
| 21 | auto_correction_event{Kernel::WritableEvent::CreateEventPair( | 21 | auto_correction_event{Kernel::KEvent::Create( |
| 22 | system.Kernel(), "StandardUserSystemClockCore:AutoCorrectionEvent")} {} | 22 | system.Kernel(), "StandardUserSystemClockCore:AutoCorrectionEvent")} { |
| 23 | auto_correction_event->Initialize(); | ||
| 24 | } | ||
| 23 | 25 | ||
| 24 | ResultCode StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::System& system, | 26 | ResultCode StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::System& system, |
| 25 | bool value) { | 27 | bool value) { |
diff --git a/src/core/hle/service/time/standard_user_system_clock_core.h b/src/core/hle/service/time/standard_user_system_clock_core.h index ef3d468b7..aac44d72f 100644 --- a/src/core/hle/service/time/standard_user_system_clock_core.h +++ b/src/core/hle/service/time/standard_user_system_clock_core.h | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "core/hle/kernel/writable_event.h" | ||
| 8 | #include "core/hle/service/time/clock_types.h" | 7 | #include "core/hle/service/time/clock_types.h" |
| 9 | #include "core/hle/service/time/system_clock_core.h" | 8 | #include "core/hle/service/time/system_clock_core.h" |
| 10 | 9 | ||
| @@ -12,6 +11,10 @@ namespace Core { | |||
| 12 | class System; | 11 | class System; |
| 13 | } | 12 | } |
| 14 | 13 | ||
| 14 | namespace Kernel { | ||
| 15 | class KEvent; | ||
| 16 | } | ||
| 17 | |||
| 15 | namespace Service::Time::Clock { | 18 | namespace Service::Time::Clock { |
| 16 | 19 | ||
| 17 | class StandardLocalSystemClockCore; | 20 | class StandardLocalSystemClockCore; |
| @@ -51,7 +54,7 @@ private: | |||
| 51 | StandardNetworkSystemClockCore& network_system_clock_core; | 54 | StandardNetworkSystemClockCore& network_system_clock_core; |
| 52 | bool auto_correction_enabled{}; | 55 | bool auto_correction_enabled{}; |
| 53 | SteadyClockTimePoint auto_correction_time; | 56 | SteadyClockTimePoint auto_correction_time; |
| 54 | Kernel::EventPair auto_correction_event; | 57 | std::shared_ptr<Kernel::KEvent> auto_correction_event; |
| 55 | }; | 58 | }; |
| 56 | 59 | ||
| 57 | } // namespace Service::Time::Clock | 60 | } // namespace Service::Time::Clock |
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.cpp b/src/core/hle/service/time/system_clock_context_update_callback.cpp index 5cdb80703..bca7d869e 100644 --- a/src/core/hle/service/time/system_clock_context_update_callback.cpp +++ b/src/core/hle/service/time/system_clock_context_update_callback.cpp | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/hle/kernel/writable_event.h" | 5 | #include "core/hle/kernel/k_writable_event.h" |
| 6 | #include "core/hle/service/time/errors.h" | 6 | #include "core/hle/service/time/errors.h" |
| 7 | #include "core/hle/service/time/system_clock_context_update_callback.h" | 7 | #include "core/hle/service/time/system_clock_context_update_callback.h" |
| 8 | 8 | ||
| @@ -21,7 +21,7 @@ bool SystemClockContextUpdateCallback::NeedUpdate(const SystemClockContext& valu | |||
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | void SystemClockContextUpdateCallback::RegisterOperationEvent( | 23 | void SystemClockContextUpdateCallback::RegisterOperationEvent( |
| 24 | std::shared_ptr<Kernel::WritableEvent>&& writable_event) { | 24 | std::shared_ptr<Kernel::KWritableEvent>&& writable_event) { |
| 25 | operation_event_list.emplace_back(std::move(writable_event)); | 25 | operation_event_list.emplace_back(std::move(writable_event)); |
| 26 | } | 26 | } |
| 27 | 27 | ||
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.h b/src/core/hle/service/time/system_clock_context_update_callback.h index 2b0fa7e75..797954958 100644 --- a/src/core/hle/service/time/system_clock_context_update_callback.h +++ b/src/core/hle/service/time/system_clock_context_update_callback.h | |||
| @@ -9,7 +9,7 @@ | |||
| 9 | #include "core/hle/service/time/clock_types.h" | 9 | #include "core/hle/service/time/clock_types.h" |
| 10 | 10 | ||
| 11 | namespace Kernel { | 11 | namespace Kernel { |
| 12 | class WritableEvent; | 12 | class KWritableEvent; |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | namespace Service::Time::Clock { | 15 | namespace Service::Time::Clock { |
| @@ -24,7 +24,7 @@ public: | |||
| 24 | 24 | ||
| 25 | bool NeedUpdate(const SystemClockContext& value) const; | 25 | bool NeedUpdate(const SystemClockContext& value) const; |
| 26 | 26 | ||
| 27 | void RegisterOperationEvent(std::shared_ptr<Kernel::WritableEvent>&& writable_event); | 27 | void RegisterOperationEvent(std::shared_ptr<Kernel::KWritableEvent>&& writable_event); |
| 28 | 28 | ||
| 29 | void BroadcastOperationEvent(); | 29 | void BroadcastOperationEvent(); |
| 30 | 30 | ||
| @@ -37,7 +37,7 @@ protected: | |||
| 37 | 37 | ||
| 38 | private: | 38 | private: |
| 39 | bool has_context{}; | 39 | bool has_context{}; |
| 40 | std::vector<std::shared_ptr<Kernel::WritableEvent>> operation_event_list; | 40 | std::vector<std::shared_ptr<Kernel::KWritableEvent>> operation_event_list; |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | } // namespace Service::Time::Clock | 43 | } // namespace Service::Time::Clock |
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp index 5a202ac81..7f42aa4a0 100644 --- a/src/core/hle/service/vi/display/vi_display.cpp +++ b/src/core/hle/service/vi/display/vi_display.cpp | |||
| @@ -9,7 +9,9 @@ | |||
| 9 | 9 | ||
| 10 | #include "common/assert.h" | 10 | #include "common/assert.h" |
| 11 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/hle/kernel/readable_event.h" | 12 | #include "core/hle/kernel/k_event.h" |
| 13 | #include "core/hle/kernel/k_readable_event.h" | ||
| 14 | #include "core/hle/kernel/k_writable_event.h" | ||
| 13 | #include "core/hle/service/vi/display/vi_display.h" | 15 | #include "core/hle/service/vi/display/vi_display.h" |
| 14 | #include "core/hle/service/vi/layer/vi_layer.h" | 16 | #include "core/hle/service/vi/layer/vi_layer.h" |
| 15 | 17 | ||
| @@ -17,8 +19,8 @@ namespace Service::VI { | |||
| 17 | 19 | ||
| 18 | Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} { | 20 | Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} { |
| 19 | auto& kernel = system.Kernel(); | 21 | auto& kernel = system.Kernel(); |
| 20 | vsync_event = | 22 | vsync_event = Kernel::KEvent::Create(kernel, fmt::format("Display VSync Event {}", id)); |
| 21 | Kernel::WritableEvent::CreateEventPair(kernel, fmt::format("Display VSync Event {}", id)); | 23 | vsync_event->Initialize(); |
| 22 | } | 24 | } |
| 23 | 25 | ||
| 24 | Display::~Display() = default; | 26 | Display::~Display() = default; |
| @@ -31,12 +33,12 @@ const Layer& Display::GetLayer(std::size_t index) const { | |||
| 31 | return *layers.at(index); | 33 | return *layers.at(index); |
| 32 | } | 34 | } |
| 33 | 35 | ||
| 34 | std::shared_ptr<Kernel::ReadableEvent> Display::GetVSyncEvent() const { | 36 | std::shared_ptr<Kernel::KReadableEvent> Display::GetVSyncEvent() const { |
| 35 | return vsync_event.readable; | 37 | return vsync_event->GetReadableEvent(); |
| 36 | } | 38 | } |
| 37 | 39 | ||
| 38 | void Display::SignalVSyncEvent() { | 40 | void Display::SignalVSyncEvent() { |
| 39 | vsync_event.writable->Signal(); | 41 | vsync_event->GetWritableEvent()->Signal(); |
| 40 | } | 42 | } |
| 41 | 43 | ||
| 42 | void Display::CreateLayer(u64 id, NVFlinger::BufferQueue& buffer_queue) { | 44 | void Display::CreateLayer(u64 id, NVFlinger::BufferQueue& buffer_queue) { |
diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h index a3855d8cd..931c898f6 100644 --- a/src/core/hle/service/vi/display/vi_display.h +++ b/src/core/hle/service/vi/display/vi_display.h | |||
| @@ -9,7 +9,10 @@ | |||
| 9 | #include <vector> | 9 | #include <vector> |
| 10 | 10 | ||
| 11 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 12 | #include "core/hle/kernel/writable_event.h" | 12 | |
| 13 | namespace Kernel { | ||
| 14 | class KEvent; | ||
| 15 | } | ||
| 13 | 16 | ||
| 14 | namespace Service::NVFlinger { | 17 | namespace Service::NVFlinger { |
| 15 | class BufferQueue; | 18 | class BufferQueue; |
| @@ -58,7 +61,7 @@ public: | |||
| 58 | const Layer& GetLayer(std::size_t index) const; | 61 | const Layer& GetLayer(std::size_t index) const; |
| 59 | 62 | ||
| 60 | /// Gets the readable vsync event. | 63 | /// Gets the readable vsync event. |
| 61 | std::shared_ptr<Kernel::ReadableEvent> GetVSyncEvent() const; | 64 | std::shared_ptr<Kernel::KReadableEvent> GetVSyncEvent() const; |
| 62 | 65 | ||
| 63 | /// Signals the internal vsync event. | 66 | /// Signals the internal vsync event. |
| 64 | void SignalVSyncEvent(); | 67 | void SignalVSyncEvent(); |
| @@ -99,7 +102,7 @@ private: | |||
| 99 | std::string name; | 102 | std::string name; |
| 100 | 103 | ||
| 101 | std::vector<std::shared_ptr<Layer>> layers; | 104 | std::vector<std::shared_ptr<Layer>> layers; |
| 102 | Kernel::EventPair vsync_event; | 105 | std::shared_ptr<Kernel::KEvent> vsync_event; |
| 103 | }; | 106 | }; |
| 104 | 107 | ||
| 105 | } // namespace Service::VI | 108 | } // namespace Service::VI |
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index f3de2c428..8661895ae 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -18,9 +18,9 @@ | |||
| 18 | #include "common/swap.h" | 18 | #include "common/swap.h" |
| 19 | #include "core/core_timing.h" | 19 | #include "core/core_timing.h" |
| 20 | #include "core/hle/ipc_helpers.h" | 20 | #include "core/hle/ipc_helpers.h" |
| 21 | #include "core/hle/kernel/k_readable_event.h" | ||
| 21 | #include "core/hle/kernel/k_thread.h" | 22 | #include "core/hle/kernel/k_thread.h" |
| 22 | #include "core/hle/kernel/readable_event.h" | 23 | #include "core/hle/kernel/k_writable_event.h" |
| 23 | #include "core/hle/kernel/writable_event.h" | ||
| 24 | #include "core/hle/service/nvdrv/nvdata.h" | 24 | #include "core/hle/service/nvdrv/nvdata.h" |
| 25 | #include "core/hle/service/nvdrv/nvdrv.h" | 25 | #include "core/hle/service/nvdrv/nvdrv.h" |
| 26 | #include "core/hle/service/nvflinger/buffer_queue.h" | 26 | #include "core/hle/service/nvflinger/buffer_queue.h" |
diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 39306509a..2ae5196e0 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp | |||
| @@ -70,6 +70,9 @@ void LogSettings() { | |||
| 70 | log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue()); | 70 | log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue()); |
| 71 | log_setting("Audio_OutputDevice", values.audio_device_id); | 71 | log_setting("Audio_OutputDevice", values.audio_device_id); |
| 72 | log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd); | 72 | log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd); |
| 73 | log_setting("DataStorage_CacheDir", Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)); | ||
| 74 | log_setting("DataStorage_ConfigDir", Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir)); | ||
| 75 | log_setting("DataStorage_LoadDir", Common::FS::GetUserPath(Common::FS::UserPath::LoadDir)); | ||
| 73 | log_setting("DataStorage_NandDir", Common::FS::GetUserPath(Common::FS::UserPath::NANDDir)); | 76 | log_setting("DataStorage_NandDir", Common::FS::GetUserPath(Common::FS::UserPath::NANDDir)); |
| 74 | log_setting("DataStorage_SdmcDir", Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir)); | 77 | log_setting("DataStorage_SdmcDir", Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir)); |
| 75 | log_setting("Debugging_ProgramArgs", values.program_args); | 78 | log_setting("Debugging_ProgramArgs", values.program_args); |
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 73f331d4c..28f2b8614 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt | |||
| @@ -20,6 +20,7 @@ set(SHADER_FILES | |||
| 20 | find_program(GLSLANGVALIDATOR "glslangValidator" REQUIRED) | 20 | find_program(GLSLANGVALIDATOR "glslangValidator" REQUIRED) |
| 21 | 21 | ||
| 22 | set(GLSL_FLAGS "") | 22 | set(GLSL_FLAGS "") |
| 23 | set(QUIET_FLAG "--quiet") | ||
| 23 | 24 | ||
| 24 | set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) | 25 | set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) |
| 25 | set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) | 26 | set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) |
| @@ -28,6 +29,23 @@ set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE) | |||
| 28 | set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in) | 29 | set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in) |
| 29 | set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake) | 30 | set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake) |
| 30 | 31 | ||
| 32 | # Check if `--quiet` is available on host's glslangValidator version | ||
| 33 | # glslangValidator prints to STDERR iff an unrecognized flag is passed to it | ||
| 34 | execute_process( | ||
| 35 | COMMAND | ||
| 36 | ${GLSLANGVALIDATOR} ${QUIET_FLAG} | ||
| 37 | ERROR_VARIABLE | ||
| 38 | GLSLANG_ERROR | ||
| 39 | # STDOUT variable defined to silence unnecessary output during CMake configuration | ||
| 40 | OUTPUT_VARIABLE | ||
| 41 | GLSLANG_OUTPUT | ||
| 42 | ) | ||
| 43 | |||
| 44 | if (NOT GLSLANG_ERROR STREQUAL "") | ||
| 45 | message(WARNING "Refusing to use unavailable flag `${QUIET_FLAG}` on `${GLSLANGVALIDATOR}`") | ||
| 46 | set(QUIET_FLAG "") | ||
| 47 | endif() | ||
| 48 | |||
| 31 | foreach(FILENAME IN ITEMS ${SHADER_FILES}) | 49 | foreach(FILENAME IN ITEMS ${SHADER_FILES}) |
| 32 | string(REPLACE "." "_" SHADER_NAME ${FILENAME}) | 50 | string(REPLACE "." "_" SHADER_NAME ${FILENAME}) |
| 33 | set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}) | 51 | set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}) |
| @@ -55,7 +73,7 @@ foreach(FILENAME IN ITEMS ${SHADER_FILES}) | |||
| 55 | OUTPUT | 73 | OUTPUT |
| 56 | ${SPIRV_HEADER_FILE} | 74 | ${SPIRV_HEADER_FILE} |
| 57 | COMMAND | 75 | COMMAND |
| 58 | ${GLSLANGVALIDATOR} -V --quiet ${GLSL_FLAGS} --variable-name ${SPIRV_VARIABLE_NAME} -o ${SPIRV_HEADER_FILE} ${SOURCE_FILE} | 76 | ${GLSLANGVALIDATOR} -V ${QUIET_FLAG} ${GLSL_FLAGS} --variable-name ${SPIRV_VARIABLE_NAME} -o ${SPIRV_HEADER_FILE} ${SOURCE_FILE} |
| 59 | MAIN_DEPENDENCY | 77 | MAIN_DEPENDENCY |
| 60 | ${SOURCE_FILE} | 78 | ${SOURCE_FILE} |
| 61 | ) | 79 | ) |
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index fbe36046b..b40d7c5e2 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -580,9 +580,7 @@ void ConfigureInputPlayer::ApplyConfiguration() { | |||
| 580 | if (player_index == 0) { | 580 | if (player_index == 0) { |
| 581 | auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; | 581 | auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; |
| 582 | const auto handheld_connected = handheld.connected; | 582 | const auto handheld_connected = handheld.connected; |
| 583 | if (player.controller_type == Settings::ControllerType::Handheld) { | 583 | handheld = player; |
| 584 | handheld = player; | ||
| 585 | } | ||
| 586 | handheld.connected = handheld_connected; | 584 | handheld.connected = handheld_connected; |
| 587 | } | 585 | } |
| 588 | } | 586 | } |
| @@ -596,7 +594,7 @@ void ConfigureInputPlayer::TryConnectSelectedController() { | |||
| 596 | controller_type != Settings::ControllerType::Handheld; | 594 | controller_type != Settings::ControllerType::Handheld; |
| 597 | 595 | ||
| 598 | // Connect Handheld depending on Player 1's controller configuration. | 596 | // Connect Handheld depending on Player 1's controller configuration. |
| 599 | if (player_index == 0 && controller_type == Settings::ControllerType::Handheld) { | 597 | if (player_index == 0) { |
| 600 | auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; | 598 | auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; |
| 601 | const auto handheld_connected = ui->groupConnectedController->isChecked() && | 599 | const auto handheld_connected = ui->groupConnectedController->isChecked() && |
| 602 | controller_type == Settings::ControllerType::Handheld; | 600 | controller_type == Settings::ControllerType::Handheld; |
| @@ -886,7 +884,7 @@ void ConfigureInputPlayer::SetConnectableControllers() { | |||
| 886 | index_controller_type_pairs.clear(); | 884 | index_controller_type_pairs.clear(); |
| 887 | ui->comboControllerType->clear(); | 885 | ui->comboControllerType->clear(); |
| 888 | 886 | ||
| 889 | if (enable_all || npad_style_set.pro_controller == 1) { | 887 | if (enable_all || npad_style_set.fullkey == 1) { |
| 890 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), | 888 | index_controller_type_pairs.emplace_back(ui->comboControllerType->count(), |
| 891 | Settings::ControllerType::ProController); | 889 | Settings::ControllerType::ProController); |
| 892 | ui->comboControllerType->addItem(tr("Pro Controller")); | 890 | ui->comboControllerType->addItem(tr("Pro Controller")); |
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp index d102a43af..51647a028 100644 --- a/src/yuzu/configuration/configure_profile_manager.cpp +++ b/src/yuzu/configuration/configure_profile_manager.cpp | |||
| @@ -116,8 +116,8 @@ ConfigureProfileManager ::ConfigureProfileManager(QWidget* parent) | |||
| 116 | scene = new QGraphicsScene; | 116 | scene = new QGraphicsScene; |
| 117 | ui->current_user_icon->setScene(scene); | 117 | ui->current_user_icon->setScene(scene); |
| 118 | 118 | ||
| 119 | SetConfiguration(); | ||
| 120 | RetranslateUI(); | 119 | RetranslateUI(); |
| 120 | SetConfiguration(); | ||
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | ConfigureProfileManager::~ConfigureProfileManager() = default; | 123 | ConfigureProfileManager::~ConfigureProfileManager() = default; |
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 0e5156dcc..3bca6277b 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp | |||
| @@ -13,11 +13,11 @@ | |||
| 13 | #include "core/arm/arm_interface.h" | 13 | #include "core/arm/arm_interface.h" |
| 14 | #include "core/core.h" | 14 | #include "core/core.h" |
| 15 | #include "core/hle/kernel/handle_table.h" | 15 | #include "core/hle/kernel/handle_table.h" |
| 16 | #include "core/hle/kernel/k_readable_event.h" | ||
| 16 | #include "core/hle/kernel/k_scheduler.h" | 17 | #include "core/hle/kernel/k_scheduler.h" |
| 17 | #include "core/hle/kernel/k_synchronization_object.h" | 18 | #include "core/hle/kernel/k_synchronization_object.h" |
| 18 | #include "core/hle/kernel/k_thread.h" | 19 | #include "core/hle/kernel/k_thread.h" |
| 19 | #include "core/hle/kernel/process.h" | 20 | #include "core/hle/kernel/process.h" |
| 20 | #include "core/hle/kernel/readable_event.h" | ||
| 21 | #include "core/hle/kernel/svc_common.h" | 21 | #include "core/hle/kernel/svc_common.h" |
| 22 | #include "core/hle/kernel/svc_types.h" | 22 | #include "core/hle/kernel/svc_types.h" |
| 23 | #include "core/memory.h" | 23 | #include "core/memory.h" |
| @@ -193,7 +193,7 @@ std::unique_ptr<WaitTreeSynchronizationObject> WaitTreeSynchronizationObject::ma | |||
| 193 | const Kernel::KSynchronizationObject& object) { | 193 | const Kernel::KSynchronizationObject& object) { |
| 194 | switch (object.GetHandleType()) { | 194 | switch (object.GetHandleType()) { |
| 195 | case Kernel::HandleType::ReadableEvent: | 195 | case Kernel::HandleType::ReadableEvent: |
| 196 | return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::ReadableEvent&>(object)); | 196 | return std::make_unique<WaitTreeEvent>(static_cast<const Kernel::KReadableEvent&>(object)); |
| 197 | case Kernel::HandleType::Thread: | 197 | case Kernel::HandleType::Thread: |
| 198 | return std::make_unique<WaitTreeThread>(static_cast<const Kernel::KThread&>(object)); | 198 | return std::make_unique<WaitTreeThread>(static_cast<const Kernel::KThread&>(object)); |
| 199 | default: | 199 | default: |
| @@ -373,7 +373,7 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const { | |||
| 373 | return list; | 373 | return list; |
| 374 | } | 374 | } |
| 375 | 375 | ||
| 376 | WaitTreeEvent::WaitTreeEvent(const Kernel::ReadableEvent& object) | 376 | WaitTreeEvent::WaitTreeEvent(const Kernel::KReadableEvent& object) |
| 377 | : WaitTreeSynchronizationObject(object) {} | 377 | : WaitTreeSynchronizationObject(object) {} |
| 378 | WaitTreeEvent::~WaitTreeEvent() = default; | 378 | WaitTreeEvent::~WaitTreeEvent() = default; |
| 379 | 379 | ||
diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index b202c5567..3da2fdfd2 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h | |||
| @@ -18,9 +18,9 @@ class EmuThread; | |||
| 18 | 18 | ||
| 19 | namespace Kernel { | 19 | namespace Kernel { |
| 20 | class HandleTable; | 20 | class HandleTable; |
| 21 | class KReadableEvent; | ||
| 21 | class KSynchronizationObject; | 22 | class KSynchronizationObject; |
| 22 | class KThread; | 23 | class KThread; |
| 23 | class ReadableEvent; | ||
| 24 | } // namespace Kernel | 24 | } // namespace Kernel |
| 25 | 25 | ||
| 26 | class WaitTreeThread; | 26 | class WaitTreeThread; |
| @@ -142,7 +142,7 @@ public: | |||
| 142 | class WaitTreeEvent : public WaitTreeSynchronizationObject { | 142 | class WaitTreeEvent : public WaitTreeSynchronizationObject { |
| 143 | Q_OBJECT | 143 | Q_OBJECT |
| 144 | public: | 144 | public: |
| 145 | explicit WaitTreeEvent(const Kernel::ReadableEvent& object); | 145 | explicit WaitTreeEvent(const Kernel::KReadableEvent& object); |
| 146 | ~WaitTreeEvent() override; | 146 | ~WaitTreeEvent() override; |
| 147 | }; | 147 | }; |
| 148 | 148 | ||