diff options
Diffstat (limited to 'src/core/hle')
-rw-r--r-- | src/core/hle/ipc.h | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 55 | ||||
-rw-r--r-- | src/core/hle/kernel/scheduler.h | 109 | ||||
-rw-r--r-- | src/core/hle/service/am/am.cpp | 31 | ||||
-rw-r--r-- | src/core/hle/service/am/am.h | 3 | ||||
-rw-r--r-- | src/core/hle/service/am/applets/error.cpp | 11 | ||||
-rw-r--r-- | src/core/hle/service/hid/hid.cpp | 204 | ||||
-rw-r--r-- | src/core/hle/service/hid/hid.h | 14 | ||||
-rw-r--r-- | src/core/hle/service/vi/vi.cpp | 2 |
9 files changed, 241 insertions, 194 deletions
diff --git a/src/core/hle/ipc.h b/src/core/hle/ipc.h index fae54bcc7..7ce313190 100644 --- a/src/core/hle/ipc.h +++ b/src/core/hle/ipc.h @@ -160,7 +160,7 @@ struct DomainMessageHeader { // Used when responding to an IPC request, Server -> Client. struct { u32_le num_objects; - INSERT_PADDING_WORDS(3); + INSERT_UNION_PADDING_WORDS(3); }; // Used when performing an IPC request, Client -> Server. @@ -171,8 +171,10 @@ struct DomainMessageHeader { BitField<16, 16, u32> size; }; u32_le object_id; - INSERT_PADDING_WORDS(2); + INSERT_UNION_PADDING_WORDS(2); }; + + std::array<u32, 4> raw{}; }; }; static_assert(sizeof(DomainMessageHeader) == 16, "DomainMessageHeader size is incorrect"); diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index e6dcb9639..0e2dbf13e 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -22,9 +22,9 @@ namespace Kernel { -GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} { - is_reselection_pending = false; -} +GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} {} + +GlobalScheduler::~GlobalScheduler() = default; void GlobalScheduler::AddThread(SharedPtr<Thread> thread) { thread_list.push_back(std::move(thread)); @@ -35,24 +35,11 @@ void GlobalScheduler::RemoveThread(const Thread* thread) { thread_list.end()); } -/* - * UnloadThread selects a core and forces it to unload its current thread's context - */ void GlobalScheduler::UnloadThread(s32 core) { Scheduler& sched = system.Scheduler(core); sched.UnloadThread(); } -/* - * SelectThread takes care of selecting the new scheduled thread. - * It does it in 3 steps: - * - First a thread is selected from the top of the priority queue. If no thread - * is obtained then we move to step two, else we are done. - * - Second we try to get a suggested thread that's not assigned to any core or - * that is not the top thread in that core. - * - Third is no suggested thread is found, we do a second pass and pick a running - * thread in another core and swap it with its current thread. - */ void GlobalScheduler::SelectThread(u32 core) { const auto update_thread = [](Thread* thread, Scheduler& sched) { if (thread != sched.selected_thread) { @@ -114,30 +101,19 @@ void GlobalScheduler::SelectThread(u32 core) { update_thread(current_thread, sched); } -/* - * YieldThread takes a thread and moves it to the back of the it's priority list - * This operation can be redundant and no scheduling is changed if marked as so. - */ bool GlobalScheduler::YieldThread(Thread* yielding_thread) { // Note: caller should use critical section, etc. const u32 core_id = static_cast<u32>(yielding_thread->GetProcessorID()); const u32 priority = yielding_thread->GetPriority(); // Yield the thread - ASSERT_MSG(yielding_thread == scheduled_queue[core_id].front(priority), - "Thread yielding without being in front"); + const Thread* const winner = scheduled_queue[core_id].front(priority); + ASSERT_MSG(yielding_thread == winner, "Thread yielding without being in front"); scheduled_queue[core_id].yield(priority); - Thread* winner = scheduled_queue[core_id].front(priority); return AskForReselectionOrMarkRedundant(yielding_thread, winner); } -/* - * YieldThreadAndBalanceLoad takes a thread and moves it to the back of the it's priority list. - * Afterwards, tries to pick a suggested thread from the suggested queue that has worse time or - * a better priority than the next thread in the core. - * This operation can be redundant and no scheduling is changed if marked as so. - */ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) { // Note: caller should check if !thread.IsSchedulerOperationRedundant and use critical section, // etc. @@ -189,12 +165,6 @@ bool GlobalScheduler::YieldThreadAndBalanceLoad(Thread* yielding_thread) { return AskForReselectionOrMarkRedundant(yielding_thread, winner); } -/* - * YieldThreadAndWaitForLoadBalancing takes a thread and moves it out of the scheduling queue - * and into the suggested queue. If no thread can be squeduled afterwards in that core, - * a suggested thread is obtained instead. - * This operation can be redundant and no scheduling is changed if marked as so. - */ bool GlobalScheduler::YieldThreadAndWaitForLoadBalancing(Thread* yielding_thread) { // Note: caller should check if !thread.IsSchedulerOperationRedundant and use critical section, // etc. @@ -280,7 +250,7 @@ void GlobalScheduler::PreemptThreads() { if (winner->IsRunning()) { UnloadThread(winner->GetProcessorID()); } - TransferToCore(winner->GetPriority(), core_id, winner); + TransferToCore(winner->GetPriority(), s32(core_id), winner); current_thread = winner->GetPriority() <= current_thread->GetPriority() ? winner : current_thread; } @@ -313,7 +283,7 @@ void GlobalScheduler::PreemptThreads() { if (winner->IsRunning()) { UnloadThread(winner->GetProcessorID()); } - TransferToCore(winner->GetPriority(), core_id, winner); + TransferToCore(winner->GetPriority(), s32(core_id), winner); current_thread = winner; } } @@ -331,12 +301,12 @@ void GlobalScheduler::Unsuggest(u32 priority, u32 core, Thread* thread) { } void GlobalScheduler::Schedule(u32 priority, u32 core, Thread* thread) { - ASSERT_MSG(thread->GetProcessorID() == core, "Thread must be assigned to this core."); + ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core."); scheduled_queue[core].add(thread, priority); } void GlobalScheduler::SchedulePrepend(u32 priority, u32 core, Thread* thread) { - ASSERT_MSG(thread->GetProcessorID() == core, "Thread must be assigned to this core."); + ASSERT_MSG(thread->GetProcessorID() == s32(core), "Thread must be assigned to this core."); scheduled_queue[core].add(thread, priority, false); } @@ -368,7 +338,8 @@ void GlobalScheduler::TransferToCore(u32 priority, s32 destination_core, Thread* } } -bool GlobalScheduler::AskForReselectionOrMarkRedundant(Thread* current_thread, Thread* winner) { +bool GlobalScheduler::AskForReselectionOrMarkRedundant(Thread* current_thread, + const Thread* winner) { if (current_thread == winner) { current_thread->IncrementYieldCount(); return true; @@ -386,8 +357,6 @@ void GlobalScheduler::Shutdown() { thread_list.clear(); } -GlobalScheduler::~GlobalScheduler() = default; - Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, u32 core_id) : system(system), cpu_core(cpu_core), core_id(core_id) {} @@ -470,7 +439,7 @@ void Scheduler::SwitchContext() { // Load context of new thread if (new_thread) { - ASSERT_MSG(new_thread->GetProcessorID() == this->core_id, + ASSERT_MSG(new_thread->GetProcessorID() == s32(this->core_id), "Thread must be assigned to this core."); ASSERT_MSG(new_thread->GetStatus() == ThreadStatus::Ready, "Thread must be ready to become running."); diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h index fcae28e0a..f2d6311b8 100644 --- a/src/core/hle/kernel/scheduler.h +++ b/src/core/hle/kernel/scheduler.h @@ -26,6 +26,7 @@ public: explicit GlobalScheduler(Core::System& system); ~GlobalScheduler(); + /// Adds a new thread to the scheduler void AddThread(SharedPtr<Thread> thread); @@ -37,47 +38,57 @@ public: return thread_list; } - // Add a thread to the suggested queue of a cpu core. Suggested threads may be - // picked if no thread is scheduled to run on the core. + /** + * Add a thread to the suggested queue of a cpu core. Suggested threads may be + * picked if no thread is scheduled to run on the core. + */ void Suggest(u32 priority, u32 core, Thread* thread); - // Remove a thread to the suggested queue of a cpu core. Suggested threads may be - // picked if no thread is scheduled to run on the core. + /** + * Remove a thread to the suggested queue of a cpu core. Suggested threads may be + * picked if no thread is scheduled to run on the core. + */ void Unsuggest(u32 priority, u32 core, Thread* thread); - // Add a thread to the scheduling queue of a cpu core. The thread is added at the - // back the queue in its priority level + /** + * Add a thread to the scheduling queue of a cpu core. The thread is added at the + * back the queue in its priority level. + */ void Schedule(u32 priority, u32 core, Thread* thread); - // Add a thread to the scheduling queue of a cpu core. The thread is added at the - // front the queue in its priority level + /** + * Add a thread to the scheduling queue of a cpu core. The thread is added at the + * front the queue in its priority level. + */ void SchedulePrepend(u32 priority, u32 core, Thread* thread); - // Reschedule an already scheduled thread based on a new priority + /// Reschedule an already scheduled thread based on a new priority void Reschedule(u32 priority, u32 core, Thread* thread); - // Unschedule a thread. + /// Unschedules a thread. void Unschedule(u32 priority, u32 core, Thread* thread); - // Transfers a thread into an specific core. If the destination_core is -1 - // it will be unscheduled from its source code and added into its suggested - // queue. + /** + * Transfers a thread into an specific core. If the destination_core is -1 + * it will be unscheduled from its source code and added into its suggested + * queue. + */ void TransferToCore(u32 priority, s32 destination_core, Thread* thread); - /* - * UnloadThread selects a core and forces it to unload its current thread's context - */ + /// Selects a core and forces it to unload its current thread's context void UnloadThread(s32 core); - /* - * SelectThread takes care of selecting the new scheduled thread. - * It does it in 3 steps: - * - First a thread is selected from the top of the priority queue. If no thread - * is obtained then we move to step two, else we are done. - * - Second we try to get a suggested thread that's not assigned to any core or - * that is not the top thread in that core. - * - Third is no suggested thread is found, we do a second pass and pick a running - * thread in another core and swap it with its current thread. + /** + * Takes care of selecting the new scheduled thread in three steps: + * + * 1. First a thread is selected from the top of the priority queue. If no thread + * is obtained then we move to step two, else we are done. + * + * 2. Second we try to get a suggested thread that's not assigned to any core or + * that is not the top thread in that core. + * + * 3. Third is no suggested thread is found, we do a second pass and pick a running + * thread in another core and swap it with its current thread. */ void SelectThread(u32 core); @@ -85,33 +96,37 @@ public: return !scheduled_queue[core_id].empty(); } - /* - * YieldThread takes a thread and moves it to the back of the it's priority list - * This operation can be redundant and no scheduling is changed if marked as so. + /** + * Takes a thread and moves it to the back of the it's priority list. + * + * @note This operation can be redundant and no scheduling is changed if marked as so. */ bool YieldThread(Thread* thread); - /* - * YieldThreadAndBalanceLoad takes a thread and moves it to the back of the it's priority list. + /** + * Takes a thread and moves it to the back of the it's priority list. * Afterwards, tries to pick a suggested thread from the suggested queue that has worse time or * a better priority than the next thread in the core. - * This operation can be redundant and no scheduling is changed if marked as so. + * + * @note This operation can be redundant and no scheduling is changed if marked as so. */ bool YieldThreadAndBalanceLoad(Thread* thread); - /* - * YieldThreadAndWaitForLoadBalancing takes a thread and moves it out of the scheduling queue - * and into the suggested queue. If no thread can be squeduled afterwards in that core, + /** + * Takes a thread and moves it out of the scheduling queue. + * and into the suggested queue. If no thread can be scheduled afterwards in that core, * a suggested thread is obtained instead. - * This operation can be redundant and no scheduling is changed if marked as so. + * + * @note This operation can be redundant and no scheduling is changed if marked as so. */ bool YieldThreadAndWaitForLoadBalancing(Thread* thread); - /* - * PreemptThreads this operation rotates the scheduling queues of threads at - * a preemption priority and then does some core rebalancing. Preemption priorities - * can be found in the array 'preemption_priorities'. This operation happens - * every 10ms. + /** + * Rotates the scheduling queues of threads at a preemption priority and then does + * some core rebalancing. Preemption priorities can be found in the array + * 'preemption_priorities'. + * + * @note This operation happens every 10ms. */ void PreemptThreads(); @@ -130,15 +145,15 @@ public: void Shutdown(); private: - bool AskForReselectionOrMarkRedundant(Thread* current_thread, Thread* winner); + bool AskForReselectionOrMarkRedundant(Thread* current_thread, const Thread* winner); static constexpr u32 min_regular_priority = 2; std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> scheduled_queue; std::array<Common::MultiLevelQueue<Thread*, THREADPRIO_COUNT>, NUM_CPU_CORES> suggested_queue; - std::atomic<bool> is_reselection_pending; + std::atomic<bool> is_reselection_pending{false}; - // `preemption_priorities` are the priority levels at which the global scheduler - // preempts threads every 10 ms. They are ordered from Core 0 to Core 3 + // The priority levels at which the global scheduler preempts threads every 10 ms. They are + // ordered from Core 0 to Core 3. std::array<u32, NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62}; /// Lists all thread ids that aren't deleted/etc. @@ -181,10 +196,8 @@ public: private: friend class GlobalScheduler; - /** - * Switches the CPU's active thread context to that of the specified thread - * @param new_thread The thread to switch to - */ + + /// Switches the CPU's active thread context to that of the specified thread void SwitchContext(); /** diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 3a32d5b41..3d8a91d22 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1073,9 +1073,9 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) {71, nullptr, "RequestToReboot"}, {80, nullptr, "ExitAndRequestToShowThanksMessage"}, {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"}, - {100, nullptr, "InitializeApplicationCopyrightFrameBuffer"}, - {101, nullptr, "SetApplicationCopyrightImage"}, - {102, nullptr, "SetApplicationCopyrightVisibility"}, + {100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"}, + {101, &IApplicationFunctions::SetApplicationCopyrightImage, "SetApplicationCopyrightImage"}, + {102, &IApplicationFunctions::SetApplicationCopyrightVisibility, "SetApplicationCopyrightVisibility"}, {110, nullptr, "QueryApplicationPlayStatistics"}, {120, nullptr, "ExecuteProgram"}, {121, nullptr, "ClearUserChannel"}, @@ -1103,6 +1103,31 @@ void IApplicationFunctions::EnableApplicationCrashReport(Kernel::HLERequestConte rb.Push(RESULT_SUCCESS); } +void IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer( + Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void IApplicationFunctions::SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void IApplicationFunctions::SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto is_visible = rp.Pop<bool>(); + + LOG_WARNING(Service_AM, "(STUBBED) called, is_visible={}", is_visible); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + void IApplicationFunctions::BeginBlockingHomeButtonShortAndLongPressed( Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_AM, "(STUBBED) called"); diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index ccd053c13..2ae9402a8 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -252,6 +252,9 @@ private: void BeginBlockingHomeButton(Kernel::HLERequestContext& ctx); void EndBlockingHomeButton(Kernel::HLERequestContext& ctx); void EnableApplicationCrashReport(Kernel::HLERequestContext& ctx); + void InitializeApplicationCopyrightFrameBuffer(Kernel::HLERequestContext& ctx); + void SetApplicationCopyrightImage(Kernel::HLERequestContext& ctx); + void SetApplicationCopyrightVisibility(Kernel::HLERequestContext& ctx); void GetGpuErrorDetectedSystemEvent(Kernel::HLERequestContext& ctx); bool launch_popped_application_specific = false; diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp index a7db26725..eab0d42c9 100644 --- a/src/core/hle/service/am/applets/error.cpp +++ b/src/core/hle/service/am/applets/error.cpp @@ -20,9 +20,9 @@ namespace Service::AM::Applets { struct ShowError { u8 mode; bool jump; - INSERT_PADDING_BYTES(4); + INSERT_UNION_PADDING_BYTES(4); bool use_64bit_error_code; - INSERT_PADDING_BYTES(1); + INSERT_UNION_PADDING_BYTES(1); u64 error_code_64; u32 error_code_32; }; @@ -32,7 +32,7 @@ static_assert(sizeof(ShowError) == 0x14, "ShowError has incorrect size."); struct ShowErrorRecord { u8 mode; bool jump; - INSERT_PADDING_BYTES(6); + INSERT_UNION_PADDING_BYTES(6); u64 error_code_64; u64 posix_time; }; @@ -41,7 +41,7 @@ static_assert(sizeof(ShowErrorRecord) == 0x18, "ShowErrorRecord has incorrect si struct SystemErrorArg { u8 mode; bool jump; - INSERT_PADDING_BYTES(6); + INSERT_UNION_PADDING_BYTES(6); u64 error_code_64; std::array<char, 8> language_code; std::array<char, 0x800> main_text; @@ -52,7 +52,7 @@ static_assert(sizeof(SystemErrorArg) == 0x1018, "SystemErrorArg has incorrect si struct ApplicationErrorArg { u8 mode; bool jump; - INSERT_PADDING_BYTES(6); + INSERT_UNION_PADDING_BYTES(6); u32 error_code; std::array<char, 8> language_code; std::array<char, 0x800> main_text; @@ -65,6 +65,7 @@ union Error::ErrorArguments { ShowErrorRecord error_record; SystemErrorArg system_error; ApplicationErrorArg application_error; + std::array<u8, 0x1018> raw{}; }; namespace { diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index ba1da4181..ecc130f6c 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -203,13 +203,13 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) { {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"}, {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"}, {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"}, - {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"}, + {123, &Hid::SetNpadJoyAssignmentModeSingle, "SetNpadJoyAssignmentModeSingle"}, {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"}, {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"}, {126, &Hid::StartLrAssignmentMode, "StartLrAssignmentMode"}, {127, &Hid::StopLrAssignmentMode, "StopLrAssignmentMode"}, {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"}, - {129, nullptr, "GetNpadHandheldActivationMode"}, + {129, &Hid::GetNpadHandheldActivationMode, "GetNpadHandheldActivationMode"}, {130, &Hid::SwapNpadAssignment, "SwapNpadAssignment"}, {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"}, {132, nullptr, "EnableUnintendedHomeButtonInputProtection"}, @@ -557,10 +557,126 @@ void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id, applet_resource_user_id); + auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); + controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx) { + // TODO: Check the differences between this and SetNpadJoyAssignmentModeSingleByDefault + IPC::RequestParser rp{ctx}; + const auto npad_id{rp.Pop<u32>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + const auto npad_joy_device_type{rp.Pop<u64>()}; + + LOG_WARNING(Service_HID, + "(STUBBED) called, npad_id={}, applet_resource_user_id={}, npad_joy_device_type={}", + npad_id, applet_resource_user_id, npad_joy_device_type); + + auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); + controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Single); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto npad_id{rp.Pop<u32>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id, + applet_resource_user_id); + + auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); + controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto unknown_1{rp.Pop<u32>()}; + const auto unknown_2{rp.Pop<u32>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING(Service_HID, + "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", + unknown_1, unknown_2, applet_resource_user_id); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); + controller.StartLRAssignmentMode(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); + auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); + controller.StopLRAssignmentMode(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + const auto mode{rp.Pop<u64>()}; + + LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}", + applet_resource_user_id, mode); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void Hid::GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", + applet_resource_user_id); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } +void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto npad_1{rp.Pop<u32>()}; + const auto npad_2{rp.Pop<u32>()}; + const auto applet_resource_user_id{rp.Pop<u64>()}; + + LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}", + applet_resource_user_id, npad_1, npad_2); + + auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); + IPC::ResponseBuilder rb{ctx, 2}; + if (controller.SwapNpadAssignment(npad_1, npad_2)) { + rb.Push(RESULT_SUCCESS); + } else { + LOG_ERROR(Service_HID, "Npads are not connected!"); + rb.Push(ERR_NPAD_NOT_CONNECTED); + } +} + void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto applet_resource_user_id{rp.Pop<u64>()}; @@ -635,47 +751,6 @@ void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) { applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration()); } -void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto npad_id{rp.Pop<u32>()}; - const auto applet_resource_user_id{rp.Pop<u64>()}; - - LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id, - applet_resource_user_id); - - auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); - controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_SUCCESS); -} - -void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto unknown_1{rp.Pop<u32>()}; - const auto unknown_2{rp.Pop<u32>()}; - const auto applet_resource_user_id{rp.Pop<u64>()}; - - LOG_WARNING(Service_HID, - "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", - unknown_1, unknown_2, applet_resource_user_id); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_SUCCESS); -} - -void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto applet_resource_user_id{rp.Pop<u64>()}; - const auto mode{rp.Pop<u64>()}; - - LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}", - applet_resource_user_id, mode); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_SUCCESS); -} - void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_HID, "called"); @@ -769,49 +844,6 @@ void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) { rb.Push(RESULT_SUCCESS); } -void Hid::StartLrAssignmentMode(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto applet_resource_user_id{rp.Pop<u64>()}; - - LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); - auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); - controller.StartLRAssignmentMode(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_SUCCESS); -} - -void Hid::StopLrAssignmentMode(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto applet_resource_user_id{rp.Pop<u64>()}; - - LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); - auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); - controller.StopLRAssignmentMode(); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(RESULT_SUCCESS); -} - -void Hid::SwapNpadAssignment(Kernel::HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto npad_1{rp.Pop<u32>()}; - const auto npad_2{rp.Pop<u32>()}; - const auto applet_resource_user_id{rp.Pop<u64>()}; - - LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, npad_1={}, npad_2={}", - applet_resource_user_id, npad_1, npad_2); - - auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); - IPC::ResponseBuilder rb{ctx, 2}; - if (controller.SwapNpadAssignment(npad_1, npad_2)) { - rb.Push(RESULT_SUCCESS); - } else { - LOG_ERROR(Service_HID, "Npads are not connected!"); - rb.Push(ERR_NPAD_NOT_CONNECTED); - } -} - class HidDbg final : public ServiceFramework<HidDbg> { public: explicit HidDbg() : ServiceFramework{"hid:dbg"} { diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 01852e019..f08e036a3 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -106,14 +106,19 @@ private: void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx); void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx); void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx); + void SetNpadJoyAssignmentModeSingle(Kernel::HLERequestContext& ctx); + void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx); + void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx); + void StartLrAssignmentMode(Kernel::HLERequestContext& ctx); + void StopLrAssignmentMode(Kernel::HLERequestContext& ctx); + void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); + void GetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); + void SwapNpadAssignment(Kernel::HLERequestContext& ctx); void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx); void EndPermitVibrationSession(Kernel::HLERequestContext& ctx); void SendVibrationValue(Kernel::HLERequestContext& ctx); void SendVibrationValues(Kernel::HLERequestContext& ctx); void GetActualVibrationValue(Kernel::HLERequestContext& ctx); - void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx); - void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx); - void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx); void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx); void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx); void PermitVibration(Kernel::HLERequestContext& ctx); @@ -123,9 +128,6 @@ private: void StopSixAxisSensor(Kernel::HLERequestContext& ctx); void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx); void SetPalmaBoostMode(Kernel::HLERequestContext& ctx); - void StartLrAssignmentMode(Kernel::HLERequestContext& ctx); - void StopLrAssignmentMode(Kernel::HLERequestContext& ctx); - void SwapNpadAssignment(Kernel::HLERequestContext& ctx); std::shared_ptr<IAppletResource> applet_resource; Core::System& system; diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 199b30635..611cecc20 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -45,7 +45,7 @@ struct DisplayInfo { /// Whether or not the display has a limited number of layers. u8 has_limited_layers{1}; - INSERT_PADDING_BYTES(7){}; + INSERT_PADDING_BYTES(7); /// Indicates the total amount of layers supported by the display. /// @note This is only valid if has_limited_layers is set. |