Compare commits
62 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
922d5187c4 | ||
|
|
5068279f23 | ||
|
|
136e8e829f | ||
|
|
ea4e4b05e4 | ||
|
|
7626ca3343 | ||
|
|
5153d5387a | ||
|
|
b5d21cc1b1 | ||
|
|
41b1f8d616 | ||
|
|
12ef74456c | ||
|
|
5396593b55 | ||
|
|
7d86a6ff02 | ||
|
|
61f293e5c9 | ||
|
|
7f78b17e20 | ||
|
|
93bc59b62d | ||
|
|
339dc4f806 | ||
|
|
b462618ed7 | ||
|
|
e8269fe3bc | ||
|
|
d001687ca6 | ||
|
|
cd6dcef5aa | ||
|
|
0a74d8490a | ||
|
|
af69b48390 | ||
|
|
440eb840ea | ||
|
|
bfe8816f7c | ||
|
|
acf22336ec | ||
|
|
9ec26a805a | ||
|
|
d5131805ce | ||
|
|
ad6e20cfde | ||
|
|
e8d2de1f99 | ||
|
|
a170aa16b6 | ||
|
|
049769a0c9 | ||
|
|
81a5ecdb18 | ||
|
|
9edfd88a8a | ||
|
|
9a07ed53eb | ||
|
|
06c410ee88 | ||
|
|
ab2677f0a1 | ||
|
|
5a2b15bf75 | ||
|
|
a1138028a8 | ||
|
|
faaea00069 | ||
|
|
6c78c2ae38 | ||
|
|
4aac1ae4b1 | ||
|
|
59236b7d0f | ||
|
|
e169fdad4f | ||
|
|
5bef54618a | ||
|
|
a3e68dce56 | ||
|
|
f20f4587e6 | ||
|
|
904584e4ba | ||
|
|
fd7c273fab | ||
|
|
0949e38263 | ||
|
|
0ecb6c6647 | ||
|
|
e12ee020e7 | ||
|
|
c8707628f6 | ||
|
|
271f2e2d78 | ||
|
|
5a042bdaa1 | ||
|
|
02547439b1 | ||
|
|
1b4331397b | ||
|
|
0aff3ba2ff | ||
|
|
fa647cc0b9 | ||
|
|
648bef235e | ||
|
|
3671fd0a97 | ||
|
|
da62e92784 | ||
|
|
8c30ed6d09 | ||
|
|
6a2084a204 |
@@ -30,10 +30,10 @@ make install DESTDIR=AppDir
|
||||
rm -vf AppDir/usr/bin/yuzu-cmd AppDir/usr/bin/yuzu-tester
|
||||
|
||||
# Download tools needed to build an AppImage
|
||||
wget -nc https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
|
||||
wget -nc https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
wget -nc https://github.com/darealshinji/AppImageKit-checkrt/releases/download/continuous/AppRun-patched-x86_64
|
||||
wget -nc https://github.com/darealshinji/AppImageKit-checkrt/releases/download/continuous/exec-x86_64.so
|
||||
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/linuxdeploy-x86_64.AppImage
|
||||
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/linuxdeploy-plugin-qt-x86_64.AppImage
|
||||
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/AppRun-patched-x86_64
|
||||
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/exec-x86_64.so
|
||||
# Set executable bit
|
||||
chmod 755 \
|
||||
AppRun-patched-x86_64 \
|
||||
|
||||
@@ -21,7 +21,7 @@ cp build/bin/yuzu "$DIR_NAME"
|
||||
# Build an AppImage
|
||||
cd build
|
||||
|
||||
wget -nc https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
|
||||
wget -nc https://github.com/yuzu-emu/ext-linux-bin/raw/main/appimage/appimagetool-x86_64.AppImage
|
||||
chmod 755 appimagetool-x86_64.AppImage
|
||||
|
||||
if [ "${RELEASE_NAME}" = "mainline" ]; then
|
||||
|
||||
@@ -12,6 +12,8 @@ project(yuzu)
|
||||
# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
|
||||
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
|
||||
# On Linux system SDL2 is likely to be lacking HIDAPI support which have drawbacks but is needed for SDL motion
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_ALLOW_SYSTEM_SDL2 "Try using system SDL2 before fallling back to one from externals" NOT UNIX "ENABLE_SDL2" OFF)
|
||||
|
||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
|
||||
@@ -172,7 +174,7 @@ macro(yuzu_find_packages)
|
||||
"lz4 1.8 lz4/1.9.2"
|
||||
"nlohmann_json 3.8 nlohmann_json/3.8.0"
|
||||
"ZLIB 1.2 zlib/1.2.11"
|
||||
"zstd 1.4 zstd/1.4.8"
|
||||
"zstd 1.5 zstd/1.5.0"
|
||||
# can't use opus until AVX check is fixed: https://github.com/yuzu-emu/yuzu/pull/4068
|
||||
#"opus 1.3 opus/1.3.1"
|
||||
)
|
||||
@@ -292,20 +294,24 @@ if (ENABLE_SDL2)
|
||||
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARY}")
|
||||
target_include_directories(SDL2 INTERFACE "${SDL2_INCLUDE_DIR}")
|
||||
else()
|
||||
find_package(SDL2 2.0.15 QUIET)
|
||||
if (YUZU_ALLOW_SYSTEM_SDL2)
|
||||
find_package(SDL2 2.0.15 QUIET)
|
||||
|
||||
if (SDL2_FOUND)
|
||||
# Some installations don't set SDL2_LIBRARIES
|
||||
if("${SDL2_LIBRARIES}" STREQUAL "")
|
||||
message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2")
|
||||
set(SDL2_LIBRARIES "SDL2::SDL2")
|
||||
if (SDL2_FOUND)
|
||||
# Some installations don't set SDL2_LIBRARIES
|
||||
if("${SDL2_LIBRARIES}" STREQUAL "")
|
||||
message(WARNING "SDL2_LIBRARIES wasn't set, manually setting to SDL2::SDL2")
|
||||
set(SDL2_LIBRARIES "SDL2::SDL2")
|
||||
endif()
|
||||
|
||||
include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
|
||||
add_library(SDL2 INTERFACE)
|
||||
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}")
|
||||
else()
|
||||
message(STATUS "SDL2 2.0.15 or newer not found, falling back to externals.")
|
||||
endif()
|
||||
|
||||
include_directories(SYSTEM ${SDL2_INCLUDE_DIRS})
|
||||
add_library(SDL2 INTERFACE)
|
||||
target_link_libraries(SDL2 INTERFACE "${SDL2_LIBRARIES}")
|
||||
else()
|
||||
message(STATUS "SDL2 2.0.15 or newer not found, falling back to externals.")
|
||||
message(STATUS "Using SDL2 from externals.")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
12
externals/CMakeLists.txt
vendored
12
externals/CMakeLists.txt
vendored
@@ -47,8 +47,20 @@ target_include_directories(unicorn-headers INTERFACE ./unicorn/include)
|
||||
|
||||
# SDL2
|
||||
if (NOT SDL2_FOUND AND ENABLE_SDL2)
|
||||
# Yuzu itself needs: Events Joystick Haptic Sensor Timers
|
||||
# Yuzu-cmd also needs: Video (depends on Loadso/Dlopen)
|
||||
set(SDL_UNUSED_SUBSYSTEMS
|
||||
Atomic Audio Render Power Threads
|
||||
File CPUinfo Filesystem Locale)
|
||||
foreach(_SUB ${SDL_UNUSED_SUBSYSTEMS})
|
||||
string(TOUPPER ${_SUB} _OPT)
|
||||
option(SDL_${_OPT} "" OFF)
|
||||
endforeach()
|
||||
|
||||
set(SDL_STATIC ON)
|
||||
set(SDL_SHARED OFF)
|
||||
option(HIDAPI "" ON)
|
||||
|
||||
add_subdirectory(SDL EXCLUDE_FROM_ALL)
|
||||
add_library(SDL2 ALIAS SDL2-static)
|
||||
endif()
|
||||
|
||||
2
externals/ffmpeg
vendored
2
externals/ffmpeg
vendored
Submodule externals/ffmpeg updated: 6b6b9e593d...79e8d17024
2
externals/mbedtls
vendored
2
externals/mbedtls
vendored
Submodule externals/mbedtls updated: eac2416b8f...8c88150ca1
@@ -54,6 +54,7 @@ if (MSVC)
|
||||
/we4547 # 'operator' : operator before comma has no effect; expected operator with side-effect
|
||||
/we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'?
|
||||
/we4555 # Expression has no effect; expected expression with side-effect
|
||||
/we4715 # 'function': not all control paths return a value
|
||||
/we4834 # Discarding return value of function with 'nodiscard' attribute
|
||||
/we5038 # data member 'member1' will be initialized after data member 'member2'
|
||||
)
|
||||
|
||||
@@ -109,7 +109,8 @@ struct OffsetOfCalculator {
|
||||
}
|
||||
}
|
||||
|
||||
return (next - start) * sizeof(MemberType) + Offset;
|
||||
return static_cast<ptrdiff_t>(static_cast<size_t>(next - start) * sizeof(MemberType) +
|
||||
Offset);
|
||||
}
|
||||
|
||||
static constexpr std::ptrdiff_t OffsetOf(MemberType ParentType::*member) {
|
||||
|
||||
@@ -42,7 +42,7 @@ void LogSettings() {
|
||||
log_setting("System_RegionIndex", values.region_index.GetValue());
|
||||
log_setting("System_TimeZoneIndex", values.time_zone_index.GetValue());
|
||||
log_setting("Core_UseMultiCore", values.use_multi_core.GetValue());
|
||||
log_setting("CPU_Accuracy", values.cpu_accuracy);
|
||||
log_setting("CPU_Accuracy", values.cpu_accuracy.GetValue());
|
||||
log_setting("Renderer_UseResolutionFactor", values.resolution_factor.GetValue());
|
||||
log_setting("Renderer_UseFrameLimit", values.use_frame_limit.GetValue());
|
||||
log_setting("Renderer_FrameLimit", values.frame_limit.GetValue());
|
||||
@@ -106,6 +106,12 @@ void RestoreGlobalState(bool is_powered_on) {
|
||||
// Core
|
||||
values.use_multi_core.SetGlobal(true);
|
||||
|
||||
// CPU
|
||||
values.cpu_accuracy.SetGlobal(true);
|
||||
values.cpuopt_unsafe_unfuse_fma.SetGlobal(true);
|
||||
values.cpuopt_unsafe_reduce_fp_error.SetGlobal(true);
|
||||
values.cpuopt_unsafe_inaccurate_nan.SetGlobal(true);
|
||||
|
||||
// Renderer
|
||||
values.renderer_backend.SetGlobal(true);
|
||||
values.vulkan_device.SetGlobal(true);
|
||||
@@ -130,7 +136,6 @@ void RestoreGlobalState(bool is_powered_on) {
|
||||
values.region_index.SetGlobal(true);
|
||||
values.time_zone_index.SetGlobal(true);
|
||||
values.rng_seed.SetGlobal(true);
|
||||
values.custom_rtc.SetGlobal(true);
|
||||
values.sound_index.SetGlobal(true);
|
||||
|
||||
// Controls
|
||||
|
||||
@@ -115,7 +115,7 @@ struct Values {
|
||||
Setting<bool> use_multi_core;
|
||||
|
||||
// Cpu
|
||||
CPUAccuracy cpu_accuracy;
|
||||
Setting<CPUAccuracy> cpu_accuracy;
|
||||
|
||||
bool cpuopt_page_tables;
|
||||
bool cpuopt_block_linking;
|
||||
@@ -126,9 +126,9 @@ struct Values {
|
||||
bool cpuopt_misc_ir;
|
||||
bool cpuopt_reduce_misalign_checks;
|
||||
|
||||
bool cpuopt_unsafe_unfuse_fma;
|
||||
bool cpuopt_unsafe_reduce_fp_error;
|
||||
bool cpuopt_unsafe_inaccurate_nan;
|
||||
Setting<bool> cpuopt_unsafe_unfuse_fma;
|
||||
Setting<bool> cpuopt_unsafe_reduce_fp_error;
|
||||
Setting<bool> cpuopt_unsafe_inaccurate_nan;
|
||||
|
||||
// Renderer
|
||||
Setting<RendererBackend> renderer_backend;
|
||||
@@ -157,7 +157,7 @@ struct Values {
|
||||
// System
|
||||
Setting<std::optional<u32>> rng_seed;
|
||||
// Measured in seconds since epoch
|
||||
Setting<std::optional<std::chrono::seconds>> custom_rtc;
|
||||
std::optional<std::chrono::seconds> custom_rtc;
|
||||
// Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
|
||||
std::chrono::seconds custom_rtc_differential;
|
||||
|
||||
|
||||
@@ -651,20 +651,17 @@ endif()
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(core PRIVATE
|
||||
# 'expression' : signed/unsigned mismatch
|
||||
/we4018
|
||||
# 'argument' : conversion from 'type1' to 'type2', possible loss of data (floating-point)
|
||||
/we4244
|
||||
# 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch
|
||||
/we4245
|
||||
# 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
|
||||
/we4254
|
||||
# 'var' : conversion from 'size_t' to 'type', possible loss of data
|
||||
/we4267
|
||||
# 'context' : truncation from 'type1' to 'type2'
|
||||
/we4305
|
||||
# 'function' : not all control paths return a value
|
||||
/we4715
|
||||
/we4018 # 'expression' : signed/unsigned mismatch
|
||||
/we4244 # 'argument' : conversion from 'type1' to 'type2', possible loss of data (floating-point)
|
||||
/we4245 # 'conversion' : conversion from 'type1' to 'type2', signed/unsigned mismatch
|
||||
/we4254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data
|
||||
/we4267 # 'var' : conversion from 'size_t' to 'type', possible loss of data
|
||||
/we4305 # 'context' : truncation from 'type1' to 'type2'
|
||||
/we4456 # Declaration of 'identifier' hides previous local declaration
|
||||
/we4457 # Declaration of 'identifier' hides function parameter
|
||||
/we4458 # Declaration of 'identifier' hides class member
|
||||
/we4459 # Declaration of 'identifier' hides global declaration
|
||||
/we4715 # 'function' : not all control paths return a value
|
||||
)
|
||||
else()
|
||||
target_compile_options(core PRIVATE
|
||||
@@ -672,6 +669,7 @@ else()
|
||||
-Werror=ignored-qualifiers
|
||||
-Werror=implicit-fallthrough
|
||||
-Werror=sign-compare
|
||||
-Werror=shadow
|
||||
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Werror=class-memaccess>
|
||||
$<$<CXX_COMPILER_ID:GNU>:-Werror=unused-but-set-parameter>
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace Core {
|
||||
|
||||
class DynarmicCallbacks32 : public Dynarmic::A32::UserCallbacks {
|
||||
public:
|
||||
explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent) : parent(parent) {}
|
||||
explicit DynarmicCallbacks32(ARM_Dynarmic_32& parent_) : parent{parent_} {}
|
||||
|
||||
u8 MemoryRead8(u32 vaddr) override {
|
||||
return parent.system.Memory().Read8(vaddr);
|
||||
@@ -142,7 +142,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
|
||||
config.far_code_offset = 256 * 1024 * 1024;
|
||||
|
||||
// Safe optimizations
|
||||
if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::DebugMode) {
|
||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
|
||||
if (!Settings::values.cpuopt_page_tables) {
|
||||
config.page_table = nullptr;
|
||||
}
|
||||
@@ -170,15 +170,15 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
|
||||
}
|
||||
|
||||
// Unsafe optimizations
|
||||
if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::Unsafe) {
|
||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
|
||||
config.unsafe_optimizations = true;
|
||||
if (Settings::values.cpuopt_unsafe_unfuse_fma) {
|
||||
if (Settings::values.cpuopt_unsafe_unfuse_fma.GetValue()) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||
}
|
||||
if (Settings::values.cpuopt_unsafe_reduce_fp_error) {
|
||||
if (Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue()) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
|
||||
}
|
||||
if (Settings::values.cpuopt_unsafe_inaccurate_nan) {
|
||||
if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ using Vector = Dynarmic::A64::Vector;
|
||||
|
||||
class DynarmicCallbacks64 : public Dynarmic::A64::UserCallbacks {
|
||||
public:
|
||||
explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent) : parent(parent) {}
|
||||
explicit DynarmicCallbacks64(ARM_Dynarmic_64& parent_) : parent{parent_} {}
|
||||
|
||||
u8 MemoryRead8(u64 vaddr) override {
|
||||
return parent.system.Memory().Read8(vaddr);
|
||||
@@ -182,7 +182,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
|
||||
config.far_code_offset = 256 * 1024 * 1024;
|
||||
|
||||
// Safe optimizations
|
||||
if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::DebugMode) {
|
||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::DebugMode) {
|
||||
if (!Settings::values.cpuopt_page_tables) {
|
||||
config.page_table = nullptr;
|
||||
}
|
||||
@@ -210,15 +210,15 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
|
||||
}
|
||||
|
||||
// Unsafe optimizations
|
||||
if (Settings::values.cpu_accuracy == Settings::CPUAccuracy::Unsafe) {
|
||||
if (Settings::values.cpu_accuracy.GetValue() == Settings::CPUAccuracy::Unsafe) {
|
||||
config.unsafe_optimizations = true;
|
||||
if (Settings::values.cpuopt_unsafe_unfuse_fma) {
|
||||
if (Settings::values.cpuopt_unsafe_unfuse_fma.GetValue()) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_UnfuseFMA;
|
||||
}
|
||||
if (Settings::values.cpuopt_unsafe_reduce_fp_error) {
|
||||
if (Settings::values.cpuopt_unsafe_reduce_fp_error.GetValue()) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_ReducedErrorFP;
|
||||
}
|
||||
if (Settings::values.cpuopt_unsafe_inaccurate_nan) {
|
||||
if (Settings::values.cpuopt_unsafe_inaccurate_nan.GetValue()) {
|
||||
config.optimizations |= Dynarmic::OptimizationFlag::Unsafe_InaccurateNaN;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ class DynarmicCP15 final : public Dynarmic::A32::Coprocessor {
|
||||
public:
|
||||
using CoprocReg = Dynarmic::A32::CoprocReg;
|
||||
|
||||
explicit DynarmicCP15(ARM_Dynarmic_32& parent) : parent(parent) {}
|
||||
explicit DynarmicCP15(ARM_Dynarmic_32& parent_) : parent{parent_} {}
|
||||
|
||||
std::optional<Callback> CompileInternalOperation(bool two, unsigned opc1, CoprocReg CRd,
|
||||
CoprocReg CRn, CoprocReg CRm,
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
namespace Core {
|
||||
|
||||
DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(Memory::Memory& memory, std::size_t core_count)
|
||||
: monitor(core_count), memory{memory} {}
|
||||
DynarmicExclusiveMonitor::DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count_)
|
||||
: monitor{core_count_}, memory{memory_} {}
|
||||
|
||||
DynarmicExclusiveMonitor::~DynarmicExclusiveMonitor() = default;
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace Core {
|
||||
|
||||
class DynarmicExclusiveMonitor final : public ExclusiveMonitor {
|
||||
public:
|
||||
explicit DynarmicExclusiveMonitor(Memory::Memory& memory, std::size_t core_count);
|
||||
explicit DynarmicExclusiveMonitor(Memory::Memory& memory_, std::size_t core_count_);
|
||||
~DynarmicExclusiveMonitor() override;
|
||||
|
||||
u8 ExclusiveRead8(std::size_t core_index, VAddr addr) override;
|
||||
|
||||
@@ -173,7 +173,7 @@ struct System::Impl {
|
||||
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch());
|
||||
Settings::values.custom_rtc_differential =
|
||||
Settings::values.custom_rtc.GetValue().value_or(current_time) - current_time;
|
||||
Settings::values.custom_rtc.value_or(current_time) - current_time;
|
||||
|
||||
// Create a default fs if one doesn't already exist.
|
||||
if (virtual_filesystem == nullptr)
|
||||
@@ -289,7 +289,8 @@ struct System::Impl {
|
||||
|
||||
telemetry_session->AddField(performance, "Shutdown_EmulationSpeed",
|
||||
perf_results.emulation_speed * 100.0);
|
||||
telemetry_session->AddField(performance, "Shutdown_Framerate", perf_results.game_fps);
|
||||
telemetry_session->AddField(performance, "Shutdown_Framerate",
|
||||
perf_results.average_game_fps);
|
||||
telemetry_session->AddField(performance, "Shutdown_Frametime",
|
||||
perf_results.frametime * 1000.0);
|
||||
telemetry_session->AddField(performance, "Mean_Frametime_MS",
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
namespace Core {
|
||||
|
||||
CpuManager::CpuManager(System& system) : system{system} {}
|
||||
CpuManager::CpuManager(System& system_) : system{system_} {}
|
||||
CpuManager::~CpuManager() = default;
|
||||
|
||||
void CpuManager::ThreadStart(CpuManager& cpu_manager, std::size_t core) {
|
||||
|
||||
@@ -25,7 +25,7 @@ class System;
|
||||
|
||||
class CpuManager {
|
||||
public:
|
||||
explicit CpuManager(System& system);
|
||||
explicit CpuManager(System& system_);
|
||||
CpuManager(const CpuManager&) = delete;
|
||||
CpuManager(CpuManager&&) = delete;
|
||||
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
namespace Core::Crypto {
|
||||
|
||||
CTREncryptionLayer::CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_,
|
||||
std::size_t base_offset)
|
||||
: EncryptionLayer(std::move(base_)), base_offset(base_offset), cipher(key_, Mode::CTR) {}
|
||||
std::size_t base_offset_)
|
||||
: EncryptionLayer(std::move(base_)), base_offset(base_offset_), cipher(key_, Mode::CTR) {}
|
||||
|
||||
std::size_t CTREncryptionLayer::Read(u8* data, std::size_t length, std::size_t offset) const {
|
||||
if (length == 0)
|
||||
|
||||
@@ -17,7 +17,7 @@ class CTREncryptionLayer : public EncryptionLayer {
|
||||
public:
|
||||
using IVData = std::array<u8, 16>;
|
||||
|
||||
CTREncryptionLayer(FileSys::VirtualFile base, Key128 key, std::size_t base_offset);
|
||||
CTREncryptionLayer(FileSys::VirtualFile base_, Key128 key_, std::size_t base_offset_);
|
||||
|
||||
std::size_t Read(u8* data, std::size_t length, std::size_t offset) const override;
|
||||
|
||||
|
||||
@@ -458,7 +458,7 @@ static std::array<u8, size> operator^(const std::array<u8, size>& lhs,
|
||||
const std::array<u8, size>& rhs) {
|
||||
std::array<u8, size> out;
|
||||
std::transform(lhs.begin(), lhs.end(), rhs.begin(), out.begin(),
|
||||
[](u8 lhs, u8 rhs) { return u8(lhs ^ rhs); });
|
||||
[](u8 lhs_elem, u8 rhs_elem) { return u8(lhs_elem ^ rhs_elem); });
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
@@ -39,10 +39,10 @@ CNMT::CNMT(VirtualFile file) {
|
||||
}
|
||||
}
|
||||
|
||||
CNMT::CNMT(CNMTHeader header, OptionalHeader opt_header, std::vector<ContentRecord> content_records,
|
||||
std::vector<MetaRecord> meta_records)
|
||||
: header(std::move(header)), opt_header(std::move(opt_header)),
|
||||
content_records(std::move(content_records)), meta_records(std::move(meta_records)) {}
|
||||
CNMT::CNMT(CNMTHeader header_, OptionalHeader opt_header_,
|
||||
std::vector<ContentRecord> content_records_, std::vector<MetaRecord> meta_records_)
|
||||
: header(std::move(header_)), opt_header(std::move(opt_header_)),
|
||||
content_records(std::move(content_records_)), meta_records(std::move(meta_records_)) {}
|
||||
|
||||
CNMT::~CNMT() = default;
|
||||
|
||||
|
||||
@@ -87,8 +87,8 @@ static_assert(sizeof(CNMTHeader) == 0x20, "CNMTHeader has incorrect size.");
|
||||
class CNMT {
|
||||
public:
|
||||
explicit CNMT(VirtualFile file);
|
||||
CNMT(CNMTHeader header, OptionalHeader opt_header, std::vector<ContentRecord> content_records,
|
||||
std::vector<MetaRecord> meta_records);
|
||||
CNMT(CNMTHeader header_, OptionalHeader opt_header_,
|
||||
std::vector<ContentRecord> content_records_, std::vector<MetaRecord> meta_records_);
|
||||
~CNMT();
|
||||
|
||||
u64 GetTitleID() const;
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "common/logging/log.h"
|
||||
#include "core/crypto/key_manager.h"
|
||||
#include "core/file_sys/card_image.h"
|
||||
#include "core/file_sys/common_funcs.h"
|
||||
#include "core/file_sys/content_archive.h"
|
||||
#include "core/file_sys/nca_metadata.h"
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
@@ -592,6 +593,12 @@ InstallResult RegisteredCache::InstallEntry(const NSP& nsp, bool overwrite_if_ex
|
||||
const CNMT cnmt(cnmt_file);
|
||||
|
||||
const auto title_id = cnmt.GetTitleID();
|
||||
const auto version = cnmt.GetTitleVersion();
|
||||
|
||||
if (title_id == GetBaseTitleID(title_id) && version == 0) {
|
||||
return InstallResult::ErrorBaseInstall;
|
||||
}
|
||||
|
||||
const auto result = RemoveExistingEntry(title_id);
|
||||
|
||||
// Install Metadata File
|
||||
|
||||
@@ -38,6 +38,7 @@ enum class InstallResult {
|
||||
ErrorAlreadyExists,
|
||||
ErrorCopyFailed,
|
||||
ErrorMetaFailed,
|
||||
ErrorBaseInstall,
|
||||
};
|
||||
|
||||
struct ContentProviderEntry {
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
NSP::NSP(VirtualFile file_, std::size_t program_index)
|
||||
: file(std::move(file_)), program_index(program_index), status{Loader::ResultStatus::Success},
|
||||
NSP::NSP(VirtualFile file_, std::size_t program_index_)
|
||||
: file(std::move(file_)), program_index(program_index_), status{Loader::ResultStatus::Success},
|
||||
pfs(std::make_shared<PartitionFilesystem>(file)), keys{Core::Crypto::KeyManager::Instance()} {
|
||||
if (pfs->GetStatus() != Loader::ResultStatus::Success) {
|
||||
status = pfs->GetStatus();
|
||||
|
||||
@@ -27,7 +27,7 @@ enum class ContentRecordType : u8;
|
||||
|
||||
class NSP : public ReadOnlyVfsDirectory {
|
||||
public:
|
||||
explicit NSP(VirtualFile file, std::size_t program_index = 0);
|
||||
explicit NSP(VirtualFile file_, std::size_t program_index_ = 0);
|
||||
~NSP() override;
|
||||
|
||||
Loader::ResultStatus GetStatus() const;
|
||||
|
||||
@@ -23,8 +23,8 @@ static bool VerifyConcatenationMapContinuity(const std::multimap<u64, VirtualFil
|
||||
return map.begin()->first == 0;
|
||||
}
|
||||
|
||||
ConcatenatedVfsFile::ConcatenatedVfsFile(std::vector<VirtualFile> files_, std::string name)
|
||||
: name(std::move(name)) {
|
||||
ConcatenatedVfsFile::ConcatenatedVfsFile(std::vector<VirtualFile> files_, std::string name_)
|
||||
: name(std::move(name_)) {
|
||||
std::size_t next_offset = 0;
|
||||
for (const auto& file : files_) {
|
||||
files.emplace(next_offset, file);
|
||||
@@ -32,8 +32,8 @@ ConcatenatedVfsFile::ConcatenatedVfsFile(std::vector<VirtualFile> files_, std::s
|
||||
}
|
||||
}
|
||||
|
||||
ConcatenatedVfsFile::ConcatenatedVfsFile(std::multimap<u64, VirtualFile> files_, std::string name)
|
||||
: files(std::move(files_)), name(std::move(name)) {
|
||||
ConcatenatedVfsFile::ConcatenatedVfsFile(std::multimap<u64, VirtualFile> files_, std::string name_)
|
||||
: files(std::move(files_)), name(std::move(name_)) {
|
||||
ASSERT(VerifyConcatenationMapContinuity(files));
|
||||
}
|
||||
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace FileSys {
|
||||
// Class that wraps multiple vfs files and concatenates them, making reads seamless. Currently
|
||||
// read-only.
|
||||
class ConcatenatedVfsFile : public VfsFile {
|
||||
ConcatenatedVfsFile(std::vector<VirtualFile> files, std::string name);
|
||||
ConcatenatedVfsFile(std::multimap<u64, VirtualFile> files, std::string name);
|
||||
explicit ConcatenatedVfsFile(std::vector<VirtualFile> files, std::string name_);
|
||||
explicit ConcatenatedVfsFile(std::multimap<u64, VirtualFile> files, std::string name_);
|
||||
|
||||
public:
|
||||
~ConcatenatedVfsFile() override;
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
namespace FileSys {
|
||||
|
||||
LayeredVfsDirectory::LayeredVfsDirectory(std::vector<VirtualDir> dirs, std::string name)
|
||||
: dirs(std::move(dirs)), name(std::move(name)) {}
|
||||
LayeredVfsDirectory::LayeredVfsDirectory(std::vector<VirtualDir> dirs_, std::string name_)
|
||||
: dirs(std::move(dirs_)), name(std::move(name_)) {}
|
||||
|
||||
LayeredVfsDirectory::~LayeredVfsDirectory() = default;
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ namespace FileSys {
|
||||
// one and falling back to the one after. The highest priority directory (overwrites all others)
|
||||
// should be element 0 in the dirs vector.
|
||||
class LayeredVfsDirectory : public VfsDirectory {
|
||||
LayeredVfsDirectory(std::vector<VirtualDir> dirs, std::string name);
|
||||
explicit LayeredVfsDirectory(std::vector<VirtualDir> dirs_, std::string name_);
|
||||
|
||||
public:
|
||||
~LayeredVfsDirectory() override;
|
||||
|
||||
@@ -3,7 +3,16 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <string>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
#include <zip.h>
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "common/logging/backend.h"
|
||||
#include "core/file_sys/vfs.h"
|
||||
#include "core/file_sys/vfs_libzip.h"
|
||||
|
||||
@@ -14,9 +14,9 @@ namespace FileSys {
|
||||
|
||||
class StaticVfsFile : public VfsFile {
|
||||
public:
|
||||
explicit StaticVfsFile(u8 value, std::size_t size = 0, std::string name = "",
|
||||
VirtualDir parent = nullptr)
|
||||
: value{value}, size{size}, name{std::move(name)}, parent{std::move(parent)} {}
|
||||
explicit StaticVfsFile(u8 value_, std::size_t size_ = 0, std::string name_ = "",
|
||||
VirtualDir parent_ = nullptr)
|
||||
: value{value_}, size{size_}, name{std::move(name_)}, parent{std::move(parent_)} {}
|
||||
|
||||
std::string GetName() const override {
|
||||
return name;
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
#include "core/file_sys/vfs_vector.h"
|
||||
|
||||
namespace FileSys {
|
||||
VectorVfsFile::VectorVfsFile(std::vector<u8> initial_data, std::string name, VirtualDir parent)
|
||||
: data(std::move(initial_data)), parent(std::move(parent)), name(std::move(name)) {}
|
||||
VectorVfsFile::VectorVfsFile(std::vector<u8> initial_data, std::string name_, VirtualDir parent_)
|
||||
: data(std::move(initial_data)), parent(std::move(parent_)), name(std::move(name_)) {}
|
||||
|
||||
VectorVfsFile::~VectorVfsFile() = default;
|
||||
|
||||
|
||||
@@ -75,8 +75,8 @@ std::shared_ptr<ArrayVfsFile<Size>> MakeArrayFile(const std::array<u8, Size>& da
|
||||
// An implementation of VfsFile that is backed by a vector optionally supplied upon construction
|
||||
class VectorVfsFile : public VfsFile {
|
||||
public:
|
||||
explicit VectorVfsFile(std::vector<u8> initial_data = {}, std::string name = "",
|
||||
VirtualDir parent = nullptr);
|
||||
explicit VectorVfsFile(std::vector<u8> initial_data = {}, std::string name_ = "",
|
||||
VirtualDir parent_ = nullptr);
|
||||
~VectorVfsFile() override;
|
||||
|
||||
std::string GetName() const override;
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
private:
|
||||
class Device : public Input::TouchDevice {
|
||||
public:
|
||||
explicit Device(std::weak_ptr<TouchState>&& touch_state) : touch_state(touch_state) {}
|
||||
explicit Device(std::weak_ptr<TouchState>&& touch_state_) : touch_state(touch_state_) {}
|
||||
Input::TouchStatus GetStatus() const override {
|
||||
if (auto state = touch_state.lock()) {
|
||||
std::lock_guard guard{state->mutex};
|
||||
|
||||
@@ -33,8 +33,8 @@ protected:
|
||||
public:
|
||||
explicit RequestHelperBase(u32* command_buffer) : cmdbuf(command_buffer) {}
|
||||
|
||||
explicit RequestHelperBase(Kernel::HLERequestContext& context)
|
||||
: context(&context), cmdbuf(context.CommandBuffer()) {}
|
||||
explicit RequestHelperBase(Kernel::HLERequestContext& ctx)
|
||||
: context(&ctx), cmdbuf(ctx.CommandBuffer()) {}
|
||||
|
||||
void Skip(u32 size_in_words, bool set_to_null) {
|
||||
if (set_to_null) {
|
||||
@@ -71,12 +71,12 @@ public:
|
||||
AlwaysMoveHandles = 1,
|
||||
};
|
||||
|
||||
explicit ResponseBuilder(Kernel::HLERequestContext& ctx, u32 normal_params_size,
|
||||
u32 num_handles_to_copy = 0, u32 num_objects_to_move = 0,
|
||||
explicit ResponseBuilder(Kernel::HLERequestContext& ctx, u32 normal_params_size_,
|
||||
u32 num_handles_to_copy_ = 0, u32 num_objects_to_move_ = 0,
|
||||
Flags flags = Flags::None)
|
||||
: RequestHelperBase(ctx), normal_params_size(normal_params_size),
|
||||
num_handles_to_copy(num_handles_to_copy),
|
||||
num_objects_to_move(num_objects_to_move), kernel{ctx.kernel} {
|
||||
: RequestHelperBase(ctx), normal_params_size(normal_params_size_),
|
||||
num_handles_to_copy(num_handles_to_copy_),
|
||||
num_objects_to_move(num_objects_to_move_), kernel{ctx.kernel} {
|
||||
|
||||
memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH);
|
||||
|
||||
@@ -110,14 +110,14 @@ public:
|
||||
|
||||
ctx.data_size = static_cast<u32>(raw_data_size);
|
||||
header.data_size.Assign(static_cast<u32>(raw_data_size));
|
||||
if (num_handles_to_copy || num_handles_to_move) {
|
||||
if (num_handles_to_copy != 0 || num_handles_to_move != 0) {
|
||||
header.enable_handle_descriptor.Assign(1);
|
||||
}
|
||||
PushRaw(header);
|
||||
|
||||
if (header.enable_handle_descriptor) {
|
||||
IPC::HandleDescriptorHeader handle_descriptor_header{};
|
||||
handle_descriptor_header.num_handles_to_copy.Assign(num_handles_to_copy);
|
||||
handle_descriptor_header.num_handles_to_copy.Assign(num_handles_to_copy_);
|
||||
handle_descriptor_header.num_handles_to_move.Assign(num_handles_to_move);
|
||||
PushRaw(handle_descriptor_header);
|
||||
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
GlobalSchedulerContext::GlobalSchedulerContext(KernelCore& kernel)
|
||||
: kernel{kernel}, scheduler_lock{kernel} {}
|
||||
GlobalSchedulerContext::GlobalSchedulerContext(KernelCore& kernel_)
|
||||
: kernel{kernel_}, scheduler_lock{kernel_} {}
|
||||
|
||||
GlobalSchedulerContext::~GlobalSchedulerContext() = default;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ class GlobalSchedulerContext final {
|
||||
public:
|
||||
using LockType = KAbstractSchedulerLock<KScheduler>;
|
||||
|
||||
explicit GlobalSchedulerContext(KernelCore& kernel);
|
||||
explicit GlobalSchedulerContext(KernelCore& kernel_);
|
||||
~GlobalSchedulerContext();
|
||||
|
||||
/// Adds a new thread to the scheduler
|
||||
|
||||
@@ -64,7 +64,7 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32
|
||||
if (command_header->enable_handle_descriptor) {
|
||||
handle_descriptor_header = rp.PopRaw<IPC::HandleDescriptorHeader>();
|
||||
if (handle_descriptor_header->send_current_pid) {
|
||||
rp.Skip(2, false);
|
||||
pid = rp.Pop<u64>();
|
||||
}
|
||||
if (incoming) {
|
||||
// Populate the object lists with the data in the IPC request.
|
||||
@@ -86,16 +86,16 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < command_header->num_buf_x_descriptors; ++i) {
|
||||
for (u32 i = 0; i < command_header->num_buf_x_descriptors; ++i) {
|
||||
buffer_x_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorX>());
|
||||
}
|
||||
for (unsigned i = 0; i < command_header->num_buf_a_descriptors; ++i) {
|
||||
for (u32 i = 0; i < command_header->num_buf_a_descriptors; ++i) {
|
||||
buffer_a_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorABW>());
|
||||
}
|
||||
for (unsigned i = 0; i < command_header->num_buf_b_descriptors; ++i) {
|
||||
for (u32 i = 0; i < command_header->num_buf_b_descriptors; ++i) {
|
||||
buffer_b_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorABW>());
|
||||
}
|
||||
for (unsigned i = 0; i < command_header->num_buf_w_descriptors; ++i) {
|
||||
for (u32 i = 0; i < command_header->num_buf_w_descriptors; ++i) {
|
||||
buffer_w_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorABW>());
|
||||
}
|
||||
|
||||
@@ -148,14 +148,14 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32
|
||||
IPC::CommandHeader::BufferDescriptorCFlag::OneDescriptor) {
|
||||
buffer_c_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorC>());
|
||||
} else {
|
||||
unsigned num_buf_c_descriptors =
|
||||
static_cast<unsigned>(command_header->buf_c_descriptor_flags.Value()) - 2;
|
||||
u32 num_buf_c_descriptors =
|
||||
static_cast<u32>(command_header->buf_c_descriptor_flags.Value()) - 2;
|
||||
|
||||
// This is used to detect possible underflows, in case something is broken
|
||||
// with the two ifs above and the flags value is == 0 || == 1.
|
||||
ASSERT(num_buf_c_descriptors < 14);
|
||||
|
||||
for (unsigned i = 0; i < num_buf_c_descriptors; ++i) {
|
||||
for (u32 i = 0; i < num_buf_c_descriptors; ++i) {
|
||||
buffer_c_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorC>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,6 +150,10 @@ public:
|
||||
return command_header->type;
|
||||
}
|
||||
|
||||
u64 GetPID() const {
|
||||
return pid;
|
||||
}
|
||||
|
||||
u32 GetDataPayloadOffset() const {
|
||||
return data_payload_offset;
|
||||
}
|
||||
@@ -305,11 +309,12 @@ private:
|
||||
std::vector<IPC::BufferDescriptorABW> buffer_w_desciptors;
|
||||
std::vector<IPC::BufferDescriptorC> buffer_c_desciptors;
|
||||
|
||||
u32_le command{};
|
||||
u64 pid{};
|
||||
u32 data_payload_offset{};
|
||||
u32 handles_offset{};
|
||||
u32 domain_offset{};
|
||||
u32 data_size{};
|
||||
u32_le command{};
|
||||
|
||||
std::vector<std::shared_ptr<SessionRequestHandler>> domain_request_handlers;
|
||||
bool is_thread_waiting{};
|
||||
|
||||
@@ -18,7 +18,8 @@ class KernelCore;
|
||||
|
||||
class KLightConditionVariable {
|
||||
public:
|
||||
explicit KLightConditionVariable(KernelCore& kernel) : thread_queue(kernel), kernel(kernel) {}
|
||||
explicit KLightConditionVariable(KernelCore& kernel_)
|
||||
: thread_queue(kernel_), kernel(kernel_) {}
|
||||
|
||||
void Wait(KLightLock* lock, s64 timeout = -1) {
|
||||
WaitImpl(lock, timeout);
|
||||
|
||||
@@ -201,10 +201,10 @@ public:
|
||||
}
|
||||
|
||||
iterator insert(const_iterator pos, reference ref) {
|
||||
KLinkedListNode* node = KLinkedListNode::Allocate(kernel);
|
||||
ASSERT(node != nullptr);
|
||||
node->Initialize(std::addressof(ref));
|
||||
return iterator(BaseList::insert(pos.m_base_it, *node));
|
||||
KLinkedListNode* new_node = KLinkedListNode::Allocate(kernel);
|
||||
ASSERT(new_node != nullptr);
|
||||
new_node->Initialize(std::addressof(ref));
|
||||
return iterator(BaseList::insert(pos.m_base_it, *new_node));
|
||||
}
|
||||
|
||||
void push_back(reference ref) {
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
KMemoryBlockManager::KMemoryBlockManager(VAddr start_addr, VAddr end_addr)
|
||||
: start_addr{start_addr}, end_addr{end_addr} {
|
||||
KMemoryBlockManager::KMemoryBlockManager(VAddr start_addr_, VAddr end_addr_)
|
||||
: start_addr{start_addr_}, end_addr{end_addr_} {
|
||||
const u64 num_pages{(end_addr - start_addr) / PageSize};
|
||||
memory_block_tree.emplace_back(start_addr, num_pages, KMemoryState::Free,
|
||||
KMemoryPermission::None, KMemoryAttribute::None);
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
using const_iterator = MemoryBlockTree::const_iterator;
|
||||
|
||||
public:
|
||||
KMemoryBlockManager(VAddr start_addr, VAddr end_addr);
|
||||
KMemoryBlockManager(VAddr start_addr_, VAddr end_addr_);
|
||||
|
||||
iterator end() {
|
||||
return memory_block_tree.end();
|
||||
|
||||
@@ -17,7 +17,7 @@ class KPageLinkedList final {
|
||||
public:
|
||||
class Node final {
|
||||
public:
|
||||
constexpr Node(u64 addr, std::size_t num_pages) : addr{addr}, num_pages{num_pages} {}
|
||||
constexpr Node(u64 addr_, std::size_t num_pages_) : addr{addr_}, num_pages{num_pages_} {}
|
||||
|
||||
constexpr u64 GetAddress() const {
|
||||
return addr;
|
||||
|
||||
@@ -58,7 +58,7 @@ constexpr std::size_t GetSizeInRange(const KMemoryInfo& info, VAddr start, VAddr
|
||||
|
||||
} // namespace
|
||||
|
||||
KPageTable::KPageTable(Core::System& system) : system{system} {}
|
||||
KPageTable::KPageTable(Core::System& system_) : system{system_} {}
|
||||
|
||||
ResultCode KPageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type,
|
||||
bool enable_aslr, VAddr code_addr,
|
||||
@@ -906,8 +906,8 @@ ResultCode KPageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) {
|
||||
|
||||
block_manager->UpdateLock(
|
||||
addr, size / PageSize,
|
||||
[](KMemoryBlockManager::iterator block, KMemoryPermission perm) {
|
||||
block->ShareToDevice(perm);
|
||||
[](KMemoryBlockManager::iterator block, KMemoryPermission permission) {
|
||||
block->ShareToDevice(permission);
|
||||
},
|
||||
perm);
|
||||
|
||||
@@ -929,8 +929,8 @@ ResultCode KPageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size)
|
||||
|
||||
block_manager->UpdateLock(
|
||||
addr, size / PageSize,
|
||||
[](KMemoryBlockManager::iterator block, KMemoryPermission perm) {
|
||||
block->UnshareToDevice(perm);
|
||||
[](KMemoryBlockManager::iterator block, KMemoryPermission permission) {
|
||||
block->UnshareToDevice(permission);
|
||||
},
|
||||
perm);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ class KMemoryBlockManager;
|
||||
|
||||
class KPageTable final : NonCopyable {
|
||||
public:
|
||||
explicit KPageTable(Core::System& system);
|
||||
explicit KPageTable(Core::System& system_);
|
||||
|
||||
ResultCode InitializeForProcess(FileSys::ProgramAddressSpaceType as_type, bool enable_aslr,
|
||||
VAddr code_addr, std::size_t code_size,
|
||||
|
||||
@@ -607,7 +607,7 @@ void KScheduler::YieldToAnyThread(KernelCore& kernel) {
|
||||
}
|
||||
}
|
||||
|
||||
KScheduler::KScheduler(Core::System& system, s32 core_id) : system(system), core_id(core_id) {
|
||||
KScheduler::KScheduler(Core::System& system_, s32 core_id_) : system{system_}, core_id{core_id_} {
|
||||
switch_fiber = std::make_shared<Common::Fiber>(OnSwitch, this);
|
||||
state.needs_scheduling.store(true);
|
||||
state.interrupt_task_thread_runnable = false;
|
||||
|
||||
@@ -30,7 +30,7 @@ class KThread;
|
||||
|
||||
class KScheduler final {
|
||||
public:
|
||||
explicit KScheduler(Core::System& system, s32 core_id);
|
||||
explicit KScheduler(Core::System& system_, s32 core_id_);
|
||||
~KScheduler();
|
||||
|
||||
/// Reschedules to the next available thread (call after current thread is suspended)
|
||||
|
||||
@@ -17,8 +17,8 @@ namespace Kernel {
|
||||
|
||||
class [[nodiscard]] KScopedSchedulerLockAndSleep {
|
||||
public:
|
||||
explicit KScopedSchedulerLockAndSleep(KernelCore & kernel, KThread * t, s64 timeout)
|
||||
: kernel(kernel), thread(t), timeout_tick(timeout) {
|
||||
explicit KScopedSchedulerLockAndSleep(KernelCore & kernel_, KThread * t, s64 timeout)
|
||||
: kernel(kernel_), thread(t), timeout_tick(timeout) {
|
||||
// Lock the scheduler.
|
||||
kernel.GlobalSchedulerContext().scheduler_lock.Lock();
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Kernel {
|
||||
|
||||
class KThreadQueue {
|
||||
public:
|
||||
explicit KThreadQueue(KernelCore& kernel) : kernel{kernel} {}
|
||||
explicit KThreadQueue(KernelCore& kernel_) : kernel{kernel_} {}
|
||||
|
||||
bool IsEmpty() const {
|
||||
return wait_list.empty();
|
||||
|
||||
@@ -52,7 +52,7 @@ public:
|
||||
}
|
||||
|
||||
size_t GetSize() const {
|
||||
return is_initialized ? size * PageSize : 0;
|
||||
return is_initialized ? size : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
PhysicalCore::PhysicalCore(std::size_t core_index, Core::System& system,
|
||||
Kernel::KScheduler& scheduler, Core::CPUInterrupts& interrupts)
|
||||
: core_index{core_index}, system{system}, scheduler{scheduler},
|
||||
interrupts{interrupts}, guard{std::make_unique<Common::SpinLock>()} {}
|
||||
PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_,
|
||||
Core::CPUInterrupts& interrupts_)
|
||||
: core_index{core_index_}, system{system_}, scheduler{scheduler_},
|
||||
interrupts{interrupts_}, guard{std::make_unique<Common::SpinLock>()} {}
|
||||
|
||||
PhysicalCore::~PhysicalCore() = default;
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ namespace Kernel {
|
||||
|
||||
class PhysicalCore {
|
||||
public:
|
||||
PhysicalCore(std::size_t core_index, Core::System& system, Kernel::KScheduler& scheduler,
|
||||
Core::CPUInterrupts& interrupts);
|
||||
PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_,
|
||||
Core::CPUInterrupts& interrupts_);
|
||||
~PhysicalCore();
|
||||
|
||||
PhysicalCore(const PhysicalCore&) = delete;
|
||||
|
||||
@@ -819,10 +819,10 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
Handle handle{};
|
||||
R_TRY(handle_table.Add(&handle, resource_limit));
|
||||
Handle resource_handle{};
|
||||
R_TRY(handle_table.Add(&resource_handle, resource_limit));
|
||||
|
||||
*result = handle;
|
||||
*result = resource_handle;
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ enum class ErrorModule : u32 {
|
||||
PCIe = 120,
|
||||
Friends = 121,
|
||||
BCAT = 122,
|
||||
SSL = 123,
|
||||
SSLSrv = 123,
|
||||
Account = 124,
|
||||
News = 125,
|
||||
Mii = 126,
|
||||
|
||||
@@ -833,7 +833,7 @@ IStorageImpl::~IStorageImpl() = default;
|
||||
|
||||
class StorageDataImpl final : public IStorageImpl {
|
||||
public:
|
||||
explicit StorageDataImpl(std::vector<u8>&& buffer) : buffer{std::move(buffer)} {}
|
||||
explicit StorageDataImpl(std::vector<u8>&& buffer_) : buffer{std::move(buffer_)} {}
|
||||
|
||||
std::vector<u8>& GetData() override {
|
||||
return buffer;
|
||||
@@ -1513,9 +1513,9 @@ void IApplicationFunctions::GetDisplayVersion(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
auto res = pm.GetControlMetadata();
|
||||
if (res.first != nullptr) {
|
||||
return res;
|
||||
auto metadata = pm.GetControlMetadata();
|
||||
if (metadata.first != nullptr) {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id),
|
||||
@@ -1550,9 +1550,9 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
|
||||
|
||||
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
|
||||
system.GetContentProvider()};
|
||||
auto res = pm.GetControlMetadata();
|
||||
if (res.first != nullptr) {
|
||||
return res;
|
||||
auto metadata = pm.GetControlMetadata();
|
||||
if (metadata.first != nullptr) {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
const FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id),
|
||||
|
||||
@@ -15,11 +15,11 @@ namespace Service::APM {
|
||||
|
||||
constexpr auto DEFAULT_PERFORMANCE_CONFIGURATION = PerformanceConfiguration::Config7;
|
||||
|
||||
Controller::Controller(Core::Timing::CoreTiming& core_timing)
|
||||
: core_timing{core_timing}, configs{
|
||||
{PerformanceMode::Handheld, DEFAULT_PERFORMANCE_CONFIGURATION},
|
||||
{PerformanceMode::Docked, DEFAULT_PERFORMANCE_CONFIGURATION},
|
||||
} {}
|
||||
Controller::Controller(Core::Timing::CoreTiming& core_timing_)
|
||||
: core_timing{core_timing_}, configs{
|
||||
{PerformanceMode::Handheld, DEFAULT_PERFORMANCE_CONFIGURATION},
|
||||
{PerformanceMode::Docked, DEFAULT_PERFORMANCE_CONFIGURATION},
|
||||
} {}
|
||||
|
||||
Controller::~Controller() = default;
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ enum class PerformanceMode : u8 {
|
||||
// system during times of high load -- this simply maps to different PerformanceConfigs to use.
|
||||
class Controller {
|
||||
public:
|
||||
explicit Controller(Core::Timing::CoreTiming& core_timing);
|
||||
explicit Controller(Core::Timing::CoreTiming& core_timing_);
|
||||
~Controller();
|
||||
|
||||
void SetPerformanceConfiguration(PerformanceMode mode, PerformanceConfiguration config);
|
||||
|
||||
@@ -362,7 +362,7 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
|
||||
static constexpr u64 max_perf_detail_entries = 100;
|
||||
|
||||
// Size of the data structure representing the bulk of the voice-related state.
|
||||
static constexpr u64 voice_state_size = 0x100;
|
||||
static constexpr u64 voice_state_size_bytes = 0x100;
|
||||
|
||||
// Size of the upsampler manager data structure
|
||||
constexpr u64 upsampler_manager_size = 0x48;
|
||||
@@ -449,7 +449,8 @@ void AudRenU::GetAudioRendererWorkBufferSize(Kernel::HLERequestContext& ctx) {
|
||||
size += Common::AlignUp(voice_info_size * params.voice_count, info_field_alignment_size);
|
||||
size +=
|
||||
Common::AlignUp(voice_resource_size * params.voice_count, info_field_alignment_size);
|
||||
size += Common::AlignUp(voice_state_size * params.voice_count, info_field_alignment_size);
|
||||
size +=
|
||||
Common::AlignUp(voice_state_size_bytes * params.voice_count, info_field_alignment_size);
|
||||
return size;
|
||||
};
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ public:
|
||||
Enabled,
|
||||
};
|
||||
|
||||
explicit OpusDecoderState(OpusDecoderPtr decoder, u32 sample_rate, u32 channel_count)
|
||||
: decoder{std::move(decoder)}, sample_rate{sample_rate}, channel_count{channel_count} {}
|
||||
explicit OpusDecoderState(OpusDecoderPtr decoder_, u32 sample_rate_, u32 channel_count_)
|
||||
: decoder{std::move(decoder_)}, sample_rate{sample_rate_}, channel_count{channel_count_} {}
|
||||
|
||||
// Decodes interleaved Opus packets. Optionally allows reporting time taken to
|
||||
// perform the decoding, as well as any relevant extra behavior.
|
||||
@@ -160,9 +160,9 @@ private:
|
||||
|
||||
class IHardwareOpusDecoderManager final : public ServiceFramework<IHardwareOpusDecoderManager> {
|
||||
public:
|
||||
explicit IHardwareOpusDecoderManager(Core::System& system_, OpusDecoderState decoder_state)
|
||||
explicit IHardwareOpusDecoderManager(Core::System& system_, OpusDecoderState decoder_state_)
|
||||
: ServiceFramework{system_, "IHardwareOpusDecoderManager"}, decoder_state{
|
||||
std::move(decoder_state)} {
|
||||
std::move(decoder_state_)} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IHardwareOpusDecoderManager::DecodeInterleavedOld, "DecodeInterleavedOld"},
|
||||
|
||||
@@ -3,9 +3,18 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <fmt/ostream.h>
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
#endif
|
||||
#include <httplib.h>
|
||||
#include <mbedtls/sha256.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
#include "common/hex_util.h"
|
||||
#include "common/logging/backend.h"
|
||||
#include "common/logging/log.h"
|
||||
@@ -178,8 +187,8 @@ bool VfsRawCopyDProgress(FileSys::VirtualDir src, FileSys::VirtualDir dest,
|
||||
|
||||
class Boxcat::Client {
|
||||
public:
|
||||
Client(std::string path, u64 title_id, u64 build_id)
|
||||
: path(std::move(path)), title_id(title_id), build_id(build_id) {}
|
||||
Client(std::string path_, u64 title_id_, u64 build_id_)
|
||||
: path(std::move(path_)), title_id(title_id_), build_id(build_id_) {}
|
||||
|
||||
DownloadResult DownloadDataZip() {
|
||||
return DownloadInternal(fmt::format(BOXCAT_PATHNAME_DATA, title_id), TIMEOUT_SECONDS,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
namespace Service::HID {
|
||||
|
||||
ControllerBase::ControllerBase(Core::System& system) : system(system) {}
|
||||
ControllerBase::ControllerBase(Core::System& system_) : system(system_) {}
|
||||
ControllerBase::~ControllerBase() = default;
|
||||
|
||||
void ControllerBase::ActivateController() {
|
||||
|
||||
@@ -18,7 +18,7 @@ class System;
|
||||
namespace Service::HID {
|
||||
class ControllerBase {
|
||||
public:
|
||||
explicit ControllerBase(Core::System& system);
|
||||
explicit ControllerBase(Core::System& system_);
|
||||
virtual ~ControllerBase();
|
||||
|
||||
// Called when the controller is initialized
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <cstring>
|
||||
#include "common/common_types.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "common/math_util.h"
|
||||
#include "common/settings.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/frontend/emu_window.h"
|
||||
@@ -12,10 +11,19 @@
|
||||
|
||||
namespace Service::HID {
|
||||
constexpr std::size_t SHARED_MEMORY_OFFSET = 0x3BA00;
|
||||
constexpr f32 angle_threshold = 0.08f;
|
||||
constexpr f32 pinch_threshold = 100.0f;
|
||||
|
||||
Controller_Gesture::Controller_Gesture(Core::System& system_) : ControllerBase{system_} {}
|
||||
// HW is around 700, value is set to 400 to make it easier to trigger with mouse
|
||||
constexpr f32 swipe_threshold = 400.0f; // Threshold in pixels/s
|
||||
constexpr f32 angle_threshold = 0.015f; // Threshold in radians
|
||||
constexpr f32 pinch_threshold = 0.5f; // Threshold in pixels
|
||||
constexpr f32 press_delay = 0.5f; // Time in seconds
|
||||
constexpr f32 double_tap_delay = 0.35f; // Time in seconds
|
||||
|
||||
constexpr f32 Square(s32 num) {
|
||||
return static_cast<f32>(num * num);
|
||||
}
|
||||
|
||||
Controller_Gesture::Controller_Gesture(Core::System& system_) : ControllerBase(system_) {}
|
||||
Controller_Gesture::~Controller_Gesture() = default;
|
||||
|
||||
void Controller_Gesture::OnInit() {
|
||||
@@ -24,6 +32,8 @@ void Controller_Gesture::OnInit() {
|
||||
keyboard_finger_id[id] = MAX_POINTS;
|
||||
udp_finger_id[id] = MAX_POINTS;
|
||||
}
|
||||
shared_memory.header.entry_count = 0;
|
||||
force_update = true;
|
||||
}
|
||||
|
||||
void Controller_Gesture::OnRelease() {}
|
||||
@@ -38,17 +48,23 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
|
||||
shared_memory.header.last_entry_index = 0;
|
||||
return;
|
||||
}
|
||||
shared_memory.header.entry_count = 16;
|
||||
|
||||
const auto& last_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
|
||||
shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17;
|
||||
auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
|
||||
ReadTouchInput();
|
||||
|
||||
cur_entry.sampling_number = last_entry.sampling_number + 1;
|
||||
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
||||
GestureProperties gesture = GetGestureProperties();
|
||||
f32 time_difference = static_cast<f32>(shared_memory.header.timestamp - last_update_timestamp) /
|
||||
(1000 * 1000 * 1000);
|
||||
|
||||
// TODO(german77): Implement all gesture types
|
||||
// Only update if necesary
|
||||
if (!ShouldUpdateGesture(gesture, time_difference)) {
|
||||
return;
|
||||
}
|
||||
|
||||
last_update_timestamp = shared_memory.header.timestamp;
|
||||
UpdateGestureSharedMemory(data, size, gesture, time_difference);
|
||||
}
|
||||
|
||||
void Controller_Gesture::ReadTouchInput() {
|
||||
const Input::TouchStatus& mouse_status = touch_mouse_device->GetStatus();
|
||||
const Input::TouchStatus& udp_status = touch_udp_device->GetStatus();
|
||||
for (std::size_t id = 0; id < mouse_status.size(); ++id) {
|
||||
@@ -63,50 +79,71 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
|
||||
UpdateTouchInputEvent(keyboard_status[id], keyboard_finger_id[id]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture,
|
||||
f32 time_difference) {
|
||||
const auto& last_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
|
||||
if (force_update) {
|
||||
force_update = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Update if coordinates change
|
||||
for (size_t id = 0; id < MAX_POINTS; id++) {
|
||||
if (gesture.points[id].x != last_gesture.points[id].x ||
|
||||
gesture.points[id].y != last_gesture.points[id].y) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Update on press and hold event after 0.5 seconds
|
||||
if (last_entry.type == TouchType::Touch && last_entry.point_count == 1 &&
|
||||
time_difference > press_delay) {
|
||||
return enable_press_and_tap;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size,
|
||||
GestureProperties& gesture,
|
||||
f32 time_difference) {
|
||||
TouchType type = TouchType::Idle;
|
||||
Attribute attributes{};
|
||||
GestureProperties gesture = GetGestureProperties();
|
||||
if (last_gesture.active_points != gesture.active_points) {
|
||||
++last_gesture.detection_count;
|
||||
|
||||
const auto& last_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
|
||||
shared_memory.header.last_entry_index = (shared_memory.header.last_entry_index + 1) % 17;
|
||||
auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
|
||||
|
||||
if (shared_memory.header.entry_count < 16) {
|
||||
shared_memory.header.entry_count++;
|
||||
}
|
||||
|
||||
cur_entry.sampling_number = last_entry.sampling_number + 1;
|
||||
cur_entry.sampling_number2 = cur_entry.sampling_number;
|
||||
|
||||
// Reset values to default
|
||||
cur_entry.delta_x = 0;
|
||||
cur_entry.delta_y = 0;
|
||||
cur_entry.vel_x = 0;
|
||||
cur_entry.vel_y = 0;
|
||||
cur_entry.direction = Direction::None;
|
||||
cur_entry.rotation_angle = 0;
|
||||
cur_entry.scale = 0;
|
||||
|
||||
if (gesture.active_points > 0) {
|
||||
if (last_gesture.active_points == 0) {
|
||||
attributes.is_new_touch.Assign(true);
|
||||
last_gesture.average_distance = gesture.average_distance;
|
||||
last_gesture.angle = gesture.angle;
|
||||
NewGesture(gesture, type, attributes);
|
||||
} else {
|
||||
UpdateExistingGesture(gesture, type, time_difference);
|
||||
}
|
||||
|
||||
type = TouchType::Touch;
|
||||
if (gesture.mid_point.x != last_entry.x || gesture.mid_point.y != last_entry.y) {
|
||||
type = TouchType::Pan;
|
||||
}
|
||||
if (std::abs(gesture.average_distance - last_gesture.average_distance) > pinch_threshold) {
|
||||
type = TouchType::Pinch;
|
||||
}
|
||||
if (std::abs(gesture.angle - last_gesture.angle) > angle_threshold) {
|
||||
type = TouchType::Rotate;
|
||||
}
|
||||
|
||||
cur_entry.delta_x = gesture.mid_point.x - last_entry.x;
|
||||
cur_entry.delta_y = gesture.mid_point.y - last_entry.y;
|
||||
// TODO: Find how velocities are calculated
|
||||
cur_entry.vel_x = static_cast<float>(cur_entry.delta_x) * 150.1f;
|
||||
cur_entry.vel_y = static_cast<float>(cur_entry.delta_y) * 150.1f;
|
||||
|
||||
// Slowdown the rate of change for less flapping
|
||||
last_gesture.average_distance =
|
||||
(last_gesture.average_distance * 0.9f) + (gesture.average_distance * 0.1f);
|
||||
last_gesture.angle = (last_gesture.angle * 0.9f) + (gesture.angle * 0.1f);
|
||||
|
||||
} else {
|
||||
cur_entry.delta_x = 0;
|
||||
cur_entry.delta_y = 0;
|
||||
cur_entry.vel_x = 0;
|
||||
cur_entry.vel_y = 0;
|
||||
EndGesture(gesture, last_gesture, type, attributes, time_difference);
|
||||
}
|
||||
last_gesture.active_points = gesture.active_points;
|
||||
cur_entry.detection_count = last_gesture.detection_count;
|
||||
|
||||
// Apply attributes
|
||||
cur_entry.detection_count = gesture.detection_count;
|
||||
cur_entry.type = type;
|
||||
cur_entry.attributes = attributes;
|
||||
cur_entry.x = gesture.mid_point.x;
|
||||
@@ -116,12 +153,195 @@ void Controller_Gesture::OnUpdate(const Core::Timing::CoreTiming& core_timing, u
|
||||
cur_entry.points[id].x = gesture.points[id].x;
|
||||
cur_entry.points[id].y = gesture.points[id].y;
|
||||
}
|
||||
cur_entry.rotation_angle = 0;
|
||||
cur_entry.scale = 0;
|
||||
last_gesture = gesture;
|
||||
|
||||
std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory));
|
||||
}
|
||||
|
||||
void Controller_Gesture::NewGesture(GestureProperties& gesture, TouchType& type,
|
||||
Attribute& attributes) {
|
||||
const auto& last_entry =
|
||||
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
|
||||
gesture.detection_count++;
|
||||
type = TouchType::Touch;
|
||||
|
||||
// New touch after cancel is not considered new
|
||||
if (last_entry.type != TouchType::Cancel) {
|
||||
attributes.is_new_touch.Assign(1);
|
||||
enable_press_and_tap = true;
|
||||
}
|
||||
}
|
||||
|
||||
void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, TouchType& type,
|
||||
f32 time_difference) {
|
||||
const auto& last_entry =
|
||||
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
|
||||
|
||||
// Promote to pan type if touch moved
|
||||
for (size_t id = 0; id < MAX_POINTS; id++) {
|
||||
if (gesture.points[id].x != last_gesture.points[id].x ||
|
||||
gesture.points[id].y != last_gesture.points[id].y) {
|
||||
type = TouchType::Pan;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Number of fingers changed cancel the last event and clear data
|
||||
if (gesture.active_points != last_gesture.active_points) {
|
||||
type = TouchType::Cancel;
|
||||
enable_press_and_tap = false;
|
||||
gesture.active_points = 0;
|
||||
gesture.mid_point = {};
|
||||
for (size_t id = 0; id < MAX_POINTS; id++) {
|
||||
gesture.points[id].x = 0;
|
||||
gesture.points[id].y = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Calculate extra parameters of panning
|
||||
if (type == TouchType::Pan) {
|
||||
UpdatePanEvent(gesture, last_gesture, type, time_difference);
|
||||
return;
|
||||
}
|
||||
|
||||
// Promote to press type
|
||||
if (last_entry.type == TouchType::Touch) {
|
||||
type = TouchType::Press;
|
||||
}
|
||||
}
|
||||
|
||||
void Controller_Gesture::EndGesture(GestureProperties& gesture,
|
||||
GestureProperties& last_gesture_props, TouchType& type,
|
||||
Attribute& attributes, f32 time_difference) {
|
||||
const auto& last_entry =
|
||||
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
|
||||
if (last_gesture_props.active_points != 0) {
|
||||
switch (last_entry.type) {
|
||||
case TouchType::Touch:
|
||||
if (enable_press_and_tap) {
|
||||
SetTapEvent(gesture, last_gesture_props, type, attributes);
|
||||
return;
|
||||
}
|
||||
type = TouchType::Cancel;
|
||||
force_update = true;
|
||||
break;
|
||||
case TouchType::Press:
|
||||
case TouchType::Tap:
|
||||
case TouchType::Swipe:
|
||||
case TouchType::Pinch:
|
||||
case TouchType::Rotate:
|
||||
type = TouchType::Complete;
|
||||
force_update = true;
|
||||
break;
|
||||
case TouchType::Pan:
|
||||
EndPanEvent(gesture, last_gesture_props, type, time_difference);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (last_entry.type == TouchType::Complete || last_entry.type == TouchType::Cancel) {
|
||||
gesture.detection_count++;
|
||||
}
|
||||
}
|
||||
|
||||
void Controller_Gesture::SetTapEvent(GestureProperties& gesture,
|
||||
GestureProperties& last_gesture_props, TouchType& type,
|
||||
Attribute& attributes) {
|
||||
type = TouchType::Tap;
|
||||
gesture = last_gesture_props;
|
||||
force_update = true;
|
||||
f32 tap_time_difference =
|
||||
static_cast<f32>(last_update_timestamp - last_tap_timestamp) / (1000 * 1000 * 1000);
|
||||
last_tap_timestamp = last_update_timestamp;
|
||||
if (tap_time_difference < double_tap_delay) {
|
||||
attributes.is_double_tap.Assign(1);
|
||||
}
|
||||
}
|
||||
|
||||
void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture,
|
||||
GestureProperties& last_gesture_props, TouchType& type,
|
||||
f32 time_difference) {
|
||||
auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
|
||||
const auto& last_entry =
|
||||
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
|
||||
cur_entry.delta_x = gesture.mid_point.x - last_entry.x;
|
||||
cur_entry.delta_y = gesture.mid_point.y - last_entry.y;
|
||||
|
||||
cur_entry.vel_x = static_cast<f32>(cur_entry.delta_x) / time_difference;
|
||||
cur_entry.vel_y = static_cast<f32>(cur_entry.delta_y) / time_difference;
|
||||
last_pan_time_difference = time_difference;
|
||||
|
||||
// Promote to pinch type
|
||||
if (std::abs(gesture.average_distance - last_gesture_props.average_distance) >
|
||||
pinch_threshold) {
|
||||
type = TouchType::Pinch;
|
||||
cur_entry.scale = gesture.average_distance / last_gesture_props.average_distance;
|
||||
}
|
||||
|
||||
const f32 angle_between_two_lines = std::atan((gesture.angle - last_gesture_props.angle) /
|
||||
(1 + (gesture.angle * last_gesture_props.angle)));
|
||||
// Promote to rotate type
|
||||
if (std::abs(angle_between_two_lines) > angle_threshold) {
|
||||
type = TouchType::Rotate;
|
||||
cur_entry.scale = 0;
|
||||
cur_entry.rotation_angle = angle_between_two_lines * 180.0f / Common::PI;
|
||||
}
|
||||
}
|
||||
|
||||
void Controller_Gesture::EndPanEvent(GestureProperties& gesture,
|
||||
GestureProperties& last_gesture_props, TouchType& type,
|
||||
f32 time_difference) {
|
||||
auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
|
||||
const auto& last_entry =
|
||||
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
|
||||
cur_entry.vel_x =
|
||||
static_cast<f32>(last_entry.delta_x) / (last_pan_time_difference + time_difference);
|
||||
cur_entry.vel_y =
|
||||
static_cast<f32>(last_entry.delta_y) / (last_pan_time_difference + time_difference);
|
||||
const f32 curr_vel =
|
||||
std::sqrt((cur_entry.vel_x * cur_entry.vel_x) + (cur_entry.vel_y * cur_entry.vel_y));
|
||||
|
||||
// Set swipe event with parameters
|
||||
if (curr_vel > swipe_threshold) {
|
||||
SetSwipeEvent(gesture, last_gesture_props, type);
|
||||
return;
|
||||
}
|
||||
|
||||
// End panning without swipe
|
||||
type = TouchType::Complete;
|
||||
cur_entry.vel_x = 0;
|
||||
cur_entry.vel_y = 0;
|
||||
force_update = true;
|
||||
}
|
||||
|
||||
void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture,
|
||||
GestureProperties& last_gesture_props, TouchType& type) {
|
||||
auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index];
|
||||
const auto& last_entry =
|
||||
shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17];
|
||||
type = TouchType::Swipe;
|
||||
gesture = last_gesture_props;
|
||||
force_update = true;
|
||||
cur_entry.delta_x = last_entry.delta_x;
|
||||
cur_entry.delta_y = last_entry.delta_y;
|
||||
if (std::abs(cur_entry.delta_x) > std::abs(cur_entry.delta_y)) {
|
||||
if (cur_entry.delta_x > 0) {
|
||||
cur_entry.direction = Direction::Right;
|
||||
return;
|
||||
}
|
||||
cur_entry.direction = Direction::Left;
|
||||
return;
|
||||
}
|
||||
if (cur_entry.delta_y > 0) {
|
||||
cur_entry.direction = Direction::Down;
|
||||
return;
|
||||
}
|
||||
cur_entry.direction = Direction::Up;
|
||||
}
|
||||
|
||||
void Controller_Gesture::OnLoadInputDevices() {
|
||||
touch_mouse_device = Input::CreateDevice<Input::TouchDevice>("engine:emu_window");
|
||||
touch_udp_device = Input::CreateDevice<Input::TouchDevice>("engine:cemuhookudp");
|
||||
@@ -183,23 +403,33 @@ Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties()
|
||||
|
||||
for (size_t id = 0; id < gesture.active_points; ++id) {
|
||||
gesture.points[id].x =
|
||||
static_cast<int>(active_fingers[id].x * Layout::ScreenUndocked::Width);
|
||||
static_cast<s32>(active_fingers[id].x * Layout::ScreenUndocked::Width);
|
||||
gesture.points[id].y =
|
||||
static_cast<int>(active_fingers[id].y * Layout::ScreenUndocked::Height);
|
||||
gesture.mid_point.x += static_cast<int>(gesture.points[id].x / gesture.active_points);
|
||||
gesture.mid_point.y += static_cast<int>(gesture.points[id].y / gesture.active_points);
|
||||
static_cast<s32>(active_fingers[id].y * Layout::ScreenUndocked::Height);
|
||||
|
||||
// Hack: There is no touch in docked but games still allow it
|
||||
if (Settings::values.use_docked_mode.GetValue()) {
|
||||
gesture.points[id].x =
|
||||
static_cast<s32>(active_fingers[id].x * Layout::ScreenDocked::Width);
|
||||
gesture.points[id].y =
|
||||
static_cast<s32>(active_fingers[id].y * Layout::ScreenDocked::Height);
|
||||
}
|
||||
|
||||
gesture.mid_point.x += static_cast<s32>(gesture.points[id].x / gesture.active_points);
|
||||
gesture.mid_point.y += static_cast<s32>(gesture.points[id].y / gesture.active_points);
|
||||
}
|
||||
|
||||
for (size_t id = 0; id < gesture.active_points; ++id) {
|
||||
const double distance =
|
||||
std::pow(static_cast<float>(gesture.mid_point.x - gesture.points[id].x), 2) +
|
||||
std::pow(static_cast<float>(gesture.mid_point.y - gesture.points[id].y), 2);
|
||||
gesture.average_distance +=
|
||||
static_cast<float>(distance) / static_cast<float>(gesture.active_points);
|
||||
const f32 distance = std::sqrt(Square(gesture.mid_point.x - gesture.points[id].x) +
|
||||
Square(gesture.mid_point.y - gesture.points[id].y));
|
||||
gesture.average_distance += distance / static_cast<f32>(gesture.active_points);
|
||||
}
|
||||
|
||||
gesture.angle = std::atan2(static_cast<float>(gesture.mid_point.y - gesture.points[0].y),
|
||||
static_cast<float>(gesture.mid_point.x - gesture.points[0].x));
|
||||
gesture.angle = std::atan2(static_cast<f32>(gesture.mid_point.y - gesture.points[0].y),
|
||||
static_cast<f32>(gesture.mid_point.x - gesture.points[0].x));
|
||||
|
||||
gesture.detection_count = last_gesture.detection_count;
|
||||
|
||||
return gesture;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Copyright 2021 yuzu Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <array>
|
||||
#include "common/bit_field.h"
|
||||
#include "common/common_types.h"
|
||||
#include "common/swap.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/service/hid/controllers/controller_base.h"
|
||||
|
||||
@@ -35,10 +34,10 @@ private:
|
||||
|
||||
enum class TouchType : u32 {
|
||||
Idle, // Nothing touching the screen
|
||||
Complete, // Unknown. End of touch?
|
||||
Cancel, // Never triggered
|
||||
Touch, // Pressing without movement
|
||||
Press, // Never triggered
|
||||
Complete, // Set at the end of a touch event
|
||||
Cancel, // Set when the number of fingers change
|
||||
Touch, // A finger just touched the screen
|
||||
Press, // Set if last type is touch and the finger hasn't moved
|
||||
Tap, // Fast press then release
|
||||
Pan, // All points moving together across the screen
|
||||
Swipe, // Fast press movement and release of a single point
|
||||
@@ -58,8 +57,8 @@ private:
|
||||
union {
|
||||
u32_le raw{};
|
||||
|
||||
BitField<0, 1, u32> is_new_touch;
|
||||
BitField<1, 1, u32> is_double_tap;
|
||||
BitField<4, 1, u32> is_new_touch;
|
||||
BitField<8, 1, u32> is_double_tap;
|
||||
};
|
||||
};
|
||||
static_assert(sizeof(Attribute) == 4, "Attribute is an invalid size");
|
||||
@@ -73,10 +72,9 @@ private:
|
||||
struct GestureState {
|
||||
s64_le sampling_number;
|
||||
s64_le sampling_number2;
|
||||
|
||||
s64_le detection_count;
|
||||
TouchType type;
|
||||
Direction dir;
|
||||
Direction direction;
|
||||
s32_le x;
|
||||
s32_le y;
|
||||
s32_le delta_x;
|
||||
@@ -84,8 +82,8 @@ private:
|
||||
f32 vel_x;
|
||||
f32 vel_y;
|
||||
Attribute attributes;
|
||||
u32 scale;
|
||||
u32 rotation_angle;
|
||||
f32 scale;
|
||||
f32 rotation_angle;
|
||||
s32_le point_count;
|
||||
std::array<Points, 4> points;
|
||||
};
|
||||
@@ -109,17 +107,55 @@ private:
|
||||
Points mid_point{};
|
||||
s64_le detection_count{};
|
||||
u64_le delta_time{};
|
||||
float average_distance{};
|
||||
float angle{};
|
||||
f32 average_distance{};
|
||||
f32 angle{};
|
||||
};
|
||||
|
||||
// Returns an unused finger id, if there is no fingers avaliable MAX_FINGERS will be returned
|
||||
// Reads input from all available input engines
|
||||
void ReadTouchInput();
|
||||
|
||||
// Returns true if gesture state needs to be updated
|
||||
bool ShouldUpdateGesture(const GestureProperties& gesture, f32 time_difference);
|
||||
|
||||
// Updates the shared memory to the next state
|
||||
void UpdateGestureSharedMemory(u8* data, std::size_t size, GestureProperties& gesture,
|
||||
f32 time_difference);
|
||||
|
||||
// Initializes new gesture
|
||||
void NewGesture(GestureProperties& gesture, TouchType& type, Attribute& attributes);
|
||||
|
||||
// Updates existing gesture state
|
||||
void UpdateExistingGesture(GestureProperties& gesture, TouchType& type, f32 time_difference);
|
||||
|
||||
// Terminates exiting gesture
|
||||
void EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props,
|
||||
TouchType& type, Attribute& attributes, f32 time_difference);
|
||||
|
||||
// Set current event to a tap event
|
||||
void SetTapEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
|
||||
TouchType& type, Attribute& attributes);
|
||||
|
||||
// Calculates and set the extra parameters related to a pan event
|
||||
void UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
|
||||
TouchType& type, f32 time_difference);
|
||||
|
||||
// Terminates the pan event
|
||||
void EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
|
||||
TouchType& type, f32 time_difference);
|
||||
|
||||
// Set current event to a swipe event
|
||||
void SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props,
|
||||
TouchType& type);
|
||||
|
||||
// Returns an unused finger id, if there is no fingers available std::nullopt is returned.
|
||||
std::optional<size_t> GetUnusedFingerID() const;
|
||||
|
||||
/** If the touch is new it tries to assing a new finger id, if there is no fingers avaliable no
|
||||
/**
|
||||
* If the touch is new it tries to assign a new finger id, if there is no fingers available no
|
||||
* changes will be made. Updates the coordinates if the finger id it's already set. If the touch
|
||||
* ends delays the output by one frame to set the end_touch flag before finally freeing the
|
||||
* finger id */
|
||||
* finger id
|
||||
*/
|
||||
size_t UpdateTouchInputEvent(const std::tuple<float, float, bool>& touch_input,
|
||||
size_t finger_id);
|
||||
|
||||
@@ -134,6 +170,11 @@ private:
|
||||
std::array<size_t, MAX_FINGERS> keyboard_finger_id;
|
||||
std::array<size_t, MAX_FINGERS> udp_finger_id;
|
||||
std::array<Finger, MAX_POINTS> fingers;
|
||||
GestureProperties last_gesture;
|
||||
GestureProperties last_gesture{};
|
||||
s64_le last_update_timestamp{};
|
||||
s64_le last_tap_timestamp{};
|
||||
f32 last_pan_time_difference{};
|
||||
bool force_update{false};
|
||||
bool enable_press_and_tap{false};
|
||||
};
|
||||
} // namespace Service::HID
|
||||
|
||||
@@ -89,7 +89,7 @@ static_assert(std::has_unique_object_representations_v<MiiInfo>,
|
||||
#pragma pack(push, 4)
|
||||
|
||||
struct MiiInfoElement {
|
||||
MiiInfoElement(const MiiInfo& info, Source source) : info{info}, source{source} {}
|
||||
MiiInfoElement(const MiiInfo& info_, Source source_) : info{info_}, source{source_} {}
|
||||
|
||||
MiiInfo info{};
|
||||
Source source{};
|
||||
|
||||
@@ -253,8 +253,8 @@ private:
|
||||
|
||||
class MiiDBModule final : public ServiceFramework<MiiDBModule> {
|
||||
public:
|
||||
explicit MiiDBModule(Core::System& system_, const char* name)
|
||||
: ServiceFramework{system_, name} {
|
||||
explicit MiiDBModule(Core::System& system_, const char* name_)
|
||||
: ServiceFramework{system_, name_} {
|
||||
// clang-format off
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &MiiDBModule::GetDatabaseService, "GetDatabaseService"},
|
||||
|
||||
@@ -368,7 +368,7 @@ private:
|
||||
},
|
||||
};
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 2 + sizeof(IpConfigInfo) / sizeof(u32)};
|
||||
IPC::ResponseBuilder rb{ctx, 2 + (sizeof(IpConfigInfo) + 3) / sizeof(u32)};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw<IpConfigInfo>(ip_config_info);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace Service::Nvidia::Devices {
|
||||
/// implement the ioctl interface.
|
||||
class nvdevice {
|
||||
public:
|
||||
explicit nvdevice(Core::System& system) : system{system} {}
|
||||
explicit nvdevice(Core::System& system_) : system{system_} {}
|
||||
virtual ~nvdevice() = default;
|
||||
|
||||
/**
|
||||
|
||||
@@ -52,7 +52,6 @@ void nvdisp_disp0::flip(u32 buffer_handle, u32 offset, u32 format, u32 width, u3
|
||||
addr, offset, width, height, stride, static_cast<PixelFormat>(format),
|
||||
transform, crop_rect};
|
||||
|
||||
system.GetPerfStats().EndGameFrame();
|
||||
system.GetPerfStats().EndSystemFrame();
|
||||
system.GPU().SwapBuffers(&framebuffer);
|
||||
system.FrameLimiter().DoFrameLimiting(system.CoreTiming().GetGlobalTimeUs());
|
||||
|
||||
@@ -48,13 +48,13 @@ private:
|
||||
public:
|
||||
constexpr BufferMap() = default;
|
||||
|
||||
constexpr BufferMap(GPUVAddr start_addr, std::size_t size)
|
||||
: start_addr{start_addr}, end_addr{start_addr + size} {}
|
||||
constexpr BufferMap(GPUVAddr start_addr_, std::size_t size_)
|
||||
: start_addr{start_addr_}, end_addr{start_addr_ + size_} {}
|
||||
|
||||
constexpr BufferMap(GPUVAddr start_addr, std::size_t size, VAddr cpu_addr,
|
||||
bool is_allocated)
|
||||
: start_addr{start_addr}, end_addr{start_addr + size}, cpu_addr{cpu_addr},
|
||||
is_allocated{is_allocated} {}
|
||||
constexpr BufferMap(GPUVAddr start_addr_, std::size_t size_, VAddr cpu_addr_,
|
||||
bool is_allocated_)
|
||||
: start_addr{start_addr_}, end_addr{start_addr_ + size_}, cpu_addr{cpu_addr_},
|
||||
is_allocated{is_allocated_} {}
|
||||
|
||||
constexpr VAddr StartAddr() const {
|
||||
return start_addr;
|
||||
|
||||
@@ -27,13 +27,13 @@ protected:
|
||||
public:
|
||||
constexpr BufferMap() = default;
|
||||
|
||||
constexpr BufferMap(GPUVAddr start_addr, std::size_t size)
|
||||
: start_addr{start_addr}, end_addr{start_addr + size} {}
|
||||
constexpr BufferMap(GPUVAddr start_addr_, std::size_t size_)
|
||||
: start_addr{start_addr_}, end_addr{start_addr_ + size_} {}
|
||||
|
||||
constexpr BufferMap(GPUVAddr start_addr, std::size_t size, VAddr cpu_addr,
|
||||
bool is_allocated)
|
||||
: start_addr{start_addr}, end_addr{start_addr + size}, cpu_addr{cpu_addr},
|
||||
is_allocated{is_allocated} {}
|
||||
constexpr BufferMap(GPUVAddr start_addr_, std::size_t size_, VAddr cpu_addr_,
|
||||
bool is_allocated_)
|
||||
: start_addr{start_addr_}, end_addr{start_addr_ + size_}, cpu_addr{cpu_addr_},
|
||||
is_allocated{is_allocated_} {}
|
||||
|
||||
constexpr VAddr StartAddr() const {
|
||||
return start_addr;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
namespace Service::Nvidia {
|
||||
|
||||
SyncpointManager::SyncpointManager(Tegra::GPU& gpu) : gpu{gpu} {}
|
||||
SyncpointManager::SyncpointManager(Tegra::GPU& gpu_) : gpu{gpu_} {}
|
||||
|
||||
SyncpointManager::~SyncpointManager() = default;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Service::Nvidia {
|
||||
|
||||
class SyncpointManager final {
|
||||
public:
|
||||
explicit SyncpointManager(Tegra::GPU& gpu);
|
||||
explicit SyncpointManager(Tegra::GPU& gpu_);
|
||||
~SyncpointManager();
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
|
||||
namespace Service::NVFlinger {
|
||||
|
||||
BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id)
|
||||
: id(id), layer_id(layer_id), buffer_wait_event{kernel} {
|
||||
BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id_, u64 layer_id_)
|
||||
: id(id_), layer_id(layer_id_), buffer_wait_event{kernel} {
|
||||
Kernel::KAutoObject::Create(std::addressof(buffer_wait_event));
|
||||
buffer_wait_event.Initialize("BufferQueue:WaitEvent");
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public:
|
||||
NativeWindowFormat = 2,
|
||||
};
|
||||
|
||||
explicit BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id);
|
||||
explicit BufferQueue(Kernel::KernelCore& kernel, u32 id_, u64 layer_id_);
|
||||
~BufferQueue();
|
||||
|
||||
enum class BufferTransformFlags : u32 {
|
||||
|
||||
@@ -61,7 +61,7 @@ void NVFlinger::SplitVSync() {
|
||||
}
|
||||
}
|
||||
|
||||
NVFlinger::NVFlinger(Core::System& system) : system(system) {
|
||||
NVFlinger::NVFlinger(Core::System& system_) : system(system_) {
|
||||
displays.emplace_back(0, "Default", system);
|
||||
displays.emplace_back(1, "External", system);
|
||||
displays.emplace_back(2, "Edid", system);
|
||||
@@ -139,11 +139,15 @@ std::optional<u64> NVFlinger::CreateLayer(u64 display_id) {
|
||||
}
|
||||
|
||||
const u64 layer_id = next_layer_id++;
|
||||
CreateLayerAtId(*display, layer_id);
|
||||
return layer_id;
|
||||
}
|
||||
|
||||
void NVFlinger::CreateLayerAtId(VI::Display& display, u64 layer_id) {
|
||||
const u32 buffer_queue_id = next_buffer_queue_id++;
|
||||
buffer_queues.emplace_back(
|
||||
std::make_unique<BufferQueue>(system.Kernel(), buffer_queue_id, layer_id));
|
||||
display->CreateLayer(layer_id, *buffer_queues.back());
|
||||
return layer_id;
|
||||
display.CreateLayer(layer_id, *buffer_queues.back());
|
||||
}
|
||||
|
||||
void NVFlinger::CloseLayer(u64 layer_id) {
|
||||
@@ -154,9 +158,9 @@ void NVFlinger::CloseLayer(u64 layer_id) {
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) const {
|
||||
std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) {
|
||||
const auto lock_guard = Lock();
|
||||
const auto* const layer = FindLayer(display_id, layer_id);
|
||||
const auto* const layer = FindOrCreateLayer(display_id, layer_id);
|
||||
|
||||
if (layer == nullptr) {
|
||||
return std::nullopt;
|
||||
@@ -232,6 +236,24 @@ const VI::Layer* NVFlinger::FindLayer(u64 display_id, u64 layer_id) const {
|
||||
return display->FindLayer(layer_id);
|
||||
}
|
||||
|
||||
VI::Layer* NVFlinger::FindOrCreateLayer(u64 display_id, u64 layer_id) {
|
||||
auto* const display = FindDisplay(display_id);
|
||||
|
||||
if (display == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto* layer = display->FindLayer(layer_id);
|
||||
|
||||
if (layer == nullptr) {
|
||||
LOG_DEBUG(Service, "Layer at id {} not found. Trying to create it.", layer_id);
|
||||
CreateLayerAtId(*display, layer_id);
|
||||
return display->FindLayer(layer_id);
|
||||
}
|
||||
|
||||
return layer;
|
||||
}
|
||||
|
||||
void NVFlinger::Compose() {
|
||||
for (auto& display : displays) {
|
||||
// Trigger vsync for this display at the end of drawing
|
||||
|
||||
@@ -45,7 +45,7 @@ class BufferQueue;
|
||||
|
||||
class NVFlinger final {
|
||||
public:
|
||||
explicit NVFlinger(Core::System& system);
|
||||
explicit NVFlinger(Core::System& system_);
|
||||
~NVFlinger();
|
||||
|
||||
/// Sets the NVDrv module instance to use to send buffers to the GPU.
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
/// Finds the buffer queue ID of the specified layer in the specified display.
|
||||
///
|
||||
/// If an invalid display ID or layer ID is provided, then an empty optional is returned.
|
||||
[[nodiscard]] std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id) const;
|
||||
[[nodiscard]] std::optional<u32> FindBufferQueueId(u64 display_id, u64 layer_id);
|
||||
|
||||
/// Gets the vsync event for the specified display.
|
||||
///
|
||||
@@ -100,6 +100,14 @@ private:
|
||||
/// Finds the layer identified by the specified ID in the desired display.
|
||||
[[nodiscard]] const VI::Layer* FindLayer(u64 display_id, u64 layer_id) const;
|
||||
|
||||
/// Finds the layer identified by the specified ID in the desired display,
|
||||
/// or creates the layer if it is not found.
|
||||
/// To be used when the system expects the specified ID to already exist.
|
||||
[[nodiscard]] VI::Layer* FindOrCreateLayer(u64 display_id, u64 layer_id);
|
||||
|
||||
/// Creates a layer with the specified layer ID in the desired display.
|
||||
void CreateLayerAtId(VI::Display& display, u64 layer_id);
|
||||
|
||||
static void VSyncThread(NVFlinger& nv_flinger);
|
||||
|
||||
void SplitVSync();
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
namespace Service::PCTL {
|
||||
|
||||
PCTL::PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name,
|
||||
Capability capability)
|
||||
: Interface{system_, std::move(module_), name, capability} {
|
||||
Capability capability_)
|
||||
: Interface{system_, std::move(module_), name, capability_} {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &PCTL::CreateService, "CreateService"},
|
||||
{1, &PCTL::CreateServiceWithoutInitialize, "CreateServiceWithoutInitialize"},
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Service::PCTL {
|
||||
class PCTL final : public Module::Interface {
|
||||
public:
|
||||
explicit PCTL(Core::System& system_, std::shared_ptr<Module> module_, const char* name,
|
||||
Capability capability);
|
||||
Capability capability_);
|
||||
~PCTL() override;
|
||||
};
|
||||
|
||||
|
||||
@@ -31,8 +31,8 @@ std::optional<Kernel::KProcess*> SearchProcessList(
|
||||
|
||||
void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
|
||||
const std::vector<Kernel::KProcess*>& process_list) {
|
||||
const auto process = SearchProcessList(process_list, [](const auto& process) {
|
||||
return process->GetProcessID() == Kernel::KProcess::ProcessIDMin;
|
||||
const auto process = SearchProcessList(process_list, [](const auto& proc) {
|
||||
return proc->GetProcessID() == Kernel::KProcess::ProcessIDMin;
|
||||
});
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
@@ -100,8 +100,8 @@ private:
|
||||
LOG_DEBUG(Service_PM, "called, title_id={:016X}", title_id);
|
||||
|
||||
const auto process =
|
||||
SearchProcessList(kernel.GetProcessList(), [title_id](const auto& process) {
|
||||
return process->GetTitleID() == title_id;
|
||||
SearchProcessList(kernel.GetProcessList(), [title_id](const auto& proc) {
|
||||
return proc->GetTitleID() == title_id;
|
||||
});
|
||||
|
||||
if (!process.has_value()) {
|
||||
@@ -140,8 +140,8 @@ private:
|
||||
|
||||
LOG_DEBUG(Service_PM, "called, process_id={:016X}", process_id);
|
||||
|
||||
const auto process = SearchProcessList(process_list, [process_id](const auto& process) {
|
||||
return process->GetProcessID() == process_id;
|
||||
const auto process = SearchProcessList(process_list, [process_id](const auto& proc) {
|
||||
return proc->GetProcessID() == process_id;
|
||||
});
|
||||
|
||||
if (!process.has_value()) {
|
||||
|
||||
@@ -155,17 +155,17 @@ protected:
|
||||
/**
|
||||
* Constructs a FunctionInfo for a function.
|
||||
*
|
||||
* @param expected_header request header in the command buffer which will trigger dispatch
|
||||
* @param expected_header_ request header in the command buffer which will trigger dispatch
|
||||
* to this handler
|
||||
* @param handler_callback member function in this service which will be called to handle
|
||||
* @param handler_callback_ member function in this service which will be called to handle
|
||||
* the request
|
||||
* @param name human-friendly name for the request. Used mostly for logging purposes.
|
||||
* @param name_ human-friendly name for the request. Used mostly for logging purposes.
|
||||
*/
|
||||
FunctionInfo(u32 expected_header, HandlerFnP<Self> handler_callback, const char* name)
|
||||
FunctionInfo(u32 expected_header_, HandlerFnP<Self> handler_callback_, const char* name_)
|
||||
: FunctionInfoBase{
|
||||
expected_header,
|
||||
expected_header_,
|
||||
// Type-erase member function pointer by casting it down to the base class.
|
||||
static_cast<HandlerFnP<ServiceFrameworkBase>>(handler_callback), name} {}
|
||||
static_cast<HandlerFnP<ServiceFrameworkBase>>(handler_callback_), name_} {}
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,6 +10,11 @@
|
||||
|
||||
namespace Service::SSL {
|
||||
|
||||
enum class CertificateFormat : u32 {
|
||||
Pem = 1,
|
||||
Der = 2,
|
||||
};
|
||||
|
||||
class ISslConnection final : public ServiceFramework<ISslConnection> {
|
||||
public:
|
||||
explicit ISslConnection(Core::System& system_) : ServiceFramework{system_, "ISslConnection"} {
|
||||
@@ -58,8 +63,8 @@ public:
|
||||
{1, nullptr, "GetOption"},
|
||||
{2, &ISslContext::CreateConnection, "CreateConnection"},
|
||||
{3, nullptr, "GetConnectionCount"},
|
||||
{4, nullptr, "ImportServerPki"},
|
||||
{5, nullptr, "ImportClientPki"},
|
||||
{4, &ISslContext::ImportServerPki, "ImportServerPki"},
|
||||
{5, &ISslContext::ImportClientPki, "ImportClientPki"},
|
||||
{6, nullptr, "RemoveServerPki"},
|
||||
{7, nullptr, "RemoveClientPki"},
|
||||
{8, nullptr, "RegisterInternalPki"},
|
||||
@@ -94,6 +99,39 @@ private:
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISslConnection>(system);
|
||||
}
|
||||
|
||||
void ImportServerPki(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto certificate_format = rp.PopEnum<CertificateFormat>();
|
||||
const auto pkcs_12_certificates = ctx.ReadBuffer(0);
|
||||
|
||||
constexpr u64 server_id = 0;
|
||||
|
||||
LOG_WARNING(Service_SSL, "(STUBBED) called, certificate_format={}", certificate_format);
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(server_id);
|
||||
}
|
||||
|
||||
void ImportClientPki(Kernel::HLERequestContext& ctx) {
|
||||
const auto pkcs_12_certificate = ctx.ReadBuffer(0);
|
||||
const auto ascii_password = [&ctx] {
|
||||
if (ctx.CanReadBuffer(1)) {
|
||||
return ctx.ReadBuffer(1);
|
||||
}
|
||||
|
||||
return std::vector<u8>{};
|
||||
}();
|
||||
|
||||
constexpr u64 client_id = 0;
|
||||
|
||||
LOG_WARNING(Service_SSL, "(STUBBED) called");
|
||||
|
||||
IPC::ResponseBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(client_id);
|
||||
}
|
||||
};
|
||||
|
||||
class SSL final : public ServiceFramework<SSL> {
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace Service::Time::Clock {
|
||||
|
||||
class EphemeralNetworkSystemClockCore final : public SystemClockCore {
|
||||
public:
|
||||
explicit EphemeralNetworkSystemClockCore(SteadyClockCore& steady_clock_core)
|
||||
: SystemClockCore{steady_clock_core} {}
|
||||
explicit EphemeralNetworkSystemClockCore(SteadyClockCore& steady_clock_core_)
|
||||
: SystemClockCore{steady_clock_core_} {}
|
||||
};
|
||||
|
||||
} // namespace Service::Time::Clock
|
||||
|
||||
@@ -12,8 +12,8 @@ namespace Service::Time::Clock {
|
||||
|
||||
class LocalSystemClockContextWriter final : public SystemClockContextUpdateCallback {
|
||||
public:
|
||||
explicit LocalSystemClockContextWriter(SharedMemory& shared_memory)
|
||||
: SystemClockContextUpdateCallback{}, shared_memory{shared_memory} {}
|
||||
explicit LocalSystemClockContextWriter(SharedMemory& shared_memory_)
|
||||
: SystemClockContextUpdateCallback{}, shared_memory{shared_memory_} {}
|
||||
|
||||
protected:
|
||||
ResultCode Update() override {
|
||||
|
||||
@@ -12,8 +12,8 @@ namespace Service::Time::Clock {
|
||||
|
||||
class NetworkSystemClockContextWriter final : public SystemClockContextUpdateCallback {
|
||||
public:
|
||||
explicit NetworkSystemClockContextWriter(SharedMemory& shared_memory)
|
||||
: SystemClockContextUpdateCallback{}, shared_memory{shared_memory} {}
|
||||
explicit NetworkSystemClockContextWriter(SharedMemory& shared_memory_)
|
||||
: SystemClockContextUpdateCallback{}, shared_memory{shared_memory_} {}
|
||||
|
||||
protected:
|
||||
ResultCode Update() override {
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace Service::Time::Clock {
|
||||
|
||||
class StandardLocalSystemClockCore final : public SystemClockCore {
|
||||
public:
|
||||
explicit StandardLocalSystemClockCore(SteadyClockCore& steady_clock_core)
|
||||
: SystemClockCore{steady_clock_core} {}
|
||||
explicit StandardLocalSystemClockCore(SteadyClockCore& steady_clock_core_)
|
||||
: SystemClockCore{steady_clock_core_} {}
|
||||
};
|
||||
|
||||
} // namespace Service::Time::Clock
|
||||
|
||||
@@ -16,21 +16,21 @@ namespace Service::Time::Clock {
|
||||
|
||||
class StandardNetworkSystemClockCore final : public SystemClockCore {
|
||||
public:
|
||||
explicit StandardNetworkSystemClockCore(SteadyClockCore& steady_clock_core)
|
||||
: SystemClockCore{steady_clock_core} {}
|
||||
explicit StandardNetworkSystemClockCore(SteadyClockCore& steady_clock_core_)
|
||||
: SystemClockCore{steady_clock_core_} {}
|
||||
|
||||
void SetStandardNetworkClockSufficientAccuracy(TimeSpanType value) {
|
||||
standard_network_clock_sufficient_accuracy = value;
|
||||
}
|
||||
|
||||
bool IsStandardNetworkSystemClockAccuracySufficient(Core::System& system) const {
|
||||
SystemClockContext context{};
|
||||
if (GetClockContext(system, context) != RESULT_SUCCESS) {
|
||||
SystemClockContext clock_ctx{};
|
||||
if (GetClockContext(system, clock_ctx) != RESULT_SUCCESS) {
|
||||
return {};
|
||||
}
|
||||
|
||||
s64 span{};
|
||||
if (context.steady_time_point.GetSpanBetween(
|
||||
if (clock_ctx.steady_time_point.GetSpanBetween(
|
||||
GetSteadyClockCore().GetCurrentTimePoint(system), span) != RESULT_SUCCESS) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@
|
||||
namespace Service::Time::Clock {
|
||||
|
||||
StandardUserSystemClockCore::StandardUserSystemClockCore(
|
||||
StandardLocalSystemClockCore& local_system_clock_core,
|
||||
StandardNetworkSystemClockCore& network_system_clock_core, Core::System& system)
|
||||
: SystemClockCore(local_system_clock_core.GetSteadyClockCore()),
|
||||
local_system_clock_core{local_system_clock_core},
|
||||
network_system_clock_core{network_system_clock_core}, auto_correction_enabled{},
|
||||
StandardLocalSystemClockCore& local_system_clock_core_,
|
||||
StandardNetworkSystemClockCore& network_system_clock_core_, Core::System& system_)
|
||||
: SystemClockCore(local_system_clock_core_.GetSteadyClockCore()),
|
||||
local_system_clock_core{local_system_clock_core_},
|
||||
network_system_clock_core{network_system_clock_core_},
|
||||
auto_correction_time{SteadyClockTimePoint::GetRandom()}, auto_correction_event{
|
||||
system.Kernel()} {
|
||||
system_.Kernel()} {
|
||||
Kernel::KAutoObject::Create(std::addressof(auto_correction_event));
|
||||
auto_correction_event.Initialize("StandardUserSystemClockCore:AutoCorrectionEvent");
|
||||
}
|
||||
@@ -35,13 +35,13 @@ ResultCode StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::Syst
|
||||
}
|
||||
|
||||
ResultCode StandardUserSystemClockCore::GetClockContext(Core::System& system,
|
||||
SystemClockContext& context) const {
|
||||
SystemClockContext& ctx) const {
|
||||
if (const ResultCode result{ApplyAutomaticCorrection(system, false)};
|
||||
result != RESULT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return local_system_clock_core.GetClockContext(system, context);
|
||||
return local_system_clock_core.GetClockContext(system, ctx);
|
||||
}
|
||||
|
||||
ResultCode StandardUserSystemClockCore::Flush(const SystemClockContext&) {
|
||||
@@ -64,13 +64,13 @@ ResultCode StandardUserSystemClockCore::ApplyAutomaticCorrection(Core::System& s
|
||||
return ERROR_UNINITIALIZED_CLOCK;
|
||||
}
|
||||
|
||||
SystemClockContext context{};
|
||||
if (const ResultCode result{network_system_clock_core.GetClockContext(system, context)};
|
||||
SystemClockContext ctx{};
|
||||
if (const ResultCode result{network_system_clock_core.GetClockContext(system, ctx)};
|
||||
result != RESULT_SUCCESS) {
|
||||
return result;
|
||||
}
|
||||
|
||||
local_system_clock_core.SetClockContext(context);
|
||||
local_system_clock_core.SetClockContext(ctx);
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -23,13 +23,13 @@ class StandardNetworkSystemClockCore;
|
||||
|
||||
class StandardUserSystemClockCore final : public SystemClockCore {
|
||||
public:
|
||||
StandardUserSystemClockCore(StandardLocalSystemClockCore& local_system_clock_core,
|
||||
StandardNetworkSystemClockCore& network_system_clock_core,
|
||||
Core::System& system);
|
||||
StandardUserSystemClockCore(StandardLocalSystemClockCore& local_system_clock_core_,
|
||||
StandardNetworkSystemClockCore& network_system_clock_core_,
|
||||
Core::System& system_);
|
||||
|
||||
ResultCode SetAutomaticCorrectionEnabled(Core::System& system, bool value);
|
||||
|
||||
ResultCode GetClockContext(Core::System& system, SystemClockContext& context) const override;
|
||||
ResultCode GetClockContext(Core::System& system, SystemClockContext& ctx) const override;
|
||||
|
||||
bool IsAutomaticCorrectionEnabled() const {
|
||||
return auto_correction_enabled;
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
namespace Service::Time::Clock {
|
||||
|
||||
SystemClockCore::SystemClockCore(SteadyClockCore& steady_clock_core)
|
||||
: steady_clock_core{steady_clock_core} {
|
||||
SystemClockCore::SystemClockCore(SteadyClockCore& steady_clock_core_)
|
||||
: steady_clock_core{steady_clock_core_} {
|
||||
context.steady_time_point.clock_source_id = steady_clock_core.GetClockSourceId();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ class SystemClockContextUpdateCallback;
|
||||
|
||||
class SystemClockCore {
|
||||
public:
|
||||
explicit SystemClockCore(SteadyClockCore& steady_clock_core);
|
||||
explicit SystemClockCore(SteadyClockCore& steady_clock_core_);
|
||||
virtual ~SystemClockCore();
|
||||
|
||||
SteadyClockCore& GetSteadyClockCore() const {
|
||||
|
||||
@@ -223,7 +223,7 @@ struct TimeManager::Impl final {
|
||||
TimeZone::TimeZoneContentManager time_zone_content_manager;
|
||||
};
|
||||
|
||||
TimeManager::TimeManager(Core::System& system) : system{system} {}
|
||||
TimeManager::TimeManager(Core::System& system_) : system{system_} {}
|
||||
|
||||
TimeManager::~TimeManager() = default;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class NetworkSystemClockContextWriter;
|
||||
|
||||
class TimeManager final {
|
||||
public:
|
||||
explicit TimeManager(Core::System& system);
|
||||
explicit TimeManager(Core::System& system_);
|
||||
~TimeManager();
|
||||
|
||||
void Initialize();
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace Service::Time {
|
||||
|
||||
static constexpr std::size_t SHARED_MEMORY_SIZE{0x1000};
|
||||
|
||||
SharedMemory::SharedMemory(Core::System& system) : system(system) {
|
||||
SharedMemory::SharedMemory(Core::System& system_) : system(system_) {
|
||||
std::memset(system.Kernel().GetTimeSharedMem().GetPointer(), 0, SHARED_MEMORY_SIZE);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace Service::Time {
|
||||
|
||||
class SharedMemory final {
|
||||
public:
|
||||
explicit SharedMemory(Core::System& system);
|
||||
explicit SharedMemory(Core::System& system_);
|
||||
~SharedMemory();
|
||||
|
||||
// TODO(ogniK): We have to properly simulate memory barriers, how are we going to do this?
|
||||
|
||||
@@ -68,8 +68,8 @@ static std::vector<std::string> BuildLocationNameCache(Core::System& system) {
|
||||
return location_name_cache;
|
||||
}
|
||||
|
||||
TimeZoneContentManager::TimeZoneContentManager(Core::System& system)
|
||||
: system{system}, location_name_cache{BuildLocationNameCache(system)} {}
|
||||
TimeZoneContentManager::TimeZoneContentManager(Core::System& system_)
|
||||
: system{system_}, location_name_cache{BuildLocationNameCache(system)} {}
|
||||
|
||||
void TimeZoneContentManager::Initialize(TimeManager& time_manager) {
|
||||
std::string location_name;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user