Compare commits
65 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36aacf62ad | ||
|
|
0308a2679e | ||
|
|
255f8d22d7 | ||
|
|
791d3d1bea | ||
|
|
2fa207058b | ||
|
|
0394893354 | ||
|
|
76b2313b25 | ||
|
|
cf0b9d1de2 | ||
|
|
81b1b71993 | ||
|
|
faf57c183f | ||
|
|
0e2c1a5739 | ||
|
|
698add8541 | ||
|
|
c9c8537643 | ||
|
|
2a7a65c944 | ||
|
|
cf116a28a6 | ||
|
|
0485b8e84b | ||
|
|
2a3d3d3895 | ||
|
|
83ac715e76 | ||
|
|
2298508465 | ||
|
|
ad8aab915b | ||
|
|
03da34b330 | ||
|
|
9a06b85b24 | ||
|
|
e704da9192 | ||
|
|
3870ba670f | ||
|
|
8a83e3412a | ||
|
|
fd5ef1970c | ||
|
|
bb18a6533d | ||
|
|
1a5eceeb9c | ||
|
|
0b172d12c0 | ||
|
|
36250a4730 | ||
|
|
3522fc019c | ||
|
|
abb0124b84 | ||
|
|
c5b517aa5f | ||
|
|
973bf306ed | ||
|
|
92942fe01b | ||
|
|
4a4e304319 | ||
|
|
8ba83c4c2a | ||
|
|
e4318a1914 | ||
|
|
ded36b8688 | ||
|
|
faf11fe46d | ||
|
|
95f203b7c7 | ||
|
|
74790e4f33 | ||
|
|
0f48292de1 | ||
|
|
78651b5476 | ||
|
|
5fc8393125 | ||
|
|
f9bfeaa2bc | ||
|
|
b2955479e5 | ||
|
|
c4ff7ecf51 | ||
|
|
f3caf53648 | ||
|
|
422a15ee75 | ||
|
|
3d89398b84 | ||
|
|
c8f86edee6 | ||
|
|
8d4dfc98ec | ||
|
|
de12dbb01a | ||
|
|
a4454329c1 | ||
|
|
391e823c79 | ||
|
|
8150c65c07 | ||
|
|
a98b6c8f07 | ||
|
|
56afd4ab4b | ||
|
|
c11b4c45e1 | ||
|
|
c978f3144c | ||
|
|
827483409b | ||
|
|
f611506dca | ||
|
|
df8a2e3ad8 | ||
|
|
c7c99905f4 |
@@ -18,19 +18,20 @@ cd ..
|
||||
mkdir package
|
||||
|
||||
if [ -d "/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/" ]; then
|
||||
QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt5/plugins/platforms/'
|
||||
QT_PLUGINS_PATH='/usr/x86_64-w64-mingw32/lib/qt5/plugins'
|
||||
else
|
||||
#fallback to qt
|
||||
QT_PLATFORM_DLL_PATH='/usr/x86_64-w64-mingw32/lib/qt/plugins/platforms/'
|
||||
QT_PLUGINS_PATH='/usr/x86_64-w64-mingw32/lib/qt/plugins'
|
||||
fi
|
||||
|
||||
find build/ -name "yuzu*.exe" -exec cp {} 'package' \;
|
||||
|
||||
# copy Qt plugins
|
||||
mkdir package/platforms
|
||||
cp "${QT_PLATFORM_DLL_PATH}/qwindows.dll" package/platforms/
|
||||
cp -rv "${QT_PLATFORM_DLL_PATH}/../mediaservice/" package/
|
||||
cp -rv "${QT_PLATFORM_DLL_PATH}/../imageformats/" package/
|
||||
cp -v "${QT_PLUGINS_PATH}/platforms/qwindows.dll" package/platforms/
|
||||
cp -rv "${QT_PLUGINS_PATH}/mediaservice/" package/
|
||||
cp -rv "${QT_PLUGINS_PATH}/imageformats/" package/
|
||||
cp -rv "${QT_PLUGINS_PATH}/styles/" package/
|
||||
rm -f package/mediaservice/*d.dll
|
||||
|
||||
for i in package/*.exe; do
|
||||
|
||||
5
.gitmodules
vendored
5
.gitmodules
vendored
@@ -18,7 +18,7 @@
|
||||
url = https://github.com/libusb/libusb.git
|
||||
[submodule "discord-rpc"]
|
||||
path = externals/discord-rpc
|
||||
url = https://github.com/discordapp/discord-rpc.git
|
||||
url = https://github.com/discord/discord-rpc.git
|
||||
[submodule "Vulkan-Headers"]
|
||||
path = externals/Vulkan-Headers
|
||||
url = https://github.com/KhronosGroup/Vulkan-Headers.git
|
||||
@@ -43,3 +43,6 @@
|
||||
[submodule "SDL"]
|
||||
path = externals/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
[submodule "externals/cpp-httplib"]
|
||||
path = externals/cpp-httplib
|
||||
url = https://github.com/yhirose/cpp-httplib.git
|
||||
|
||||
6
externals/CMakeLists.txt
vendored
6
externals/CMakeLists.txt
vendored
@@ -53,10 +53,10 @@ endif()
|
||||
# SDL2
|
||||
if (NOT SDL2_FOUND AND ENABLE_SDL2)
|
||||
if (NOT WIN32)
|
||||
# Yuzu itself needs: Events Joystick Haptic Sensor Timers
|
||||
# Yuzu itself needs: Events Joystick Haptic Sensor Timers Audio
|
||||
# Yuzu-cmd also needs: Video (depends on Loadso/Dlopen)
|
||||
set(SDL_UNUSED_SUBSYSTEMS
|
||||
Atomic Audio Render Power Threads
|
||||
Atomic Render Power Threads
|
||||
File CPUinfo Filesystem Locale)
|
||||
foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
|
||||
string(TOUPPER ${_SUB} _OPT)
|
||||
@@ -115,7 +115,7 @@ if (ENABLE_WEB_SERVICE)
|
||||
|
||||
# httplib
|
||||
add_library(httplib INTERFACE)
|
||||
target_include_directories(httplib INTERFACE ./httplib)
|
||||
target_include_directories(httplib INTERFACE ./cpp-httplib)
|
||||
target_compile_definitions(httplib INTERFACE -DCPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
target_link_libraries(httplib INTERFACE ${OPENSSL_LIBRARIES})
|
||||
if (WIN32)
|
||||
|
||||
1
externals/cpp-httplib
vendored
Submodule
1
externals/cpp-httplib
vendored
Submodule
Submodule externals/cpp-httplib added at 9648f950f5
2
externals/discord-rpc
vendored
2
externals/discord-rpc
vendored
Submodule externals/discord-rpc updated: e32d001809...963aa9f3e5
2
externals/dynarmic
vendored
2
externals/dynarmic
vendored
Submodule externals/dynarmic updated: 0c12614d1a...c6125082ea
15
externals/httplib/README.md
vendored
15
externals/httplib/README.md
vendored
@@ -1,15 +0,0 @@
|
||||
From https://github.com/yhirose/cpp-httplib/tree/ff5677ad197947177c158fe857caff4f0e242045 with https://github.com/yhirose/cpp-httplib/pull/701
|
||||
|
||||
MIT License
|
||||
|
||||
===
|
||||
|
||||
cpp-httplib
|
||||
|
||||
A C++11 header-only HTTP library.
|
||||
|
||||
It's extremely easy to setup. Just include httplib.h file in your code!
|
||||
|
||||
Inspired by Sinatra and express.
|
||||
|
||||
© 2017 Yuji Hirose
|
||||
6714
externals/httplib/httplib.h
vendored
6714
externals/httplib/httplib.h
vendored
File diff suppressed because it is too large
Load Diff
@@ -42,6 +42,7 @@ add_library(audio_core STATIC
|
||||
voice_context.h
|
||||
|
||||
$<$<BOOL:${ENABLE_CUBEB}>:cubeb_sink.cpp cubeb_sink.h>
|
||||
$<$<BOOL:${ENABLE_SDL2}>:sdl2_sink.cpp sdl2_sink.h>
|
||||
)
|
||||
|
||||
create_target_directory_groups(audio_core)
|
||||
@@ -71,3 +72,7 @@ if(ENABLE_CUBEB)
|
||||
target_link_libraries(audio_core PRIVATE cubeb)
|
||||
target_compile_definitions(audio_core PRIVATE -DHAVE_CUBEB=1)
|
||||
endif()
|
||||
if(ENABLE_SDL2)
|
||||
target_link_libraries(audio_core PRIVATE SDL2)
|
||||
target_compile_definitions(audio_core PRIVATE HAVE_SDL2)
|
||||
endif()
|
||||
|
||||
163
src/audio_core/sdl2_sink.cpp
Normal file
163
src/audio_core/sdl2_sink.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
// Copyright 2018 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstring>
|
||||
#include "audio_core/sdl2_sink.h"
|
||||
#include "audio_core/stream.h"
|
||||
#include "audio_core/time_stretch.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
//#include "common/settings.h"
|
||||
|
||||
// Ignore -Wimplicit-fallthrough due to https://github.com/libsdl-org/SDL/issues/4307
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
|
||||
#endif
|
||||
#include <SDL.h>
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
class SDLSinkStream final : public SinkStream {
|
||||
public:
|
||||
SDLSinkStream(u32 sample_rate, u32 num_channels_, const std::string& output_device)
|
||||
: num_channels{std::min(num_channels_, 6u)}, time_stretch{sample_rate, num_channels} {
|
||||
|
||||
SDL_AudioSpec spec;
|
||||
spec.freq = sample_rate;
|
||||
spec.channels = static_cast<u8>(num_channels);
|
||||
spec.format = AUDIO_S16SYS;
|
||||
spec.samples = 4096;
|
||||
spec.callback = nullptr;
|
||||
|
||||
SDL_AudioSpec obtained;
|
||||
if (output_device.empty()) {
|
||||
dev = SDL_OpenAudioDevice(nullptr, 0, &spec, &obtained, 0);
|
||||
} else {
|
||||
dev = SDL_OpenAudioDevice(output_device.c_str(), 0, &spec, &obtained, 0);
|
||||
}
|
||||
|
||||
if (dev == 0) {
|
||||
LOG_CRITICAL(Audio_Sink, "Error opening sdl audio device: {}", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_PauseAudioDevice(dev, 0);
|
||||
}
|
||||
|
||||
~SDLSinkStream() override {
|
||||
if (dev == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_CloseAudioDevice(dev);
|
||||
}
|
||||
|
||||
void EnqueueSamples(u32 source_num_channels, const std::vector<s16>& samples) override {
|
||||
if (source_num_channels > num_channels) {
|
||||
// Downsample 6 channels to 2
|
||||
ASSERT_MSG(source_num_channels == 6, "Channel count must be 6");
|
||||
|
||||
std::vector<s16> buf;
|
||||
buf.reserve(samples.size() * num_channels / source_num_channels);
|
||||
for (std::size_t i = 0; i < samples.size(); i += source_num_channels) {
|
||||
// Downmixing implementation taken from the ATSC standard
|
||||
const s16 left{samples[i + 0]};
|
||||
const s16 right{samples[i + 1]};
|
||||
const s16 center{samples[i + 2]};
|
||||
const s16 surround_left{samples[i + 4]};
|
||||
const s16 surround_right{samples[i + 5]};
|
||||
// Not used in the ATSC reference implementation
|
||||
[[maybe_unused]] const s16 low_frequency_effects{samples[i + 3]};
|
||||
|
||||
constexpr s32 clev{707}; // center mixing level coefficient
|
||||
constexpr s32 slev{707}; // surround mixing level coefficient
|
||||
|
||||
buf.push_back(static_cast<s16>(left + (clev * center / 1000) +
|
||||
(slev * surround_left / 1000)));
|
||||
buf.push_back(static_cast<s16>(right + (clev * center / 1000) +
|
||||
(slev * surround_right / 1000)));
|
||||
}
|
||||
int ret = SDL_QueueAudio(dev, static_cast<const void*>(buf.data()),
|
||||
static_cast<u32>(buf.size() * sizeof(s16)));
|
||||
if (ret < 0)
|
||||
LOG_WARNING(Audio_Sink, "Could not queue audio buffer: {}", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
|
||||
int ret = SDL_QueueAudio(dev, static_cast<const void*>(samples.data()),
|
||||
static_cast<u32>(samples.size() * sizeof(s16)));
|
||||
if (ret < 0)
|
||||
LOG_WARNING(Audio_Sink, "Could not queue audio buffer: {}", SDL_GetError());
|
||||
}
|
||||
|
||||
std::size_t SamplesInQueue(u32 channel_count) const override {
|
||||
if (dev == 0)
|
||||
return 0;
|
||||
|
||||
return SDL_GetQueuedAudioSize(dev) / (channel_count * sizeof(s16));
|
||||
}
|
||||
|
||||
void Flush() override {
|
||||
should_flush = true;
|
||||
}
|
||||
|
||||
u32 GetNumChannels() const {
|
||||
return num_channels;
|
||||
}
|
||||
|
||||
private:
|
||||
SDL_AudioDeviceID dev = 0;
|
||||
u32 num_channels{};
|
||||
std::atomic<bool> should_flush{};
|
||||
TimeStretcher time_stretch;
|
||||
};
|
||||
|
||||
SDLSink::SDLSink(std::string_view target_device_name) {
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
||||
LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem audio failed: {}", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (target_device_name != auto_device_name && !target_device_name.empty()) {
|
||||
output_device = target_device_name;
|
||||
} else {
|
||||
output_device.clear();
|
||||
}
|
||||
}
|
||||
|
||||
SDLSink::~SDLSink() = default;
|
||||
|
||||
SinkStream& SDLSink::AcquireSinkStream(u32 sample_rate, u32 num_channels, const std::string&) {
|
||||
sink_streams.push_back(
|
||||
std::make_unique<SDLSinkStream>(sample_rate, num_channels, output_device));
|
||||
return *sink_streams.back();
|
||||
}
|
||||
|
||||
std::vector<std::string> ListSDLSinkDevices() {
|
||||
std::vector<std::string> device_list;
|
||||
|
||||
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
|
||||
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
|
||||
LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem audio failed: {}", SDL_GetError());
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
const int device_count = SDL_GetNumAudioDevices(0);
|
||||
for (int i = 0; i < device_count; ++i) {
|
||||
device_list.emplace_back(SDL_GetAudioDeviceName(i, 0));
|
||||
}
|
||||
|
||||
return device_list;
|
||||
}
|
||||
|
||||
} // namespace AudioCore
|
||||
29
src/audio_core/sdl2_sink.h
Normal file
29
src/audio_core/sdl2_sink.h
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright 2018 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "audio_core/sink.h"
|
||||
|
||||
namespace AudioCore {
|
||||
|
||||
class SDLSink final : public Sink {
|
||||
public:
|
||||
explicit SDLSink(std::string_view device_id);
|
||||
~SDLSink() override;
|
||||
|
||||
SinkStream& AcquireSinkStream(u32 sample_rate, u32 num_channels,
|
||||
const std::string& name) override;
|
||||
|
||||
private:
|
||||
std::string output_device;
|
||||
std::vector<SinkStreamPtr> sink_streams;
|
||||
};
|
||||
|
||||
std::vector<std::string> ListSDLSinkDevices();
|
||||
|
||||
} // namespace AudioCore
|
||||
@@ -11,6 +11,9 @@
|
||||
#ifdef HAVE_CUBEB
|
||||
#include "audio_core/cubeb_sink.h"
|
||||
#endif
|
||||
#ifdef HAVE_SDL2
|
||||
#include "audio_core/sdl2_sink.h"
|
||||
#endif
|
||||
#include "common/logging/log.h"
|
||||
|
||||
namespace AudioCore {
|
||||
@@ -35,6 +38,13 @@ constexpr SinkDetails sink_details[] = {
|
||||
return std::make_unique<CubebSink>(device_id);
|
||||
},
|
||||
&ListCubebSinkDevices},
|
||||
#endif
|
||||
#ifdef HAVE_SDL2
|
||||
SinkDetails{"sdl2",
|
||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||
return std::make_unique<SDLSink>(device_id);
|
||||
},
|
||||
&ListSDLSinkDevices},
|
||||
#endif
|
||||
SinkDetails{"null",
|
||||
[](std::string_view device_id) -> std::unique_ptr<Sink> {
|
||||
|
||||
@@ -141,6 +141,7 @@ add_library(common STATIC
|
||||
logging/log.h
|
||||
logging/text_formatter.cpp
|
||||
logging/text_formatter.h
|
||||
logging/types.h
|
||||
lz4_compression.cpp
|
||||
lz4_compression.h
|
||||
math_util.h
|
||||
|
||||
@@ -172,7 +172,7 @@ std::string ReadStringFromFile(const std::filesystem::path& path, FileType type)
|
||||
|
||||
size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
|
||||
std::string_view string) {
|
||||
if (!IsFile(path)) {
|
||||
if (Exists(path) && !IsFile(path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -183,11 +183,7 @@ size_t WriteStringToFile(const std::filesystem::path& path, FileType type,
|
||||
|
||||
size_t AppendStringToFile(const std::filesystem::path& path, FileType type,
|
||||
std::string_view string) {
|
||||
if (!Exists(path)) {
|
||||
return WriteStringToFile(path, type, string);
|
||||
}
|
||||
|
||||
if (!IsFile(path)) {
|
||||
if (Exists(path) && !IsFile(path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -309,7 +305,11 @@ bool IOFile::Flush() const {
|
||||
|
||||
errno = 0;
|
||||
|
||||
const auto flush_result = std::fflush(file) == 0;
|
||||
#ifdef _WIN32
|
||||
const auto flush_result = std::fflush(file) == 0 && _commit(fileno(file)) == 0;
|
||||
#else
|
||||
const auto flush_result = std::fflush(file) == 0 && fsync(fileno(file)) == 0;
|
||||
#endif
|
||||
|
||||
if (!flush_result) {
|
||||
const auto ec = std::error_code{errno, std::generic_category()};
|
||||
|
||||
@@ -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.
|
||||
* 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 type File type
|
||||
@@ -71,8 +71,9 @@ template <typename Path>
|
||||
|
||||
/**
|
||||
* Writes a string to a file at path and returns the number of characters successfully written.
|
||||
* If an 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 already exists at path, its contents will be erased.
|
||||
* 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 type File type
|
||||
@@ -95,8 +96,8 @@ template <typename Path>
|
||||
|
||||
/**
|
||||
* Appends a string to a file at path and returns the number of characters successfully written.
|
||||
* If a file does not exist at path, WriteStringToFile is called instead.
|
||||
* 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 type File type
|
||||
@@ -395,11 +396,11 @@ public:
|
||||
[[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.
|
||||
*/
|
||||
[[nodiscard]] bool Flush() const;
|
||||
bool Flush() const;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
if (!IsFile(path)) {
|
||||
LOG_ERROR(Common_Filesystem, "Filesystem object at path={} is not a file",
|
||||
if (Exists(path) && !IsFile(path)) {
|
||||
LOG_ERROR(Common_Filesystem,
|
||||
"Filesystem object at path={} exists and is not a regular file",
|
||||
PathToUTF8String(path));
|
||||
return nullptr;
|
||||
}
|
||||
@@ -321,7 +322,8 @@ bool RemoveDirContentsRecursively(const fs::path& path) {
|
||||
|
||||
std::error_code ec;
|
||||
|
||||
for (const auto& entry : fs::recursive_directory_iterator(path, ec)) {
|
||||
// TODO (Morph): Replace this with recursive_directory_iterator once it's fixed in MSVC.
|
||||
for (const auto& entry : fs::directory_iterator(path, ec)) {
|
||||
if (ec) {
|
||||
LOG_ERROR(Common_Filesystem,
|
||||
"Failed to completely enumerate the directory at path={}, ec_message={}",
|
||||
@@ -337,6 +339,12 @@ bool RemoveDirContentsRecursively(const fs::path& path) {
|
||||
PathToUTF8String(entry.path()), ec.message());
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO (Morph): Remove this when MSVC fixes recursive_directory_iterator.
|
||||
// recursive_directory_iterator throws an exception despite passing in a std::error_code.
|
||||
if (entry.status().type() == fs::file_type::directory) {
|
||||
return RemoveDirContentsRecursively(entry.path());
|
||||
}
|
||||
}
|
||||
|
||||
if (ec) {
|
||||
@@ -475,7 +483,8 @@ void IterateDirEntriesRecursively(const std::filesystem::path& path,
|
||||
|
||||
std::error_code ec;
|
||||
|
||||
for (const auto& entry : fs::recursive_directory_iterator(path, ec)) {
|
||||
// TODO (Morph): Replace this with recursive_directory_iterator once it's fixed in MSVC.
|
||||
for (const auto& entry : fs::directory_iterator(path, ec)) {
|
||||
if (ec) {
|
||||
break;
|
||||
}
|
||||
@@ -495,6 +504,12 @@ void IterateDirEntriesRecursively(const std::filesystem::path& path,
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (Morph): Remove this when MSVC fixes recursive_directory_iterator.
|
||||
// recursive_directory_iterator throws an exception despite passing in a std::error_code.
|
||||
if (entry.status().type() == fs::file_type::directory) {
|
||||
IterateDirEntriesRecursively(entry.path(), callback, filter);
|
||||
}
|
||||
}
|
||||
|
||||
if (callback_error || ec) {
|
||||
|
||||
@@ -48,18 +48,18 @@ template <typename Path>
|
||||
*
|
||||
* Failures occur when:
|
||||
* - 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
|
||||
*
|
||||
* @param path Filesystem path
|
||||
*
|
||||
* @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
|
||||
template <typename Path>
|
||||
[[nodiscard]] bool RemoveFile(const Path& path) {
|
||||
bool RemoveFile(const Path& path) {
|
||||
if constexpr (IsChar<typename Path::value_type>) {
|
||||
return RemoveFile(ToU8String(path));
|
||||
} else {
|
||||
@@ -74,7 +74,7 @@ template <typename Path>
|
||||
* Failures occur when:
|
||||
* - One or both input path(s) is not valid
|
||||
* - 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 at either path is read only
|
||||
*
|
||||
@@ -110,8 +110,8 @@ template <typename Path1, typename Path2>
|
||||
*
|
||||
* Failures occur when:
|
||||
* - Input path is not valid
|
||||
* - Filesystem object at path is not a file
|
||||
* - The file is not opened
|
||||
* - Filesystem object at path exists and is not a regular file
|
||||
* - The file is not open
|
||||
*
|
||||
* @param path Filesystem path
|
||||
* @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.
|
||||
*/
|
||||
[[nodiscard]] bool RemoveDir(const std::filesystem::path& path);
|
||||
bool RemoveDir(const std::filesystem::path& path);
|
||||
|
||||
#ifdef _WIN32
|
||||
template <typename Path>
|
||||
[[nodiscard]] bool RemoveDir(const Path& path) {
|
||||
bool RemoveDir(const Path& path) {
|
||||
if constexpr (IsChar<typename Path::value_type>) {
|
||||
return RemoveDir(ToU8String(path));
|
||||
} else {
|
||||
@@ -276,11 +276,11 @@ template <typename Path>
|
||||
*
|
||||
* @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
|
||||
template <typename Path>
|
||||
[[nodiscard]] bool RemoveDirRecursively(const Path& path) {
|
||||
bool RemoveDirRecursively(const Path& path) {
|
||||
if constexpr (IsChar<typename Path::value_type>) {
|
||||
return RemoveDirRecursively(ToU8String(path));
|
||||
} else {
|
||||
@@ -301,11 +301,11 @@ template <typename Path>
|
||||
*
|
||||
* @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
|
||||
template <typename Path>
|
||||
[[nodiscard]] bool RemoveDirContentsRecursively(const Path& path) {
|
||||
bool RemoveDirContentsRecursively(const Path& path) {
|
||||
if constexpr (IsChar<typename Path::value_type>) {
|
||||
return RemoveDirContentsRecursively(ToU8String(path));
|
||||
} else {
|
||||
@@ -435,11 +435,13 @@ template <typename Path>
|
||||
#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
|
||||
*
|
||||
* @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);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ constexpr size_t HugePageSize = 0x200000;
|
||||
|
||||
// Manually imported for MinGW compatibility
|
||||
#ifndef MEM_RESERVE_PLACEHOLDER
|
||||
#define MEM_RESERVE_PLACEHOLDER 0x0004000
|
||||
#define MEM_RESERVE_PLACEHOLDER 0x00040000
|
||||
#endif
|
||||
#ifndef MEM_REPLACE_PLACEHOLDER
|
||||
#define MEM_REPLACE_PLACEHOLDER 0x00004000
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#endif
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/fs/file.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/logging/backend.h"
|
||||
#include "common/logging/log.h"
|
||||
@@ -140,10 +141,14 @@ private:
|
||||
std::chrono::steady_clock::time_point time_origin{std::chrono::steady_clock::now()};
|
||||
};
|
||||
|
||||
ConsoleBackend::~ConsoleBackend() = default;
|
||||
|
||||
void ConsoleBackend::Write(const Entry& entry) {
|
||||
PrintMessage(entry);
|
||||
}
|
||||
|
||||
ColorConsoleBackend::~ColorConsoleBackend() = default;
|
||||
|
||||
void ColorConsoleBackend::Write(const Entry& entry) {
|
||||
PrintColoredMessage(entry);
|
||||
}
|
||||
@@ -154,19 +159,22 @@ FileBackend::FileBackend(const std::filesystem::path& filename) {
|
||||
|
||||
// Existence checks are done within the functions themselves.
|
||||
// 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));
|
||||
|
||||
file = FS::IOFile(filename, FS::FileAccessMode::Write, FS::FileType::TextFile);
|
||||
file =
|
||||
std::make_unique<FS::IOFile>(filename, FS::FileAccessMode::Write, FS::FileType::TextFile);
|
||||
}
|
||||
|
||||
FileBackend::~FileBackend() = default;
|
||||
|
||||
void FileBackend::Write(const Entry& entry) {
|
||||
// prevent logs from going over the maximum size (in case its spamming and the user doesn't
|
||||
// know)
|
||||
constexpr std::size_t MAX_BYTES_WRITTEN = 100 * 1024 * 1024;
|
||||
constexpr std::size_t MAX_BYTES_WRITTEN_EXTENDED = 1024 * 1024 * 1024;
|
||||
|
||||
if (!file.IsOpen()) {
|
||||
if (!file->IsOpen()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -176,147 +184,20 @@ void FileBackend::Write(const Entry& entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
bytes_written += file.WriteString(FormatLogMessage(entry).append(1, '\n'));
|
||||
bytes_written += file->WriteString(FormatLogMessage(entry).append(1, '\n'));
|
||||
if (entry.log_level >= Level::Error) {
|
||||
void(file.Flush());
|
||||
file->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
DebuggerBackend::~DebuggerBackend() = default;
|
||||
|
||||
void DebuggerBackend::Write(const Entry& entry) {
|
||||
#ifdef _WIN32
|
||||
::OutputDebugStringW(UTF8ToUTF16W(FormatLogMessage(entry).append(1, '\n')).c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this.
|
||||
#define ALL_LOG_CLASSES() \
|
||||
CLS(Log) \
|
||||
CLS(Common) \
|
||||
SUB(Common, Filesystem) \
|
||||
SUB(Common, Memory) \
|
||||
CLS(Core) \
|
||||
SUB(Core, ARM) \
|
||||
SUB(Core, Timing) \
|
||||
CLS(Config) \
|
||||
CLS(Debug) \
|
||||
SUB(Debug, Emulated) \
|
||||
SUB(Debug, GPU) \
|
||||
SUB(Debug, Breakpoint) \
|
||||
SUB(Debug, GDBStub) \
|
||||
CLS(Kernel) \
|
||||
SUB(Kernel, SVC) \
|
||||
CLS(Service) \
|
||||
SUB(Service, ACC) \
|
||||
SUB(Service, Audio) \
|
||||
SUB(Service, AM) \
|
||||
SUB(Service, AOC) \
|
||||
SUB(Service, APM) \
|
||||
SUB(Service, ARP) \
|
||||
SUB(Service, BCAT) \
|
||||
SUB(Service, BPC) \
|
||||
SUB(Service, BGTC) \
|
||||
SUB(Service, BTDRV) \
|
||||
SUB(Service, BTM) \
|
||||
SUB(Service, Capture) \
|
||||
SUB(Service, ERPT) \
|
||||
SUB(Service, ETicket) \
|
||||
SUB(Service, EUPLD) \
|
||||
SUB(Service, Fatal) \
|
||||
SUB(Service, FGM) \
|
||||
SUB(Service, Friend) \
|
||||
SUB(Service, FS) \
|
||||
SUB(Service, GRC) \
|
||||
SUB(Service, HID) \
|
||||
SUB(Service, IRS) \
|
||||
SUB(Service, LBL) \
|
||||
SUB(Service, LDN) \
|
||||
SUB(Service, LDR) \
|
||||
SUB(Service, LM) \
|
||||
SUB(Service, Migration) \
|
||||
SUB(Service, Mii) \
|
||||
SUB(Service, MM) \
|
||||
SUB(Service, NCM) \
|
||||
SUB(Service, NFC) \
|
||||
SUB(Service, NFP) \
|
||||
SUB(Service, NIFM) \
|
||||
SUB(Service, NIM) \
|
||||
SUB(Service, NPNS) \
|
||||
SUB(Service, NS) \
|
||||
SUB(Service, NVDRV) \
|
||||
SUB(Service, OLSC) \
|
||||
SUB(Service, PCIE) \
|
||||
SUB(Service, PCTL) \
|
||||
SUB(Service, PCV) \
|
||||
SUB(Service, PM) \
|
||||
SUB(Service, PREPO) \
|
||||
SUB(Service, PSC) \
|
||||
SUB(Service, PSM) \
|
||||
SUB(Service, SET) \
|
||||
SUB(Service, SM) \
|
||||
SUB(Service, SPL) \
|
||||
SUB(Service, SSL) \
|
||||
SUB(Service, TCAP) \
|
||||
SUB(Service, Time) \
|
||||
SUB(Service, USB) \
|
||||
SUB(Service, VI) \
|
||||
SUB(Service, WLAN) \
|
||||
CLS(HW) \
|
||||
SUB(HW, Memory) \
|
||||
SUB(HW, LCD) \
|
||||
SUB(HW, GPU) \
|
||||
SUB(HW, AES) \
|
||||
CLS(IPC) \
|
||||
CLS(Frontend) \
|
||||
CLS(Render) \
|
||||
SUB(Render, Software) \
|
||||
SUB(Render, OpenGL) \
|
||||
SUB(Render, Vulkan) \
|
||||
CLS(Audio) \
|
||||
SUB(Audio, DSP) \
|
||||
SUB(Audio, Sink) \
|
||||
CLS(Input) \
|
||||
CLS(Network) \
|
||||
CLS(Loader) \
|
||||
CLS(CheatEngine) \
|
||||
CLS(Crypto) \
|
||||
CLS(WebService)
|
||||
|
||||
// GetClassName is a macro defined by Windows.h, grrr...
|
||||
const char* GetLogClassName(Class log_class) {
|
||||
switch (log_class) {
|
||||
#define CLS(x) \
|
||||
case Class::x: \
|
||||
return #x;
|
||||
#define SUB(x, y) \
|
||||
case Class::x##_##y: \
|
||||
return #x "." #y;
|
||||
ALL_LOG_CLASSES()
|
||||
#undef CLS
|
||||
#undef SUB
|
||||
case Class::Count:
|
||||
break;
|
||||
}
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
const char* GetLevelName(Level log_level) {
|
||||
#define LVL(x) \
|
||||
case Level::x: \
|
||||
return #x
|
||||
switch (log_level) {
|
||||
LVL(Trace);
|
||||
LVL(Debug);
|
||||
LVL(Info);
|
||||
LVL(Warning);
|
||||
LVL(Error);
|
||||
LVL(Critical);
|
||||
case Level::Count:
|
||||
break;
|
||||
}
|
||||
#undef LVL
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
void SetGlobalFilter(const Filter& filter) {
|
||||
Impl::Instance().SetGlobalFilter(filter);
|
||||
}
|
||||
|
||||
@@ -1,36 +1,24 @@
|
||||
// Copyright 2014 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include "common/fs/file.h"
|
||||
#include "common/logging/filter.h"
|
||||
#include "common/logging/log.h"
|
||||
|
||||
namespace Common::FS {
|
||||
class IOFile;
|
||||
}
|
||||
|
||||
namespace Common::Log {
|
||||
|
||||
class Filter;
|
||||
|
||||
/**
|
||||
* A log entry. Log entries are store in a structured format to permit more varied output
|
||||
* formatting on different frontends, as well as facilitating filtering and aggregation.
|
||||
*/
|
||||
struct Entry {
|
||||
std::chrono::microseconds timestamp;
|
||||
Class log_class{};
|
||||
Level log_level{};
|
||||
const char* filename = nullptr;
|
||||
unsigned int line_num = 0;
|
||||
std::string function;
|
||||
std::string message;
|
||||
bool final_entry = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Interface for logging backends. As loggers can be created and removed at runtime, this can be
|
||||
* used by a frontend for adding a custom logging backend as needed
|
||||
@@ -38,6 +26,7 @@ struct Entry {
|
||||
class Backend {
|
||||
public:
|
||||
virtual ~Backend() = default;
|
||||
|
||||
virtual void SetFilter(const Filter& new_filter) {
|
||||
filter = new_filter;
|
||||
}
|
||||
@@ -53,6 +42,8 @@ private:
|
||||
*/
|
||||
class ConsoleBackend : public Backend {
|
||||
public:
|
||||
~ConsoleBackend() override;
|
||||
|
||||
static const char* Name() {
|
||||
return "console";
|
||||
}
|
||||
@@ -67,6 +58,8 @@ public:
|
||||
*/
|
||||
class ColorConsoleBackend : public Backend {
|
||||
public:
|
||||
~ColorConsoleBackend() override;
|
||||
|
||||
static const char* Name() {
|
||||
return "color_console";
|
||||
}
|
||||
@@ -83,6 +76,7 @@ public:
|
||||
class FileBackend : public Backend {
|
||||
public:
|
||||
explicit FileBackend(const std::filesystem::path& filename);
|
||||
~FileBackend() override;
|
||||
|
||||
static const char* Name() {
|
||||
return "file";
|
||||
@@ -95,7 +89,7 @@ public:
|
||||
void Write(const Entry& entry) override;
|
||||
|
||||
private:
|
||||
FS::IOFile file;
|
||||
std::unique_ptr<FS::IOFile> file;
|
||||
std::size_t bytes_written = 0;
|
||||
};
|
||||
|
||||
@@ -104,6 +98,8 @@ private:
|
||||
*/
|
||||
class DebuggerBackend : public Backend {
|
||||
public:
|
||||
~DebuggerBackend() override;
|
||||
|
||||
static const char* Name() {
|
||||
return "debugger";
|
||||
}
|
||||
@@ -119,17 +115,6 @@ void RemoveBackend(std::string_view backend_name);
|
||||
|
||||
Backend* GetBackend(std::string_view backend_name);
|
||||
|
||||
/**
|
||||
* Returns the name of the passed log class as a C-string. Subclasses are separated by periods
|
||||
* instead of underscores as in the enumeration.
|
||||
*/
|
||||
const char* GetLogClassName(Class log_class);
|
||||
|
||||
/**
|
||||
* Returns the name of the passed log level as a C-string.
|
||||
*/
|
||||
const char* GetLevelName(Level log_level);
|
||||
|
||||
/**
|
||||
* The global filter will prevent any messages from even being processed if they are filtered. Each
|
||||
* backend can have a filter, but if the level is lower than the global filter, the backend will
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include "common/logging/backend.h"
|
||||
#include "common/logging/filter.h"
|
||||
#include "common/string_util.h"
|
||||
|
||||
@@ -22,7 +21,7 @@ Level GetLevelByName(const It begin, const It end) {
|
||||
|
||||
template <typename It>
|
||||
Class GetClassByName(const It begin, const It end) {
|
||||
for (ClassType i = 0; i < static_cast<ClassType>(Class::Count); ++i) {
|
||||
for (u8 i = 0; i < static_cast<u8>(Class::Count); ++i) {
|
||||
const char* level_name = GetLogClassName(static_cast<Class>(i));
|
||||
if (Common::ComparePartialString(begin, end, level_name)) {
|
||||
return static_cast<Class>(i);
|
||||
@@ -62,6 +61,135 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
/// Macro listing all log classes. Code should define CLS and SUB as desired before invoking this.
|
||||
#define ALL_LOG_CLASSES() \
|
||||
CLS(Log) \
|
||||
CLS(Common) \
|
||||
SUB(Common, Filesystem) \
|
||||
SUB(Common, Memory) \
|
||||
CLS(Core) \
|
||||
SUB(Core, ARM) \
|
||||
SUB(Core, Timing) \
|
||||
CLS(Config) \
|
||||
CLS(Debug) \
|
||||
SUB(Debug, Emulated) \
|
||||
SUB(Debug, GPU) \
|
||||
SUB(Debug, Breakpoint) \
|
||||
SUB(Debug, GDBStub) \
|
||||
CLS(Kernel) \
|
||||
SUB(Kernel, SVC) \
|
||||
CLS(Service) \
|
||||
SUB(Service, ACC) \
|
||||
SUB(Service, Audio) \
|
||||
SUB(Service, AM) \
|
||||
SUB(Service, AOC) \
|
||||
SUB(Service, APM) \
|
||||
SUB(Service, ARP) \
|
||||
SUB(Service, BCAT) \
|
||||
SUB(Service, BPC) \
|
||||
SUB(Service, BGTC) \
|
||||
SUB(Service, BTDRV) \
|
||||
SUB(Service, BTM) \
|
||||
SUB(Service, Capture) \
|
||||
SUB(Service, ERPT) \
|
||||
SUB(Service, ETicket) \
|
||||
SUB(Service, EUPLD) \
|
||||
SUB(Service, Fatal) \
|
||||
SUB(Service, FGM) \
|
||||
SUB(Service, Friend) \
|
||||
SUB(Service, FS) \
|
||||
SUB(Service, GRC) \
|
||||
SUB(Service, HID) \
|
||||
SUB(Service, IRS) \
|
||||
SUB(Service, LBL) \
|
||||
SUB(Service, LDN) \
|
||||
SUB(Service, LDR) \
|
||||
SUB(Service, LM) \
|
||||
SUB(Service, Migration) \
|
||||
SUB(Service, Mii) \
|
||||
SUB(Service, MM) \
|
||||
SUB(Service, NCM) \
|
||||
SUB(Service, NFC) \
|
||||
SUB(Service, NFP) \
|
||||
SUB(Service, NIFM) \
|
||||
SUB(Service, NIM) \
|
||||
SUB(Service, NPNS) \
|
||||
SUB(Service, NS) \
|
||||
SUB(Service, NVDRV) \
|
||||
SUB(Service, OLSC) \
|
||||
SUB(Service, PCIE) \
|
||||
SUB(Service, PCTL) \
|
||||
SUB(Service, PCV) \
|
||||
SUB(Service, PM) \
|
||||
SUB(Service, PREPO) \
|
||||
SUB(Service, PSC) \
|
||||
SUB(Service, PSM) \
|
||||
SUB(Service, SET) \
|
||||
SUB(Service, SM) \
|
||||
SUB(Service, SPL) \
|
||||
SUB(Service, SSL) \
|
||||
SUB(Service, TCAP) \
|
||||
SUB(Service, Time) \
|
||||
SUB(Service, USB) \
|
||||
SUB(Service, VI) \
|
||||
SUB(Service, WLAN) \
|
||||
CLS(HW) \
|
||||
SUB(HW, Memory) \
|
||||
SUB(HW, LCD) \
|
||||
SUB(HW, GPU) \
|
||||
SUB(HW, AES) \
|
||||
CLS(IPC) \
|
||||
CLS(Frontend) \
|
||||
CLS(Render) \
|
||||
SUB(Render, Software) \
|
||||
SUB(Render, OpenGL) \
|
||||
SUB(Render, Vulkan) \
|
||||
CLS(Audio) \
|
||||
SUB(Audio, DSP) \
|
||||
SUB(Audio, Sink) \
|
||||
CLS(Input) \
|
||||
CLS(Network) \
|
||||
CLS(Loader) \
|
||||
CLS(CheatEngine) \
|
||||
CLS(Crypto) \
|
||||
CLS(WebService)
|
||||
|
||||
// GetClassName is a macro defined by Windows.h, grrr...
|
||||
const char* GetLogClassName(Class log_class) {
|
||||
switch (log_class) {
|
||||
#define CLS(x) \
|
||||
case Class::x: \
|
||||
return #x;
|
||||
#define SUB(x, y) \
|
||||
case Class::x##_##y: \
|
||||
return #x "." #y;
|
||||
ALL_LOG_CLASSES()
|
||||
#undef CLS
|
||||
#undef SUB
|
||||
case Class::Count:
|
||||
break;
|
||||
}
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
const char* GetLevelName(Level log_level) {
|
||||
#define LVL(x) \
|
||||
case Level::x: \
|
||||
return #x
|
||||
switch (log_level) {
|
||||
LVL(Trace);
|
||||
LVL(Debug);
|
||||
LVL(Info);
|
||||
LVL(Warning);
|
||||
LVL(Error);
|
||||
LVL(Critical);
|
||||
case Level::Count:
|
||||
break;
|
||||
}
|
||||
#undef LVL
|
||||
return "Invalid";
|
||||
}
|
||||
|
||||
Filter::Filter(Level default_level) {
|
||||
ResetAll(default_level);
|
||||
}
|
||||
|
||||
@@ -5,12 +5,24 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
#include <cstddef>
|
||||
#include <string_view>
|
||||
#include "common/logging/log.h"
|
||||
|
||||
namespace Common::Log {
|
||||
|
||||
/**
|
||||
* Returns the name of the passed log class as a C-string. Subclasses are separated by periods
|
||||
* instead of underscores as in the enumeration.
|
||||
*/
|
||||
const char* GetLogClassName(Class log_class);
|
||||
|
||||
/**
|
||||
* Returns the name of the passed log level as a C-string.
|
||||
*/
|
||||
const char* GetLevelName(Level log_level);
|
||||
|
||||
/**
|
||||
* Implements a log message filter which allows different log classes to have different minimum
|
||||
* severity levels. The filter can be changed at runtime and can be parsed from a string to allow
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/types.h"
|
||||
|
||||
namespace Common::Log {
|
||||
|
||||
@@ -18,124 +18,6 @@ constexpr const char* TrimSourcePath(std::string_view source) {
|
||||
return source.data() + idx;
|
||||
}
|
||||
|
||||
/// Specifies the severity or level of detail of the log message.
|
||||
enum class Level : u8 {
|
||||
Trace, ///< Extremely detailed and repetitive debugging information that is likely to
|
||||
///< pollute logs.
|
||||
Debug, ///< Less detailed debugging information.
|
||||
Info, ///< Status information from important points during execution.
|
||||
Warning, ///< Minor or potential problems found during execution of a task.
|
||||
Error, ///< Major problems found during execution of a task that prevent it from being
|
||||
///< completed.
|
||||
Critical, ///< Major problems during execution that threaten the stability of the entire
|
||||
///< application.
|
||||
|
||||
Count ///< Total number of logging levels
|
||||
};
|
||||
|
||||
typedef u8 ClassType;
|
||||
|
||||
/**
|
||||
* Specifies the sub-system that generated the log message.
|
||||
*
|
||||
* @note If you add a new entry here, also add a corresponding one to `ALL_LOG_CLASSES` in
|
||||
* backend.cpp.
|
||||
*/
|
||||
enum class Class : ClassType {
|
||||
Log, ///< Messages about the log system itself
|
||||
Common, ///< Library routines
|
||||
Common_Filesystem, ///< Filesystem interface library
|
||||
Common_Memory, ///< Memory mapping and management functions
|
||||
Core, ///< LLE emulation core
|
||||
Core_ARM, ///< ARM CPU core
|
||||
Core_Timing, ///< CoreTiming functions
|
||||
Config, ///< Emulator configuration (including commandline)
|
||||
Debug, ///< Debugging tools
|
||||
Debug_Emulated, ///< Debug messages from the emulated programs
|
||||
Debug_GPU, ///< GPU debugging tools
|
||||
Debug_Breakpoint, ///< Logging breakpoints and watchpoints
|
||||
Debug_GDBStub, ///< GDB Stub
|
||||
Kernel, ///< The HLE implementation of the CTR kernel
|
||||
Kernel_SVC, ///< Kernel system calls
|
||||
Service, ///< HLE implementation of system services. Each major service
|
||||
///< should have its own subclass.
|
||||
Service_ACC, ///< The ACC (Accounts) service
|
||||
Service_AM, ///< The AM (Applet manager) service
|
||||
Service_AOC, ///< The AOC (AddOn Content) service
|
||||
Service_APM, ///< The APM (Performance) service
|
||||
Service_ARP, ///< The ARP service
|
||||
Service_Audio, ///< The Audio (Audio control) service
|
||||
Service_BCAT, ///< The BCAT service
|
||||
Service_BGTC, ///< The BGTC (Background Task Controller) service
|
||||
Service_BPC, ///< The BPC service
|
||||
Service_BTDRV, ///< The Bluetooth driver service
|
||||
Service_BTM, ///< The BTM service
|
||||
Service_Capture, ///< The capture service
|
||||
Service_ERPT, ///< The error reporting service
|
||||
Service_ETicket, ///< The ETicket service
|
||||
Service_EUPLD, ///< The error upload service
|
||||
Service_Fatal, ///< The Fatal service
|
||||
Service_FGM, ///< The FGM service
|
||||
Service_Friend, ///< The friend service
|
||||
Service_FS, ///< The FS (Filesystem) service
|
||||
Service_GRC, ///< The game recording service
|
||||
Service_HID, ///< The HID (Human interface device) service
|
||||
Service_IRS, ///< The IRS service
|
||||
Service_LBL, ///< The LBL (LCD backlight) service
|
||||
Service_LDN, ///< The LDN (Local domain network) service
|
||||
Service_LDR, ///< The loader service
|
||||
Service_LM, ///< The LM (Logger) service
|
||||
Service_Migration, ///< The migration service
|
||||
Service_Mii, ///< The Mii service
|
||||
Service_MM, ///< The MM (Multimedia) service
|
||||
Service_NCM, ///< The NCM service
|
||||
Service_NFC, ///< The NFC (Near-field communication) service
|
||||
Service_NFP, ///< The NFP service
|
||||
Service_NIFM, ///< The NIFM (Network interface) service
|
||||
Service_NIM, ///< The NIM service
|
||||
Service_NPNS, ///< The NPNS service
|
||||
Service_NS, ///< The NS services
|
||||
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
|
||||
Service_OLSC, ///< The OLSC service
|
||||
Service_PCIE, ///< The PCIe service
|
||||
Service_PCTL, ///< The PCTL (Parental control) service
|
||||
Service_PCV, ///< The PCV service
|
||||
Service_PM, ///< The PM service
|
||||
Service_PREPO, ///< The PREPO (Play report) service
|
||||
Service_PSC, ///< The PSC service
|
||||
Service_PSM, ///< The PSM service
|
||||
Service_SET, ///< The SET (Settings) service
|
||||
Service_SM, ///< The SM (Service manager) service
|
||||
Service_SPL, ///< The SPL service
|
||||
Service_SSL, ///< The SSL service
|
||||
Service_TCAP, ///< The TCAP service.
|
||||
Service_Time, ///< The time service
|
||||
Service_USB, ///< The USB (Universal Serial Bus) service
|
||||
Service_VI, ///< The VI (Video interface) service
|
||||
Service_WLAN, ///< The WLAN (Wireless local area network) service
|
||||
HW, ///< Low-level hardware emulation
|
||||
HW_Memory, ///< Memory-map and address translation
|
||||
HW_LCD, ///< LCD register emulation
|
||||
HW_GPU, ///< GPU control emulation
|
||||
HW_AES, ///< AES engine emulation
|
||||
IPC, ///< IPC interface
|
||||
Frontend, ///< Emulator UI
|
||||
Render, ///< Emulator video output and hardware acceleration
|
||||
Render_Software, ///< Software renderer backend
|
||||
Render_OpenGL, ///< OpenGL backend
|
||||
Render_Vulkan, ///< Vulkan backend
|
||||
Audio, ///< Audio emulation
|
||||
Audio_DSP, ///< The HLE implementation of the DSP
|
||||
Audio_Sink, ///< Emulator audio output backend
|
||||
Loader, ///< ROM loader
|
||||
CheatEngine, ///< Memory manipulation and engine VM functions
|
||||
Crypto, ///< Cryptographic engine/functions
|
||||
Input, ///< Input emulation
|
||||
Network, ///< Network emulation
|
||||
WebService, ///< Interface to yuzu Web Services
|
||||
Count ///< Total number of logging classes
|
||||
};
|
||||
|
||||
/// Logs a message to the global logger, using fmt
|
||||
void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename,
|
||||
unsigned int line_num, const char* function, const char* format,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/common_funcs.h"
|
||||
#include "common/logging/backend.h"
|
||||
#include "common/logging/filter.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/logging/text_formatter.h"
|
||||
#include "common/string_util.h"
|
||||
|
||||
142
src/common/logging/types.h
Normal file
142
src/common/logging/types.h
Normal file
@@ -0,0 +1,142 @@
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <chrono>
|
||||
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Common::Log {
|
||||
|
||||
/// Specifies the severity or level of detail of the log message.
|
||||
enum class Level : u8 {
|
||||
Trace, ///< Extremely detailed and repetitive debugging information that is likely to
|
||||
///< pollute logs.
|
||||
Debug, ///< Less detailed debugging information.
|
||||
Info, ///< Status information from important points during execution.
|
||||
Warning, ///< Minor or potential problems found during execution of a task.
|
||||
Error, ///< Major problems found during execution of a task that prevent it from being
|
||||
///< completed.
|
||||
Critical, ///< Major problems during execution that threaten the stability of the entire
|
||||
///< application.
|
||||
|
||||
Count ///< Total number of logging levels
|
||||
};
|
||||
|
||||
/**
|
||||
* Specifies the sub-system that generated the log message.
|
||||
*
|
||||
* @note If you add a new entry here, also add a corresponding one to `ALL_LOG_CLASSES` in
|
||||
* filter.cpp.
|
||||
*/
|
||||
enum class Class : u8 {
|
||||
Log, ///< Messages about the log system itself
|
||||
Common, ///< Library routines
|
||||
Common_Filesystem, ///< Filesystem interface library
|
||||
Common_Memory, ///< Memory mapping and management functions
|
||||
Core, ///< LLE emulation core
|
||||
Core_ARM, ///< ARM CPU core
|
||||
Core_Timing, ///< CoreTiming functions
|
||||
Config, ///< Emulator configuration (including commandline)
|
||||
Debug, ///< Debugging tools
|
||||
Debug_Emulated, ///< Debug messages from the emulated programs
|
||||
Debug_GPU, ///< GPU debugging tools
|
||||
Debug_Breakpoint, ///< Logging breakpoints and watchpoints
|
||||
Debug_GDBStub, ///< GDB Stub
|
||||
Kernel, ///< The HLE implementation of the CTR kernel
|
||||
Kernel_SVC, ///< Kernel system calls
|
||||
Service, ///< HLE implementation of system services. Each major service
|
||||
///< should have its own subclass.
|
||||
Service_ACC, ///< The ACC (Accounts) service
|
||||
Service_AM, ///< The AM (Applet manager) service
|
||||
Service_AOC, ///< The AOC (AddOn Content) service
|
||||
Service_APM, ///< The APM (Performance) service
|
||||
Service_ARP, ///< The ARP service
|
||||
Service_Audio, ///< The Audio (Audio control) service
|
||||
Service_BCAT, ///< The BCAT service
|
||||
Service_BGTC, ///< The BGTC (Background Task Controller) service
|
||||
Service_BPC, ///< The BPC service
|
||||
Service_BTDRV, ///< The Bluetooth driver service
|
||||
Service_BTM, ///< The BTM service
|
||||
Service_Capture, ///< The capture service
|
||||
Service_ERPT, ///< The error reporting service
|
||||
Service_ETicket, ///< The ETicket service
|
||||
Service_EUPLD, ///< The error upload service
|
||||
Service_Fatal, ///< The Fatal service
|
||||
Service_FGM, ///< The FGM service
|
||||
Service_Friend, ///< The friend service
|
||||
Service_FS, ///< The FS (Filesystem) service
|
||||
Service_GRC, ///< The game recording service
|
||||
Service_HID, ///< The HID (Human interface device) service
|
||||
Service_IRS, ///< The IRS service
|
||||
Service_LBL, ///< The LBL (LCD backlight) service
|
||||
Service_LDN, ///< The LDN (Local domain network) service
|
||||
Service_LDR, ///< The loader service
|
||||
Service_LM, ///< The LM (Logger) service
|
||||
Service_Migration, ///< The migration service
|
||||
Service_Mii, ///< The Mii service
|
||||
Service_MM, ///< The MM (Multimedia) service
|
||||
Service_NCM, ///< The NCM service
|
||||
Service_NFC, ///< The NFC (Near-field communication) service
|
||||
Service_NFP, ///< The NFP service
|
||||
Service_NIFM, ///< The NIFM (Network interface) service
|
||||
Service_NIM, ///< The NIM service
|
||||
Service_NPNS, ///< The NPNS service
|
||||
Service_NS, ///< The NS services
|
||||
Service_NVDRV, ///< The NVDRV (Nvidia driver) service
|
||||
Service_OLSC, ///< The OLSC service
|
||||
Service_PCIE, ///< The PCIe service
|
||||
Service_PCTL, ///< The PCTL (Parental control) service
|
||||
Service_PCV, ///< The PCV service
|
||||
Service_PM, ///< The PM service
|
||||
Service_PREPO, ///< The PREPO (Play report) service
|
||||
Service_PSC, ///< The PSC service
|
||||
Service_PSM, ///< The PSM service
|
||||
Service_SET, ///< The SET (Settings) service
|
||||
Service_SM, ///< The SM (Service manager) service
|
||||
Service_SPL, ///< The SPL service
|
||||
Service_SSL, ///< The SSL service
|
||||
Service_TCAP, ///< The TCAP service.
|
||||
Service_Time, ///< The time service
|
||||
Service_USB, ///< The USB (Universal Serial Bus) service
|
||||
Service_VI, ///< The VI (Video interface) service
|
||||
Service_WLAN, ///< The WLAN (Wireless local area network) service
|
||||
HW, ///< Low-level hardware emulation
|
||||
HW_Memory, ///< Memory-map and address translation
|
||||
HW_LCD, ///< LCD register emulation
|
||||
HW_GPU, ///< GPU control emulation
|
||||
HW_AES, ///< AES engine emulation
|
||||
IPC, ///< IPC interface
|
||||
Frontend, ///< Emulator UI
|
||||
Render, ///< Emulator video output and hardware acceleration
|
||||
Render_Software, ///< Software renderer backend
|
||||
Render_OpenGL, ///< OpenGL backend
|
||||
Render_Vulkan, ///< Vulkan backend
|
||||
Audio, ///< Audio emulation
|
||||
Audio_DSP, ///< The HLE implementation of the DSP
|
||||
Audio_Sink, ///< Emulator audio output backend
|
||||
Loader, ///< ROM loader
|
||||
CheatEngine, ///< Memory manipulation and engine VM functions
|
||||
Crypto, ///< Cryptographic engine/functions
|
||||
Input, ///< Input emulation
|
||||
Network, ///< Network emulation
|
||||
WebService, ///< Interface to yuzu Web Services
|
||||
Count ///< Total number of logging classes
|
||||
};
|
||||
|
||||
/**
|
||||
* A log entry. Log entries are store in a structured format to permit more varied output
|
||||
* formatting on different frontends, as well as facilitating filtering and aggregation.
|
||||
*/
|
||||
struct Entry {
|
||||
std::chrono::microseconds timestamp;
|
||||
Class log_class{};
|
||||
Level log_level{};
|
||||
const char* filename = nullptr;
|
||||
unsigned int line_num = 0;
|
||||
std::string function;
|
||||
std::string message;
|
||||
bool final_entry = false;
|
||||
};
|
||||
|
||||
} // namespace Common::Log
|
||||
@@ -55,6 +55,7 @@ void LogSettings() {
|
||||
log_setting("Renderer_UseAsynchronousGpuEmulation",
|
||||
values.use_asynchronous_gpu_emulation.GetValue());
|
||||
log_setting("Renderer_UseNvdecEmulation", values.use_nvdec_emulation.GetValue());
|
||||
log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue());
|
||||
log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
|
||||
log_setting("Renderer_UseAssemblyShaders", values.use_assembly_shaders.GetValue());
|
||||
log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
|
||||
@@ -121,6 +122,7 @@ void RestoreGlobalState(bool is_powered_on) {
|
||||
values.cpu_accuracy.SetGlobal(true);
|
||||
values.cpuopt_unsafe_unfuse_fma.SetGlobal(true);
|
||||
values.cpuopt_unsafe_reduce_fp_error.SetGlobal(true);
|
||||
values.cpuopt_unsafe_ignore_standard_fpcr.SetGlobal(true);
|
||||
values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true);
|
||||
values.cpuopt_unsafe_fastmem_check.SetGlobal(true);
|
||||
|
||||
@@ -135,6 +137,7 @@ void RestoreGlobalState(bool is_powered_on) {
|
||||
values.gpu_accuracy.SetGlobal(true);
|
||||
values.use_asynchronous_gpu_emulation.SetGlobal(true);
|
||||
values.use_nvdec_emulation.SetGlobal(true);
|
||||
values.accelerate_astc.SetGlobal(true);
|
||||
values.use_vsync.SetGlobal(true);
|
||||
values.use_assembly_shaders.SetGlobal(true);
|
||||
values.use_asynchronous_shaders.SetGlobal(true);
|
||||
|
||||
@@ -129,6 +129,7 @@ struct Values {
|
||||
|
||||
Setting<bool> cpuopt_unsafe_unfuse_fma;
|
||||
Setting<bool> cpuopt_unsafe_reduce_fp_error;
|
||||
Setting<bool> cpuopt_unsafe_ignore_standard_fpcr;
|
||||
Setting<bool> cpuopt_unsafe_inaccurate_nan;
|
||||
Setting<bool> cpuopt_unsafe_fastmem_check;
|
||||
|
||||
@@ -147,7 +148,9 @@ struct Values {
|
||||
Setting<GPUAccuracy> gpu_accuracy;
|
||||
Setting<bool> use_asynchronous_gpu_emulation;
|
||||
Setting<bool> use_nvdec_emulation;
|
||||
Setting<bool> accelerate_astc;
|
||||
Setting<bool> use_vsync;
|
||||
Setting<bool> disable_fps_limit;
|
||||
Setting<bool> use_assembly_shaders;
|
||||
Setting<bool> use_asynchronous_shaders;
|
||||
Setting<bool> use_fast_gpu_time;
|
||||
@@ -218,6 +221,7 @@ struct Values {
|
||||
std::string program_args;
|
||||
bool dump_exefs;
|
||||
bool dump_nso;
|
||||
bool enable_fs_access_log;
|
||||
bool reporting_services;
|
||||
bool quest_flag;
|
||||
bool disable_macro_jit;
|
||||
|
||||
@@ -139,6 +139,7 @@ add_library(core STATIC
|
||||
frontend/input.h
|
||||
hardware_interrupt_manager.cpp
|
||||
hardware_interrupt_manager.h
|
||||
hle/api_version.h
|
||||
hle/ipc.h
|
||||
hle/ipc_helpers.h
|
||||
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/spl.cpp
|
||||
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.h
|
||||
hle/service/time/clock_types.h
|
||||
|
||||
@@ -186,6 +186,9 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
|
||||
if (Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue()) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
|
||||
}
|
||||
if (Settings::values.cpuopt_unsafe_ignore_standard_fpcr.GetValue()) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_IgnoreStandardFPCRValue;
|
||||
}
|
||||
if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
@@ -377,7 +378,7 @@ struct System::Impl {
|
||||
std::unique_ptr<Core::DeviceMemory> device_memory;
|
||||
Core::Memory::Memory memory;
|
||||
CpuManager cpu_manager;
|
||||
bool is_powered_on = false;
|
||||
std::atomic_bool is_powered_on{};
|
||||
bool exit_lock = false;
|
||||
|
||||
Reporter reporter;
|
||||
@@ -463,7 +464,7 @@ System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::st
|
||||
}
|
||||
|
||||
bool System::IsPoweredOn() const {
|
||||
return impl->is_powered_on;
|
||||
return impl->is_powered_on.load(std::memory_order::relaxed);
|
||||
}
|
||||
|
||||
void System::PrepareReschedule() {
|
||||
|
||||
@@ -4,47 +4,29 @@
|
||||
|
||||
#include "core/file_sys/system_archive/system_version.h"
|
||||
#include "core/file_sys/vfs_vector.h"
|
||||
#include "core/hle/api_version.h"
|
||||
|
||||
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() {
|
||||
return SystemVersionData::DISPLAY_TITLE;
|
||||
return HLE::ApiVersion::DISPLAY_TITLE;
|
||||
}
|
||||
|
||||
VirtualDir SystemVersion() {
|
||||
VirtualFile file = std::make_shared<VectorVfsFile>(std::vector<u8>(0x100), "file");
|
||||
file->WriteObject(SystemVersionData::VERSION_MAJOR, 0);
|
||||
file->WriteObject(SystemVersionData::VERSION_MINOR, 1);
|
||||
file->WriteObject(SystemVersionData::VERSION_MICRO, 2);
|
||||
file->WriteObject(SystemVersionData::REVISION_MAJOR, 4);
|
||||
file->WriteObject(SystemVersionData::REVISION_MINOR, 5);
|
||||
file->WriteArray(SystemVersionData::PLATFORM_STRING,
|
||||
std::min<u64>(sizeof(SystemVersionData::PLATFORM_STRING), 0x20ULL), 0x8);
|
||||
file->WriteArray(SystemVersionData::VERSION_HASH,
|
||||
std::min<u64>(sizeof(SystemVersionData::VERSION_HASH), 0x40ULL), 0x28);
|
||||
file->WriteArray(SystemVersionData::DISPLAY_VERSION,
|
||||
std::min<u64>(sizeof(SystemVersionData::DISPLAY_VERSION), 0x18ULL), 0x68);
|
||||
file->WriteArray(SystemVersionData::DISPLAY_TITLE,
|
||||
std::min<u64>(sizeof(SystemVersionData::DISPLAY_TITLE), 0x80ULL), 0x80);
|
||||
file->WriteObject(HLE::ApiVersion::HOS_VERSION_MAJOR, 0);
|
||||
file->WriteObject(HLE::ApiVersion::HOS_VERSION_MINOR, 1);
|
||||
file->WriteObject(HLE::ApiVersion::HOS_VERSION_MICRO, 2);
|
||||
file->WriteObject(HLE::ApiVersion::SDK_REVISION_MAJOR, 4);
|
||||
file->WriteObject(HLE::ApiVersion::SDK_REVISION_MINOR, 5);
|
||||
file->WriteArray(HLE::ApiVersion::PLATFORM_STRING,
|
||||
std::min<u64>(sizeof(HLE::ApiVersion::PLATFORM_STRING), 0x20ULL), 0x8);
|
||||
file->WriteArray(HLE::ApiVersion::VERSION_HASH,
|
||||
std::min<u64>(sizeof(HLE::ApiVersion::VERSION_HASH), 0x40ULL), 0x28);
|
||||
file->WriteArray(HLE::ApiVersion::DISPLAY_VERSION,
|
||||
std::min<u64>(sizeof(HLE::ApiVersion::DISPLAY_VERSION), 0x18ULL), 0x68);
|
||||
file->WriteArray(HLE::ApiVersion::DISPLAY_TITLE,
|
||||
std::min<u64>(sizeof(HLE::ApiVersion::DISPLAY_TITLE), 0x80ULL), 0x80);
|
||||
return std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{file},
|
||||
std::vector<VirtualDir>{}, "data");
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <numeric>
|
||||
#include <string>
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/logging/backend.h"
|
||||
#include "core/file_sys/mode.h"
|
||||
#include "core/file_sys/vfs.h"
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#endif
|
||||
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/logging/backend.h"
|
||||
#include "core/file_sys/vfs.h"
|
||||
#include "core/file_sys/vfs_libzip.h"
|
||||
#include "core/file_sys/vfs_vector.h"
|
||||
|
||||
@@ -24,17 +24,12 @@ constexpr FS::FileAccessMode ModeFlagsToFileAccessMode(Mode mode) {
|
||||
case Mode::Read:
|
||||
return FS::FileAccessMode::Read;
|
||||
case Mode::Write:
|
||||
return FS::FileAccessMode::Write;
|
||||
case Mode::ReadWrite:
|
||||
return FS::FileAccessMode::ReadWrite;
|
||||
case Mode::Append:
|
||||
return FS::FileAccessMode::Append;
|
||||
case Mode::ReadAppend:
|
||||
return FS::FileAccessMode::ReadAppend;
|
||||
case Mode::WriteAppend:
|
||||
return FS::FileAccessMode::Append;
|
||||
case Mode::All:
|
||||
return FS::FileAccessMode::ReadAppend;
|
||||
return FS::FileAccessMode::ReadWrite;
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
38
src/core/hle/api_version.h
Normal file
38
src/core/hle/api_version.h
Normal 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
|
||||
@@ -79,6 +79,7 @@ ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
|
||||
R_UNLESS(current_values[index] <= value, ResultInvalidState);
|
||||
|
||||
limit_values[index] = value;
|
||||
peak_values[index] = current_values[index];
|
||||
|
||||
return ResultSuccess;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging/backend.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/core.h"
|
||||
@@ -314,7 +313,7 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe
|
||||
LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
|
||||
|
||||
if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
|
||||
void(Common::FS::RemoveFile(zip_path));
|
||||
Common::FS::RemoveFile(zip_path);
|
||||
}
|
||||
|
||||
HandleDownloadDisplayResult(applet_manager, res);
|
||||
@@ -446,7 +445,7 @@ std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title)
|
||||
LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res);
|
||||
|
||||
if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) {
|
||||
void(Common::FS::RemoveFile(bin_file_path));
|
||||
Common::FS::RemoveFile(bin_file_path);
|
||||
}
|
||||
|
||||
HandleDownloadDisplayResult(applet_manager, res);
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@@ -14,6 +13,7 @@
|
||||
#include "common/common_types.h"
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/directory.h"
|
||||
@@ -786,6 +786,10 @@ FSP_SRV::FSP_SRV(Core::System& system_)
|
||||
};
|
||||
// clang-format on
|
||||
RegisterHandlers(functions);
|
||||
|
||||
if (Settings::values.enable_fs_access_log) {
|
||||
access_log_mode = AccessLogMode::SdCard;
|
||||
}
|
||||
}
|
||||
|
||||
FSP_SRV::~FSP_SRV() = default;
|
||||
@@ -1042,9 +1046,9 @@ void FSP_SRV::DisableAutoSaveDataCreation(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
log_mode = rp.PopEnum<LogMode>();
|
||||
access_log_mode = rp.PopEnum<AccessLogMode>();
|
||||
|
||||
LOG_DEBUG(Service_FS, "called, log_mode={:08X}", log_mode);
|
||||
LOG_DEBUG(Service_FS, "called, access_log_mode={}", access_log_mode);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
@@ -1055,7 +1059,7 @@ void FSP_SRV::GetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.PushEnum(log_mode);
|
||||
rb.PushEnum(access_log_mode);
|
||||
}
|
||||
|
||||
void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) {
|
||||
@@ -1063,11 +1067,9 @@ void FSP_SRV::OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx) {
|
||||
auto log = Common::StringFromFixedZeroTerminatedBuffer(
|
||||
reinterpret_cast<const char*>(raw.data()), raw.size());
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::microseconds(50));
|
||||
LOG_DEBUG(Service_FS, "called");
|
||||
|
||||
LOG_DEBUG(Service_FS, "called, log='{}'", log);
|
||||
|
||||
reporter.SaveFilesystemAccessReport(log_mode, std::move(log));
|
||||
reporter.SaveFSAccessLog(log);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(ResultSuccess);
|
||||
|
||||
@@ -24,11 +24,10 @@ enum class AccessLogVersion : u32 {
|
||||
Latest = V7_0_0,
|
||||
};
|
||||
|
||||
enum class LogMode : u32 {
|
||||
Off,
|
||||
enum class AccessLogMode : u32 {
|
||||
None,
|
||||
Log,
|
||||
RedirectToSdCard,
|
||||
LogToSdCard = Log | RedirectToSdCard,
|
||||
SdCard,
|
||||
};
|
||||
|
||||
class FSP_SRV final : public ServiceFramework<FSP_SRV> {
|
||||
@@ -59,13 +58,12 @@ private:
|
||||
|
||||
FileSystemController& fsc;
|
||||
const FileSys::ContentProvider& content_provider;
|
||||
const Core::Reporter& reporter;
|
||||
|
||||
FileSys::VirtualFile romfs;
|
||||
u64 current_process_id = 0;
|
||||
u32 access_log_program_index = 0;
|
||||
LogMode log_mode = LogMode::LogToSdCard;
|
||||
|
||||
const Core::Reporter& reporter;
|
||||
AccessLogMode access_log_mode = AccessLogMode::None;
|
||||
};
|
||||
|
||||
} // namespace Service::FileSystem
|
||||
|
||||
@@ -236,7 +236,7 @@ Hid::Hid(Core::System& system_) : ServiceFramework{system_, "hid"} {
|
||||
{80, &Hid::GetGyroscopeZeroDriftMode, "GetGyroscopeZeroDriftMode"},
|
||||
{81, &Hid::ResetGyroscopeZeroDriftMode, "ResetGyroscopeZeroDriftMode"},
|
||||
{82, &Hid::IsSixAxisSensorAtRest, "IsSixAxisSensorAtRest"},
|
||||
{83, nullptr, "IsFirmwareUpdateAvailableForSixAxisSensor"},
|
||||
{83, &Hid::IsFirmwareUpdateAvailableForSixAxisSensor, "IsFirmwareUpdateAvailableForSixAxisSensor"},
|
||||
{91, &Hid::ActivateGesture, "ActivateGesture"},
|
||||
{100, &Hid::SetSupportedNpadStyleSet, "SetSupportedNpadStyleSet"},
|
||||
{101, &Hid::GetSupportedNpadStyleSet, "GetSupportedNpadStyleSet"},
|
||||
@@ -710,6 +710,27 @@ void Hid::IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx) {
|
||||
.IsSixAxisSensorAtRest());
|
||||
}
|
||||
|
||||
void Hid::IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
Controller_NPad::DeviceHandle sixaxis_handle;
|
||||
INSERT_PADDING_WORDS_NOINIT(1);
|
||||
u64 applet_resource_user_id;
|
||||
};
|
||||
|
||||
const auto parameters{rp.PopRaw<Parameters>()};
|
||||
|
||||
LOG_WARNING(
|
||||
Service_HID,
|
||||
"(STUBBED) called, npad_type={}, npad_id={}, device_index={}, applet_resource_user_id={}",
|
||||
parameters.sixaxis_handle.npad_type, parameters.sixaxis_handle.npad_id,
|
||||
parameters.sixaxis_handle.device_index, parameters.applet_resource_user_id);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 3};
|
||||
rb.Push(ResultSuccess);
|
||||
rb.Push(false);
|
||||
}
|
||||
|
||||
void Hid::ActivateGesture(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
struct Parameters {
|
||||
|
||||
@@ -100,6 +100,7 @@ private:
|
||||
void GetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
|
||||
void ResetGyroscopeZeroDriftMode(Kernel::HLERequestContext& ctx);
|
||||
void IsSixAxisSensorAtRest(Kernel::HLERequestContext& ctx);
|
||||
void IsFirmwareUpdateAvailableForSixAxisSensor(Kernel::HLERequestContext& ctx);
|
||||
void ActivateGesture(Kernel::HLERequestContext& ctx);
|
||||
void SetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
|
||||
void GetSupportedNpadStyleSet(Kernel::HLERequestContext& ctx);
|
||||
|
||||
@@ -51,6 +51,24 @@ struct hash<Service::LM::LogPacketHeaderEntry> {
|
||||
} // namespace std
|
||||
|
||||
namespace Service::LM {
|
||||
namespace {
|
||||
std::string_view NameOf(LogSeverity severity) {
|
||||
switch (severity) {
|
||||
case LogSeverity::Trace:
|
||||
return "TRACE";
|
||||
case LogSeverity::Info:
|
||||
return "INFO";
|
||||
case LogSeverity::Warning:
|
||||
return "WARNING";
|
||||
case LogSeverity::Error:
|
||||
return "ERROR";
|
||||
case LogSeverity::Fatal:
|
||||
return "FATAL";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
enum class LogDestination : u32 {
|
||||
TargetManager = 1 << 0,
|
||||
@@ -262,33 +280,8 @@ private:
|
||||
if (text_log) {
|
||||
output_log += fmt::format("Log Text: {}\n", *text_log);
|
||||
}
|
||||
|
||||
switch (entry.severity) {
|
||||
case LogSeverity::Trace:
|
||||
LOG_DEBUG(Service_LM, "LogManager TRACE ({}):\n{}", DestinationToString(destination),
|
||||
output_log);
|
||||
break;
|
||||
case LogSeverity::Info:
|
||||
LOG_INFO(Service_LM, "LogManager INFO ({}):\n{}", DestinationToString(destination),
|
||||
output_log);
|
||||
break;
|
||||
case LogSeverity::Warning:
|
||||
LOG_WARNING(Service_LM, "LogManager WARNING ({}):\n{}",
|
||||
DestinationToString(destination), output_log);
|
||||
break;
|
||||
case LogSeverity::Error:
|
||||
LOG_ERROR(Service_LM, "LogManager ERROR ({}):\n{}", DestinationToString(destination),
|
||||
output_log);
|
||||
break;
|
||||
case LogSeverity::Fatal:
|
||||
LOG_CRITICAL(Service_LM, "LogManager FATAL ({}):\n{}", DestinationToString(destination),
|
||||
output_log);
|
||||
break;
|
||||
default:
|
||||
LOG_CRITICAL(Service_LM, "LogManager UNKNOWN ({}):\n{}",
|
||||
DestinationToString(destination), output_log);
|
||||
break;
|
||||
}
|
||||
LOG_DEBUG(Service_LM, "LogManager {} ({}):\n{}", NameOf(entry.severity),
|
||||
DestinationToString(destination), output_log);
|
||||
}
|
||||
|
||||
static std::string DestinationToString(LogDestination destination) {
|
||||
|
||||
@@ -307,6 +307,9 @@ void NVFlinger::Compose() {
|
||||
}
|
||||
|
||||
s64 NVFlinger::GetNextTicks() const {
|
||||
if (Settings::values.disable_fps_limit.GetValue()) {
|
||||
return 0;
|
||||
}
|
||||
constexpr s64 max_hertz = 120LL;
|
||||
return (1000000000 * (1LL << swap_interval)) / max_hertz;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Service::SPL {
|
||||
CSRNG::CSRNG(Core::System& system_, std::shared_ptr<Module> module_)
|
||||
: Interface(system_, std::move(module_), "csrng") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &CSRNG::GetRandomBytes, "GetRandomBytes"},
|
||||
{0, &CSRNG::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
#include "common/logging/log.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/hle/api_version.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/spl/csrng.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;
|
||||
|
||||
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");
|
||||
|
||||
const std::size_t size = ctx.GetWriteBufferSize();
|
||||
@@ -39,6 +79,88 @@ void Module::Interface::GetRandomBytes(Kernel::HLERequestContext& ctx) {
|
||||
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) {
|
||||
auto module = std::make_shared<Module>();
|
||||
std::make_shared<CSRNG>(system, module)->InstallAsService(service_manager);
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
|
||||
#include <random>
|
||||
#include "core/hle/service/service.h"
|
||||
#include "core/hle/service/spl/spl_results.h"
|
||||
#include "core/hle/service/spl/spl_types.h"
|
||||
|
||||
namespace Core {
|
||||
class System;
|
||||
@@ -21,12 +23,21 @@ public:
|
||||
const char* name);
|
||||
~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:
|
||||
std::shared_ptr<Module> module;
|
||||
|
||||
private:
|
||||
ResultVal<u64> GetConfigImpl(ConfigItem config_item) const;
|
||||
|
||||
std::mt19937 rng;
|
||||
};
|
||||
};
|
||||
|
||||
@@ -10,13 +10,13 @@ SPL::SPL(Core::System& system_, std::shared_ptr<Module> module_)
|
||||
: Interface(system_, std::move(module_), "spl:") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetConfig"},
|
||||
{1, nullptr, "ModularExponentiate"},
|
||||
{5, nullptr, "SetConfig"},
|
||||
{7, &SPL::GetRandomBytes, "GetRandomBytes"},
|
||||
{11, nullptr, "IsDevelopment"},
|
||||
{24, nullptr, "SetBootReason"},
|
||||
{25, nullptr, "GetBootReason"},
|
||||
{0, &SPL::GetConfig, "GetConfig"},
|
||||
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||
{5, &SPL::SetConfig, "SetConfig"},
|
||||
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||
};
|
||||
// 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") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetConfig"},
|
||||
{1, nullptr, "ModularExponentiate"},
|
||||
{0, &SPL::GetConfig, "GetConfig"},
|
||||
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||
{2, nullptr, "GenerateAesKek"},
|
||||
{3, nullptr, "LoadAesKey"},
|
||||
{4, nullptr, "GenerateAesKey"},
|
||||
{5, nullptr, "SetConfig"},
|
||||
{7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
|
||||
{11, nullptr, "IsDevelopment"},
|
||||
{5, &SPL::SetConfig, "SetConfig"},
|
||||
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||
{14, nullptr, "DecryptAesKey"},
|
||||
{15, nullptr, "CryptAesCtr"},
|
||||
{16, nullptr, "ComputeCmac"},
|
||||
{21, nullptr, "AllocateAesKeyslot"},
|
||||
{22, nullptr, "DeallocateAesKeySlot"},
|
||||
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
||||
{24, nullptr, "SetBootReason"},
|
||||
{25, nullptr, "GetBootReason"},
|
||||
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||
};
|
||||
// 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") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetConfig"},
|
||||
{1, nullptr, "ModularExponentiate"},
|
||||
{0, &SPL::GetConfig, "GetConfig"},
|
||||
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||
{2, nullptr, "GenerateAesKek"},
|
||||
{3, nullptr, "LoadAesKey"},
|
||||
{4, nullptr, "GenerateAesKey"},
|
||||
{5, nullptr, "SetConfig"},
|
||||
{7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
|
||||
{5, &SPL::SetConfig, "SetConfig"},
|
||||
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||
{9, nullptr, "ImportLotusKey"},
|
||||
{10, nullptr, "DecryptLotusMessage"},
|
||||
{11, nullptr, "IsDevelopment"},
|
||||
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||
{12, nullptr, "GenerateSpecificAesKey"},
|
||||
{14, nullptr, "DecryptAesKey"},
|
||||
{15, nullptr, "CryptAesCtr"},
|
||||
@@ -71,8 +71,8 @@ SPL_FS::SPL_FS(Core::System& system_, std::shared_ptr<Module> module_)
|
||||
{21, nullptr, "AllocateAesKeyslot"},
|
||||
{22, nullptr, "DeallocateAesKeySlot"},
|
||||
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
||||
{24, nullptr, "SetBootReason"},
|
||||
{25, nullptr, "GetBootReason"},
|
||||
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||
{31, nullptr, "GetPackage2Hash"},
|
||||
};
|
||||
// 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") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetConfig"},
|
||||
{1, nullptr, "ModularExponentiate"},
|
||||
{0, &SPL::GetConfig, "GetConfig"},
|
||||
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||
{2, nullptr, "GenerateAesKek"},
|
||||
{3, nullptr, "LoadAesKey"},
|
||||
{4, nullptr, "GenerateAesKey"},
|
||||
{5, nullptr, "SetConfig"},
|
||||
{7, &SPL::GetRandomBytes, "GetRandomBytes"},
|
||||
{11, nullptr, "IsDevelopment"},
|
||||
{5, &SPL::SetConfig, "SetConfig"},
|
||||
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||
{13, nullptr, "DecryptDeviceUniqueData"},
|
||||
{14, nullptr, "DecryptAesKey"},
|
||||
{15, nullptr, "CryptAesCtr"},
|
||||
@@ -99,8 +99,8 @@ SPL_SSL::SPL_SSL(Core::System& system_, std::shared_ptr<Module> module_)
|
||||
{21, nullptr, "AllocateAesKeyslot"},
|
||||
{22, nullptr, "DeallocateAesKeySlot"},
|
||||
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
||||
{24, nullptr, "SetBootReason"},
|
||||
{25, nullptr, "GetBootReason"},
|
||||
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||
{26, nullptr, "DecryptAndStoreSslClientCertKey"},
|
||||
{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") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetConfig"},
|
||||
{1, nullptr, "ModularExponentiate"},
|
||||
{0, &SPL::GetConfig, "GetConfig"},
|
||||
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||
{2, nullptr, "GenerateAesKek"},
|
||||
{3, nullptr, "LoadAesKey"},
|
||||
{4, nullptr, "GenerateAesKey"},
|
||||
{5, nullptr, "SetConfig"},
|
||||
{7, &SPL::GetRandomBytes, "GenerateRandomBytes"},
|
||||
{11, nullptr, "IsDevelopment"},
|
||||
{5, &SPL::SetConfig, "SetConfig"},
|
||||
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||
{13, nullptr, "DecryptDeviceUniqueData"},
|
||||
{14, nullptr, "DecryptAesKey"},
|
||||
{15, nullptr, "CryptAesCtr"},
|
||||
@@ -131,8 +131,8 @@ SPL_ES::SPL_ES(Core::System& system_, std::shared_ptr<Module> module_)
|
||||
{21, nullptr, "AllocateAesKeyslot"},
|
||||
{22, nullptr, "DeallocateAesKeySlot"},
|
||||
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
||||
{24, nullptr, "SetBootReason"},
|
||||
{25, nullptr, "GetBootReason"},
|
||||
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||
{28, nullptr, "DecryptAndStoreDrmDeviceCertKey"},
|
||||
{29, nullptr, "ModularExponentiateWithDrmDeviceCertKey"},
|
||||
{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") {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, nullptr, "GetConfig"},
|
||||
{1, nullptr, "ModularExponentiate"},
|
||||
{0, &SPL::GetConfig, "GetConfig"},
|
||||
{1, &SPL::ModularExponentiate, "ModularExponentiate"},
|
||||
{2, nullptr, "GenerateAesKek"},
|
||||
{3, nullptr, "LoadAesKey"},
|
||||
{4, nullptr, "GenerateAesKey"},
|
||||
{5, nullptr, "SetConfig"},
|
||||
{7, &SPL::GetRandomBytes, "GetRandomBytes"},
|
||||
{11, nullptr, "IsDevelopment"},
|
||||
{5, &SPL::SetConfig, "SetConfig"},
|
||||
{7, &SPL::GenerateRandomBytes, "GenerateRandomBytes"},
|
||||
{11, &SPL::IsDevelopment, "IsDevelopment"},
|
||||
{13, nullptr, "DecryptDeviceUniqueData"},
|
||||
{14, nullptr, "DecryptAesKey"},
|
||||
{15, nullptr, "CryptAesCtr"},
|
||||
@@ -162,8 +162,8 @@ SPL_MANU::SPL_MANU(Core::System& system_, std::shared_ptr<Module> module_)
|
||||
{21, nullptr, "AllocateAesKeyslot"},
|
||||
{22, nullptr, "DeallocateAesKeySlot"},
|
||||
{23, nullptr, "GetAesKeyslotAvailableEvent"},
|
||||
{24, nullptr, "SetBootReason"},
|
||||
{25, nullptr, "GetBootReason"},
|
||||
{24, &SPL::SetBootReason, "SetBootReason"},
|
||||
{25, &SPL::GetBootReason, "GetBootReason"},
|
||||
{30, nullptr, "ReencryptDeviceUniqueData"},
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
29
src/core/hle/service/spl/spl_results.h
Normal file
29
src/core/hle/service/spl/spl_results.h
Normal 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
Normal file
230
src/core/hle/service/spl/spl_types.h
Normal 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;
|
||||
}
|
||||
|
||||
vfs_file = zoneinfo_dir->GetFile(location_name);
|
||||
vfs_file = zoneinfo_dir->GetFileRelative(location_name);
|
||||
if (!vfs_file) {
|
||||
LOG_ERROR(Service_Time, "{:016X} has no file \"{}\"! Using default timezone.",
|
||||
time_zone_binary_titleid, location_name);
|
||||
|
||||
@@ -195,7 +195,9 @@ json GetHLERequestContextData(Kernel::HLERequestContext& ctx, Core::Memory::Memo
|
||||
|
||||
namespace Core {
|
||||
|
||||
Reporter::Reporter(System& system_) : system(system_) {}
|
||||
Reporter::Reporter(System& system_) : system(system_) {
|
||||
ClearFSAccessLog();
|
||||
}
|
||||
|
||||
Reporter::~Reporter() = default;
|
||||
|
||||
@@ -362,22 +364,12 @@ void Reporter::SaveErrorReport(u64 title_id, ResultCode result,
|
||||
SaveToFile(std::move(out), GetPath("error_report", title_id, timestamp));
|
||||
}
|
||||
|
||||
void Reporter::SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode,
|
||||
std::string log_message) const {
|
||||
if (!IsReportingEnabled())
|
||||
return;
|
||||
void Reporter::SaveFSAccessLog(std::string_view log_message) const {
|
||||
const auto access_log_path =
|
||||
Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "FsAccessLog.txt";
|
||||
|
||||
const auto timestamp = GetTimestamp();
|
||||
const auto title_id = system.CurrentProcess()->GetTitleID();
|
||||
json out;
|
||||
|
||||
out["yuzu_version"] = GetYuzuVersionData();
|
||||
out["report_common"] = GetReportCommonData(title_id, ResultSuccess, timestamp);
|
||||
|
||||
out["log_mode"] = fmt::format("{:08X}", static_cast<u32>(log_mode));
|
||||
out["log_message"] = std::move(log_message);
|
||||
|
||||
SaveToFile(std::move(out), GetPath("filesystem_access_report", title_id, timestamp));
|
||||
void(Common::FS::AppendStringToFile(access_log_path, Common::FS::FileType::TextFile,
|
||||
log_message));
|
||||
}
|
||||
|
||||
void Reporter::SaveUserReport() const {
|
||||
@@ -392,6 +384,18 @@ void Reporter::SaveUserReport() const {
|
||||
GetPath("user_report", title_id, timestamp));
|
||||
}
|
||||
|
||||
void Reporter::ClearFSAccessLog() const {
|
||||
const auto access_log_path =
|
||||
Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir) / "FsAccessLog.txt";
|
||||
|
||||
Common::FS::IOFile access_log_file{access_log_path, Common::FS::FileAccessMode::Write,
|
||||
Common::FS::FileType::TextFile};
|
||||
|
||||
if (!access_log_file.IsOpen()) {
|
||||
LOG_ERROR(Common_Filesystem, "Failed to clear the filesystem access log.");
|
||||
}
|
||||
}
|
||||
|
||||
bool Reporter::IsReportingEnabled() const {
|
||||
return Settings::values.reporting_services;
|
||||
}
|
||||
|
||||
@@ -16,10 +16,6 @@ namespace Kernel {
|
||||
class HLERequestContext;
|
||||
} // namespace Kernel
|
||||
|
||||
namespace Service::FileSystem {
|
||||
enum class LogMode : u32;
|
||||
}
|
||||
|
||||
namespace Service::LM {
|
||||
struct LogMessage;
|
||||
} // namespace Service::LM
|
||||
@@ -69,14 +65,15 @@ public:
|
||||
std::optional<std::string> custom_text_main = {},
|
||||
std::optional<std::string> custom_text_detail = {}) const;
|
||||
|
||||
void SaveFilesystemAccessReport(Service::FileSystem::LogMode log_mode,
|
||||
std::string log_message) const;
|
||||
void SaveFSAccessLog(std::string_view log_message) const;
|
||||
|
||||
// Can be used anywhere to generate a backtrace and general info report at any point during
|
||||
// execution. Not intended to be used for anything other than debugging or testing.
|
||||
void SaveUserReport() const;
|
||||
|
||||
private:
|
||||
void ClearFSAccessLog() const;
|
||||
|
||||
bool IsReportingEnabled() const;
|
||||
|
||||
System& system;
|
||||
|
||||
@@ -230,6 +230,7 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader,
|
||||
Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||
AddField(field_type, "Renderer_UseNvdecEmulation",
|
||||
Settings::values.use_nvdec_emulation.GetValue());
|
||||
AddField(field_type, "Renderer_AccelerateASTC", Settings::values.accelerate_astc.GetValue());
|
||||
AddField(field_type, "Renderer_UseVsync", Settings::values.use_vsync.GetValue());
|
||||
AddField(field_type, "Renderer_UseAssemblyShaders",
|
||||
Settings::values.use_assembly_shaders.GetValue());
|
||||
|
||||
@@ -237,6 +237,7 @@ add_library(video_core STATIC
|
||||
texture_cache/util.cpp
|
||||
texture_cache/util.h
|
||||
textures/astc.h
|
||||
textures/astc.cpp
|
||||
textures/decoders.cpp
|
||||
textures/decoders.h
|
||||
textures/texture.cpp
|
||||
|
||||
@@ -763,7 +763,7 @@ void ComputeEndpoints(out uvec4 ep1, out uvec4 ep2, uint color_endpoint_mode) {
|
||||
case 1: {
|
||||
READ_UINT_VALUES(2)
|
||||
uint L0 = (v[0] >> 2) | (v[1] & 0xC0);
|
||||
uint L1 = max(L0 + (v[1] & 0x3F), 0xFFU);
|
||||
uint L1 = min(L0 + (v[1] & 0x3F), 0xFFU);
|
||||
ep1 = uvec4(0xFF, L0, L0, L0);
|
||||
ep2 = uvec4(0xFF, L1, L1, L1);
|
||||
break;
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
#include "common/settings.h"
|
||||
|
||||
#include "video_core/renderer_opengl/gl_device.h"
|
||||
#include "video_core/renderer_opengl/gl_shader_manager.h"
|
||||
#include "video_core/renderer_opengl/gl_state_tracker.h"
|
||||
@@ -307,7 +309,9 @@ void ApplySwizzle(GLuint handle, PixelFormat format, std::array<SwizzleSource, 4
|
||||
|
||||
[[nodiscard]] bool CanBeAccelerated(const TextureCacheRuntime& runtime,
|
||||
const VideoCommon::ImageInfo& info) {
|
||||
return !runtime.HasNativeASTC() && IsPixelFormatASTC(info.format);
|
||||
if (IsPixelFormatASTC(info.format)) {
|
||||
return !runtime.HasNativeASTC() && Settings::values.accelerate_astc.GetValue();
|
||||
}
|
||||
// Disable other accelerated uploads for now as they don't implement swizzled uploads
|
||||
return false;
|
||||
switch (info.type) {
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "common/settings.h"
|
||||
#include "video_core/renderer_vulkan/vk_master_semaphore.h"
|
||||
@@ -12,8 +11,6 @@
|
||||
|
||||
namespace Vulkan {
|
||||
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
MasterSemaphore::MasterSemaphore(const Device& device) {
|
||||
static constexpr VkSemaphoreTypeCreateInfoKHR semaphore_type_ci{
|
||||
.sType = VK_STRUCTURE_TYPE_SEMAPHORE_TYPE_CREATE_INFO_KHR,
|
||||
@@ -34,9 +31,9 @@ MasterSemaphore::MasterSemaphore(const Device& device) {
|
||||
// Validation layers have a bug where they fail to track resource usage when using timeline
|
||||
// semaphores and synchronizing with GetSemaphoreCounterValueKHR. To workaround this issue, have
|
||||
// a separate thread waiting for each timeline semaphore value.
|
||||
debug_thread = std::thread([this] {
|
||||
debug_thread = std::jthread([this](std::stop_token stop_token) {
|
||||
u64 counter = 0;
|
||||
while (!shutdown) {
|
||||
while (!stop_token.stop_requested()) {
|
||||
if (semaphore.Wait(counter, 10'000'000)) {
|
||||
++counter;
|
||||
}
|
||||
@@ -44,13 +41,6 @@ MasterSemaphore::MasterSemaphore(const Device& device) {
|
||||
});
|
||||
}
|
||||
|
||||
MasterSemaphore::~MasterSemaphore() {
|
||||
shutdown = true;
|
||||
|
||||
// This thread might not be started
|
||||
if (debug_thread.joinable()) {
|
||||
debug_thread.join();
|
||||
}
|
||||
}
|
||||
MasterSemaphore::~MasterSemaphore() = default;
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -65,11 +65,10 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
vk::Semaphore semaphore; ///< Timeline semaphore.
|
||||
std::atomic<u64> gpu_tick{0}; ///< Current known GPU tick.
|
||||
std::atomic<u64> current_tick{1}; ///< Current logical tick.
|
||||
std::atomic<bool> shutdown{false}; ///< True when the object is being destroyed.
|
||||
std::thread debug_thread; ///< Debug thread to workaround validation layer bugs.
|
||||
vk::Semaphore semaphore; ///< Timeline semaphore.
|
||||
std::atomic<u64> gpu_tick{0}; ///< Current known GPU tick.
|
||||
std::atomic<u64> current_tick{1}; ///< Current logical tick.
|
||||
std::jthread debug_thread; ///< Debug thread to workaround validation layer bugs.
|
||||
};
|
||||
|
||||
} // namespace Vulkan
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "common/bit_cast.h"
|
||||
#include "common/settings.h"
|
||||
|
||||
#include "video_core/engines/fermi_2d.h"
|
||||
#include "video_core/renderer_vulkan/blit_image.h"
|
||||
@@ -828,7 +829,11 @@ Image::Image(TextureCacheRuntime& runtime, const ImageInfo& info_, GPUVAddr gpu_
|
||||
commit = runtime.memory_allocator.Commit(buffer, MemoryUsage::DeviceLocal);
|
||||
}
|
||||
if (IsPixelFormatASTC(info.format) && !runtime.device.IsOptimalAstcSupported()) {
|
||||
flags |= VideoCommon::ImageFlagBits::AcceleratedUpload;
|
||||
if (Settings::values.accelerate_astc.GetValue()) {
|
||||
flags |= VideoCommon::ImageFlagBits::AcceleratedUpload;
|
||||
} else {
|
||||
flags |= VideoCommon::ImageFlagBits::Converted;
|
||||
}
|
||||
}
|
||||
if (runtime.device.HasDebuggingToolAttached()) {
|
||||
if (image) {
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "video_core/texture_cache/formatter.h"
|
||||
#include "video_core/texture_cache/samples_helper.h"
|
||||
#include "video_core/texture_cache/util.h"
|
||||
#include "video_core/textures/astc.h"
|
||||
#include "video_core/textures/decoders.h"
|
||||
|
||||
namespace VideoCommon {
|
||||
@@ -884,8 +885,16 @@ void ConvertImage(std::span<const u8> input, const ImageInfo& info, std::span<u8
|
||||
ASSERT(copy.image_extent == mip_size);
|
||||
ASSERT(copy.buffer_row_length == Common::AlignUp(mip_size.width, tile_size.width));
|
||||
ASSERT(copy.buffer_image_height == Common::AlignUp(mip_size.height, tile_size.height));
|
||||
DecompressBC4(input.subspan(copy.buffer_offset), copy.image_extent,
|
||||
output.subspan(output_offset));
|
||||
if (IsPixelFormatASTC(info.format)) {
|
||||
ASSERT(copy.image_extent.depth == 1);
|
||||
Tegra::Texture::ASTC::Decompress(input.subspan(copy.buffer_offset),
|
||||
copy.image_extent.width, copy.image_extent.height,
|
||||
copy.image_subresource.num_layers, tile_size.width,
|
||||
tile_size.height, output.subspan(output_offset));
|
||||
} else {
|
||||
DecompressBC4(input.subspan(copy.buffer_offset), copy.image_extent,
|
||||
output.subspan(output_offset));
|
||||
}
|
||||
copy.buffer_offset = output_offset;
|
||||
copy.buffer_row_length = mip_size.width;
|
||||
copy.buffer_image_height = mip_size.height;
|
||||
@@ -1087,7 +1096,15 @@ std::optional<SubresourceBase> FindSubresource(const ImageInfo& candidate, const
|
||||
return std::nullopt;
|
||||
}
|
||||
const ImageInfo& existing = image.info;
|
||||
if (False(options & RelaxedOptions::Format)) {
|
||||
if (True(options & RelaxedOptions::Format)) {
|
||||
// Format checking is relaxed, but we still have to check for matching bytes per block.
|
||||
// This avoids creating a view for blits on UE4 titles where formats with different bytes
|
||||
// per block are aliased.
|
||||
if (BytesPerBlock(existing.format) != BytesPerBlock(candidate.format)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
} else {
|
||||
// Format comaptibility is not relaxed, ensure we are creating a view on a compatible format
|
||||
if (!IsViewCompatible(existing.format, candidate.format, broken_views, native_bgr)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
1577
src/video_core/textures/astc.cpp
Normal file
1577
src/video_core/textures/astc.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@@ -129,4 +129,7 @@ struct AstcBufferData {
|
||||
decltype(REPLICATE_BYTE_TO_16_TABLE) replicate_byte_to_16 = REPLICATE_BYTE_TO_16_TABLE;
|
||||
} constexpr ASTC_BUFFER_DATA;
|
||||
|
||||
void Decompress(std::span<const uint8_t> data, uint32_t width, uint32_t height, uint32_t depth,
|
||||
uint32_t block_width, uint32_t block_height, std::span<uint8_t> output);
|
||||
|
||||
} // namespace Tegra::Texture::ASTC
|
||||
|
||||
@@ -50,7 +50,7 @@ NsightAftermathTracker::NsightAftermathTracker() {
|
||||
}
|
||||
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)) {
|
||||
LOG_ERROR(Render_Vulkan, "Failed to create Nsight Aftermath dump directory");
|
||||
return;
|
||||
|
||||
@@ -12,6 +12,14 @@ VkBool32 Callback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
|
||||
VkDebugUtilsMessageTypeFlagsEXT type,
|
||||
const VkDebugUtilsMessengerCallbackDataEXT* data,
|
||||
[[maybe_unused]] void* user_data) {
|
||||
// Skip logging known false-positive validation errors
|
||||
switch (static_cast<u32>(data->messageIdNumber)) {
|
||||
case 0x682a878au: // VUID-vkCmdBindVertexBuffers2EXT-pBuffers-parameter
|
||||
case 0x99fb7dfdu: // UNASSIGNED-RequiredParameter (vkCmdBindVertexBuffers2EXT pBuffers[0])
|
||||
return VK_FALSE;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
const std::string_view message{data->pMessage};
|
||||
if (severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) {
|
||||
LOG_CRITICAL(Render_Vulkan, "{}", message);
|
||||
|
||||
@@ -100,8 +100,9 @@ struct Client::Impl {
|
||||
request.body = data;
|
||||
|
||||
httplib::Response response;
|
||||
httplib::Error error;
|
||||
|
||||
if (!cli->send(request, response)) {
|
||||
if (!cli->send(request, response, error)) {
|
||||
LOG_ERROR(WebService, "{} to {} returned null", method, host + path);
|
||||
return WebResult{WebResult::Code::LibError, "Null response", ""};
|
||||
}
|
||||
|
||||
@@ -221,7 +221,7 @@ const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> Config::default
|
||||
// This must be in alphabetical order according to action name as it must have the same order as
|
||||
// UISetting::values.shortcuts, which is alphabetically ordered.
|
||||
// clang-format off
|
||||
const std::array<UISettings::Shortcut, 17> Config::default_hotkeys{{
|
||||
const std::array<UISettings::Shortcut, 18> Config::default_hotkeys{{
|
||||
{QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::WidgetWithChildrenShortcut}},
|
||||
{QStringLiteral("Change Docked Mode"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}},
|
||||
@@ -236,6 +236,7 @@ const std::array<UISettings::Shortcut, 17> Config::default_hotkeys{{
|
||||
{QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
|
||||
{QStringLiteral("Toggle Framerate Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+U"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Mouse Panning"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F9"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
|
||||
{QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}},
|
||||
@@ -647,6 +648,8 @@ void Config::ReadDebuggingValues() {
|
||||
ReadSetting(QStringLiteral("program_args"), QString{}).toString().toStdString();
|
||||
Settings::values.dump_exefs = ReadSetting(QStringLiteral("dump_exefs"), false).toBool();
|
||||
Settings::values.dump_nso = ReadSetting(QStringLiteral("dump_nso"), false).toBool();
|
||||
Settings::values.enable_fs_access_log =
|
||||
ReadSetting(QStringLiteral("enable_fs_access_log"), false).toBool();
|
||||
Settings::values.reporting_services =
|
||||
ReadSetting(QStringLiteral("reporting_services"), false).toBool();
|
||||
Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool();
|
||||
@@ -754,6 +757,8 @@ void Config::ReadCpuValues() {
|
||||
QStringLiteral("cpuopt_unsafe_unfuse_fma"), true);
|
||||
ReadSettingGlobal(Settings::values.cpuopt_unsafe_reduce_fp_error,
|
||||
QStringLiteral("cpuopt_unsafe_reduce_fp_error"), true);
|
||||
ReadSettingGlobal(Settings::values.cpuopt_unsafe_ignore_standard_fpcr,
|
||||
QStringLiteral("cpuopt_unsafe_ignore_standard_fpcr"), true);
|
||||
ReadSettingGlobal(Settings::values.cpuopt_unsafe_inaccurate_nan,
|
||||
QStringLiteral("cpuopt_unsafe_inaccurate_nan"), true);
|
||||
ReadSettingGlobal(Settings::values.cpuopt_unsafe_fastmem_check,
|
||||
@@ -807,7 +812,10 @@ void Config::ReadRendererValues() {
|
||||
QStringLiteral("use_asynchronous_gpu_emulation"), true);
|
||||
ReadSettingGlobal(Settings::values.use_nvdec_emulation, QStringLiteral("use_nvdec_emulation"),
|
||||
true);
|
||||
ReadSettingGlobal(Settings::values.accelerate_astc, QStringLiteral("accelerate_astc"), true);
|
||||
ReadSettingGlobal(Settings::values.use_vsync, QStringLiteral("use_vsync"), true);
|
||||
ReadSettingGlobal(Settings::values.disable_fps_limit, QStringLiteral("disable_fps_limit"),
|
||||
false);
|
||||
ReadSettingGlobal(Settings::values.use_assembly_shaders, QStringLiteral("use_assembly_shaders"),
|
||||
false);
|
||||
ReadSettingGlobal(Settings::values.use_asynchronous_shaders,
|
||||
@@ -1258,6 +1266,8 @@ void Config::SaveDebuggingValues() {
|
||||
QString::fromStdString(Settings::values.program_args), QString{});
|
||||
WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false);
|
||||
WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false);
|
||||
WriteSetting(QStringLiteral("enable_fs_access_log"), Settings::values.enable_fs_access_log,
|
||||
false);
|
||||
WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false);
|
||||
WriteSetting(QStringLiteral("use_debug_asserts"), Settings::values.use_debug_asserts, false);
|
||||
WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false);
|
||||
@@ -1334,6 +1344,8 @@ void Config::SaveCpuValues() {
|
||||
Settings::values.cpuopt_unsafe_unfuse_fma, true);
|
||||
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_reduce_fp_error"),
|
||||
Settings::values.cpuopt_unsafe_reduce_fp_error, true);
|
||||
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_ignore_standard_fpcr"),
|
||||
Settings::values.cpuopt_unsafe_ignore_standard_fpcr, true);
|
||||
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_inaccurate_nan"),
|
||||
Settings::values.cpuopt_unsafe_inaccurate_nan, true);
|
||||
WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_fastmem_check"),
|
||||
@@ -1388,7 +1400,10 @@ void Config::SaveRendererValues() {
|
||||
Settings::values.use_asynchronous_gpu_emulation, true);
|
||||
WriteSettingGlobal(QStringLiteral("use_nvdec_emulation"), Settings::values.use_nvdec_emulation,
|
||||
true);
|
||||
WriteSettingGlobal(QStringLiteral("accelerate_astc"), Settings::values.accelerate_astc, true);
|
||||
WriteSettingGlobal(QStringLiteral("use_vsync"), Settings::values.use_vsync, true);
|
||||
WriteSettingGlobal(QStringLiteral("disable_fps_limit"), Settings::values.disable_fps_limit,
|
||||
false);
|
||||
WriteSettingGlobal(QStringLiteral("use_assembly_shaders"),
|
||||
Settings::values.use_assembly_shaders, false);
|
||||
WriteSettingGlobal(QStringLiteral("use_asynchronous_shaders"),
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
default_mouse_buttons;
|
||||
static const std::array<int, Settings::NativeKeyboard::NumKeyboardKeys> default_keyboard_keys;
|
||||
static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods;
|
||||
static const std::array<UISettings::Shortcut, 17> default_hotkeys;
|
||||
static const std::array<UISettings::Shortcut, 18> default_hotkeys;
|
||||
|
||||
private:
|
||||
void Initialize(const std::string& config_name);
|
||||
|
||||
@@ -34,12 +34,15 @@ void ConfigureCpu::SetConfiguration() {
|
||||
ui->accuracy->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_unfuse_fma->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_reduce_fp_error->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_ignore_standard_fpcr->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_inaccurate_nan->setEnabled(runtime_lock);
|
||||
ui->cpuopt_unsafe_fastmem_check->setEnabled(runtime_lock);
|
||||
|
||||
ui->cpuopt_unsafe_unfuse_fma->setChecked(Settings::values.cpuopt_unsafe_unfuse_fma.GetValue());
|
||||
ui->cpuopt_unsafe_reduce_fp_error->setChecked(
|
||||
Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue());
|
||||
ui->cpuopt_unsafe_ignore_standard_fpcr->setChecked(
|
||||
Settings::values.cpuopt_unsafe_ignore_standard_fpcr.GetValue());
|
||||
ui->cpuopt_unsafe_inaccurate_nan->setChecked(
|
||||
Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue());
|
||||
ui->cpuopt_unsafe_fastmem_check->setChecked(
|
||||
@@ -84,6 +87,9 @@ void ConfigureCpu::ApplyConfiguration() {
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_reduce_fp_error,
|
||||
ui->cpuopt_unsafe_reduce_fp_error,
|
||||
cpuopt_unsafe_reduce_fp_error);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_ignore_standard_fpcr,
|
||||
ui->cpuopt_unsafe_ignore_standard_fpcr,
|
||||
cpuopt_unsafe_ignore_standard_fpcr);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_inaccurate_nan,
|
||||
ui->cpuopt_unsafe_inaccurate_nan,
|
||||
cpuopt_unsafe_inaccurate_nan);
|
||||
@@ -137,6 +143,9 @@ void ConfigureCpu::SetupPerGameUI() {
|
||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_reduce_fp_error,
|
||||
Settings::values.cpuopt_unsafe_reduce_fp_error,
|
||||
cpuopt_unsafe_reduce_fp_error);
|
||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_ignore_standard_fpcr,
|
||||
Settings::values.cpuopt_unsafe_ignore_standard_fpcr,
|
||||
cpuopt_unsafe_ignore_standard_fpcr);
|
||||
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_inaccurate_nan,
|
||||
Settings::values.cpuopt_unsafe_inaccurate_nan,
|
||||
cpuopt_unsafe_inaccurate_nan);
|
||||
|
||||
@@ -40,6 +40,7 @@ private:
|
||||
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_unfuse_fma;
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_reduce_fp_error;
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_ignore_standard_fpcr;
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_inaccurate_nan;
|
||||
ConfigurationShared::CheckState cpuopt_unsafe_fastmem_check;
|
||||
};
|
||||
|
||||
@@ -111,6 +111,18 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cpuopt_unsafe_ignore_standard_fpcr">
|
||||
<property name="toolTip">
|
||||
<string>
|
||||
<div>This option improves the speed of 32 bits ASIMD floating-point functions by running with incorrect rounding modes.</div>
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Faster ASIMD instructions (32 bits only)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="cpuopt_unsafe_inaccurate_nan">
|
||||
<property name="toolTip">
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
<br>
|
||||
If you're not sure what these do, keep all of these enabled.
|
||||
<br>
|
||||
These settings only take effect when CPU Accuracy is "Debug Mode".
|
||||
These settings, when disabled, only take effect when CPU Accuracy is "Debug Mode".
|
||||
</div>
|
||||
</string>
|
||||
</property>
|
||||
|
||||
@@ -28,17 +28,21 @@ ConfigureDebug::ConfigureDebug(QWidget* parent) : QWidget(parent), ui(new Ui::Co
|
||||
ConfigureDebug::~ConfigureDebug() = default;
|
||||
|
||||
void ConfigureDebug::SetConfiguration() {
|
||||
ui->toggle_console->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
|
||||
|
||||
ui->toggle_console->setEnabled(runtime_lock);
|
||||
ui->toggle_console->setChecked(UISettings::values.show_console);
|
||||
ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter));
|
||||
ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args));
|
||||
ui->fs_access_log->setEnabled(runtime_lock);
|
||||
ui->fs_access_log->setChecked(Settings::values.enable_fs_access_log);
|
||||
ui->reporting_services->setChecked(Settings::values.reporting_services);
|
||||
ui->quest_flag->setChecked(Settings::values.quest_flag);
|
||||
ui->use_debug_asserts->setChecked(Settings::values.use_debug_asserts);
|
||||
ui->use_auto_stub->setChecked(Settings::values.use_auto_stub);
|
||||
ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||
ui->enable_graphics_debugging->setEnabled(runtime_lock);
|
||||
ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug);
|
||||
ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn());
|
||||
ui->disable_macro_jit->setEnabled(runtime_lock);
|
||||
ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit);
|
||||
ui->extended_logging->setChecked(Settings::values.extended_logging);
|
||||
}
|
||||
@@ -47,6 +51,7 @@ void ConfigureDebug::ApplyConfiguration() {
|
||||
UISettings::values.show_console = ui->toggle_console->isChecked();
|
||||
Settings::values.log_filter = ui->log_filter_edit->text().toStdString();
|
||||
Settings::values.program_args = ui->homebrew_args_edit->text().toStdString();
|
||||
Settings::values.enable_fs_access_log = ui->fs_access_log->isChecked();
|
||||
Settings::values.reporting_services = ui->reporting_services->isChecked();
|
||||
Settings::values.quest_flag = ui->quest_flag->isChecked();
|
||||
Settings::values.use_debug_asserts = ui->use_debug_asserts->isChecked();
|
||||
|
||||
@@ -144,9 +144,16 @@
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_5">
|
||||
<property name="title">
|
||||
<string>Dump</string>
|
||||
<string>Debugging</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="fs_access_log">
|
||||
<property name="text">
|
||||
<string>Enable FS Access Log</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="reporting_services">
|
||||
<property name="text">
|
||||
|
||||
@@ -70,10 +70,12 @@ void ConfigureGraphics::SetConfiguration() {
|
||||
ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock);
|
||||
ui->use_disk_shader_cache->setEnabled(runtime_lock);
|
||||
ui->use_nvdec_emulation->setEnabled(runtime_lock);
|
||||
ui->accelerate_astc->setEnabled(runtime_lock);
|
||||
ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue());
|
||||
ui->use_asynchronous_gpu_emulation->setChecked(
|
||||
Settings::values.use_asynchronous_gpu_emulation.GetValue());
|
||||
ui->use_nvdec_emulation->setChecked(Settings::values.use_nvdec_emulation.GetValue());
|
||||
ui->accelerate_astc->setChecked(Settings::values.accelerate_astc.GetValue());
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue()));
|
||||
@@ -118,6 +120,8 @@ void ConfigureGraphics::ApplyConfiguration() {
|
||||
use_asynchronous_gpu_emulation);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_nvdec_emulation,
|
||||
ui->use_nvdec_emulation, use_nvdec_emulation);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.accelerate_astc, ui->accelerate_astc,
|
||||
accelerate_astc);
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
// Guard if during game and set to game-specific value
|
||||
@@ -254,6 +258,7 @@ void ConfigureGraphics::SetupPerGameUI() {
|
||||
ui->use_asynchronous_gpu_emulation->setEnabled(
|
||||
Settings::values.use_asynchronous_gpu_emulation.UsingGlobal());
|
||||
ui->use_nvdec_emulation->setEnabled(Settings::values.use_nvdec_emulation.UsingGlobal());
|
||||
ui->accelerate_astc->setEnabled(Settings::values.accelerate_astc.UsingGlobal());
|
||||
ui->use_disk_shader_cache->setEnabled(Settings::values.use_disk_shader_cache.UsingGlobal());
|
||||
ui->bg_button->setEnabled(Settings::values.bg_red.UsingGlobal());
|
||||
|
||||
@@ -269,6 +274,8 @@ void ConfigureGraphics::SetupPerGameUI() {
|
||||
ui->use_disk_shader_cache, Settings::values.use_disk_shader_cache, use_disk_shader_cache);
|
||||
ConfigurationShared::SetColoredTristate(
|
||||
ui->use_nvdec_emulation, Settings::values.use_nvdec_emulation, use_nvdec_emulation);
|
||||
ConfigurationShared::SetColoredTristate(ui->accelerate_astc, Settings::values.accelerate_astc,
|
||||
accelerate_astc);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_asynchronous_gpu_emulation,
|
||||
Settings::values.use_asynchronous_gpu_emulation,
|
||||
use_asynchronous_gpu_emulation);
|
||||
|
||||
@@ -47,6 +47,7 @@ private:
|
||||
QColor bg_color;
|
||||
|
||||
ConfigurationShared::CheckState use_nvdec_emulation;
|
||||
ConfigurationShared::CheckState accelerate_astc;
|
||||
ConfigurationShared::CheckState use_disk_shader_cache;
|
||||
ConfigurationShared::CheckState use_asynchronous_gpu_emulation;
|
||||
|
||||
|
||||
@@ -104,6 +104,13 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="accelerate_astc">
|
||||
<property name="text">
|
||||
<string>Accelerate ASTC texture decoding</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="fullscreen_mode_layout" native="true">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_1">
|
||||
|
||||
@@ -28,6 +28,7 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
|
||||
ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
|
||||
|
||||
ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
|
||||
ui->disable_fps_limit->setChecked(Settings::values.disable_fps_limit.GetValue());
|
||||
ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue());
|
||||
ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
|
||||
ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
|
||||
@@ -57,6 +58,8 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
|
||||
ui->anisotropic_filtering_combobox);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.disable_fps_limit,
|
||||
ui->disable_fps_limit, disable_fps_limit);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders,
|
||||
ui->use_assembly_shaders, use_assembly_shaders);
|
||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
|
||||
@@ -97,6 +100,7 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal());
|
||||
ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal());
|
||||
ui->disable_fps_limit->setEnabled(Settings::values.disable_fps_limit.UsingGlobal());
|
||||
ui->use_assembly_shaders->setEnabled(Settings::values.use_assembly_shaders.UsingGlobal());
|
||||
ui->use_asynchronous_shaders->setEnabled(
|
||||
Settings::values.use_asynchronous_shaders.UsingGlobal());
|
||||
@@ -108,6 +112,8 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
|
||||
}
|
||||
|
||||
ConfigurationShared::SetColoredTristate(ui->use_vsync, Settings::values.use_vsync, use_vsync);
|
||||
ConfigurationShared::SetColoredTristate(ui->disable_fps_limit,
|
||||
Settings::values.disable_fps_limit, disable_fps_limit);
|
||||
ConfigurationShared::SetColoredTristate(
|
||||
ui->use_assembly_shaders, Settings::values.use_assembly_shaders, use_assembly_shaders);
|
||||
ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders,
|
||||
|
||||
@@ -35,6 +35,7 @@ private:
|
||||
std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
|
||||
|
||||
ConfigurationShared::CheckState use_vsync;
|
||||
ConfigurationShared::CheckState disable_fps_limit;
|
||||
ConfigurationShared::CheckState use_assembly_shaders;
|
||||
ConfigurationShared::CheckState use_asynchronous_shaders;
|
||||
ConfigurationShared::CheckState use_fast_gpu_time;
|
||||
|
||||
@@ -76,6 +76,24 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="disable_fps_limit">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>
|
||||
<html><head/><body>
|
||||
<p>Presents guest frames as they become available, disabling the FPS limit in most titles.</p>
|
||||
<p>NOTE: Will cause instabilities.</p>
|
||||
</body></html>
|
||||
</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Disable framerate limit (experimental)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="use_assembly_shaders">
|
||||
<property name="toolTip">
|
||||
|
||||
@@ -47,6 +47,8 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id, const std::str
|
||||
ui->setupUi(this);
|
||||
setFocusPolicy(Qt::ClickFocus);
|
||||
setWindowTitle(tr("Properties"));
|
||||
// remove Help question mark button from the title bar
|
||||
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||
|
||||
ui->addonsTab->SetTitleId(title_id);
|
||||
|
||||
|
||||
@@ -6,10 +6,15 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>800</width>
|
||||
<width>900</width>
|
||||
<height>600</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>900</width>
|
||||
</size>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
|
||||
@@ -79,8 +79,8 @@ void ConfigurePerGameAddons::ApplyConfiguration() {
|
||||
std::sort(disabled_addons.begin(), disabled_addons.end());
|
||||
std::sort(current.begin(), current.end());
|
||||
if (disabled_addons != current) {
|
||||
void(Common::FS::RemoveFile(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
||||
"game_list" / fmt::format("{:016X}.pv.txt", title_id)));
|
||||
Common::FS::RemoveFile(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
||||
"game_list" / fmt::format("{:016X}.pv.txt", title_id));
|
||||
}
|
||||
|
||||
Settings::values.disabled_addons[title_id] = disabled_addons;
|
||||
|
||||
@@ -194,10 +194,10 @@ static void RemoveCachedContents() {
|
||||
const auto offline_legal_information = cache_dir / "offline_web_applet_legal_information";
|
||||
const auto offline_system_data = cache_dir / "offline_web_applet_system_data";
|
||||
|
||||
void(Common::FS::RemoveDirRecursively(offline_fonts));
|
||||
void(Common::FS::RemoveDirRecursively(offline_manual));
|
||||
void(Common::FS::RemoveDirRecursively(offline_legal_information));
|
||||
void(Common::FS::RemoveDirRecursively(offline_system_data));
|
||||
Common::FS::RemoveDirRecursively(offline_fonts);
|
||||
Common::FS::RemoveDirRecursively(offline_manual);
|
||||
Common::FS::RemoveDirRecursively(offline_legal_information);
|
||||
Common::FS::RemoveDirRecursively(offline_system_data);
|
||||
}
|
||||
|
||||
GMainWindow::GMainWindow()
|
||||
@@ -1025,7 +1025,11 @@ void GMainWindow::InitializeHotkeys() {
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Mute Audio"), this),
|
||||
&QShortcut::activated, this,
|
||||
[] { Settings::values.audio_muted = !Settings::values.audio_muted; });
|
||||
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Framerate Limit"), this),
|
||||
&QShortcut::activated, this, [] {
|
||||
Settings::values.disable_fps_limit.SetValue(
|
||||
!Settings::values.disable_fps_limit.GetValue());
|
||||
});
|
||||
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Mouse Panning"), this),
|
||||
&QShortcut::activated, this, [&] {
|
||||
Settings::values.mouse_panning = !Settings::values.mouse_panning;
|
||||
@@ -1739,8 +1743,8 @@ void GMainWindow::OnGameListRemoveInstalledEntry(u64 program_id, InstalledEntryT
|
||||
RemoveAddOnContent(program_id, entry_type);
|
||||
break;
|
||||
}
|
||||
void(Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
||||
"game_list"));
|
||||
Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
||||
"game_list");
|
||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||
}
|
||||
|
||||
@@ -2209,8 +2213,8 @@ void GMainWindow::OnMenuInstallToNAND() {
|
||||
: tr("%n file(s) failed to install\n", "", failed_files.size()));
|
||||
|
||||
QMessageBox::information(this, tr("Install Results"), install_results);
|
||||
void(Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
||||
"game_list"));
|
||||
Common::FS::RemoveDirRecursively(Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) /
|
||||
"game_list");
|
||||
game_list->PopulateAsync(UISettings::values.game_dirs);
|
||||
ui.action_Install_File_NAND->setEnabled(true);
|
||||
}
|
||||
@@ -2842,7 +2846,7 @@ void GMainWindow::MigrateConfigFiles() {
|
||||
LOG_INFO(Frontend, "Migrating config file from {} to {}", origin, destination);
|
||||
if (!Common::FS::RenameFile(origin, destination)) {
|
||||
// Delete the old config file if one already exists in the new location.
|
||||
void(Common::FS::RemoveFile(origin));
|
||||
Common::FS::RemoveFile(origin);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3036,9 +3040,9 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
|
||||
|
||||
const auto keys_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::KeysDir);
|
||||
|
||||
void(Common::FS::RemoveFile(keys_dir / "prod.keys_autogenerated"));
|
||||
void(Common::FS::RemoveFile(keys_dir / "console.keys_autogenerated"));
|
||||
void(Common::FS::RemoveFile(keys_dir / "title.keys_autogenerated"));
|
||||
Common::FS::RemoveFile(keys_dir / "prod.keys_autogenerated");
|
||||
Common::FS::RemoveFile(keys_dir / "console.keys_autogenerated");
|
||||
Common::FS::RemoveFile(keys_dir / "title.keys_autogenerated");
|
||||
}
|
||||
|
||||
Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();
|
||||
|
||||
@@ -443,12 +443,16 @@ void Config::ReadValues() {
|
||||
sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", true));
|
||||
Settings::values.use_vsync.SetValue(
|
||||
static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1)));
|
||||
Settings::values.disable_fps_limit.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "disable_fps_limit", false));
|
||||
Settings::values.use_assembly_shaders.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", true));
|
||||
Settings::values.use_asynchronous_shaders.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_asynchronous_shaders", false));
|
||||
Settings::values.use_asynchronous_shaders.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_asynchronous_shaders", false));
|
||||
Settings::values.use_nvdec_emulation.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_nvdec_emulation", true));
|
||||
Settings::values.accelerate_astc.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "accelerate_astc", true));
|
||||
Settings::values.use_fast_gpu_time.SetValue(
|
||||
sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true));
|
||||
|
||||
@@ -477,6 +481,8 @@ void Config::ReadValues() {
|
||||
Settings::values.program_args = sdl2_config->Get("Debugging", "program_args", "");
|
||||
Settings::values.dump_exefs = sdl2_config->GetBoolean("Debugging", "dump_exefs", false);
|
||||
Settings::values.dump_nso = sdl2_config->GetBoolean("Debugging", "dump_nso", false);
|
||||
Settings::values.enable_fs_access_log =
|
||||
sdl2_config->GetBoolean("Debugging", "enable_fs_access_log", false);
|
||||
Settings::values.reporting_services =
|
||||
sdl2_config->GetBoolean("Debugging", "reporting_services", false);
|
||||
Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false);
|
||||
|
||||
@@ -194,6 +194,14 @@ use_assembly_shaders =
|
||||
# 0 (default): Off, 1: On
|
||||
use_asynchronous_shaders =
|
||||
|
||||
# Enable NVDEC emulation.
|
||||
# 0: Off, 1 (default): On
|
||||
use_nvdec_emulation =
|
||||
|
||||
# Accelerate ASTC texture decoding.
|
||||
# 0: Off, 1 (default): On
|
||||
accelerate_astc =
|
||||
|
||||
# Turns on the frame limiter, which will limit frames output to the target game speed
|
||||
# 0: Off, 1: On (default)
|
||||
use_frame_limit =
|
||||
@@ -252,7 +260,10 @@ swap_screen =
|
||||
|
||||
[Audio]
|
||||
# Which audio output engine to use.
|
||||
# auto (default): Auto-select, null: No audio output, cubeb: Cubeb audio engine (if available)
|
||||
# auto (default): Auto-select
|
||||
# cubeb: Cubeb audio engine (if available)
|
||||
# sdl2: SDL2 audio engine (if available)
|
||||
# null: No audio output
|
||||
output_engine =
|
||||
|
||||
# Whether or not to enable the audio-stretching post-processing effect.
|
||||
@@ -338,6 +349,8 @@ record_frame_times =
|
||||
dump_exefs=false
|
||||
# Determines whether or not yuzu will dump all NSOs it attempts to load while loading them
|
||||
dump_nso=false
|
||||
# Determines whether or not yuzu will save the filesystem access log.
|
||||
enable_fs_access_log=false
|
||||
# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
|
||||
# false: Retail/Normal Mode (default), true: Kiosk Mode
|
||||
quest_flag =
|
||||
@@ -349,6 +362,9 @@ use_debug_asserts =
|
||||
use_auto_stub =
|
||||
# Enables/Disables the macro JIT compiler
|
||||
disable_macro_jit=false
|
||||
# Presents guest frames as they become available. Experimental.
|
||||
# false: Disabled (default), true: Enabled
|
||||
disable_fps_limit=false
|
||||
|
||||
[WebService]
|
||||
# Whether or not to enable telemetry
|
||||
|
||||
Reference in New Issue
Block a user