summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Subv2015-02-26 21:13:08 -0500
committerGravatar Subv2015-03-03 21:48:08 -0500
commit83a8975cb89b908b4737d647a210c19775f25ed7 (patch)
tree53fd0e37dcab9c3a5328338273315b159381d949 /src
parentMerge pull request #622 from Subv/titles (diff)
downloadyuzu-83a8975cb89b908b4737d647a210c19775f25ed7.tar.gz
yuzu-83a8975cb89b908b4737d647a210c19775f25ed7.tar.xz
yuzu-83a8975cb89b908b4737d647a210c19775f25ed7.zip
Services: Moved the PTM and APT services to their own folder
This coincidentally fixes an issue about the PTM service failing to create its SharedExtSaveData archive due to the FS service not being initialized by the time the creating code runs. Ideally I'd like to move each process to its own folder, and have a single file per process that registers the service classes, which would be in their own files inside that folder. Then each service class would just call functions from the process to complete the commands.
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt28
-rw-r--r--src/core/hle/hle.cpp9
-rw-r--r--src/core/hle/service/apt/apt.cpp285
-rw-r--r--src/core/hle/service/apt/apt.h222
-rw-r--r--src/core/hle/service/apt/apt_a.cpp33
-rw-r--r--src/core/hle/service/apt/apt_a.h (renamed from src/core/hle/service/apt_a.h)13
-rw-r--r--src/core/hle/service/apt/apt_s.cpp104
-rw-r--r--src/core/hle/service/apt/apt_s.h (renamed from src/core/hle/service/apt_s.h)13
-rw-r--r--src/core/hle/service/apt/apt_u.cpp103
-rw-r--r--src/core/hle/service/apt/apt_u.h (renamed from src/core/hle/service/apt_u.h)13
-rw-r--r--src/core/hle/service/apt_a.cpp44
-rw-r--r--src/core/hle/service/apt_s.cpp123
-rw-r--r--src/core/hle/service/apt_u.cpp526
-rw-r--r--src/core/hle/service/cfg/cfg.cpp12
-rw-r--r--src/core/hle/service/cfg/cfg_i.cpp14
-rw-r--r--src/core/hle/service/cfg/cfg_i.h13
-rw-r--r--src/core/hle/service/cfg/cfg_s.cpp14
-rw-r--r--src/core/hle/service/cfg/cfg_s.h13
-rw-r--r--src/core/hle/service/cfg/cfg_u.cpp14
-rw-r--r--src/core/hle/service/cfg/cfg_u.h13
-rw-r--r--src/core/hle/service/fs/archive.cpp4
-rw-r--r--src/core/hle/service/fs/fs_user.cpp4
-rw-r--r--src/core/hle/service/fs/fs_user.h7
-rw-r--r--src/core/hle/service/hid/hid.cpp32
-rw-r--r--src/core/hle/service/hid/hid.h17
-rw-r--r--src/core/hle/service/hid/hid_spvr.cpp21
-rw-r--r--src/core/hle/service/hid/hid_spvr.h13
-rw-r--r--src/core/hle/service/hid/hid_user.cpp58
-rw-r--r--src/core/hle/service/hid/hid_user.h15
-rw-r--r--src/core/hle/service/ptm/ptm.cpp76
-rw-r--r--src/core/hle/service/ptm/ptm.h65
-rw-r--r--src/core/hle/service/ptm/ptm_play.cpp (renamed from src/core/hle/service/ptm_play.cpp)16
-rw-r--r--src/core/hle/service/ptm/ptm_play.h (renamed from src/core/hle/service/ptm_play.h)13
-rw-r--r--src/core/hle/service/ptm/ptm_sysm.cpp (renamed from src/core/hle/service/ptm_sysm.cpp)16
-rw-r--r--src/core/hle/service/ptm/ptm_sysm.h (renamed from src/core/hle/service/ptm_sysm.h)13
-rw-r--r--src/core/hle/service/ptm/ptm_u.cpp99
-rw-r--r--src/core/hle/service/ptm/ptm_u.h (renamed from src/core/hle/service/ptm_u.h)15
-rw-r--r--src/core/hle/service/ptm_u.cpp166
-rw-r--r--src/core/hle/service/service.cpp50
-rw-r--r--src/core/hle/service/service.h3
40 files changed, 1202 insertions, 1110 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 0ab0e440c..212da25c5 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -35,9 +35,10 @@ set(SRCS
35 hle/service/am_app.cpp 35 hle/service/am_app.cpp
36 hle/service/am_net.cpp 36 hle/service/am_net.cpp
37 hle/service/am_sys.cpp 37 hle/service/am_sys.cpp
38 hle/service/apt_a.cpp 38 hle/service/apt/apt.cpp
39 hle/service/apt_s.cpp 39 hle/service/apt/apt_a.cpp
40 hle/service/apt_u.cpp 40 hle/service/apt/apt_s.cpp
41 hle/service/apt/apt_u.cpp
41 hle/service/boss_p.cpp 42 hle/service/boss_p.cpp
42 hle/service/boss_u.cpp 43 hle/service/boss_u.cpp
43 hle/service/cam_u.cpp 44 hle/service/cam_u.cpp
@@ -71,9 +72,10 @@ set(SRCS
71 hle/service/ns_s.cpp 72 hle/service/ns_s.cpp
72 hle/service/nwm_uds.cpp 73 hle/service/nwm_uds.cpp
73 hle/service/pm_app.cpp 74 hle/service/pm_app.cpp
74 hle/service/ptm_play.cpp 75 hle/service/ptm/ptm.cpp
75 hle/service/ptm_u.cpp 76 hle/service/ptm/ptm_play.cpp
76 hle/service/ptm_sysm.cpp 77 hle/service/ptm/ptm_u.cpp
78 hle/service/ptm/ptm_sysm.cpp
77 hle/service/service.cpp 79 hle/service/service.cpp
78 hle/service/soc_u.cpp 80 hle/service/soc_u.cpp
79 hle/service/srv.cpp 81 hle/service/srv.cpp
@@ -140,9 +142,10 @@ set(HEADERS
140 hle/service/am_app.h 142 hle/service/am_app.h
141 hle/service/am_net.h 143 hle/service/am_net.h
142 hle/service/am_sys.h 144 hle/service/am_sys.h
143 hle/service/apt_a.h 145 hle/service/apt/apt.h
144 hle/service/apt_s.h 146 hle/service/apt/apt_a.h
145 hle/service/apt_u.h 147 hle/service/apt/apt_s.h
148 hle/service/apt/apt_u.h
146 hle/service/boss_p.h 149 hle/service/boss_p.h
147 hle/service/boss_u.h 150 hle/service/boss_u.h
148 hle/service/cam_u.h 151 hle/service/cam_u.h
@@ -176,9 +179,10 @@ set(HEADERS
176 hle/service/ns_s.h 179 hle/service/ns_s.h
177 hle/service/nwm_uds.h 180 hle/service/nwm_uds.h
178 hle/service/pm_app.h 181 hle/service/pm_app.h
179 hle/service/ptm_play.h 182 hle/service/ptm/ptm.h
180 hle/service/ptm_u.h 183 hle/service/ptm/ptm_play.h
181 hle/service/ptm_sysm.h 184 hle/service/ptm/ptm_u.h
185 hle/service/ptm/ptm_sysm.h
182 hle/service/service.h 186 hle/service/service.h
183 hle/service/soc_u.h 187 hle/service/soc_u.h
184 hle/service/srv.h 188 hle/service/srv.h
diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp
index b0066e15e..c6764a529 100644
--- a/src/core/hle/hle.cpp
+++ b/src/core/hle/hle.cpp
@@ -11,9 +11,6 @@
11#include "core/hle/shared_page.h" 11#include "core/hle/shared_page.h"
12#include "core/hle/kernel/thread.h" 12#include "core/hle/kernel/thread.h"
13#include "core/hle/service/service.h" 13#include "core/hle/service/service.h"
14#include "core/hle/service/fs/archive.h"
15#include "core/hle/service/cfg/cfg.h"
16#include "core/hle/service/hid/hid.h"
17 14
18//////////////////////////////////////////////////////////////////////////////////////////////////// 15////////////////////////////////////////////////////////////////////////////////////////////////////
19 16
@@ -70,9 +67,6 @@ static void RegisterAllModules() {
70 67
71void Init() { 68void Init() {
72 Service::Init(); 69 Service::Init();
73 Service::FS::ArchiveInit();
74 Service::CFG::CFGInit();
75 Service::HID::HIDInit();
76 70
77 RegisterAllModules(); 71 RegisterAllModules();
78 72
@@ -83,9 +77,6 @@ void Init() {
83} 77}
84 78
85void Shutdown() { 79void Shutdown() {
86 Service::HID::HIDShutdown();
87 Service::CFG::CFGShutdown();
88 Service::FS::ArchiveShutdown();
89 Service::Shutdown(); 80 Service::Shutdown();
90 81
91 g_module_db.clear(); 82 g_module_db.clear();
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp
new file mode 100644
index 000000000..5971f860b
--- /dev/null
+++ b/src/core/hle/service/apt/apt.cpp
@@ -0,0 +1,285 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/file_util.h"
6
7#include "core/hle/service/service.h"
8#include "core/hle/service/apt/apt.h"
9#include "core/hle/service/apt/apt_a.h"
10#include "core/hle/service/apt/apt_s.h"
11#include "core/hle/service/apt/apt_u.h"
12
13#include "core/hle/hle.h"
14#include "core/hle/kernel/event.h"
15#include "core/hle/kernel/mutex.h"
16#include "core/hle/kernel/shared_memory.h"
17#include "core/hle/kernel/thread.h"
18
19namespace Service {
20namespace APT {
21
22// Address used for shared font (as observed on HW)
23// TODO(bunnei): This is the hard-coded address where we currently dump the shared font from via
24// https://github.com/citra-emu/3dsutils. This is technically a hack, and will not work at any
25// address other than 0x18000000 due to internal pointers in the shared font dump that would need to
26// be relocated. This might be fixed by dumping the shared font @ address 0x00000000 and then
27// correctly mapping it in Citra, however we still do not understand how the mapping is determined.
28static const VAddr SHARED_FONT_VADDR = 0x18000000;
29
30/// Handle to shared memory region designated to for shared system font
31static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
32
33static Kernel::SharedPtr<Kernel::Mutex> lock;
34static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
35static Kernel::SharedPtr<Kernel::Event> pause_event = 0; ///< APT pause event
36static std::vector<u8> shared_font;
37
38void Initialize(Service::Interface* self) {
39 u32* cmd_buff = Kernel::GetCommandBuffer();
40
41 cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom();
42 cmd_buff[4] = Kernel::g_handle_table.Create(pause_event).MoveFrom();
43
44 // TODO(bunnei): Check if these events are cleared/signaled every time Initialize is called.
45 notification_event->Clear();
46 pause_event->Signal(); // Fire start event
47
48 ASSERT_MSG((nullptr != lock), "Cannot initialize without lock");
49 lock->Release();
50
51 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
52}
53
54void GetSharedFont(Service::Interface* self) {
55 u32* cmd_buff = Kernel::GetCommandBuffer();
56
57 if (!shared_font.empty()) {
58 // TODO(bunnei): This function shouldn't copy the shared font every time it's called.
59 // Instead, it should probably map the shared font as RO memory. We don't currently have
60 // an easy way to do this, but the copy should be sufficient for now.
61 memcpy(Memory::GetPointer(SHARED_FONT_VADDR), shared_font.data(), shared_font.size());
62
63 cmd_buff[0] = 0x00440082;
64 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
65 cmd_buff[2] = SHARED_FONT_VADDR;
66 cmd_buff[4] = Kernel::g_handle_table.Create(shared_font_mem).MoveFrom();
67 } else {
68 cmd_buff[1] = -1; // Generic error (not really possible to verify this on hardware)
69 LOG_ERROR(Kernel_SVC, "called, but %s has not been loaded!", SHARED_FONT);
70 }
71}
72
73void NotifyToWait(Service::Interface* self) {
74 u32* cmd_buff = Kernel::GetCommandBuffer();
75 u32 app_id = cmd_buff[1];
76 // TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further.
77 pause_event->Signal();
78
79 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
80 LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id);
81}
82
83void GetLockHandle(Service::Interface* self) {
84 u32* cmd_buff = Kernel::GetCommandBuffer();
85 u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
86
87 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
88
89 // Not sure what these parameters are used for, but retail apps check that they are 0 after
90 // GetLockHandle has been called.
91 cmd_buff[2] = 0;
92 cmd_buff[3] = 0;
93 cmd_buff[4] = 0;
94
95 cmd_buff[5] = Kernel::g_handle_table.Create(lock).MoveFrom();
96 LOG_TRACE(Service_APT, "called handle=0x%08X", cmd_buff[5]);
97}
98
99void Enable(Service::Interface* self) {
100 u32* cmd_buff = Kernel::GetCommandBuffer();
101 u32 unk = cmd_buff[1]; // TODO(bunnei): What is this field used for?
102 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
103 LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
104}
105
106void GetAppletManInfo(Service::Interface* self) {
107 u32* cmd_buff = Kernel::GetCommandBuffer();
108 u32 unk = cmd_buff[1];
109 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
110 cmd_buff[2] = 0;
111 cmd_buff[3] = 0;
112 cmd_buff[4] = static_cast<u32>(AppID::HomeMenu); // Home menu AppID
113 cmd_buff[5] = static_cast<u32>(AppID::Application); // TODO(purpasmart96): Do this correctly
114
115 LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
116}
117
118void IsRegistered(Service::Interface* self) {
119 u32* cmd_buff = Kernel::GetCommandBuffer();
120 u32 app_id = cmd_buff[1];
121 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
122 cmd_buff[2] = 1; // Set to registered
123 LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
124}
125
126void InquireNotification(Service::Interface* self) {
127 u32* cmd_buff = Kernel::GetCommandBuffer();
128 u32 app_id = cmd_buff[1];
129 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
130 cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type
131 LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
132}
133
134void SendParameter(Service::Interface* self) {
135 u32* cmd_buff = Kernel::GetCommandBuffer();
136 u32 src_app_id = cmd_buff[1];
137 u32 dst_app_id = cmd_buff[2];
138 u32 signal_type = cmd_buff[3];
139 u32 buffer_size = cmd_buff[4];
140 u32 value = cmd_buff[5];
141 u32 handle = cmd_buff[6];
142 u32 size = cmd_buff[7];
143 u32 in_param_buffer_ptr = cmd_buff[8];
144
145 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
146
147 LOG_WARNING(Service_APT, "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
148 "buffer_size=0x%08X, value=0x%08X, handle=0x%08X, size=0x%08X, in_param_buffer_ptr=0x%08X",
149 src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, in_param_buffer_ptr);
150}
151
152void ReceiveParameter(Service::Interface* self) {
153 u32* cmd_buff = Kernel::GetCommandBuffer();
154 u32 app_id = cmd_buff[1];
155 u32 buffer_size = cmd_buff[2];
156 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
157 cmd_buff[2] = 0;
158 cmd_buff[3] = static_cast<u32>(SignalType::AppJustStarted); // Signal type
159 cmd_buff[4] = 0x10; // Parameter buffer size (16)
160 cmd_buff[5] = 0;
161 cmd_buff[6] = 0;
162 cmd_buff[7] = 0;
163 LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
164}
165
166void GlanceParameter(Service::Interface* self) {
167 u32* cmd_buff = Kernel::GetCommandBuffer();
168 u32 app_id = cmd_buff[1];
169 u32 buffer_size = cmd_buff[2];
170
171 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
172 cmd_buff[2] = 0;
173 cmd_buff[3] = static_cast<u32>(SignalType::AppJustStarted); // Signal type
174 cmd_buff[4] = 0x10; // Parameter buffer size (16)
175 cmd_buff[5] = 0;
176 cmd_buff[6] = 0;
177 cmd_buff[7] = 0;
178
179 LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
180}
181
182void CancelParameter(Service::Interface* self) {
183 u32* cmd_buff = Kernel::GetCommandBuffer();
184 u32 flag1 = cmd_buff[1];
185 u32 unk = cmd_buff[2];
186 u32 flag2 = cmd_buff[3];
187 u32 app_id = cmd_buff[4];
188
189 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
190 cmd_buff[2] = 1; // Set to Success
191
192 LOG_WARNING(Service_APT, "(STUBBED) called flag1=0x%08X, unk=0x%08X, flag2=0x%08X, app_id=0x%08X",
193 flag1, unk, flag2, app_id);
194}
195
196void AppletUtility(Service::Interface* self) {
197 u32* cmd_buff = Kernel::GetCommandBuffer();
198
199 // These are from 3dbrew - I'm not really sure what they're used for.
200 u32 unk = cmd_buff[1];
201 u32 buffer1_size = cmd_buff[2];
202 u32 buffer2_size = cmd_buff[3];
203 u32 buffer1_addr = cmd_buff[5];
204 u32 buffer2_addr = cmd_buff[65];
205
206 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
207
208 LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X, buffer1_size=0x%08x, buffer2_size=0x%08x, "
209 "buffer1_addr=0x%08x, buffer2_addr=0x%08x", unk, buffer1_size, buffer2_size,
210 buffer1_addr, buffer2_addr);
211}
212
213void SetAppCpuTimeLimit(Service::Interface* self) {
214 u32* cmd_buff = Kernel::GetCommandBuffer();
215 u32 value = cmd_buff[1];
216 u32 percent = cmd_buff[2];
217
218 if (value != 1) {
219 LOG_ERROR(Service_APT, "This value should be one, but is actually %u!", value);
220 }
221
222 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
223
224 LOG_WARNING(Service_APT, "(STUBBED) called percent=0x%08X, value=0x%08x", percent, value);
225}
226
227void GetAppCpuTimeLimit(Service::Interface* self) {
228 u32* cmd_buff = Kernel::GetCommandBuffer();
229 u32 value = cmd_buff[1];
230
231 if (value != 1) {
232 LOG_ERROR(Service_APT, "This value should be one, but is actually %u!", value);
233 }
234
235 // TODO(purpasmart96): This is incorrect, I'm pretty sure the percentage should
236 // be set by the application.
237
238 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
239 cmd_buff[2] = 0x80; // Set to 80%
240
241 LOG_WARNING(Service_APT, "(STUBBED) called value=0x%08x", value);
242}
243
244void APTInit() {
245 AddService(new APT_A_Interface);
246 AddService(new APT_S_Interface);
247 AddService(new APT_U_Interface);
248
249 // Load the shared system font (if available).
250 // The expected format is a decrypted, uncompressed BCFNT file with the 0x80 byte header
251 // generated by the APT:U service. The best way to get is by dumping it from RAM. We've provided
252 // a homebrew app to do this: https://github.com/citra-emu/3dsutils. Put the resulting file
253 // "shared_font.bin" in the Citra "sysdata" directory.
254
255 shared_font.clear();
256 std::string filepath = FileUtil::GetUserPath(D_SYSDATA_IDX) + SHARED_FONT;
257
258 FileUtil::CreateFullPath(filepath); // Create path if not already created
259 FileUtil::IOFile file(filepath, "rb");
260
261 if (file.IsOpen()) {
262 // Read shared font data
263 shared_font.resize((size_t)file.GetSize());
264 file.ReadBytes(shared_font.data(), (size_t)file.GetSize());
265
266 // Create shared font memory object
267 shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem");
268 } else {
269 LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str());
270 shared_font_mem = nullptr;
271 }
272
273 lock = Kernel::Mutex::Create(false, "APT_U:Lock");
274
275 // TODO(bunnei): Check if these are created in Initialize or on APT process startup.
276 notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification");
277 pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause");
278}
279
280void APTShutdown() {
281
282}
283
284} // namespace APT
285} // namespace Service
diff --git a/src/core/hle/service/apt/apt.h b/src/core/hle/service/apt/apt.h
new file mode 100644
index 000000000..a39adbff9
--- /dev/null
+++ b/src/core/hle/service/apt/apt.h
@@ -0,0 +1,222 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include "core/hle/result.h"
9#include "core/hle/service/service.h"
10
11namespace Service {
12namespace APT {
13
14/// Signals used by APT functions
15enum class SignalType : u32 {
16 None = 0x0,
17 AppJustStarted = 0x1,
18 ReturningToApp = 0xB,
19 ExitingApp = 0xC,
20};
21
22/// App Id's used by APT functions
23enum class AppID : u32 {
24 HomeMenu = 0x101,
25 AlternateMenu = 0x103,
26 Camera = 0x110,
27 FriendsList = 0x112,
28 GameNotes = 0x113,
29 InternetBrowser = 0x114,
30 InstructionManual = 0x115,
31 Notifications = 0x116,
32 Miiverse = 0x117,
33 SoftwareKeyboard1 = 0x201,
34 Ed = 0x202,
35 PnoteApp = 0x204,
36 SnoteApp = 0x205,
37 Error = 0x206,
38 Mint = 0x207,
39 Extrapad = 0x208,
40 Memolib = 0x209,
41 Application = 0x300,
42 SoftwareKeyboard2 = 0x401,
43};
44
45/**
46 * APT::Initialize service function
47 * Service function that initializes the APT process for the running application
48 * Outputs:
49 * 1 : Result of the function, 0 on success, otherwise error code
50 * 3 : Handle to the notification event
51 * 4 : Handle to the pause event
52 */
53void Initialize(Service::Interface* self);
54
55/**
56 * APT::GetSharedFont service function
57 * Outputs:
58 * 1 : Result of function, 0 on success, otherwise error code
59 * 2 : Virtual address of where shared font will be loaded in memory
60 * 4 : Handle to shared font memory
61 */
62void GetSharedFont(Service::Interface* self);
63
64/**
65 * APT::NotifyToWait service function
66 * Inputs:
67 * 1 : AppID
68 * Outputs:
69 * 1 : Result of function, 0 on success, otherwise error code
70 */
71void NotifyToWait(Service::Interface* self);
72
73void GetLockHandle(Service::Interface* self);
74
75void Enable(Service::Interface* self);
76
77/**
78 * APT::GetAppletManInfo service function.
79 * Inputs:
80 * 1 : Unknown
81 * Outputs:
82 * 1 : Result of function, 0 on success, otherwise error code
83 * 2 : Unknown u32 value
84 * 3 : Unknown u8 value
85 * 4 : Home Menu AppId
86 * 5 : AppID of currently active app
87 */
88void GetAppletManInfo(Service::Interface* self);
89
90/**
91 * APT::IsRegistered service function. This returns whether the specified AppID is registered with NS yet.
92 * An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home Menu uses this
93 * command to determine when the launched process is running and to determine when to stop using GSP etc,
94 * while displaying the "Nintendo 3DS" loading screen.
95 * Inputs:
96 * 1 : AppID
97 * Outputs:
98 * 0 : Return header
99 * 1 : Result of function, 0 on success, otherwise error code
100 * 2 : Output, 0 = not registered, 1 = registered.
101 */
102void IsRegistered(Service::Interface* self);
103
104void InquireNotification(Service::Interface* self);
105
106/**
107 * APT::SendParameter service function. This sets the parameter data state.
108 * Inputs:
109 * 1 : Source AppID
110 * 2 : Destination AppID
111 * 3 : Signal type
112 * 4 : Parameter buffer size, max size is 0x1000 (this can be zero)
113 * 5 : Value
114 * 6 : Handle to the destination process, likely used for shared memory (this can be zero)
115 * 7 : (Size<<14) | 2
116 * 8 : Input parameter buffer ptr
117 * Outputs:
118 * 0 : Return Header
119 * 1 : Result of function, 0 on success, otherwise error code
120*/
121void SendParameter(Service::Interface* self);
122
123/**
124 * APT::ReceiveParameter service function. This returns the current parameter data from NS state,
125 * from the source process which set the parameters. Once finished, NS will clear a flag in the NS
126 * state so that this command will return an error if this command is used again if parameters were
127 * not set again. This is called when the second Initialize event is triggered. It returns a signal
128 * type indicating why it was triggered.
129 * Inputs:
130 * 1 : AppID
131 * 2 : Parameter buffer size, max size is 0x1000
132 * Outputs:
133 * 1 : Result of function, 0 on success, otherwise error code
134 * 2 : AppID of the process which sent these parameters
135 * 3 : Signal type
136 * 4 : Actual parameter buffer size, this is <= to the the input size
137 * 5 : Value
138 * 6 : Handle from the source process which set the parameters, likely used for shared memory
139 * 7 : Size
140 * 8 : Output parameter buffer ptr
141 */
142void ReceiveParameter(Service::Interface* self);
143
144/**
145 * APT::GlanceParameter service function. This is exactly the same as APT_U::ReceiveParameter
146 * (except for the word value prior to the output handle), except this will not clear the flag
147 * (except when responseword[3]==8 || responseword[3]==9) in NS state.
148 * Inputs:
149 * 1 : AppID
150 * 2 : Parameter buffer size, max size is 0x1000
151 * Outputs:
152 * 1 : Result of function, 0 on success, otherwise error code
153 * 2 : Unknown, for now assume AppID of the process which sent these parameters
154 * 3 : Unknown, for now assume Signal type
155 * 4 : Actual parameter buffer size, this is <= to the the input size
156 * 5 : Value
157 * 6 : Handle from the source process which set the parameters, likely used for shared memory
158 * 7 : Size
159 * 8 : Output parameter buffer ptr
160 */
161void GlanceParameter(Service::Interface* self);
162
163/**
164 * APT::CancelParameter service function. When the parameter data is available, and when the above
165 * specified fields match the ones in NS state(for the ones where the checks are enabled), this
166 * clears the flag which indicates that parameter data is available
167 * (same flag cleared by APT:ReceiveParameter).
168 * Inputs:
169 * 1 : Flag, when non-zero NS will compare the word after this one with a field in the NS state.
170 * 2 : Unknown, this is the same as the first unknown field returned by APT:ReceiveParameter.
171 * 3 : Flag, when non-zero NS will compare the word after this one with a field in the NS state.
172 * 4 : AppID
173 * Outputs:
174 * 0 : Return header
175 * 1 : Result of function, 0 on success, otherwise error code
176 * 2 : Status flag, 0 = failure due to no parameter data being available, or the above enabled
177 * fields don't match the fields in NS state. 1 = success.
178 */
179void CancelParameter(Service::Interface* self);
180
181/**
182 * APT::AppletUtility service function
183 * Inputs:
184 * 1 : Unknown, but clearly used for something
185 * 2 : Buffer 1 size (purpose is unknown)
186 * 3 : Buffer 2 size (purpose is unknown)
187 * 5 : Buffer 1 address (purpose is unknown)
188 * 65 : Buffer 2 address (purpose is unknown)
189 * Outputs:
190 * 1 : Result of function, 0 on success, otherwise error code
191 */
192void AppletUtility(Service::Interface* self);
193
194/**
195 * APT::SetAppCpuTimeLimit service function
196 * Inputs:
197 * 1 : Value, must be one
198 * 2 : Percentage of CPU time from 5 to 80
199 * Outputs:
200 * 1 : Result of function, 0 on success, otherwise error code
201 */
202void SetAppCpuTimeLimit(Service::Interface* self);
203
204/**
205 * APT::GetAppCpuTimeLimit service function
206 * Inputs:
207 * 1 : Value, must be one
208 * Outputs:
209 * 0 : Return header
210 * 1 : Result of function, 0 on success, otherwise error code
211 * 2 : System core CPU time percentage
212 */
213void GetAppCpuTimeLimit(Service::Interface* self);
214
215/// Initialize the APT service
216void APTInit();
217
218/// Shutdown the APT service
219void APTShutdown();
220
221} // namespace APT
222} // namespace Service
diff --git a/src/core/hle/service/apt/apt_a.cpp b/src/core/hle/service/apt/apt_a.cpp
new file mode 100644
index 000000000..dbe5c1d87
--- /dev/null
+++ b/src/core/hle/service/apt/apt_a.cpp
@@ -0,0 +1,33 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/apt/apt.h"
7#include "core/hle/service/apt/apt_a.h"
8
9namespace Service {
10namespace APT {
11
12const Interface::FunctionInfo FunctionTable[] = {
13 {0x00010040, GetLockHandle, "GetLockHandle?"},
14 {0x00020080, Initialize, "Initialize?"},
15 {0x00030040, nullptr, "Enable?"},
16 {0x00040040, nullptr, "Finalize?"},
17 {0x00050040, nullptr, "GetAppletManInfo?"},
18 {0x00060040, nullptr, "GetAppletInfo?"},
19 {0x000D0080, ReceiveParameter, "ReceiveParameter?"},
20 {0x000E0080, GlanceParameter, "GlanceParameter?"},
21 {0x003B0040, nullptr, "CancelLibraryApplet?"},
22 {0x00430040, nullptr, "NotifyToWait?"},
23 {0x00440000, GetSharedFont, "GetSharedFont?"},
24 {0x004B00C2, nullptr, "AppletUtility?"},
25 {0x00550040, nullptr, "WriteInputToNsState?"},
26};
27
28APT_A_Interface::APT_A_Interface() {
29 Register(FunctionTable);
30}
31
32} // namespace APT
33} // namespace Service
diff --git a/src/core/hle/service/apt_a.h b/src/core/hle/service/apt/apt_a.h
index 6cbf1288f..331fb5586 100644
--- a/src/core/hle/service/apt_a.h
+++ b/src/core/hle/service/apt/apt_a.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace APT_A 10namespace APT {
11 11
12namespace APT_A { 12class APT_A_Interface : public Service::Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 APT_A_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "APT:A"; 17 return "APT:A";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace APT
22} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/apt/apt_s.cpp b/src/core/hle/service/apt/apt_s.cpp
new file mode 100644
index 000000000..3fd348651
--- /dev/null
+++ b/src/core/hle/service/apt/apt_s.cpp
@@ -0,0 +1,104 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5
6#include "common/common.h"
7#include "common/file_util.h"
8
9#include "core/hle/hle.h"
10#include "core/hle/service/apt/apt.h"
11#include "core/hle/service/apt/apt_s.h"
12
13namespace Service {
14namespace APT {
15
16const Interface::FunctionInfo FunctionTable[] = {
17 {0x00010040, GetLockHandle, "GetLockHandle"},
18 {0x00020080, Initialize, "Initialize"},
19 {0x00030040, Enable, "Enable"},
20 {0x00040040, nullptr, "Finalize"},
21 {0x00050040, nullptr, "GetAppletManInfo"},
22 {0x00060040, nullptr, "GetAppletInfo"},
23 {0x00070000, nullptr, "GetLastSignaledAppletId"},
24 {0x00080000, nullptr, "CountRegisteredApplet"},
25 {0x00090040, nullptr, "IsRegistered"},
26 {0x000A0040, nullptr, "GetAttribute"},
27 {0x000B0040, InquireNotification, "InquireNotification"},
28 {0x000C0104, nullptr, "SendParameter"},
29 {0x000D0080, ReceiveParameter, "ReceiveParameter"},
30 {0x000E0080, GlanceParameter, "GlanceParameter"},
31 {0x000F0100, nullptr, "CancelParameter"},
32 {0x001000C2, nullptr, "DebugFunc"},
33 {0x001100C0, nullptr, "MapProgramIdForDebug"},
34 {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"},
35 {0x00130000, nullptr, "GetPreparationState"},
36 {0x00140040, nullptr, "SetPreparationState"},
37 {0x00150140, nullptr, "PrepareToStartApplication"},
38 {0x00160040, nullptr, "PreloadLibraryApplet"},
39 {0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
40 {0x00180040, nullptr, "PrepareToStartLibraryApplet"},
41 {0x00190040, nullptr, "PrepareToStartSystemApplet"},
42 {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"},
43 {0x001B00C4, nullptr, "StartApplication"},
44 {0x001C0000, nullptr, "WakeupApplication"},
45 {0x001D0000, nullptr, "CancelApplication"},
46 {0x001E0084, nullptr, "StartLibraryApplet"},
47 {0x001F0084, nullptr, "StartSystemApplet"},
48 {0x00200044, nullptr, "StartNewestHomeMenu"},
49 {0x00210000, nullptr, "OrderToCloseApplication"},
50 {0x00220040, nullptr, "PrepareToCloseApplication"},
51 {0x00230040, nullptr, "PrepareToJumpToApplication"},
52 {0x00240044, nullptr, "JumpToApplication"},
53 {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
54 {0x00260000, nullptr, "PrepareToCloseSystemApplet"},
55 {0x00270044, nullptr, "CloseApplication"},
56 {0x00280044, nullptr, "CloseLibraryApplet"},
57 {0x00290044, nullptr, "CloseSystemApplet"},
58 {0x002A0000, nullptr, "OrderToCloseSystemApplet"},
59 {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},
60 {0x002C0044, nullptr, "JumpToHomeMenu"},
61 {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"},
62 {0x002E0044, nullptr, "LeaveHomeMenu"},
63 {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"},
64 {0x00300044, nullptr, "LeaveResidentApplet"},
65 {0x00310100, nullptr, "PrepareToDoApplicationJump"},
66 {0x00320084, nullptr, "DoApplicationJump"},
67 {0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
68 {0x00340084, nullptr, "SendDeliverArg"},
69 {0x00350080, nullptr, "ReceiveDeliverArg"},
70 {0x00360040, nullptr, "LoadSysMenuArg"},
71 {0x00370042, nullptr, "StoreSysMenuArg"},
72 {0x00380040, nullptr, "PreloadResidentApplet"},
73 {0x00390040, nullptr, "PrepareToStartResidentApplet"},
74 {0x003A0044, nullptr, "StartResidentApplet"},
75 {0x003B0040, nullptr, "CancelLibraryApplet"},
76 {0x003C0042, nullptr, "SendDspSleep"},
77 {0x003D0042, nullptr, "SendDspWakeUp"},
78 {0x003E0080, nullptr, "ReplySleepQuery"},
79 {0x003F0040, nullptr, "ReplySleepNotificationComplete"},
80 {0x00400042, nullptr, "SendCaptureBufferInfo"},
81 {0x00410040, nullptr, "ReceiveCaptureBufferInfo"},
82 {0x00420080, nullptr, "SleepSystem"},
83 {0x00430040, NotifyToWait, "NotifyToWait"},
84 {0x00440000, GetSharedFont, "GetSharedFont"},
85 {0x00450040, nullptr, "GetWirelessRebootInfo"},
86 {0x00460104, nullptr, "Wrap"},
87 {0x00470104, nullptr, "Unwrap"},
88 {0x00480100, nullptr, "GetProgramInfo"},
89 {0x00490180, nullptr, "Reboot"},
90 {0x004A0040, nullptr, "GetCaptureInfo"},
91 {0x004B00C2, AppletUtility, "AppletUtility"},
92 {0x004C0000, nullptr, "SetFatalErrDispMode"},
93 {0x004D0080, nullptr, "GetAppletProgramInfo"},
94 {0x004E0000, nullptr, "HardwareResetAsync"},
95 {0x004F0080, nullptr, "SetApplicationCpuTimeLimit"},
96 {0x00500040, nullptr, "GetApplicationCpuTimeLimit"},
97};
98
99APT_S_Interface::APT_S_Interface() {
100 Register(FunctionTable);
101}
102
103} // namespace APT
104} // namespace Service
diff --git a/src/core/hle/service/apt_s.h b/src/core/hle/service/apt/apt_s.h
index f097c9747..8e87b69af 100644
--- a/src/core/hle/service/apt_s.h
+++ b/src/core/hle/service/apt/apt_s.h
@@ -6,10 +6,8 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace APT_S 10namespace APT {
11
12namespace APT_S {
13 11
14// Application and title launching service. These services handle signaling for home/power button as 12// Application and title launching service. These services handle signaling for home/power button as
15// well. Only one session for either APT service can be open at a time, normally processes close the 13// well. Only one session for either APT service can be open at a time, normally processes close the
@@ -18,13 +16,14 @@ namespace APT_S {
18// svcBreak when the command isn't accessible). See http://3dbrew.org/wiki/NS#APT_Services. 16// svcBreak when the command isn't accessible). See http://3dbrew.org/wiki/NS#APT_Services.
19 17
20/// Interface to "APT:S" service 18/// Interface to "APT:S" service
21class Interface : public Service::Interface { 19class APT_S_Interface : public Service::Interface {
22public: 20public:
23 Interface(); 21 APT_S_Interface();
24 22
25 std::string GetPortName() const override { 23 std::string GetPortName() const override {
26 return "APT:S"; 24 return "APT:S";
27 } 25 }
28}; 26};
29 27
30} // namespace 28} // namespace APT
29} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/apt/apt_u.cpp b/src/core/hle/service/apt/apt_u.cpp
new file mode 100644
index 000000000..5ab23801e
--- /dev/null
+++ b/src/core/hle/service/apt/apt_u.cpp
@@ -0,0 +1,103 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5
6#include "common/common.h"
7#include "common/file_util.h"
8
9#include "core/hle/service/apt/apt.h"
10#include "core/hle/service/apt/apt_u.h"
11
12namespace Service {
13namespace APT {
14
15const Interface::FunctionInfo FunctionTable[] = {
16 {0x00010040, GetLockHandle, "GetLockHandle"},
17 {0x00020080, Initialize, "Initialize"},
18 {0x00030040, Enable, "Enable"},
19 {0x00040040, nullptr, "Finalize"},
20 {0x00050040, GetAppletManInfo, "GetAppletManInfo"},
21 {0x00060040, nullptr, "GetAppletInfo"},
22 {0x00070000, nullptr, "GetLastSignaledAppletId"},
23 {0x00080000, nullptr, "CountRegisteredApplet"},
24 {0x00090040, IsRegistered, "IsRegistered"},
25 {0x000A0040, nullptr, "GetAttribute"},
26 {0x000B0040, InquireNotification, "InquireNotification"},
27 {0x000C0104, SendParameter, "SendParameter"},
28 {0x000D0080, ReceiveParameter, "ReceiveParameter"},
29 {0x000E0080, GlanceParameter, "GlanceParameter"},
30 {0x000F0100, CancelParameter, "CancelParameter"},
31 {0x001000C2, nullptr, "DebugFunc"},
32 {0x001100C0, nullptr, "MapProgramIdForDebug"},
33 {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"},
34 {0x00130000, nullptr, "GetPreparationState"},
35 {0x00140040, nullptr, "SetPreparationState"},
36 {0x00150140, nullptr, "PrepareToStartApplication"},
37 {0x00160040, nullptr, "PreloadLibraryApplet"},
38 {0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
39 {0x00180040, nullptr, "PrepareToStartLibraryApplet"},
40 {0x00190040, nullptr, "PrepareToStartSystemApplet"},
41 {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"},
42 {0x001B00C4, nullptr, "StartApplication"},
43 {0x001C0000, nullptr, "WakeupApplication"},
44 {0x001D0000, nullptr, "CancelApplication"},
45 {0x001E0084, nullptr, "StartLibraryApplet"},
46 {0x001F0084, nullptr, "StartSystemApplet"},
47 {0x00200044, nullptr, "StartNewestHomeMenu"},
48 {0x00210000, nullptr, "OrderToCloseApplication"},
49 {0x00220040, nullptr, "PrepareToCloseApplication"},
50 {0x00230040, nullptr, "PrepareToJumpToApplication"},
51 {0x00240044, nullptr, "JumpToApplication"},
52 {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
53 {0x00260000, nullptr, "PrepareToCloseSystemApplet"},
54 {0x00270044, nullptr, "CloseApplication"},
55 {0x00280044, nullptr, "CloseLibraryApplet"},
56 {0x00290044, nullptr, "CloseSystemApplet"},
57 {0x002A0000, nullptr, "OrderToCloseSystemApplet"},
58 {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},
59 {0x002C0044, nullptr, "JumpToHomeMenu"},
60 {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"},
61 {0x002E0044, nullptr, "LeaveHomeMenu"},
62 {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"},
63 {0x00300044, nullptr, "LeaveResidentApplet"},
64 {0x00310100, nullptr, "PrepareToDoApplicationJump"},
65 {0x00320084, nullptr, "DoApplicationJump"},
66 {0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
67 {0x00340084, nullptr, "SendDeliverArg"},
68 {0x00350080, nullptr, "ReceiveDeliverArg"},
69 {0x00360040, nullptr, "LoadSysMenuArg"},
70 {0x00370042, nullptr, "StoreSysMenuArg"},
71 {0x00380040, nullptr, "PreloadResidentApplet"},
72 {0x00390040, nullptr, "PrepareToStartResidentApplet"},
73 {0x003A0044, nullptr, "StartResidentApplet"},
74 {0x003B0040, nullptr, "CancelLibraryApplet"},
75 {0x003C0042, nullptr, "SendDspSleep"},
76 {0x003D0042, nullptr, "SendDspWakeUp"},
77 {0x003E0080, nullptr, "ReplySleepQuery"},
78 {0x003F0040, nullptr, "ReplySleepNotificationComplete"},
79 {0x00400042, nullptr, "SendCaptureBufferInfo"},
80 {0x00410040, nullptr, "ReceiveCaptureBufferInfo"},
81 {0x00420080, nullptr, "SleepSystem"},
82 {0x00430040, NotifyToWait, "NotifyToWait"},
83 {0x00440000, GetSharedFont, "GetSharedFont"},
84 {0x00450040, nullptr, "GetWirelessRebootInfo"},
85 {0x00460104, nullptr, "Wrap"},
86 {0x00470104, nullptr, "Unwrap"},
87 {0x00480100, nullptr, "GetProgramInfo"},
88 {0x00490180, nullptr, "Reboot"},
89 {0x004A0040, nullptr, "GetCaptureInfo"},
90 {0x004B00C2, AppletUtility, "AppletUtility"},
91 {0x004C0000, nullptr, "SetFatalErrDispMode"},
92 {0x004D0080, nullptr, "GetAppletProgramInfo"},
93 {0x004E0000, nullptr, "HardwareResetAsync"},
94 {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
95 {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},
96};
97
98APT_U_Interface::APT_U_Interface() {
99 Register(FunctionTable);
100}
101
102} // namespace APT
103} // namespace Service
diff --git a/src/core/hle/service/apt_u.h b/src/core/hle/service/apt/apt_u.h
index aad918cfc..8c7fe0ccb 100644
--- a/src/core/hle/service/apt_u.h
+++ b/src/core/hle/service/apt/apt_u.h
@@ -6,10 +6,8 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace APT_U 10namespace APT {
11
12namespace APT_U {
13 11
14// Application and title launching service. These services handle signaling for home/power button as 12// Application and title launching service. These services handle signaling for home/power button as
15// well. Only one session for either APT service can be open at a time, normally processes close the 13// well. Only one session for either APT service can be open at a time, normally processes close the
@@ -18,13 +16,14 @@ namespace APT_U {
18// svcBreak when the command isn't accessible). See http://3dbrew.org/wiki/NS#APT_Services. 16// svcBreak when the command isn't accessible). See http://3dbrew.org/wiki/NS#APT_Services.
19 17
20/// Interface to "APT:U" service 18/// Interface to "APT:U" service
21class Interface : public Service::Interface { 19class APT_U_Interface : public Service::Interface {
22public: 20public:
23 Interface(); 21 APT_U_Interface();
24 22
25 std::string GetPortName() const override { 23 std::string GetPortName() const override {
26 return "APT:U"; 24 return "APT:U";
27 } 25 }
28}; 26};
29 27
30} // namespace 28} // namespace APT
29} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/apt_a.cpp b/src/core/hle/service/apt_a.cpp
deleted file mode 100644
index 1c1d92572..000000000
--- a/src/core/hle/service/apt_a.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/hle.h"
6#include "core/hle/service/apt_a.h"
7
8namespace APT_U {
9 extern void Initialize(Service::Interface* self);
10 extern void GetLockHandle(Service::Interface* self);
11 extern void ReceiveParameter(Service::Interface* self);
12 extern void GlanceParameter(Service::Interface* self);
13 extern void GetSharedFont(Service::Interface* self);
14}
15
16////////////////////////////////////////////////////////////////////////////////////////////////////
17// Namespace APT_A
18
19namespace APT_A {
20
21const Interface::FunctionInfo FunctionTable[] = {
22 {0x00010040, APT_U::GetLockHandle, "GetLockHandle?"},
23 {0x00020080, APT_U::Initialize, "Initialize?"},
24 {0x00030040, nullptr, "Enable?"},
25 {0x00040040, nullptr, "Finalize?"},
26 {0x00050040, nullptr, "GetAppletManInfo?"},
27 {0x00060040, nullptr, "GetAppletInfo?"},
28 {0x000D0080, APT_U::ReceiveParameter, "ReceiveParameter?"},
29 {0x000E0080, APT_U::GlanceParameter, "GlanceParameter?"},
30 {0x003B0040, nullptr, "CancelLibraryApplet?"},
31 {0x00430040, nullptr, "NotifyToWait?"},
32 {0x00440000, APT_U::GetSharedFont, "GetSharedFont?"},
33 {0x004B00C2, nullptr, "AppletUtility?"},
34 {0x00550040, nullptr, "WriteInputToNsState?"},
35};
36
37////////////////////////////////////////////////////////////////////////////////////////////////////
38// Interface class
39
40Interface::Interface() {
41 Register(FunctionTable);
42}
43
44} // namespace
diff --git a/src/core/hle/service/apt_s.cpp b/src/core/hle/service/apt_s.cpp
deleted file mode 100644
index 686335428..000000000
--- a/src/core/hle/service/apt_s.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5
6#include "common/common.h"
7#include "common/file_util.h"
8
9#include "core/hle/hle.h"
10#include "core/hle/kernel/event.h"
11#include "core/hle/kernel/mutex.h"
12#include "core/hle/kernel/shared_memory.h"
13#include "core/hle/kernel/thread.h"
14#include "core/hle/service/apt_s.h"
15
16////////////////////////////////////////////////////////////////////////////////////////////////////
17// Namespace APT_S
18
19namespace APT_U {
20 extern void GetLockHandle(Service::Interface* self);
21 extern void Initialize(Service::Interface* self);
22 extern void Enable(Service::Interface* self);
23 extern void InquireNotification(Service::Interface* self);
24 extern void NotifyToWait(Service::Interface* self);
25 extern void GetSharedFont(Service::Interface* self);
26 extern void AppletUtility(Service::Interface* self);
27 extern void GlanceParameter(Service::Interface* self);
28 extern void ReceiveParameter(Service::Interface* self);
29}
30
31namespace APT_S {
32
33const Interface::FunctionInfo FunctionTable[] = {
34 {0x00010040, APT_U::GetLockHandle, "GetLockHandle"},
35 {0x00020080, APT_U::Initialize, "Initialize"},
36 {0x00030040, APT_U::Enable, "Enable"},
37 {0x00040040, nullptr, "Finalize"},
38 {0x00050040, nullptr, "GetAppletManInfo"},
39 {0x00060040, nullptr, "GetAppletInfo"},
40 {0x00070000, nullptr, "GetLastSignaledAppletId"},
41 {0x00080000, nullptr, "CountRegisteredApplet"},
42 {0x00090040, nullptr, "IsRegistered"},
43 {0x000A0040, nullptr, "GetAttribute"},
44 {0x000B0040, APT_U::InquireNotification, "InquireNotification"},
45 {0x000C0104, nullptr, "SendParameter"},
46 {0x000D0080, APT_U::ReceiveParameter, "ReceiveParameter"},
47 {0x000E0080, APT_U::GlanceParameter, "GlanceParameter"},
48 {0x000F0100, nullptr, "CancelParameter"},
49 {0x001000C2, nullptr, "DebugFunc"},
50 {0x001100C0, nullptr, "MapProgramIdForDebug"},
51 {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"},
52 {0x00130000, nullptr, "GetPreparationState"},
53 {0x00140040, nullptr, "SetPreparationState"},
54 {0x00150140, nullptr, "PrepareToStartApplication"},
55 {0x00160040, nullptr, "PreloadLibraryApplet"},
56 {0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
57 {0x00180040, nullptr, "PrepareToStartLibraryApplet"},
58 {0x00190040, nullptr, "PrepareToStartSystemApplet"},
59 {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"},
60 {0x001B00C4, nullptr, "StartApplication"},
61 {0x001C0000, nullptr, "WakeupApplication"},
62 {0x001D0000, nullptr, "CancelApplication"},
63 {0x001E0084, nullptr, "StartLibraryApplet"},
64 {0x001F0084, nullptr, "StartSystemApplet"},
65 {0x00200044, nullptr, "StartNewestHomeMenu"},
66 {0x00210000, nullptr, "OrderToCloseApplication"},
67 {0x00220040, nullptr, "PrepareToCloseApplication"},
68 {0x00230040, nullptr, "PrepareToJumpToApplication"},
69 {0x00240044, nullptr, "JumpToApplication"},
70 {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
71 {0x00260000, nullptr, "PrepareToCloseSystemApplet"},
72 {0x00270044, nullptr, "CloseApplication"},
73 {0x00280044, nullptr, "CloseLibraryApplet"},
74 {0x00290044, nullptr, "CloseSystemApplet"},
75 {0x002A0000, nullptr, "OrderToCloseSystemApplet"},
76 {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},
77 {0x002C0044, nullptr, "JumpToHomeMenu"},
78 {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"},
79 {0x002E0044, nullptr, "LeaveHomeMenu"},
80 {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"},
81 {0x00300044, nullptr, "LeaveResidentApplet"},
82 {0x00310100, nullptr, "PrepareToDoApplicationJump"},
83 {0x00320084, nullptr, "DoApplicationJump"},
84 {0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
85 {0x00340084, nullptr, "SendDeliverArg"},
86 {0x00350080, nullptr, "ReceiveDeliverArg"},
87 {0x00360040, nullptr, "LoadSysMenuArg"},
88 {0x00370042, nullptr, "StoreSysMenuArg"},
89 {0x00380040, nullptr, "PreloadResidentApplet"},
90 {0x00390040, nullptr, "PrepareToStartResidentApplet"},
91 {0x003A0044, nullptr, "StartResidentApplet"},
92 {0x003B0040, nullptr, "CancelLibraryApplet"},
93 {0x003C0042, nullptr, "SendDspSleep"},
94 {0x003D0042, nullptr, "SendDspWakeUp"},
95 {0x003E0080, nullptr, "ReplySleepQuery"},
96 {0x003F0040, nullptr, "ReplySleepNotificationComplete"},
97 {0x00400042, nullptr, "SendCaptureBufferInfo"},
98 {0x00410040, nullptr, "ReceiveCaptureBufferInfo"},
99 {0x00420080, nullptr, "SleepSystem"},
100 {0x00430040, APT_U::NotifyToWait, "NotifyToWait"},
101 {0x00440000, APT_U::GetSharedFont, "GetSharedFont"},
102 {0x00450040, nullptr, "GetWirelessRebootInfo"},
103 {0x00460104, nullptr, "Wrap"},
104 {0x00470104, nullptr, "Unwrap"},
105 {0x00480100, nullptr, "GetProgramInfo"},
106 {0x00490180, nullptr, "Reboot"},
107 {0x004A0040, nullptr, "GetCaptureInfo"},
108 {0x004B00C2, APT_U::AppletUtility, "AppletUtility"},
109 {0x004C0000, nullptr, "SetFatalErrDispMode"},
110 {0x004D0080, nullptr, "GetAppletProgramInfo"},
111 {0x004E0000, nullptr, "HardwareResetAsync"},
112 {0x004F0080, nullptr, "SetApplicationCpuTimeLimit"},
113 {0x00500040, nullptr, "GetApplicationCpuTimeLimit"},
114};
115
116////////////////////////////////////////////////////////////////////////////////////////////////////
117// Interface class
118
119Interface::Interface() {
120 Register(FunctionTable);
121}
122
123} // namespace
diff --git a/src/core/hle/service/apt_u.cpp b/src/core/hle/service/apt_u.cpp
deleted file mode 100644
index 2d605a767..000000000
--- a/src/core/hle/service/apt_u.cpp
+++ /dev/null
@@ -1,526 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5
6#include "common/common.h"
7#include "common/file_util.h"
8
9#include "core/hle/hle.h"
10#include "core/hle/kernel/event.h"
11#include "core/hle/kernel/mutex.h"
12#include "core/hle/kernel/shared_memory.h"
13#include "core/hle/kernel/thread.h"
14#include "core/hle/service/apt_u.h"
15
16////////////////////////////////////////////////////////////////////////////////////////////////////
17// Namespace APT_U
18
19namespace APT_U {
20
21// Address used for shared font (as observed on HW)
22// TODO(bunnei): This is the hard-coded address where we currently dump the shared font from via
23// https://github.com/citra-emu/3dsutils. This is technically a hack, and will not work at any
24// address other than 0x18000000 due to internal pointers in the shared font dump that would need to
25// be relocated. This might be fixed by dumping the shared font @ address 0x00000000 and then
26// correctly mapping it in Citra, however we still do not understand how the mapping is determined.
27static const VAddr SHARED_FONT_VADDR = 0x18000000;
28
29/// Handle to shared memory region designated to for shared system font
30static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
31
32static Kernel::SharedPtr<Kernel::Mutex> lock;
33static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
34static Kernel::SharedPtr<Kernel::Event> pause_event = 0; ///< APT pause event
35static std::vector<u8> shared_font;
36
37/// Signals used by APT functions
38enum class SignalType : u32 {
39 None = 0x0,
40 AppJustStarted = 0x1,
41 ReturningToApp = 0xB,
42 ExitingApp = 0xC,
43};
44
45/// App Id's used by APT functions
46enum class AppID : u32 {
47 HomeMenu = 0x101,
48 AlternateMenu = 0x103,
49 Camera = 0x110,
50 FriendsList = 0x112,
51 GameNotes = 0x113,
52 InternetBrowser = 0x114,
53 InstructionManual = 0x115,
54 Notifications = 0x116,
55 Miiverse = 0x117,
56 SoftwareKeyboard1 = 0x201,
57 Ed = 0x202,
58 PnoteApp = 0x204,
59 SnoteApp = 0x205,
60 Error = 0x206,
61 Mint = 0x207,
62 Extrapad = 0x208,
63 Memolib = 0x209,
64 Application = 0x300,
65 SoftwareKeyboard2 = 0x401,
66};
67
68void Initialize(Service::Interface* self) {
69 u32* cmd_buff = Kernel::GetCommandBuffer();
70
71 // TODO(bunnei): Check if these are created in Initialize or on APT process startup.
72 notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification");
73 pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause");
74
75 cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom();
76 cmd_buff[4] = Kernel::g_handle_table.Create(pause_event).MoveFrom();
77
78 // TODO(bunnei): Check if these events are cleared/signaled every time Initialize is called.
79 notification_event->Clear();
80 pause_event->Signal(); // Fire start event
81
82 ASSERT_MSG((nullptr != lock), "Cannot initialize without lock");
83 lock->Release();
84
85 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
86}
87
88/**
89 * APT_U::NotifyToWait service function
90 * Inputs:
91 * 1 : AppID
92 * Outputs:
93 * 1 : Result of function, 0 on success, otherwise error code
94 */
95void NotifyToWait(Service::Interface* self) {
96 u32* cmd_buff = Kernel::GetCommandBuffer();
97 u32 app_id = cmd_buff[1];
98 // TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further.
99 pause_event->Signal();
100
101 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
102 LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id);
103}
104
105void GetLockHandle(Service::Interface* self) {
106 u32* cmd_buff = Kernel::GetCommandBuffer();
107 u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
108
109 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
110
111 // Not sure what these parameters are used for, but retail apps check that they are 0 after
112 // GetLockHandle has been called.
113 cmd_buff[2] = 0;
114 cmd_buff[3] = 0;
115 cmd_buff[4] = 0;
116
117 cmd_buff[5] = Kernel::g_handle_table.Create(lock).MoveFrom();
118 LOG_TRACE(Service_APT, "called handle=0x%08X", cmd_buff[5]);
119}
120
121void Enable(Service::Interface* self) {
122 u32* cmd_buff = Kernel::GetCommandBuffer();
123 u32 unk = cmd_buff[1]; // TODO(bunnei): What is this field used for?
124 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
125 LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
126}
127
128/**
129 * APT_U::GetAppletManInfo service function.
130 * Inputs:
131 * 1 : Unknown
132 * Outputs:
133 * 1 : Result of function, 0 on success, otherwise error code
134 * 2 : Unknown u32 value
135 * 3 : Unknown u8 value
136 * 4 : Home Menu AppId
137 * 5 : AppID of currently active app
138 */
139void GetAppletManInfo(Service::Interface* self) {
140 u32* cmd_buff = Kernel::GetCommandBuffer();
141 u32 unk = cmd_buff[1];
142 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
143 cmd_buff[2] = 0;
144 cmd_buff[3] = 0;
145 cmd_buff[4] = static_cast<u32>(AppID::HomeMenu); // Home menu AppID
146 cmd_buff[5] = static_cast<u32>(AppID::Application); // TODO(purpasmart96): Do this correctly
147
148 LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
149}
150
151/**
152 * APT_U::IsRegistered service function. This returns whether the specified AppID is registered with NS yet.
153 * An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home Menu uses this
154 * command to determine when the launched process is running and to determine when to stop using GSP etc,
155 * while displaying the "Nintendo 3DS" loading screen.
156 * Inputs:
157 * 1 : AppID
158 * Outputs:
159 * 0 : Return header
160 * 1 : Result of function, 0 on success, otherwise error code
161 * 2 : Output, 0 = not registered, 1 = registered.
162 */
163static void IsRegistered(Service::Interface* self) {
164 u32* cmd_buff = Kernel::GetCommandBuffer();
165 u32 app_id = cmd_buff[1];
166 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
167 cmd_buff[2] = 1; // Set to registered
168 LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
169}
170
171void InquireNotification(Service::Interface* self) {
172 u32* cmd_buff = Kernel::GetCommandBuffer();
173 u32 app_id = cmd_buff[1];
174 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
175 cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type
176 LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
177}
178
179/**
180 * APT_U::SendParameter service function. This sets the parameter data state.
181 * Inputs:
182 * 1 : Source AppID
183 * 2 : Destination AppID
184 * 3 : Signal type
185 * 4 : Parameter buffer size, max size is 0x1000 (this can be zero)
186 * 5 : Value
187 * 6 : Handle to the destination process, likely used for shared memory (this can be zero)
188 * 7 : (Size<<14) | 2
189 * 8 : Input parameter buffer ptr
190 * Outputs:
191 * 0 : Return Header
192 * 1 : Result of function, 0 on success, otherwise error code
193*/
194static void SendParameter(Service::Interface* self) {
195 u32* cmd_buff = Kernel::GetCommandBuffer();
196 u32 src_app_id = cmd_buff[1];
197 u32 dst_app_id = cmd_buff[2];
198 u32 signal_type = cmd_buff[3];
199 u32 buffer_size = cmd_buff[4];
200 u32 value = cmd_buff[5];
201 u32 handle = cmd_buff[6];
202 u32 size = cmd_buff[7];
203 u32 in_param_buffer_ptr = cmd_buff[8];
204
205 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
206
207 LOG_WARNING(Service_APT, "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
208 "buffer_size=0x%08X, value=0x%08X, handle=0x%08X, size=0x%08X, in_param_buffer_ptr=0x%08X",
209 src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, in_param_buffer_ptr);
210}
211
212/**
213 * APT_U::ReceiveParameter service function. This returns the current parameter data from NS state,
214 * from the source process which set the parameters. Once finished, NS will clear a flag in the NS
215 * state so that this command will return an error if this command is used again if parameters were
216 * not set again. This is called when the second Initialize event is triggered. It returns a signal
217 * type indicating why it was triggered.
218 * Inputs:
219 * 1 : AppID
220 * 2 : Parameter buffer size, max size is 0x1000
221 * Outputs:
222 * 1 : Result of function, 0 on success, otherwise error code
223 * 2 : AppID of the process which sent these parameters
224 * 3 : Signal type
225 * 4 : Actual parameter buffer size, this is <= to the the input size
226 * 5 : Value
227 * 6 : Handle from the source process which set the parameters, likely used for shared memory
228 * 7 : Size
229 * 8 : Output parameter buffer ptr
230 */
231void ReceiveParameter(Service::Interface* self) {
232 u32* cmd_buff = Kernel::GetCommandBuffer();
233 u32 app_id = cmd_buff[1];
234 u32 buffer_size = cmd_buff[2];
235 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
236 cmd_buff[2] = 0;
237 cmd_buff[3] = static_cast<u32>(SignalType::AppJustStarted); // Signal type
238 cmd_buff[4] = 0x10; // Parameter buffer size (16)
239 cmd_buff[5] = 0;
240 cmd_buff[6] = 0;
241 cmd_buff[7] = 0;
242 LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
243}
244
245/**
246 * APT_U::GlanceParameter service function. This is exactly the same as APT_U::ReceiveParameter
247 * (except for the word value prior to the output handle), except this will not clear the flag
248 * (except when responseword[3]==8 || responseword[3]==9) in NS state.
249 * Inputs:
250 * 1 : AppID
251 * 2 : Parameter buffer size, max size is 0x1000
252 * Outputs:
253 * 1 : Result of function, 0 on success, otherwise error code
254 * 2 : Unknown, for now assume AppID of the process which sent these parameters
255 * 3 : Unknown, for now assume Signal type
256 * 4 : Actual parameter buffer size, this is <= to the the input size
257 * 5 : Value
258 * 6 : Handle from the source process which set the parameters, likely used for shared memory
259 * 7 : Size
260 * 8 : Output parameter buffer ptr
261 */
262void GlanceParameter(Service::Interface* self) {
263 u32* cmd_buff = Kernel::GetCommandBuffer();
264 u32 app_id = cmd_buff[1];
265 u32 buffer_size = cmd_buff[2];
266
267 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
268 cmd_buff[2] = 0;
269 cmd_buff[3] = static_cast<u32>(SignalType::AppJustStarted); // Signal type
270 cmd_buff[4] = 0x10; // Parameter buffer size (16)
271 cmd_buff[5] = 0;
272 cmd_buff[6] = 0;
273 cmd_buff[7] = 0;
274
275 LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
276}
277
278/**
279 * APT_U::CancelParameter service function. When the parameter data is available, and when the above
280 * specified fields match the ones in NS state(for the ones where the checks are enabled), this
281 * clears the flag which indicates that parameter data is available
282 * (same flag cleared by APT:ReceiveParameter).
283 * Inputs:
284 * 1 : Flag, when non-zero NS will compare the word after this one with a field in the NS state.
285 * 2 : Unknown, this is the same as the first unknown field returned by APT:ReceiveParameter.
286 * 3 : Flag, when non-zero NS will compare the word after this one with a field in the NS state.
287 * 4 : AppID
288 * Outputs:
289 * 0 : Return header
290 * 1 : Result of function, 0 on success, otherwise error code
291 * 2 : Status flag, 0 = failure due to no parameter data being available, or the above enabled
292 * fields don't match the fields in NS state. 1 = success.
293 */
294static void CancelParameter(Service::Interface* self) {
295 u32* cmd_buff = Kernel::GetCommandBuffer();
296 u32 flag1 = cmd_buff[1];
297 u32 unk = cmd_buff[2];
298 u32 flag2 = cmd_buff[3];
299 u32 app_id = cmd_buff[4];
300
301 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
302 cmd_buff[2] = 1; // Set to Success
303
304 LOG_WARNING(Service_APT, "(STUBBED) called flag1=0x%08X, unk=0x%08X, flag2=0x%08X, app_id=0x%08X",
305 flag1, unk, flag2, app_id);
306}
307
308/**
309 * APT_U::AppletUtility service function
310 * Inputs:
311 * 1 : Unknown, but clearly used for something
312 * 2 : Buffer 1 size (purpose is unknown)
313 * 3 : Buffer 2 size (purpose is unknown)
314 * 5 : Buffer 1 address (purpose is unknown)
315 * 65 : Buffer 2 address (purpose is unknown)
316 * Outputs:
317 * 1 : Result of function, 0 on success, otherwise error code
318 */
319void AppletUtility(Service::Interface* self) {
320 u32* cmd_buff = Kernel::GetCommandBuffer();
321
322 // These are from 3dbrew - I'm not really sure what they're used for.
323 u32 unk = cmd_buff[1];
324 u32 buffer1_size = cmd_buff[2];
325 u32 buffer2_size = cmd_buff[3];
326 u32 buffer1_addr = cmd_buff[5];
327 u32 buffer2_addr = cmd_buff[65];
328
329 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
330
331 LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X, buffer1_size=0x%08x, buffer2_size=0x%08x, "
332 "buffer1_addr=0x%08x, buffer2_addr=0x%08x", unk, buffer1_size, buffer2_size,
333 buffer1_addr, buffer2_addr);
334}
335
336/**
337 * APT_U::GetSharedFont service function
338 * Outputs:
339 * 1 : Result of function, 0 on success, otherwise error code
340 * 2 : Virtual address of where shared font will be loaded in memory
341 * 4 : Handle to shared font memory
342 */
343void GetSharedFont(Service::Interface* self) {
344 u32* cmd_buff = Kernel::GetCommandBuffer();
345
346 if (!shared_font.empty()) {
347 // TODO(bunnei): This function shouldn't copy the shared font every time it's called.
348 // Instead, it should probably map the shared font as RO memory. We don't currently have
349 // an easy way to do this, but the copy should be sufficient for now.
350 memcpy(Memory::GetPointer(SHARED_FONT_VADDR), shared_font.data(), shared_font.size());
351
352 cmd_buff[0] = 0x00440082;
353 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
354 cmd_buff[2] = SHARED_FONT_VADDR;
355 cmd_buff[4] = Kernel::g_handle_table.Create(shared_font_mem).MoveFrom();
356 } else {
357 cmd_buff[1] = -1; // Generic error (not really possible to verify this on hardware)
358 LOG_ERROR(Kernel_SVC, "called, but %s has not been loaded!", SHARED_FONT);
359 }
360}
361
362/**
363 * APT_U::SetAppCpuTimeLimit service function
364 * Inputs:
365 * 1 : Value, must be one
366 * 2 : Percentage of CPU time from 5 to 80
367 * Outputs:
368 * 1 : Result of function, 0 on success, otherwise error code
369 */
370static void SetAppCpuTimeLimit(Service::Interface* self) {
371 u32* cmd_buff = Kernel::GetCommandBuffer();
372 u32 value = cmd_buff[1];
373 u32 percent = cmd_buff[2];
374
375 if (value != 1) {
376 LOG_ERROR(Service_APT, "This value should be one, but is actually %u!", value);
377 }
378
379 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
380
381 LOG_WARNING(Service_APT, "(STUBBED) called percent=0x%08X, value=0x%08x", percent, value);
382}
383
384/**
385 * APT_U::GetAppCpuTimeLimit service function
386 * Inputs:
387 * 1 : Value, must be one
388 * Outputs:
389 * 0 : Return header
390 * 1 : Result of function, 0 on success, otherwise error code
391 * 2 : System core CPU time percentage
392 */
393static void GetAppCpuTimeLimit(Service::Interface* self) {
394 u32* cmd_buff = Kernel::GetCommandBuffer();
395 u32 value = cmd_buff[1];
396
397 if (value != 1) {
398 LOG_ERROR(Service_APT, "This value should be one, but is actually %u!", value);
399 }
400
401 // TODO(purpasmart96): This is incorrect, I'm pretty sure the percentage should
402 // be set by the application.
403
404 cmd_buff[1] = RESULT_SUCCESS.raw; // No error
405 cmd_buff[2] = 0x80; // Set to 80%
406
407 LOG_WARNING(Service_APT, "(STUBBED) called value=0x%08x", value);
408}
409
410const Interface::FunctionInfo FunctionTable[] = {
411 {0x00010040, GetLockHandle, "GetLockHandle"},
412 {0x00020080, Initialize, "Initialize"},
413 {0x00030040, Enable, "Enable"},
414 {0x00040040, nullptr, "Finalize"},
415 {0x00050040, GetAppletManInfo, "GetAppletManInfo"},
416 {0x00060040, nullptr, "GetAppletInfo"},
417 {0x00070000, nullptr, "GetLastSignaledAppletId"},
418 {0x00080000, nullptr, "CountRegisteredApplet"},
419 {0x00090040, IsRegistered, "IsRegistered"},
420 {0x000A0040, nullptr, "GetAttribute"},
421 {0x000B0040, InquireNotification, "InquireNotification"},
422 {0x000C0104, SendParameter, "SendParameter"},
423 {0x000D0080, ReceiveParameter, "ReceiveParameter"},
424 {0x000E0080, GlanceParameter, "GlanceParameter"},
425 {0x000F0100, CancelParameter, "CancelParameter"},
426 {0x001000C2, nullptr, "DebugFunc"},
427 {0x001100C0, nullptr, "MapProgramIdForDebug"},
428 {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"},
429 {0x00130000, nullptr, "GetPreparationState"},
430 {0x00140040, nullptr, "SetPreparationState"},
431 {0x00150140, nullptr, "PrepareToStartApplication"},
432 {0x00160040, nullptr, "PreloadLibraryApplet"},
433 {0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
434 {0x00180040, nullptr, "PrepareToStartLibraryApplet"},
435 {0x00190040, nullptr, "PrepareToStartSystemApplet"},
436 {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"},
437 {0x001B00C4, nullptr, "StartApplication"},
438 {0x001C0000, nullptr, "WakeupApplication"},
439 {0x001D0000, nullptr, "CancelApplication"},
440 {0x001E0084, nullptr, "StartLibraryApplet"},
441 {0x001F0084, nullptr, "StartSystemApplet"},
442 {0x00200044, nullptr, "StartNewestHomeMenu"},
443 {0x00210000, nullptr, "OrderToCloseApplication"},
444 {0x00220040, nullptr, "PrepareToCloseApplication"},
445 {0x00230040, nullptr, "PrepareToJumpToApplication"},
446 {0x00240044, nullptr, "JumpToApplication"},
447 {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
448 {0x00260000, nullptr, "PrepareToCloseSystemApplet"},
449 {0x00270044, nullptr, "CloseApplication"},
450 {0x00280044, nullptr, "CloseLibraryApplet"},
451 {0x00290044, nullptr, "CloseSystemApplet"},
452 {0x002A0000, nullptr, "OrderToCloseSystemApplet"},
453 {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},
454 {0x002C0044, nullptr, "JumpToHomeMenu"},
455 {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"},
456 {0x002E0044, nullptr, "LeaveHomeMenu"},
457 {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"},
458 {0x00300044, nullptr, "LeaveResidentApplet"},
459 {0x00310100, nullptr, "PrepareToDoApplicationJump"},
460 {0x00320084, nullptr, "DoApplicationJump"},
461 {0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
462 {0x00340084, nullptr, "SendDeliverArg"},
463 {0x00350080, nullptr, "ReceiveDeliverArg"},
464 {0x00360040, nullptr, "LoadSysMenuArg"},
465 {0x00370042, nullptr, "StoreSysMenuArg"},
466 {0x00380040, nullptr, "PreloadResidentApplet"},
467 {0x00390040, nullptr, "PrepareToStartResidentApplet"},
468 {0x003A0044, nullptr, "StartResidentApplet"},
469 {0x003B0040, nullptr, "CancelLibraryApplet"},
470 {0x003C0042, nullptr, "SendDspSleep"},
471 {0x003D0042, nullptr, "SendDspWakeUp"},
472 {0x003E0080, nullptr, "ReplySleepQuery"},
473 {0x003F0040, nullptr, "ReplySleepNotificationComplete"},
474 {0x00400042, nullptr, "SendCaptureBufferInfo"},
475 {0x00410040, nullptr, "ReceiveCaptureBufferInfo"},
476 {0x00420080, nullptr, "SleepSystem"},
477 {0x00430040, NotifyToWait, "NotifyToWait"},
478 {0x00440000, GetSharedFont, "GetSharedFont"},
479 {0x00450040, nullptr, "GetWirelessRebootInfo"},
480 {0x00460104, nullptr, "Wrap"},
481 {0x00470104, nullptr, "Unwrap"},
482 {0x00480100, nullptr, "GetProgramInfo"},
483 {0x00490180, nullptr, "Reboot"},
484 {0x004A0040, nullptr, "GetCaptureInfo"},
485 {0x004B00C2, AppletUtility, "AppletUtility"},
486 {0x004C0000, nullptr, "SetFatalErrDispMode"},
487 {0x004D0080, nullptr, "GetAppletProgramInfo"},
488 {0x004E0000, nullptr, "HardwareResetAsync"},
489 {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
490 {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},
491};
492
493////////////////////////////////////////////////////////////////////////////////////////////////////
494// Interface class
495
496Interface::Interface() {
497 // Load the shared system font (if available).
498 // The expected format is a decrypted, uncompressed BCFNT file with the 0x80 byte header
499 // generated by the APT:U service. The best way to get is by dumping it from RAM. We've provided
500 // a homebrew app to do this: https://github.com/citra-emu/3dsutils. Put the resulting file
501 // "shared_font.bin" in the Citra "sysdata" directory.
502
503 shared_font.clear();
504 std::string filepath = FileUtil::GetUserPath(D_SYSDATA_IDX) + SHARED_FONT;
505
506 FileUtil::CreateFullPath(filepath); // Create path if not already created
507 FileUtil::IOFile file(filepath, "rb");
508
509 if (file.IsOpen()) {
510 // Read shared font data
511 shared_font.resize((size_t)file.GetSize());
512 file.ReadBytes(shared_font.data(), (size_t)file.GetSize());
513
514 // Create shared font memory object
515 shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem");
516 } else {
517 LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str());
518 shared_font_mem = nullptr;
519 }
520
521 lock = Kernel::Mutex::Create(false, "APT_U:Lock");
522
523 Register(FunctionTable);
524}
525
526} // namespace
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index b7cdccb86..1eb2562d8 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -3,9 +3,13 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include "common/make_unique.h" 6
7#include "core/hle/service/cfg/cfg.h"
8#include "core/hle/service/fs/archive.h" 7#include "core/hle/service/fs/archive.h"
8#include "core/hle/service/service.h"
9#include "core/hle/service/cfg/cfg.h"
10#include "core/hle/service/cfg/cfg_i.h"
11#include "core/hle/service/cfg/cfg_s.h"
12#include "core/hle/service/cfg/cfg_u.h"
9 13
10namespace Service { 14namespace Service {
11namespace CFG { 15namespace CFG {
@@ -162,6 +166,10 @@ ResultCode FormatConfig() {
162} 166}
163 167
164void CFGInit() { 168void CFGInit() {
169 AddService(new CFG_I_Interface);
170 AddService(new CFG_S_Interface);
171 AddService(new CFG_U_Interface);
172
165 // Open the SystemSaveData archive 0x00010017 173 // Open the SystemSaveData archive 0x00010017
166 FileSys::Path archive_path(cfg_system_savedata_id); 174 FileSys::Path archive_path(cfg_system_savedata_id);
167 auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path); 175 auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SystemSaveData, archive_path);
diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp
index 20b09a8cb..6d1eee4e0 100644
--- a/src/core/hle/service/cfg/cfg_i.cpp
+++ b/src/core/hle/service/cfg/cfg_i.cpp
@@ -6,10 +6,8 @@
6#include "core/hle/service/cfg/cfg.h" 6#include "core/hle/service/cfg/cfg.h"
7#include "core/hle/service/cfg/cfg_i.h" 7#include "core/hle/service/cfg/cfg_i.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace CFG_I 10namespace CFG {
11
12namespace CFG_I {
13 11
14/** 12/**
15 * CFG_I::GetConfigInfoBlk8 service function 13 * CFG_I::GetConfigInfoBlk8 service function
@@ -99,11 +97,9 @@ const Interface::FunctionInfo FunctionTable[] = {
99 {0x08180042, nullptr, "SecureInfoGetSerialNo"}, 97 {0x08180042, nullptr, "SecureInfoGetSerialNo"},
100}; 98};
101 99
102//////////////////////////////////////////////////////////////////////////////////////////////////// 100CFG_I_Interface::CFG_I_Interface() {
103// Interface class
104
105Interface::Interface() {
106 Register(FunctionTable); 101 Register(FunctionTable);
107} 102}
108 103
109} // namespace 104} // namespace CFG
105} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/cfg/cfg_i.h b/src/core/hle/service/cfg/cfg_i.h
index a498dd589..d0a2cce39 100644
--- a/src/core/hle/service/cfg/cfg_i.h
+++ b/src/core/hle/service/cfg/cfg_i.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace CFG_I 10namespace CFG {
11 11
12namespace CFG_I { 12class CFG_I_Interface : public Service::Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 CFG_I_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "cfg:i"; 17 return "cfg:i";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace CFG
22} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp
index d80aeae8d..d9a3e5d51 100644
--- a/src/core/hle/service/cfg/cfg_s.cpp
+++ b/src/core/hle/service/cfg/cfg_s.cpp
@@ -6,10 +6,8 @@
6#include "core/hle/service/cfg/cfg.h" 6#include "core/hle/service/cfg/cfg.h"
7#include "core/hle/service/cfg/cfg_s.h" 7#include "core/hle/service/cfg/cfg_s.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace CFG_S 10namespace CFG {
11
12namespace CFG_S {
13 11
14/** 12/**
15 * CFG_S::GetConfigInfoBlk2 service function 13 * CFG_S::GetConfigInfoBlk2 service function
@@ -87,11 +85,9 @@ const Interface::FunctionInfo FunctionTable[] = {
87 {0x04090000, nullptr, "UpdateConfigBlk00040003"}, 85 {0x04090000, nullptr, "UpdateConfigBlk00040003"},
88}; 86};
89 87
90//////////////////////////////////////////////////////////////////////////////////////////////////// 88CFG_S_Interface::CFG_S_Interface() {
91// Interface class
92
93Interface::Interface() {
94 Register(FunctionTable); 89 Register(FunctionTable);
95} 90}
96 91
97} // namespace 92} // namespace CFG
93} // namespace Service
diff --git a/src/core/hle/service/cfg/cfg_s.h b/src/core/hle/service/cfg/cfg_s.h
index d8b67137f..5568d6485 100644
--- a/src/core/hle/service/cfg/cfg_s.h
+++ b/src/core/hle/service/cfg/cfg_s.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace CFG_S 10namespace CFG {
11 11
12namespace CFG_S { 12class CFG_S_Interface : public Service::Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 CFG_S_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "cfg:s"; 17 return "cfg:s";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace CFG
22} // namespace Service
diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp
index a65da90c5..c8c1c5b17 100644
--- a/src/core/hle/service/cfg/cfg_u.cpp
+++ b/src/core/hle/service/cfg/cfg_u.cpp
@@ -10,10 +10,8 @@
10#include "core/hle/service/cfg/cfg.h" 10#include "core/hle/service/cfg/cfg.h"
11#include "core/hle/service/cfg/cfg_u.h" 11#include "core/hle/service/cfg/cfg_u.h"
12 12
13//////////////////////////////////////////////////////////////////////////////////////////////////// 13namespace Service {
14// Namespace CFG_U 14namespace CFG {
15
16namespace CFG_U {
17 15
18// TODO(Link Mauve): use a constexpr once MSVC starts supporting it. 16// TODO(Link Mauve): use a constexpr once MSVC starts supporting it.
19#define C(code) ((code)[0] | ((code)[1] << 8)) 17#define C(code) ((code)[0] | ((code)[1] << 8))
@@ -241,11 +239,9 @@ const Interface::FunctionInfo FunctionTable[] = {
241 {0x000A0040, GetCountryCodeID, "GetCountryCodeID"}, 239 {0x000A0040, GetCountryCodeID, "GetCountryCodeID"},
242}; 240};
243 241
244//////////////////////////////////////////////////////////////////////////////////////////////////// 242CFG_U_Interface::CFG_U_Interface() {
245// Interface class
246
247Interface::Interface() {
248 Register(FunctionTable); 243 Register(FunctionTable);
249} 244}
250 245
251} // namespace 246} // namespace CFG
247} // namespace Service
diff --git a/src/core/hle/service/cfg/cfg_u.h b/src/core/hle/service/cfg/cfg_u.h
index 9ad73f355..5303d8ac6 100644
--- a/src/core/hle/service/cfg/cfg_u.h
+++ b/src/core/hle/service/cfg/cfg_u.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace CFG_U 10namespace CFG {
11 11
12namespace CFG_U { 12class CFG_U_Interface : public Service::Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 CFG_U_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "cfg:u"; 17 return "cfg:u";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace CFG
22} // namespace Service
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp
index c5020cb24..9da2e7aa2 100644
--- a/src/core/hle/service/fs/archive.cpp
+++ b/src/core/hle/service/fs/archive.cpp
@@ -20,7 +20,9 @@
20#include "core/file_sys/archive_sdmc.h" 20#include "core/file_sys/archive_sdmc.h"
21#include "core/file_sys/archive_systemsavedata.h" 21#include "core/file_sys/archive_systemsavedata.h"
22#include "core/file_sys/directory_backend.h" 22#include "core/file_sys/directory_backend.h"
23#include "core/hle/service/service.h"
23#include "core/hle/service/fs/archive.h" 24#include "core/hle/service/fs/archive.h"
25#include "core/hle/service/fs/fs_user.h"
24#include "core/hle/result.h" 26#include "core/hle/result.h"
25 27
26// Specializes std::hash for ArchiveIdCode, so that we can use it in std::unordered_map. 28// Specializes std::hash for ArchiveIdCode, so that we can use it in std::unordered_map.
@@ -419,6 +421,8 @@ ResultCode CreateExtSaveData(u32 high, u32 low) {
419void ArchiveInit() { 421void ArchiveInit() {
420 next_handle = 1; 422 next_handle = 1;
421 423
424 AddService(new FS::Interface);
425
422 // TODO(Subv): Add the other archive types (see here for the known types: 426 // TODO(Subv): Add the other archive types (see here for the known types:
423 // http://3dbrew.org/wiki/FS:OpenArchive#Archive_idcodes). 427 // http://3dbrew.org/wiki/FS:OpenArchive#Archive_idcodes).
424 428
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp
index 2c1302208..eb312496e 100644
--- a/src/core/hle/service/fs/fs_user.cpp
+++ b/src/core/hle/service/fs/fs_user.cpp
@@ -520,7 +520,7 @@ static void CardSlotIsInserted(Service::Interface* self) {
520 LOG_WARNING(Service_FS, "(STUBBED) called"); 520 LOG_WARNING(Service_FS, "(STUBBED) called");
521} 521}
522 522
523const FSUserInterface::FunctionInfo FunctionTable[] = { 523const Interface::FunctionInfo FunctionTable[] = {
524 {0x000100C6, nullptr, "Dummy1"}, 524 {0x000100C6, nullptr, "Dummy1"},
525 {0x040100C4, nullptr, "Control"}, 525 {0x040100C4, nullptr, "Control"},
526 {0x08010002, Initialize, "Initialize"}, 526 {0x08010002, Initialize, "Initialize"},
@@ -614,7 +614,7 @@ const FSUserInterface::FunctionInfo FunctionTable[] = {
614//////////////////////////////////////////////////////////////////////////////////////////////////// 614////////////////////////////////////////////////////////////////////////////////////////////////////
615// Interface class 615// Interface class
616 616
617FSUserInterface::FSUserInterface() { 617Interface::Interface() {
618 Register(FunctionTable); 618 Register(FunctionTable);
619} 619}
620 620
diff --git a/src/core/hle/service/fs/fs_user.h b/src/core/hle/service/fs/fs_user.h
index 2d896dd5f..bb6ab195e 100644
--- a/src/core/hle/service/fs/fs_user.h
+++ b/src/core/hle/service/fs/fs_user.h
@@ -6,16 +6,13 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace FS_User
11
12namespace Service { 9namespace Service {
13namespace FS { 10namespace FS {
14 11
15/// Interface to "fs:USER" service 12/// Interface to "fs:USER" service
16class FSUserInterface : public Service::Interface { 13class Interface : public Service::Interface {
17public: 14public:
18 FSUserInterface(); 15 Interface();
19 16
20 std::string GetPortName() const override { 17 std::string GetPortName() const override {
21 return "fs:USER"; 18 return "fs:USER";
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 7cb01729e..e0689be2e 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -2,7 +2,10 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/service/service.h"
5#include "core/hle/service/hid/hid.h" 6#include "core/hle/service/hid/hid.h"
7#include "core/hle/service/hid/hid_spvr.h"
8#include "core/hle/service/hid/hid_user.h"
6 9
7#include "core/arm/arm_interface.h" 10#include "core/arm/arm_interface.h"
8#include "core/hle/kernel/event.h" 11#include "core/hle/kernel/event.h"
@@ -35,6 +38,19 @@ static inline PadData* GetPadData() {
35 return reinterpret_cast<PadData*>(g_shared_mem->GetPointer().ValueOr(nullptr)); 38 return reinterpret_cast<PadData*>(g_shared_mem->GetPointer().ValueOr(nullptr));
36} 39}
37 40
41// TODO(peachum):
42// Add a method for setting analog input from joystick device for the circle Pad.
43//
44// This method should:
45// * Be called after both PadButton<Press, Release>().
46// * Be called before PadUpdateComplete()
47// * Set current PadEntry.circle_pad_<axis> using analog data
48// * Set PadData.raw_circle_pad_data
49// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_x >= 41
50// * Set PadData.current_state.circle_up = 1 if current PadEntry.circle_pad_y >= 41
51// * Set PadData.current_state.circle_left = 1 if current PadEntry.circle_pad_x <= -41
52// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
53
38/** 54/**
39 * Circle Pad from keys. 55 * Circle Pad from keys.
40 * 56 *
@@ -121,9 +137,25 @@ void PadUpdateComplete() {
121 g_event_pad_or_touch_2->Signal(); 137 g_event_pad_or_touch_2->Signal();
122} 138}
123 139
140void GetIPCHandles(Service::Interface* self) {
141 u32* cmd_buff = Kernel::GetCommandBuffer();
142
143 cmd_buff[1] = 0; // No error
144 // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling)
145 cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::g_shared_mem).MoveFrom();
146 cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_1).MoveFrom();
147 cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_2).MoveFrom();
148 cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::g_event_accelerometer).MoveFrom();
149 cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::g_event_gyroscope).MoveFrom();
150 cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::g_event_debug_pad).MoveFrom();
151}
152
124void HIDInit() { 153void HIDInit() {
125 using namespace Kernel; 154 using namespace Kernel;
126 155
156 AddService(new HID_U_Interface);
157 AddService(new HID_SPVR_Interface);
158
127 g_shared_mem = SharedMemory::Create("HID:SharedMem"); 159 g_shared_mem = SharedMemory::Create("HID:SharedMem");
128 160
129 // Create event handles 161 // Create event handles
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index fc628f36a..9c6e86f77 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -7,6 +7,7 @@
7#include <array> 7#include <array>
8 8
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
10#include "core/hle/service/service.h"
10#include "common/bit_field.h" 11#include "common/bit_field.h"
11 12
12namespace Kernel { 13namespace Kernel {
@@ -123,6 +124,22 @@ const PadState PAD_CIRCLE_LEFT = {{1u << 29}};
123const PadState PAD_CIRCLE_UP = {{1u << 30}}; 124const PadState PAD_CIRCLE_UP = {{1u << 30}};
124const PadState PAD_CIRCLE_DOWN = {{1u << 31}}; 125const PadState PAD_CIRCLE_DOWN = {{1u << 31}};
125 126
127/**
128 * HID::GetIPCHandles service function
129 * Inputs:
130 * None
131 * Outputs:
132 * 1 : Result of function, 0 on success, otherwise error code
133 * 2 : Unused
134 * 3 : Handle to HID_User shared memory
135 * 4 : Event signaled by HID_User
136 * 5 : Event signaled by HID_User
137 * 6 : Event signaled by HID_User
138 * 7 : Gyroscope event
139 * 8 : Event signaled by HID_User
140 */
141void GetIPCHandles(Interface* self);
142
126// Methods for updating the HID module's state 143// Methods for updating the HID module's state
127void PadButtonPress(const PadState& pad_state); 144void PadButtonPress(const PadState& pad_state);
128void PadButtonRelease(const PadState& pad_state); 145void PadButtonRelease(const PadState& pad_state);
diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp
index 8f06b224d..790dcabbf 100644
--- a/src/core/hle/service/hid/hid_spvr.cpp
+++ b/src/core/hle/service/hid/hid_spvr.cpp
@@ -3,19 +3,14 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/hle.h" 5#include "core/hle/hle.h"
6#include "core/hle/service/hid/hid.h"
6#include "core/hle/service/hid/hid_spvr.h" 7#include "core/hle/service/hid/hid_spvr.h"
7 8
8//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
9// Namespace HID_SPVR 10namespace HID {
10
11namespace HID_User {
12 extern void GetIPCHandles(Service::Interface* self);
13}
14
15namespace HID_SPVR {
16 11
17const Interface::FunctionInfo FunctionTable[] = { 12const Interface::FunctionInfo FunctionTable[] = {
18 {0x000A0000, HID_User::GetIPCHandles, "GetIPCHandles"}, 13 {0x000A0000, GetIPCHandles, "GetIPCHandles"},
19 {0x000B0000, nullptr, "StartAnalogStickCalibration"}, 14 {0x000B0000, nullptr, "StartAnalogStickCalibration"},
20 {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"}, 15 {0x000E0000, nullptr, "GetAnalogStickCalibrateParam"},
21 {0x00110000, nullptr, "EnableAccelerometer"}, 16 {0x00110000, nullptr, "EnableAccelerometer"},
@@ -27,11 +22,9 @@ const Interface::FunctionInfo FunctionTable[] = {
27 {0x00170000, nullptr, "GetSoundVolume"}, 22 {0x00170000, nullptr, "GetSoundVolume"},
28}; 23};
29 24
30//////////////////////////////////////////////////////////////////////////////////////////////////// 25HID_SPVR_Interface::HID_SPVR_Interface() {
31// Interface class
32
33Interface::Interface() {
34 Register(FunctionTable); 26 Register(FunctionTable);
35} 27}
36 28
37} // namespace 29} // namespace HID
30} // namespace Service
diff --git a/src/core/hle/service/hid/hid_spvr.h b/src/core/hle/service/hid/hid_spvr.h
index 53ddc8569..ba61583d2 100644
--- a/src/core/hle/service/hid/hid_spvr.h
+++ b/src/core/hle/service/hid/hid_spvr.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace HID_SPVR 10namespace HID {
11 11
12namespace HID_SPVR { 12class HID_SPVR_Interface : public Service::Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 HID_SPVR_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "hid:SPVR"; 17 return "hid:SPVR";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace HID
22} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp
index 7f464705f..1d0accefe 100644
--- a/src/core/hle/service/hid/hid_user.cpp
+++ b/src/core/hle/service/hid/hid_user.cpp
@@ -6,54 +6,10 @@
6#include "core/hle/kernel/event.h" 6#include "core/hle/kernel/event.h"
7#include "core/hle/kernel/shared_memory.h" 7#include "core/hle/kernel/shared_memory.h"
8#include "core/hle/service/hid/hid.h" 8#include "core/hle/service/hid/hid.h"
9#include "hid_user.h" 9#include "core/hle/service/hid/hid_user.h"
10 10
11//////////////////////////////////////////////////////////////////////////////////////////////////// 11namespace Service {
12// Namespace HID_User 12namespace HID {
13
14namespace HID_User {
15
16
17// TODO(peachum):
18// Add a method for setting analog input from joystick device for the circle Pad.
19//
20// This method should:
21// * Be called after both PadButton<Press, Release>().
22// * Be called before PadUpdateComplete()
23// * Set current PadEntry.circle_pad_<axis> using analog data
24// * Set PadData.raw_circle_pad_data
25// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_x >= 41
26// * Set PadData.current_state.circle_up = 1 if current PadEntry.circle_pad_y >= 41
27// * Set PadData.current_state.circle_left = 1 if current PadEntry.circle_pad_x <= -41
28// * Set PadData.current_state.circle_right = 1 if current PadEntry.circle_pad_y <= -41
29
30
31/**
32 * HID_User::GetIPCHandles service function
33 * Inputs:
34 * None
35 * Outputs:
36 * 1 : Result of function, 0 on success, otherwise error code
37 * 2 : Unused
38 * 3 : Handle to HID_User shared memory
39 * 4 : Event signaled by HID_User
40 * 5 : Event signaled by HID_User
41 * 6 : Event signaled by HID_User
42 * 7 : Gyroscope event
43 * 8 : Event signaled by HID_User
44 */
45void GetIPCHandles(Service::Interface* self) {
46 u32* cmd_buff = Kernel::GetCommandBuffer();
47
48 cmd_buff[1] = 0; // No error
49 // TODO(yuriks): Return error from SendSyncRequest is this fails (part of IPC marshalling)
50 cmd_buff[3] = Kernel::g_handle_table.Create(Service::HID::g_shared_mem).MoveFrom();
51 cmd_buff[4] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_1).MoveFrom();
52 cmd_buff[5] = Kernel::g_handle_table.Create(Service::HID::g_event_pad_or_touch_2).MoveFrom();
53 cmd_buff[6] = Kernel::g_handle_table.Create(Service::HID::g_event_accelerometer).MoveFrom();
54 cmd_buff[7] = Kernel::g_handle_table.Create(Service::HID::g_event_gyroscope).MoveFrom();
55 cmd_buff[8] = Kernel::g_handle_table.Create(Service::HID::g_event_debug_pad).MoveFrom();
56}
57 13
58const Interface::FunctionInfo FunctionTable[] = { 14const Interface::FunctionInfo FunctionTable[] = {
59 {0x000A0000, GetIPCHandles, "GetIPCHandles"}, 15 {0x000A0000, GetIPCHandles, "GetIPCHandles"},
@@ -66,11 +22,9 @@ const Interface::FunctionInfo FunctionTable[] = {
66 {0x00170000, nullptr, "GetSoundVolume"}, 22 {0x00170000, nullptr, "GetSoundVolume"},
67}; 23};
68 24
69//////////////////////////////////////////////////////////////////////////////////////////////////// 25HID_U_Interface::HID_U_Interface() {
70// Interface class
71
72Interface::Interface() {
73 Register(FunctionTable); 26 Register(FunctionTable);
74} 27}
75 28
76} // namespace 29} // namespace HID
30} // namespace Service
diff --git a/src/core/hle/service/hid/hid_user.h b/src/core/hle/service/hid/hid_user.h
index 1d9929e67..0eeec2c25 100644
--- a/src/core/hle/service/hid/hid_user.h
+++ b/src/core/hle/service/hid/hid_user.h
@@ -6,24 +6,23 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9////////////////////////////////////////////////////////////////////////////////////////////////////
10// Namespace HID_User
11
12// This service is used for interfacing to physical user controls. 9// This service is used for interfacing to physical user controls.
13// Uses include game pad controls, touchscreen, accelerometers, gyroscopes, and debug pad. 10// Uses include game pad controls, touchscreen, accelerometers, gyroscopes, and debug pad.
14 11
15namespace HID_User { 12namespace Service {
16 13namespace HID {
14
17/** 15/**
18 * HID service interface. 16 * HID service interface.
19 */ 17 */
20class Interface : public Service::Interface { 18class HID_U_Interface : public Service::Interface {
21public: 19public:
22 Interface(); 20 HID_U_Interface();
23 21
24 std::string GetPortName() const override { 22 std::string GetPortName() const override {
25 return "hid:USER"; 23 return "hid:USER";
26 } 24 }
27}; 25};
28 26
29} // namespace 27} // namespace HID
28} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp
new file mode 100644
index 000000000..56c918d4f
--- /dev/null
+++ b/src/core/hle/service/ptm/ptm.cpp
@@ -0,0 +1,76 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/service.h"
6#include "core/hle/service/fs/archive.h"
7#include "core/hle/service/ptm/ptm.h"
8#include "core/hle/service/ptm/ptm_play.h"
9#include "core/hle/service/ptm/ptm_sysm.h"
10#include "core/hle/service/ptm/ptm_u.h"
11
12namespace Service {
13namespace PTM {
14
15/// Values for the default gamecoin.dat file
16static const GameCoin default_game_coin = { 0x4F00, 42, 0, 0, 0, 2014, 12, 29 };
17
18/// Id of the SharedExtData archive used by the PTM process
19static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0};
20
21static bool shell_open = true;
22
23static bool battery_is_charging = true;
24
25u32 GetAdapterState() {
26 // TODO(purpasmart96): This function is only a stub,
27 // it returns a valid result without implementing full functionality.
28 return battery_is_charging ? 1 : 0;
29}
30
31u32 GetShellState() {
32 return shell_open ? 1 : 0;
33}
34
35ChargeLevels GetBatteryLevel() {
36 // TODO(purpasmart96): This function is only a stub,
37 // it returns a valid result without implementing full functionality.
38 return ChargeLevels::CompletelyFull; // Set to a completely full battery
39}
40
41void PTMInit() {
42 AddService(new PTM_Play_Interface);
43 AddService(new PTM_Sysm_Interface);
44 AddService(new PTM_U_Interface);
45
46 // Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't exist
47 FileSys::Path archive_path(ptm_shared_extdata_id);
48 auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
49 // If the archive didn't exist, create the files inside
50 if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) {
51 // Format the archive to create the directories
52 Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
53 // Open it again to get a valid archive now that the folder exists
54 archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
55 ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!");
56
57 FileSys::Path gamecoin_path("gamecoin.dat");
58 FileSys::Mode open_mode = {};
59 open_mode.write_flag = 1;
60 open_mode.create_flag = 1;
61 // Open the file and write the default gamecoin information
62 auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode);
63 if (gamecoin_result.Succeeded()) {
64 auto gamecoin = gamecoin_result.MoveFrom();
65 gamecoin->backend->Write(0, sizeof(GameCoin), 1, reinterpret_cast<const u8*>(&default_game_coin));
66 gamecoin->backend->Close();
67 }
68 }
69}
70
71void PTMShutdown() {
72
73}
74
75} // namespace PTM
76} // namespace Service
diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h
new file mode 100644
index 000000000..f697aae4d
--- /dev/null
+++ b/src/core/hle/service/ptm/ptm.h
@@ -0,0 +1,65 @@
1// Copyright 2015 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <array>
8#include "core/hle/result.h"
9
10namespace Service {
11namespace PTM {
12
13/// Charge levels used by PTM functions
14enum class ChargeLevels : u32 {
15 CriticalBattery = 1,
16 LowBattery = 2,
17 HalfFull = 3,
18 MostlyFull = 4,
19 CompletelyFull = 5,
20};
21
22/**
23 * Represents the gamecoin file structure in the SharedExtData archive
24 * More information in 3dbrew (http://www.3dbrew.org/wiki/Extdata#Shared_Extdata_0xf000000b_gamecoin.dat)
25 */
26struct GameCoin {
27 u32 magic; ///< Magic number: 0x4F00
28 u16 total_coins; ///< Total Play Coins
29 u16 total_coins_on_date; ///< Total Play Coins obtained on the date stored below.
30 u32 step_count; ///< Total step count at the time a new Play Coin was obtained.
31 u32 last_step_count; ///< Step count for the day the last Play Coin was obtained
32 u16 year;
33 u8 month;
34 u8 day;
35};
36
37/**
38 * Returns whether the battery is charging or not.
39 * It is unknown if GetAdapterState is the same as GetBatteryChargeState,
40 * it is likely to just be a duplicate function of GetBatteryChargeState
41 * that controls another part of the HW.
42 * @returns 1 if the battery is charging, and 0 otherwise.
43 */
44u32 GetAdapterState();
45
46/**
47 * Returns whether the 3DS's physical shell casing is open or closed
48 * @returns 1 if the shell is open, and 0 if otherwise
49 */
50u32 GetShellState();
51
52/**
53 * Get the current battery's charge level.
54 * @returns The battery's charge level.
55 */
56ChargeLevels GetBatteryLevel();
57
58/// Initialize the PTM service
59void PTMInit();
60
61/// Shutdown the PTM service
62void PTMShutdown();
63
64} // namespace PTM
65} // namespace Service
diff --git a/src/core/hle/service/ptm_play.cpp b/src/core/hle/service/ptm/ptm_play.cpp
index f21d9088e..8e8ae8558 100644
--- a/src/core/hle/service/ptm_play.cpp
+++ b/src/core/hle/service/ptm/ptm_play.cpp
@@ -3,12 +3,10 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/hle/hle.h" 5#include "core/hle/hle.h"
6#include "core/hle/service/ptm_play.h" 6#include "core/hle/service/ptm/ptm_play.h"
7 7
8//////////////////////////////////////////////////////////////////////////////////////////////////// 8namespace Service {
9// Namespace PTM_PLAY 9namespace PTM {
10
11namespace PTM_PLAY {
12 10
13const Interface::FunctionInfo FunctionTable[] = { 11const Interface::FunctionInfo FunctionTable[] = {
14 { 0x08070082, nullptr, "GetPlayHistory" }, 12 { 0x08070082, nullptr, "GetPlayHistory" },
@@ -17,11 +15,9 @@ const Interface::FunctionInfo FunctionTable[] = {
17 { 0x080B0080, nullptr, "CalcPlayHistoryStart" }, 15 { 0x080B0080, nullptr, "CalcPlayHistoryStart" },
18}; 16};
19 17
20//////////////////////////////////////////////////////////////////////////////////////////////////// 18PTM_Play_Interface::PTM_Play_Interface() {
21// Interface class
22
23Interface::Interface() {
24 Register(FunctionTable); 19 Register(FunctionTable);
25} 20}
26 21
27} // namespace 22} // namespace PTM
23} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/ptm_play.h b/src/core/hle/service/ptm/ptm_play.h
index 2f4f0d6fd..e5c3e04df 100644
--- a/src/core/hle/service/ptm_play.h
+++ b/src/core/hle/service/ptm/ptm_play.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace PTM_PLAY 10namespace PTM {
11 11
12namespace PTM_PLAY { 12class PTM_Play_Interface : public Service::Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 PTM_Play_Interface();
17 15
18std::string GetPortName() const override { 16std::string GetPortName() const override {
19 return "ptm:play"; 17 return "ptm:play";
20} 18}
21}; 19};
22 20
23} // namespace 21} // namespace PTM
22} // namespace Service
diff --git a/src/core/hle/service/ptm_sysm.cpp b/src/core/hle/service/ptm/ptm_sysm.cpp
index dc4a9c569..2d841f69c 100644
--- a/src/core/hle/service/ptm_sysm.cpp
+++ b/src/core/hle/service/ptm/ptm_sysm.cpp
@@ -5,12 +5,10 @@
5#include "common/make_unique.h" 5#include "common/make_unique.h"
6#include "core/file_sys/archive_extsavedata.h" 6#include "core/file_sys/archive_extsavedata.h"
7#include "core/hle/hle.h" 7#include "core/hle/hle.h"
8#include "core/hle/service/ptm_sysm.h" 8#include "core/hle/service/ptm/ptm_sysm.h"
9 9
10//////////////////////////////////////////////////////////////////////////////////////////////////// 10namespace Service {
11// Namespace PTM_SYSM 11namespace PTM {
12
13namespace PTM_SYSM {
14 12
15/** 13/**
16 * Returns whether the system is powering off (?) 14 * Returns whether the system is powering off (?)
@@ -57,11 +55,9 @@ const Interface::FunctionInfo FunctionTable[] = {
57 {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"} 55 {0x08140000, nullptr, "GetLegacyJumpProhibitedFlag"}
58}; 56};
59 57
60//////////////////////////////////////////////////////////////////////////////////////////////////// 58PTM_Sysm_Interface::PTM_Sysm_Interface() {
61// Interface class
62
63Interface::Interface() {
64 Register(FunctionTable); 59 Register(FunctionTable);
65} 60}
66 61
67} // namespace 62} // namespace PTM
63} // namespace Service
diff --git a/src/core/hle/service/ptm_sysm.h b/src/core/hle/service/ptm/ptm_sysm.h
index 0f267b214..e37f20546 100644
--- a/src/core/hle/service/ptm_sysm.h
+++ b/src/core/hle/service/ptm/ptm_sysm.h
@@ -6,18 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace PTM_SYSM 10namespace PTM {
11 11
12namespace PTM_SYSM { 12class PTM_Sysm_Interface : public Interface {
13
14class Interface : public Service::Interface {
15public: 13public:
16 Interface(); 14 PTM_Sysm_Interface();
17 15
18 std::string GetPortName() const override { 16 std::string GetPortName() const override {
19 return "ptm:sysm"; 17 return "ptm:sysm";
20 } 18 }
21}; 19};
22 20
23} // namespace 21} // namespace PTM
22} // namespace Service
diff --git a/src/core/hle/service/ptm/ptm_u.cpp b/src/core/hle/service/ptm/ptm_u.cpp
new file mode 100644
index 000000000..0af7c8bf6
--- /dev/null
+++ b/src/core/hle/service/ptm/ptm_u.cpp
@@ -0,0 +1,99 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/make_unique.h"
6
7#include "core/hle/hle.h"
8#include "core/hle/service/ptm/ptm.h"
9#include "core/hle/service/ptm/ptm_u.h"
10
11namespace Service {
12namespace PTM {
13
14/**
15 * PTM_U::GetAdapterState service function
16 * Outputs:
17 * 1 : Result of function, 0 on success, otherwise error code
18 * 2 : Output of function, 0 = not charging, 1 = charging.
19 */
20static void GetAdapterState(Service::Interface* self) {
21 u32* cmd_buff = Kernel::GetCommandBuffer();
22
23 cmd_buff[1] = RESULT_SUCCESS.raw;
24 cmd_buff[2] = GetAdapterState();
25
26 LOG_WARNING(Service_PTM, "(STUBBED) called");
27}
28
29/*
30 * PTM_User::GetShellState service function.
31 * Outputs:
32 * 1 : Result of function, 0 on success, otherwise error code
33 * 2 : Whether the 3DS's physical shell casing is open (1) or closed (0)
34 */
35static void GetShellState(Service::Interface* self) {
36 u32* cmd_buff = Kernel::GetCommandBuffer();
37
38 cmd_buff[1] = RESULT_SUCCESS.raw;
39 cmd_buff[2] = GetShellState();
40}
41
42/**
43 * PTM_U::GetBatteryLevel service function
44 * Outputs:
45 * 1 : Result of function, 0 on success, otherwise error code
46 * 2 : Battery level, 5 = completely full battery, 4 = mostly full battery,
47 * 3 = half full battery, 2 = low battery, 1 = critical battery.
48 */
49static void GetBatteryLevel(Service::Interface* self) {
50 u32* cmd_buff = Kernel::GetCommandBuffer();
51
52 cmd_buff[1] = RESULT_SUCCESS.raw;
53 cmd_buff[2] = static_cast<u32>(GetBatteryLevel());
54
55 LOG_WARNING(Service_PTM, "(STUBBED) called");
56}
57
58/**
59 * PTM_U::GetBatteryChargeState service function
60 * Outputs:
61 * 1 : Result of function, 0 on success, otherwise error code
62 * 2 : Output of function, 0 = not charging, 1 = charging.
63 */
64static void GetBatteryChargeState(Service::Interface* self) {
65 u32* cmd_buff = Kernel::GetCommandBuffer();
66
67 // TODO(purpasmart96): This function is only a stub,
68 // it returns a valid result without implementing full functionality.
69
70 cmd_buff[1] = RESULT_SUCCESS.raw;
71 cmd_buff[2] = GetAdapterState();
72
73 LOG_WARNING(Service_PTM, "(STUBBED) called");
74}
75
76const Interface::FunctionInfo FunctionTable[] = {
77 {0x00010002, nullptr, "RegisterAlarmClient"},
78 {0x00020080, nullptr, "SetRtcAlarm"},
79 {0x00030000, nullptr, "GetRtcAlarm"},
80 {0x00040000, nullptr, "CancelRtcAlarm"},
81 {0x00050000, GetAdapterState, "GetAdapterState"},
82 {0x00060000, GetShellState, "GetShellState"},
83 {0x00070000, GetBatteryLevel, "GetBatteryLevel"},
84 {0x00080000, GetBatteryChargeState, "GetBatteryChargeState"},
85 {0x00090000, nullptr, "GetPedometerState"},
86 {0x000A0042, nullptr, "GetStepHistoryEntry"},
87 {0x000B00C2, nullptr, "GetStepHistory"},
88 {0x000C0000, nullptr, "GetTotalStepCount"},
89 {0x000D0040, nullptr, "SetPedometerRecordingMode"},
90 {0x000E0000, nullptr, "GetPedometerRecordingMode"},
91 {0x000F0084, nullptr, "GetStepHistoryAll"},
92};
93
94PTM_U_Interface::PTM_U_Interface() {
95 Register(FunctionTable);
96}
97
98} // namespace PTM
99} // namespace Service
diff --git a/src/core/hle/service/ptm_u.h b/src/core/hle/service/ptm/ptm_u.h
index a44624fd5..bf132f610 100644
--- a/src/core/hle/service/ptm_u.h
+++ b/src/core/hle/service/ptm/ptm_u.h
@@ -6,20 +6,17 @@
6 6
7#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
8 8
9//////////////////////////////////////////////////////////////////////////////////////////////////// 9namespace Service {
10// Namespace PTM_U 10namespace PTM {
11 11
12// ptm service 12class PTM_U_Interface : public Interface {
13
14namespace PTM_U {
15
16class Interface : public Service::Interface {
17public: 13public:
18 Interface(); 14 PTM_U_Interface();
19 15
20 std::string GetPortName() const override { 16 std::string GetPortName() const override {
21 return "ptm:u"; 17 return "ptm:u";
22 } 18 }
23}; 19};
24 20
25} // namespace 21} // namespace PTM
22} // namespace Service \ No newline at end of file
diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp
deleted file mode 100644
index 7121d837c..000000000
--- a/src/core/hle/service/ptm_u.cpp
+++ /dev/null
@@ -1,166 +0,0 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "common/make_unique.h"
6
7#include "core/hle/hle.h"
8#include "core/hle/service/fs/archive.h"
9#include "core/hle/service/ptm_u.h"
10
11////////////////////////////////////////////////////////////////////////////////////////////////////
12// Namespace PTM_U
13
14namespace PTM_U {
15
16/**
17 * Represents the gamecoin file structure in the SharedExtData archive
18 * More information in 3dbrew (http://www.3dbrew.org/wiki/Extdata#Shared_Extdata_0xf000000b_gamecoin.dat)
19 */
20struct GameCoin {
21 u32 magic; ///< Magic number: 0x4F00
22 u16 total_coins; ///< Total Play Coins
23 u16 total_coins_on_date; ///< Total Play Coins obtained on the date stored below.
24 u32 step_count; ///< Total step count at the time a new Play Coin was obtained.
25 u32 last_step_count; ///< Step count for the day the last Play Coin was obtained
26 u16 year;
27 u8 month;
28 u8 day;
29};
30static const GameCoin default_game_coin = { 0x4F00, 42, 0, 0, 0, 2014, 12, 29 };
31static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0};
32
33/// Charge levels used by PTM functions
34enum class ChargeLevels : u32 {
35 CriticalBattery = 1,
36 LowBattery = 2,
37 HalfFull = 3,
38 MostlyFull = 4,
39 CompletelyFull = 5,
40};
41
42static bool shell_open = true;
43
44static bool battery_is_charging = true;
45
46/**
47 * It is unknown if GetAdapterState is the same as GetBatteryChargeState,
48 * it is likely to just be a duplicate function of GetBatteryChargeState
49 * that controls another part of the HW.
50 * PTM_U::GetAdapterState service function
51 * Outputs:
52 * 1 : Result of function, 0 on success, otherwise error code
53 * 2 : Output of function, 0 = not charging, 1 = charging.
54 */
55static void GetAdapterState(Service::Interface* self) {
56 u32* cmd_buff = Kernel::GetCommandBuffer();
57
58 // TODO(purpasmart96): This function is only a stub,
59 // it returns a valid result without implementing full functionality.
60
61 cmd_buff[1] = 0; // No error
62 cmd_buff[2] = battery_is_charging ? 1 : 0;
63
64 LOG_WARNING(Service_PTM, "(STUBBED) called");
65}
66
67/*
68 * PTM_User::GetShellState service function.
69 * Outputs:
70 * 1 : Result of function, 0 on success, otherwise error code
71 * 2 : Whether the 3DS's physical shell casing is open (1) or closed (0)
72 */
73static void GetShellState(Service::Interface* self) {
74 u32* cmd_buff = Kernel::GetCommandBuffer();
75
76 cmd_buff[1] = 0;
77 cmd_buff[2] = shell_open ? 1 : 0;
78}
79
80/**
81 * PTM_U::GetBatteryLevel service function
82 * Outputs:
83 * 1 : Result of function, 0 on success, otherwise error code
84 * 2 : Battery level, 5 = completely full battery, 4 = mostly full battery,
85 * 3 = half full battery, 2 = low battery, 1 = critical battery.
86 */
87static void GetBatteryLevel(Service::Interface* self) {
88 u32* cmd_buff = Kernel::GetCommandBuffer();
89
90 // TODO(purpasmart96): This function is only a stub,
91 // it returns a valid result without implementing full functionality.
92
93 cmd_buff[1] = 0; // No error
94 cmd_buff[2] = static_cast<u32>(ChargeLevels::CompletelyFull); // Set to a completely full battery
95
96 LOG_WARNING(Service_PTM, "(STUBBED) called");
97}
98
99/**
100 * PTM_U::GetBatteryChargeState service function
101 * Outputs:
102 * 1 : Result of function, 0 on success, otherwise error code
103 * 2 : Output of function, 0 = not charging, 1 = charging.
104 */
105static void GetBatteryChargeState(Service::Interface* self) {
106 u32* cmd_buff = Kernel::GetCommandBuffer();
107
108 // TODO(purpasmart96): This function is only a stub,
109 // it returns a valid result without implementing full functionality.
110
111 cmd_buff[1] = 0; // No error
112 cmd_buff[2] = battery_is_charging ? 1 : 0;
113
114 LOG_WARNING(Service_PTM, "(STUBBED) called");
115}
116
117const Interface::FunctionInfo FunctionTable[] = {
118 {0x00010002, nullptr, "RegisterAlarmClient"},
119 {0x00020080, nullptr, "SetRtcAlarm"},
120 {0x00030000, nullptr, "GetRtcAlarm"},
121 {0x00040000, nullptr, "CancelRtcAlarm"},
122 {0x00050000, GetAdapterState, "GetAdapterState"},
123 {0x00060000, GetShellState, "GetShellState"},
124 {0x00070000, GetBatteryLevel, "GetBatteryLevel"},
125 {0x00080000, GetBatteryChargeState, "GetBatteryChargeState"},
126 {0x00090000, nullptr, "GetPedometerState"},
127 {0x000A0042, nullptr, "GetStepHistoryEntry"},
128 {0x000B00C2, nullptr, "GetStepHistory"},
129 {0x000C0000, nullptr, "GetTotalStepCount"},
130 {0x000D0040, nullptr, "SetPedometerRecordingMode"},
131 {0x000E0000, nullptr, "GetPedometerRecordingMode"},
132 {0x000F0084, nullptr, "GetStepHistoryAll"},
133};
134
135////////////////////////////////////////////////////////////////////////////////////////////////////
136// Interface class
137
138Interface::Interface() {
139 Register(FunctionTable);
140
141 // Open the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file
142 FileSys::Path archive_path(ptm_shared_extdata_id);
143 auto archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
144 // If the archive didn't exist, create the files inside
145 if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) {
146 // Format the archive to create the directories
147 Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
148 // Open it again to get a valid archive now that the folder exists
149 archive_result = Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
150 ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!");
151
152 FileSys::Path gamecoin_path("gamecoin.dat");
153 FileSys::Mode open_mode = {};
154 open_mode.write_flag = 1;
155 open_mode.create_flag = 1;
156 // Open the file and write the default gamecoin information
157 auto gamecoin_result = Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode);
158 if (gamecoin_result.Succeeded()) {
159 auto gamecoin = gamecoin_result.MoveFrom();
160 gamecoin->backend->Write(0, sizeof(GameCoin), 1, reinterpret_cast<const u8*>(&default_game_coin));
161 gamecoin->backend->Close();
162 }
163 }
164}
165
166} // namespace
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 5dce8068e..91f13cd7e 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -11,26 +11,17 @@
11#include "core/hle/service/am_app.h" 11#include "core/hle/service/am_app.h"
12#include "core/hle/service/am_net.h" 12#include "core/hle/service/am_net.h"
13#include "core/hle/service/am_sys.h" 13#include "core/hle/service/am_sys.h"
14#include "core/hle/service/apt_a.h"
15#include "core/hle/service/apt_s.h"
16#include "core/hle/service/apt_u.h"
17#include "core/hle/service/boss_p.h" 14#include "core/hle/service/boss_p.h"
18#include "core/hle/service/boss_u.h" 15#include "core/hle/service/boss_u.h"
19#include "core/hle/service/cam_u.h" 16#include "core/hle/service/cam_u.h"
20#include "core/hle/service/cecd_u.h" 17#include "core/hle/service/cecd_u.h"
21#include "core/hle/service/cecd_s.h" 18#include "core/hle/service/cecd_s.h"
22#include "core/hle/service/cfg/cfg_i.h"
23#include "core/hle/service/cfg/cfg_s.h"
24#include "core/hle/service/cfg/cfg_u.h"
25#include "core/hle/service/csnd_snd.h" 19#include "core/hle/service/csnd_snd.h"
26#include "core/hle/service/dsp_dsp.h" 20#include "core/hle/service/dsp_dsp.h"
27#include "core/hle/service/err_f.h" 21#include "core/hle/service/err_f.h"
28#include "core/hle/service/fs/fs_user.h"
29#include "core/hle/service/frd_a.h" 22#include "core/hle/service/frd_a.h"
30#include "core/hle/service/frd_u.h" 23#include "core/hle/service/frd_u.h"
31#include "core/hle/service/gsp_gpu.h" 24#include "core/hle/service/gsp_gpu.h"
32#include "core/hle/service/hid/hid_spvr.h"
33#include "core/hle/service/hid/hid_user.h"
34#include "core/hle/service/gsp_lcd.h" 25#include "core/hle/service/gsp_lcd.h"
35#include "core/hle/service/http_c.h" 26#include "core/hle/service/http_c.h"
36#include "core/hle/service/ir_rst.h" 27#include "core/hle/service/ir_rst.h"
@@ -44,14 +35,17 @@
44#include "core/hle/service/ns_s.h" 35#include "core/hle/service/ns_s.h"
45#include "core/hle/service/nwm_uds.h" 36#include "core/hle/service/nwm_uds.h"
46#include "core/hle/service/pm_app.h" 37#include "core/hle/service/pm_app.h"
47#include "core/hle/service/ptm_play.h"
48#include "core/hle/service/ptm_u.h"
49#include "core/hle/service/ptm_sysm.h"
50#include "core/hle/service/soc_u.h" 38#include "core/hle/service/soc_u.h"
51#include "core/hle/service/srv.h" 39#include "core/hle/service/srv.h"
52#include "core/hle/service/ssl_c.h" 40#include "core/hle/service/ssl_c.h"
53#include "core/hle/service/y2r_u.h" 41#include "core/hle/service/y2r_u.h"
54 42
43#include "core/hle/service/apt/apt.h"
44#include "core/hle/service/fs/archive.h"
45#include "core/hle/service/cfg/cfg.h"
46#include "core/hle/service/hid/hid.h"
47#include "core/hle/service/ptm/ptm.h"
48
55namespace Service { 49namespace Service {
56 50
57std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports; 51std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports;
@@ -60,12 +54,12 @@ std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;
60//////////////////////////////////////////////////////////////////////////////////////////////////// 54////////////////////////////////////////////////////////////////////////////////////////////////////
61// Module interface 55// Module interface
62 56
63static void AddNamedPort(Interface* interface) { 57static void AddNamedPort(Interface* interface_) {
64 g_kernel_named_ports.emplace(interface->GetPortName(), interface); 58 g_kernel_named_ports.emplace(interface_->GetPortName(), interface_);
65} 59}
66 60
67static void AddService(Interface* interface) { 61void AddService(Interface* interface_) {
68 g_srv_services.emplace(interface->GetPortName(), interface); 62 g_srv_services.emplace(interface_->GetPortName(), interface_);
69} 63}
70 64
71/// Initialize ServiceManager 65/// Initialize ServiceManager
@@ -73,31 +67,28 @@ void Init() {
73 AddNamedPort(new SRV::Interface); 67 AddNamedPort(new SRV::Interface);
74 AddNamedPort(new ERR_F::Interface); 68 AddNamedPort(new ERR_F::Interface);
75 69
70 Service::FS::ArchiveInit();
71 Service::CFG::CFGInit();
72 Service::APT::APTInit();
73 Service::PTM::PTMInit();
74 Service::HID::HIDInit();
75
76 AddService(new AC_U::Interface); 76 AddService(new AC_U::Interface);
77 AddService(new ACT_U::Interface); 77 AddService(new ACT_U::Interface);
78 AddService(new AM_APP::Interface); 78 AddService(new AM_APP::Interface);
79 AddService(new AM_NET::Interface); 79 AddService(new AM_NET::Interface);
80 AddService(new AM_SYS::Interface); 80 AddService(new AM_SYS::Interface);
81 AddService(new APT_A::Interface);
82 AddService(new APT_S::Interface);
83 AddService(new APT_U::Interface);
84 AddService(new BOSS_P::Interface); 81 AddService(new BOSS_P::Interface);
85 AddService(new BOSS_U::Interface); 82 AddService(new BOSS_U::Interface);
86 AddService(new CAM_U::Interface); 83 AddService(new CAM_U::Interface);
87 AddService(new CECD_S::Interface); 84 AddService(new CECD_S::Interface);
88 AddService(new CECD_U::Interface); 85 AddService(new CECD_U::Interface);
89 AddService(new CFG_I::Interface);
90 AddService(new CFG_S::Interface);
91 AddService(new CFG_U::Interface);
92 AddService(new CSND_SND::Interface); 86 AddService(new CSND_SND::Interface);
93 AddService(new DSP_DSP::Interface); 87 AddService(new DSP_DSP::Interface);
94 AddService(new FRD_A::Interface); 88 AddService(new FRD_A::Interface);
95 AddService(new FRD_U::Interface); 89 AddService(new FRD_U::Interface);
96 AddService(new FS::FSUserInterface);
97 AddService(new GSP_GPU::Interface); 90 AddService(new GSP_GPU::Interface);
98 AddService(new GSP_LCD::Interface); 91 AddService(new GSP_LCD::Interface);
99 AddService(new HID_User::Interface);
100 AddService(new HID_SPVR::Interface);
101 AddService(new HTTP_C::Interface); 92 AddService(new HTTP_C::Interface);
102 AddService(new IR_RST::Interface); 93 AddService(new IR_RST::Interface);
103 AddService(new IR_U::Interface); 94 AddService(new IR_U::Interface);
@@ -110,9 +101,6 @@ void Init() {
110 AddService(new NS_S::Interface); 101 AddService(new NS_S::Interface);
111 AddService(new NWM_UDS::Interface); 102 AddService(new NWM_UDS::Interface);
112 AddService(new PM_APP::Interface); 103 AddService(new PM_APP::Interface);
113 AddService(new PTM_PLAY::Interface);
114 AddService(new PTM_U::Interface);
115 AddService(new PTM_SYSM::Interface);
116 AddService(new SOC_U::Interface); 104 AddService(new SOC_U::Interface);
117 AddService(new SSL_C::Interface); 105 AddService(new SSL_C::Interface);
118 AddService(new Y2R_U::Interface); 106 AddService(new Y2R_U::Interface);
@@ -122,6 +110,12 @@ void Init() {
122 110
123/// Shutdown ServiceManager 111/// Shutdown ServiceManager
124void Shutdown() { 112void Shutdown() {
113 Service::HID::HIDShutdown();
114 Service::PTM::PTMShutdown();
115 Service::APT::APTShutdown();
116 Service::CFG::CFGShutdown();
117 Service::FS::ArchiveShutdown();
118
125 g_srv_services.clear(); 119 g_srv_services.clear();
126 g_kernel_named_ports.clear(); 120 g_kernel_named_ports.clear();
127 LOG_DEBUG(Service, "shutdown OK"); 121 LOG_DEBUG(Service, "shutdown OK");
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 3370f9f9b..bfe16ebad 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -120,4 +120,7 @@ extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_na
120/// Map of services registered with the "srv:" service, retrieved using GetServiceHandle. 120/// Map of services registered with the "srv:" service, retrieved using GetServiceHandle.
121extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services; 121extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services;
122 122
123/// Adds a service to the services table
124void AddService(Interface* interface_);
125
123} // namespace 126} // namespace