diff options
| -rw-r--r-- | CMakeLists.txt | 9 | ||||
| -rw-r--r-- | src/citra_qt/main.cpp | 2 | ||||
| -rw-r--r-- | src/common/scm_rev.cpp.in | 2 | ||||
| -rw-r--r-- | src/common/scm_rev.h | 1 | ||||
| -rw-r--r-- | src/core/core.h | 9 | ||||
| -rw-r--r-- | src/core/file_sys/archive_sdmc.cpp | 41 | ||||
| -rw-r--r-- | src/core/file_sys/savedata_archive.cpp | 41 | ||||
| -rw-r--r-- | src/core/hle/service/apt/apt.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/service/dlp/dlp_clnt.cpp | 21 | ||||
| -rw-r--r-- | src/core/hle/service/dlp/dlp_fkcl.cpp | 18 | ||||
| -rw-r--r-- | src/core/hle/service/dlp/dlp_srvr.cpp | 9 | ||||
| -rw-r--r-- | src/core/loader/loader.h | 9 | ||||
| -rw-r--r-- | src/core/loader/ncch.cpp | 20 | ||||
| -rw-r--r-- | src/core/loader/ncch.h | 14 | ||||
| -rw-r--r-- | src/core/telemetry_session.cpp | 17 |
15 files changed, 191 insertions, 26 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 79d8046d9..ddba04ef9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
| @@ -295,11 +295,18 @@ function(create_directory_groups) | |||
| 295 | endforeach() | 295 | endforeach() |
| 296 | endfunction() | 296 | endfunction() |
| 297 | 297 | ||
| 298 | # generate git revision information | 298 | # Gets a UTC timstamp and sets the provided variable to it |
| 299 | function(get_timestamp _var) | ||
| 300 | string(TIMESTAMP timestamp UTC) | ||
| 301 | set(${_var} "${timestamp}" PARENT_SCOPE) | ||
| 302 | endfunction() | ||
| 303 | |||
| 304 | # generate git/build information | ||
| 299 | include(GetGitRevisionDescription) | 305 | include(GetGitRevisionDescription) |
| 300 | get_git_head_revision(GIT_REF_SPEC GIT_REV) | 306 | get_git_head_revision(GIT_REF_SPEC GIT_REV) |
| 301 | git_describe(GIT_DESC --always --long --dirty) | 307 | git_describe(GIT_DESC --always --long --dirty) |
| 302 | git_branch_name(GIT_BRANCH) | 308 | git_branch_name(GIT_BRANCH) |
| 309 | get_timestamp(BUILD_DATE) | ||
| 303 | 310 | ||
| 304 | enable_testing() | 311 | enable_testing() |
| 305 | add_subdirectory(externals) | 312 | add_subdirectory(externals) |
diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp index 02bfdca3d..c1ae0ccc8 100644 --- a/src/citra_qt/main.cpp +++ b/src/citra_qt/main.cpp | |||
| @@ -311,7 +311,7 @@ bool GMainWindow::LoadROM(const QString& filename) { | |||
| 311 | 311 | ||
| 312 | if (!gladLoadGL()) { | 312 | if (!gladLoadGL()) { |
| 313 | QMessageBox::critical(this, tr("Error while initializing OpenGL 3.3 Core!"), | 313 | QMessageBox::critical(this, tr("Error while initializing OpenGL 3.3 Core!"), |
| 314 | tr("Your GPU may not support OpenGL 3.3, or you do not" | 314 | tr("Your GPU may not support OpenGL 3.3, or you do not " |
| 315 | "have the latest graphics driver.")); | 315 | "have the latest graphics driver.")); |
| 316 | return false; | 316 | return false; |
| 317 | } | 317 | } |
diff --git a/src/common/scm_rev.cpp.in b/src/common/scm_rev.cpp.in index 0080db5d5..4083095d5 100644 --- a/src/common/scm_rev.cpp.in +++ b/src/common/scm_rev.cpp.in | |||
| @@ -8,6 +8,7 @@ | |||
| 8 | #define GIT_BRANCH "@GIT_BRANCH@" | 8 | #define GIT_BRANCH "@GIT_BRANCH@" |
| 9 | #define GIT_DESC "@GIT_DESC@" | 9 | #define GIT_DESC "@GIT_DESC@" |
| 10 | #define BUILD_NAME "@REPO_NAME@" | 10 | #define BUILD_NAME "@REPO_NAME@" |
| 11 | #define BUILD_DATE "@BUILD_DATE@" | ||
| 11 | 12 | ||
| 12 | namespace Common { | 13 | namespace Common { |
| 13 | 14 | ||
| @@ -15,6 +16,7 @@ const char g_scm_rev[] = GIT_REV; | |||
| 15 | const char g_scm_branch[] = GIT_BRANCH; | 16 | const char g_scm_branch[] = GIT_BRANCH; |
| 16 | const char g_scm_desc[] = GIT_DESC; | 17 | const char g_scm_desc[] = GIT_DESC; |
| 17 | const char g_build_name[] = BUILD_NAME; | 18 | const char g_build_name[] = BUILD_NAME; |
| 19 | const char g_build_date[] = BUILD_DATE; | ||
| 18 | 20 | ||
| 19 | } // namespace | 21 | } // namespace |
| 20 | 22 | ||
diff --git a/src/common/scm_rev.h b/src/common/scm_rev.h index e22389803..18aaa1735 100644 --- a/src/common/scm_rev.h +++ b/src/common/scm_rev.h | |||
| @@ -10,5 +10,6 @@ extern const char g_scm_rev[]; | |||
| 10 | extern const char g_scm_branch[]; | 10 | extern const char g_scm_branch[]; |
| 11 | extern const char g_scm_desc[]; | 11 | extern const char g_scm_desc[]; |
| 12 | extern const char g_build_name[]; | 12 | extern const char g_build_name[]; |
| 13 | extern const char g_build_date[]; | ||
| 13 | 14 | ||
| 14 | } // namespace | 15 | } // namespace |
diff --git a/src/core/core.h b/src/core/core.h index 4e3b6b409..9805cc694 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | #include "common/common_types.h" | 9 | #include "common/common_types.h" |
| 10 | #include "core/loader/loader.h" | ||
| 10 | #include "core/memory.h" | 11 | #include "core/memory.h" |
| 11 | #include "core/perf_stats.h" | 12 | #include "core/perf_stats.h" |
| 12 | #include "core/telemetry_session.h" | 13 | #include "core/telemetry_session.h" |
| @@ -14,10 +15,6 @@ | |||
| 14 | class EmuWindow; | 15 | class EmuWindow; |
| 15 | class ARM_Interface; | 16 | class ARM_Interface; |
| 16 | 17 | ||
| 17 | namespace Loader { | ||
| 18 | class AppLoader; | ||
| 19 | } | ||
| 20 | |||
| 21 | namespace Core { | 18 | namespace Core { |
| 22 | 19 | ||
| 23 | class System { | 20 | class System { |
| @@ -119,6 +116,10 @@ public: | |||
| 119 | return status_details; | 116 | return status_details; |
| 120 | } | 117 | } |
| 121 | 118 | ||
| 119 | Loader::AppLoader& GetAppLoader() const { | ||
| 120 | return *app_loader; | ||
| 121 | } | ||
| 122 | |||
| 122 | private: | 123 | private: |
| 123 | /** | 124 | /** |
| 124 | * Initialize the emulated system. | 125 | * Initialize the emulated system. |
diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp index 679909d06..fe3dce5d4 100644 --- a/src/core/file_sys/archive_sdmc.cpp +++ b/src/core/file_sys/archive_sdmc.cpp | |||
| @@ -121,7 +121,25 @@ ResultCode SDMCArchive::DeleteFile(const Path& path) const { | |||
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | ResultCode SDMCArchive::RenameFile(const Path& src_path, const Path& dest_path) const { | 123 | ResultCode SDMCArchive::RenameFile(const Path& src_path, const Path& dest_path) const { |
| 124 | if (FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString())) { | 124 | const PathParser path_parser_src(src_path); |
| 125 | |||
| 126 | // TODO: Verify these return codes with HW | ||
| 127 | if (!path_parser_src.IsValid()) { | ||
| 128 | LOG_ERROR(Service_FS, "Invalid src path %s", src_path.DebugStr().c_str()); | ||
| 129 | return ERROR_INVALID_PATH; | ||
| 130 | } | ||
| 131 | |||
| 132 | const PathParser path_parser_dest(dest_path); | ||
| 133 | |||
| 134 | if (!path_parser_dest.IsValid()) { | ||
| 135 | LOG_ERROR(Service_FS, "Invalid dest path %s", dest_path.DebugStr().c_str()); | ||
| 136 | return ERROR_INVALID_PATH; | ||
| 137 | } | ||
| 138 | |||
| 139 | const auto src_path_full = path_parser_src.BuildHostPath(mount_point); | ||
| 140 | const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); | ||
| 141 | |||
| 142 | if (FileUtil::Rename(src_path_full, dest_path_full)) { | ||
| 125 | return RESULT_SUCCESS; | 143 | return RESULT_SUCCESS; |
| 126 | } | 144 | } |
| 127 | 145 | ||
| @@ -260,8 +278,27 @@ ResultCode SDMCArchive::CreateDirectory(const Path& path) const { | |||
| 260 | } | 278 | } |
| 261 | 279 | ||
| 262 | ResultCode SDMCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { | 280 | ResultCode SDMCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { |
| 263 | if (FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString())) | 281 | const PathParser path_parser_src(src_path); |
| 282 | |||
| 283 | // TODO: Verify these return codes with HW | ||
| 284 | if (!path_parser_src.IsValid()) { | ||
| 285 | LOG_ERROR(Service_FS, "Invalid src path %s", src_path.DebugStr().c_str()); | ||
| 286 | return ERROR_INVALID_PATH; | ||
| 287 | } | ||
| 288 | |||
| 289 | const PathParser path_parser_dest(dest_path); | ||
| 290 | |||
| 291 | if (!path_parser_dest.IsValid()) { | ||
| 292 | LOG_ERROR(Service_FS, "Invalid dest path %s", dest_path.DebugStr().c_str()); | ||
| 293 | return ERROR_INVALID_PATH; | ||
| 294 | } | ||
| 295 | |||
| 296 | const auto src_path_full = path_parser_src.BuildHostPath(mount_point); | ||
| 297 | const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); | ||
| 298 | |||
| 299 | if (FileUtil::Rename(src_path_full, dest_path_full)) { | ||
| 264 | return RESULT_SUCCESS; | 300 | return RESULT_SUCCESS; |
| 301 | } | ||
| 265 | 302 | ||
| 266 | // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't | 303 | // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't |
| 267 | // exist or similar. Verify. | 304 | // exist or similar. Verify. |
diff --git a/src/core/file_sys/savedata_archive.cpp b/src/core/file_sys/savedata_archive.cpp index f540c4a93..f8f811ba0 100644 --- a/src/core/file_sys/savedata_archive.cpp +++ b/src/core/file_sys/savedata_archive.cpp | |||
| @@ -106,7 +106,25 @@ ResultCode SaveDataArchive::DeleteFile(const Path& path) const { | |||
| 106 | } | 106 | } |
| 107 | 107 | ||
| 108 | ResultCode SaveDataArchive::RenameFile(const Path& src_path, const Path& dest_path) const { | 108 | ResultCode SaveDataArchive::RenameFile(const Path& src_path, const Path& dest_path) const { |
| 109 | if (FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString())) { | 109 | const PathParser path_parser_src(src_path); |
| 110 | |||
| 111 | // TODO: Verify these return codes with HW | ||
| 112 | if (!path_parser_src.IsValid()) { | ||
| 113 | LOG_ERROR(Service_FS, "Invalid src path %s", src_path.DebugStr().c_str()); | ||
| 114 | return ERROR_INVALID_PATH; | ||
| 115 | } | ||
| 116 | |||
| 117 | const PathParser path_parser_dest(dest_path); | ||
| 118 | |||
| 119 | if (!path_parser_dest.IsValid()) { | ||
| 120 | LOG_ERROR(Service_FS, "Invalid dest path %s", dest_path.DebugStr().c_str()); | ||
| 121 | return ERROR_INVALID_PATH; | ||
| 122 | } | ||
| 123 | |||
| 124 | const auto src_path_full = path_parser_src.BuildHostPath(mount_point); | ||
| 125 | const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); | ||
| 126 | |||
| 127 | if (FileUtil::Rename(src_path_full, dest_path_full)) { | ||
| 110 | return RESULT_SUCCESS; | 128 | return RESULT_SUCCESS; |
| 111 | } | 129 | } |
| 112 | 130 | ||
| @@ -247,8 +265,27 @@ ResultCode SaveDataArchive::CreateDirectory(const Path& path) const { | |||
| 247 | } | 265 | } |
| 248 | 266 | ||
| 249 | ResultCode SaveDataArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { | 267 | ResultCode SaveDataArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { |
| 250 | if (FileUtil::Rename(mount_point + src_path.AsString(), mount_point + dest_path.AsString())) | 268 | const PathParser path_parser_src(src_path); |
| 269 | |||
| 270 | // TODO: Verify these return codes with HW | ||
| 271 | if (!path_parser_src.IsValid()) { | ||
| 272 | LOG_ERROR(Service_FS, "Invalid src path %s", src_path.DebugStr().c_str()); | ||
| 273 | return ERROR_INVALID_PATH; | ||
| 274 | } | ||
| 275 | |||
| 276 | const PathParser path_parser_dest(dest_path); | ||
| 277 | |||
| 278 | if (!path_parser_dest.IsValid()) { | ||
| 279 | LOG_ERROR(Service_FS, "Invalid dest path %s", dest_path.DebugStr().c_str()); | ||
| 280 | return ERROR_INVALID_PATH; | ||
| 281 | } | ||
| 282 | |||
| 283 | const auto src_path_full = path_parser_src.BuildHostPath(mount_point); | ||
| 284 | const auto dest_path_full = path_parser_dest.BuildHostPath(mount_point); | ||
| 285 | |||
| 286 | if (FileUtil::Rename(src_path_full, dest_path_full)) { | ||
| 251 | return RESULT_SUCCESS; | 287 | return RESULT_SUCCESS; |
| 288 | } | ||
| 252 | 289 | ||
| 253 | // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't | 290 | // TODO(yuriks): This code probably isn't right, it'll return a Status even if the file didn't |
| 254 | // exist or similar. Verify. | 291 | // exist or similar. Verify. |
diff --git a/src/core/hle/service/apt/apt.cpp b/src/core/hle/service/apt/apt.cpp index 4e6b7b6f5..0109fa2b2 100644 --- a/src/core/hle/service/apt/apt.cpp +++ b/src/core/hle/service/apt/apt.cpp | |||
| @@ -75,6 +75,10 @@ void Initialize(Service::Interface* self) { | |||
| 75 | void GetSharedFont(Service::Interface* self) { | 75 | void GetSharedFont(Service::Interface* self) { |
| 76 | IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x44, 0, 0); // 0x00440000 | 76 | IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x44, 0, 0); // 0x00440000 |
| 77 | IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); | 77 | IPC::RequestBuilder rb = rp.MakeBuilder(2, 2); |
| 78 | |||
| 79 | // Log in telemetry if the game uses the shared font | ||
| 80 | Core::Telemetry().AddField(Telemetry::FieldType::Session, "RequiresSharedFont", true); | ||
| 81 | |||
| 78 | if (!shared_font_loaded) { | 82 | if (!shared_font_loaded) { |
| 79 | LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds"); | 83 | LOG_ERROR(Service_APT, "shared font file missing - go dump it from your 3ds"); |
| 80 | rb.Push<u32>(-1); // TODO: Find the right error code | 84 | rb.Push<u32>(-1); // TODO: Find the right error code |
diff --git a/src/core/hle/service/dlp/dlp_clnt.cpp b/src/core/hle/service/dlp/dlp_clnt.cpp index 56f934b3f..6f2bf2061 100644 --- a/src/core/hle/service/dlp/dlp_clnt.cpp +++ b/src/core/hle/service/dlp/dlp_clnt.cpp | |||
| @@ -8,7 +8,26 @@ namespace Service { | |||
| 8 | namespace DLP { | 8 | namespace DLP { |
| 9 | 9 | ||
| 10 | const Interface::FunctionInfo FunctionTable[] = { | 10 | const Interface::FunctionInfo FunctionTable[] = { |
| 11 | {0x000100C3, nullptr, "Initialize"}, {0x00110000, nullptr, "GetWirelessRebootPassphrase"}, | 11 | {0x000100C3, nullptr, "Initialize"}, |
| 12 | {0x00020000, nullptr, "Finalize"}, | ||
| 13 | {0x00030000, nullptr, "GetEventDesc"}, | ||
| 14 | {0x00040000, nullptr, "GetChannel"}, | ||
| 15 | {0x00050180, nullptr, "StartScan"}, | ||
| 16 | {0x00060000, nullptr, "StopScan"}, | ||
| 17 | {0x00070080, nullptr, "GetServerInfo"}, | ||
| 18 | {0x00080100, nullptr, "GetTitleInfo"}, | ||
| 19 | {0x00090040, nullptr, "GetTitleInfoInOrder"}, | ||
| 20 | {0x000A0080, nullptr, "DeleteScanInfo"}, | ||
| 21 | {0x000B0100, nullptr, "PrepareForSystemDownload"}, | ||
| 22 | {0x000C0000, nullptr, "StartSystemDownload"}, | ||
| 23 | {0x000D0100, nullptr, "StartTitleDownload"}, | ||
| 24 | {0x000E0000, nullptr, "GetMyStatus"}, | ||
| 25 | {0x000F0040, nullptr, "GetConnectingNodes"}, | ||
| 26 | {0x00100040, nullptr, "GetNodeInfo"}, | ||
| 27 | {0x00110000, nullptr, "GetWirelessRebootPassphrase"}, | ||
| 28 | {0x00120000, nullptr, "StopSession"}, | ||
| 29 | {0x00130100, nullptr, "GetCupVersion"}, | ||
| 30 | {0x00140100, nullptr, "GetDupAvailability"}, | ||
| 12 | }; | 31 | }; |
| 13 | 32 | ||
| 14 | DLP_CLNT_Interface::DLP_CLNT_Interface() { | 33 | DLP_CLNT_Interface::DLP_CLNT_Interface() { |
diff --git a/src/core/hle/service/dlp/dlp_fkcl.cpp b/src/core/hle/service/dlp/dlp_fkcl.cpp index 29b9d52e0..fe6be7d32 100644 --- a/src/core/hle/service/dlp/dlp_fkcl.cpp +++ b/src/core/hle/service/dlp/dlp_fkcl.cpp | |||
| @@ -8,7 +8,23 @@ namespace Service { | |||
| 8 | namespace DLP { | 8 | namespace DLP { |
| 9 | 9 | ||
| 10 | const Interface::FunctionInfo FunctionTable[] = { | 10 | const Interface::FunctionInfo FunctionTable[] = { |
| 11 | {0x00010083, nullptr, "Initialize"}, {0x000F0000, nullptr, "GetWirelessRebootPassphrase"}, | 11 | {0x00010083, nullptr, "Initialize"}, |
| 12 | {0x00020000, nullptr, "Finalize"}, | ||
| 13 | {0x00030000, nullptr, "GetEventDesc"}, | ||
| 14 | {0x00040000, nullptr, "GetChannels"}, | ||
| 15 | {0x00050180, nullptr, "StartScan"}, | ||
| 16 | {0x00060000, nullptr, "StopScan"}, | ||
| 17 | {0x00070080, nullptr, "GetServerInfo"}, | ||
| 18 | {0x00080100, nullptr, "GetTitleInfo"}, | ||
| 19 | {0x00090040, nullptr, "GetTitleInfoInOrder"}, | ||
| 20 | {0x000A0080, nullptr, "DeleteScanInfo"}, | ||
| 21 | {0x000B0100, nullptr, "StartFakeSession"}, | ||
| 22 | {0x000C0000, nullptr, "GetMyStatus"}, | ||
| 23 | {0x000D0040, nullptr, "GetConnectingNodes"}, | ||
| 24 | {0x000E0040, nullptr, "GetNodeInfo"}, | ||
| 25 | {0x000F0000, nullptr, "GetWirelessRebootPassphrase"}, | ||
| 26 | {0x00100000, nullptr, "StopSession"}, | ||
| 27 | {0x00110203, nullptr, "Initialize2"}, | ||
| 12 | }; | 28 | }; |
| 13 | 29 | ||
| 14 | DLP_FKCL_Interface::DLP_FKCL_Interface() { | 30 | DLP_FKCL_Interface::DLP_FKCL_Interface() { |
diff --git a/src/core/hle/service/dlp/dlp_srvr.cpp b/src/core/hle/service/dlp/dlp_srvr.cpp index 32cfa2c44..1bcea43d3 100644 --- a/src/core/hle/service/dlp/dlp_srvr.cpp +++ b/src/core/hle/service/dlp/dlp_srvr.cpp | |||
| @@ -11,7 +11,7 @@ | |||
| 11 | namespace Service { | 11 | namespace Service { |
| 12 | namespace DLP { | 12 | namespace DLP { |
| 13 | 13 | ||
| 14 | static void unk_0x000E0040(Interface* self) { | 14 | static void IsChild(Interface* self) { |
| 15 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 15 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 16 | 16 | ||
| 17 | cmd_buff[1] = RESULT_SUCCESS.raw; | 17 | cmd_buff[1] = RESULT_SUCCESS.raw; |
| @@ -24,14 +24,19 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 24 | {0x00010183, nullptr, "Initialize"}, | 24 | {0x00010183, nullptr, "Initialize"}, |
| 25 | {0x00020000, nullptr, "Finalize"}, | 25 | {0x00020000, nullptr, "Finalize"}, |
| 26 | {0x00030000, nullptr, "GetServerState"}, | 26 | {0x00030000, nullptr, "GetServerState"}, |
| 27 | {0x00040000, nullptr, "GetEventDescription"}, | ||
| 27 | {0x00050080, nullptr, "StartAccepting"}, | 28 | {0x00050080, nullptr, "StartAccepting"}, |
| 29 | {0x00060000, nullptr, "EndAccepting"}, | ||
| 28 | {0x00070000, nullptr, "StartDistribution"}, | 30 | {0x00070000, nullptr, "StartDistribution"}, |
| 29 | {0x000800C0, nullptr, "SendWirelessRebootPassphrase"}, | 31 | {0x000800C0, nullptr, "SendWirelessRebootPassphrase"}, |
| 30 | {0x00090040, nullptr, "AcceptClient"}, | 32 | {0x00090040, nullptr, "AcceptClient"}, |
| 33 | {0x000A0040, nullptr, "DisconnectClient"}, | ||
| 31 | {0x000B0042, nullptr, "GetConnectingClients"}, | 34 | {0x000B0042, nullptr, "GetConnectingClients"}, |
| 32 | {0x000C0040, nullptr, "GetClientInfo"}, | 35 | {0x000C0040, nullptr, "GetClientInfo"}, |
| 33 | {0x000D0040, nullptr, "GetClientState"}, | 36 | {0x000D0040, nullptr, "GetClientState"}, |
| 34 | {0x000E0040, unk_0x000E0040, "unk_0x000E0040"}, | 37 | {0x000E0040, IsChild, "IsChild"}, |
| 38 | {0x000F0303, nullptr, "InitializeWithName"}, | ||
| 39 | {0x00100000, nullptr, "GetDupNoticeNeed"}, | ||
| 35 | }; | 40 | }; |
| 36 | 41 | ||
| 37 | DLP_SRVR_Interface::DLP_SRVR_Interface() { | 42 | DLP_SRVR_Interface::DLP_SRVR_Interface() { |
diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 48bbf687d..e731888a2 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h | |||
| @@ -166,6 +166,15 @@ public: | |||
| 166 | return ResultStatus::ErrorNotImplemented; | 166 | return ResultStatus::ErrorNotImplemented; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | /** | ||
| 170 | * Get the title of the application | ||
| 171 | * @param title Reference to store the application title into | ||
| 172 | * @return ResultStatus result of function | ||
| 173 | */ | ||
| 174 | virtual ResultStatus ReadTitle(std::string& title) { | ||
| 175 | return ResultStatus::ErrorNotImplemented; | ||
| 176 | } | ||
| 177 | |||
| 169 | protected: | 178 | protected: |
| 170 | FileUtil::IOFile file; | 179 | FileUtil::IOFile file; |
| 171 | bool is_loaded = false; | 180 | bool is_loaded = false; |
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index fc4d14a59..c007069a9 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp | |||
| @@ -4,7 +4,9 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <cinttypes> | 6 | #include <cinttypes> |
| 7 | #include <codecvt> | ||
| 7 | #include <cstring> | 8 | #include <cstring> |
| 9 | #include <locale> | ||
| 8 | #include <memory> | 10 | #include <memory> |
| 9 | #include "common/logging/log.h" | 11 | #include "common/logging/log.h" |
| 10 | #include "common/string_util.h" | 12 | #include "common/string_util.h" |
| @@ -420,4 +422,22 @@ ResultStatus AppLoader_NCCH::ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_ | |||
| 420 | return ResultStatus::ErrorNotUsed; | 422 | return ResultStatus::ErrorNotUsed; |
| 421 | } | 423 | } |
| 422 | 424 | ||
| 425 | ResultStatus AppLoader_NCCH::ReadTitle(std::string& title) { | ||
| 426 | std::vector<u8> data; | ||
| 427 | Loader::SMDH smdh; | ||
| 428 | ReadIcon(data); | ||
| 429 | |||
| 430 | if (!Loader::IsValidSMDH(data)) { | ||
| 431 | return ResultStatus::ErrorInvalidFormat; | ||
| 432 | } | ||
| 433 | |||
| 434 | memcpy(&smdh, data.data(), sizeof(Loader::SMDH)); | ||
| 435 | |||
| 436 | const auto& short_title = smdh.GetShortTitle(SMDH::TitleLanguage::English); | ||
| 437 | auto title_end = std::find(short_title.begin(), short_title.end(), u'\0'); | ||
| 438 | title = Common::UTF16ToUTF8(std::u16string{short_title.begin(), title_end}); | ||
| 439 | |||
| 440 | return ResultStatus::Success; | ||
| 441 | } | ||
| 442 | |||
| 423 | } // namespace Loader | 443 | } // namespace Loader |
diff --git a/src/core/loader/ncch.h b/src/core/loader/ncch.h index 0ebd47fd5..e40cef764 100644 --- a/src/core/loader/ncch.h +++ b/src/core/loader/ncch.h | |||
| @@ -191,23 +191,13 @@ public: | |||
| 191 | 191 | ||
| 192 | ResultStatus ReadLogo(std::vector<u8>& buffer) override; | 192 | ResultStatus ReadLogo(std::vector<u8>& buffer) override; |
| 193 | 193 | ||
| 194 | /** | ||
| 195 | * Get the program id of the application | ||
| 196 | * @param out_program_id Reference to store program id into | ||
| 197 | * @return ResultStatus result of function | ||
| 198 | */ | ||
| 199 | ResultStatus ReadProgramId(u64& out_program_id) override; | 194 | ResultStatus ReadProgramId(u64& out_program_id) override; |
| 200 | 195 | ||
| 201 | /** | ||
| 202 | * Get the RomFS of the application | ||
| 203 | * @param romfs_file Reference to buffer to store data | ||
| 204 | * @param offset Offset in the file to the RomFS | ||
| 205 | * @param size Size of the RomFS in bytes | ||
| 206 | * @return ResultStatus result of function | ||
| 207 | */ | ||
| 208 | ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, | 196 | ResultStatus ReadRomFS(std::shared_ptr<FileUtil::IOFile>& romfs_file, u64& offset, |
| 209 | u64& size) override; | 197 | u64& size) override; |
| 210 | 198 | ||
| 199 | ResultStatus ReadTitle(std::string& title) override; | ||
| 200 | |||
| 211 | private: | 201 | private: |
| 212 | /** | 202 | /** |
| 213 | * Reads an application ExeFS section of an NCCH file into AppLoader (e.g. .code, .logo, etc.) | 203 | * Reads an application ExeFS section of an NCCH file into AppLoader (e.g. .code, .logo, etc.) |
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index 841d6cfa1..94483f385 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include "common/assert.h" | 7 | #include "common/assert.h" |
| 8 | #include "common/scm_rev.h" | 8 | #include "common/scm_rev.h" |
| 9 | #include "common/x64/cpu_detect.h" | 9 | #include "common/x64/cpu_detect.h" |
| 10 | #include "core/core.h" | ||
| 10 | #include "core/settings.h" | 11 | #include "core/settings.h" |
| 11 | #include "core/telemetry_session.h" | 12 | #include "core/telemetry_session.h" |
| 12 | 13 | ||
| @@ -39,12 +40,19 @@ TelemetrySession::TelemetrySession() { | |||
| 39 | std::chrono::system_clock::now().time_since_epoch()) | 40 | std::chrono::system_clock::now().time_since_epoch()) |
| 40 | .count()}; | 41 | .count()}; |
| 41 | AddField(Telemetry::FieldType::Session, "Init_Time", init_time); | 42 | AddField(Telemetry::FieldType::Session, "Init_Time", init_time); |
| 43 | std::string program_name; | ||
| 44 | const Loader::ResultStatus res{System::GetInstance().GetAppLoader().ReadTitle(program_name)}; | ||
| 45 | if (res == Loader::ResultStatus::Success) { | ||
| 46 | AddField(Telemetry::FieldType::Session, "ProgramName", program_name); | ||
| 47 | } | ||
| 42 | 48 | ||
| 43 | // Log application information | 49 | // Log application information |
| 44 | const bool is_git_dirty{std::strstr(Common::g_scm_desc, "dirty") != nullptr}; | 50 | const bool is_git_dirty{std::strstr(Common::g_scm_desc, "dirty") != nullptr}; |
| 45 | AddField(Telemetry::FieldType::App, "Git_IsDirty", is_git_dirty); | 51 | AddField(Telemetry::FieldType::App, "Git_IsDirty", is_git_dirty); |
| 46 | AddField(Telemetry::FieldType::App, "Git_Branch", Common::g_scm_branch); | 52 | AddField(Telemetry::FieldType::App, "Git_Branch", Common::g_scm_branch); |
| 47 | AddField(Telemetry::FieldType::App, "Git_Revision", Common::g_scm_rev); | 53 | AddField(Telemetry::FieldType::App, "Git_Revision", Common::g_scm_rev); |
| 54 | AddField(Telemetry::FieldType::App, "BuildDate", Common::g_build_date); | ||
| 55 | AddField(Telemetry::FieldType::App, "BuildName", Common::g_build_name); | ||
| 48 | 56 | ||
| 49 | // Log user system information | 57 | // Log user system information |
| 50 | AddField(Telemetry::FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string); | 58 | AddField(Telemetry::FieldType::UserSystem, "CPU_Model", Common::GetCPUCaps().cpu_string); |
| @@ -68,6 +76,15 @@ TelemetrySession::TelemetrySession() { | |||
| 68 | Common::GetCPUCaps().sse4_1); | 76 | Common::GetCPUCaps().sse4_1); |
| 69 | AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE42", | 77 | AddField(Telemetry::FieldType::UserSystem, "CPU_Extension_x64_SSE42", |
| 70 | Common::GetCPUCaps().sse4_2); | 78 | Common::GetCPUCaps().sse4_2); |
| 79 | #ifdef __APPLE__ | ||
| 80 | AddField(Telemetry::FieldType::UserSystem, "OsPlatform", "Apple"); | ||
| 81 | #elif defined(_WIN32) | ||
| 82 | AddField(Telemetry::FieldType::UserSystem, "OsPlatform", "Windows"); | ||
| 83 | #elif defined(__linux__) || defined(linux) || defined(__linux) | ||
| 84 | AddField(Telemetry::FieldType::UserSystem, "OsPlatform", "Linux"); | ||
| 85 | #else | ||
| 86 | AddField(Telemetry::FieldType::UserSystem, "OsPlatform", "Unknown"); | ||
| 87 | #endif | ||
| 71 | 88 | ||
| 72 | // Log user configuration information | 89 | // Log user configuration information |
| 73 | AddField(Telemetry::FieldType::UserConfig, "Audio_EnableAudioStretching", | 90 | AddField(Telemetry::FieldType::UserConfig, "Audio_EnableAudioStretching", |