summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2015-03-04 21:27:24 -0500
committerGravatar bunnei2015-03-04 21:27:24 -0500
commit8e4e28aacb38b4f80c3ae80167841f4e451f6ef5 (patch)
treecd4efbdfb0e01e9e2b424f17339f11873c90485c /src
parentMerge pull request #625 from lioncash/warn (diff)
parentServices: Moved the PTM and APT services to their own folder (diff)
downloadyuzu-8e4e28aacb38b4f80c3ae80167841f4e451f6ef5.tar.gz
yuzu-8e4e28aacb38b4f80c3ae80167841f4e451f6ef5.tar.xz
yuzu-8e4e28aacb38b4f80c3ae80167841f4e451f6ef5.zip
Merge pull request #615 from Subv/services
Services: Moved the PTM and APT services to their own folder
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