Compare commits
18
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1a5ef3a0d | ||
|
|
5299554bb0 | ||
|
|
494e34af6a | ||
|
|
ad8afaf1ef | ||
|
|
2686bf6734 | ||
|
|
33e92c15eb | ||
|
|
7461196839 | ||
|
|
b769bea61b | ||
|
|
b65314dc21 | ||
|
|
1841f63a40 | ||
|
|
b01aa721ff | ||
|
|
f190547bbb | ||
|
|
c82318c9cb | ||
|
|
c871320760 | ||
|
|
ef811c6425 | ||
|
|
abe6d39b1a | ||
|
|
60a3980561 | ||
|
|
d4cab35533 |
No files matched your search
+3
-2
@@ -411,12 +411,13 @@ if (CONAN_REQUIRED_LIBS)
|
||||
# Download conan.cmake automatically, you can also just copy the conan.cmake file
|
||||
if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
|
||||
message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
|
||||
file(DOWNLOAD "https://github.com/conan-io/cmake-conan/raw/v0.15/conan.cmake"
|
||||
# TODO: Use a tagged release. The latest tagged release does not support VS2022 as of this writing.
|
||||
file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/43e385830ee35377dbd2dcbe8d5a9e750301ea00/conan.cmake"
|
||||
"${CMAKE_BINARY_DIR}/conan.cmake")
|
||||
endif()
|
||||
include(${CMAKE_BINARY_DIR}/conan.cmake)
|
||||
|
||||
conan_check(VERSION 1.24.0 REQUIRED)
|
||||
conan_check(VERSION 1.41.0 REQUIRED)
|
||||
|
||||
# Manually add iconv to fix a dep conflict between qt and sdl2
|
||||
# We don't need to add it through find_package or anything since the other two can find it just fine
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
using propagate_on_container_copy_assignment = std::true_type;
|
||||
using propagate_on_container_move_assignment = std::true_type;
|
||||
using propagate_on_container_swap = std::true_type;
|
||||
using is_always_equal = std::true_type;
|
||||
using is_always_equal = std::false_type;
|
||||
|
||||
constexpr AlignmentAllocator() noexcept = default;
|
||||
|
||||
@@ -83,6 +83,11 @@ public:
|
||||
struct rebind {
|
||||
using other = AlignmentAllocator<T2, Align>;
|
||||
};
|
||||
|
||||
template <typename T2, size_t Align2>
|
||||
constexpr bool operator==(const AlignmentAllocator<T2, Align2>&) const noexcept {
|
||||
return std::is_same_v<T, T2> && Align == Align2;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Common
|
||||
@@ -7,7 +7,6 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
@@ -487,9 +486,9 @@ struct Values {
|
||||
// System
|
||||
Setting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"};
|
||||
// Measured in seconds since epoch
|
||||
std::optional<std::chrono::seconds> custom_rtc;
|
||||
std::optional<s64> custom_rtc;
|
||||
// Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
|
||||
std::chrono::seconds custom_rtc_differential;
|
||||
s64 custom_rtc_differential;
|
||||
|
||||
BasicSetting<s32> current_user{0, "current_user"};
|
||||
RangedSetting<s32> language_index{1, 0, 17, "language_index"};
|
||||
|
||||
+3
-2
@@ -196,8 +196,9 @@ struct System::Impl {
|
||||
cpu_manager.Initialize();
|
||||
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
|
||||
|
||||
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch());
|
||||
const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
|
||||
const auto current_time =
|
||||
std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
|
||||
Settings::values.custom_rtc_differential =
|
||||
Settings::values.custom_rtc.value_or(current_time) - current_time;
|
||||
|
||||
|
||||
@@ -13,18 +13,19 @@
|
||||
#include "core/hle/service/time/time_manager.h"
|
||||
|
||||
namespace Service::Time {
|
||||
|
||||
namespace {
|
||||
constexpr Clock::TimeSpanType standard_network_clock_accuracy{0x0009356907420000ULL};
|
||||
|
||||
static std::chrono::seconds GetSecondsSinceEpoch() {
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch()) +
|
||||
s64 GetSecondsSinceEpoch() {
|
||||
const auto time_since_epoch = std::chrono::system_clock::now().time_since_epoch();
|
||||
return std::chrono::duration_cast<std::chrono::seconds>(time_since_epoch).count() +
|
||||
Settings::values.custom_rtc_differential;
|
||||
}
|
||||
|
||||
static s64 GetExternalRtcValue() {
|
||||
return GetSecondsSinceEpoch().count() + TimeManager::GetExternalTimeZoneOffset();
|
||||
s64 GetExternalRtcValue() {
|
||||
return GetSecondsSinceEpoch() + TimeManager::GetExternalTimeZoneOffset();
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
struct TimeManager::Impl final {
|
||||
explicit Impl(Core::System& system)
|
||||
|
||||
@@ -471,46 +471,42 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
|
||||
std::function<void(u16, u16, u16, u16)> data_callback) {
|
||||
|
||||
std::thread([=, this] {
|
||||
constexpr u16 CALIBRATION_THRESHOLD = 100;
|
||||
|
||||
u16 min_x{UINT16_MAX};
|
||||
u16 min_y{UINT16_MAX};
|
||||
u16 max_x{};
|
||||
u16 max_y{};
|
||||
|
||||
Status current_status{Status::Initialized};
|
||||
SocketCallback callback{[](Response::Version) {}, [](Response::PortInfo) {},
|
||||
[&](Response::PadData data) {
|
||||
if (current_status == Status::Initialized) {
|
||||
// Receiving data means the communication is ready now
|
||||
current_status = Status::Ready;
|
||||
status_callback(current_status);
|
||||
}
|
||||
if (data.touch[0].is_active == 0) {
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG(Input, "Current touch: {} {}", data.touch[0].x,
|
||||
data.touch[0].y);
|
||||
min_x = std::min(min_x, static_cast<u16>(data.touch[0].x));
|
||||
min_y = std::min(min_y, static_cast<u16>(data.touch[0].y));
|
||||
if (current_status == Status::Ready) {
|
||||
// First touch - min data (min_x/min_y)
|
||||
current_status = Status::Stage1Completed;
|
||||
status_callback(current_status);
|
||||
}
|
||||
if (data.touch[0].x - min_x > CALIBRATION_THRESHOLD &&
|
||||
data.touch[0].y - min_y > CALIBRATION_THRESHOLD) {
|
||||
// Set the current position as max value and finishes
|
||||
// configuration
|
||||
max_x = data.touch[0].x;
|
||||
max_y = data.touch[0].y;
|
||||
current_status = Status::Completed;
|
||||
data_callback(min_x, min_y, max_x, max_y);
|
||||
status_callback(current_status);
|
||||
SocketCallback callback{
|
||||
[](Response::Version) {}, [](Response::PortInfo) {},
|
||||
[&](Response::PadData data) {
|
||||
static constexpr u16 CALIBRATION_THRESHOLD = 100;
|
||||
static constexpr u16 MAX_VALUE = UINT16_MAX;
|
||||
|
||||
complete_event.Set();
|
||||
}
|
||||
}};
|
||||
if (current_status == Status::Initialized) {
|
||||
// Receiving data means the communication is ready now
|
||||
current_status = Status::Ready;
|
||||
status_callback(current_status);
|
||||
}
|
||||
const auto& touchpad_0 = data.touch[0];
|
||||
if (touchpad_0.is_active == 0) {
|
||||
return;
|
||||
}
|
||||
LOG_DEBUG(Input, "Current touch: {} {}", touchpad_0.x, touchpad_0.y);
|
||||
const u16 min_x = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.x));
|
||||
const u16 min_y = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.y));
|
||||
if (current_status == Status::Ready) {
|
||||
// First touch - min data (min_x/min_y)
|
||||
current_status = Status::Stage1Completed;
|
||||
status_callback(current_status);
|
||||
}
|
||||
if (touchpad_0.x - min_x > CALIBRATION_THRESHOLD &&
|
||||
touchpad_0.y - min_y > CALIBRATION_THRESHOLD) {
|
||||
// Set the current position as max value and finishes configuration
|
||||
const u16 max_x = touchpad_0.x;
|
||||
const u16 max_y = touchpad_0.y;
|
||||
current_status = Status::Completed;
|
||||
data_callback(min_x, min_y, max_x, max_y);
|
||||
status_callback(current_status);
|
||||
|
||||
complete_event.Set();
|
||||
}
|
||||
}};
|
||||
Socket socket{host, port, std::move(callback)};
|
||||
std::thread worker_thread{SocketLoop, &socket};
|
||||
complete_event.Wait();
|
||||
|
||||
@@ -38,6 +38,9 @@ enum : u8 {
|
||||
|
||||
Shaders,
|
||||
|
||||
// Special entries
|
||||
DepthBiasGlobal,
|
||||
|
||||
LastCommonEntry,
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include "common/scope_exit.h"
|
||||
#include "video_core/dirty_flags.h"
|
||||
#include "video_core/engines/maxwell_3d.h"
|
||||
#include "video_core/macro/macro_hle.h"
|
||||
#include "video_core/rasterizer_interface.h"
|
||||
@@ -56,6 +58,7 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
|
||||
maxwell3d.regs.index_array.first = parameters[3];
|
||||
maxwell3d.regs.reg_array[0x446] = element_base; // vertex id base?
|
||||
maxwell3d.regs.index_array.count = parameters[1];
|
||||
maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
|
||||
maxwell3d.regs.vb_element_base = element_base;
|
||||
maxwell3d.regs.vb_base_instance = base_instance;
|
||||
maxwell3d.mme_draw.instance_count = instance_count;
|
||||
@@ -77,12 +80,70 @@ void HLE_0217920100488FF7(Engines::Maxwell3D& maxwell3d, const std::vector<u32>&
|
||||
maxwell3d.CallMethodFromMME(0x8e5, 0x0);
|
||||
maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
|
||||
}
|
||||
|
||||
// Multidraw Indirect
|
||||
void HLE_3f5e74b9c9a50164(Engines::Maxwell3D& maxwell3d, const std::vector<u32>& parameters) {
|
||||
SCOPE_EXIT({
|
||||
// Clean everything.
|
||||
maxwell3d.regs.reg_array[0x446] = 0x0; // vertex id base?
|
||||
maxwell3d.regs.index_array.count = 0;
|
||||
maxwell3d.regs.vb_element_base = 0x0;
|
||||
maxwell3d.regs.vb_base_instance = 0x0;
|
||||
maxwell3d.mme_draw.instance_count = 0;
|
||||
maxwell3d.CallMethodFromMME(0x8e3, 0x640);
|
||||
maxwell3d.CallMethodFromMME(0x8e4, 0x0);
|
||||
maxwell3d.CallMethodFromMME(0x8e5, 0x0);
|
||||
maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
|
||||
maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
|
||||
});
|
||||
const u32 start_indirect = parameters[0];
|
||||
const u32 end_indirect = parameters[1];
|
||||
if (start_indirect >= end_indirect) {
|
||||
// Nothing to do.
|
||||
return;
|
||||
}
|
||||
const auto topology =
|
||||
static_cast<Tegra::Engines::Maxwell3D::Regs::PrimitiveTopology>(parameters[2]);
|
||||
maxwell3d.regs.draw.topology.Assign(topology);
|
||||
const u32 padding = parameters[3];
|
||||
const std::size_t max_draws = parameters[4];
|
||||
|
||||
const u32 indirect_words = 5 + padding;
|
||||
const std::size_t first_draw = start_indirect;
|
||||
const std::size_t effective_draws = end_indirect - start_indirect;
|
||||
const std::size_t last_draw = start_indirect + std::min(effective_draws, max_draws);
|
||||
|
||||
for (std::size_t index = first_draw; index < last_draw; index++) {
|
||||
const std::size_t base = index * indirect_words + 5;
|
||||
const u32 num_vertices = parameters[base];
|
||||
const u32 instance_count = parameters[base + 1];
|
||||
const u32 first_index = parameters[base + 2];
|
||||
const u32 base_vertex = parameters[base + 3];
|
||||
const u32 base_instance = parameters[base + 4];
|
||||
maxwell3d.regs.index_array.first = first_index;
|
||||
maxwell3d.regs.reg_array[0x446] = base_vertex;
|
||||
maxwell3d.regs.index_array.count = num_vertices;
|
||||
maxwell3d.regs.vb_element_base = base_vertex;
|
||||
maxwell3d.regs.vb_base_instance = base_instance;
|
||||
maxwell3d.mme_draw.instance_count = instance_count;
|
||||
maxwell3d.CallMethodFromMME(0x8e3, 0x640);
|
||||
maxwell3d.CallMethodFromMME(0x8e4, base_vertex);
|
||||
maxwell3d.CallMethodFromMME(0x8e5, base_instance);
|
||||
maxwell3d.dirty.flags[VideoCommon::Dirty::IndexBuffer] = true;
|
||||
if (maxwell3d.ShouldExecute()) {
|
||||
maxwell3d.Rasterizer().Draw(true, true);
|
||||
}
|
||||
maxwell3d.mme_draw.current_mode = Engines::Maxwell3D::MMEDrawMode::Undefined;
|
||||
}
|
||||
}
|
||||
|
||||
} // Anonymous namespace
|
||||
|
||||
constexpr std::array<std::pair<u64, HLEFunction>, 3> hle_funcs{{
|
||||
constexpr std::array<std::pair<u64, HLEFunction>, 4> hle_funcs{{
|
||||
{0x771BB18C62444DA0, &HLE_771BB18C62444DA0},
|
||||
{0x0D61FC9FAAC9FCAD, &HLE_0D61FC9FAAC9FCAD},
|
||||
{0x0217920100488FF7, &HLE_0217920100488FF7},
|
||||
{0x3f5e74b9c9a50164, &HLE_3f5e74b9c9a50164},
|
||||
}};
|
||||
|
||||
HLEMacro::HLEMacro(Engines::Maxwell3D& maxwell3d_) : maxwell3d{maxwell3d_} {}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <span>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include <glad/glad.h>
|
||||
|
||||
@@ -627,9 +627,21 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {
|
||||
if (!state_tracker.TouchDepthBias()) {
|
||||
return;
|
||||
}
|
||||
scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp,
|
||||
float units = regs.polygon_offset_units / 2.0f;
|
||||
const bool is_d24 = regs.zeta.format == Tegra::DepthFormat::S8_UINT_Z24_UNORM ||
|
||||
regs.zeta.format == Tegra::DepthFormat::D24X8_UNORM ||
|
||||
regs.zeta.format == Tegra::DepthFormat::D24S8_UNORM ||
|
||||
regs.zeta.format == Tegra::DepthFormat::D24C8_UNORM;
|
||||
if (is_d24 && !device.SupportsD24DepthBuffer()) {
|
||||
// the base formulas can be obtained from here:
|
||||
// https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias
|
||||
const double rescale_factor =
|
||||
static_cast<double>(1ULL << (32 - 24)) / (static_cast<double>(0x1.ep+127));
|
||||
units = static_cast<float>(static_cast<double>(units) * rescale_factor);
|
||||
}
|
||||
scheduler.Record([constant = units, clamp = regs.polygon_offset_clamp,
|
||||
factor = regs.polygon_offset_factor](vk::CommandBuffer cmdbuf) {
|
||||
cmdbuf.SetDepthBias(constant, clamp, factor / 2.0f);
|
||||
cmdbuf.SetDepthBias(constant, clamp, factor);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ void SetupDirtyViewports(Tables& tables) {
|
||||
FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports);
|
||||
FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports);
|
||||
tables[0][OFF(viewport_transform_enabled)] = Viewports;
|
||||
tables[1][OFF(screen_y_control)] = Viewports;
|
||||
}
|
||||
|
||||
void SetupDirtyScissors(Tables& tables) {
|
||||
|
||||
@@ -79,7 +79,8 @@ public:
|
||||
}
|
||||
|
||||
bool TouchDepthBias() {
|
||||
return Exchange(Dirty::DepthBias, false);
|
||||
return Exchange(Dirty::DepthBias, false) ||
|
||||
Exchange(VideoCommon::Dirty::DepthBiasGlobal, false);
|
||||
}
|
||||
|
||||
bool TouchBlendConstants() {
|
||||
|
||||
@@ -221,6 +221,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
|
||||
BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
|
||||
}
|
||||
const ImageViewId depth_buffer_id = render_targets.depth_buffer_id;
|
||||
|
||||
PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
|
||||
|
||||
for (size_t index = 0; index < NUM_RT; ++index) {
|
||||
@@ -230,6 +231,8 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
|
||||
maxwell3d.regs.render_area.width,
|
||||
maxwell3d.regs.render_area.height,
|
||||
};
|
||||
|
||||
flags[Dirty::DepthBiasGlobal] = true;
|
||||
}
|
||||
|
||||
template <class P>
|
||||
|
||||
@@ -623,6 +623,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
|
||||
is_float16_supported = false;
|
||||
}
|
||||
|
||||
supports_d24_depth =
|
||||
IsFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT,
|
||||
VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, FormatType::Optimal);
|
||||
|
||||
graphics_queue = logical.GetQueue(graphics_family);
|
||||
present_queue = logical.GetQueue(present_family);
|
||||
}
|
||||
|
||||
@@ -332,6 +332,10 @@ public:
|
||||
return sets_per_pool;
|
||||
}
|
||||
|
||||
bool SupportsD24DepthBuffer() const {
|
||||
return supports_d24_depth;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Checks if the physical device is suitable.
|
||||
void CheckSuitability(bool requires_swapchain) const;
|
||||
@@ -425,6 +429,7 @@ private:
|
||||
bool has_broken_cube_compatibility{}; ///< Has broken cube compatiblity bit
|
||||
bool has_renderdoc{}; ///< Has RenderDoc attached
|
||||
bool has_nsight_graphics{}; ///< Has Nsight Graphics attached
|
||||
bool supports_d24_depth{}; ///< Supports D24 depth buffers.
|
||||
|
||||
// Telemetry parameters
|
||||
std::string vendor_name; ///< Device's driver name.
|
||||
|
||||
@@ -918,8 +918,7 @@ void Config::ReadSystemValues() {
|
||||
const auto custom_rtc_enabled =
|
||||
ReadSetting(QStringLiteral("custom_rtc_enabled"), false).toBool();
|
||||
if (custom_rtc_enabled) {
|
||||
Settings::values.custom_rtc =
|
||||
std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong());
|
||||
Settings::values.custom_rtc = ReadSetting(QStringLiteral("custom_rtc"), 0).toLongLong();
|
||||
} else {
|
||||
Settings::values.custom_rtc = std::nullopt;
|
||||
}
|
||||
@@ -1450,9 +1449,7 @@ void Config::SaveSystemValues() {
|
||||
WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(),
|
||||
false);
|
||||
WriteSetting(QStringLiteral("custom_rtc"),
|
||||
QVariant::fromValue<long long>(
|
||||
Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()),
|
||||
0);
|
||||
QVariant::fromValue<long long>(Settings::values.custom_rtc.value_or(0)), 0);
|
||||
}
|
||||
|
||||
WriteGlobalSetting(Settings::values.sound_index);
|
||||
|
||||
@@ -65,8 +65,7 @@ void ConfigureSystem::SetConfiguration() {
|
||||
QStringLiteral("%1")
|
||||
.arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'})
|
||||
.toUpper();
|
||||
const auto rtc_time = Settings::values.custom_rtc.value_or(
|
||||
std::chrono::seconds(QDateTime::currentSecsSinceEpoch()));
|
||||
const auto rtc_time = Settings::values.custom_rtc.value_or(QDateTime::currentSecsSinceEpoch());
|
||||
|
||||
ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value());
|
||||
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() &&
|
||||
@@ -75,7 +74,7 @@ void ConfigureSystem::SetConfiguration() {
|
||||
|
||||
ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value());
|
||||
ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value());
|
||||
ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count()));
|
||||
ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time));
|
||||
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue());
|
||||
@@ -108,10 +107,9 @@ void ConfigureSystem::ApplyConfiguration() {
|
||||
// to allow in-game time to be fast forwarded
|
||||
if (Settings::IsConfiguringGlobal()) {
|
||||
if (ui->custom_rtc_checkbox->isChecked()) {
|
||||
Settings::values.custom_rtc =
|
||||
std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch());
|
||||
Settings::values.custom_rtc = ui->custom_rtc_edit->dateTime().toSecsSinceEpoch();
|
||||
if (system.IsPoweredOn()) {
|
||||
const s64 posix_time{Settings::values.custom_rtc->count() +
|
||||
const s64 posix_time{*Settings::values.custom_rtc +
|
||||
Service::Time::TimeManager::GetExternalTimeZoneOffset()};
|
||||
system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);
|
||||
}
|
||||
|
||||
@@ -14,14 +14,14 @@
|
||||
<item row="0" column="0" colspan="4">
|
||||
<widget class="QLabel" name="label_1">
|
||||
<property name="text">
|
||||
<string>Reads controller input from scripts in the same format as TAS-nx scripts.<br/>For a more detailed explanation please consult the FAQ on the yuzu website.</string>
|
||||
<string><html><head/><body><p>Reads controller input from scripts in the same format as TAS-nx scripts.<br/>For a more detailed explanation, please consult the <a href="https://yuzu-emu.org/help/feature/tas/"><span style=" text-decoration: underline; color:#039be5;">help page</span></a> on the yuzu website.</p></body></html></string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" colspan="4">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (General -> Hotkeys).</string>
|
||||
<string>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -> General -> Hotkeys).</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
|
||||
@@ -412,8 +412,7 @@ void Config::ReadValues() {
|
||||
|
||||
const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false);
|
||||
if (custom_rtc_enabled) {
|
||||
Settings::values.custom_rtc =
|
||||
std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0));
|
||||
Settings::values.custom_rtc = sdl2_config->GetInteger("System", "custom_rtc", 0);
|
||||
} else {
|
||||
Settings::values.custom_rtc = std::nullopt;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user