early-access version 1814
This commit is contained in:
parent
abcdc84bad
commit
23cae6079a
52 changed files with 752 additions and 179 deletions
|
@ -1,7 +1,7 @@
|
||||||
yuzu emulator early access
|
yuzu emulator early access
|
||||||
=============
|
=============
|
||||||
|
|
||||||
This is the source code for early-access 1805.
|
This is the source code for early-access 1814.
|
||||||
|
|
||||||
## Legal Notice
|
## Legal Notice
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,8 @@ void DetachedTasks::WaitForAllTasks() {
|
||||||
}
|
}
|
||||||
|
|
||||||
DetachedTasks::~DetachedTasks() {
|
DetachedTasks::~DetachedTasks() {
|
||||||
|
WaitForAllTasks();
|
||||||
|
|
||||||
std::unique_lock lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
ASSERT(count == 0);
|
ASSERT(count == 0);
|
||||||
instance = nullptr;
|
instance = nullptr;
|
||||||
|
|
|
@ -172,7 +172,7 @@ std::string ReadStringFromFile(const std::filesystem::path& path, FileType type)
|
||||||
|
|
||||||
size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
|
size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
|
||||||
std::string_view string) {
|
std::string_view string) {
|
||||||
if (!IsFile(path)) {
|
if (Exists(path) && !IsFile(path)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
|
||||||
|
|
||||||
size_t AppendStringToFile(const std::filesystem::path& path, FileType type,
|
size_t AppendStringToFile(const std::filesystem::path& path, FileType type,
|
||||||
std::string_view string) {
|
std::string_view string) {
|
||||||
if (!IsFile(path)) {
|
if (Exists(path) && !IsFile(path)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ void OpenFileStream(FileStream& file_stream, const Path& path, std::ios_base::op
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads an entire file at path and returns a string of the contents read from the file.
|
* Reads an entire file at path and returns a string of the contents read from the file.
|
||||||
* If the filesystem object at path is not a file, this function returns an empty string.
|
* If the filesystem object at path is not a regular file, this function returns an empty string.
|
||||||
*
|
*
|
||||||
* @param path Filesystem path
|
* @param path Filesystem path
|
||||||
* @param type File type
|
* @param type File type
|
||||||
|
@ -72,7 +72,8 @@ template <typename Path>
|
||||||
/**
|
/**
|
||||||
* Writes a string to a file at path and returns the number of characters successfully written.
|
* Writes a string to a file at path and returns the number of characters successfully written.
|
||||||
* If a file already exists at path, its contents will be erased.
|
* If a file already exists at path, its contents will be erased.
|
||||||
* If the filesystem object at path is not a file, this function returns 0.
|
* If a file does not exist at path, it creates and opens a new empty file for writing.
|
||||||
|
* If the filesystem object at path exists and is not a regular file, this function returns 0.
|
||||||
*
|
*
|
||||||
* @param path Filesystem path
|
* @param path Filesystem path
|
||||||
* @param type File type
|
* @param type File type
|
||||||
|
@ -95,7 +96,8 @@ template <typename Path>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends a string to a file at path and returns the number of characters successfully written.
|
* Appends a string to a file at path and returns the number of characters successfully written.
|
||||||
* If the filesystem object at path is not a file, this function returns 0.
|
* If a file does not exist at path, it creates and opens a new empty file for appending.
|
||||||
|
* If the filesystem object at path exists and is not a regular file, this function returns 0.
|
||||||
*
|
*
|
||||||
* @param path Filesystem path
|
* @param path Filesystem path
|
||||||
* @param type File type
|
* @param type File type
|
||||||
|
@ -394,11 +396,11 @@ public:
|
||||||
[[nodiscard]] size_t WriteString(std::span<const char> string) const;
|
[[nodiscard]] size_t WriteString(std::span<const char> string) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flushes any unwritten buffered data into the file.
|
* Attempts to flush any unwritten buffered data into the file and flush the file into the disk.
|
||||||
*
|
*
|
||||||
* @returns True if the flush was successful, false otherwise.
|
* @returns True if the flush was successful, false otherwise.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool Flush() const;
|
bool Flush() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resizes the file to a given size.
|
* Resizes the file to a given size.
|
||||||
|
|
|
@ -135,8 +135,9 @@ std::shared_ptr<IOFile> FileOpen(const fs::path& path, FileAccessMode mode, File
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsFile(path)) {
|
if (Exists(path) && !IsFile(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Filesystem object at path={} is not a file",
|
LOG_ERROR(Common_Filesystem,
|
||||||
|
"Filesystem object at path={} exists and is not a regular file",
|
||||||
PathToUTF8String(path));
|
PathToUTF8String(path));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,18 +48,18 @@ template <typename Path>
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is not valid
|
* - Input path is not valid
|
||||||
* - Filesystem object at path is not a file
|
* - Filesystem object at path is not a regular file
|
||||||
* - Filesystem at path is read only
|
* - Filesystem at path is read only
|
||||||
*
|
*
|
||||||
* @param path Filesystem path
|
* @param path Filesystem path
|
||||||
*
|
*
|
||||||
* @returns True if file removal succeeds or file does not exist, false otherwise.
|
* @returns True if file removal succeeds or file does not exist, false otherwise.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool RemoveFile(const std::filesystem::path& path);
|
bool RemoveFile(const std::filesystem::path& path);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool RemoveFile(const Path& path) {
|
bool RemoveFile(const Path& path) {
|
||||||
if constexpr (IsChar<typename Path::value_type>) {
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
return RemoveFile(ToU8String(path));
|
return RemoveFile(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
|
@ -74,7 +74,7 @@ template <typename Path>
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - One or both input path(s) is not valid
|
* - One or both input path(s) is not valid
|
||||||
* - Filesystem object at old_path does not exist
|
* - Filesystem object at old_path does not exist
|
||||||
* - Filesystem object at old_path is not a file
|
* - Filesystem object at old_path is not a regular file
|
||||||
* - Filesystem object at new_path exists
|
* - Filesystem object at new_path exists
|
||||||
* - Filesystem at either path is read only
|
* - Filesystem at either path is read only
|
||||||
*
|
*
|
||||||
|
@ -110,8 +110,8 @@ template <typename Path1, typename Path2>
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is not valid
|
* - Input path is not valid
|
||||||
* - Filesystem object at path is not a file
|
* - Filesystem object at path exists and is not a regular file
|
||||||
* - The file is not opened
|
* - The file is not open
|
||||||
*
|
*
|
||||||
* @param path Filesystem path
|
* @param path Filesystem path
|
||||||
* @param mode File access mode
|
* @param mode File access mode
|
||||||
|
@ -251,11 +251,11 @@ template <typename Path>
|
||||||
*
|
*
|
||||||
* @returns True if directory removal succeeds or directory does not exist, false otherwise.
|
* @returns True if directory removal succeeds or directory does not exist, false otherwise.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool RemoveDir(const std::filesystem::path& path);
|
bool RemoveDir(const std::filesystem::path& path);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool RemoveDir(const Path& path) {
|
bool RemoveDir(const Path& path) {
|
||||||
if constexpr (IsChar<typename Path::value_type>) {
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
return RemoveDir(ToU8String(path));
|
return RemoveDir(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
|
@ -276,11 +276,11 @@ template <typename Path>
|
||||||
*
|
*
|
||||||
* @returns True if the directory and all of its contents are removed successfully, false otherwise.
|
* @returns True if the directory and all of its contents are removed successfully, false otherwise.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool RemoveDirRecursively(const std::filesystem::path& path);
|
bool RemoveDirRecursively(const std::filesystem::path& path);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool RemoveDirRecursively(const Path& path) {
|
bool RemoveDirRecursively(const Path& path) {
|
||||||
if constexpr (IsChar<typename Path::value_type>) {
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
return RemoveDirRecursively(ToU8String(path));
|
return RemoveDirRecursively(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
|
@ -301,11 +301,11 @@ template <typename Path>
|
||||||
*
|
*
|
||||||
* @returns True if all of the directory's contents are removed successfully, false otherwise.
|
* @returns True if all of the directory's contents are removed successfully, false otherwise.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool RemoveDirContentsRecursively(const std::filesystem::path& path);
|
bool RemoveDirContentsRecursively(const std::filesystem::path& path);
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
template <typename Path>
|
template <typename Path>
|
||||||
[[nodiscard]] bool RemoveDirContentsRecursively(const Path& path) {
|
bool RemoveDirContentsRecursively(const Path& path) {
|
||||||
if constexpr (IsChar<typename Path::value_type>) {
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
return RemoveDirContentsRecursively(ToU8String(path));
|
return RemoveDirContentsRecursively(ToU8String(path));
|
||||||
} else {
|
} else {
|
||||||
|
@ -435,11 +435,13 @@ template <typename Path>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether a filesystem object at path is a file.
|
* Returns whether a filesystem object at path is a regular file.
|
||||||
|
* A regular file is a file that stores text or binary data.
|
||||||
|
* It is not a directory, symlink, FIFO, socket, block device, or character device.
|
||||||
*
|
*
|
||||||
* @param path Filesystem path
|
* @param path Filesystem path
|
||||||
*
|
*
|
||||||
* @returns True if a filesystem object at path is a file, false otherwise.
|
* @returns True if a filesystem object at path is a regular file, false otherwise.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] bool IsFile(const std::filesystem::path& path);
|
[[nodiscard]] bool IsFile(const std::filesystem::path& path);
|
||||||
|
|
||||||
|
|
|
@ -159,7 +159,7 @@ FileBackend::FileBackend(const std::filesystem::path& filename) {
|
||||||
|
|
||||||
// Existence checks are done within the functions themselves.
|
// Existence checks are done within the functions themselves.
|
||||||
// We don't particularly care if these succeed or not.
|
// We don't particularly care if these succeed or not.
|
||||||
void(FS::RemoveFile(old_filename));
|
FS::RemoveFile(old_filename);
|
||||||
void(FS::RenameFile(filename, old_filename));
|
void(FS::RenameFile(filename, old_filename));
|
||||||
|
|
||||||
file =
|
file =
|
||||||
|
@ -186,7 +186,7 @@ void FileBackend::Write(const Entry& entry) {
|
||||||
|
|
||||||
bytes_written += file->WriteString(FormatLogMessage(entry).append(1, '\n'));
|
bytes_written += file->WriteString(FormatLogMessage(entry).append(1, '\n'));
|
||||||
if (entry.log_level >= Level::Error) {
|
if (entry.log_level >= Level::Error) {
|
||||||
void(file->Flush());
|
file->Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,6 +139,7 @@ add_library(core STATIC
|
||||||
frontend/input.h
|
frontend/input.h
|
||||||
hardware_interrupt_manager.cpp
|
hardware_interrupt_manager.cpp
|
||||||
hardware_interrupt_manager.h
|
hardware_interrupt_manager.h
|
||||||
|
hle/api_version.h
|
||||||
hle/ipc.h
|
hle/ipc.h
|
||||||
hle/ipc_helpers.h
|
hle/ipc_helpers.h
|
||||||
hle/kernel/board/nintendo/nx/k_system_control.cpp
|
hle/kernel/board/nintendo/nx/k_system_control.cpp
|
||||||
|
@ -550,6 +551,8 @@ add_library(core STATIC
|
||||||
hle/service/spl/module.h
|
hle/service/spl/module.h
|
||||||
hle/service/spl/spl.cpp
|
hle/service/spl/spl.cpp
|
||||||
hle/service/spl/spl.h
|
hle/service/spl/spl.h
|
||||||
|
hle/service/spl/spl_results.h
|
||||||
|
hle/service/spl/spl_types.h
|
||||||
hle/service/ssl/ssl.cpp
|
hle/service/ssl/ssl.cpp
|
||||||
hle/service/ssl/ssl.h
|
hle/service/ssl/ssl.h
|
||||||
hle/service/time/clock_types.h
|
hle/service/time/clock_types.h
|
||||||
|
|
|
@ -345,8 +345,10 @@ std::vector<Core::Memory::CheatEntry> PatchManager::CreateCheatList(
|
||||||
static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type,
|
static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType type,
|
||||||
const Service::FileSystem::FileSystemController& fs_controller) {
|
const Service::FileSystem::FileSystemController& fs_controller) {
|
||||||
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
const auto load_dir = fs_controller.GetModificationLoadRoot(title_id);
|
||||||
|
const auto sdmc_load_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
|
||||||
if ((type != ContentRecordType::Program && type != ContentRecordType::Data) ||
|
if ((type != ContentRecordType::Program && type != ContentRecordType::Data) ||
|
||||||
load_dir == nullptr || load_dir->GetSize() <= 0) {
|
((load_dir == nullptr || load_dir->GetSize() <= 0) &&
|
||||||
|
(sdmc_load_dir == nullptr || sdmc_load_dir->GetSize() <= 0))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -356,7 +358,10 @@ static void ApplyLayeredFS(VirtualFile& romfs, u64 title_id, ContentRecordType t
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto& disabled = Settings::values.disabled_addons[title_id];
|
const auto& disabled = Settings::values.disabled_addons[title_id];
|
||||||
auto patch_dirs = load_dir->GetSubdirectories();
|
std::vector<VirtualDir> patch_dirs = load_dir->GetSubdirectories();
|
||||||
|
if (std::find(disabled.cbegin(), disabled.cend(), "SDMC") == disabled.cend()) {
|
||||||
|
patch_dirs.push_back(sdmc_load_dir);
|
||||||
|
}
|
||||||
std::sort(patch_dirs.begin(), patch_dirs.end(),
|
std::sort(patch_dirs.begin(), patch_dirs.end(),
|
||||||
[](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); });
|
[](const VirtualDir& l, const VirtualDir& r) { return l->GetName() < r->GetName(); });
|
||||||
|
|
||||||
|
@ -524,6 +529,15 @@ PatchManager::PatchVersionNames PatchManager::GetPatchVersionNames(VirtualFile u
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SDMC mod directory (RomFS LayeredFS)
|
||||||
|
const auto sdmc_mod_dir = fs_controller.GetSDMCModificationLoadRoot(title_id);
|
||||||
|
if (sdmc_mod_dir != nullptr && sdmc_mod_dir->GetSize() > 0 &&
|
||||||
|
IsDirValidAndNonEmpty(FindSubdirectoryCaseless(sdmc_mod_dir, "romfs"))) {
|
||||||
|
const auto mod_disabled =
|
||||||
|
std::find(disabled.begin(), disabled.end(), "SDMC") != disabled.end();
|
||||||
|
out.insert_or_assign(mod_disabled ? "[D] SDMC" : "SDMC", "LayeredFS");
|
||||||
|
}
|
||||||
|
|
||||||
// DLC
|
// DLC
|
||||||
const auto dlc_entries =
|
const auto dlc_entries =
|
||||||
content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data);
|
content_provider.ListEntriesFilter(TitleType::AOC, ContentRecordType::Data);
|
||||||
|
|
|
@ -27,6 +27,14 @@ ResultVal<VirtualDir> SDMCFactory::Open() const {
|
||||||
return MakeResult<VirtualDir>(dir);
|
return MakeResult<VirtualDir>(dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VirtualDir SDMCFactory::GetSDMCModificationLoadRoot(u64 title_id) const {
|
||||||
|
// LayeredFS doesn't work on updates and title id-less homebrew
|
||||||
|
if (title_id == 0 || (title_id & 0xFFF) == 0x800) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
return GetOrCreateDirectoryRelative(dir, fmt::format("/atmosphere/contents/{:016X}", title_id));
|
||||||
|
}
|
||||||
|
|
||||||
VirtualDir SDMCFactory::GetSDMCContentDirectory() const {
|
VirtualDir SDMCFactory::GetSDMCContentDirectory() const {
|
||||||
return GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents");
|
return GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents");
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@ public:
|
||||||
|
|
||||||
ResultVal<VirtualDir> Open() const;
|
ResultVal<VirtualDir> Open() const;
|
||||||
|
|
||||||
|
VirtualDir GetSDMCModificationLoadRoot(u64 title_id) const;
|
||||||
VirtualDir GetSDMCContentDirectory() const;
|
VirtualDir GetSDMCContentDirectory() const;
|
||||||
|
|
||||||
RegisteredCache* GetSDMCContents() const;
|
RegisteredCache* GetSDMCContents() const;
|
||||||
|
|
|
@ -4,47 +4,29 @@
|
||||||
|
|
||||||
#include "core/file_sys/system_archive/system_version.h"
|
#include "core/file_sys/system_archive/system_version.h"
|
||||||
#include "core/file_sys/vfs_vector.h"
|
#include "core/file_sys/vfs_vector.h"
|
||||||
|
#include "core/hle/api_version.h"
|
||||||
|
|
||||||
namespace FileSys::SystemArchive {
|
namespace FileSys::SystemArchive {
|
||||||
|
|
||||||
namespace SystemVersionData {
|
|
||||||
|
|
||||||
// This section should reflect the best system version to describe yuzu's HLE api.
|
|
||||||
// TODO(DarkLordZach): Update when HLE gets better.
|
|
||||||
|
|
||||||
constexpr u8 VERSION_MAJOR = 11;
|
|
||||||
constexpr u8 VERSION_MINOR = 0;
|
|
||||||
constexpr u8 VERSION_MICRO = 1;
|
|
||||||
|
|
||||||
constexpr u8 REVISION_MAJOR = 1;
|
|
||||||
constexpr u8 REVISION_MINOR = 0;
|
|
||||||
|
|
||||||
constexpr char PLATFORM_STRING[] = "NX";
|
|
||||||
constexpr char VERSION_HASH[] = "69103fcb2004dace877094c2f8c29e6113be5dbf";
|
|
||||||
constexpr char DISPLAY_VERSION[] = "11.0.1";
|
|
||||||
constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 11.0.1-1.0";
|
|
||||||
|
|
||||||
} // namespace SystemVersionData
|
|
||||||
|
|
||||||
std::string GetLongDisplayVersion() {
|
std::string GetLongDisplayVersion() {
|
||||||
return SystemVersionData::DISPLAY_TITLE;
|
return HLE::ApiVersion::DISPLAY_TITLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualDir SystemVersion() {
|
VirtualDir SystemVersion() {
|
||||||
VirtualFile file = std::make_shared<VectorVfsFile>(std::vector<u8>(0x100), "file");
|
VirtualFile file = std::make_shared<VectorVfsFile>(std::vector<u8>(0x100), "file");
|
||||||
file->WriteObject(SystemVersionData::VERSION_MAJOR, 0);
|
file->WriteObject(HLE::ApiVersion::HOS_VERSION_MAJOR, 0);
|
||||||
file->WriteObject(SystemVersionData::VERSION_MINOR, 1);
|
file->WriteObject(HLE::ApiVersion::HOS_VERSION_MINOR, 1);
|
||||||
file->WriteObject(SystemVersionData::VERSION_MICRO, 2);
|
file->WriteObject(HLE::ApiVersion::HOS_VERSION_MICRO, 2);
|
||||||
file->WriteObject(SystemVersionData::REVISION_MAJOR, 4);
|
file->WriteObject(HLE::ApiVersion::SDK_REVISION_MAJOR, 4);
|
||||||
file->WriteObject(SystemVersionData::REVISION_MINOR, 5);
|
file->WriteObject(HLE::ApiVersion::SDK_REVISION_MINOR, 5);
|
||||||
file->WriteArray(SystemVersionData::PLATFORM_STRING,
|
file->WriteArray(HLE::ApiVersion::PLATFORM_STRING,
|
||||||
std::min<u64>(sizeof(SystemVersionData::PLATFORM_STRING), 0x20ULL), 0x8);
|
std::min<u64>(sizeof(HLE::ApiVersion::PLATFORM_STRING), 0x20ULL), 0x8);
|
||||||
file->WriteArray(SystemVersionData::VERSION_HASH,
|
file->WriteArray(HLE::ApiVersion::VERSION_HASH,
|
||||||
std::min<u64>(sizeof(SystemVersionData::VERSION_HASH), 0x40ULL), 0x28);
|
std::min<u64>(sizeof(HLE::ApiVersion::VERSION_HASH), 0x40ULL), 0x28);
|
||||||
file->WriteArray(SystemVersionData::DISPLAY_VERSION,
|
file->WriteArray(HLE::ApiVersion::DISPLAY_VERSION,
|
||||||
std::min<u64>(sizeof(SystemVersionData::DISPLAY_VERSION), 0x18ULL), 0x68);
|
std::min<u64>(sizeof(HLE::ApiVersion::DISPLAY_VERSION), 0x18ULL), 0x68);
|
||||||
file->WriteArray(SystemVersionData::DISPLAY_TITLE,
|
file->WriteArray(HLE::ApiVersion::DISPLAY_TITLE,
|
||||||
std::min<u64>(sizeof(SystemVersionData::DISPLAY_TITLE), 0x80ULL), 0x80);
|
std::min<u64>(sizeof(HLE::ApiVersion::DISPLAY_TITLE), 0x80ULL), 0x80);
|
||||||
return std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{file},
|
return std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{file},
|
||||||
std::vector<VirtualDir>{}, "data");
|
std::vector<VirtualDir>{}, "data");
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,17 +24,12 @@ constexpr FS::FileAccessMode ModeFlagsToFileAccessMode(Mode mode) {
|
||||||
case Mode::Read:
|
case Mode::Read:
|
||||||
return FS::FileAccessMode::Read;
|
return FS::FileAccessMode::Read;
|
||||||
case Mode::Write:
|
case Mode::Write:
|
||||||
return FS::FileAccessMode::Write;
|
|
||||||
case Mode::ReadWrite:
|
case Mode::ReadWrite:
|
||||||
return FS::FileAccessMode::ReadWrite;
|
|
||||||
case Mode::Append:
|
case Mode::Append:
|
||||||
return FS::FileAccessMode::Append;
|
|
||||||
case Mode::ReadAppend:
|
case Mode::ReadAppend:
|
||||||
return FS::FileAccessMode::ReadAppend;
|
|
||||||
case Mode::WriteAppend:
|
case Mode::WriteAppend:
|
||||||
return FS::FileAccessMode::Append;
|
|
||||||
case Mode::All:
|
case Mode::All:
|
||||||
return FS::FileAccessMode::ReadAppend;
|
return FS::FileAccessMode::ReadWrite;
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
38
src/core/hle/api_version.h
Executable file
38
src/core/hle/api_version.h
Executable file
|
@ -0,0 +1,38 @@
|
||||||
|
// Copyright 2021 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
// This file contains yuzu's HLE API version constants.
|
||||||
|
|
||||||
|
namespace HLE::ApiVersion {
|
||||||
|
|
||||||
|
// Horizon OS version constants.
|
||||||
|
|
||||||
|
constexpr u8 HOS_VERSION_MAJOR = 11;
|
||||||
|
constexpr u8 HOS_VERSION_MINOR = 0;
|
||||||
|
constexpr u8 HOS_VERSION_MICRO = 1;
|
||||||
|
|
||||||
|
// NintendoSDK version constants.
|
||||||
|
|
||||||
|
constexpr u8 SDK_REVISION_MAJOR = 1;
|
||||||
|
constexpr u8 SDK_REVISION_MINOR = 0;
|
||||||
|
|
||||||
|
constexpr char PLATFORM_STRING[] = "NX";
|
||||||
|
constexpr char VERSION_HASH[] = "69103fcb2004dace877094c2f8c29e6113be5dbf";
|
||||||
|
constexpr char DISPLAY_VERSION[] = "11.0.1";
|
||||||
|
constexpr char DISPLAY_TITLE[] = "NintendoSDK Firmware for NX 11.0.1-1.0";
|
||||||
|
|
||||||
|
// Atmosphere version constants.
|
||||||
|
|
||||||
|
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MAJOR = 0;
|
||||||
|
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MINOR = 19;
|
||||||
|
constexpr u8 ATMOSPHERE_RELEASE_VERSION_MICRO = 4;
|
||||||
|
|
||||||
|
constexpr u32 GetTargetFirmware() {
|
||||||
|
return u32{HOS_VERSION_MAJOR} << 24 | u32{HOS_VERSION_MINOR} << 16 |
|
||||||
|
u32{HOS_VERSION_MICRO} << 8 | 0U;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace HLE::ApiVersion
|
|
@ -313,7 +313,7 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe
|
||||||
LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
|
LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
|
||||||
|
|
||||||
if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
|
if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
|
||||||
void(Common::FS::RemoveFile(zip_path));
|
Common::FS::RemoveFile(zip_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleDownloadDisplayResult(applet_manager, res);
|
HandleDownloadDisplayResult(applet_manager, res);
|
||||||
|
@ -445,7 +445,7 @@ std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title)
|
||||||
LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
|
LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
|
||||||
|
|
||||||
if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
|
if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
|
||||||
void(Common::FS::RemoveFile(bin_file_path));
|
Common::FS::RemoveFile(bin_file_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleDownloadDisplayResult(applet_manager, res);
|
HandleDownloadDisplayResult(applet_manager, res);
|
||||||
|
|
|
@ -703,6 +703,16 @@ FileSys::VirtualDir FileSystemController::GetModificationLoadRoot(u64 title_id)
|
||||||
return bis_factory->GetModificationLoadRoot(title_id);
|
return bis_factory->GetModificationLoadRoot(title_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileSys::VirtualDir FileSystemController::GetSDMCModificationLoadRoot(u64 title_id) const {
|
||||||
|
LOG_TRACE(Service_FS, "Opening SDMC mod load root for tid={:016X}", title_id);
|
||||||
|
|
||||||
|
if (sdmc_factory == nullptr) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sdmc_factory->GetSDMCModificationLoadRoot(title_id);
|
||||||
|
}
|
||||||
|
|
||||||
FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const {
|
FileSys::VirtualDir FileSystemController::GetModificationDumpRoot(u64 title_id) const {
|
||||||
LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id);
|
LOG_TRACE(Service_FS, "Opening mod dump root for tid={:016X}", title_id);
|
||||||
|
|
||||||
|
|
|
@ -115,6 +115,7 @@ public:
|
||||||
FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const;
|
FileSys::VirtualDir GetContentDirectory(ContentStorageId id) const;
|
||||||
FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const;
|
FileSys::VirtualDir GetImageDirectory(ImageDirectoryId id) const;
|
||||||
|
|
||||||
|
FileSys::VirtualDir GetSDMCModificationLoadRoot(u64 title_id) const;
|
||||||
FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const;
|
FileSys::VirtualDir GetModificationLoadRoot(u64 title_id) const;
|
||||||
FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const;
|
FileSys::VirtualDir GetModificationDumpRoot(u64 title_id) const;
|
||||||
|
|
||||||
|
|
|
@ -314,6 +314,8 @@ void Controller_NPad::OnInit() {
|
||||||
|
|
||||||
void Controller_NPad::OnLoadInputDevices() {
|
void Controller_NPad::OnLoadInputDevices() {
|
||||||
const auto& players = Settings::values.players.GetValue();
|
const auto& players = Settings::values.players.GetValue();
|
||||||
|
|
||||||
|
std::lock_guard lock{mutex};
|
||||||
for (std::size_t i = 0; i < players.size(); ++i) {
|
for (std::size_t i = 0; i < players.size(); ++i) {
|
||||||
std::transform(players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
|
std::transform(players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
|
||||||
players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
|
players[i].buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
|
||||||
|
@ -348,6 +350,8 @@ void Controller_NPad::OnRelease() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
|
void Controller_NPad::RequestPadStateUpdate(u32 npad_id) {
|
||||||
|
std::lock_guard lock{mutex};
|
||||||
|
|
||||||
const auto controller_idx = NPadIdToIndex(npad_id);
|
const auto controller_idx = NPadIdToIndex(npad_id);
|
||||||
const auto controller_type = connected_controllers[controller_idx].type;
|
const auto controller_type = connected_controllers[controller_idx].type;
|
||||||
if (!connected_controllers[controller_idx].is_connected) {
|
if (!connected_controllers[controller_idx].is_connected) {
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include "common/bit_field.h"
|
#include "common/bit_field.h"
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/quaternion.h"
|
#include "common/quaternion.h"
|
||||||
|
@ -563,6 +565,8 @@ private:
|
||||||
using MotionArray = std::array<
|
using MotionArray = std::array<
|
||||||
std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>,
|
std::array<std::unique_ptr<Input::MotionDevice>, Settings::NativeMotion::NUM_MOTIONS_HID>,
|
||||||
10>;
|
10>;
|
||||||
|
|
||||||
|
std::mutex mutex;
|
||||||
ButtonArray buttons;
|
ButtonArray buttons;
|
||||||
StickArray sticks;
|
StickArray sticks;
|
||||||
VibrationArray vibrations;
|
VibrationArray vibrations;
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace Service::SPL {
|
||||||
CSRNG::CSRNG(Core::System& system_, std::shared_ptr<Module> module_)
|
CSRNG::CSRNG(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
: Interface(system_, std::move(module_), "csrng") {
|
: Interface(system_, std::move(module_), "csrng") {
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, &CSRNG::GetRandomBytes, "GetRandomBytes"},
|
{0, &CSRNG::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||||
};
|
};
|
||||||
RegisterHandlers(functions);
|
RegisterHandlers(functions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
|
#include "core/hle/api_version.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/service/spl/csrng.h"
|
#include "core/hle/service/spl/csrng.h"
|
||||||
#include "core/hle/service/spl/module.h"
|
#include "core/hle/service/spl/module.h"
|
||||||
|
@ -24,7 +25,46 @@ Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> modu
|
||||||
|
|
||||||
Module::Interface::~Interface() = default;
|
Module::Interface::~Interface() = default;
|
||||||
|
|
||||||
void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
|
void Module::Interface::GetConfig(Kernel::HLERequestContext& ctx) {
|
||||||
|
IPC::RequestParser rp{ctx};
|
||||||
|
const auto config_item = rp.PopEnum<ConfigItem>();
|
||||||
|
|
||||||
|
// This should call svcCallSecureMonitor with the appropriate args.
|
||||||
|
// Since we do not have it implemented yet, we will use this for now.
|
||||||
|
const auto smc_result = GetConfigImpl(config_item);
|
||||||
|
const auto result_code = smc_result.Code();
|
||||||
|
|
||||||
|
if (smc_result.Failed()) {
|
||||||
|
LOG_ERROR(Service_SPL, "called, config_item={}, result_code={}", config_item,
|
||||||
|
result_code.raw);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(result_code);
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_DEBUG(Service_SPL, "called, config_item={}, result_code={}, smc_result={}", config_item,
|
||||||
|
result_code.raw, *smc_result);
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
|
rb.Push(result_code);
|
||||||
|
rb.Push(*smc_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::Interface::ModularExponentiate(Kernel::HLERequestContext& ctx) {
|
||||||
|
UNIMPLEMENTED_MSG("ModularExponentiate is not implemented!");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSecureMonitorNotImplemented);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::Interface::SetConfig(Kernel::HLERequestContext& ctx) {
|
||||||
|
UNIMPLEMENTED_MSG("SetConfig is not implemented!");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSecureMonitorNotImplemented);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::Interface::GenerateRandomBytes(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_SPL, "called");
|
LOG_DEBUG(Service_SPL, "called");
|
||||||
|
|
||||||
const std::size_t size = ctx.GetWriteBufferSize();
|
const std::size_t size = ctx.GetWriteBufferSize();
|
||||||
|
@ -39,6 +79,88 @@ void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Module::Interface::IsDevelopment(Kernel::HLERequestContext& ctx) {
|
||||||
|
UNIMPLEMENTED_MSG("IsDevelopment is not implemented!");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSecureMonitorNotImplemented);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::Interface::SetBootReason(Kernel::HLERequestContext& ctx) {
|
||||||
|
UNIMPLEMENTED_MSG("SetBootReason is not implemented!");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSecureMonitorNotImplemented);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Module::Interface::GetBootReason(Kernel::HLERequestContext& ctx) {
|
||||||
|
UNIMPLEMENTED_MSG("GetBootReason is not implemented!");
|
||||||
|
|
||||||
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
|
rb.Push(ResultSecureMonitorNotImplemented);
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultVal<u64> Module::Interface::GetConfigImpl(ConfigItem config_item) const {
|
||||||
|
switch (config_item) {
|
||||||
|
case ConfigItem::DisableProgramVerification:
|
||||||
|
case ConfigItem::DramId:
|
||||||
|
case ConfigItem::SecurityEngineInterruptNumber:
|
||||||
|
case ConfigItem::FuseVersion:
|
||||||
|
case ConfigItem::HardwareType:
|
||||||
|
case ConfigItem::HardwareState:
|
||||||
|
case ConfigItem::IsRecoveryBoot:
|
||||||
|
case ConfigItem::DeviceId:
|
||||||
|
case ConfigItem::BootReason:
|
||||||
|
case ConfigItem::MemoryMode:
|
||||||
|
case ConfigItem::IsDevelopmentFunctionEnabled:
|
||||||
|
case ConfigItem::KernelConfiguration:
|
||||||
|
case ConfigItem::IsChargerHiZModeEnabled:
|
||||||
|
case ConfigItem::QuestState:
|
||||||
|
case ConfigItem::RegulatorType:
|
||||||
|
case ConfigItem::DeviceUniqueKeyGeneration:
|
||||||
|
case ConfigItem::Package2Hash:
|
||||||
|
return ResultSecureMonitorNotImplemented;
|
||||||
|
case ConfigItem::ExosphereApiVersion:
|
||||||
|
// Get information about the current exosphere version.
|
||||||
|
return MakeResult((u64{HLE::ApiVersion::ATMOSPHERE_RELEASE_VERSION_MAJOR} << 56) |
|
||||||
|
(u64{HLE::ApiVersion::ATMOSPHERE_RELEASE_VERSION_MINOR} << 48) |
|
||||||
|
(u64{HLE::ApiVersion::ATMOSPHERE_RELEASE_VERSION_MICRO} << 40) |
|
||||||
|
(static_cast<u64>(HLE::ApiVersion::GetTargetFirmware())));
|
||||||
|
case ConfigItem::ExosphereNeedsReboot:
|
||||||
|
// We are executing, so we aren't in the process of rebooting.
|
||||||
|
return MakeResult(u64{0});
|
||||||
|
case ConfigItem::ExosphereNeedsShutdown:
|
||||||
|
// We are executing, so we aren't in the process of shutting down.
|
||||||
|
return MakeResult(u64{0});
|
||||||
|
case ConfigItem::ExosphereGitCommitHash:
|
||||||
|
// Get information about the current exosphere git commit hash.
|
||||||
|
return MakeResult(u64{0});
|
||||||
|
case ConfigItem::ExosphereHasRcmBugPatch:
|
||||||
|
// Get information about whether this unit has the RCM bug patched.
|
||||||
|
return MakeResult(u64{0});
|
||||||
|
case ConfigItem::ExosphereBlankProdInfo:
|
||||||
|
// Get whether this unit should simulate a "blanked" PRODINFO.
|
||||||
|
return MakeResult(u64{0});
|
||||||
|
case ConfigItem::ExosphereAllowCalWrites:
|
||||||
|
// Get whether this unit should allow writing to the calibration partition.
|
||||||
|
return MakeResult(u64{0});
|
||||||
|
case ConfigItem::ExosphereEmummcType:
|
||||||
|
// Get what kind of emummc this unit has active.
|
||||||
|
return MakeResult(u64{0});
|
||||||
|
case ConfigItem::ExospherePayloadAddress:
|
||||||
|
// Gets the physical address of the reboot payload buffer, if one exists.
|
||||||
|
return ResultSecureMonitorNotInitialized;
|
||||||
|
case ConfigItem::ExosphereLogConfiguration:
|
||||||
|
// Get the log configuration.
|
||||||
|
return MakeResult(u64{0});
|
||||||
|
case ConfigItem::ExosphereForceEnableUsb30:
|
||||||
|
// Get whether usb 3.0 should be force-enabled.
|
||||||
|
return MakeResult(u64{0});
|
||||||
|
default:
|
||||||
|
return ResultSecureMonitorInvalidArgument;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
|
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
|
||||||
auto module = std::make_shared<Module>();
|
auto module = std::make_shared<Module>();
|
||||||
std::make_shared<CSRNG>(system, module)->InstallAsService(service_manager);
|
std::make_shared<CSRNG>(system, module)->InstallAsService(service_manager);
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
|
|
||||||
#include <random>
|
#include <random>
|
||||||
#include "core/hle/service/service.h"
|
#include "core/hle/service/service.h"
|
||||||
|
#include "core/hle/service/spl/spl_results.h"
|
||||||
|
#include "core/hle/service/spl/spl_types.h"
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class System;
|
class System;
|
||||||
|
@ -21,12 +23,21 @@ public:
|
||||||
const char* name);
|
const char* name);
|
||||||
~Interface() override;
|
~Interface() override;
|
||||||
|
|
||||||
void GetRandomBytes(Kernel::HLERequestContext& ctx);
|
// General
|
||||||
|
void GetConfig(Kernel::HLERequestContext& ctx);
|
||||||
|
void ModularExponentiate(Kernel::HLERequestContext& ctx);
|
||||||
|
void SetConfig(Kernel::HLERequestContext& ctx);
|
||||||
|
void GenerateRandomBytes(Kernel::HLERequestContext& ctx);
|
||||||
|
void IsDevelopment(Kernel::HLERequestContext& ctx);
|
||||||
|
void SetBootReason(Kernel::HLERequestContext& ctx);
|
||||||
|
void GetBootReason(Kernel::HLERequestContext& ctx);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<Module> module;
|
std::shared_ptr<Module> module;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
ResultVal<u64> GetConfigImpl(ConfigItem config_item) const;
|
||||||
|
|
||||||
std::mt19937 rng;
|
std::mt19937 rng;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,13 +10,13 @@ SPL::SPL(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
: Interface(system_, std::move(module_), "spl:") {
|
: Interface(system_, std::move(module_), "spl:") {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "GetConfig"},
|
{0, &SPL::GetConfig, "GetConfig"},
|
||||||
{1, nullptr, "ModularExponentiate"},
|
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||||
{5, nullptr, "SetConfig"},
|
{5, &SPL::SetConfig, "SetConfig"},
|
||||||
{7, &SPL::GetRandomBytes, "GetRandomBytes"},
|
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||||
{11, nullptr, "IsDevelopment"},
|
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||||
{24, nullptr, "SetBootReason"},
|
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||||
{25, nullptr, "GetBootReason"},
|
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
@ -27,22 +27,22 @@ SPL_MIG::SPL_MIG(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
: Interface(system_, std::move(module_), "spl:mig") {
|
: Interface(system_, std::move(module_), "spl:mig") {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "GetConfig"},
|
{0, &SPL::GetConfig, "GetConfig"},
|
||||||
{1, nullptr, "ModularExponentiate"},
|
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||||
{2, nullptr, "GenerateAesKek"},
|
{2, nullptr, "GenerateAesKek"},
|
||||||
{3, nullptr, "LoadAesKey"},
|
{3, nullptr, "LoadAesKey"},
|
||||||
{4, nullptr, "GenerateAesKey"},
|
{4, nullptr, "GenerateAesKey"},
|
||||||
{5, nullptr, "SetConfig"},
|
{5, &SPL::SetConfig, "SetConfig"},
|
||||||
{7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
|
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||||
{11, nullptr, "IsDevelopment"},
|
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||||
{14, nullptr, "DecryptAesKey"},
|
{14, nullptr, "DecryptAesKey"},
|
||||||
{15, nullptr, "CryptAesCtr"},
|
{15, nullptr, "CryptAesCtr"},
|
||||||
{16, nullptr, "ComputeCmac"},
|
{16, nullptr, "ComputeCmac"},
|
||||||
{21, nullptr, "AllocateAesKeyslot"},
|
{21, nullptr, "AllocateAesKeyslot"},
|
||||||
{22, nullptr, "DeallocateAesKeySlot"},
|
{22, nullptr, "DeallocateAesKeySlot"},
|
||||||
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
||||||
{24, nullptr, "SetBootReason"},
|
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||||
{25, nullptr, "GetBootReason"},
|
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
@ -53,16 +53,16 @@ SPL_FS::SPL_FS(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
: Interface(system_, std::move(module_), "spl:fs") {
|
: Interface(system_, std::move(module_), "spl:fs") {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "GetConfig"},
|
{0, &SPL::GetConfig, "GetConfig"},
|
||||||
{1, nullptr, "ModularExponentiate"},
|
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||||
{2, nullptr, "GenerateAesKek"},
|
{2, nullptr, "GenerateAesKek"},
|
||||||
{3, nullptr, "LoadAesKey"},
|
{3, nullptr, "LoadAesKey"},
|
||||||
{4, nullptr, "GenerateAesKey"},
|
{4, nullptr, "GenerateAesKey"},
|
||||||
{5, nullptr, "SetConfig"},
|
{5, &SPL::SetConfig, "SetConfig"},
|
||||||
{7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
|
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||||
{9, nullptr, "ImportLotusKey"},
|
{9, nullptr, "ImportLotusKey"},
|
||||||
{10, nullptr, "DecryptLotusMessage"},
|
{10, nullptr, "DecryptLotusMessage"},
|
||||||
{11, nullptr, "IsDevelopment"},
|
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||||
{12, nullptr, "GenerateSpecificAesKey"},
|
{12, nullptr, "GenerateSpecificAesKey"},
|
||||||
{14, nullptr, "DecryptAesKey"},
|
{14, nullptr, "DecryptAesKey"},
|
||||||
{15, nullptr, "CryptAesCtr"},
|
{15, nullptr, "CryptAesCtr"},
|
||||||
|
@ -71,8 +71,8 @@ SPL_FS::SPL_FS(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
{21, nullptr, "AllocateAesKeyslot"},
|
{21, nullptr, "AllocateAesKeyslot"},
|
||||||
{22, nullptr, "DeallocateAesKeySlot"},
|
{22, nullptr, "DeallocateAesKeySlot"},
|
||||||
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
||||||
{24, nullptr, "SetBootReason"},
|
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||||
{25, nullptr, "GetBootReason"},
|
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||||
{31, nullptr, "GetPackage2Hash"},
|
{31, nullptr, "GetPackage2Hash"},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
@ -84,14 +84,14 @@ SPL_SSL::SPL_SSL(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
: Interface(system_, std::move(module_), "spl:ssl") {
|
: Interface(system_, std::move(module_), "spl:ssl") {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "GetConfig"},
|
{0, &SPL::GetConfig, "GetConfig"},
|
||||||
{1, nullptr, "ModularExponentiate"},
|
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||||
{2, nullptr, "GenerateAesKek"},
|
{2, nullptr, "GenerateAesKek"},
|
||||||
{3, nullptr, "LoadAesKey"},
|
{3, nullptr, "LoadAesKey"},
|
||||||
{4, nullptr, "GenerateAesKey"},
|
{4, nullptr, "GenerateAesKey"},
|
||||||
{5, nullptr, "SetConfig"},
|
{5, &SPL::SetConfig, "SetConfig"},
|
||||||
{7, &SPL::GetRandomBytes, "GetRandomBytes"},
|
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||||
{11, nullptr, "IsDevelopment"},
|
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||||
{13, nullptr, "DecryptDeviceUniqueData"},
|
{13, nullptr, "DecryptDeviceUniqueData"},
|
||||||
{14, nullptr, "DecryptAesKey"},
|
{14, nullptr, "DecryptAesKey"},
|
||||||
{15, nullptr, "CryptAesCtr"},
|
{15, nullptr, "CryptAesCtr"},
|
||||||
|
@ -99,8 +99,8 @@ SPL_SSL::SPL_SSL(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
{21, nullptr, "AllocateAesKeyslot"},
|
{21, nullptr, "AllocateAesKeyslot"},
|
||||||
{22, nullptr, "DeallocateAesKeySlot"},
|
{22, nullptr, "DeallocateAesKeySlot"},
|
||||||
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
||||||
{24, nullptr, "SetBootReason"},
|
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||||
{25, nullptr, "GetBootReason"},
|
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||||
{26, nullptr, "DecryptAndStoreSslClientCertKey"},
|
{26, nullptr, "DecryptAndStoreSslClientCertKey"},
|
||||||
{27, nullptr, "ModularExponentiateWithSslClientCertKey"},
|
{27, nullptr, "ModularExponentiateWithSslClientCertKey"},
|
||||||
};
|
};
|
||||||
|
@ -113,14 +113,14 @@ SPL_ES::SPL_ES(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
: Interface(system_, std::move(module_), "spl:es") {
|
: Interface(system_, std::move(module_), "spl:es") {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "GetConfig"},
|
{0, &SPL::GetConfig, "GetConfig"},
|
||||||
{1, nullptr, "ModularExponentiate"},
|
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||||
{2, nullptr, "GenerateAesKek"},
|
{2, nullptr, "GenerateAesKek"},
|
||||||
{3, nullptr, "LoadAesKey"},
|
{3, nullptr, "LoadAesKey"},
|
||||||
{4, nullptr, "GenerateAesKey"},
|
{4, nullptr, "GenerateAesKey"},
|
||||||
{5, nullptr, "SetConfig"},
|
{5, &SPL::SetConfig, "SetConfig"},
|
||||||
{7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
|
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||||
{11, nullptr, "IsDevelopment"},
|
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||||
{13, nullptr, "DecryptDeviceUniqueData"},
|
{13, nullptr, "DecryptDeviceUniqueData"},
|
||||||
{14, nullptr, "DecryptAesKey"},
|
{14, nullptr, "DecryptAesKey"},
|
||||||
{15, nullptr, "CryptAesCtr"},
|
{15, nullptr, "CryptAesCtr"},
|
||||||
|
@ -131,8 +131,8 @@ SPL_ES::SPL_ES(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
{21, nullptr, "AllocateAesKeyslot"},
|
{21, nullptr, "AllocateAesKeyslot"},
|
||||||
{22, nullptr, "DeallocateAesKeySlot"},
|
{22, nullptr, "DeallocateAesKeySlot"},
|
||||||
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
||||||
{24, nullptr, "SetBootReason"},
|
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||||
{25, nullptr, "GetBootReason"},
|
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||||
{28, nullptr, "DecryptAndStoreDrmDeviceCertKey"},
|
{28, nullptr, "DecryptAndStoreDrmDeviceCertKey"},
|
||||||
{29, nullptr, "ModularExponentiateWithDrmDeviceCertKey"},
|
{29, nullptr, "ModularExponentiateWithDrmDeviceCertKey"},
|
||||||
{31, nullptr, "PrepareEsArchiveKey"},
|
{31, nullptr, "PrepareEsArchiveKey"},
|
||||||
|
@ -147,14 +147,14 @@ SPL_MANU::SPL_MANU(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
: Interface(system_, std::move(module_), "spl:manu") {
|
: Interface(system_, std::move(module_), "spl:manu") {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, nullptr, "GetConfig"},
|
{0, &SPL::GetConfig, "GetConfig"},
|
||||||
{1, nullptr, "ModularExponentiate"},
|
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||||
{2, nullptr, "GenerateAesKek"},
|
{2, nullptr, "GenerateAesKek"},
|
||||||
{3, nullptr, "LoadAesKey"},
|
{3, nullptr, "LoadAesKey"},
|
||||||
{4, nullptr, "GenerateAesKey"},
|
{4, nullptr, "GenerateAesKey"},
|
||||||
{5, nullptr, "SetConfig"},
|
{5, &SPL::SetConfig, "SetConfig"},
|
||||||
{7, &SPL::GetRandomBytes, "GetRandomBytes"},
|
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||||
{11, nullptr, "IsDevelopment"},
|
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||||
{13, nullptr, "DecryptDeviceUniqueData"},
|
{13, nullptr, "DecryptDeviceUniqueData"},
|
||||||
{14, nullptr, "DecryptAesKey"},
|
{14, nullptr, "DecryptAesKey"},
|
||||||
{15, nullptr, "CryptAesCtr"},
|
{15, nullptr, "CryptAesCtr"},
|
||||||
|
@ -162,8 +162,8 @@ SPL_MANU::SPL_MANU(Core::System& system_, std::shared_ptr<Module> module_)
|
||||||
{21, nullptr, "AllocateAesKeyslot"},
|
{21, nullptr, "AllocateAesKeyslot"},
|
||||||
{22, nullptr, "DeallocateAesKeySlot"},
|
{22, nullptr, "DeallocateAesKeySlot"},
|
||||||
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
||||||
{24, nullptr, "SetBootReason"},
|
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||||
{25, nullptr, "GetBootReason"},
|
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||||
{30, nullptr, "ReencryptDeviceUniqueData"},
|
{30, nullptr, "ReencryptDeviceUniqueData"},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
29
src/core/hle/service/spl/spl_results.h
Executable file
29
src/core/hle/service/spl/spl_results.h
Executable file
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2021 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
|
namespace Service::SPL {
|
||||||
|
|
||||||
|
// Description 0 - 99
|
||||||
|
constexpr ResultCode ResultSecureMonitorError{ErrorModule::SPL, 0};
|
||||||
|
constexpr ResultCode ResultSecureMonitorNotImplemented{ErrorModule::SPL, 1};
|
||||||
|
constexpr ResultCode ResultSecureMonitorInvalidArgument{ErrorModule::SPL, 2};
|
||||||
|
constexpr ResultCode ResultSecureMonitorBusy{ErrorModule::SPL, 3};
|
||||||
|
constexpr ResultCode ResultSecureMonitorNoAsyncOperation{ErrorModule::SPL, 4};
|
||||||
|
constexpr ResultCode ResultSecureMonitorInvalidAsyncOperation{ErrorModule::SPL, 5};
|
||||||
|
constexpr ResultCode ResultSecureMonitorNotPermitted{ErrorModule::SPL, 6};
|
||||||
|
constexpr ResultCode ResultSecureMonitorNotInitialized{ErrorModule::SPL, 7};
|
||||||
|
|
||||||
|
constexpr ResultCode ResultInvalidSize{ErrorModule::SPL, 100};
|
||||||
|
constexpr ResultCode ResultUnknownSecureMonitorError{ErrorModule::SPL, 101};
|
||||||
|
constexpr ResultCode ResultDecryptionFailed{ErrorModule::SPL, 102};
|
||||||
|
|
||||||
|
constexpr ResultCode ResultOutOfKeySlots{ErrorModule::SPL, 104};
|
||||||
|
constexpr ResultCode ResultInvalidKeySlot{ErrorModule::SPL, 105};
|
||||||
|
constexpr ResultCode ResultBootReasonAlreadySet{ErrorModule::SPL, 106};
|
||||||
|
constexpr ResultCode ResultBootReasonNotSet{ErrorModule::SPL, 107};
|
||||||
|
constexpr ResultCode ResultInvalidArgument{ErrorModule::SPL, 108};
|
||||||
|
|
||||||
|
} // namespace Service::SPL
|
230
src/core/hle/service/spl/spl_types.h
Executable file
230
src/core/hle/service/spl/spl_types.h
Executable file
|
@ -0,0 +1,230 @@
|
||||||
|
// Copyright 2021 yuzu Emulator Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <span>
|
||||||
|
|
||||||
|
#include "common/bit_field.h"
|
||||||
|
#include "common/common_types.h"
|
||||||
|
|
||||||
|
namespace Service::SPL {
|
||||||
|
|
||||||
|
constexpr size_t AES_128_KEY_SIZE = 0x10;
|
||||||
|
|
||||||
|
namespace Smc {
|
||||||
|
|
||||||
|
enum class FunctionId : u32 {
|
||||||
|
SetConfig = 0xC3000401,
|
||||||
|
GetConfig = 0xC3000002,
|
||||||
|
GetResult = 0xC3000003,
|
||||||
|
GetResultData = 0xC3000404,
|
||||||
|
ModularExponentiate = 0xC3000E05,
|
||||||
|
GenerateRandomBytes = 0xC3000006,
|
||||||
|
GenerateAesKek = 0xC3000007,
|
||||||
|
LoadAesKey = 0xC3000008,
|
||||||
|
ComputeAes = 0xC3000009,
|
||||||
|
GenerateSpecificAesKey = 0xC300000A,
|
||||||
|
ComputeCmac = 0xC300040B,
|
||||||
|
ReencryptDeviceUniqueData = 0xC300D60C,
|
||||||
|
DecryptDeviceUniqueData = 0xC300100D,
|
||||||
|
|
||||||
|
ModularExponentiateWithStorageKey = 0xC300060F,
|
||||||
|
PrepareEsDeviceUniqueKey = 0xC3000610,
|
||||||
|
LoadPreparedAesKey = 0xC3000011,
|
||||||
|
PrepareCommonEsTitleKey = 0xC3000012,
|
||||||
|
|
||||||
|
// Deprecated functions.
|
||||||
|
LoadEsDeviceKey = 0xC300100C,
|
||||||
|
DecryptAndStoreGcKey = 0xC300100E,
|
||||||
|
|
||||||
|
// Atmosphere functions.
|
||||||
|
AtmosphereIramCopy = 0xF0000201,
|
||||||
|
AtmosphereReadWriteRegister = 0xF0000002,
|
||||||
|
|
||||||
|
AtmosphereGetEmummcConfig = 0xF0000404,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class CipherMode {
|
||||||
|
CbcEncrypt = 0,
|
||||||
|
CbcDecrypt = 1,
|
||||||
|
Ctr = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DeviceUniqueDataMode {
|
||||||
|
DecryptDeviceUniqueData = 0,
|
||||||
|
DecryptAndStoreGcKey = 1,
|
||||||
|
DecryptAndStoreEsDeviceKey = 2,
|
||||||
|
DecryptAndStoreSslKey = 3,
|
||||||
|
DecryptAndStoreDrmDeviceCertKey = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class ModularExponentiateWithStorageKeyMode {
|
||||||
|
Gc = 0,
|
||||||
|
Ssl = 1,
|
||||||
|
DrmDeviceCert = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class EsCommonKeyType {
|
||||||
|
TitleKey = 0,
|
||||||
|
ArchiveKey = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AsyncOperationKey {
|
||||||
|
u64 value;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Smc
|
||||||
|
|
||||||
|
enum class HardwareType {
|
||||||
|
Icosa = 0,
|
||||||
|
Copper = 1,
|
||||||
|
Hoag = 2,
|
||||||
|
Iowa = 3,
|
||||||
|
Calcio = 4,
|
||||||
|
Aula = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class SocType {
|
||||||
|
Erista = 0,
|
||||||
|
Mariko = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class HardwareState {
|
||||||
|
Development = 0,
|
||||||
|
Production = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class MemoryArrangement {
|
||||||
|
Standard = 0,
|
||||||
|
StandardForAppletDev = 1,
|
||||||
|
StandardForSystemDev = 2,
|
||||||
|
Expanded = 3,
|
||||||
|
ExpandedForAppletDev = 4,
|
||||||
|
|
||||||
|
// Note: Dynamic is not official.
|
||||||
|
// Atmosphere uses it to maintain compatibility with firmwares prior to 6.0.0,
|
||||||
|
// which removed the explicit retrieval of memory arrangement from PM.
|
||||||
|
Dynamic = 5,
|
||||||
|
Count,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class BootReason {
|
||||||
|
Unknown = 0,
|
||||||
|
AcOk = 1,
|
||||||
|
OnKey = 2,
|
||||||
|
RtcAlarm1 = 3,
|
||||||
|
RtcAlarm2 = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BootReasonValue {
|
||||||
|
union {
|
||||||
|
u32 value{};
|
||||||
|
|
||||||
|
BitField<0, 8, u32> power_intr;
|
||||||
|
BitField<8, 8, u32> rtc_intr;
|
||||||
|
BitField<16, 8, u32> nv_erc;
|
||||||
|
BitField<24, 8, u32> boot_reason;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static_assert(sizeof(BootReasonValue) == sizeof(u32), "BootReasonValue definition!");
|
||||||
|
|
||||||
|
struct AesKey {
|
||||||
|
std::array<u64, AES_128_KEY_SIZE / sizeof(u64)> data64{};
|
||||||
|
|
||||||
|
std::span<u8> AsBytes() {
|
||||||
|
return std::span{reinterpret_cast<u8*>(data64.data()), AES_128_KEY_SIZE};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::span<const u8> AsBytes() const {
|
||||||
|
return std::span{reinterpret_cast<const u8*>(data64.data()), AES_128_KEY_SIZE};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(AesKey) == AES_128_KEY_SIZE, "AesKey definition!");
|
||||||
|
|
||||||
|
struct IvCtr {
|
||||||
|
std::array<u64, AES_128_KEY_SIZE / sizeof(u64)> data64{};
|
||||||
|
|
||||||
|
std::span<u8> AsBytes() {
|
||||||
|
return std::span{reinterpret_cast<u8*>(data64.data()), AES_128_KEY_SIZE};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::span<const u8> AsBytes() const {
|
||||||
|
return std::span{reinterpret_cast<const u8*>(data64.data()), AES_128_KEY_SIZE};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(AesKey) == AES_128_KEY_SIZE, "IvCtr definition!");
|
||||||
|
|
||||||
|
struct Cmac {
|
||||||
|
std::array<u64, AES_128_KEY_SIZE / sizeof(u64)> data64{};
|
||||||
|
|
||||||
|
std::span<u8> AsBytes() {
|
||||||
|
return std::span{reinterpret_cast<u8*>(data64.data()), AES_128_KEY_SIZE};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::span<const u8> AsBytes() const {
|
||||||
|
return std::span{reinterpret_cast<const u8*>(data64.data()), AES_128_KEY_SIZE};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(AesKey) == AES_128_KEY_SIZE, "Cmac definition!");
|
||||||
|
|
||||||
|
struct AccessKey {
|
||||||
|
std::array<u64, AES_128_KEY_SIZE / sizeof(u64)> data64{};
|
||||||
|
|
||||||
|
std::span<u8> AsBytes() {
|
||||||
|
return std::span{reinterpret_cast<u8*>(data64.data()), AES_128_KEY_SIZE};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::span<const u8> AsBytes() const {
|
||||||
|
return std::span{reinterpret_cast<const u8*>(data64.data()), AES_128_KEY_SIZE};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(AesKey) == AES_128_KEY_SIZE, "AccessKey definition!");
|
||||||
|
|
||||||
|
struct KeySource {
|
||||||
|
std::array<u64, AES_128_KEY_SIZE / sizeof(u64)> data64{};
|
||||||
|
|
||||||
|
std::span<u8> AsBytes() {
|
||||||
|
return std::span{reinterpret_cast<u8*>(data64.data()), AES_128_KEY_SIZE};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::span<const u8> AsBytes() const {
|
||||||
|
return std::span{reinterpret_cast<const u8*>(data64.data()), AES_128_KEY_SIZE};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
static_assert(sizeof(AesKey) == AES_128_KEY_SIZE, "KeySource definition!");
|
||||||
|
|
||||||
|
enum class ConfigItem : u32 {
|
||||||
|
// Standard config items.
|
||||||
|
DisableProgramVerification = 1,
|
||||||
|
DramId = 2,
|
||||||
|
SecurityEngineInterruptNumber = 3,
|
||||||
|
FuseVersion = 4,
|
||||||
|
HardwareType = 5,
|
||||||
|
HardwareState = 6,
|
||||||
|
IsRecoveryBoot = 7,
|
||||||
|
DeviceId = 8,
|
||||||
|
BootReason = 9,
|
||||||
|
MemoryMode = 10,
|
||||||
|
IsDevelopmentFunctionEnabled = 11,
|
||||||
|
KernelConfiguration = 12,
|
||||||
|
IsChargerHiZModeEnabled = 13,
|
||||||
|
QuestState = 14,
|
||||||
|
RegulatorType = 15,
|
||||||
|
DeviceUniqueKeyGeneration = 16,
|
||||||
|
Package2Hash = 17,
|
||||||
|
|
||||||
|
// Extension config items for exosphere.
|
||||||
|
ExosphereApiVersion = 65000,
|
||||||
|
ExosphereNeedsReboot = 65001,
|
||||||
|
ExosphereNeedsShutdown = 65002,
|
||||||
|
ExosphereGitCommitHash = 65003,
|
||||||
|
ExosphereHasRcmBugPatch = 65004,
|
||||||
|
ExosphereBlankProdInfo = 65005,
|
||||||
|
ExosphereAllowCalWrites = 65006,
|
||||||
|
ExosphereEmummcType = 65007,
|
||||||
|
ExospherePayloadAddress = 65008,
|
||||||
|
ExosphereLogConfiguration = 65009,
|
||||||
|
ExosphereForceEnableUsb30 = 65010,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Service::SPL
|
|
@ -125,7 +125,7 @@ ResultCode TimeZoneContentManager::GetTimeZoneInfoFile(const std::string& locati
|
||||||
return ERROR_TIME_NOT_FOUND;
|
return ERROR_TIME_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
vfs_file = zoneinfo_dir->GetFile(location_name);
|
vfs_file = zoneinfo_dir->GetFileRelative(location_name);
|
||||||
if (!vfs_file) {
|
if (!vfs_file) {
|
||||||
LOG_ERROR(Service_Time, "{:016X} has no file \"{}\"! Using default timezone.",
|
LOG_ERROR(Service_Time, "{:016X} has no file \"{}\"! Using default timezone.",
|
||||||
time_zone_binary_titleid, location_name);
|
time_zone_binary_titleid, location_name);
|
||||||
|
|
|
@ -2,25 +2,23 @@
|
||||||
// Licensed under GPLv2+
|
// Licensed under GPLv2+
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <stop_token>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "input_common/mouse/mouse_input.h"
|
#include "input_common/mouse/mouse_input.h"
|
||||||
|
|
||||||
namespace MouseInput {
|
namespace MouseInput {
|
||||||
|
|
||||||
Mouse::Mouse() {
|
Mouse::Mouse() {
|
||||||
update_thread = std::thread(&Mouse::UpdateThread, this);
|
update_thread = std::jthread([this](std::stop_token stop_token) { UpdateThread(stop_token); });
|
||||||
}
|
}
|
||||||
|
|
||||||
Mouse::~Mouse() {
|
Mouse::~Mouse() = default;
|
||||||
update_thread_running = false;
|
|
||||||
if (update_thread.joinable()) {
|
|
||||||
update_thread.join();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Mouse::UpdateThread() {
|
void Mouse::UpdateThread(std::stop_token stop_token) {
|
||||||
constexpr int update_time = 10;
|
constexpr int update_time = 10;
|
||||||
while (update_thread_running) {
|
while (!stop_token.stop_requested()) {
|
||||||
for (MouseInfo& info : mouse_info) {
|
for (MouseInfo& info : mouse_info) {
|
||||||
const Common::Vec3f angular_direction{
|
const Common::Vec3f angular_direction{
|
||||||
-info.tilt_direction.y,
|
-info.tilt_direction.y,
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <stop_token>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
@ -85,7 +86,7 @@ public:
|
||||||
[[nodiscard]] const MouseData& GetMouseState(std::size_t button) const;
|
[[nodiscard]] const MouseData& GetMouseState(std::size_t button) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void UpdateThread();
|
void UpdateThread(std::stop_token stop_token);
|
||||||
void UpdateYuzuSettings();
|
void UpdateYuzuSettings();
|
||||||
void StopPanning();
|
void StopPanning();
|
||||||
|
|
||||||
|
@ -105,12 +106,11 @@ private:
|
||||||
u16 buttons{};
|
u16 buttons{};
|
||||||
u16 toggle_buttons{};
|
u16 toggle_buttons{};
|
||||||
u16 lock_buttons{};
|
u16 lock_buttons{};
|
||||||
std::thread update_thread;
|
std::jthread update_thread;
|
||||||
MouseButton last_button{MouseButton::Undefined};
|
MouseButton last_button{MouseButton::Undefined};
|
||||||
std::array<MouseInfo, 7> mouse_info;
|
std::array<MouseInfo, 7> mouse_info;
|
||||||
Common::SPSCQueue<MouseStatus> mouse_queue;
|
Common::SPSCQueue<MouseStatus> mouse_queue;
|
||||||
bool configuring{false};
|
bool configuring{false};
|
||||||
bool update_thread_running{true};
|
|
||||||
int mouse_panning_timout{};
|
int mouse_panning_timout{};
|
||||||
};
|
};
|
||||||
} // namespace MouseInput
|
} // namespace MouseInput
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <atomic>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <span>
|
#include <span>
|
||||||
|
#include <stop_token>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "video_core/engines/fermi_2d.h"
|
#include "video_core/engines/fermi_2d.h"
|
||||||
#include "video_core/gpu.h"
|
#include "video_core/gpu.h"
|
||||||
|
@ -129,7 +129,7 @@ public:
|
||||||
virtual void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {}
|
virtual void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {}
|
||||||
|
|
||||||
/// Initialize disk cached resources for the game being emulated
|
/// Initialize disk cached resources for the game being emulated
|
||||||
virtual void LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
|
virtual void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
|
||||||
const DiskResourceLoadCallback& callback) {}
|
const DiskResourceLoadCallback& callback) {}
|
||||||
|
|
||||||
/// Grant access to the Guest Driver Profile for recording/obtaining info on the guest driver.
|
/// Grant access to the Guest Driver Profile for recording/obtaining info on the guest driver.
|
||||||
|
|
|
@ -42,6 +42,8 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] virtual RasterizerInterface* ReadRasterizer() = 0;
|
[[nodiscard]] virtual RasterizerInterface* ReadRasterizer() = 0;
|
||||||
|
|
||||||
|
[[nodiscard]] virtual std::string GetDeviceVendor() const = 0;
|
||||||
|
|
||||||
// Getter/setter functions:
|
// Getter/setter functions:
|
||||||
// ------------------------
|
// ------------------------
|
||||||
|
|
||||||
|
|
|
@ -202,13 +202,13 @@ Device::Device() {
|
||||||
LOG_ERROR(Render_OpenGL, "OpenGL 4.6 is not available");
|
LOG_ERROR(Render_OpenGL, "OpenGL 4.6 is not available");
|
||||||
throw std::runtime_error{"Insufficient version"};
|
throw std::runtime_error{"Insufficient version"};
|
||||||
}
|
}
|
||||||
const std::string_view vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
|
vendor_name = reinterpret_cast<const char*>(glGetString(GL_VENDOR));
|
||||||
const std::string_view version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
const std::string_view version = reinterpret_cast<const char*>(glGetString(GL_VERSION));
|
||||||
const std::vector extensions = GetExtensions();
|
const std::vector extensions = GetExtensions();
|
||||||
|
|
||||||
const bool is_nvidia = vendor == "NVIDIA Corporation";
|
const bool is_nvidia = vendor_name == "NVIDIA Corporation";
|
||||||
const bool is_amd = vendor == "ATI Technologies Inc.";
|
const bool is_amd = vendor_name == "ATI Technologies Inc.";
|
||||||
const bool is_intel = vendor == "Intel";
|
const bool is_intel = vendor_name == "Intel";
|
||||||
|
|
||||||
#ifdef __unix__
|
#ifdef __unix__
|
||||||
const bool is_linux = true;
|
const bool is_linux = true;
|
||||||
|
@ -275,6 +275,56 @@ Device::Device() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Device::GetVendorName() const {
|
||||||
|
if (vendor_name == "NVIDIA Corporation") {
|
||||||
|
return "NVIDIA";
|
||||||
|
}
|
||||||
|
if (vendor_name == "ATI Technologies Inc.") {
|
||||||
|
return "AMD";
|
||||||
|
}
|
||||||
|
if (vendor_name == "Intel") {
|
||||||
|
// For Mesa, `Intel` is an overloaded vendor string that could mean crocus or iris.
|
||||||
|
// Simply return `INTEL` for those as well as the Windows driver.
|
||||||
|
return "INTEL";
|
||||||
|
}
|
||||||
|
if (vendor_name == "Intel Open Source Technology Center") {
|
||||||
|
return "I965";
|
||||||
|
}
|
||||||
|
if (vendor_name == "Mesa Project") {
|
||||||
|
return "I915";
|
||||||
|
}
|
||||||
|
if (vendor_name == "Mesa/X.org") {
|
||||||
|
// This vendor string is overloaded between llvmpipe, softpipe, and virgl, so just return
|
||||||
|
// MESA instead of one of those driver names.
|
||||||
|
return "MESA";
|
||||||
|
}
|
||||||
|
if (vendor_name == "AMD") {
|
||||||
|
return "RADEONSI";
|
||||||
|
}
|
||||||
|
if (vendor_name == "nouveau") {
|
||||||
|
return "NOUVEAU";
|
||||||
|
}
|
||||||
|
if (vendor_name == "X.Org") {
|
||||||
|
return "R600";
|
||||||
|
}
|
||||||
|
if (vendor_name == "Collabora Ltd") {
|
||||||
|
return "ZINK";
|
||||||
|
}
|
||||||
|
if (vendor_name == "Intel Corporation") {
|
||||||
|
return "OPENSWR";
|
||||||
|
}
|
||||||
|
if (vendor_name == "Microsoft Corporation") {
|
||||||
|
return "D3D12";
|
||||||
|
}
|
||||||
|
if (vendor_name == "NVIDIA") {
|
||||||
|
// Mesa's tegra driver reports `NVIDIA`. Only present in this list because the default
|
||||||
|
// strategy would have returned `NVIDIA` here for this driver, the same result as the
|
||||||
|
// proprietary driver.
|
||||||
|
return "TEGRA";
|
||||||
|
}
|
||||||
|
return vendor_name;
|
||||||
|
}
|
||||||
|
|
||||||
Device::Device(std::nullptr_t) {
|
Device::Device(std::nullptr_t) {
|
||||||
max_uniform_buffers.fill(std::numeric_limits<u32>::max());
|
max_uniform_buffers.fill(std::numeric_limits<u32>::max());
|
||||||
uniform_buffer_alignment = 4;
|
uniform_buffer_alignment = 4;
|
||||||
|
|
|
@ -22,6 +22,8 @@ public:
|
||||||
explicit Device();
|
explicit Device();
|
||||||
explicit Device(std::nullptr_t);
|
explicit Device(std::nullptr_t);
|
||||||
|
|
||||||
|
[[nodiscard]] std::string GetVendorName() const;
|
||||||
|
|
||||||
u32 GetMaxUniformBuffers(Tegra::Engines::ShaderType shader_type) const noexcept {
|
u32 GetMaxUniformBuffers(Tegra::Engines::ShaderType shader_type) const noexcept {
|
||||||
return max_uniform_buffers[static_cast<std::size_t>(shader_type)];
|
return max_uniform_buffers[static_cast<std::size_t>(shader_type)];
|
||||||
}
|
}
|
||||||
|
@ -130,6 +132,7 @@ private:
|
||||||
static bool TestVariableAoffi();
|
static bool TestVariableAoffi();
|
||||||
static bool TestPreciseBug();
|
static bool TestPreciseBug();
|
||||||
|
|
||||||
|
std::string vendor_name;
|
||||||
std::array<u32, Tegra::Engines::MaxShaderTypes> max_uniform_buffers{};
|
std::array<u32, Tegra::Engines::MaxShaderTypes> max_uniform_buffers{};
|
||||||
std::array<BaseBindings, Tegra::Engines::MaxShaderTypes> base_bindings{};
|
std::array<BaseBindings, Tegra::Engines::MaxShaderTypes> base_bindings{};
|
||||||
size_t uniform_buffer_alignment{};
|
size_t uniform_buffer_alignment{};
|
||||||
|
|
|
@ -351,7 +351,7 @@ void RasterizerOpenGL::SetupShaders(bool is_indexed) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RasterizerOpenGL::LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
|
void RasterizerOpenGL::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
|
||||||
const VideoCore::DiskResourceLoadCallback& callback) {
|
const VideoCore::DiskResourceLoadCallback& callback) {
|
||||||
shader_cache.LoadDiskCache(title_id, stop_loading, callback);
|
shader_cache.LoadDiskCache(title_id, stop_loading, callback);
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,7 +96,7 @@ public:
|
||||||
const Tegra::Engines::Fermi2D::Config& copy_config) override;
|
const Tegra::Engines::Fermi2D::Config& copy_config) override;
|
||||||
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
|
bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
|
||||||
u32 pixel_stride) override;
|
u32 pixel_stride) override;
|
||||||
void LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
|
void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
|
||||||
const VideoCore::DiskResourceLoadCallback& callback) override;
|
const VideoCore::DiskResourceLoadCallback& callback) override;
|
||||||
|
|
||||||
/// Returns true when there are commands queued to the OpenGL server.
|
/// Returns true when there are commands queued to the OpenGL server.
|
||||||
|
|
|
@ -331,7 +331,7 @@ ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer_,
|
||||||
|
|
||||||
ShaderCacheOpenGL::~ShaderCacheOpenGL() = default;
|
ShaderCacheOpenGL::~ShaderCacheOpenGL() = default;
|
||||||
|
|
||||||
void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop_loading,
|
void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, std::stop_token stop_loading,
|
||||||
const VideoCore::DiskResourceLoadCallback& callback) {
|
const VideoCore::DiskResourceLoadCallback& callback) {
|
||||||
disk_cache.BindTitleID(title_id);
|
disk_cache.BindTitleID(title_id);
|
||||||
const std::optional transferable = disk_cache.LoadTransferable();
|
const std::optional transferable = disk_cache.LoadTransferable();
|
||||||
|
@ -372,7 +372,7 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop
|
||||||
const auto scope = context->Acquire();
|
const auto scope = context->Acquire();
|
||||||
|
|
||||||
for (std::size_t i = begin; i < end; ++i) {
|
for (std::size_t i = begin; i < end; ++i) {
|
||||||
if (stop_loading) {
|
if (stop_loading.stop_requested()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto& entry = (*transferable)[i];
|
const auto& entry = (*transferable)[i];
|
||||||
|
@ -435,7 +435,7 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop
|
||||||
precompiled_cache_altered = true;
|
precompiled_cache_altered = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (stop_loading) {
|
if (stop_loading.stop_requested()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ public:
|
||||||
~ShaderCacheOpenGL() override;
|
~ShaderCacheOpenGL() override;
|
||||||
|
|
||||||
/// Loads disk cache for the current game
|
/// Loads disk cache for the current game
|
||||||
void LoadDiskCache(u64 title_id, const std::atomic_bool& stop_loading,
|
void LoadDiskCache(u64 title_id, std::stop_token stop_loading,
|
||||||
const VideoCore::DiskResourceLoadCallback& callback);
|
const VideoCore::DiskResourceLoadCallback& callback);
|
||||||
|
|
||||||
/// Gets the current specified shader stage program
|
/// Gets the current specified shader stage program
|
||||||
|
|
|
@ -70,6 +70,10 @@ public:
|
||||||
return &rasterizer;
|
return &rasterizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::string GetDeviceVendor() const override {
|
||||||
|
return device.GetVendorName();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Initializes the OpenGL state and creates persistent objects.
|
/// Initializes the OpenGL state and creates persistent objects.
|
||||||
void InitOpenGLObjects();
|
void InitOpenGLObjects();
|
||||||
|
|
|
@ -47,6 +47,10 @@ public:
|
||||||
return &rasterizer;
|
return &rasterizer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] std::string GetDeviceVendor() const override {
|
||||||
|
return device.GetDriverName();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Report() const;
|
void Report() const;
|
||||||
|
|
||||||
|
|
|
@ -344,6 +344,7 @@ private:
|
||||||
|
|
||||||
bool has_deleted_images = false;
|
bool has_deleted_images = false;
|
||||||
u64 total_used_memory = 0;
|
u64 total_used_memory = 0;
|
||||||
|
u64 minimum_memory;
|
||||||
u64 expected_memory;
|
u64 expected_memory;
|
||||||
u64 critical_memory;
|
u64 critical_memory;
|
||||||
|
|
||||||
|
@ -396,10 +397,12 @@ TextureCache<P>::TextureCache(Runtime& runtime_, VideoCore::RasterizerInterface&
|
||||||
const u64 possible_critical_memory = (device_memory * 6) / 10;
|
const u64 possible_critical_memory = (device_memory * 6) / 10;
|
||||||
expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY);
|
expected_memory = std::max(possible_expected_memory, DEFAULT_EXPECTED_MEMORY);
|
||||||
critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY);
|
critical_memory = std::max(possible_critical_memory, DEFAULT_CRITICAL_MEMORY);
|
||||||
|
minimum_memory = 0;
|
||||||
} else {
|
} else {
|
||||||
// on OGL we can be more conservatives as the driver takes care.
|
// on OGL we can be more conservatives as the driver takes care.
|
||||||
expected_memory = DEFAULT_EXPECTED_MEMORY + Common::Size_512_MB;
|
expected_memory = DEFAULT_EXPECTED_MEMORY + Common::Size_512_MB;
|
||||||
critical_memory = DEFAULT_CRITICAL_MEMORY + Common::Size_1_GB;
|
critical_memory = DEFAULT_CRITICAL_MEMORY + Common::Size_1_GB;
|
||||||
|
minimum_memory = expected_memory;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -470,7 +473,7 @@ void TextureCache<P>::RunGarbageCollector() {
|
||||||
|
|
||||||
template <class P>
|
template <class P>
|
||||||
void TextureCache<P>::TickFrame() {
|
void TextureCache<P>::TickFrame() {
|
||||||
if (Settings::values.use_caches_gc.GetValue()) {
|
if (Settings::values.use_caches_gc.GetValue() && total_used_memory > minimum_memory) {
|
||||||
RunGarbageCollector();
|
RunGarbageCollector();
|
||||||
}
|
}
|
||||||
sentenced_images.Tick();
|
sentenced_images.Tick();
|
||||||
|
|
|
@ -50,7 +50,7 @@ NsightAftermathTracker::NsightAftermathTracker() {
|
||||||
}
|
}
|
||||||
dump_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::LogDir) / "gpucrash";
|
dump_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::LogDir) / "gpucrash";
|
||||||
|
|
||||||
void(Common::FS::RemoveDirRecursively(dump_dir));
|
Common::FS::RemoveDirRecursively(dump_dir);
|
||||||
if (!Common::FS::CreateDir(dump_dir)) {
|
if (!Common::FS::CreateDir(dump_dir)) {
|
||||||
LOG_ERROR(Render_Vulkan, "Failed to create Nsight Aftermath dump directory");
|
LOG_ERROR(Render_Vulkan, "Failed to create Nsight Aftermath dump directory");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -532,6 +532,27 @@ bool Device::IsFormatSupported(VkFormat wanted_format, VkFormatFeatureFlags want
|
||||||
return (supported_usage & wanted_usage) == wanted_usage;
|
return (supported_usage & wanted_usage) == wanted_usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Device::GetDriverName() const {
|
||||||
|
switch (driver_id) {
|
||||||
|
case VK_DRIVER_ID_AMD_PROPRIETARY:
|
||||||
|
return "AMD";
|
||||||
|
case VK_DRIVER_ID_AMD_OPEN_SOURCE:
|
||||||
|
return "AMDVLK";
|
||||||
|
case VK_DRIVER_ID_MESA_RADV:
|
||||||
|
return "RADV";
|
||||||
|
case VK_DRIVER_ID_NVIDIA_PROPRIETARY:
|
||||||
|
return "NVIDIA";
|
||||||
|
case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS:
|
||||||
|
return "INTEL";
|
||||||
|
case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA:
|
||||||
|
return "ANV";
|
||||||
|
case VK_DRIVER_ID_MESA_LLVMPIPE:
|
||||||
|
return "LAVAPIPE";
|
||||||
|
default:
|
||||||
|
return vendor_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Device::CheckSuitability(bool requires_swapchain) const {
|
void Device::CheckSuitability(bool requires_swapchain) const {
|
||||||
std::bitset<REQUIRED_EXTENSIONS.size()> available_extensions;
|
std::bitset<REQUIRED_EXTENSIONS.size()> available_extensions;
|
||||||
bool has_swapchain = false;
|
bool has_swapchain = false;
|
||||||
|
|
|
@ -45,6 +45,9 @@ public:
|
||||||
/// Reports a shader to Nsight Aftermath.
|
/// Reports a shader to Nsight Aftermath.
|
||||||
void SaveShader(const std::vector<u32>& spirv) const;
|
void SaveShader(const std::vector<u32>& spirv) const;
|
||||||
|
|
||||||
|
/// Returns the name of the VkDriverId reported from Vulkan.
|
||||||
|
std::string GetDriverName() const;
|
||||||
|
|
||||||
/// Returns the dispatch loader with direct function pointers of the device.
|
/// Returns the dispatch loader with direct function pointers of the device.
|
||||||
const vk::DeviceDispatch& GetDispatchLoader() const {
|
const vk::DeviceDispatch& GetDispatchLoader() const {
|
||||||
return dld;
|
return dld;
|
||||||
|
|
|
@ -51,11 +51,11 @@ void EmuThread::run() {
|
||||||
Common::SetCurrentThreadName(name.c_str());
|
Common::SetCurrentThreadName(name.c_str());
|
||||||
|
|
||||||
auto& system = Core::System::GetInstance();
|
auto& system = Core::System::GetInstance();
|
||||||
|
auto& gpu = system.GPU();
|
||||||
|
auto stop_token = stop_source.get_token();
|
||||||
|
|
||||||
system.RegisterHostThread();
|
system.RegisterHostThread();
|
||||||
|
|
||||||
auto& gpu = system.GPU();
|
|
||||||
|
|
||||||
// Main process has been loaded. Make the context current to this thread and begin GPU and CPU
|
// Main process has been loaded. Make the context current to this thread and begin GPU and CPU
|
||||||
// execution.
|
// execution.
|
||||||
gpu.Start();
|
gpu.Start();
|
||||||
|
@ -65,7 +65,7 @@ void EmuThread::run() {
|
||||||
emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
|
emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
|
||||||
|
|
||||||
system.Renderer().ReadRasterizer()->LoadDiskResources(
|
system.Renderer().ReadRasterizer()->LoadDiskResources(
|
||||||
system.CurrentProcess()->GetTitleID(), stop_run,
|
system.CurrentProcess()->GetTitleID(), stop_token,
|
||||||
[this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
|
[this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
|
||||||
emit LoadProgress(stage, value, total);
|
emit LoadProgress(stage, value, total);
|
||||||
});
|
});
|
||||||
|
@ -78,7 +78,7 @@ void EmuThread::run() {
|
||||||
// so that the DebugModeLeft signal can be emitted before the
|
// so that the DebugModeLeft signal can be emitted before the
|
||||||
// next execution step
|
// next execution step
|
||||||
bool was_active = false;
|
bool was_active = false;
|
||||||
while (!stop_run) {
|
while (!stop_token.stop_requested()) {
|
||||||
if (running) {
|
if (running) {
|
||||||
if (was_active) {
|
if (was_active) {
|
||||||
emit DebugModeLeft();
|
emit DebugModeLeft();
|
||||||
|
@ -100,7 +100,7 @@ void EmuThread::run() {
|
||||||
}
|
}
|
||||||
running_guard = false;
|
running_guard = false;
|
||||||
|
|
||||||
if (!stop_run) {
|
if (!stop_token.stop_requested()) {
|
||||||
was_active = true;
|
was_active = true;
|
||||||
emit DebugModeEntered();
|
emit DebugModeEntered();
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ void EmuThread::run() {
|
||||||
UNIMPLEMENTED();
|
UNIMPLEMENTED();
|
||||||
} else {
|
} else {
|
||||||
std::unique_lock lock{running_mutex};
|
std::unique_lock lock{running_mutex};
|
||||||
running_cv.wait(lock, [this] { return IsRunning() || exec_step || stop_run; });
|
running_cv.wait(lock, stop_token, [this] { return IsRunning() || exec_step; });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,16 +89,16 @@ public:
|
||||||
* Requests for the emulation thread to stop running
|
* Requests for the emulation thread to stop running
|
||||||
*/
|
*/
|
||||||
void RequestStop() {
|
void RequestStop() {
|
||||||
stop_run = true;
|
stop_source.request_stop();
|
||||||
SetRunning(false);
|
SetRunning(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool exec_step = false;
|
bool exec_step = false;
|
||||||
bool running = false;
|
bool running = false;
|
||||||
std::atomic_bool stop_run{false};
|
std::stop_source stop_source;
|
||||||
std::mutex running_mutex;
|
std::mutex running_mutex;
|
||||||
std::condition_variable running_cv;
|
std::condition_variable_any running_cv;
|
||||||
Common::Event running_wait{};
|
Common::Event running_wait{};
|
||||||
std::atomic_bool running_guard{false};
|
std::atomic_bool running_guard{false};
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,8 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id, const std::str
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setFocusPolicy(Qt::ClickFocus);
|
setFocusPolicy(Qt::ClickFocus);
|
||||||
setWindowTitle(tr("Properties"));
|
setWindowTitle(tr("Properties"));
|
||||||
|
// remove Help question mark button from the title bar
|
||||||
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||||
|
|
||||||
ui->addonsTab->SetTitleId(title_id);
|
ui->addonsTab->SetTitleId(title_id);
|
||||||
|
|
||||||
|
|
|
@ -6,10 +6,15 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>800</width>
|
<width>900</width>
|
||||||
<height>600</height>
|
<height>600</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>900</width>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Dialog</string>
|
<string>Dialog</string>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -79,8 +79,8 @@ void ConfigurePerGameAddons::ApplyConfiguration() {
|
||||||
std::sort(disabled_addons.begin(), disabled_addons.end());
|
std::sort(disabled_addons.begin(), disabled_addons.end());
|
||||||
std::sort(current.begin(), current.end());
|
std::sort(current.begin(), current.end());
|
||||||
if (disabled_addons != current) {
|
if (disabled_addons != current) {
|
||||||
void(Common::FS::RemoveFile(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
Common::FS::RemoveFile(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
||||||
"game_list" / fmt::format("{:016X}.pv.txt", title_id)));
|
"game_list" / fmt::format("{:016X}.pv.txt", title_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
Settings::values.disabled_addons[title_id] = disabled_addons;
|
Settings::values.disabled_addons[title_id] = disabled_addons;
|
||||||
|
|
|
@ -521,7 +521,9 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
|
||||||
QAction* remove_custom_config = remove_menu->addAction(tr("Remove Custom Configuration"));
|
QAction* remove_custom_config = remove_menu->addAction(tr("Remove Custom Configuration"));
|
||||||
remove_menu->addSeparator();
|
remove_menu->addSeparator();
|
||||||
QAction* remove_all_content = remove_menu->addAction(tr("Remove All Installed Contents"));
|
QAction* remove_all_content = remove_menu->addAction(tr("Remove All Installed Contents"));
|
||||||
QAction* dump_romfs = context_menu.addAction(tr("Dump RomFS"));
|
QMenu* dump_romfs_menu = context_menu.addMenu(tr("Dump RomFS"));
|
||||||
|
QAction* dump_romfs = dump_romfs_menu->addAction(tr("Dump RomFS"));
|
||||||
|
QAction* dump_romfs_sdmc = dump_romfs_menu->addAction(tr("Dump RomFS to SDMC"));
|
||||||
QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard"));
|
QAction* copy_tid = context_menu.addAction(tr("Copy Title ID to Clipboard"));
|
||||||
QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry"));
|
QAction* navigate_to_gamedb_entry = context_menu.addAction(tr("Navigate to GameDB entry"));
|
||||||
context_menu.addSeparator();
|
context_menu.addSeparator();
|
||||||
|
@ -570,8 +572,12 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
|
||||||
connect(remove_custom_config, &QAction::triggered, [this, program_id, path]() {
|
connect(remove_custom_config, &QAction::triggered, [this, program_id, path]() {
|
||||||
emit RemoveFileRequested(program_id, GameListRemoveTarget::CustomConfiguration, path);
|
emit RemoveFileRequested(program_id, GameListRemoveTarget::CustomConfiguration, path);
|
||||||
});
|
});
|
||||||
connect(dump_romfs, &QAction::triggered,
|
connect(dump_romfs, &QAction::triggered, [this, program_id, path]() {
|
||||||
[this, program_id, path]() { emit DumpRomFSRequested(program_id, path); });
|
emit DumpRomFSRequested(program_id, path, DumpRomFSTarget::Normal);
|
||||||
|
});
|
||||||
|
connect(dump_romfs_sdmc, &QAction::triggered, [this, program_id, path]() {
|
||||||
|
emit DumpRomFSRequested(program_id, path, DumpRomFSTarget::SDMC);
|
||||||
|
});
|
||||||
connect(copy_tid, &QAction::triggered,
|
connect(copy_tid, &QAction::triggered,
|
||||||
[this, program_id]() { emit CopyTIDRequested(program_id); });
|
[this, program_id]() { emit CopyTIDRequested(program_id); });
|
||||||
connect(navigate_to_gamedb_entry, &QAction::triggered, [this, program_id]() {
|
connect(navigate_to_gamedb_entry, &QAction::triggered, [this, program_id]() {
|
||||||
|
|
|
@ -45,6 +45,11 @@ enum class GameListRemoveTarget {
|
||||||
CustomConfiguration,
|
CustomConfiguration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class DumpRomFSTarget {
|
||||||
|
Normal,
|
||||||
|
SDMC,
|
||||||
|
};
|
||||||
|
|
||||||
enum class InstalledEntryType {
|
enum class InstalledEntryType {
|
||||||
Game,
|
Game,
|
||||||
Update,
|
Update,
|
||||||
|
@ -92,7 +97,7 @@ signals:
|
||||||
void RemoveInstalledEntryRequested(u64 program_id, InstalledEntryType type);
|
void RemoveInstalledEntryRequested(u64 program_id, InstalledEntryType type);
|
||||||
void RemoveFileRequested(u64 program_id, GameListRemoveTarget target,
|
void RemoveFileRequested(u64 program_id, GameListRemoveTarget target,
|
||||||
const std::string& game_path);
|
const std::string& game_path);
|
||||||
void DumpRomFSRequested(u64 program_id, const std::string& game_path);
|
void DumpRomFSRequested(u64 program_id, const std::string& game_path, DumpRomFSTarget target);
|
||||||
void CopyTIDRequested(u64 program_id);
|
void CopyTIDRequested(u64 program_id);
|
||||||
void NavigateToGamedbEntryRequested(u64 program_id,
|
void NavigateToGamedbEntryRequested(u64 program_id,
|
||||||
const CompatibilityList& compatibility_list);
|
const CompatibilityList& compatibility_list);
|
||||||
|
|
|
@ -104,6 +104,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
|
||||||
#include "input_common/main.h"
|
#include "input_common/main.h"
|
||||||
#include "util/overlay_dialog.h"
|
#include "util/overlay_dialog.h"
|
||||||
#include "video_core/gpu.h"
|
#include "video_core/gpu.h"
|
||||||
|
#include "video_core/renderer_base.h"
|
||||||
#include "video_core/shader_notify.h"
|
#include "video_core/shader_notify.h"
|
||||||
#include "yuzu/about_dialog.h"
|
#include "yuzu/about_dialog.h"
|
||||||
#include "yuzu/bootmanager.h"
|
#include "yuzu/bootmanager.h"
|
||||||
|
@ -194,10 +195,10 @@ static void RemoveCachedContents() {
|
||||||
const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information";
|
const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information";
|
||||||
const auto offline_system_data = cache_dir / "offline_web_applet_system_data";
|
const auto offline_system_data = cache_dir / "offline_web_applet_system_data";
|
||||||
|
|
||||||
void(Common::FS::RemoveDirRecursively(offline_fonts));
|
Common::FS::RemoveDirRecursively(offline_fonts);
|
||||||
void(Common::FS::RemoveDirRecursively(offline_manual));
|
Common::FS::RemoveDirRecursively(offline_manual);
|
||||||
void(Common::FS::RemoveDirRecursively(offline_legal_information));
|
Common::FS::RemoveDirRecursively(offline_legal_information);
|
||||||
void(Common::FS::RemoveDirRecursively(offline_system_data));
|
Common::FS::RemoveDirRecursively(offline_system_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
GMainWindow::GMainWindow()
|
GMainWindow::GMainWindow()
|
||||||
|
@ -1422,7 +1423,8 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S
|
||||||
std::filesystem::path{filename.toStdU16String()}.filename());
|
std::filesystem::path{filename.toStdU16String()}.filename());
|
||||||
}
|
}
|
||||||
LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version);
|
LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version);
|
||||||
UpdateWindowTitle(title_name, title_version);
|
const auto gpu_vendor = system.GPU().Renderer().GetDeviceVendor();
|
||||||
|
UpdateWindowTitle(title_name, title_version, gpu_vendor);
|
||||||
|
|
||||||
loading_screen->Prepare(system.GetAppLoader());
|
loading_screen->Prepare(system.GetAppLoader());
|
||||||
loading_screen->show();
|
loading_screen->show();
|
||||||
|
@ -1743,8 +1745,8 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT
|
||||||
RemoveAddOnContent(program_id, entry_type);
|
RemoveAddOnContent(program_id, entry_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
void(Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
||||||
"game_list"));
|
"game_list");
|
||||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1876,7 +1878,8 @@ void GMainWindow::RemoveCustomConfiguration(u64 program_id, const std::string& g
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path) {
|
void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_path,
|
||||||
|
DumpRomFSTarget target) {
|
||||||
const auto failed = [this] {
|
const auto failed = [this] {
|
||||||
QMessageBox::warning(this, tr("RomFS Extraction Failed!"),
|
QMessageBox::warning(this, tr("RomFS Extraction Failed!"),
|
||||||
tr("There was an error copying the RomFS files or the user "
|
tr("There was an error copying the RomFS files or the user "
|
||||||
|
@ -1904,7 +1907,10 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto dump_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir);
|
const auto dump_dir =
|
||||||
|
target == DumpRomFSTarget::Normal
|
||||||
|
? Common::FS::GetYuzuPath(Common::FS::YuzuPath::DumpDir)
|
||||||
|
: Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "atmosphere" / "contents";
|
||||||
const auto romfs_dir = fmt::format("{:016X}/romfs", *romfs_title_id);
|
const auto romfs_dir = fmt::format("{:016X}/romfs", *romfs_title_id);
|
||||||
|
|
||||||
const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir);
|
const auto path = Common::FS::PathToUTF8String(dump_dir / romfs_dir);
|
||||||
|
@ -2213,8 +2219,8 @@ void GMainWindow::OnMenuInstallToNAND() {
|
||||||
: tr("%n file(s) failed to install\n", "", failed_files.size()));
|
: tr("%n file(s) failed to install\n", "", failed_files.size()));
|
||||||
|
|
||||||
QMessageBox::information(this, tr("Install Results"), install_results);
|
QMessageBox::information(this, tr("Install Results"), install_results);
|
||||||
void(Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
||||||
"game_list"));
|
"game_list");
|
||||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||||
ui.action_Install_File_NAND->setEnabled(true);
|
ui.action_Install_File_NAND->setEnabled(true);
|
||||||
}
|
}
|
||||||
|
@ -2846,13 +2852,13 @@ void GMainWindow::MigrateConfigFiles() {
|
||||||
LOG_INFO(Frontend, "Migrating config file from {} to {}", origin, destination);
|
LOG_INFO(Frontend, "Migrating config file from {} to {}", origin, destination);
|
||||||
if (!Common::FS::RenameFile(origin, destination)) {
|
if (!Common::FS::RenameFile(origin, destination)) {
|
||||||
// Delete the old config file if one already exists in the new location.
|
// Delete the old config file if one already exists in the new location.
|
||||||
void(Common::FS::RemoveFile(origin));
|
Common::FS::RemoveFile(origin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GMainWindow::UpdateWindowTitle(const std::string& title_name,
|
void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_view title_version,
|
||||||
const std::string& title_version) {
|
std::string_view gpu_vendor) {
|
||||||
const auto branch_name = std::string(Common::g_scm_branch);
|
const auto branch_name = std::string(Common::g_scm_branch);
|
||||||
const auto description = std::string(Common::g_scm_desc);
|
const auto description = std::string(Common::g_scm_desc);
|
||||||
const auto build_id = std::string(Common::g_build_id);
|
const auto build_id = std::string(Common::g_build_id);
|
||||||
|
@ -2864,7 +2870,8 @@ void GMainWindow::UpdateWindowTitle(const std::string& title_name,
|
||||||
if (title_name.empty()) {
|
if (title_name.empty()) {
|
||||||
setWindowTitle(QString::fromStdString(window_title));
|
setWindowTitle(QString::fromStdString(window_title));
|
||||||
} else {
|
} else {
|
||||||
const auto run_title = fmt::format("{} | {} | {}", window_title, title_name, title_version);
|
const auto run_title =
|
||||||
|
fmt::format("{} | {} | {} | {}", window_title, title_name, title_version, gpu_vendor);
|
||||||
setWindowTitle(QString::fromStdString(run_title));
|
setWindowTitle(QString::fromStdString(run_title));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3040,9 +3047,9 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
|
||||||
|
|
||||||
const auto keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
|
const auto keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
|
||||||
|
|
||||||
void(Common::FS::RemoveFile(keys_dir / "prod.keys_autogenerated"));
|
Common::FS::RemoveFile(keys_dir / "prod.keys_autogenerated");
|
||||||
void(Common::FS::RemoveFile(keys_dir / "console.keys_autogenerated"));
|
Common::FS::RemoveFile(keys_dir / "console.keys_autogenerated");
|
||||||
void(Common::FS::RemoveFile(keys_dir / "title.keys_autogenerated"));
|
Common::FS::RemoveFile(keys_dir / "title.keys_autogenerated");
|
||||||
}
|
}
|
||||||
|
|
||||||
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();
|
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();
|
||||||
|
|
|
@ -34,6 +34,7 @@ class QProgressDialog;
|
||||||
class WaitTreeWidget;
|
class WaitTreeWidget;
|
||||||
enum class GameListOpenTarget;
|
enum class GameListOpenTarget;
|
||||||
enum class GameListRemoveTarget;
|
enum class GameListRemoveTarget;
|
||||||
|
enum class DumpRomFSTarget;
|
||||||
enum class InstalledEntryType;
|
enum class InstalledEntryType;
|
||||||
class GameListPlaceholder;
|
class GameListPlaceholder;
|
||||||
|
|
||||||
|
@ -244,7 +245,7 @@ private slots:
|
||||||
void OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type);
|
void OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryType type);
|
||||||
void OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target,
|
void OnGameListRemoveFile(u64 program_id, GameListRemoveTarget target,
|
||||||
const std::string& game_path);
|
const std::string& game_path);
|
||||||
void OnGameListDumpRomFS(u64 program_id, const std::string& game_path);
|
void OnGameListDumpRomFS(u64 program_id, const std::string& game_path, DumpRomFSTarget target);
|
||||||
void OnGameListCopyTID(u64 program_id);
|
void OnGameListCopyTID(u64 program_id);
|
||||||
void OnGameListNavigateToGamedbEntry(u64 program_id,
|
void OnGameListNavigateToGamedbEntry(u64 program_id,
|
||||||
const CompatibilityList& compatibility_list);
|
const CompatibilityList& compatibility_list);
|
||||||
|
@ -287,8 +288,8 @@ private:
|
||||||
InstallResult InstallNSPXCI(const QString& filename);
|
InstallResult InstallNSPXCI(const QString& filename);
|
||||||
InstallResult InstallNCA(const QString& filename);
|
InstallResult InstallNCA(const QString& filename);
|
||||||
void MigrateConfigFiles();
|
void MigrateConfigFiles();
|
||||||
void UpdateWindowTitle(const std::string& title_name = {},
|
void UpdateWindowTitle(std::string_view title_name = {}, std::string_view title_version = {},
|
||||||
const std::string& title_version = {});
|
std::string_view gpu_vendor = {});
|
||||||
void UpdateStatusBar();
|
void UpdateStatusBar();
|
||||||
void UpdateStatusButtons();
|
void UpdateStatusButtons();
|
||||||
void UpdateUISettings();
|
void UpdateUISettings();
|
||||||
|
|
|
@ -219,7 +219,7 @@ int main(int argc, char** argv) {
|
||||||
system.GPU().Start();
|
system.GPU().Start();
|
||||||
|
|
||||||
system.Renderer().ReadRasterizer()->LoadDiskResources(
|
system.Renderer().ReadRasterizer()->LoadDiskResources(
|
||||||
system.CurrentProcess()->GetTitleID(), false,
|
system.CurrentProcess()->GetTitleID(), std::stop_token{},
|
||||||
[](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
|
[](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
|
||||||
|
|
||||||
void(system.Run());
|
void(system.Run());
|
||||||
|
|
Loading…
Reference in a new issue