apt_u.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "common/common.h"
  5. #include "common/file_util.h"
  6. #include "core/hle/hle.h"
  7. #include "core/hle/kernel/event.h"
  8. #include "core/hle/kernel/mutex.h"
  9. #include "core/hle/kernel/shared_memory.h"
  10. #include "core/hle/kernel/thread.h"
  11. #include "core/hle/service/apt_u.h"
  12. ////////////////////////////////////////////////////////////////////////////////////////////////////
  13. // Namespace APT_U
  14. namespace APT_U {
  15. // Address used for shared font (as observed on HW)
  16. // TODO(bunnei): This is the hard-coded address where we currently dump the shared font from via
  17. // https://github.com/citra-emu/3dsutils. This is technically a hack, and will not work at any
  18. // address other than 0x18000000 due to internal pointers in the shared font dump that would need to
  19. // be relocated. This might be fixed by dumping the shared font @ address 0x00000000 and then
  20. // correctly mapping it in Citra, however we still do not understand how the mapping is determined.
  21. static const VAddr SHARED_FONT_VADDR = 0x18000000;
  22. /// Handle to shared memory region designated to for shared system font
  23. static Kernel::SharedPtr<Kernel::SharedMemory> shared_font_mem;
  24. static Kernel::SharedPtr<Kernel::Mutex> lock;
  25. static Kernel::SharedPtr<Kernel::Event> notification_event; ///< APT notification event
  26. static Kernel::SharedPtr<Kernel::Event> pause_event = 0; ///< APT pause event
  27. static std::vector<u8> shared_font;
  28. /// Signals used by APT functions
  29. enum class SignalType : u32 {
  30. None = 0x0,
  31. AppJustStarted = 0x1,
  32. ReturningToApp = 0xB,
  33. ExitingApp = 0xC,
  34. };
  35. /// App Id's used by APT functions
  36. enum class AppID : u32 {
  37. HomeMenu = 0x101,
  38. AlternateMenu = 0x103,
  39. Camera = 0x110,
  40. FriendsList = 0x112,
  41. GameNotes = 0x113,
  42. InternetBrowser = 0x114,
  43. InstructionManual = 0x115,
  44. Notifications = 0x116,
  45. Miiverse = 0x117,
  46. SoftwareKeyboard1 = 0x201,
  47. Ed = 0x202,
  48. PnoteApp = 0x204,
  49. SnoteApp = 0x205,
  50. Error = 0x206,
  51. Mint = 0x207,
  52. Extrapad = 0x208,
  53. Memolib = 0x209,
  54. Application = 0x300,
  55. SoftwareKeyboard2 = 0x401,
  56. };
  57. void Initialize(Service::Interface* self) {
  58. u32* cmd_buff = Kernel::GetCommandBuffer();
  59. // TODO(bunnei): Check if these are created in Initialize or on APT process startup.
  60. notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification").MoveFrom();
  61. pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause").MoveFrom();
  62. cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom();
  63. cmd_buff[4] = Kernel::g_handle_table.Create(pause_event).MoveFrom();
  64. // TODO(bunnei): Check if these events are cleared/signaled every time Initialize is called.
  65. notification_event->Clear();
  66. pause_event->Signal(); // Fire start event
  67. _assert_msg_(KERNEL, (nullptr != lock), "Cannot initialize without lock");
  68. lock->Release();
  69. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  70. }
  71. /**
  72. * APT_U::NotifyToWait service function
  73. * Inputs:
  74. * 1 : AppID
  75. * Outputs:
  76. * 1 : Result of function, 0 on success, otherwise error code
  77. */
  78. void NotifyToWait(Service::Interface* self) {
  79. u32* cmd_buff = Kernel::GetCommandBuffer();
  80. u32 app_id = cmd_buff[1];
  81. // TODO(Subv): Verify this, it seems to get SWKBD and Home Menu further.
  82. pause_event->Signal();
  83. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  84. LOG_WARNING(Service_APT, "(STUBBED) app_id=%u", app_id);
  85. }
  86. void GetLockHandle(Service::Interface* self) {
  87. u32* cmd_buff = Kernel::GetCommandBuffer();
  88. u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
  89. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  90. // Not sure what these parameters are used for, but retail apps check that they are 0 after
  91. // GetLockHandle has been called.
  92. cmd_buff[2] = 0;
  93. cmd_buff[3] = 0;
  94. cmd_buff[4] = 0;
  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. void Enable(Service::Interface* self) {
  99. u32* cmd_buff = Kernel::GetCommandBuffer();
  100. u32 unk = cmd_buff[1]; // TODO(bunnei): What is this field used for?
  101. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  102. LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
  103. }
  104. /**
  105. * APT_U::GetAppletManInfo service function.
  106. * Inputs:
  107. * 1 : Unknown
  108. * Outputs:
  109. * 1 : Result of function, 0 on success, otherwise error code
  110. * 2 : Unknown u32 value
  111. * 3 : Unknown u8 value
  112. * 4 : Home Menu AppId
  113. * 5 : AppID of currently active app
  114. */
  115. void GetAppletManInfo(Service::Interface* self) {
  116. u32* cmd_buff = Kernel::GetCommandBuffer();
  117. u32 unk = cmd_buff[1];
  118. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  119. cmd_buff[2] = 0;
  120. cmd_buff[3] = 0;
  121. cmd_buff[4] = static_cast<u32>(AppID::HomeMenu); // Home menu AppID
  122. cmd_buff[5] = static_cast<u32>(AppID::Application); // TODO(purpasmart96): Do this correctly
  123. LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X", unk);
  124. }
  125. /**
  126. * APT_U::IsRegistered service function. This returns whether the specified AppID is registered with NS yet.
  127. * An AppID is "registered" once the process associated with the AppID uses APT:Enable. Home Menu uses this
  128. * command to determine when the launched process is running and to determine when to stop using GSP etc,
  129. * while displaying the "Nintendo 3DS" loading screen.
  130. * Inputs:
  131. * 1 : AppID
  132. * Outputs:
  133. * 0 : Return header
  134. * 1 : Result of function, 0 on success, otherwise error code
  135. * 2 : Output, 0 = not registered, 1 = registered.
  136. */
  137. void IsRegistered(Service::Interface* self) {
  138. u32* cmd_buff = Kernel::GetCommandBuffer();
  139. u32 app_id = cmd_buff[1];
  140. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  141. cmd_buff[2] = 1; // Set to registered
  142. LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
  143. }
  144. void InquireNotification(Service::Interface* self) {
  145. u32* cmd_buff = Kernel::GetCommandBuffer();
  146. u32 app_id = cmd_buff[1];
  147. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  148. cmd_buff[2] = static_cast<u32>(SignalType::None); // Signal type
  149. LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X", app_id);
  150. }
  151. /**
  152. * APT_U::SendParameter service function. This sets the parameter data state.
  153. * Inputs:
  154. * 1 : Source AppID
  155. * 2 : Destination AppID
  156. * 3 : Signal type
  157. * 4 : Parameter buffer size, max size is 0x1000 (this can be zero)
  158. * 5 : Value
  159. * 6 : Handle to the destination process, likely used for shared memory (this can be zero)
  160. * 7 : (Size<<14) | 2
  161. * 8 : Input parameter buffer ptr
  162. * Outputs:
  163. * 0 : Return Header
  164. * 1 : Result of function, 0 on success, otherwise error code
  165. */
  166. void SendParameter(Service::Interface* self) {
  167. u32* cmd_buff = Kernel::GetCommandBuffer();
  168. u32 src_app_id = cmd_buff[1];
  169. u32 dst_app_id = cmd_buff[2];
  170. u32 signal_type = cmd_buff[3];
  171. u32 buffer_size = cmd_buff[4];
  172. u32 value = cmd_buff[5];
  173. u32 handle = cmd_buff[6];
  174. u32 size = cmd_buff[7];
  175. u32 in_param_buffer_ptr = cmd_buff[8];
  176. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  177. LOG_WARNING(Service_APT, "(STUBBED) called src_app_id=0x%08X, dst_app_id=0x%08X, signal_type=0x%08X,"
  178. "buffer_size=0x%08X, value=0x%08X, handle=0x%08X, size=0x%08X, in_param_buffer_ptr=0x%08X",
  179. src_app_id, dst_app_id, signal_type, buffer_size, value, handle, size, in_param_buffer_ptr);
  180. }
  181. /**
  182. * APT_U::ReceiveParameter service function. This returns the current parameter data from NS state,
  183. * from the source process which set the parameters. Once finished, NS will clear a flag in the NS
  184. * state so that this command will return an error if this command is used again if parameters were
  185. * not set again. This is called when the second Initialize event is triggered. It returns a signal
  186. * type indicating why it was triggered.
  187. * Inputs:
  188. * 1 : AppID
  189. * 2 : Parameter buffer size, max size is 0x1000
  190. * Outputs:
  191. * 1 : Result of function, 0 on success, otherwise error code
  192. * 2 : AppID of the process which sent these parameters
  193. * 3 : Signal type
  194. * 4 : Actual parameter buffer size, this is <= to the the input size
  195. * 5 : Value
  196. * 6 : Handle from the source process which set the parameters, likely used for shared memory
  197. * 7 : Size
  198. * 8 : Output parameter buffer ptr
  199. */
  200. void ReceiveParameter(Service::Interface* self) {
  201. u32* cmd_buff = Kernel::GetCommandBuffer();
  202. u32 app_id = cmd_buff[1];
  203. u32 buffer_size = cmd_buff[2];
  204. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  205. cmd_buff[2] = 0;
  206. cmd_buff[3] = static_cast<u32>(SignalType::AppJustStarted); // Signal type
  207. cmd_buff[4] = 0x10; // Parameter buffer size (16)
  208. cmd_buff[5] = 0;
  209. cmd_buff[6] = 0;
  210. cmd_buff[7] = 0;
  211. LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
  212. }
  213. /**
  214. * APT_U::GlanceParameter service function. This is exactly the same as APT_U::ReceiveParameter
  215. * (except for the word value prior to the output handle), except this will not clear the flag
  216. * (except when responseword[3]==8 || responseword[3]==9) in NS state.
  217. * Inputs:
  218. * 1 : AppID
  219. * 2 : Parameter buffer size, max size is 0x1000
  220. * Outputs:
  221. * 1 : Result of function, 0 on success, otherwise error code
  222. * 2 : Unknown, for now assume AppID of the process which sent these parameters
  223. * 3 : Unknown, for now assume Signal type
  224. * 4 : Actual parameter buffer size, this is <= to the the input size
  225. * 5 : Value
  226. * 6 : Handle from the source process which set the parameters, likely used for shared memory
  227. * 7 : Size
  228. * 8 : Output parameter buffer ptr
  229. */
  230. void GlanceParameter(Service::Interface* self) {
  231. u32* cmd_buff = Kernel::GetCommandBuffer();
  232. u32 app_id = cmd_buff[1];
  233. u32 buffer_size = cmd_buff[2];
  234. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  235. cmd_buff[2] = 0;
  236. cmd_buff[3] = static_cast<u32>(SignalType::AppJustStarted); // Signal type
  237. cmd_buff[4] = 0x10; // Parameter buffer size (16)
  238. cmd_buff[5] = 0;
  239. cmd_buff[6] = 0;
  240. cmd_buff[7] = 0;
  241. LOG_WARNING(Service_APT, "(STUBBED) called app_id=0x%08X, buffer_size=0x%08X", app_id, buffer_size);
  242. }
  243. /**
  244. * APT_U::CancelParameter service function. When the parameter data is available, and when the above
  245. * specified fields match the ones in NS state(for the ones where the checks are enabled), this
  246. * clears the flag which indicates that parameter data is available
  247. * (same flag cleared by APT:ReceiveParameter).
  248. * Inputs:
  249. * 1 : Flag, when non-zero NS will compare the word after this one with a field in the NS state.
  250. * 2 : Unknown, this is the same as the first unknown field returned by APT:ReceiveParameter.
  251. * 3 : Flag, when non-zero NS will compare the word after this one with a field in the NS state.
  252. * 4 : AppID
  253. * Outputs:
  254. * 0 : Return header
  255. * 1 : Result of function, 0 on success, otherwise error code
  256. * 2 : Status flag, 0 = failure due to no parameter data being available, or the above enabled
  257. * fields don't match the fields in NS state. 1 = success.
  258. */
  259. void CancelParameter(Service::Interface* self) {
  260. u32* cmd_buff = Kernel::GetCommandBuffer();
  261. u32 flag1 = cmd_buff[1];
  262. u32 unk = cmd_buff[2];
  263. u32 flag2 = cmd_buff[3];
  264. u32 app_id = cmd_buff[4];
  265. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  266. cmd_buff[2] = 1; // Set to Success
  267. LOG_WARNING(Service_APT, "(STUBBED) called flag1=0x%08X, unk=0x%08X, flag2=0x%08X, app_id=0x%08X",
  268. flag1, unk, flag2, app_id);
  269. }
  270. /**
  271. * APT_U::AppletUtility service function
  272. * Inputs:
  273. * 1 : Unknown, but clearly used for something
  274. * 2 : Buffer 1 size (purpose is unknown)
  275. * 3 : Buffer 2 size (purpose is unknown)
  276. * 5 : Buffer 1 address (purpose is unknown)
  277. * 65 : Buffer 2 address (purpose is unknown)
  278. * Outputs:
  279. * 1 : Result of function, 0 on success, otherwise error code
  280. */
  281. void AppletUtility(Service::Interface* self) {
  282. u32* cmd_buff = Kernel::GetCommandBuffer();
  283. // These are from 3dbrew - I'm not really sure what they're used for.
  284. u32 unk = cmd_buff[1];
  285. u32 buffer1_size = cmd_buff[2];
  286. u32 buffer2_size = cmd_buff[3];
  287. u32 buffer1_addr = cmd_buff[5];
  288. u32 buffer2_addr = cmd_buff[65];
  289. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  290. LOG_WARNING(Service_APT, "(STUBBED) called unk=0x%08X, buffer1_size=0x%08x, buffer2_size=0x%08x, "
  291. "buffer1_addr=0x%08x, buffer2_addr=0x%08x", unk, buffer1_size, buffer2_size,
  292. buffer1_addr, buffer2_addr);
  293. }
  294. /**
  295. * APT_U::GetSharedFont service function
  296. * Outputs:
  297. * 1 : Result of function, 0 on success, otherwise error code
  298. * 2 : Virtual address of where shared font will be loaded in memory
  299. * 4 : Handle to shared font memory
  300. */
  301. void GetSharedFont(Service::Interface* self) {
  302. u32* cmd_buff = Kernel::GetCommandBuffer();
  303. if (!shared_font.empty()) {
  304. // TODO(bunnei): This function shouldn't copy the shared font every time it's called.
  305. // Instead, it should probably map the shared font as RO memory. We don't currently have
  306. // an easy way to do this, but the copy should be sufficient for now.
  307. memcpy(Memory::GetPointer(SHARED_FONT_VADDR), shared_font.data(), shared_font.size());
  308. cmd_buff[0] = 0x00440082;
  309. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  310. cmd_buff[2] = SHARED_FONT_VADDR;
  311. cmd_buff[4] = Kernel::g_handle_table.Create(shared_font_mem).MoveFrom();
  312. } else {
  313. cmd_buff[1] = -1; // Generic error (not really possible to verify this on hardware)
  314. LOG_ERROR(Kernel_SVC, "called, but %s has not been loaded!", SHARED_FONT);
  315. }
  316. }
  317. /**
  318. * APT_U::SetAppCpuTimeLimit service function
  319. * Inputs:
  320. * 1 : Value, must be one
  321. * 2 : Percentage of CPU time from 5 to 80
  322. * Outputs:
  323. * 1 : Result of function, 0 on success, otherwise error code
  324. */
  325. void SetAppCpuTimeLimit(Service::Interface* self) {
  326. u32* cmd_buff = Kernel::GetCommandBuffer();
  327. u32 value = cmd_buff[1];
  328. u32 percent = cmd_buff[2];
  329. if (value != 1) {
  330. LOG_ERROR(Service_APT, "This value must be one!", value);
  331. }
  332. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  333. LOG_WARNING(Service_APT, "(STUBBED) called percent=0x%08X, value=0x%08x", percent, value);
  334. }
  335. /**
  336. * APT_U::GetAppCpuTimeLimit service function
  337. * Inputs:
  338. * 1 : Value, must be one
  339. * Outputs:
  340. * 0 : Return header
  341. * 1 : Result of function, 0 on success, otherwise error code
  342. * 2 : System core CPU time percentage
  343. */
  344. void GetAppCpuTimeLimit(Service::Interface* self) {
  345. u32* cmd_buff = Kernel::GetCommandBuffer();
  346. u32 value = cmd_buff[1];
  347. if (value != 1) {
  348. LOG_ERROR(Service_APT, "This value must be one!", value);
  349. }
  350. // TODO(purpasmart96): This is incorrect, I'm pretty sure the percentage should
  351. // be set by the application.
  352. cmd_buff[1] = RESULT_SUCCESS.raw; // No error
  353. cmd_buff[2] = 0x80; // Set to 80%
  354. LOG_WARNING(Service_APT, "(STUBBED) called value=0x%08x", value);
  355. }
  356. const Interface::FunctionInfo FunctionTable[] = {
  357. {0x00010040, GetLockHandle, "GetLockHandle"},
  358. {0x00020080, Initialize, "Initialize"},
  359. {0x00030040, Enable, "Enable"},
  360. {0x00040040, nullptr, "Finalize"},
  361. {0x00050040, GetAppletManInfo, "GetAppletManInfo"},
  362. {0x00060040, nullptr, "GetAppletInfo"},
  363. {0x00070000, nullptr, "GetLastSignaledAppletId"},
  364. {0x00080000, nullptr, "CountRegisteredApplet"},
  365. {0x00090040, IsRegistered, "IsRegistered"},
  366. {0x000A0040, nullptr, "GetAttribute"},
  367. {0x000B0040, InquireNotification, "InquireNotification"},
  368. {0x000C0104, SendParameter, "SendParameter"},
  369. {0x000D0080, ReceiveParameter, "ReceiveParameter"},
  370. {0x000E0080, GlanceParameter, "GlanceParameter"},
  371. {0x000F0100, CancelParameter, "CancelParameter"},
  372. {0x001000C2, nullptr, "DebugFunc"},
  373. {0x001100C0, nullptr, "MapProgramIdForDebug"},
  374. {0x00120040, nullptr, "SetHomeMenuAppletIdForDebug"},
  375. {0x00130000, nullptr, "GetPreparationState"},
  376. {0x00140040, nullptr, "SetPreparationState"},
  377. {0x00150140, nullptr, "PrepareToStartApplication"},
  378. {0x00160040, nullptr, "PreloadLibraryApplet"},
  379. {0x00170040, nullptr, "FinishPreloadingLibraryApplet"},
  380. {0x00180040, nullptr, "PrepareToStartLibraryApplet"},
  381. {0x00190040, nullptr, "PrepareToStartSystemApplet"},
  382. {0x001A0000, nullptr, "PrepareToStartNewestHomeMenu"},
  383. {0x001B00C4, nullptr, "StartApplication"},
  384. {0x001C0000, nullptr, "WakeupApplication"},
  385. {0x001D0000, nullptr, "CancelApplication"},
  386. {0x001E0084, nullptr, "StartLibraryApplet"},
  387. {0x001F0084, nullptr, "StartSystemApplet"},
  388. {0x00200044, nullptr, "StartNewestHomeMenu"},
  389. {0x00210000, nullptr, "OrderToCloseApplication"},
  390. {0x00220040, nullptr, "PrepareToCloseApplication"},
  391. {0x00230040, nullptr, "PrepareToJumpToApplication"},
  392. {0x00240044, nullptr, "JumpToApplication"},
  393. {0x002500C0, nullptr, "PrepareToCloseLibraryApplet"},
  394. {0x00260000, nullptr, "PrepareToCloseSystemApplet"},
  395. {0x00270044, nullptr, "CloseApplication"},
  396. {0x00280044, nullptr, "CloseLibraryApplet"},
  397. {0x00290044, nullptr, "CloseSystemApplet"},
  398. {0x002A0000, nullptr, "OrderToCloseSystemApplet"},
  399. {0x002B0000, nullptr, "PrepareToJumpToHomeMenu"},
  400. {0x002C0044, nullptr, "JumpToHomeMenu"},
  401. {0x002D0000, nullptr, "PrepareToLeaveHomeMenu"},
  402. {0x002E0044, nullptr, "LeaveHomeMenu"},
  403. {0x002F0040, nullptr, "PrepareToLeaveResidentApplet"},
  404. {0x00300044, nullptr, "LeaveResidentApplet"},
  405. {0x00310100, nullptr, "PrepareToDoApplicationJump"},
  406. {0x00320084, nullptr, "DoApplicationJump"},
  407. {0x00330000, nullptr, "GetProgramIdOnApplicationJump"},
  408. {0x00340084, nullptr, "SendDeliverArg"},
  409. {0x00350080, nullptr, "ReceiveDeliverArg"},
  410. {0x00360040, nullptr, "LoadSysMenuArg"},
  411. {0x00370042, nullptr, "StoreSysMenuArg"},
  412. {0x00380040, nullptr, "PreloadResidentApplet"},
  413. {0x00390040, nullptr, "PrepareToStartResidentApplet"},
  414. {0x003A0044, nullptr, "StartResidentApplet"},
  415. {0x003B0040, nullptr, "CancelLibraryApplet"},
  416. {0x003C0042, nullptr, "SendDspSleep"},
  417. {0x003D0042, nullptr, "SendDspWakeUp"},
  418. {0x003E0080, nullptr, "ReplySleepQuery"},
  419. {0x003F0040, nullptr, "ReplySleepNotificationComplete"},
  420. {0x00400042, nullptr, "SendCaptureBufferInfo"},
  421. {0x00410040, nullptr, "ReceiveCaptureBufferInfo"},
  422. {0x00420080, nullptr, "SleepSystem"},
  423. {0x00430040, NotifyToWait, "NotifyToWait"},
  424. {0x00440000, GetSharedFont, "GetSharedFont"},
  425. {0x00450040, nullptr, "GetWirelessRebootInfo"},
  426. {0x00460104, nullptr, "Wrap"},
  427. {0x00470104, nullptr, "Unwrap"},
  428. {0x00480100, nullptr, "GetProgramInfo"},
  429. {0x00490180, nullptr, "Reboot"},
  430. {0x004A0040, nullptr, "GetCaptureInfo"},
  431. {0x004B00C2, AppletUtility, "AppletUtility"},
  432. {0x004C0000, nullptr, "SetFatalErrDispMode"},
  433. {0x004D0080, nullptr, "GetAppletProgramInfo"},
  434. {0x004E0000, nullptr, "HardwareResetAsync"},
  435. {0x004F0080, SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
  436. {0x00500040, GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},
  437. };
  438. ////////////////////////////////////////////////////////////////////////////////////////////////////
  439. // Interface class
  440. Interface::Interface() {
  441. // Load the shared system font (if available).
  442. // The expected format is a decrypted, uncompressed BCFNT file with the 0x80 byte header
  443. // generated by the APT:U service. The best way to get is by dumping it from RAM. We've provided
  444. // a homebrew app to do this: https://github.com/citra-emu/3dsutils. Put the resulting file
  445. // "shared_font.bin" in the Citra "sysdata" directory.
  446. shared_font.clear();
  447. std::string filepath = FileUtil::GetUserPath(D_SYSDATA_IDX) + SHARED_FONT;
  448. FileUtil::CreateFullPath(filepath); // Create path if not already created
  449. FileUtil::IOFile file(filepath, "rb");
  450. if (file.IsOpen()) {
  451. // Read shared font data
  452. shared_font.resize((size_t)file.GetSize());
  453. file.ReadBytes(shared_font.data(), (size_t)file.GetSize());
  454. // Create shared font memory object
  455. shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem").MoveFrom();
  456. } else {
  457. LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str());
  458. shared_font_mem = nullptr;
  459. }
  460. lock = Kernel::Mutex::Create(false, "APT_U:Lock").MoveFrom();
  461. Register(FunctionTable, ARRAY_SIZE(FunctionTable));
  462. }
  463. } // namespace