summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt9
-rw-r--r--src/citra_qt/main.cpp2
-rw-r--r--src/common/scm_rev.cpp.in2
-rw-r--r--src/common/scm_rev.h1
-rw-r--r--src/core/core.h9
-rw-r--r--src/core/file_sys/archive_sdmc.cpp41
-rw-r--r--src/core/file_sys/savedata_archive.cpp41
-rw-r--r--src/core/hle/service/apt/apt.cpp4
-rw-r--r--src/core/hle/service/dlp/dlp_clnt.cpp21
-rw-r--r--src/core/hle/service/dlp/dlp_fkcl.cpp18
-rw-r--r--src/core/hle/service/dlp/dlp_srvr.cpp9
-rw-r--r--src/core/loader/loader.h9
-rw-r--r--src/core/loader/ncch.cpp20
-rw-r--r--src/core/loader/ncch.h14
-rw-r--r--src/core/telemetry_session.cpp17
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()
296endfunction() 296endfunction()
297 297
298# generate git revision information 298# Gets a UTC timstamp and sets the provided variable to it
299function(get_timestamp _var)
300 string(TIMESTAMP timestamp UTC)
301 set(${_var} "${timestamp}" PARENT_SCOPE)
302endfunction()
303
304# generate git/build information
299include(GetGitRevisionDescription) 305include(GetGitRevisionDescription)
300get_git_head_revision(GIT_REF_SPEC GIT_REV) 306get_git_head_revision(GIT_REF_SPEC GIT_REV)
301git_describe(GIT_DESC --always --long --dirty) 307git_describe(GIT_DESC --always --long --dirty)
302git_branch_name(GIT_BRANCH) 308git_branch_name(GIT_BRANCH)
309get_timestamp(BUILD_DATE)
303 310
304enable_testing() 311enable_testing()
305add_subdirectory(externals) 312add_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
12namespace Common { 13namespace Common {
13 14
@@ -15,6 +16,7 @@ const char g_scm_rev[] = GIT_REV;
15const char g_scm_branch[] = GIT_BRANCH; 16const char g_scm_branch[] = GIT_BRANCH;
16const char g_scm_desc[] = GIT_DESC; 17const char g_scm_desc[] = GIT_DESC;
17const char g_build_name[] = BUILD_NAME; 18const char g_build_name[] = BUILD_NAME;
19const 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[];
10extern const char g_scm_branch[]; 10extern const char g_scm_branch[];
11extern const char g_scm_desc[]; 11extern const char g_scm_desc[];
12extern const char g_build_name[]; 12extern const char g_build_name[];
13extern 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 @@
14class EmuWindow; 15class EmuWindow;
15class ARM_Interface; 16class ARM_Interface;
16 17
17namespace Loader {
18class AppLoader;
19}
20
21namespace Core { 18namespace Core {
22 19
23class System { 20class 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
122private: 123private:
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
123ResultCode SDMCArchive::RenameFile(const Path& src_path, const Path& dest_path) const { 123ResultCode 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
262ResultCode SDMCArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { 280ResultCode 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
108ResultCode SaveDataArchive::RenameFile(const Path& src_path, const Path& dest_path) const { 108ResultCode 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
249ResultCode SaveDataArchive::RenameDirectory(const Path& src_path, const Path& dest_path) const { 267ResultCode 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) {
75void GetSharedFont(Service::Interface* self) { 75void 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 {
8namespace DLP { 8namespace DLP {
9 9
10const Interface::FunctionInfo FunctionTable[] = { 10const 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
14DLP_CLNT_Interface::DLP_CLNT_Interface() { 33DLP_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 {
8namespace DLP { 8namespace DLP {
9 9
10const Interface::FunctionInfo FunctionTable[] = { 10const 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
14DLP_FKCL_Interface::DLP_FKCL_Interface() { 30DLP_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 @@
11namespace Service { 11namespace Service {
12namespace DLP { 12namespace DLP {
13 13
14static void unk_0x000E0040(Interface* self) { 14static 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
37DLP_SRVR_Interface::DLP_SRVR_Interface() { 42DLP_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
169protected: 178protected:
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
425ResultStatus 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
211private: 201private:
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",