summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md3
-rw-r--r--README.md4
-rw-r--r--appveyor.yml2
m---------externals/boost0
-rw-r--r--src/common/file_util.cpp18
-rw-r--r--src/common/x64/cpu_detect.cpp12
-rw-r--r--src/core/file_sys/archive_extsavedata.cpp2
-rw-r--r--src/core/file_sys/archive_sdmc.cpp2
-rw-r--r--src/core/file_sys/archive_sdmcwriteonly.cpp2
-rw-r--r--src/core/file_sys/archive_source_sd_savedata.cpp2
-rw-r--r--src/core/hle/service/cfg/cfg.cpp31
-rw-r--r--src/core/hle/svc.cpp20
-rw-r--r--src/core/loader/loader.cpp2
-rw-r--r--src/core/loader/ncch.cpp9
14 files changed, 71 insertions, 38 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 55f520cb4..f0b012ed9 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,7 +1,6 @@
# Reporting Issues
-**The issue tracker is not a support forum.** Unless you can provide precise *technical information* regarding an issue, you *should not post in it*. If you need support, first read the [FAQ](https://github.com/citra-emu/citra/wiki/FAQ) and then either visit our IRC channel, [our forum](https://community.citra-emu.org)
-.citra-emu.org/) or ask in a general emulation forum such as [/r/emulation](https://www.reddit.com/r/emulation/). If you post support questions, generic messages to the developers or vague reports without technical details, they will be closed and locked.
+**The issue tracker is not a support forum.** Unless you can provide precise *technical information* regarding an issue, you *should not post in it*. If you need support, first read the [FAQ](https://github.com/citra-emu/citra/wiki/FAQ) and then either visit our IRC channel, [our forum](https://community.citra-emu.org) or ask in a general emulation forum such as [/r/emulation](https://www.reddit.com/r/emulation/). If you post support questions, generic messages to the developers or vague reports without technical details, they will be closed and locked.
If you believe you have a valid issue report, please post text or a screenshot from the log (the console window that opens alongside Citra) and build version (hex string visible in the titlebar and zip filename), as well as your hardware and software information if applicable.
diff --git a/README.md b/README.md
index 461d2e3a7..df1d0b4eb 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Citra Emulator
Citra is an experimental open-source Nintendo 3DS emulator/debugger written in C++. It is written with portability in mind, with builds actively maintained for Windows, Linux and macOS. Citra only emulates a subset of 3DS hardware, and therefore is generally only useful for running/debugging homebrew applications. At this time, Citra is even able to boot several commercial games! Most of these do not run to a playable state, but we are working every day to advance the project forward.
-Citra is licensed under the GPLv2 (or any later version). Refer to the license.txt file included. Please read the [FAQ](https://citra-emu.org/wikis/faq) before getting started with the project.
+Citra is licensed under the GPLv2 (or any later version). Refer to the license.txt file included. Please read the [FAQ](https://citra-emu.org/wiki/FAQ/) before getting started with the project.
Check out our [website](https://citra-emu.org/)!
@@ -27,7 +27,7 @@ If you want to contribute please take a look at the [Contributor's Guide](CONTRI
### Support
-We happily accept monetary donations, or donated games and hardware. Please see our [donations page](https://citra-emu.org/page/donate) for more information on how you can contribute to Citra. Any donations received will go towards things like:
+We happily accept monetary donations, or donated games and hardware. Please see our [donations page](https://citra-emu.org/donate/) for more information on how you can contribute to Citra. Any donations received will go towards things like:
* 3DS consoles for developers to explore the hardware
* 3DS games for testing
* Any equipment required for homebrew
diff --git a/appveyor.yml b/appveyor.yml
index c07559479..2a4a15d40 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -20,6 +20,8 @@ install:
- git submodule update --init --recursive
before_build:
+ # Xamarin log spam workaround
+ - del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
- mkdir build
- cd build
- cmake -G "Visual Studio 14 2015 Win64" -DCITRA_USE_BUNDLED_QT=1 -DCITRA_USE_BUNDLED_SDL2=1 ..
diff --git a/externals/boost b/externals/boost
-Subproject f005c955f8147a29667aa0b65257abc3dd520b0
+Subproject 351972396392c97a659b9a02f34ce9269293d21
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index df234c225..5ab036b34 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -118,8 +118,7 @@ bool IsDirectory(const std::string& filename) {
#endif
if (result < 0) {
- LOG_WARNING(Common_Filesystem, "stat failed on %s: %s", filename.c_str(),
- GetLastErrorMsg());
+ LOG_DEBUG(Common_Filesystem, "stat failed on %s: %s", filename.c_str(), GetLastErrorMsg());
return false;
}
@@ -129,12 +128,12 @@ bool IsDirectory(const std::string& filename) {
// Deletes a given filename, return true on success
// Doesn't supports deleting a directory
bool Delete(const std::string& filename) {
- LOG_INFO(Common_Filesystem, "file %s", filename.c_str());
+ LOG_TRACE(Common_Filesystem, "file %s", filename.c_str());
// Return true because we care about the file no
// being there, not the actual delete.
if (!Exists(filename)) {
- LOG_WARNING(Common_Filesystem, "%s does not exist", filename.c_str());
+ LOG_DEBUG(Common_Filesystem, "%s does not exist", filename.c_str());
return true;
}
@@ -169,8 +168,7 @@ bool CreateDir(const std::string& path) {
return true;
DWORD error = GetLastError();
if (error == ERROR_ALREADY_EXISTS) {
- LOG_WARNING(Common_Filesystem, "CreateDirectory failed on %s: already exists",
- path.c_str());
+ LOG_DEBUG(Common_Filesystem, "CreateDirectory failed on %s: already exists", path.c_str());
return true;
}
LOG_ERROR(Common_Filesystem, "CreateDirectory failed on %s: %i", path.c_str(), error);
@@ -182,7 +180,7 @@ bool CreateDir(const std::string& path) {
int err = errno;
if (err == EEXIST) {
- LOG_WARNING(Common_Filesystem, "mkdir failed on %s: already exists", path.c_str());
+ LOG_DEBUG(Common_Filesystem, "mkdir failed on %s: already exists", path.c_str());
return true;
}
@@ -197,7 +195,7 @@ bool CreateFullPath(const std::string& fullPath) {
LOG_TRACE(Common_Filesystem, "path %s", fullPath.c_str());
if (FileUtil::Exists(fullPath)) {
- LOG_WARNING(Common_Filesystem, "path exists %s", fullPath.c_str());
+ LOG_DEBUG(Common_Filesystem, "path exists %s", fullPath.c_str());
return true;
}
@@ -229,7 +227,7 @@ bool CreateFullPath(const std::string& fullPath) {
// Deletes a directory filename, returns true on success
bool DeleteDir(const std::string& filename) {
- LOG_INFO(Common_Filesystem, "directory %s", filename.c_str());
+ LOG_TRACE(Common_Filesystem, "directory %s", filename.c_str());
// check if a directory
if (!FileUtil::IsDirectory(filename)) {
@@ -693,6 +691,8 @@ const std::string& GetUserPath(const unsigned int DirIDX, const std::string& new
paths[D_USER_IDX] = GetExeDirectory() + DIR_SEP USERDATA_DIR DIR_SEP;
if (!FileUtil::IsDirectory(paths[D_USER_IDX])) {
paths[D_USER_IDX] = AppDataRoamingDirectory() + DIR_SEP EMU_DATA_DIR DIR_SEP;
+ } else {
+ LOG_INFO(Common_Filesystem, "Using the local user directory");
}
paths[D_CONFIG_IDX] = paths[D_USER_IDX] + CONFIG_DIR DIR_SEP;
diff --git a/src/common/x64/cpu_detect.cpp b/src/common/x64/cpu_detect.cpp
index 370ae2c80..2cb3ab9cc 100644
--- a/src/common/x64/cpu_detect.cpp
+++ b/src/common/x64/cpu_detect.cpp
@@ -8,9 +8,9 @@
#include "common/common_types.h"
#include "cpu_detect.h"
-namespace Common {
-
-#ifndef _MSC_VER
+#ifdef _MSC_VER
+#include <intrin.h>
+#else
#if defined(__DragonFly__) || defined(__FreeBSD__)
// clang-format off
@@ -37,13 +37,15 @@ static inline void __cpuid(int info[4], int function_id) {
}
#define _XCR_XFEATURE_ENABLED_MASK 0
-static u64 _xgetbv(u32 index) {
+static inline u64 _xgetbv(u32 index) {
u32 eax, edx;
__asm__ __volatile__("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
return ((u64)edx << 32) | eax;
}
-#endif // ifndef _MSC_VER
+#endif // _MSC_VER
+
+namespace Common {
// Detects the various CPU features
static CPUCaps Detect() {
diff --git a/src/core/file_sys/archive_extsavedata.cpp b/src/core/file_sys/archive_extsavedata.cpp
index dd2fb167f..f454e7840 100644
--- a/src/core/file_sys/archive_extsavedata.cpp
+++ b/src/core/file_sys/archive_extsavedata.cpp
@@ -173,7 +173,7 @@ Path ConstructExtDataBinaryPath(u32 media_type, u32 high, u32 low) {
ArchiveFactory_ExtSaveData::ArchiveFactory_ExtSaveData(const std::string& mount_location,
bool shared)
: shared(shared), mount_point(GetExtDataContainerPath(mount_location, shared)) {
- LOG_INFO(Service_FS, "Directory %s set as base for ExtSaveData.", mount_point.c_str());
+ LOG_DEBUG(Service_FS, "Directory %s set as base for ExtSaveData.", mount_point.c_str());
}
bool ArchiveFactory_ExtSaveData::Initialize() {
diff --git a/src/core/file_sys/archive_sdmc.cpp b/src/core/file_sys/archive_sdmc.cpp
index 72ff05c65..679909d06 100644
--- a/src/core/file_sys/archive_sdmc.cpp
+++ b/src/core/file_sys/archive_sdmc.cpp
@@ -306,7 +306,7 @@ u64 SDMCArchive::GetFreeBytes() const {
ArchiveFactory_SDMC::ArchiveFactory_SDMC(const std::string& sdmc_directory)
: sdmc_directory(sdmc_directory) {
- LOG_INFO(Service_FS, "Directory %s set as SDMC.", sdmc_directory.c_str());
+ LOG_DEBUG(Service_FS, "Directory %s set as SDMC.", sdmc_directory.c_str());
}
bool ArchiveFactory_SDMC::Initialize() {
diff --git a/src/core/file_sys/archive_sdmcwriteonly.cpp b/src/core/file_sys/archive_sdmcwriteonly.cpp
index 2aafc9b1d..244aef48a 100644
--- a/src/core/file_sys/archive_sdmcwriteonly.cpp
+++ b/src/core/file_sys/archive_sdmcwriteonly.cpp
@@ -32,7 +32,7 @@ ResultVal<std::unique_ptr<DirectoryBackend>> SDMCWriteOnlyArchive::OpenDirectory
ArchiveFactory_SDMCWriteOnly::ArchiveFactory_SDMCWriteOnly(const std::string& mount_point)
: sdmc_directory(mount_point) {
- LOG_INFO(Service_FS, "Directory %s set as SDMCWriteOnly.", sdmc_directory.c_str());
+ LOG_DEBUG(Service_FS, "Directory %s set as SDMCWriteOnly.", sdmc_directory.c_str());
}
bool ArchiveFactory_SDMCWriteOnly::Initialize() {
diff --git a/src/core/file_sys/archive_source_sd_savedata.cpp b/src/core/file_sys/archive_source_sd_savedata.cpp
index e01357891..f31a68038 100644
--- a/src/core/file_sys/archive_source_sd_savedata.cpp
+++ b/src/core/file_sys/archive_source_sd_savedata.cpp
@@ -39,7 +39,7 @@ std::string GetSaveDataMetadataPath(const std::string& mount_location, u64 progr
ArchiveSource_SDSaveData::ArchiveSource_SDSaveData(const std::string& sdmc_directory)
: mount_point(GetSaveDataContainerPath(sdmc_directory)) {
- LOG_INFO(Service_FS, "Directory %s set as SaveData.", mount_point.c_str());
+ LOG_DEBUG(Service_FS, "Directory %s set as SaveData.", mount_point.c_str());
}
ResultVal<std::unique_ptr<ArchiveBackend>> ArchiveSource_SDSaveData::Open(u64 program_id) {
diff --git a/src/core/hle/service/cfg/cfg.cpp b/src/core/hle/service/cfg/cfg.cpp
index 6f13cde27..4ddb1bc90 100644
--- a/src/core/hle/service/cfg/cfg.cpp
+++ b/src/core/hle/service/cfg/cfg.cpp
@@ -3,6 +3,8 @@
// Refer to the license.txt file included.
#include <algorithm>
+#include <array>
+#include <cryptopp/sha.h>
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/string_util.h"
@@ -176,14 +178,29 @@ void SecureInfoGetRegion(Service::Interface* self) {
}
void GenHashConsoleUnique(Service::Interface* self) {
- u32* cmd_buff = Kernel::GetCommandBuffer();
- u32 app_id_salt = cmd_buff[1];
-
- cmd_buff[1] = RESULT_SUCCESS.raw;
- cmd_buff[2] = 0x33646D6F ^ (app_id_salt & 0xFFFFF); // 3dmoo hash
- cmd_buff[3] = 0x6F534841 ^ (app_id_salt & 0xFFFFF);
+ IPC::RequestParser rp(Kernel::GetCommandBuffer(), 0x03, 1, 0);
+ const u32 app_id_salt = rp.Pop<u32>() & 0x000FFFFF;
+
+ IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
+
+ std::array<u8, 12> buffer;
+ const ResultCode result = GetConfigInfoBlock(ConsoleUniqueID2BlockID, 8, 2, buffer.data());
+ rb.Push(result);
+ if (result.IsSuccess()) {
+ std::memcpy(&buffer[8], &app_id_salt, sizeof(u32));
+ std::array<u8, CryptoPP::SHA256::DIGESTSIZE> hash;
+ CryptoPP::SHA256().CalculateDigest(hash.data(), buffer.data(), sizeof(buffer));
+ u32 low, high;
+ memcpy(&low, &hash[hash.size() - 8], sizeof(u32));
+ memcpy(&high, &hash[hash.size() - 4], sizeof(u32));
+ rb.Push(low);
+ rb.Push(high);
+ } else {
+ rb.Push<u32>(0);
+ rb.Push<u32>(0);
+ }
- LOG_WARNING(Service_CFG, "(STUBBED) called app_id_salt=0x%X", app_id_salt);
+ LOG_DEBUG(Service_CFG, "called app_id_salt=0x%X", app_id_salt);
}
void GetRegionCanadaUSA(Service::Interface* self) {
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 1baa80671..4e0c3fb8b 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -556,11 +556,21 @@ static ResultCode CreateThread(Kernel::Handle* out_handle, s32 priority, u32 ent
break;
}
- if (processor_id == THREADPROCESSORID_1 || processor_id == THREADPROCESSORID_ALL ||
- (processor_id == THREADPROCESSORID_DEFAULT &&
- Kernel::g_current_process->ideal_processor == THREADPROCESSORID_1)) {
- LOG_WARNING(Kernel_SVC,
- "Newly created thread is allowed to be run in the SysCore, unimplemented.");
+ if (processor_id == THREADPROCESSORID_ALL) {
+ LOG_INFO(Kernel_SVC,
+ "Newly created thread is allowed to be run in any Core, unimplemented.");
+ }
+
+ if (processor_id == THREADPROCESSORID_DEFAULT &&
+ Kernel::g_current_process->ideal_processor == THREADPROCESSORID_1) {
+ LOG_WARNING(
+ Kernel_SVC,
+ "Newly created thread is allowed to be run in the SysCore (Core1), unimplemented.");
+ }
+
+ if (processor_id == THREADPROCESSORID_1) {
+ LOG_ERROR(Kernel_SVC,
+ "Newly created thread must run in the SysCore (Core1), unimplemented.");
}
CASCADE_RESULT(SharedPtr<Thread> thread, Kernel::Thread::Create(name, entry_point, priority,
diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp
index 147bf8591..be719d74c 100644
--- a/src/core/loader/loader.cpp
+++ b/src/core/loader/loader.cpp
@@ -139,7 +139,7 @@ std::unique_ptr<AppLoader> GetLoader(const std::string& filename) {
type = filename_type;
}
- LOG_INFO(Loader, "Loading file %s as %s...", filename.c_str(), GetFileTypeString(type));
+ LOG_DEBUG(Loader, "Loading file %s as %s...", filename.c_str(), GetFileTypeString(type));
return GetFileLoader(std::move(file), type, filename_filename, filename);
}
diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp
index 98b8259d9..1a4e3efa8 100644
--- a/src/core/loader/ncch.cpp
+++ b/src/core/loader/ncch.cpp
@@ -3,6 +3,7 @@
// Refer to the license.txt file included.
#include <algorithm>
+#include <cinttypes>
#include <cstring>
#include <memory>
#include "common/logging/log.h"
@@ -253,7 +254,7 @@ ResultStatus AppLoader_NCCH::LoadExeFS() {
// Skip NCSD header and load first NCCH (NCSD is just a container of NCCH files)...
if (MakeMagic('N', 'C', 'S', 'D') == ncch_header.magic) {
- LOG_WARNING(Loader, "Only loading the first (bootable) NCCH within the NCSD file!");
+ LOG_DEBUG(Loader, "Only loading the first (bootable) NCCH within the NCSD file!");
ncch_offset = 0x4000;
file.Seek(ncch_offset, SEEK_SET);
file.ReadBytes(&ncch_header, sizeof(NCCH_Header));
@@ -277,8 +278,8 @@ ResultStatus AppLoader_NCCH::LoadExeFS() {
priority = exheader_header.arm11_system_local_caps.priority;
resource_limit_category = exheader_header.arm11_system_local_caps.resource_limit_category;
- LOG_INFO(Loader, "Name: %s", exheader_header.codeset_info.name);
- LOG_INFO(Loader, "Program ID: %016llX", ncch_header.program_id);
+ LOG_DEBUG(Loader, "Name: %s", exheader_header.codeset_info.name);
+ LOG_DEBUG(Loader, "Program ID: %016" PRIX64, ncch_header.program_id);
LOG_DEBUG(Loader, "Code compressed: %s", is_compressed ? "yes" : "no");
LOG_DEBUG(Loader, "Entry point: 0x%08X", entry_point);
LOG_DEBUG(Loader, "Code size: 0x%08X", code_size);
@@ -336,6 +337,8 @@ ResultStatus AppLoader_NCCH::Load() {
if (result != ResultStatus::Success)
return result;
+ LOG_INFO(Loader, "Program ID: %016" PRIX64, ncch_header.program_id);
+
is_loaded = true; // Set state to loaded
result = LoadExec(); // Load the executable into memory for booting