summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2019-01-10 17:04:38 -0500
committerGravatar GitHub2019-01-10 17:04:38 -0500
commit83e8ad23310937bb72f4412c15f45231a19202f7 (patch)
tree80301af69b14a701f16e21d41ced436850085031 /src/core
parentMerge pull request #2010 from ReinUsesLisp/gmem (diff)
parentbuild: Copy web engine resources to correct location (diff)
downloadyuzu-83e8ad23310937bb72f4412c15f45231a19202f7.tar.gz
yuzu-83e8ad23310937bb72f4412c15f45231a19202f7.tar.xz
yuzu-83e8ad23310937bb72f4412c15f45231a19202f7.zip
Merge pull request #1939 from DarkLordZach/web-applet
applets: Implement HLE web browser applet (LibAppletOff)
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt4
-rw-r--r--src/core/core.cpp18
-rw-r--r--src/core/core.h7
-rw-r--r--src/core/file_sys/romfs.cpp3
-rw-r--r--src/core/file_sys/romfs.h5
-rw-r--r--src/core/frontend/applets/web_browser.cpp24
-rw-r--r--src/core/frontend/applets/web_browser.h28
-rw-r--r--src/core/hle/service/am/am.cpp12
-rw-r--r--src/core/hle/service/am/applets/profile_select.cpp2
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp184
-rw-r--r--src/core/hle/service/am/applets/web_browser.h44
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp6
-rw-r--r--src/core/hle/service/hid/controllers/npad.h6
-rw-r--r--src/core/hle/service/hid/hid.cpp1117
-rw-r--r--src/core/hle/service/hid/hid.h110
-rw-r--r--src/core/loader/loader.h9
-rw-r--r--src/core/loader/nsp.cpp8
-rw-r--r--src/core/loader/nsp.h1
-rw-r--r--src/core/loader/xci.cpp9
-rw-r--r--src/core/loader/xci.h1
20 files changed, 1012 insertions, 586 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 8f2db5bea..aa9e05089 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -88,6 +88,8 @@ add_library(core STATIC
88 frontend/applets/profile_select.h 88 frontend/applets/profile_select.h
89 frontend/applets/software_keyboard.cpp 89 frontend/applets/software_keyboard.cpp
90 frontend/applets/software_keyboard.h 90 frontend/applets/software_keyboard.h
91 frontend/applets/web_browser.cpp
92 frontend/applets/web_browser.h
91 frontend/emu_window.cpp 93 frontend/emu_window.cpp
92 frontend/emu_window.h 94 frontend/emu_window.h
93 frontend/framebuffer_layout.cpp 95 frontend/framebuffer_layout.cpp
@@ -173,6 +175,8 @@ add_library(core STATIC
173 hle/service/am/applets/software_keyboard.h 175 hle/service/am/applets/software_keyboard.h
174 hle/service/am/applets/stub_applet.cpp 176 hle/service/am/applets/stub_applet.cpp
175 hle/service/am/applets/stub_applet.h 177 hle/service/am/applets/stub_applet.h
178 hle/service/am/applets/web_browser.cpp
179 hle/service/am/applets/web_browser.h
176 hle/service/am/idle.cpp 180 hle/service/am/idle.cpp
177 hle/service/am/idle.h 181 hle/service/am/idle.h
178 hle/service/am/omm.cpp 182 hle/service/am/omm.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index fd10199ec..715172771 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -31,7 +31,9 @@
31#include "core/loader/loader.h" 31#include "core/loader/loader.h"
32#include "core/perf_stats.h" 32#include "core/perf_stats.h"
33#include "core/telemetry_session.h" 33#include "core/telemetry_session.h"
34#include "frontend/applets/profile_select.h"
34#include "frontend/applets/software_keyboard.h" 35#include "frontend/applets/software_keyboard.h"
36#include "frontend/applets/web_browser.h"
35#include "video_core/debug_utils/debug_utils.h" 37#include "video_core/debug_utils/debug_utils.h"
36#include "video_core/gpu.h" 38#include "video_core/gpu.h"
37#include "video_core/renderer_base.h" 39#include "video_core/renderer_base.h"
@@ -103,6 +105,8 @@ struct System::Impl {
103 profile_selector = std::make_unique<Core::Frontend::DefaultProfileSelectApplet>(); 105 profile_selector = std::make_unique<Core::Frontend::DefaultProfileSelectApplet>();
104 if (software_keyboard == nullptr) 106 if (software_keyboard == nullptr)
105 software_keyboard = std::make_unique<Core::Frontend::DefaultSoftwareKeyboardApplet>(); 107 software_keyboard = std::make_unique<Core::Frontend::DefaultSoftwareKeyboardApplet>();
108 if (web_browser == nullptr)
109 web_browser = std::make_unique<Core::Frontend::DefaultWebBrowserApplet>();
106 110
107 auto main_process = Kernel::Process::Create(kernel, "main"); 111 auto main_process = Kernel::Process::Create(kernel, "main");
108 kernel.MakeCurrentProcess(main_process.get()); 112 kernel.MakeCurrentProcess(main_process.get());
@@ -199,6 +203,11 @@ struct System::Impl {
199 // Close app loader 203 // Close app loader
200 app_loader.reset(); 204 app_loader.reset();
201 205
206 // Clear all applets
207 profile_selector.reset();
208 software_keyboard.reset();
209 web_browser.reset();
210
202 LOG_DEBUG(Core, "Shutdown OK"); 211 LOG_DEBUG(Core, "Shutdown OK");
203 } 212 }
204 213
@@ -233,6 +242,7 @@ struct System::Impl {
233 /// Frontend applets 242 /// Frontend applets
234 std::unique_ptr<Core::Frontend::ProfileSelectApplet> profile_selector; 243 std::unique_ptr<Core::Frontend::ProfileSelectApplet> profile_selector;
235 std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet> software_keyboard; 244 std::unique_ptr<Core::Frontend::SoftwareKeyboardApplet> software_keyboard;
245 std::unique_ptr<Core::Frontend::WebBrowserApplet> web_browser;
236 246
237 /// Service manager 247 /// Service manager
238 std::shared_ptr<Service::SM::ServiceManager> service_manager; 248 std::shared_ptr<Service::SM::ServiceManager> service_manager;
@@ -443,6 +453,14 @@ const Core::Frontend::SoftwareKeyboardApplet& System::GetSoftwareKeyboard() cons
443 return *impl->software_keyboard; 453 return *impl->software_keyboard;
444} 454}
445 455
456void System::SetWebBrowser(std::unique_ptr<Core::Frontend::WebBrowserApplet> applet) {
457 impl->web_browser = std::move(applet);
458}
459
460const Core::Frontend::WebBrowserApplet& System::GetWebBrowser() const {
461 return *impl->web_browser;
462}
463
446System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { 464System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) {
447 return impl->Init(*this, emu_window); 465 return impl->Init(*this, emu_window);
448} 466}
diff --git a/src/core/core.h b/src/core/core.h
index 869921493..a53dbb4d4 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -11,11 +11,12 @@
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/file_sys/vfs_types.h" 12#include "core/file_sys/vfs_types.h"
13#include "core/hle/kernel/object.h" 13#include "core/hle/kernel/object.h"
14#include "frontend/applets/profile_select.h"
15 14
16namespace Core::Frontend { 15namespace Core::Frontend {
17class EmuWindow; 16class EmuWindow;
17class ProfileSelectApplet;
18class SoftwareKeyboardApplet; 18class SoftwareKeyboardApplet;
19class WebBrowserApplet;
19} // namespace Core::Frontend 20} // namespace Core::Frontend
20 21
21namespace FileSys { 22namespace FileSys {
@@ -250,6 +251,10 @@ public:
250 251
251 const Core::Frontend::SoftwareKeyboardApplet& GetSoftwareKeyboard() const; 252 const Core::Frontend::SoftwareKeyboardApplet& GetSoftwareKeyboard() const;
252 253
254 void SetWebBrowser(std::unique_ptr<Core::Frontend::WebBrowserApplet> applet);
255
256 const Core::Frontend::WebBrowserApplet& GetWebBrowser() const;
257
253private: 258private:
254 System(); 259 System();
255 260
diff --git a/src/core/file_sys/romfs.cpp b/src/core/file_sys/romfs.cpp
index 81e1f66ac..ebbdf081e 100644
--- a/src/core/file_sys/romfs.cpp
+++ b/src/core/file_sys/romfs.cpp
@@ -119,6 +119,9 @@ VirtualDir ExtractRomFS(VirtualFile file, RomFSExtractionType type) {
119 119
120 VirtualDir out = std::move(root); 120 VirtualDir out = std::move(root);
121 121
122 if (type == RomFSExtractionType::SingleDiscard)
123 return out->GetSubdirectories().front();
124
122 while (out->GetSubdirectories().size() == 1 && out->GetFiles().empty()) { 125 while (out->GetSubdirectories().size() == 1 && out->GetFiles().empty()) {
123 if (out->GetSubdirectories().front()->GetName() == "data" && 126 if (out->GetSubdirectories().front()->GetName() == "data" &&
124 type == RomFSExtractionType::Truncated) 127 type == RomFSExtractionType::Truncated)
diff --git a/src/core/file_sys/romfs.h b/src/core/file_sys/romfs.h
index 0ec404731..0f35639bc 100644
--- a/src/core/file_sys/romfs.h
+++ b/src/core/file_sys/romfs.h
@@ -33,8 +33,9 @@ struct IVFCHeader {
33static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size."); 33static_assert(sizeof(IVFCHeader) == 0xE0, "IVFCHeader has incorrect size.");
34 34
35enum class RomFSExtractionType { 35enum class RomFSExtractionType {
36 Full, // Includes data directory 36 Full, // Includes data directory
37 Truncated, // Traverses into data directory 37 Truncated, // Traverses into data directory
38 SingleDiscard, // Traverses into the first subdirectory of root
38}; 39};
39 40
40// Converts a RomFS binary blob to VFS Filesystem 41// Converts a RomFS binary blob to VFS Filesystem
diff --git a/src/core/frontend/applets/web_browser.cpp b/src/core/frontend/applets/web_browser.cpp
new file mode 100644
index 000000000..6a36b4b8f
--- /dev/null
+++ b/src/core/frontend/applets/web_browser.cpp
@@ -0,0 +1,24 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/logging/log.h"
6#include "core/frontend/applets/web_browser.h"
7
8namespace Core::Frontend {
9
10WebBrowserApplet::~WebBrowserApplet() = default;
11
12DefaultWebBrowserApplet::~DefaultWebBrowserApplet() = default;
13
14void DefaultWebBrowserApplet::OpenPage(std::string_view filename,
15 std::function<void()> unpack_romfs_callback,
16 std::function<void()> finished_callback) const {
17 LOG_INFO(Service_AM,
18 "(STUBBED) called - No suitable web browser implementation found to open website page "
19 "at '{}'!",
20 filename);
21 finished_callback();
22}
23
24} // namespace Core::Frontend
diff --git a/src/core/frontend/applets/web_browser.h b/src/core/frontend/applets/web_browser.h
new file mode 100644
index 000000000..41d272d26
--- /dev/null
+++ b/src/core/frontend/applets/web_browser.h
@@ -0,0 +1,28 @@
1// Copyright 2018 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 <functional>
8#include <string_view>
9
10namespace Core::Frontend {
11
12class WebBrowserApplet {
13public:
14 virtual ~WebBrowserApplet();
15
16 virtual void OpenPage(std::string_view url, std::function<void()> unpack_romfs_callback,
17 std::function<void()> finished_callback) const = 0;
18};
19
20class DefaultWebBrowserApplet final : public WebBrowserApplet {
21public:
22 ~DefaultWebBrowserApplet() override;
23
24 void OpenPage(std::string_view url, std::function<void()> unpack_romfs_callback,
25 std::function<void()> finished_callback) const override;
26};
27
28} // namespace Core::Frontend
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 7a5e9d216..d1cbe0e44 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -23,6 +23,7 @@
23#include "core/hle/service/am/applets/profile_select.h" 23#include "core/hle/service/am/applets/profile_select.h"
24#include "core/hle/service/am/applets/software_keyboard.h" 24#include "core/hle/service/am/applets/software_keyboard.h"
25#include "core/hle/service/am/applets/stub_applet.h" 25#include "core/hle/service/am/applets/stub_applet.h"
26#include "core/hle/service/am/applets/web_browser.h"
26#include "core/hle/service/am/idle.h" 27#include "core/hle/service/am/idle.h"
27#include "core/hle/service/am/omm.h" 28#include "core/hle/service/am/omm.h"
28#include "core/hle/service/am/spsm.h" 29#include "core/hle/service/am/spsm.h"
@@ -44,6 +45,7 @@ constexpr ResultCode ERR_SIZE_OUT_OF_BOUNDS{ErrorModule::AM, 0x1F7};
44enum class AppletId : u32 { 45enum class AppletId : u32 {
45 ProfileSelect = 0x10, 46 ProfileSelect = 0x10,
46 SoftwareKeyboard = 0x11, 47 SoftwareKeyboard = 0x11,
48 LibAppletOff = 0x17,
47}; 49};
48 50
49constexpr u32 POP_LAUNCH_PARAMETER_MAGIC = 0xC79497CA; 51constexpr u32 POP_LAUNCH_PARAMETER_MAGIC = 0xC79497CA;
@@ -730,10 +732,10 @@ void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) {
730 IPC::RequestParser rp{ctx}; 732 IPC::RequestParser rp{ctx};
731 733
732 const u64 offset{rp.Pop<u64>()}; 734 const u64 offset{rp.Pop<u64>()};
733 LOG_DEBUG(Service_AM, "called, offset={}", offset);
734
735 const std::vector<u8> data{ctx.ReadBuffer()}; 735 const std::vector<u8> data{ctx.ReadBuffer()};
736 736
737 LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, data.size());
738
737 if (data.size() > backing.buffer.size() - offset) { 739 if (data.size() > backing.buffer.size() - offset) {
738 LOG_ERROR(Service_AM, 740 LOG_ERROR(Service_AM,
739 "offset is out of bounds, backing_buffer_sz={}, data_size={}, offset={}", 741 "offset is out of bounds, backing_buffer_sz={}, data_size={}, offset={}",
@@ -753,10 +755,10 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
753 IPC::RequestParser rp{ctx}; 755 IPC::RequestParser rp{ctx};
754 756
755 const u64 offset{rp.Pop<u64>()}; 757 const u64 offset{rp.Pop<u64>()};
756 LOG_DEBUG(Service_AM, "called, offset={}", offset);
757
758 const std::size_t size{ctx.GetWriteBufferSize()}; 758 const std::size_t size{ctx.GetWriteBufferSize()};
759 759
760 LOG_DEBUG(Service_AM, "called, offset={}, size={}", offset, size);
761
760 if (size > backing.buffer.size() - offset) { 762 if (size > backing.buffer.size() - offset) {
761 LOG_ERROR(Service_AM, "offset is out of bounds, backing_buffer_sz={}, size={}, offset={}", 763 LOG_ERROR(Service_AM, "offset is out of bounds, backing_buffer_sz={}, size={}, offset={}",
762 backing.buffer.size(), size, offset); 764 backing.buffer.size(), size, offset);
@@ -791,6 +793,8 @@ static std::shared_ptr<Applets::Applet> GetAppletFromId(AppletId id) {
791 return std::make_shared<Applets::ProfileSelect>(); 793 return std::make_shared<Applets::ProfileSelect>();
792 case AppletId::SoftwareKeyboard: 794 case AppletId::SoftwareKeyboard:
793 return std::make_shared<Applets::SoftwareKeyboard>(); 795 return std::make_shared<Applets::SoftwareKeyboard>();
796 case AppletId::LibAppletOff:
797 return std::make_shared<Applets::WebBrowser>();
794 default: 798 default:
795 LOG_ERROR(Service_AM, "Unimplemented AppletId [{:08X}]! -- Falling back to stub!", 799 LOG_ERROR(Service_AM, "Unimplemented AppletId [{:08X}]! -- Falling back to stub!",
796 static_cast<u32>(id)); 800 static_cast<u32>(id));
diff --git a/src/core/hle/service/am/applets/profile_select.cpp b/src/core/hle/service/am/applets/profile_select.cpp
index 4c7b45454..14e2a1fee 100644
--- a/src/core/hle/service/am/applets/profile_select.cpp
+++ b/src/core/hle/service/am/applets/profile_select.cpp
@@ -7,7 +7,7 @@
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/string_util.h" 8#include "common/string_util.h"
9#include "core/core.h" 9#include "core/core.h"
10#include "core/frontend/applets/software_keyboard.h" 10#include "core/frontend/applets/profile_select.h"
11#include "core/hle/service/am/am.h" 11#include "core/hle/service/am/am.h"
12#include "core/hle/service/am/applets/profile_select.h" 12#include "core/hle/service/am/applets/profile_select.h"
13 13
diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp
new file mode 100644
index 000000000..d975207f5
--- /dev/null
+++ b/src/core/hle/service/am/applets/web_browser.cpp
@@ -0,0 +1,184 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/common_paths.h"
6#include "common/hex_util.h"
7#include "common/logging/backend.h"
8#include "common/string_util.h"
9#include "core/core.h"
10#include "core/file_sys/content_archive.h"
11#include "core/file_sys/mode.h"
12#include "core/file_sys/nca_metadata.h"
13#include "core/file_sys/registered_cache.h"
14#include "core/file_sys/romfs.h"
15#include "core/file_sys/romfs_factory.h"
16#include "core/file_sys/vfs_types.h"
17#include "core/frontend/applets/web_browser.h"
18#include "core/hle/kernel/process.h"
19#include "core/hle/service/am/applets/web_browser.h"
20#include "core/hle/service/filesystem/filesystem.h"
21#include "core/loader/loader.h"
22
23namespace Service::AM::Applets {
24
25// TODO(DarkLordZach): There are other arguments in the WebBuffer structure that are currently not
26// parsed, for example footer mode and left stick mode. Some of these are not particularly relevant,
27// but some may be worth an implementation.
28constexpr u16 WEB_ARGUMENT_URL_TYPE = 0x6;
29
30struct WebBufferHeader {
31 u16 count;
32 INSERT_PADDING_BYTES(6);
33};
34static_assert(sizeof(WebBufferHeader) == 0x8, "WebBufferHeader has incorrect size.");
35
36struct WebArgumentHeader {
37 u16 type;
38 u16 size;
39 u32 offset;
40};
41static_assert(sizeof(WebArgumentHeader) == 0x8, "WebArgumentHeader has incorrect size.");
42
43struct WebArgumentResult {
44 u32 result_code;
45 std::array<char, 0x1000> last_url;
46 u64 last_url_size;
47};
48static_assert(sizeof(WebArgumentResult) == 0x1010, "WebArgumentResult has incorrect size.");
49
50static std::vector<u8> GetArgumentDataForTagType(const std::vector<u8>& data, u16 type) {
51 WebBufferHeader header;
52 ASSERT(sizeof(WebBufferHeader) <= data.size());
53 std::memcpy(&header, data.data(), sizeof(WebBufferHeader));
54
55 u64 offset = sizeof(WebBufferHeader);
56 for (u16 i = 0; i < header.count; ++i) {
57 WebArgumentHeader arg;
58 ASSERT(offset + sizeof(WebArgumentHeader) <= data.size());
59 std::memcpy(&arg, data.data() + offset, sizeof(WebArgumentHeader));
60 offset += sizeof(WebArgumentHeader);
61
62 if (arg.type == type) {
63 std::vector<u8> out(arg.size);
64 offset += arg.offset;
65 ASSERT(offset + arg.size <= data.size());
66 std::memcpy(out.data(), data.data() + offset, out.size());
67 return out;
68 }
69
70 offset += arg.offset + arg.size;
71 }
72
73 return {};
74}
75
76static FileSys::VirtualFile GetManualRomFS() {
77 auto& loader{Core::System::GetInstance().GetAppLoader()};
78
79 FileSys::VirtualFile out;
80 if (loader.ReadManualRomFS(out) == Loader::ResultStatus::Success)
81 return out;
82
83 const auto& installed{FileSystem::GetUnionContents()};
84 const auto res = installed.GetEntry(Core::System::GetInstance().CurrentProcess()->GetTitleID(),
85 FileSys::ContentRecordType::Manual);
86
87 if (res != nullptr)
88 return res->GetRomFS();
89 return nullptr;
90}
91
92WebBrowser::WebBrowser() = default;
93
94WebBrowser::~WebBrowser() = default;
95
96void WebBrowser::Initialize() {
97 Applet::Initialize();
98
99 complete = false;
100 temporary_dir.clear();
101 filename.clear();
102 status = RESULT_SUCCESS;
103
104 const auto web_arg_storage = broker.PopNormalDataToApplet();
105 ASSERT(web_arg_storage != nullptr);
106 const auto& web_arg = web_arg_storage->GetData();
107
108 const auto url_data = GetArgumentDataForTagType(web_arg, WEB_ARGUMENT_URL_TYPE);
109 filename = Common::StringFromFixedZeroTerminatedBuffer(
110 reinterpret_cast<const char*>(url_data.data()), url_data.size());
111
112 temporary_dir = FileUtil::SanitizePath(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) +
113 "web_applet_manual",
114 FileUtil::DirectorySeparator::PlatformDefault);
115 FileUtil::DeleteDirRecursively(temporary_dir);
116
117 manual_romfs = GetManualRomFS();
118 if (manual_romfs == nullptr) {
119 status = ResultCode(-1);
120 LOG_ERROR(Service_AM, "Failed to find manual for current process!");
121 }
122
123 filename =
124 FileUtil::SanitizePath(temporary_dir + DIR_SEP + "html-document" + DIR_SEP + filename,
125 FileUtil::DirectorySeparator::PlatformDefault);
126}
127
128bool WebBrowser::TransactionComplete() const {
129 return complete;
130}
131
132ResultCode WebBrowser::GetStatus() const {
133 return status;
134}
135
136void WebBrowser::ExecuteInteractive() {
137 UNIMPLEMENTED_MSG("Unexpected interactive data recieved!");
138}
139
140void WebBrowser::Execute() {
141 if (complete)
142 return;
143
144 if (status != RESULT_SUCCESS) {
145 complete = true;
146 return;
147 }
148
149 const auto& frontend{Core::System::GetInstance().GetWebBrowser()};
150
151 frontend.OpenPage(filename, [this] { UnpackRomFS(); }, [this] { Finalize(); });
152}
153
154void WebBrowser::UnpackRomFS() {
155 if (unpacked)
156 return;
157
158 ASSERT(manual_romfs != nullptr);
159 const auto dir =
160 FileSys::ExtractRomFS(manual_romfs, FileSys::RomFSExtractionType::SingleDiscard);
161 const auto& vfs{Core::System::GetInstance().GetFilesystem()};
162 const auto temp_dir = vfs->CreateDirectory(temporary_dir, FileSys::Mode::ReadWrite);
163 FileSys::VfsRawCopyD(dir, temp_dir);
164
165 unpacked = true;
166}
167
168void WebBrowser::Finalize() {
169 complete = true;
170
171 WebArgumentResult out{};
172 out.result_code = 0;
173 out.last_url_size = 0;
174
175 std::vector<u8> data(sizeof(WebArgumentResult));
176 std::memcpy(data.data(), &out, sizeof(WebArgumentResult));
177
178 broker.PushNormalDataFromApplet(IStorage{data});
179 broker.SignalStateChanged();
180
181 FileUtil::DeleteDirRecursively(temporary_dir);
182}
183
184} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h
new file mode 100644
index 000000000..b9e228fac
--- /dev/null
+++ b/src/core/hle/service/am/applets/web_browser.h
@@ -0,0 +1,44 @@
1// Copyright 2018 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/file_sys/vfs_types.h"
8#include "core/hle/service/am/am.h"
9#include "core/hle/service/am/applets/applets.h"
10
11namespace Service::AM::Applets {
12
13class WebBrowser final : public Applet {
14public:
15 WebBrowser();
16 ~WebBrowser() override;
17
18 void Initialize() override;
19
20 bool TransactionComplete() const override;
21 ResultCode GetStatus() const override;
22 void ExecuteInteractive() override;
23 void Execute() override;
24
25 // Callback to be fired when the frontend needs the manual RomFS unpacked to temporary
26 // directory. This is a blocking call and may take a while as some manuals can be up to 100MB in
27 // size. Attempting to access files at filename before invocation is likely to not work.
28 void UnpackRomFS();
29
30 // Callback to be fired when the frontend is finished browsing. This will delete the temporary
31 // manual RomFS extracted files, so ensure this is only called at actual finalization.
32 void Finalize();
33
34private:
35 bool complete = false;
36 bool unpacked = false;
37 ResultCode status = RESULT_SUCCESS;
38
39 FileSys::VirtualFile manual_romfs;
40 std::string temporary_dir;
41 std::string filename;
42};
43
44} // namespace Service::AM::Applets
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 75fdb861a..04c8c35a8 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -410,6 +410,8 @@ void Controller_NPad::OnUpdate(u8* data, std::size_t data_len) {
410 libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw; 410 libnx_entry.pad.pad_states.raw = pad_state.pad_states.raw;
411 libnx_entry.pad.l_stick = pad_state.l_stick; 411 libnx_entry.pad.l_stick = pad_state.l_stick;
412 libnx_entry.pad.r_stick = pad_state.r_stick; 412 libnx_entry.pad.r_stick = pad_state.r_stick;
413
414 press_state |= static_cast<u32>(pad_state.pad_states.raw);
413 } 415 }
414 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(), 416 std::memcpy(data + NPAD_OFFSET, shared_memory_entries.data(),
415 shared_memory_entries.size() * sizeof(NPadEntry)); 417 shared_memory_entries.size() * sizeof(NPadEntry));
@@ -636,6 +638,10 @@ void Controller_NPad::ClearAllControllers() {
636 }); 638 });
637} 639}
638 640
641u32 Controller_NPad::GetAndResetPressState() {
642 return std::exchange(press_state, 0);
643}
644
639bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const { 645bool Controller_NPad::IsControllerSupported(NPadControllerType controller) const {
640 const bool support_handheld = 646 const bool support_handheld =
641 std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), NPAD_HANDHELD) != 647 std::find(supported_npad_id_types.begin(), supported_npad_id_types.end(), NPAD_HANDHELD) !=
diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h
index 29851f16a..106cf58c8 100644
--- a/src/core/hle/service/hid/controllers/npad.h
+++ b/src/core/hle/service/hid/controllers/npad.h
@@ -124,6 +124,10 @@ public:
124 void ConnectAllDisconnectedControllers(); 124 void ConnectAllDisconnectedControllers();
125 void ClearAllControllers(); 125 void ClearAllControllers();
126 126
127 // Logical OR for all buttons presses on all controllers
128 // Specifically for cheat engine and other features.
129 u32 GetAndResetPressState();
130
127 static std::size_t NPadIdToIndex(u32 npad_id); 131 static std::size_t NPadIdToIndex(u32 npad_id);
128 static u32 IndexToNPad(std::size_t index); 132 static u32 IndexToNPad(std::size_t index);
129 133
@@ -292,6 +296,8 @@ private:
292 bool is_connected; 296 bool is_connected;
293 }; 297 };
294 298
299 u32 press_state{};
300
295 NPadType style{}; 301 NPadType style{};
296 std::array<NPadEntry, 10> shared_memory_entries{}; 302 std::array<NPadEntry, 10> shared_memory_entries{};
297 std::array< 303 std::array<
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 268409257..008bf3f02 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -40,119 +40,82 @@ constexpr u64 pad_update_ticks = CoreTiming::BASE_CLOCK_RATE / 66;
40constexpr u64 accelerometer_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; 40constexpr u64 accelerometer_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100;
41constexpr u64 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100; 41constexpr u64 gyroscope_update_ticks = CoreTiming::BASE_CLOCK_RATE / 100;
42constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000; 42constexpr std::size_t SHARED_MEMORY_SIZE = 0x40000;
43enum class HidController : std::size_t {
44 DebugPad,
45 Touchscreen,
46 Mouse,
47 Keyboard,
48 XPad,
49 Unknown1,
50 Unknown2,
51 Unknown3,
52 SixAxisSensor,
53 NPad,
54 Gesture,
55
56 MaxControllers,
57};
58
59class IAppletResource final : public ServiceFramework<IAppletResource> {
60public:
61 IAppletResource() : ServiceFramework("IAppletResource") {
62 static const FunctionInfo functions[] = {
63 {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
64 };
65 RegisterHandlers(functions);
66 43
67 auto& kernel = Core::System::GetInstance().Kernel(); 44IAppletResource::IAppletResource() : ServiceFramework("IAppletResource") {
68 shared_mem = Kernel::SharedMemory::Create( 45 static const FunctionInfo functions[] = {
69 kernel, nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite, 46 {0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
70 Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); 47 };
71 48 RegisterHandlers(functions);
72 MakeController<Controller_DebugPad>(HidController::DebugPad); 49
73 MakeController<Controller_Touchscreen>(HidController::Touchscreen); 50 auto& kernel = Core::System::GetInstance().Kernel();
74 MakeController<Controller_Mouse>(HidController::Mouse); 51 shared_mem = Kernel::SharedMemory::Create(
75 MakeController<Controller_Keyboard>(HidController::Keyboard); 52 kernel, nullptr, SHARED_MEMORY_SIZE, Kernel::MemoryPermission::ReadWrite,
76 MakeController<Controller_XPad>(HidController::XPad); 53 Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory");
77 MakeController<Controller_Stubbed>(HidController::Unknown1); 54
78 MakeController<Controller_Stubbed>(HidController::Unknown2); 55 MakeController<Controller_DebugPad>(HidController::DebugPad);
79 MakeController<Controller_Stubbed>(HidController::Unknown3); 56 MakeController<Controller_Touchscreen>(HidController::Touchscreen);
80 MakeController<Controller_Stubbed>(HidController::SixAxisSensor); 57 MakeController<Controller_Mouse>(HidController::Mouse);
81 MakeController<Controller_NPad>(HidController::NPad); 58 MakeController<Controller_Keyboard>(HidController::Keyboard);
82 MakeController<Controller_Gesture>(HidController::Gesture); 59 MakeController<Controller_XPad>(HidController::XPad);
83 60 MakeController<Controller_Stubbed>(HidController::Unknown1);
84 // Homebrew doesn't try to activate some controllers, so we activate them by default 61 MakeController<Controller_Stubbed>(HidController::Unknown2);
85 GetController<Controller_NPad>(HidController::NPad).ActivateController(); 62 MakeController<Controller_Stubbed>(HidController::Unknown3);
86 GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController(); 63 MakeController<Controller_Stubbed>(HidController::SixAxisSensor);
87 64 MakeController<Controller_NPad>(HidController::NPad);
88 GetController<Controller_Stubbed>(HidController::Unknown1).SetCommonHeaderOffset(0x4c00); 65 MakeController<Controller_Gesture>(HidController::Gesture);
89 GetController<Controller_Stubbed>(HidController::Unknown2).SetCommonHeaderOffset(0x4e00); 66
90 GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000); 67 // Homebrew doesn't try to activate some controllers, so we activate them by default
91 68 GetController<Controller_NPad>(HidController::NPad).ActivateController();
92 // Register update callbacks 69 GetController<Controller_Touchscreen>(HidController::Touchscreen).ActivateController();
93 pad_update_event = CoreTiming::RegisterEvent( 70
94 "HID::UpdatePadCallback", 71 GetController<Controller_Stubbed>(HidController::Unknown1).SetCommonHeaderOffset(0x4c00);
95 [this](u64 userdata, int cycles_late) { UpdateControllers(userdata, cycles_late); }); 72 GetController<Controller_Stubbed>(HidController::Unknown2).SetCommonHeaderOffset(0x4e00);
96 73 GetController<Controller_Stubbed>(HidController::Unknown3).SetCommonHeaderOffset(0x5000);
97 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?) 74
98 75 // Register update callbacks
99 CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event); 76 pad_update_event =
100 77 CoreTiming::RegisterEvent("HID::UpdatePadCallback", [this](u64 userdata, int cycles_late) {
101 ReloadInputDevices(); 78 UpdateControllers(userdata, cycles_late);
102 } 79 });
103 80
104 void ActivateController(HidController controller) { 81 // TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
105 controllers[static_cast<size_t>(controller)]->ActivateController(); 82
106 } 83 CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
107 84
108 void DeactivateController(HidController controller) { 85 ReloadInputDevices();
109 controllers[static_cast<size_t>(controller)]->DeactivateController(); 86}
110 }
111 87
112 template <typename T> 88void IAppletResource::ActivateController(HidController controller) {
113 void MakeController(HidController controller) { 89 controllers[static_cast<size_t>(controller)]->ActivateController();
114 controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>(); 90}
115 }
116 91
117 template <typename T> 92void IAppletResource::DeactivateController(HidController controller) {
118 T& GetController(HidController controller) { 93 controllers[static_cast<size_t>(controller)]->DeactivateController();
119 return static_cast<T&>(*controllers[static_cast<size_t>(controller)]); 94}
120 }
121 95
122 ~IAppletResource() { 96IAppletResource ::~IAppletResource() {
123 CoreTiming::UnscheduleEvent(pad_update_event, 0); 97 CoreTiming::UnscheduleEvent(pad_update_event, 0);
124 } 98}
125 99
126private: 100void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
127 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { 101 LOG_DEBUG(Service_HID, "called");
128 LOG_DEBUG(Service_HID, "called");
129 102
130 IPC::ResponseBuilder rb{ctx, 2, 1}; 103 IPC::ResponseBuilder rb{ctx, 2, 1};
131 rb.Push(RESULT_SUCCESS); 104 rb.Push(RESULT_SUCCESS);
132 rb.PushCopyObjects(shared_mem); 105 rb.PushCopyObjects(shared_mem);
133 } 106}
134 107
135 void UpdateControllers(u64 userdata, int cycles_late) { 108void IAppletResource::UpdateControllers(u64 userdata, int cycles_late) {
136 const bool should_reload = Settings::values.is_device_reload_pending.exchange(false); 109 const bool should_reload = Settings::values.is_device_reload_pending.exchange(false);
137 for (const auto& controller : controllers) { 110 for (const auto& controller : controllers) {
138 if (should_reload) { 111 if (should_reload) {
139 controller->OnLoadInputDevices(); 112 controller->OnLoadInputDevices();
140 }
141 controller->OnUpdate(shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
142 } 113 }
143 114 controller->OnUpdate(shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
144 CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
145 } 115 }
146 116
147 // Handle to shared memory region designated to HID service 117 CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
148 Kernel::SharedPtr<Kernel::SharedMemory> shared_mem; 118}
149
150 // CoreTiming update events
151 CoreTiming::EventType* pad_update_event;
152
153 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
154 controllers{};
155};
156 119
157class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> { 120class IActiveVibrationDeviceList final : public ServiceFramework<IActiveVibrationDeviceList> {
158public: 121public:
@@ -172,599 +135,597 @@ private:
172 } 135 }
173}; 136};
174 137
175class Hid final : public ServiceFramework<Hid> { 138std::shared_ptr<IAppletResource> Hid::GetAppletResource() {
176public: 139 if (applet_resource == nullptr) {
177 Hid() : ServiceFramework("hid") { 140 applet_resource = std::make_shared<IAppletResource>();
178 // clang-format off
179 static const FunctionInfo functions[] = {
180 {0, &Hid::CreateAppletResource, "CreateAppletResource"},
181 {1, &Hid::ActivateDebugPad, "ActivateDebugPad"},
182 {11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"},
183 {21, &Hid::ActivateMouse, "ActivateMouse"},
184 {31, &Hid::ActivateKeyboard, "ActivateKeyboard"},
185 {32, nullptr, "SendKeyboardLockKeyEvent"},
186 {40, nullptr, "AcquireXpadIdEventHandle"},
187 {41, nullptr, "ReleaseXpadIdEventHandle"},
188 {51, &Hid::ActivateXpad, "ActivateXpad"},
189 {55, nullptr, "GetXpadIds"},
190 {56, nullptr, "ActivateJoyXpad"},
191 {58, nullptr, "GetJoyXpadLifoHandle"},
192 {59, nullptr, "GetJoyXpadIds"},
193 {60, nullptr, "ActivateSixAxisSensor"},
194 {61, nullptr, "DeactivateSixAxisSensor"},
195 {62, nullptr, "GetSixAxisSensorLifoHandle"},
196 {63, nullptr, "ActivateJoySixAxisSensor"},
197 {64, nullptr, "DeactivateJoySixAxisSensor"},
198 {65, nullptr, "GetJoySixAxisSensorLifoHandle"},
199 {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
200 {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"},
201 {68, nullptr, "IsSixAxisSensorFusionEnabled"},
202 {69, nullptr, "EnableSixAxisSensorFusion"},
203 {70, nullptr, "SetSixAxisSensorFusionParameters"},
204 {71, nullptr, "GetSixAxisSensorFusionParameters"},
205 {72, nullptr, "ResetSixAxisSensorFusionParameters"},
206 {73, nullptr, "SetAccelerometerParameters"},
207 {74, nullptr, "GetAccelerometerParameters"},
208 {75, nullptr, "ResetAccelerometerParameters"},
209 {76, nullptr, "SetAccelerometerPlayMode"},
210 {77, nullptr, "GetAccelerometerPlayMode"},
211 {78, nullptr, "ResetAccelerometerPlayMode"},
212 {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
213 {80, nullptr, "GetGyroscopeZeroDriftMode"},
214 {81, nullptr, "ResetGyroscopeZeroDriftMode"},
215 {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
216 {83, nullptr, "IsFirmwareUpdateAvailableForSixAxisSensor"},
217 {91, &Hid::ActivateGesture, "ActivateGesture"},
218 {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
219 {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
220 {102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
221 {103, &Hid::ActivateNpad, "ActivateNpad"},
222 {104, nullptr, "DeactivateNpad"},
223 {106, &Hid::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"},
224 {107, &Hid::DisconnectNpad, "DisconnectNpad"},
225 {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"},
226 {109, &Hid::ActivateNpadWithRevision, "ActivateNpadWithRevision"},
227 {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
228 {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
229 {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"},
230 {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
231 {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
232 {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
233 {126, nullptr, "StartLrAssignmentMode"},
234 {127, nullptr, "StopLrAssignmentMode"},
235 {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
236 {129, nullptr, "GetNpadHandheldActivationMode"},
237 {130, nullptr, "SwapNpadAssignment"},
238 {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
239 {132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
240 {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
241 {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
242 {201, &Hid::SendVibrationValue, "SendVibrationValue"},
243 {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"},
244 {203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
245 {204, nullptr, "PermitVibration"},
246 {205, nullptr, "IsVibrationPermitted"},
247 {206, &Hid::SendVibrationValues, "SendVibrationValues"},
248 {207, nullptr, "SendVibrationGcErmCommand"},
249 {208, nullptr, "GetActualVibrationGcErmCommand"},
250 {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
251 {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"},
252 {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
253 {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
254 {302, nullptr, "StopConsoleSixAxisSensor"},
255 {303, nullptr, "ActivateSevenSixAxisSensor"},
256 {304, nullptr, "StartSevenSixAxisSensor"},
257 {305, nullptr, "StopSevenSixAxisSensor"},
258 {306, nullptr, "InitializeSevenSixAxisSensor"},
259 {307, nullptr, "FinalizeSevenSixAxisSensor"},
260 {308, nullptr, "SetSevenSixAxisSensorFusionStrength"},
261 {309, nullptr, "GetSevenSixAxisSensorFusionStrength"},
262 {310, nullptr, "ResetSevenSixAxisSensorTimestamp"},
263 {400, nullptr, "IsUsbFullKeyControllerEnabled"},
264 {401, nullptr, "EnableUsbFullKeyController"},
265 {402, nullptr, "IsUsbFullKeyControllerConnected"},
266 {403, nullptr, "HasBattery"},
267 {404, nullptr, "HasLeftRightBattery"},
268 {405, nullptr, "GetNpadInterfaceType"},
269 {406, nullptr, "GetNpadLeftRightInterfaceType"},
270 {500, nullptr, "GetPalmaConnectionHandle"},
271 {501, nullptr, "InitializePalma"},
272 {502, nullptr, "AcquirePalmaOperationCompleteEvent"},
273 {503, nullptr, "GetPalmaOperationInfo"},
274 {504, nullptr, "PlayPalmaActivity"},
275 {505, nullptr, "SetPalmaFrModeType"},
276 {506, nullptr, "ReadPalmaStep"},
277 {507, nullptr, "EnablePalmaStep"},
278 {508, nullptr, "ResetPalmaStep"},
279 {509, nullptr, "ReadPalmaApplicationSection"},
280 {510, nullptr, "WritePalmaApplicationSection"},
281 {511, nullptr, "ReadPalmaUniqueCode"},
282 {512, nullptr, "SetPalmaUniqueCodeInvalid"},
283 {513, nullptr, "WritePalmaActivityEntry"},
284 {514, nullptr, "WritePalmaRgbLedPatternEntry"},
285 {515, nullptr, "WritePalmaWaveEntry"},
286 {516, nullptr, "SetPalmaDataBaseIdentificationVersion"},
287 {517, nullptr, "GetPalmaDataBaseIdentificationVersion"},
288 {518, nullptr, "SuspendPalmaFeature"},
289 {519, nullptr, "GetPalmaOperationResult"},
290 {520, nullptr, "ReadPalmaPlayLog"},
291 {521, nullptr, "ResetPalmaPlayLog"},
292 {522, &Hid::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"},
293 {523, nullptr, "SetIsPalmaPairedConnectable"},
294 {524, nullptr, "PairPalma"},
295 {525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"},
296 {1000, nullptr, "SetNpadCommunicationMode"},
297 {1001, nullptr, "GetNpadCommunicationMode"},
298 };
299 // clang-format on
300
301 RegisterHandlers(functions);
302 } 141 }
303 ~Hid() = default;
304 142
305private: 143 return applet_resource;
306 std::shared_ptr<IAppletResource> applet_resource; 144}
307 145
308 void CreateAppletResource(Kernel::HLERequestContext& ctx) { 146Hid::Hid() : ServiceFramework("hid") {
309 IPC::RequestParser rp{ctx}; 147 // clang-format off
310 const auto applet_resource_user_id{rp.Pop<u64>()}; 148 static const FunctionInfo functions[] = {
149 {0, &Hid::CreateAppletResource, "CreateAppletResource"},
150 {1, &Hid::ActivateDebugPad, "ActivateDebugPad"},
151 {11, &Hid::ActivateTouchScreen, "ActivateTouchScreen"},
152 {21, &Hid::ActivateMouse, "ActivateMouse"},
153 {31, &Hid::ActivateKeyboard, "ActivateKeyboard"},
154 {32, nullptr, "SendKeyboardLockKeyEvent"},
155 {40, nullptr, "AcquireXpadIdEventHandle"},
156 {41, nullptr, "ReleaseXpadIdEventHandle"},
157 {51, &Hid::ActivateXpad, "ActivateXpad"},
158 {55, nullptr, "GetXpadIds"},
159 {56, nullptr, "ActivateJoyXpad"},
160 {58, nullptr, "GetJoyXpadLifoHandle"},
161 {59, nullptr, "GetJoyXpadIds"},
162 {60, nullptr, "ActivateSixAxisSensor"},
163 {61, nullptr, "DeactivateSixAxisSensor"},
164 {62, nullptr, "GetSixAxisSensorLifoHandle"},
165 {63, nullptr, "ActivateJoySixAxisSensor"},
166 {64, nullptr, "DeactivateJoySixAxisSensor"},
167 {65, nullptr, "GetJoySixAxisSensorLifoHandle"},
168 {66, &Hid::StartSixAxisSensor, "StartSixAxisSensor"},
169 {67, &Hid::StopSixAxisSensor, "StopSixAxisSensor"},
170 {68, nullptr, "IsSixAxisSensorFusionEnabled"},
171 {69, nullptr, "EnableSixAxisSensorFusion"},
172 {70, nullptr, "SetSixAxisSensorFusionParameters"},
173 {71, nullptr, "GetSixAxisSensorFusionParameters"},
174 {72, nullptr, "ResetSixAxisSensorFusionParameters"},
175 {73, nullptr, "SetAccelerometerParameters"},
176 {74, nullptr, "GetAccelerometerParameters"},
177 {75, nullptr, "ResetAccelerometerParameters"},
178 {76, nullptr, "SetAccelerometerPlayMode"},
179 {77, nullptr, "GetAccelerometerPlayMode"},
180 {78, nullptr, "ResetAccelerometerPlayMode"},
181 {79, &Hid::SetGyroscopeZeroDriftMode, "SetGyroscopeZeroDriftMode"},
182 {80, nullptr, "GetGyroscopeZeroDriftMode"},
183 {81, nullptr, "ResetGyroscopeZeroDriftMode"},
184 {82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
185 {83, nullptr, "IsFirmwareUpdateAvailableForSixAxisSensor"},
186 {91, &Hid::ActivateGesture, "ActivateGesture"},
187 {100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
188 {101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
189 {102, &Hid::SetSupportedNpadIdType, "SetSupportedNpadIdType"},
190 {103, &Hid::ActivateNpad, "ActivateNpad"},
191 {104, nullptr, "DeactivateNpad"},
192 {106, &Hid::AcquireNpadStyleSetUpdateEventHandle, "AcquireNpadStyleSetUpdateEventHandle"},
193 {107, &Hid::DisconnectNpad, "DisconnectNpad"},
194 {108, &Hid::GetPlayerLedPattern, "GetPlayerLedPattern"},
195 {109, &Hid::ActivateNpadWithRevision, "ActivateNpadWithRevision"},
196 {120, &Hid::SetNpadJoyHoldType, "SetNpadJoyHoldType"},
197 {121, &Hid::GetNpadJoyHoldType, "GetNpadJoyHoldType"},
198 {122, &Hid::SetNpadJoyAssignmentModeSingleByDefault, "SetNpadJoyAssignmentModeSingleByDefault"},
199 {123, nullptr, "SetNpadJoyAssignmentModeSingleByDefault"},
200 {124, &Hid::SetNpadJoyAssignmentModeDual, "SetNpadJoyAssignmentModeDual"},
201 {125, &Hid::MergeSingleJoyAsDualJoy, "MergeSingleJoyAsDualJoy"},
202 {126, nullptr, "StartLrAssignmentMode"},
203 {127, nullptr, "StopLrAssignmentMode"},
204 {128, &Hid::SetNpadHandheldActivationMode, "SetNpadHandheldActivationMode"},
205 {129, nullptr, "GetNpadHandheldActivationMode"},
206 {130, nullptr, "SwapNpadAssignment"},
207 {131, nullptr, "IsUnintendedHomeButtonInputProtectionEnabled"},
208 {132, nullptr, "EnableUnintendedHomeButtonInputProtection"},
209 {133, nullptr, "SetNpadJoyAssignmentModeSingleWithDestination"},
210 {200, &Hid::GetVibrationDeviceInfo, "GetVibrationDeviceInfo"},
211 {201, &Hid::SendVibrationValue, "SendVibrationValue"},
212 {202, &Hid::GetActualVibrationValue, "GetActualVibrationValue"},
213 {203, &Hid::CreateActiveVibrationDeviceList, "CreateActiveVibrationDeviceList"},
214 {204, nullptr, "PermitVibration"},
215 {205, nullptr, "IsVibrationPermitted"},
216 {206, &Hid::SendVibrationValues, "SendVibrationValues"},
217 {207, nullptr, "SendVibrationGcErmCommand"},
218 {208, nullptr, "GetActualVibrationGcErmCommand"},
219 {209, &Hid::BeginPermitVibrationSession, "BeginPermitVibrationSession"},
220 {210, &Hid::EndPermitVibrationSession, "EndPermitVibrationSession"},
221 {300, &Hid::ActivateConsoleSixAxisSensor, "ActivateConsoleSixAxisSensor"},
222 {301, &Hid::StartConsoleSixAxisSensor, "StartConsoleSixAxisSensor"},
223 {302, nullptr, "StopConsoleSixAxisSensor"},
224 {303, nullptr, "ActivateSevenSixAxisSensor"},
225 {304, nullptr, "StartSevenSixAxisSensor"},
226 {305, nullptr, "StopSevenSixAxisSensor"},
227 {306, nullptr, "InitializeSevenSixAxisSensor"},
228 {307, nullptr, "FinalizeSevenSixAxisSensor"},
229 {308, nullptr, "SetSevenSixAxisSensorFusionStrength"},
230 {309, nullptr, "GetSevenSixAxisSensorFusionStrength"},
231 {310, nullptr, "ResetSevenSixAxisSensorTimestamp"},
232 {400, nullptr, "IsUsbFullKeyControllerEnabled"},
233 {401, nullptr, "EnableUsbFullKeyController"},
234 {402, nullptr, "IsUsbFullKeyControllerConnected"},
235 {403, nullptr, "HasBattery"},
236 {404, nullptr, "HasLeftRightBattery"},
237 {405, nullptr, "GetNpadInterfaceType"},
238 {406, nullptr, "GetNpadLeftRightInterfaceType"},
239 {500, nullptr, "GetPalmaConnectionHandle"},
240 {501, nullptr, "InitializePalma"},
241 {502, nullptr, "AcquirePalmaOperationCompleteEvent"},
242 {503, nullptr, "GetPalmaOperationInfo"},
243 {504, nullptr, "PlayPalmaActivity"},
244 {505, nullptr, "SetPalmaFrModeType"},
245 {506, nullptr, "ReadPalmaStep"},
246 {507, nullptr, "EnablePalmaStep"},
247 {508, nullptr, "ResetPalmaStep"},
248 {509, nullptr, "ReadPalmaApplicationSection"},
249 {510, nullptr, "WritePalmaApplicationSection"},
250 {511, nullptr, "ReadPalmaUniqueCode"},
251 {512, nullptr, "SetPalmaUniqueCodeInvalid"},
252 {513, nullptr, "WritePalmaActivityEntry"},
253 {514, nullptr, "WritePalmaRgbLedPatternEntry"},
254 {515, nullptr, "WritePalmaWaveEntry"},
255 {516, nullptr, "SetPalmaDataBaseIdentificationVersion"},
256 {517, nullptr, "GetPalmaDataBaseIdentificationVersion"},
257 {518, nullptr, "SuspendPalmaFeature"},
258 {519, nullptr, "GetPalmaOperationResult"},
259 {520, nullptr, "ReadPalmaPlayLog"},
260 {521, nullptr, "ResetPalmaPlayLog"},
261 {522, &Hid::SetIsPalmaAllConnectable, "SetIsPalmaAllConnectable"},
262 {523, nullptr, "SetIsPalmaPairedConnectable"},
263 {524, nullptr, "PairPalma"},
264 {525, &Hid::SetPalmaBoostMode, "SetPalmaBoostMode"},
265 {1000, nullptr, "SetNpadCommunicationMode"},
266 {1001, nullptr, "GetNpadCommunicationMode"},
267 };
268 // clang-format on
269
270 RegisterHandlers(functions);
271}
311 272
312 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 273Hid::~Hid() = default;
313 274
314 if (applet_resource == nullptr) { 275void Hid::CreateAppletResource(Kernel::HLERequestContext& ctx) {
315 applet_resource = std::make_shared<IAppletResource>(); 276 IPC::RequestParser rp{ctx};
316 } 277 const auto applet_resource_user_id{rp.Pop<u64>()};
317 278
318 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 279 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
319 rb.Push(RESULT_SUCCESS); 280
320 rb.PushIpcInterface<IAppletResource>(applet_resource); 281 if (applet_resource == nullptr) {
282 applet_resource = std::make_shared<IAppletResource>();
321 } 283 }
322 284
323 void ActivateXpad(Kernel::HLERequestContext& ctx) { 285 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
324 IPC::RequestParser rp{ctx}; 286 rb.Push(RESULT_SUCCESS);
325 const auto basic_xpad_id{rp.Pop<u32>()}; 287 rb.PushIpcInterface<IAppletResource>(applet_resource);
326 const auto applet_resource_user_id{rp.Pop<u64>()}; 288}
327 289
328 LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}", 290void Hid::ActivateXpad(Kernel::HLERequestContext& ctx) {
329 basic_xpad_id, applet_resource_user_id); 291 IPC::RequestParser rp{ctx};
292 const auto basic_xpad_id{rp.Pop<u32>()};
293 const auto applet_resource_user_id{rp.Pop<u64>()};
330 294
331 applet_resource->ActivateController(HidController::XPad); 295 LOG_DEBUG(Service_HID, "called, basic_xpad_id={}, applet_resource_user_id={}", basic_xpad_id,
332 IPC::ResponseBuilder rb{ctx, 2}; 296 applet_resource_user_id);
333 rb.Push(RESULT_SUCCESS);
334 }
335 297
336 void ActivateDebugPad(Kernel::HLERequestContext& ctx) { 298 applet_resource->ActivateController(HidController::XPad);
337 IPC::RequestParser rp{ctx}; 299 IPC::ResponseBuilder rb{ctx, 2};
338 const auto applet_resource_user_id{rp.Pop<u64>()}; 300 rb.Push(RESULT_SUCCESS);
301}
339 302
340 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 303void Hid::ActivateDebugPad(Kernel::HLERequestContext& ctx) {
304 IPC::RequestParser rp{ctx};
305 const auto applet_resource_user_id{rp.Pop<u64>()};
341 306
342 applet_resource->ActivateController(HidController::DebugPad); 307 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
343 IPC::ResponseBuilder rb{ctx, 2};
344 rb.Push(RESULT_SUCCESS);
345 }
346 308
347 void ActivateTouchScreen(Kernel::HLERequestContext& ctx) { 309 applet_resource->ActivateController(HidController::DebugPad);
348 IPC::RequestParser rp{ctx}; 310 IPC::ResponseBuilder rb{ctx, 2};
349 const auto applet_resource_user_id{rp.Pop<u64>()}; 311 rb.Push(RESULT_SUCCESS);
312}
350 313
351 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 314void Hid::ActivateTouchScreen(Kernel::HLERequestContext& ctx) {
315 IPC::RequestParser rp{ctx};
316 const auto applet_resource_user_id{rp.Pop<u64>()};
352 317
353 applet_resource->ActivateController(HidController::Touchscreen); 318 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
354 IPC::ResponseBuilder rb{ctx, 2};
355 rb.Push(RESULT_SUCCESS);
356 }
357 319
358 void ActivateMouse(Kernel::HLERequestContext& ctx) { 320 applet_resource->ActivateController(HidController::Touchscreen);
359 IPC::RequestParser rp{ctx}; 321 IPC::ResponseBuilder rb{ctx, 2};
360 const auto applet_resource_user_id{rp.Pop<u64>()}; 322 rb.Push(RESULT_SUCCESS);
323}
361 324
362 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 325void Hid::ActivateMouse(Kernel::HLERequestContext& ctx) {
326 IPC::RequestParser rp{ctx};
327 const auto applet_resource_user_id{rp.Pop<u64>()};
363 328
364 applet_resource->ActivateController(HidController::Mouse); 329 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
365 IPC::ResponseBuilder rb{ctx, 2};
366 rb.Push(RESULT_SUCCESS);
367 }
368 330
369 void ActivateKeyboard(Kernel::HLERequestContext& ctx) { 331 applet_resource->ActivateController(HidController::Mouse);
370 IPC::RequestParser rp{ctx}; 332 IPC::ResponseBuilder rb{ctx, 2};
371 const auto applet_resource_user_id{rp.Pop<u64>()}; 333 rb.Push(RESULT_SUCCESS);
334}
372 335
373 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 336void Hid::ActivateKeyboard(Kernel::HLERequestContext& ctx) {
337 IPC::RequestParser rp{ctx};
338 const auto applet_resource_user_id{rp.Pop<u64>()};
374 339
375 applet_resource->ActivateController(HidController::Keyboard); 340 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
376 IPC::ResponseBuilder rb{ctx, 2};
377 rb.Push(RESULT_SUCCESS);
378 }
379 341
380 void ActivateGesture(Kernel::HLERequestContext& ctx) { 342 applet_resource->ActivateController(HidController::Keyboard);
381 IPC::RequestParser rp{ctx}; 343 IPC::ResponseBuilder rb{ctx, 2};
382 const auto unknown{rp.Pop<u32>()}; 344 rb.Push(RESULT_SUCCESS);
383 const auto applet_resource_user_id{rp.Pop<u64>()}; 345}
384 346
385 LOG_DEBUG(Service_HID, "called, unknown={}, applet_resource_user_id={}", unknown, 347void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) {
386 applet_resource_user_id); 348 IPC::RequestParser rp{ctx};
349 const auto unknown{rp.Pop<u32>()};
350 const auto applet_resource_user_id{rp.Pop<u64>()};
387 351
388 applet_resource->ActivateController(HidController::Gesture); 352 LOG_DEBUG(Service_HID, "called, unknown={}, applet_resource_user_id={}", unknown,
389 IPC::ResponseBuilder rb{ctx, 2}; 353 applet_resource_user_id);
390 rb.Push(RESULT_SUCCESS);
391 }
392 354
393 void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) { 355 applet_resource->ActivateController(HidController::Gesture);
394 // Should have no effect with how our npad sets up the data 356 IPC::ResponseBuilder rb{ctx, 2};
395 IPC::RequestParser rp{ctx}; 357 rb.Push(RESULT_SUCCESS);
396 const auto unknown{rp.Pop<u32>()}; 358}
397 const auto applet_resource_user_id{rp.Pop<u64>()};
398 359
399 LOG_DEBUG(Service_HID, "called, unknown={}, applet_resource_user_id={}", unknown, 360void Hid::ActivateNpadWithRevision(Kernel::HLERequestContext& ctx) {
400 applet_resource_user_id); 361 // Should have no effect with how our npad sets up the data
362 IPC::RequestParser rp{ctx};
363 const auto unknown{rp.Pop<u32>()};
364 const auto applet_resource_user_id{rp.Pop<u64>()};
401 365
402 applet_resource->ActivateController(HidController::NPad); 366 LOG_DEBUG(Service_HID, "called, unknown={}, applet_resource_user_id={}", unknown,
403 IPC::ResponseBuilder rb{ctx, 2}; 367 applet_resource_user_id);
404 rb.Push(RESULT_SUCCESS);
405 }
406 368
407 void StartSixAxisSensor(Kernel::HLERequestContext& ctx) { 369 applet_resource->ActivateController(HidController::NPad);
408 IPC::RequestParser rp{ctx}; 370 IPC::ResponseBuilder rb{ctx, 2};
409 const auto handle{rp.Pop<u32>()}; 371 rb.Push(RESULT_SUCCESS);
410 const auto applet_resource_user_id{rp.Pop<u64>()}; 372}
411 373
412 LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle, 374void Hid::StartSixAxisSensor(Kernel::HLERequestContext& ctx) {
413 applet_resource_user_id); 375 IPC::RequestParser rp{ctx};
376 const auto handle{rp.Pop<u32>()};
377 const auto applet_resource_user_id{rp.Pop<u64>()};
414 378
415 IPC::ResponseBuilder rb{ctx, 2}; 379 LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
416 rb.Push(RESULT_SUCCESS); 380 applet_resource_user_id);
417 }
418 381
419 void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) { 382 IPC::ResponseBuilder rb{ctx, 2};
420 IPC::RequestParser rp{ctx}; 383 rb.Push(RESULT_SUCCESS);
421 const auto handle{rp.Pop<u32>()}; 384}
422 const auto drift_mode{rp.Pop<u32>()};
423 const auto applet_resource_user_id{rp.Pop<u64>()};
424 385
425 LOG_WARNING(Service_HID, 386void Hid::SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx) {
426 "(STUBBED) called, handle={}, drift_mode={}, applet_resource_user_id={}", 387 IPC::RequestParser rp{ctx};
427 handle, drift_mode, applet_resource_user_id); 388 const auto handle{rp.Pop<u32>()};
389 const auto drift_mode{rp.Pop<u32>()};
390 const auto applet_resource_user_id{rp.Pop<u64>()};
428 391
429 IPC::ResponseBuilder rb{ctx, 2}; 392 LOG_WARNING(Service_HID,
430 rb.Push(RESULT_SUCCESS); 393 "(STUBBED) called, handle={}, drift_mode={}, applet_resource_user_id={}", handle,
431 } 394 drift_mode, applet_resource_user_id);
432 395
433 void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) { 396 IPC::ResponseBuilder rb{ctx, 2};
434 IPC::RequestParser rp{ctx}; 397 rb.Push(RESULT_SUCCESS);
435 const auto handle{rp.Pop<u32>()}; 398}
436 const auto applet_resource_user_id{rp.Pop<u64>()};
437 399
438 LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle, 400void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
439 applet_resource_user_id); 401 IPC::RequestParser rp{ctx};
402 const auto handle{rp.Pop<u32>()};
403 const auto applet_resource_user_id{rp.Pop<u64>()};
440 404
441 IPC::ResponseBuilder rb{ctx, 3}; 405 LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
442 rb.Push(RESULT_SUCCESS); 406 applet_resource_user_id);
443 // TODO (Hexagon12): Properly implement reading gyroscope values from controllers.
444 rb.Push(true);
445 }
446 407
447 void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { 408 IPC::ResponseBuilder rb{ctx, 3};
448 IPC::RequestParser rp{ctx}; 409 rb.Push(RESULT_SUCCESS);
449 const auto supported_styleset{rp.Pop<u32>()}; 410 // TODO (Hexagon12): Properly implement reading gyroscope values from controllers.
411 rb.Push(true);
412}
450 413
451 LOG_DEBUG(Service_HID, "called, supported_styleset={}", supported_styleset); 414void Hid::SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
415 IPC::RequestParser rp{ctx};
416 const auto supported_styleset{rp.Pop<u32>()};
452 417
453 applet_resource->GetController<Controller_NPad>(HidController::NPad) 418 LOG_DEBUG(Service_HID, "called, supported_styleset={}", supported_styleset);
454 .SetSupportedStyleSet({supported_styleset});
455 419
456 IPC::ResponseBuilder rb{ctx, 2}; 420 applet_resource->GetController<Controller_NPad>(HidController::NPad)
457 rb.Push(RESULT_SUCCESS); 421 .SetSupportedStyleSet({supported_styleset});
458 }
459 422
460 void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) { 423 IPC::ResponseBuilder rb{ctx, 2};
461 IPC::RequestParser rp{ctx}; 424 rb.Push(RESULT_SUCCESS);
462 const auto applet_resource_user_id{rp.Pop<u64>()}; 425}
463 426
464 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 427void Hid::GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx) {
428 IPC::RequestParser rp{ctx};
429 const auto applet_resource_user_id{rp.Pop<u64>()};
465 430
466 auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); 431 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
467 432
468 IPC::ResponseBuilder rb{ctx, 3}; 433 auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
469 rb.Push(RESULT_SUCCESS);
470 rb.Push<u32>(controller.GetSupportedStyleSet().raw);
471 }
472 434
473 void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) { 435 IPC::ResponseBuilder rb{ctx, 3};
474 IPC::RequestParser rp{ctx}; 436 rb.Push(RESULT_SUCCESS);
475 const auto applet_resource_user_id{rp.Pop<u64>()}; 437 rb.Push<u32>(controller.GetSupportedStyleSet().raw);
438}
476 439
477 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 440void Hid::SetSupportedNpadIdType(Kernel::HLERequestContext& ctx) {
441 IPC::RequestParser rp{ctx};
442 const auto applet_resource_user_id{rp.Pop<u64>()};
478 443
479 applet_resource->GetController<Controller_NPad>(HidController::NPad) 444 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
480 .SetSupportedNPadIdTypes(ctx.ReadBuffer().data(), ctx.GetReadBufferSize());
481 IPC::ResponseBuilder rb{ctx, 2};
482 rb.Push(RESULT_SUCCESS);
483 }
484 445
485 void ActivateNpad(Kernel::HLERequestContext& ctx) { 446 applet_resource->GetController<Controller_NPad>(HidController::NPad)
486 IPC::RequestParser rp{ctx}; 447 .SetSupportedNPadIdTypes(ctx.ReadBuffer().data(), ctx.GetReadBufferSize());
487 const auto applet_resource_user_id{rp.Pop<u64>()}; 448 IPC::ResponseBuilder rb{ctx, 2};
449 rb.Push(RESULT_SUCCESS);
450}
488 451
489 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 452void Hid::ActivateNpad(Kernel::HLERequestContext& ctx) {
453 IPC::RequestParser rp{ctx};
454 const auto applet_resource_user_id{rp.Pop<u64>()};
490 455
491 IPC::ResponseBuilder rb{ctx, 2}; 456 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
492 rb.Push(RESULT_SUCCESS);
493 applet_resource->ActivateController(HidController::NPad);
494 }
495 457
496 void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) { 458 IPC::ResponseBuilder rb{ctx, 2};
497 IPC::RequestParser rp{ctx}; 459 rb.Push(RESULT_SUCCESS);
498 const auto npad_id{rp.Pop<u32>()}; 460 applet_resource->ActivateController(HidController::NPad);
499 const auto applet_resource_user_id{rp.Pop<u64>()}; 461}
500 const auto unknown{rp.Pop<u64>()};
501 462
502 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", 463void Hid::AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx) {
503 npad_id, applet_resource_user_id, unknown); 464 IPC::RequestParser rp{ctx};
465 const auto npad_id{rp.Pop<u32>()};
466 const auto applet_resource_user_id{rp.Pop<u64>()};
467 const auto unknown{rp.Pop<u64>()};
504 468
505 IPC::ResponseBuilder rb{ctx, 2, 1}; 469 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}, unknown={}", npad_id,
506 rb.Push(RESULT_SUCCESS); 470 applet_resource_user_id, unknown);
507 rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad)
508 .GetStyleSetChangedEvent());
509 }
510 471
511 void DisconnectNpad(Kernel::HLERequestContext& ctx) { 472 IPC::ResponseBuilder rb{ctx, 2, 1};
512 IPC::RequestParser rp{ctx}; 473 rb.Push(RESULT_SUCCESS);
513 const auto npad_id{rp.Pop<u32>()}; 474 rb.PushCopyObjects(applet_resource->GetController<Controller_NPad>(HidController::NPad)
514 const auto applet_resource_user_id{rp.Pop<u64>()}; 475 .GetStyleSetChangedEvent());
476}
515 477
516 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id, 478void Hid::DisconnectNpad(Kernel::HLERequestContext& ctx) {
517 applet_resource_user_id); 479 IPC::RequestParser rp{ctx};
480 const auto npad_id{rp.Pop<u32>()};
481 const auto applet_resource_user_id{rp.Pop<u64>()};
518 482
519 applet_resource->GetController<Controller_NPad>(HidController::NPad) 483 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
520 .DisconnectNPad(npad_id); 484 applet_resource_user_id);
521 IPC::ResponseBuilder rb{ctx, 2};
522 rb.Push(RESULT_SUCCESS);
523 }
524 485
525 void GetPlayerLedPattern(Kernel::HLERequestContext& ctx) { 486 applet_resource->GetController<Controller_NPad>(HidController::NPad).DisconnectNPad(npad_id);
526 IPC::RequestParser rp{ctx}; 487 IPC::ResponseBuilder rb{ctx, 2};
527 const auto npad_id{rp.Pop<u32>()}; 488 rb.Push(RESULT_SUCCESS);
489}
528 490
529 LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id); 491void Hid::GetPlayerLedPattern(Kernel::HLERequestContext& ctx) {
492 IPC::RequestParser rp{ctx};
493 const auto npad_id{rp.Pop<u32>()};
530 494
531 IPC::ResponseBuilder rb{ctx, 4}; 495 LOG_DEBUG(Service_HID, "called, npad_id={}", npad_id);
532 rb.Push(RESULT_SUCCESS);
533 rb.PushRaw<u64>(applet_resource->GetController<Controller_NPad>(HidController::NPad)
534 .GetLedPattern(npad_id)
535 .raw);
536 }
537 496
538 void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { 497 IPC::ResponseBuilder rb{ctx, 4};
539 IPC::RequestParser rp{ctx}; 498 rb.Push(RESULT_SUCCESS);
540 const auto applet_resource_user_id{rp.Pop<u64>()}; 499 rb.PushRaw<u64>(applet_resource->GetController<Controller_NPad>(HidController::NPad)
541 const auto hold_type{rp.Pop<u64>()}; 500 .GetLedPattern(npad_id)
501 .raw);
502}
542 503
543 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}", 504void Hid::SetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
544 applet_resource_user_id, hold_type); 505 IPC::RequestParser rp{ctx};
506 const auto applet_resource_user_id{rp.Pop<u64>()};
507 const auto hold_type{rp.Pop<u64>()};
545 508
546 auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); 509 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}, hold_type={}",
547 controller.SetHoldType(Controller_NPad::NpadHoldType{hold_type}); 510 applet_resource_user_id, hold_type);
548 511
549 IPC::ResponseBuilder rb{ctx, 2}; 512 auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
550 rb.Push(RESULT_SUCCESS); 513 controller.SetHoldType(Controller_NPad::NpadHoldType{hold_type});
551 }
552 514
553 void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) { 515 IPC::ResponseBuilder rb{ctx, 2};
554 IPC::RequestParser rp{ctx}; 516 rb.Push(RESULT_SUCCESS);
555 const auto applet_resource_user_id{rp.Pop<u64>()}; 517}
556 518
557 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 519void Hid::GetNpadJoyHoldType(Kernel::HLERequestContext& ctx) {
520 IPC::RequestParser rp{ctx};
521 const auto applet_resource_user_id{rp.Pop<u64>()};
558 522
559 const auto& controller = 523 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
560 applet_resource->GetController<Controller_NPad>(HidController::NPad);
561 IPC::ResponseBuilder rb{ctx, 4};
562 rb.Push(RESULT_SUCCESS);
563 rb.Push<u64>(static_cast<u64>(controller.GetHoldType()));
564 }
565 524
566 void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) { 525 const auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
567 IPC::RequestParser rp{ctx}; 526 IPC::ResponseBuilder rb{ctx, 4};
568 const auto npad_id{rp.Pop<u32>()}; 527 rb.Push(RESULT_SUCCESS);
569 const auto applet_resource_user_id{rp.Pop<u64>()}; 528 rb.Push<u64>(static_cast<u64>(controller.GetHoldType()));
529}
570 530
571 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", 531void Hid::SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx) {
572 npad_id, applet_resource_user_id); 532 IPC::RequestParser rp{ctx};
533 const auto npad_id{rp.Pop<u32>()};
534 const auto applet_resource_user_id{rp.Pop<u64>()};
573 535
574 IPC::ResponseBuilder rb{ctx, 2}; 536 LOG_WARNING(Service_HID, "(STUBBED) called, npad_id={}, applet_resource_user_id={}", npad_id,
575 rb.Push(RESULT_SUCCESS); 537 applet_resource_user_id);
576 }
577 538
578 void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) { 539 IPC::ResponseBuilder rb{ctx, 2};
579 IPC::RequestParser rp{ctx}; 540 rb.Push(RESULT_SUCCESS);
580 const auto applet_resource_user_id{rp.Pop<u64>()}; 541}
581 542
582 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 543void Hid::BeginPermitVibrationSession(Kernel::HLERequestContext& ctx) {
544 IPC::RequestParser rp{ctx};
545 const auto applet_resource_user_id{rp.Pop<u64>()};
583 546
584 applet_resource->GetController<Controller_NPad>(HidController::NPad) 547 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
585 .SetVibrationEnabled(true);
586 IPC::ResponseBuilder rb{ctx, 2};
587 rb.Push(RESULT_SUCCESS);
588 }
589 548
590 void EndPermitVibrationSession(Kernel::HLERequestContext& ctx) { 549 applet_resource->GetController<Controller_NPad>(HidController::NPad).SetVibrationEnabled(true);
591 LOG_DEBUG(Service_HID, "called"); 550 IPC::ResponseBuilder rb{ctx, 2};
551 rb.Push(RESULT_SUCCESS);
552}
592 553
593 applet_resource->GetController<Controller_NPad>(HidController::NPad) 554void Hid::EndPermitVibrationSession(Kernel::HLERequestContext& ctx) {
594 .SetVibrationEnabled(false); 555 LOG_DEBUG(Service_HID, "called");
595 IPC::ResponseBuilder rb{ctx, 2};
596 rb.Push(RESULT_SUCCESS);
597 }
598 556
599 void SendVibrationValue(Kernel::HLERequestContext& ctx) { 557 applet_resource->GetController<Controller_NPad>(HidController::NPad).SetVibrationEnabled(false);
600 IPC::RequestParser rp{ctx}; 558 IPC::ResponseBuilder rb{ctx, 2};
601 const auto controller_id{rp.Pop<u32>()}; 559 rb.Push(RESULT_SUCCESS);
602 const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()}; 560}
603 const auto applet_resource_user_id{rp.Pop<u64>()};
604 561
605 LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", 562void Hid::SendVibrationValue(Kernel::HLERequestContext& ctx) {
606 controller_id, applet_resource_user_id); 563 IPC::RequestParser rp{ctx};
564 const auto controller_id{rp.Pop<u32>()};
565 const auto vibration_values{rp.PopRaw<Controller_NPad::Vibration>()};
566 const auto applet_resource_user_id{rp.Pop<u64>()};
607 567
608 IPC::ResponseBuilder rb{ctx, 2}; 568 LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
609 rb.Push(RESULT_SUCCESS); 569 applet_resource_user_id);
610 570
611 applet_resource->GetController<Controller_NPad>(HidController::NPad) 571 IPC::ResponseBuilder rb{ctx, 2};
612 .VibrateController({controller_id}, {vibration_values}); 572 rb.Push(RESULT_SUCCESS);
613 }
614 573
615 void SendVibrationValues(Kernel::HLERequestContext& ctx) { 574 applet_resource->GetController<Controller_NPad>(HidController::NPad)
616 IPC::RequestParser rp{ctx}; 575 .VibrateController({controller_id}, {vibration_values});
617 const auto applet_resource_user_id{rp.Pop<u64>()}; 576}
618 577
619 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id); 578void Hid::SendVibrationValues(Kernel::HLERequestContext& ctx) {
579 IPC::RequestParser rp{ctx};
580 const auto applet_resource_user_id{rp.Pop<u64>()};
620 581
621 const auto controllers = ctx.ReadBuffer(0); 582 LOG_DEBUG(Service_HID, "called, applet_resource_user_id={}", applet_resource_user_id);
622 const auto vibrations = ctx.ReadBuffer(1);
623 583
624 std::vector<u32> controller_list(controllers.size() / sizeof(u32)); 584 const auto controllers = ctx.ReadBuffer(0);
625 std::vector<Controller_NPad::Vibration> vibration_list(vibrations.size() / 585 const auto vibrations = ctx.ReadBuffer(1);
626 sizeof(Controller_NPad::Vibration));
627 586
628 std::memcpy(controller_list.data(), controllers.data(), controllers.size()); 587 std::vector<u32> controller_list(controllers.size() / sizeof(u32));
629 std::memcpy(vibration_list.data(), vibrations.data(), vibrations.size()); 588 std::vector<Controller_NPad::Vibration> vibration_list(vibrations.size() /
630 std::transform(controller_list.begin(), controller_list.end(), controller_list.begin(), 589 sizeof(Controller_NPad::Vibration));
631 [](u32 controller_id) { return controller_id - 3; });
632 590
633 applet_resource->GetController<Controller_NPad>(HidController::NPad) 591 std::memcpy(controller_list.data(), controllers.data(), controllers.size());
634 .VibrateController(controller_list, vibration_list); 592 std::memcpy(vibration_list.data(), vibrations.data(), vibrations.size());
593 std::transform(controller_list.begin(), controller_list.end(), controller_list.begin(),
594 [](u32 controller_id) { return controller_id - 3; });
635 595
636 IPC::ResponseBuilder rb{ctx, 2}; 596 applet_resource->GetController<Controller_NPad>(HidController::NPad)
637 rb.Push(RESULT_SUCCESS); 597 .VibrateController(controller_list, vibration_list);
638 }
639 598
640 void GetActualVibrationValue(Kernel::HLERequestContext& ctx) { 599 IPC::ResponseBuilder rb{ctx, 2};
641 IPC::RequestParser rp{ctx}; 600 rb.Push(RESULT_SUCCESS);
642 const auto controller_id{rp.Pop<u32>()}; 601}
643 const auto applet_resource_user_id{rp.Pop<u64>()};
644 602
645 LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", 603void Hid::GetActualVibrationValue(Kernel::HLERequestContext& ctx) {
646 controller_id, applet_resource_user_id); 604 IPC::RequestParser rp{ctx};
605 const auto controller_id{rp.Pop<u32>()};
606 const auto applet_resource_user_id{rp.Pop<u64>()};
647 607
648 IPC::ResponseBuilder rb{ctx, 6}; 608 LOG_DEBUG(Service_HID, "called, controller_id={}, applet_resource_user_id={}", controller_id,
649 rb.Push(RESULT_SUCCESS); 609 applet_resource_user_id);
650 rb.PushRaw<Controller_NPad::Vibration>(
651 applet_resource->GetController<Controller_NPad>(HidController::NPad)
652 .GetLastVibration());
653 }
654 610
655 void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) { 611 IPC::ResponseBuilder rb{ctx, 6};
656 IPC::RequestParser rp{ctx}; 612 rb.Push(RESULT_SUCCESS);
657 const auto npad_id{rp.Pop<u32>()}; 613 rb.PushRaw<Controller_NPad::Vibration>(
658 const auto applet_resource_user_id{rp.Pop<u64>()}; 614 applet_resource->GetController<Controller_NPad>(HidController::NPad).GetLastVibration());
615}
659 616
660 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id, 617void Hid::SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx) {
661 applet_resource_user_id); 618 IPC::RequestParser rp{ctx};
619 const auto npad_id{rp.Pop<u32>()};
620 const auto applet_resource_user_id{rp.Pop<u64>()};
662 621
663 auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad); 622 LOG_DEBUG(Service_HID, "called, npad_id={}, applet_resource_user_id={}", npad_id,
664 controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual); 623 applet_resource_user_id);
665 624
666 IPC::ResponseBuilder rb{ctx, 2}; 625 auto& controller = applet_resource->GetController<Controller_NPad>(HidController::NPad);
667 rb.Push(RESULT_SUCCESS); 626 controller.SetNpadMode(npad_id, Controller_NPad::NPadAssignments::Dual);
668 }
669 627
670 void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) { 628 IPC::ResponseBuilder rb{ctx, 2};
671 IPC::RequestParser rp{ctx}; 629 rb.Push(RESULT_SUCCESS);
672 const auto unknown_1{rp.Pop<u32>()}; 630}
673 const auto unknown_2{rp.Pop<u32>()};
674 const auto applet_resource_user_id{rp.Pop<u64>()};
675 631
676 LOG_WARNING(Service_HID, 632void Hid::MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx) {
677 "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}", 633 IPC::RequestParser rp{ctx};
678 unknown_1, unknown_2, applet_resource_user_id); 634 const auto unknown_1{rp.Pop<u32>()};
635 const auto unknown_2{rp.Pop<u32>()};
636 const auto applet_resource_user_id{rp.Pop<u64>()};
679 637
680 IPC::ResponseBuilder rb{ctx, 2}; 638 LOG_WARNING(Service_HID,
681 rb.Push(RESULT_SUCCESS); 639 "(STUBBED) called, unknown_1={}, unknown_2={}, applet_resource_user_id={}",
682 } 640 unknown_1, unknown_2, applet_resource_user_id);
683 641
684 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) { 642 IPC::ResponseBuilder rb{ctx, 2};
685 IPC::RequestParser rp{ctx}; 643 rb.Push(RESULT_SUCCESS);
686 const auto applet_resource_user_id{rp.Pop<u64>()}; 644}
687 const auto mode{rp.Pop<u64>()};
688 645
689 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}", 646void Hid::SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx) {
690 applet_resource_user_id, mode); 647 IPC::RequestParser rp{ctx};
648 const auto applet_resource_user_id{rp.Pop<u64>()};
649 const auto mode{rp.Pop<u64>()};
691 650
692 IPC::ResponseBuilder rb{ctx, 2}; 651 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, mode={}",
693 rb.Push(RESULT_SUCCESS); 652 applet_resource_user_id, mode);
694 }
695 653
696 void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) { 654 IPC::ResponseBuilder rb{ctx, 2};
697 LOG_DEBUG(Service_HID, "called"); 655 rb.Push(RESULT_SUCCESS);
656}
698 657
699 IPC::ResponseBuilder rb{ctx, 4}; 658void Hid::GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx) {
700 rb.Push(RESULT_SUCCESS); 659 LOG_DEBUG(Service_HID, "called");
701 rb.Push<u32>(1);
702 rb.Push<u32>(0);
703 }
704 660
705 void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) { 661 IPC::ResponseBuilder rb{ctx, 4};
706 LOG_DEBUG(Service_HID, "called"); 662 rb.Push(RESULT_SUCCESS);
663 rb.Push<u32>(1);
664 rb.Push<u32>(0);
665}
707 666
708 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 667void Hid::CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx) {
709 rb.Push(RESULT_SUCCESS); 668 LOG_DEBUG(Service_HID, "called");
710 rb.PushIpcInterface<IActiveVibrationDeviceList>();
711 }
712 669
713 void ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { 670 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
714 IPC::RequestParser rp{ctx}; 671 rb.Push(RESULT_SUCCESS);
715 const auto applet_resource_user_id{rp.Pop<u64>()}; 672 rb.PushIpcInterface<IActiveVibrationDeviceList>();
673}
716 674
717 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}", 675void Hid::ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
718 applet_resource_user_id); 676 IPC::RequestParser rp{ctx};
677 const auto applet_resource_user_id{rp.Pop<u64>()};
719 678
720 IPC::ResponseBuilder rb{ctx, 2}; 679 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}",
721 rb.Push(RESULT_SUCCESS); 680 applet_resource_user_id);
722 }
723 681
724 void StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) { 682 IPC::ResponseBuilder rb{ctx, 2};
725 IPC::RequestParser rp{ctx}; 683 rb.Push(RESULT_SUCCESS);
726 const auto handle{rp.Pop<u32>()}; 684}
727 const auto applet_resource_user_id{rp.Pop<u64>()};
728 685
729 LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle, 686void Hid::StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx) {
730 applet_resource_user_id); 687 IPC::RequestParser rp{ctx};
688 const auto handle{rp.Pop<u32>()};
689 const auto applet_resource_user_id{rp.Pop<u64>()};
731 690
732 IPC::ResponseBuilder rb{ctx, 2}; 691 LOG_WARNING(Service_HID, "(STUBBED) called, handle={}, applet_resource_user_id={}", handle,
733 rb.Push(RESULT_SUCCESS); 692 applet_resource_user_id);
734 }
735 693
736 void StopSixAxisSensor(Kernel::HLERequestContext& ctx) { 694 IPC::ResponseBuilder rb{ctx, 2};
737 IPC::RequestParser rp{ctx}; 695 rb.Push(RESULT_SUCCESS);
738 const auto handle{rp.Pop<u32>()}; 696}
739 697
740 LOG_WARNING(Service_HID, "(STUBBED) called, handle={}", handle); 698void Hid::StopSixAxisSensor(Kernel::HLERequestContext& ctx) {
699 IPC::RequestParser rp{ctx};
700 const auto handle{rp.Pop<u32>()};
741 701
742 IPC::ResponseBuilder rb{ctx, 2}; 702 LOG_WARNING(Service_HID, "(STUBBED) called, handle={}", handle);
743 rb.Push(RESULT_SUCCESS);
744 }
745 703
746 void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) { 704 IPC::ResponseBuilder rb{ctx, 2};
747 IPC::RequestParser rp{ctx}; 705 rb.Push(RESULT_SUCCESS);
748 const auto applet_resource_user_id{rp.Pop<u64>()}; 706}
749 const auto unknown{rp.Pop<u32>()};
750 707
751 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, unknown={}", 708void Hid::SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx) {
752 applet_resource_user_id, unknown); 709 IPC::RequestParser rp{ctx};
710 const auto applet_resource_user_id{rp.Pop<u64>()};
711 const auto unknown{rp.Pop<u32>()};
753 712
754 IPC::ResponseBuilder rb{ctx, 2}; 713 LOG_WARNING(Service_HID, "(STUBBED) called, applet_resource_user_id={}, unknown={}",
755 rb.Push(RESULT_SUCCESS); 714 applet_resource_user_id, unknown);
756 }
757 715
758 void SetPalmaBoostMode(Kernel::HLERequestContext& ctx) { 716 IPC::ResponseBuilder rb{ctx, 2};
759 IPC::RequestParser rp{ctx}; 717 rb.Push(RESULT_SUCCESS);
760 const auto unknown{rp.Pop<u32>()}; 718}
761 719
762 LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}", unknown); 720void Hid::SetPalmaBoostMode(Kernel::HLERequestContext& ctx) {
721 IPC::RequestParser rp{ctx};
722 const auto unknown{rp.Pop<u32>()};
763 723
764 IPC::ResponseBuilder rb{ctx, 2}; 724 LOG_WARNING(Service_HID, "(STUBBED) called, unknown={}", unknown);
765 rb.Push(RESULT_SUCCESS); 725
766 } 726 IPC::ResponseBuilder rb{ctx, 2};
767}; 727 rb.Push(RESULT_SUCCESS);
728}
768 729
769class HidDbg final : public ServiceFramework<HidDbg> { 730class HidDbg final : public ServiceFramework<HidDbg> {
770public: 731public:
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 773035460..eca27c056 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -4,12 +4,122 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "controllers/controller_base.h"
8#include "core/hle/service/service.h"
9
10namespace CoreTiming {
11struct EventType;
12}
13
14namespace Kernel {
15class SharedMemory;
16}
17
7namespace SM { 18namespace SM {
8class ServiceManager; 19class ServiceManager;
9} 20}
10 21
11namespace Service::HID { 22namespace Service::HID {
12 23
24enum class HidController : std::size_t {
25 DebugPad,
26 Touchscreen,
27 Mouse,
28 Keyboard,
29 XPad,
30 Unknown1,
31 Unknown2,
32 Unknown3,
33 SixAxisSensor,
34 NPad,
35 Gesture,
36
37 MaxControllers,
38};
39
40class IAppletResource final : public ServiceFramework<IAppletResource> {
41public:
42 IAppletResource();
43 ~IAppletResource() override;
44
45 void ActivateController(HidController controller);
46 void DeactivateController(HidController controller);
47
48 template <typename T>
49 T& GetController(HidController controller) {
50 return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
51 }
52
53 template <typename T>
54 const T& GetController(HidController controller) const {
55 return static_cast<T&>(*controllers[static_cast<size_t>(controller)]);
56 }
57
58private:
59 template <typename T>
60 void MakeController(HidController controller) {
61 controllers[static_cast<std::size_t>(controller)] = std::make_unique<T>();
62 }
63
64 void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx);
65 void UpdateControllers(u64 userdata, int cycles_late);
66
67 Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
68
69 CoreTiming::EventType* pad_update_event;
70
71 std::array<std::unique_ptr<ControllerBase>, static_cast<size_t>(HidController::MaxControllers)>
72 controllers{};
73};
74
75class Hid final : public ServiceFramework<Hid> {
76public:
77 Hid();
78 ~Hid() override;
79
80 std::shared_ptr<IAppletResource> GetAppletResource();
81
82private:
83 void CreateAppletResource(Kernel::HLERequestContext& ctx);
84 void ActivateXpad(Kernel::HLERequestContext& ctx);
85 void ActivateDebugPad(Kernel::HLERequestContext& ctx);
86 void ActivateTouchScreen(Kernel::HLERequestContext& ctx);
87 void ActivateMouse(Kernel::HLERequestContext& ctx);
88 void ActivateKeyboard(Kernel::HLERequestContext& ctx);
89 void ActivateGesture(Kernel::HLERequestContext& ctx);
90 void ActivateNpadWithRevision(Kernel::HLERequestContext& ctx);
91 void StartSixAxisSensor(Kernel::HLERequestContext& ctx);
92 void SetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
93 void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx);
94 void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
95 void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
96 void SetSupportedNpadIdType(Kernel::HLERequestContext& ctx);
97 void ActivateNpad(Kernel::HLERequestContext& ctx);
98 void AcquireNpadStyleSetUpdateEventHandle(Kernel::HLERequestContext& ctx);
99 void DisconnectNpad(Kernel::HLERequestContext& ctx);
100 void GetPlayerLedPattern(Kernel::HLERequestContext& ctx);
101 void SetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
102 void GetNpadJoyHoldType(Kernel::HLERequestContext& ctx);
103 void SetNpadJoyAssignmentModeSingleByDefault(Kernel::HLERequestContext& ctx);
104 void BeginPermitVibrationSession(Kernel::HLERequestContext& ctx);
105 void EndPermitVibrationSession(Kernel::HLERequestContext& ctx);
106 void SendVibrationValue(Kernel::HLERequestContext& ctx);
107 void SendVibrationValues(Kernel::HLERequestContext& ctx);
108 void GetActualVibrationValue(Kernel::HLERequestContext& ctx);
109 void SetNpadJoyAssignmentModeDual(Kernel::HLERequestContext& ctx);
110 void MergeSingleJoyAsDualJoy(Kernel::HLERequestContext& ctx);
111 void SetNpadHandheldActivationMode(Kernel::HLERequestContext& ctx);
112 void GetVibrationDeviceInfo(Kernel::HLERequestContext& ctx);
113 void CreateActiveVibrationDeviceList(Kernel::HLERequestContext& ctx);
114 void ActivateConsoleSixAxisSensor(Kernel::HLERequestContext& ctx);
115 void StartConsoleSixAxisSensor(Kernel::HLERequestContext& ctx);
116 void StopSixAxisSensor(Kernel::HLERequestContext& ctx);
117 void SetIsPalmaAllConnectable(Kernel::HLERequestContext& ctx);
118 void SetPalmaBoostMode(Kernel::HLERequestContext& ctx);
119
120 std::shared_ptr<IAppletResource> applet_resource;
121};
122
13/// Reload input devices. Used when input configuration changed 123/// Reload input devices. Used when input configuration changed
14void ReloadInputDevices(); 124void ReloadInputDevices();
15 125
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h
index 30eacd803..01f984098 100644
--- a/src/core/loader/loader.h
+++ b/src/core/loader/loader.h
@@ -259,6 +259,15 @@ public:
259 return ResultStatus::ErrorNotImplemented; 259 return ResultStatus::ErrorNotImplemented;
260 } 260 }
261 261
262 /**
263 * Get the RomFS of the manual of the application
264 * @param file The raw manual RomFS of the game
265 * @return ResultStatus result of function
266 */
267 virtual ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) {
268 return ResultStatus::ErrorNotImplemented;
269 }
270
262protected: 271protected:
263 FileSys::VirtualFile file; 272 FileSys::VirtualFile file;
264 bool is_loaded = false; 273 bool is_loaded = false;
diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp
index 4d4b44571..7fcb12aa2 100644
--- a/src/core/loader/nsp.cpp
+++ b/src/core/loader/nsp.cpp
@@ -158,4 +158,12 @@ ResultStatus AppLoader_NSP::ReadControlData(FileSys::NACP& nacp) {
158 nacp = *nacp_file; 158 nacp = *nacp_file;
159 return ResultStatus::Success; 159 return ResultStatus::Success;
160} 160}
161
162ResultStatus AppLoader_NSP::ReadManualRomFS(FileSys::VirtualFile& file) {
163 const auto nca = nsp->GetNCA(nsp->GetProgramTitleID(), FileSys::ContentRecordType::Manual);
164 if (nsp->GetStatus() != ResultStatus::Success || nca == nullptr)
165 return ResultStatus::ErrorNoRomFS;
166 file = nca->GetRomFS();
167 return file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success;
168}
161} // namespace Loader 169} // namespace Loader
diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h
index 32eb0193d..b6b309400 100644
--- a/src/core/loader/nsp.h
+++ b/src/core/loader/nsp.h
@@ -44,6 +44,7 @@ public:
44 ResultStatus ReadIcon(std::vector<u8>& buffer) override; 44 ResultStatus ReadIcon(std::vector<u8>& buffer) override;
45 ResultStatus ReadTitle(std::string& title) override; 45 ResultStatus ReadTitle(std::string& title) override;
46 ResultStatus ReadControlData(FileSys::NACP& nacp) override; 46 ResultStatus ReadControlData(FileSys::NACP& nacp) override;
47 ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) override;
47 48
48private: 49private:
49 std::unique_ptr<FileSys::NSP> nsp; 50 std::unique_ptr<FileSys::NSP> nsp;
diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp
index e67e43c69..ff60a3756 100644
--- a/src/core/loader/xci.cpp
+++ b/src/core/loader/xci.cpp
@@ -128,4 +128,13 @@ ResultStatus AppLoader_XCI::ReadControlData(FileSys::NACP& control) {
128 return ResultStatus::Success; 128 return ResultStatus::Success;
129} 129}
130 130
131ResultStatus AppLoader_XCI::ReadManualRomFS(FileSys::VirtualFile& file) {
132 const auto nca = xci->GetSecurePartitionNSP()->GetNCA(xci->GetProgramTitleID(),
133 FileSys::ContentRecordType::Manual);
134 if (xci->GetStatus() != ResultStatus::Success || nca == nullptr)
135 return ResultStatus::ErrorXCIMissingPartition;
136 file = nca->GetRomFS();
137 return file == nullptr ? ResultStatus::ErrorNoRomFS : ResultStatus::Success;
138}
139
131} // namespace Loader 140} // namespace Loader
diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h
index 9d3923f62..e18531c93 100644
--- a/src/core/loader/xci.h
+++ b/src/core/loader/xci.h
@@ -44,6 +44,7 @@ public:
44 ResultStatus ReadIcon(std::vector<u8>& buffer) override; 44 ResultStatus ReadIcon(std::vector<u8>& buffer) override;
45 ResultStatus ReadTitle(std::string& title) override; 45 ResultStatus ReadTitle(std::string& title) override;
46 ResultStatus ReadControlData(FileSys::NACP& control) override; 46 ResultStatus ReadControlData(FileSys::NACP& control) override;
47 ResultStatus ReadManualRomFS(FileSys::VirtualFile& file) override;
47 48
48private: 49private:
49 std::unique_ptr<FileSys::XCI> xci; 50 std::unique_ptr<FileSys::XCI> xci;