From 9e924f2ef2add0f351df6addc01c356b52c8d7be Mon Sep 17 00:00:00 2001
From: David Marcec <dmarcecguzman@gmail.com>
Date: Thu, 11 Oct 2018 00:58:47 +1100
Subject: [PATCH] Added BeginPermitVibrationSession and
 EndPermitVibrationSession

Used by Mario Party
---
 src/core/hle/service/hid/controllers/npad.cpp |  6 ++++++
 src/core/hle/service/hid/controllers/npad.h   |  2 ++
 src/core/hle/service/hid/hid.cpp              | 20 +++++++++++++++++--
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 069e0d5de..27b38abab 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -316,6 +316,9 @@ void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode)
 
 void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
                                         const std::vector<Vibration>& vibrations) {
+    if (!can_controllers_vibrate) {
+        return;
+    }
     for (std::size_t i = 0; i < controller_ids.size(); i++) {
         if (i >= controller_count) {
             continue;
@@ -386,4 +389,7 @@ Controller_NPad::LedPattern Controller_NPad::GetLedPattern(u32 npad_id) {
         return LedPattern{0, 0, 0, 0};
     };
 }
+void Controller_NPad::SetVibrationEnabled(bool can_vibrate) {
+    can_controllers_vibrate = can_vibrate;
+}
 } // namespace Service::HID
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 28c89768c..b1aa98820 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -111,6 +111,7 @@ public:
     void ConnectNPad(u32 npad_id);
     void DisconnectNPad(u32 npad_id);
     LedPattern GetLedPattern(u32 npad_id);
+    void SetVibrationEnabled(bool can_vibrate);
 
 private:
     struct CommonHeader {
@@ -275,6 +276,7 @@ private:
     std::size_t controller_count{};
     static constexpr std::array<u32, 10> npad_id_list{0, 1, 2, 3, 4, 5, 6, 7, 32, 16};
     std::array<ControllerHolder, 10> connected_controllers{};
+    bool can_controllers_vibrate{true};
 
     void InitNewlyAddedControler(std::size_t controller_idx);
 };
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 4c0d96cc2..65ee1d9bb 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -240,8 +240,8 @@ public:
             {206, &Hid::SendVibrationValues, "SendVibrationValues"},
             {207, nullptr, "SendVibrationGcErmCommand"},
             {208, nullptr, "GetActualVibrationGcErmCommand"},
-            {209, nullptr, "BeginPermitVibrationSession"},
-            {210, nullptr, "EndPermitVibrationSession"},
+            {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
+            {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"},
             {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
             {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
             {302, nullptr, "StopConsoleSixAxisSensor"},
@@ -457,6 +457,22 @@ private:
         LOG_WARNING(Service_HID, "(STUBBED) called");
     }
 
+    void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
+        applet_resource->GetController<Controller_NPad>(HidController::NPad)
+            .SetVibrationEnabled(true);
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(RESULT_SUCCESS);
+        LOG_DEBUG(Service_HID, "called");
+    }
+
+    void EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
+        applet_resource->GetController<Controller_NPad>(HidController::NPad)
+            .SetVibrationEnabled(false);
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(RESULT_SUCCESS);
+        LOG_DEBUG(Service_HID, "called");
+    }
+
     void SendVibrationValue(Kernel::HLERequestContext& ctx) {
         IPC::RequestParser rp{ctx};
         const auto controller_id = rp.PopRaw<u32>();