ptm.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // Copyright 2015 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include "common/logging/log.h"
  5. #include "core/file_sys/file_backend.h"
  6. #include "core/hle/service/fs/archive.h"
  7. #include "core/hle/service/ptm/ptm.h"
  8. #include "core/hle/service/ptm/ptm_gets.h"
  9. #include "core/hle/service/ptm/ptm_play.h"
  10. #include "core/hle/service/ptm/ptm_sets.h"
  11. #include "core/hle/service/ptm/ptm_sysm.h"
  12. #include "core/hle/service/ptm/ptm_u.h"
  13. #include "core/hle/service/service.h"
  14. #include "core/settings.h"
  15. namespace Service {
  16. namespace PTM {
  17. /// Values for the default gamecoin.dat file
  18. static const GameCoin default_game_coin = {0x4F00, 42, 0, 0, 0, 2014, 12, 29};
  19. /// Id of the SharedExtData archive used by the PTM process
  20. static const std::vector<u8> ptm_shared_extdata_id = {0, 0, 0, 0, 0x0B, 0, 0, 0xF0, 0, 0, 0, 0};
  21. static bool shell_open;
  22. static bool battery_is_charging;
  23. static bool pedometer_is_counting;
  24. void GetAdapterState(Service::Interface* self) {
  25. IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x5, 0, 0);
  26. IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
  27. rb.Push(RESULT_SUCCESS);
  28. rb.Push(battery_is_charging);
  29. LOG_WARNING(Service_PTM, "(STUBBED) called");
  30. }
  31. void GetShellState(Service::Interface* self) {
  32. IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x6, 0, 0);
  33. IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
  34. rb.Push(RESULT_SUCCESS);
  35. rb.Push(shell_open);
  36. }
  37. void GetBatteryLevel(Service::Interface* self) {
  38. IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x7, 0, 0);
  39. IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
  40. rb.Push(RESULT_SUCCESS);
  41. rb.Push(static_cast<u32>(ChargeLevels::CompletelyFull)); // Set to a completely full battery
  42. LOG_WARNING(Service_PTM, "(STUBBED) called");
  43. }
  44. void GetBatteryChargeState(Service::Interface* self) {
  45. IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x8, 0, 0);
  46. IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
  47. rb.Push(RESULT_SUCCESS);
  48. rb.Push(battery_is_charging);
  49. LOG_WARNING(Service_PTM, "(STUBBED) called");
  50. }
  51. void GetPedometerState(Service::Interface* self) {
  52. IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x9, 0, 0);
  53. IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
  54. rb.Push(RESULT_SUCCESS);
  55. rb.Push(pedometer_is_counting);
  56. LOG_WARNING(Service_PTM, "(STUBBED) called");
  57. }
  58. void GetTotalStepCount(Service::Interface* self) {
  59. IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0xC, 0, 0);
  60. IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
  61. rb.Push(RESULT_SUCCESS);
  62. rb.Push<u32>(0);
  63. LOG_WARNING(Service_PTM, "(STUBBED) called");
  64. }
  65. void GetSoftwareClosedFlag(Service::Interface* self) {
  66. IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x80F, 0, 0);
  67. IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
  68. rb.Push(RESULT_SUCCESS);
  69. rb.Push(false);
  70. LOG_WARNING(Service_PTM, "(STUBBED) called");
  71. }
  72. void CheckNew3DS(IPC::RequestBuilder& rb) {
  73. const bool is_new_3ds = Settings::values.is_new_3ds;
  74. if (is_new_3ds) {
  75. LOG_CRITICAL(Service_PTM, "The option 'is_new_3ds' is enabled as part of the 'System' "
  76. "settings. Citra does not fully support New 3DS emulation yet!");
  77. }
  78. rb.Push(RESULT_SUCCESS);
  79. rb.Push(is_new_3ds);
  80. LOG_WARNING(Service_PTM, "(STUBBED) called isNew3DS = 0x%08x", static_cast<u32>(is_new_3ds));
  81. }
  82. void CheckNew3DS(Service::Interface* self) {
  83. IPC::RequestBuilder rb(Kernel::GetCommandBuffer(), 0x40A, 0, 0); // 0x040A0000
  84. CheckNew3DS(rb);
  85. }
  86. void Init() {
  87. AddService(new PTM_Gets);
  88. AddService(new PTM_Play);
  89. AddService(new PTM_S);
  90. AddService(new PTM_Sets);
  91. AddService(new PTM_Sysm);
  92. AddService(new PTM_U);
  93. shell_open = true;
  94. battery_is_charging = true;
  95. pedometer_is_counting = false;
  96. // Open the SharedExtSaveData archive 0xF000000B and create the gamecoin.dat file if it doesn't
  97. // exist
  98. FileSys::Path archive_path(ptm_shared_extdata_id);
  99. auto archive_result =
  100. Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
  101. // If the archive didn't exist, create the files inside
  102. if (archive_result.Code().description == ErrorDescription::FS_NotFormatted) {
  103. // Format the archive to create the directories
  104. Service::FS::FormatArchive(Service::FS::ArchiveIdCode::SharedExtSaveData,
  105. FileSys::ArchiveFormatInfo(), archive_path);
  106. // Open it again to get a valid archive now that the folder exists
  107. archive_result =
  108. Service::FS::OpenArchive(Service::FS::ArchiveIdCode::SharedExtSaveData, archive_path);
  109. ASSERT_MSG(archive_result.Succeeded(), "Could not open the PTM SharedExtSaveData archive!");
  110. FileSys::Path gamecoin_path("/gamecoin.dat");
  111. Service::FS::CreateFileInArchive(*archive_result, gamecoin_path, sizeof(GameCoin));
  112. FileSys::Mode open_mode = {};
  113. open_mode.write_flag.Assign(1);
  114. // Open the file and write the default gamecoin information
  115. auto gamecoin_result =
  116. Service::FS::OpenFileFromArchive(*archive_result, gamecoin_path, open_mode);
  117. if (gamecoin_result.Succeeded()) {
  118. auto gamecoin = gamecoin_result.MoveFrom();
  119. gamecoin->backend->Write(0, sizeof(GameCoin), true,
  120. reinterpret_cast<const u8*>(&default_game_coin));
  121. gamecoin->backend->Close();
  122. }
  123. }
  124. }
  125. void Shutdown() {}
  126. } // namespace PTM
  127. } // namespace Service