summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/core.cpp15
-rw-r--r--src/core/core.h8
-rw-r--r--src/core/hle/service/bcat/backend/backend.cpp2
-rw-r--r--src/core/hle/service/time/time.cpp28
-rw-r--r--src/core/hle/service/time/time.h9
-rw-r--r--src/core/hle/service/time/time_manager.cpp359
-rw-r--r--src/core/hle/service/time/time_manager.h85
-rw-r--r--src/core/hle/service/time/time_zone_content_manager.cpp5
-rw-r--r--src/core/hle/service/time/time_zone_content_manager.h4
-rw-r--r--src/input_common/sdl/sdl_impl.cpp169
-rw-r--r--src/video_core/host_shaders/CMakeLists.txt17
-rw-r--r--src/video_core/host_shaders/StringShaderHeader.cmake2
-rw-r--r--src/yuzu/applets/controller.cpp2
-rw-r--r--src/yuzu/applets/profile_select.cpp9
-rw-r--r--src/yuzu/applets/profile_select.h1
-rw-r--r--src/yuzu/configuration/configure_system.cpp26
-rw-r--r--src/yuzu/main.cpp26
17 files changed, 454 insertions, 313 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 81e8cc338..fde2ccc09 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -40,6 +40,7 @@
40#include "core/hle/service/lm/manager.h" 40#include "core/hle/service/lm/manager.h"
41#include "core/hle/service/service.h" 41#include "core/hle/service/service.h"
42#include "core/hle/service/sm/sm.h" 42#include "core/hle/service/sm/sm.h"
43#include "core/hle/service/time/time_manager.h"
43#include "core/loader/loader.h" 44#include "core/loader/loader.h"
44#include "core/memory.h" 45#include "core/memory.h"
45#include "core/memory/cheat_engine.h" 46#include "core/memory/cheat_engine.h"
@@ -121,7 +122,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
121struct System::Impl { 122struct System::Impl {
122 explicit Impl(System& system) 123 explicit Impl(System& system)
123 : kernel{system}, fs_controller{system}, memory{system}, 124 : kernel{system}, fs_controller{system}, memory{system},
124 cpu_manager{system}, reporter{system}, applet_manager{system} {} 125 cpu_manager{system}, reporter{system}, applet_manager{system}, time_manager{system} {}
125 126
126 ResultStatus Run() { 127 ResultStatus Run() {
127 status = ResultStatus::Success; 128 status = ResultStatus::Success;
@@ -189,6 +190,9 @@ struct System::Impl {
189 return ResultStatus::ErrorVideoCore; 190 return ResultStatus::ErrorVideoCore;
190 } 191 }
191 192
193 // Initialize time manager, which must happen after kernel is created
194 time_manager.Initialize();
195
192 is_powered_on = true; 196 is_powered_on = true;
193 exit_lock = false; 197 exit_lock = false;
194 198
@@ -387,6 +391,7 @@ struct System::Impl {
387 /// Service State 391 /// Service State
388 Service::Glue::ARPManager arp_manager; 392 Service::Glue::ARPManager arp_manager;
389 Service::LM::Manager lm_manager{reporter}; 393 Service::LM::Manager lm_manager{reporter};
394 Service::Time::TimeManager time_manager;
390 395
391 /// Service manager 396 /// Service manager
392 std::shared_ptr<Service::SM::ServiceManager> service_manager; 397 std::shared_ptr<Service::SM::ServiceManager> service_manager;
@@ -717,6 +722,14 @@ const Service::LM::Manager& System::GetLogManager() const {
717 return impl->lm_manager; 722 return impl->lm_manager;
718} 723}
719 724
725Service::Time::TimeManager& System::GetTimeManager() {
726 return impl->time_manager;
727}
728
729const Service::Time::TimeManager& System::GetTimeManager() const {
730 return impl->time_manager;
731}
732
720void System::SetExitLock(bool locked) { 733void System::SetExitLock(bool locked) {
721 impl->exit_lock = locked; 734 impl->exit_lock = locked;
722} 735}
diff --git a/src/core/core.h b/src/core/core.h
index 27efe30bb..6db896bae 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -69,6 +69,10 @@ namespace SM {
69class ServiceManager; 69class ServiceManager;
70} // namespace SM 70} // namespace SM
71 71
72namespace Time {
73class TimeManager;
74} // namespace Time
75
72} // namespace Service 76} // namespace Service
73 77
74namespace Tegra { 78namespace Tegra {
@@ -361,6 +365,10 @@ public:
361 365
362 const Service::LM::Manager& GetLogManager() const; 366 const Service::LM::Manager& GetLogManager() const;
363 367
368 Service::Time::TimeManager& GetTimeManager();
369
370 const Service::Time::TimeManager& GetTimeManager() const;
371
364 void SetExitLock(bool locked); 372 void SetExitLock(bool locked);
365 373
366 bool GetExitLock() const; 374 bool GetExitLock() const;
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index def3410cc..174388445 100644
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -84,7 +84,7 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) {
84 84
85void ProgressServiceBackend::SignalUpdate() const { 85void ProgressServiceBackend::SignalUpdate() const {
86 if (need_hle_lock) { 86 if (need_hle_lock) {
87 std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); 87 std::lock_guard lock(HLE::g_hle_lock);
88 event.writable->Signal(); 88 event.writable->Signal();
89 } else { 89 } else {
90 event.writable->Signal(); 90 event.writable->Signal();
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp
index ee4fa4b48..7d0474e0b 100644
--- a/src/core/hle/service/time/time.cpp
+++ b/src/core/hle/service/time/time.cpp
@@ -10,6 +10,7 @@
10#include "core/hle/ipc_helpers.h" 10#include "core/hle/ipc_helpers.h"
11#include "core/hle/kernel/client_port.h" 11#include "core/hle/kernel/client_port.h"
12#include "core/hle/kernel/client_session.h" 12#include "core/hle/kernel/client_session.h"
13#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/scheduler.h" 14#include "core/hle/kernel/scheduler.h"
14#include "core/hle/service/time/interface.h" 15#include "core/hle/service/time/interface.h"
15#include "core/hle/service/time/time.h" 16#include "core/hle/service/time/time.h"
@@ -125,7 +126,7 @@ ResultCode Module::Interface::GetClockSnapshotFromSystemClockContextInternal(
125 Kernel::Thread* thread, Clock::SystemClockContext user_context, 126 Kernel::Thread* thread, Clock::SystemClockContext user_context,
126 Clock::SystemClockContext network_context, u8 type, Clock::ClockSnapshot& clock_snapshot) { 127 Clock::SystemClockContext network_context, u8 type, Clock::ClockSnapshot& clock_snapshot) {
127 128
128 auto& time_manager{module->GetTimeManager()}; 129 auto& time_manager{system.GetTimeManager()};
129 130
130 clock_snapshot.is_automatic_correction_enabled = 131 clock_snapshot.is_automatic_correction_enabled =
131 time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled(); 132 time_manager.GetStandardUserSystemClockCore().IsAutomaticCorrectionEnabled();
@@ -182,7 +183,7 @@ void Module::Interface::GetStandardUserSystemClock(Kernel::HLERequestContext& ct
182 LOG_DEBUG(Service_Time, "called"); 183 LOG_DEBUG(Service_Time, "called");
183 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 184 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
184 rb.Push(RESULT_SUCCESS); 185 rb.Push(RESULT_SUCCESS);
185 rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardUserSystemClockCore(), 186 rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardUserSystemClockCore(),
186 system); 187 system);
187} 188}
188 189
@@ -190,7 +191,7 @@ void Module::Interface::GetStandardNetworkSystemClock(Kernel::HLERequestContext&
190 LOG_DEBUG(Service_Time, "called"); 191 LOG_DEBUG(Service_Time, "called");
191 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 192 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
192 rb.Push(RESULT_SUCCESS); 193 rb.Push(RESULT_SUCCESS);
193 rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardNetworkSystemClockCore(), 194 rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardNetworkSystemClockCore(),
194 system); 195 system);
195} 196}
196 197
@@ -198,29 +199,28 @@ void Module::Interface::GetStandardSteadyClock(Kernel::HLERequestContext& ctx) {
198 LOG_DEBUG(Service_Time, "called"); 199 LOG_DEBUG(Service_Time, "called");
199 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 200 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
200 rb.Push(RESULT_SUCCESS); 201 rb.Push(RESULT_SUCCESS);
201 rb.PushIpcInterface<ISteadyClock>(module->GetTimeManager().GetStandardSteadyClockCore(), 202 rb.PushIpcInterface<ISteadyClock>(system.GetTimeManager().GetStandardSteadyClockCore(), system);
202 system);
203} 203}
204 204
205void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) { 205void Module::Interface::GetTimeZoneService(Kernel::HLERequestContext& ctx) {
206 LOG_DEBUG(Service_Time, "called"); 206 LOG_DEBUG(Service_Time, "called");
207 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 207 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
208 rb.Push(RESULT_SUCCESS); 208 rb.Push(RESULT_SUCCESS);
209 rb.PushIpcInterface<ITimeZoneService>(module->GetTimeManager().GetTimeZoneContentManager()); 209 rb.PushIpcInterface<ITimeZoneService>(system.GetTimeManager().GetTimeZoneContentManager());
210} 210}
211 211
212void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) { 212void Module::Interface::GetStandardLocalSystemClock(Kernel::HLERequestContext& ctx) {
213 LOG_DEBUG(Service_Time, "called"); 213 LOG_DEBUG(Service_Time, "called");
214 IPC::ResponseBuilder rb{ctx, 2, 0, 1}; 214 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
215 rb.Push(RESULT_SUCCESS); 215 rb.Push(RESULT_SUCCESS);
216 rb.PushIpcInterface<ISystemClock>(module->GetTimeManager().GetStandardLocalSystemClockCore(), 216 rb.PushIpcInterface<ISystemClock>(system.GetTimeManager().GetStandardLocalSystemClockCore(),
217 system); 217 system);
218} 218}
219 219
220void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient( 220void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient(
221 Kernel::HLERequestContext& ctx) { 221 Kernel::HLERequestContext& ctx) {
222 LOG_DEBUG(Service_Time, "called"); 222 LOG_DEBUG(Service_Time, "called");
223 auto& clock_core{module->GetTimeManager().GetStandardNetworkSystemClockCore()}; 223 auto& clock_core{system.GetTimeManager().GetStandardNetworkSystemClockCore()};
224 IPC::ResponseBuilder rb{ctx, 3}; 224 IPC::ResponseBuilder rb{ctx, 3};
225 rb.Push(RESULT_SUCCESS); 225 rb.Push(RESULT_SUCCESS);
226 rb.Push<u32>(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system)); 226 rb.Push<u32>(clock_core.IsStandardNetworkSystemClockAccuracySufficient(system));
@@ -229,7 +229,7 @@ void Module::Interface::IsStandardNetworkSystemClockAccuracySufficient(
229void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx) { 229void Module::Interface::CalculateMonotonicSystemClockBaseTimePoint(Kernel::HLERequestContext& ctx) {
230 LOG_DEBUG(Service_Time, "called"); 230 LOG_DEBUG(Service_Time, "called");
231 231
232 auto& steady_clock_core{module->GetTimeManager().GetStandardSteadyClockCore()}; 232 auto& steady_clock_core{system.GetTimeManager().GetStandardSteadyClockCore()};
233 if (!steady_clock_core.IsInitialized()) { 233 if (!steady_clock_core.IsInitialized()) {
234 IPC::ResponseBuilder rb{ctx, 2}; 234 IPC::ResponseBuilder rb{ctx, 2};
235 rb.Push(ERROR_UNINITIALIZED_CLOCK); 235 rb.Push(ERROR_UNINITIALIZED_CLOCK);
@@ -262,8 +262,8 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
262 262
263 Clock::SystemClockContext user_context{}; 263 Clock::SystemClockContext user_context{};
264 if (const ResultCode result{ 264 if (const ResultCode result{
265 module->GetTimeManager().GetStandardUserSystemClockCore().GetClockContext( 265 system.GetTimeManager().GetStandardUserSystemClockCore().GetClockContext(system,
266 system, user_context)}; 266 user_context)};
267 result.IsError()) { 267 result.IsError()) {
268 IPC::ResponseBuilder rb{ctx, 2}; 268 IPC::ResponseBuilder rb{ctx, 2};
269 rb.Push(result); 269 rb.Push(result);
@@ -271,7 +271,7 @@ void Module::Interface::GetClockSnapshot(Kernel::HLERequestContext& ctx) {
271 } 271 }
272 Clock::SystemClockContext network_context{}; 272 Clock::SystemClockContext network_context{};
273 if (const ResultCode result{ 273 if (const ResultCode result{
274 module->GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext( 274 system.GetTimeManager().GetStandardNetworkSystemClockCore().GetClockContext(
275 system, network_context)}; 275 system, network_context)};
276 result.IsError()) { 276 result.IsError()) {
277 IPC::ResponseBuilder rb{ctx, 2}; 277 IPC::ResponseBuilder rb{ctx, 2};
@@ -372,7 +372,7 @@ void Module::Interface::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& c
372 LOG_DEBUG(Service_Time, "called"); 372 LOG_DEBUG(Service_Time, "called");
373 IPC::ResponseBuilder rb{ctx, 2, 1}; 373 IPC::ResponseBuilder rb{ctx, 2, 1};
374 rb.Push(RESULT_SUCCESS); 374 rb.Push(RESULT_SUCCESS);
375 rb.PushCopyObjects(module->GetTimeManager().GetSharedMemory().GetSharedMemoryHolder()); 375 rb.PushCopyObjects(SharedFrom(&system.Kernel().GetTimeSharedMem()));
376} 376}
377 377
378Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name) 378Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& system, const char* name)
@@ -381,7 +381,7 @@ Module::Interface::Interface(std::shared_ptr<Module> module, Core::System& syste
381Module::Interface::~Interface() = default; 381Module::Interface::~Interface() = default;
382 382
383void InstallInterfaces(Core::System& system) { 383void InstallInterfaces(Core::System& system) {
384 auto module{std::make_shared<Module>(system)}; 384 auto module{std::make_shared<Module>()};
385 std::make_shared<Time>(module, system, "time:a")->InstallAsService(system.ServiceManager()); 385 std::make_shared<Time>(module, system, "time:a")->InstallAsService(system.ServiceManager());
386 std::make_shared<Time>(module, system, "time:s")->InstallAsService(system.ServiceManager()); 386 std::make_shared<Time>(module, system, "time:s")->InstallAsService(system.ServiceManager());
387 std::make_shared<Time>(module, system, "time:u")->InstallAsService(system.ServiceManager()); 387 std::make_shared<Time>(module, system, "time:u")->InstallAsService(system.ServiceManager());
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index 41f3002e9..49f4aac0a 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -16,7 +16,7 @@ namespace Service::Time {
16 16
17class Module final { 17class Module final {
18public: 18public:
19 Module(Core::System& system) : time_manager{system} {} 19 Module() = default;
20 20
21 class Interface : public ServiceFramework<Interface> { 21 class Interface : public ServiceFramework<Interface> {
22 public: 22 public:
@@ -46,13 +46,6 @@ public:
46 std::shared_ptr<Module> module; 46 std::shared_ptr<Module> module;
47 Core::System& system; 47 Core::System& system;
48 }; 48 };
49
50 TimeManager& GetTimeManager() {
51 return time_manager;
52 }
53
54private:
55 TimeManager time_manager;
56}; 49};
57 50
58/// Registers all Time services with the specified service manager. 51/// Registers all Time services with the specified service manager.
diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp
index b4dfe45e5..858623e2b 100644
--- a/src/core/hle/service/time/time_manager.cpp
+++ b/src/core/hle/service/time/time_manager.cpp
@@ -22,125 +22,282 @@ static std::chrono::seconds GetSecondsSinceEpoch() {
22 Settings::values.custom_rtc_differential; 22 Settings::values.custom_rtc_differential;
23} 23}
24 24
25static s64 GetExternalTimeZoneOffset() {
26 // With "auto" timezone setting, we use the external system's timezone offset
27 if (Settings::GetTimeZoneString() == "auto") {
28 return Common::TimeZone::GetCurrentOffsetSeconds().count();
29 }
30 return 0;
31}
32
33static s64 GetExternalRtcValue() { 25static s64 GetExternalRtcValue() {
34 return GetSecondsSinceEpoch().count() + GetExternalTimeZoneOffset(); 26 return GetSecondsSinceEpoch().count() + TimeManager::GetExternalTimeZoneOffset();
35}
36
37TimeManager::TimeManager(Core::System& system)
38 : shared_memory{system}, standard_local_system_clock_core{standard_steady_clock_core},
39 standard_network_system_clock_core{standard_steady_clock_core},
40 standard_user_system_clock_core{standard_local_system_clock_core,
41 standard_network_system_clock_core, system},
42 ephemeral_network_system_clock_core{tick_based_steady_clock_core},
43 local_system_clock_context_writer{
44 std::make_shared<Clock::LocalSystemClockContextWriter>(shared_memory)},
45 network_system_clock_context_writer{
46 std::make_shared<Clock::NetworkSystemClockContextWriter>(shared_memory)},
47 ephemeral_network_system_clock_context_writer{
48 std::make_shared<Clock::EphemeralNetworkSystemClockContextWriter>()},
49 time_zone_content_manager{*this, system} {
50
51 const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())};
52 SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {});
53 SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds());
54 SetupStandardNetworkSystemClock({}, standard_network_clock_accuracy);
55 SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom());
56 SetupEphemeralNetworkSystemClock();
57} 27}
58 28
59TimeManager::~TimeManager() = default; 29struct TimeManager::Impl final {
30 explicit Impl(Core::System& system)
31 : shared_memory{system}, standard_local_system_clock_core{standard_steady_clock_core},
32 standard_network_system_clock_core{standard_steady_clock_core},
33 standard_user_system_clock_core{standard_local_system_clock_core,
34 standard_network_system_clock_core, system},
35 ephemeral_network_system_clock_core{tick_based_steady_clock_core},
36 local_system_clock_context_writer{
37 std::make_shared<Clock::LocalSystemClockContextWriter>(shared_memory)},
38 network_system_clock_context_writer{
39 std::make_shared<Clock::NetworkSystemClockContextWriter>(shared_memory)},
40 ephemeral_network_system_clock_context_writer{
41 std::make_shared<Clock::EphemeralNetworkSystemClockContextWriter>()},
42 time_zone_content_manager{system} {
60 43
61void TimeManager::SetupTimeZoneManager(std::string location_name, 44 const auto system_time{Clock::TimeSpanType::FromSeconds(GetExternalRtcValue())};
62 Clock::SteadyClockTimePoint time_zone_updated_time_point, 45 SetupStandardSteadyClock(system, Common::UUID::Generate(), system_time, {}, {});
63 std::size_t total_location_name_count, 46 SetupStandardLocalSystemClock(system, {}, system_time.ToSeconds());
64 u128 time_zone_rule_version, 47 SetupStandardNetworkSystemClock({}, standard_network_clock_accuracy);
65 FileSys::VirtualFile& vfs_file) { 48 SetupStandardUserSystemClock(system, {}, Clock::SteadyClockTimePoint::GetRandom());
66 if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule( 49 SetupEphemeralNetworkSystemClock();
67 location_name, vfs_file) != RESULT_SUCCESS) { 50 }
68 UNREACHABLE(); 51
69 return; 52 ~Impl() = default;
70 } 53
71 54 Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() {
72 time_zone_content_manager.GetTimeZoneManager().SetUpdatedTime(time_zone_updated_time_point); 55 return standard_steady_clock_core;
73 time_zone_content_manager.GetTimeZoneManager().SetTotalLocationNameCount( 56 }
74 total_location_name_count); 57
75 time_zone_content_manager.GetTimeZoneManager().SetTimeZoneRuleVersion(time_zone_rule_version); 58 const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const {
76 time_zone_content_manager.GetTimeZoneManager().MarkAsInitialized(); 59 return standard_steady_clock_core;
77} 60 }
78 61
79void TimeManager::SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id, 62 Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() {
80 Clock::TimeSpanType setup_value, 63 return standard_local_system_clock_core;
81 Clock::TimeSpanType internal_offset, 64 }
82 bool is_rtc_reset_detected) { 65
83 standard_steady_clock_core.SetClockSourceId(clock_source_id); 66 const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const {
84 standard_steady_clock_core.SetSetupValue(setup_value); 67 return standard_local_system_clock_core;
85 standard_steady_clock_core.SetInternalOffset(internal_offset); 68 }
86 standard_steady_clock_core.MarkAsInitialized(); 69
87 70 Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() {
88 const auto current_time_point{standard_steady_clock_core.GetCurrentRawTimePoint(system)}; 71 return standard_network_system_clock_core;
89 shared_memory.SetupStandardSteadyClock(system, clock_source_id, current_time_point); 72 }
90} 73
91 74 const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const {
92void TimeManager::SetupStandardLocalSystemClock(Core::System& system, 75 return standard_network_system_clock_core;
93 Clock::SystemClockContext clock_context, 76 }
94 s64 posix_time) { 77
95 standard_local_system_clock_core.SetUpdateCallbackInstance(local_system_clock_context_writer); 78 Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() {
96 79 return standard_user_system_clock_core;
97 const auto current_time_point{ 80 }
98 standard_local_system_clock_core.GetSteadyClockCore().GetCurrentTimePoint(system)}; 81
99 if (current_time_point.clock_source_id == clock_context.steady_time_point.clock_source_id) { 82 const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const {
100 standard_local_system_clock_core.SetSystemClockContext(clock_context); 83 return standard_user_system_clock_core;
101 } else { 84 }
102 if (standard_local_system_clock_core.SetCurrentTime(system, posix_time) != RESULT_SUCCESS) { 85
86 TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() {
87 return time_zone_content_manager;
88 }
89
90 const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const {
91 return time_zone_content_manager;
92 }
93
94 SharedMemory& GetSharedMemory() {
95 return shared_memory;
96 }
97
98 const SharedMemory& GetSharedMemory() const {
99 return shared_memory;
100 }
101
102 void SetupTimeZoneManager(std::string location_name,
103 Clock::SteadyClockTimePoint time_zone_updated_time_point,
104 std::size_t total_location_name_count, u128 time_zone_rule_version,
105 FileSys::VirtualFile& vfs_file) {
106 if (time_zone_content_manager.GetTimeZoneManager().SetDeviceLocationNameWithTimeZoneRule(
107 location_name, vfs_file) != RESULT_SUCCESS) {
103 UNREACHABLE(); 108 UNREACHABLE();
104 return; 109 return;
105 } 110 }
111
112 time_zone_content_manager.GetTimeZoneManager().SetUpdatedTime(time_zone_updated_time_point);
113 time_zone_content_manager.GetTimeZoneManager().SetTotalLocationNameCount(
114 total_location_name_count);
115 time_zone_content_manager.GetTimeZoneManager().SetTimeZoneRuleVersion(
116 time_zone_rule_version);
117 time_zone_content_manager.GetTimeZoneManager().MarkAsInitialized();
106 } 118 }
107 119
108 standard_local_system_clock_core.MarkAsInitialized(); 120 static s64 GetExternalTimeZoneOffset() {
109} 121 // With "auto" timezone setting, we use the external system's timezone offset
122 if (Settings::GetTimeZoneString() == "auto") {
123 return Common::TimeZone::GetCurrentOffsetSeconds().count();
124 }
125 return 0;
126 }
110 127
111void TimeManager::SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context, 128 void SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id,
112 Clock::TimeSpanType sufficient_accuracy) { 129 Clock::TimeSpanType setup_value,
113 standard_network_system_clock_core.SetUpdateCallbackInstance( 130 Clock::TimeSpanType internal_offset, bool is_rtc_reset_detected) {
114 network_system_clock_context_writer); 131 standard_steady_clock_core.SetClockSourceId(clock_source_id);
132 standard_steady_clock_core.SetSetupValue(setup_value);
133 standard_steady_clock_core.SetInternalOffset(internal_offset);
134 standard_steady_clock_core.MarkAsInitialized();
115 135
116 if (standard_network_system_clock_core.SetSystemClockContext(clock_context) != RESULT_SUCCESS) { 136 const auto current_time_point{standard_steady_clock_core.GetCurrentRawTimePoint(system)};
117 UNREACHABLE(); 137 shared_memory.SetupStandardSteadyClock(system, clock_source_id, current_time_point);
118 return;
119 } 138 }
120 139
121 standard_network_system_clock_core.SetStandardNetworkClockSufficientAccuracy( 140 void SetupStandardLocalSystemClock(Core::System& system,
122 sufficient_accuracy); 141 Clock::SystemClockContext clock_context, s64 posix_time) {
123 standard_network_system_clock_core.MarkAsInitialized(); 142 standard_local_system_clock_core.SetUpdateCallbackInstance(
124} 143 local_system_clock_context_writer);
144
145 const auto current_time_point{
146 standard_local_system_clock_core.GetSteadyClockCore().GetCurrentTimePoint(system)};
147 if (current_time_point.clock_source_id == clock_context.steady_time_point.clock_source_id) {
148 standard_local_system_clock_core.SetSystemClockContext(clock_context);
149 } else {
150 if (standard_local_system_clock_core.SetCurrentTime(system, posix_time) !=
151 RESULT_SUCCESS) {
152 UNREACHABLE();
153 return;
154 }
155 }
156
157 standard_local_system_clock_core.MarkAsInitialized();
158 }
159
160 void SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context,
161 Clock::TimeSpanType sufficient_accuracy) {
162 standard_network_system_clock_core.SetUpdateCallbackInstance(
163 network_system_clock_context_writer);
125 164
126void TimeManager::SetupStandardUserSystemClock( 165 if (standard_network_system_clock_core.SetSystemClockContext(clock_context) !=
127 Core::System& system, bool is_automatic_correction_enabled, 166 RESULT_SUCCESS) {
128 Clock::SteadyClockTimePoint steady_clock_time_point) { 167 UNREACHABLE();
129 if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled( 168 return;
130 system, is_automatic_correction_enabled) != RESULT_SUCCESS) { 169 }
131 UNREACHABLE(); 170
132 return; 171 standard_network_system_clock_core.SetStandardNetworkClockSufficientAccuracy(
172 sufficient_accuracy);
173 standard_network_system_clock_core.MarkAsInitialized();
133 } 174 }
134 175
135 standard_user_system_clock_core.SetAutomaticCorrectionUpdatedTime(steady_clock_time_point); 176 void SetupStandardUserSystemClock(Core::System& system, bool is_automatic_correction_enabled,
136 standard_user_system_clock_core.MarkAsInitialized(); 177 Clock::SteadyClockTimePoint steady_clock_time_point) {
137 shared_memory.SetAutomaticCorrectionEnabled(is_automatic_correction_enabled); 178 if (standard_user_system_clock_core.SetAutomaticCorrectionEnabled(
179 system, is_automatic_correction_enabled) != RESULT_SUCCESS) {
180 UNREACHABLE();
181 return;
182 }
183
184 standard_user_system_clock_core.SetAutomaticCorrectionUpdatedTime(steady_clock_time_point);
185 standard_user_system_clock_core.MarkAsInitialized();
186 shared_memory.SetAutomaticCorrectionEnabled(is_automatic_correction_enabled);
187 }
188
189 void SetupEphemeralNetworkSystemClock() {
190 ephemeral_network_system_clock_core.SetUpdateCallbackInstance(
191 ephemeral_network_system_clock_context_writer);
192 ephemeral_network_system_clock_core.MarkAsInitialized();
193 }
194
195 void UpdateLocalSystemClockTime(Core::System& system, s64 posix_time) {
196 const auto timespan{Service::Time::Clock::TimeSpanType::FromSeconds(posix_time)};
197 if (GetStandardLocalSystemClockCore()
198 .SetCurrentTime(system, timespan.ToSeconds())
199 .IsError()) {
200 UNREACHABLE();
201 return;
202 }
203 }
204
205 SharedMemory shared_memory;
206
207 Clock::StandardSteadyClockCore standard_steady_clock_core;
208 Clock::TickBasedSteadyClockCore tick_based_steady_clock_core;
209 Clock::StandardLocalSystemClockCore standard_local_system_clock_core;
210 Clock::StandardNetworkSystemClockCore standard_network_system_clock_core;
211 Clock::StandardUserSystemClockCore standard_user_system_clock_core;
212 Clock::EphemeralNetworkSystemClockCore ephemeral_network_system_clock_core;
213
214 std::shared_ptr<Clock::LocalSystemClockContextWriter> local_system_clock_context_writer;
215 std::shared_ptr<Clock::NetworkSystemClockContextWriter> network_system_clock_context_writer;
216 std::shared_ptr<Clock::EphemeralNetworkSystemClockContextWriter>
217 ephemeral_network_system_clock_context_writer;
218
219 TimeZone::TimeZoneContentManager time_zone_content_manager;
220};
221
222TimeManager::TimeManager(Core::System& system) : system{system} {}
223
224TimeManager::~TimeManager() = default;
225
226void TimeManager::Initialize() {
227 impl = std::make_unique<Impl>(system);
228
229 // Time zones can only be initialized after impl is valid
230 impl->time_zone_content_manager.Initialize(*this);
231}
232
233Clock::StandardSteadyClockCore& TimeManager::GetStandardSteadyClockCore() {
234 return impl->standard_steady_clock_core;
235}
236
237const Clock::StandardSteadyClockCore& TimeManager::GetStandardSteadyClockCore() const {
238 return impl->standard_steady_clock_core;
239}
240
241Clock::StandardLocalSystemClockCore& TimeManager::GetStandardLocalSystemClockCore() {
242 return impl->standard_local_system_clock_core;
243}
244
245const Clock::StandardLocalSystemClockCore& TimeManager::GetStandardLocalSystemClockCore() const {
246 return impl->standard_local_system_clock_core;
247}
248
249Clock::StandardNetworkSystemClockCore& TimeManager::GetStandardNetworkSystemClockCore() {
250 return impl->standard_network_system_clock_core;
138} 251}
139 252
140void TimeManager::SetupEphemeralNetworkSystemClock() { 253const Clock::StandardNetworkSystemClockCore& TimeManager::GetStandardNetworkSystemClockCore()
141 ephemeral_network_system_clock_core.SetUpdateCallbackInstance( 254 const {
142 ephemeral_network_system_clock_context_writer); 255 return impl->standard_network_system_clock_core;
143 ephemeral_network_system_clock_core.MarkAsInitialized(); 256}
257
258Clock::StandardUserSystemClockCore& TimeManager::GetStandardUserSystemClockCore() {
259 return impl->standard_user_system_clock_core;
260}
261
262const Clock::StandardUserSystemClockCore& TimeManager::GetStandardUserSystemClockCore() const {
263 return impl->standard_user_system_clock_core;
264}
265
266TimeZone::TimeZoneContentManager& TimeManager::GetTimeZoneContentManager() {
267 return impl->time_zone_content_manager;
268}
269
270const TimeZone::TimeZoneContentManager& TimeManager::GetTimeZoneContentManager() const {
271 return impl->time_zone_content_manager;
272}
273
274SharedMemory& TimeManager::GetSharedMemory() {
275 return impl->shared_memory;
276}
277
278const SharedMemory& TimeManager::GetSharedMemory() const {
279 return impl->shared_memory;
280}
281
282void TimeManager::UpdateLocalSystemClockTime(s64 posix_time) {
283 impl->UpdateLocalSystemClockTime(system, posix_time);
284}
285
286void TimeManager::SetupTimeZoneManager(std::string location_name,
287 Clock::SteadyClockTimePoint time_zone_updated_time_point,
288 std::size_t total_location_name_count,
289 u128 time_zone_rule_version,
290 FileSys::VirtualFile& vfs_file) {
291 impl->SetupTimeZoneManager(location_name, time_zone_updated_time_point,
292 total_location_name_count, time_zone_rule_version, vfs_file);
293}
294
295/*static*/ s64 TimeManager::GetExternalTimeZoneOffset() {
296 // With "auto" timezone setting, we use the external system's timezone offset
297 if (Settings::GetTimeZoneString() == "auto") {
298 return Common::TimeZone::GetCurrentOffsetSeconds().count();
299 }
300 return 0;
144} 301}
145 302
146} // namespace Service::Time 303} // namespace Service::Time
diff --git a/src/core/hle/service/time/time_manager.h b/src/core/hle/service/time/time_manager.h
index 8e65f0d22..993c7c288 100644
--- a/src/core/hle/service/time/time_manager.h
+++ b/src/core/hle/service/time/time_manager.h
@@ -5,6 +5,7 @@
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "common/common_types.h"
8#include "common/time_zone.h"
8#include "core/file_sys/vfs_types.h" 9#include "core/file_sys/vfs_types.h"
9#include "core/hle/service/time/clock_types.h" 10#include "core/hle/service/time/clock_types.h"
10#include "core/hle/service/time/ephemeral_network_system_clock_core.h" 11#include "core/hle/service/time/ephemeral_network_system_clock_core.h"
@@ -32,86 +33,46 @@ public:
32 explicit TimeManager(Core::System& system); 33 explicit TimeManager(Core::System& system);
33 ~TimeManager(); 34 ~TimeManager();
34 35
35 Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() { 36 void Initialize();
36 return standard_steady_clock_core;
37 }
38 37
39 const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const { 38 Clock::StandardSteadyClockCore& GetStandardSteadyClockCore();
40 return standard_steady_clock_core;
41 }
42 39
43 Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() { 40 const Clock::StandardSteadyClockCore& GetStandardSteadyClockCore() const;
44 return standard_local_system_clock_core;
45 }
46 41
47 const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const { 42 Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore();
48 return standard_local_system_clock_core;
49 }
50 43
51 Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() { 44 const Clock::StandardLocalSystemClockCore& GetStandardLocalSystemClockCore() const;
52 return standard_network_system_clock_core;
53 }
54 45
55 const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const { 46 Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore();
56 return standard_network_system_clock_core;
57 }
58 47
59 Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() { 48 const Clock::StandardNetworkSystemClockCore& GetStandardNetworkSystemClockCore() const;
60 return standard_user_system_clock_core;
61 }
62 49
63 const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const { 50 Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore();
64 return standard_user_system_clock_core;
65 }
66 51
67 TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() { 52 const Clock::StandardUserSystemClockCore& GetStandardUserSystemClockCore() const;
68 return time_zone_content_manager;
69 }
70 53
71 const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const { 54 TimeZone::TimeZoneContentManager& GetTimeZoneContentManager();
72 return time_zone_content_manager;
73 }
74 55
75 SharedMemory& GetSharedMemory() { 56 const TimeZone::TimeZoneContentManager& GetTimeZoneContentManager() const;
76 return shared_memory;
77 }
78 57
79 const SharedMemory& GetSharedMemory() const { 58 void UpdateLocalSystemClockTime(s64 posix_time);
80 return shared_memory; 59
81 } 60 SharedMemory& GetSharedMemory();
61
62 const SharedMemory& GetSharedMemory() const;
82 63
83 void SetupTimeZoneManager(std::string location_name, 64 void SetupTimeZoneManager(std::string location_name,
84 Clock::SteadyClockTimePoint time_zone_updated_time_point, 65 Clock::SteadyClockTimePoint time_zone_updated_time_point,
85 std::size_t total_location_name_count, u128 time_zone_rule_version, 66 std::size_t total_location_name_count, u128 time_zone_rule_version,
86 FileSys::VirtualFile& vfs_file); 67 FileSys::VirtualFile& vfs_file);
87 68
69 static s64 GetExternalTimeZoneOffset();
70
88private: 71private:
89 void SetupStandardSteadyClock(Core::System& system, Common::UUID clock_source_id, 72 Core::System& system;
90 Clock::TimeSpanType setup_value, 73
91 Clock::TimeSpanType internal_offset, bool is_rtc_reset_detected); 74 struct Impl;
92 void SetupStandardLocalSystemClock(Core::System& system, 75 std::unique_ptr<Impl> impl;
93 Clock::SystemClockContext clock_context, s64 posix_time);
94 void SetupStandardNetworkSystemClock(Clock::SystemClockContext clock_context,
95 Clock::TimeSpanType sufficient_accuracy);
96 void SetupStandardUserSystemClock(Core::System& system, bool is_automatic_correction_enabled,
97 Clock::SteadyClockTimePoint steady_clock_time_point);
98 void SetupEphemeralNetworkSystemClock();
99
100 SharedMemory shared_memory;
101
102 Clock::StandardSteadyClockCore standard_steady_clock_core;
103 Clock::TickBasedSteadyClockCore tick_based_steady_clock_core;
104 Clock::StandardLocalSystemClockCore standard_local_system_clock_core;
105 Clock::StandardNetworkSystemClockCore standard_network_system_clock_core;
106 Clock::StandardUserSystemClockCore standard_user_system_clock_core;
107 Clock::EphemeralNetworkSystemClockCore ephemeral_network_system_clock_core;
108
109 std::shared_ptr<Clock::LocalSystemClockContextWriter> local_system_clock_context_writer;
110 std::shared_ptr<Clock::NetworkSystemClockContextWriter> network_system_clock_context_writer;
111 std::shared_ptr<Clock::EphemeralNetworkSystemClockContextWriter>
112 ephemeral_network_system_clock_context_writer;
113
114 TimeZone::TimeZoneContentManager time_zone_content_manager;
115}; 76};
116 77
117} // namespace Service::Time 78} // namespace Service::Time
diff --git a/src/core/hle/service/time/time_zone_content_manager.cpp b/src/core/hle/service/time/time_zone_content_manager.cpp
index 320672add..4177d0a41 100644
--- a/src/core/hle/service/time/time_zone_content_manager.cpp
+++ b/src/core/hle/service/time/time_zone_content_manager.cpp
@@ -68,9 +68,10 @@ static std::vector<std::string> BuildLocationNameCache(Core::System& system) {
68 return location_name_cache; 68 return location_name_cache;
69} 69}
70 70
71TimeZoneContentManager::TimeZoneContentManager(TimeManager& time_manager, Core::System& system) 71TimeZoneContentManager::TimeZoneContentManager(Core::System& system)
72 : system{system}, location_name_cache{BuildLocationNameCache(system)} { 72 : system{system}, location_name_cache{BuildLocationNameCache(system)} {}
73 73
74void TimeZoneContentManager::Initialize(TimeManager& time_manager) {
74 std::string location_name; 75 std::string location_name;
75 const auto timezone_setting = Settings::GetTimeZoneString(); 76 const auto timezone_setting = Settings::GetTimeZoneString();
76 if (timezone_setting == "auto" || timezone_setting == "default") { 77 if (timezone_setting == "auto" || timezone_setting == "default") {
diff --git a/src/core/hle/service/time/time_zone_content_manager.h b/src/core/hle/service/time/time_zone_content_manager.h
index 4f302c3b9..02bbbadac 100644
--- a/src/core/hle/service/time/time_zone_content_manager.h
+++ b/src/core/hle/service/time/time_zone_content_manager.h
@@ -21,7 +21,9 @@ namespace Service::Time::TimeZone {
21 21
22class TimeZoneContentManager final { 22class TimeZoneContentManager final {
23public: 23public:
24 TimeZoneContentManager(TimeManager& time_manager, Core::System& system); 24 TimeZoneContentManager(Core::System& system);
25
26 void Initialize(TimeManager& time_manager);
25 27
26 TimeZoneManager& GetTimeZoneManager() { 28 TimeZoneManager& GetTimeZoneManager() {
27 return time_zone_manager; 29 return time_zone_manager;
diff --git a/src/input_common/sdl/sdl_impl.cpp b/src/input_common/sdl/sdl_impl.cpp
index 9c3035920..10883e2d9 100644
--- a/src/input_common/sdl/sdl_impl.cpp
+++ b/src/input_common/sdl/sdl_impl.cpp
@@ -155,15 +155,15 @@ public:
155 return sdl_joystick.get(); 155 return sdl_joystick.get();
156 } 156 }
157 157
158 void SetSDLJoystick(SDL_Joystick* joystick, SDL_GameController* controller) {
159 sdl_controller.reset(controller);
160 sdl_joystick.reset(joystick);
161 }
162
163 SDL_GameController* GetSDLGameController() const { 158 SDL_GameController* GetSDLGameController() const {
164 return sdl_controller.get(); 159 return sdl_controller.get();
165 } 160 }
166 161
162 void SetSDLJoystick(SDL_Joystick* joystick, SDL_GameController* controller) {
163 sdl_joystick.reset(joystick);
164 sdl_controller.reset(controller);
165 }
166
167private: 167private:
168 struct State { 168 struct State {
169 std::unordered_map<int, bool> buttons; 169 std::unordered_map<int, bool> buttons;
@@ -186,69 +186,58 @@ private:
186std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& guid, int port) { 186std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickByGUID(const std::string& guid, int port) {
187 std::lock_guard lock{joystick_map_mutex}; 187 std::lock_guard lock{joystick_map_mutex};
188 const auto it = joystick_map.find(guid); 188 const auto it = joystick_map.find(guid);
189
189 if (it != joystick_map.end()) { 190 if (it != joystick_map.end()) {
190 while (it->second.size() <= static_cast<std::size_t>(port)) { 191 while (it->second.size() <= static_cast<std::size_t>(port)) {
191 auto joystick = std::make_shared<SDLJoystick>(guid, static_cast<int>(it->second.size()), 192 auto joystick = std::make_shared<SDLJoystick>(guid, static_cast<int>(it->second.size()),
192 nullptr, nullptr); 193 nullptr, nullptr);
193 it->second.emplace_back(std::move(joystick)); 194 it->second.emplace_back(std::move(joystick));
194 } 195 }
196
195 return it->second[static_cast<std::size_t>(port)]; 197 return it->second[static_cast<std::size_t>(port)];
196 } 198 }
199
197 auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr, nullptr); 200 auto joystick = std::make_shared<SDLJoystick>(guid, 0, nullptr, nullptr);
201
198 return joystick_map[guid].emplace_back(std::move(joystick)); 202 return joystick_map[guid].emplace_back(std::move(joystick));
199} 203}
200 204
201std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) { 205std::shared_ptr<SDLJoystick> SDLState::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) {
202 auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id); 206 auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id);
203 auto sdl_controller = SDL_GameControllerFromInstanceID(sdl_id);
204 const std::string guid = GetGUID(sdl_joystick); 207 const std::string guid = GetGUID(sdl_joystick);
205 208
206 std::lock_guard lock{joystick_map_mutex}; 209 std::lock_guard lock{joystick_map_mutex};
207 const auto map_it = joystick_map.find(guid); 210 const auto map_it = joystick_map.find(guid);
208 if (map_it != joystick_map.end()) {
209 const auto vec_it =
210 std::find_if(map_it->second.begin(), map_it->second.end(),
211 [&sdl_joystick](const std::shared_ptr<SDLJoystick>& joystick) {
212 return sdl_joystick == joystick->GetSDLJoystick();
213 });
214 if (vec_it != map_it->second.end()) {
215 // This is the common case: There is already an existing SDL_Joystick mapped to a
216 // SDLJoystick. return the SDLJoystick
217 return *vec_it;
218 }
219 211
220 // Search for a SDLJoystick without a mapped SDL_Joystick... 212 if (map_it == joystick_map.end()) {
221 const auto nullptr_it = std::find_if(map_it->second.begin(), map_it->second.end(), 213 return nullptr;
222 [](const std::shared_ptr<SDLJoystick>& joystick) { 214 }
223 return joystick->GetSDLJoystick() == nullptr;
224 });
225 if (nullptr_it != map_it->second.end()) {
226 // ... and map it
227 (*nullptr_it)->SetSDLJoystick(sdl_joystick, sdl_controller);
228 return *nullptr_it;
229 }
230 215
231 // There is no SDLJoystick without a mapped SDL_Joystick 216 const auto vec_it = std::find_if(map_it->second.begin(), map_it->second.end(),
232 // Create a new SDLJoystick 217 [&sdl_joystick](const auto& joystick) {
233 const int port = static_cast<int>(map_it->second.size()); 218 return joystick->GetSDLJoystick() == sdl_joystick;
234 auto joystick = std::make_shared<SDLJoystick>(guid, port, sdl_joystick, sdl_controller); 219 });
235 return map_it->second.emplace_back(std::move(joystick)); 220
221 if (vec_it == map_it->second.end()) {
222 return nullptr;
236 } 223 }
237 224
238 auto joystick = std::make_shared<SDLJoystick>(guid, 0, sdl_joystick, sdl_controller); 225 return *vec_it;
239 return joystick_map[guid].emplace_back(std::move(joystick));
240} 226}
241 227
242void SDLState::InitJoystick(int joystick_index) { 228void SDLState::InitJoystick(int joystick_index) {
243 SDL_Joystick* sdl_joystick = SDL_JoystickOpen(joystick_index); 229 SDL_Joystick* sdl_joystick = SDL_JoystickOpen(joystick_index);
244 SDL_GameController* sdl_gamecontroller = nullptr; 230 SDL_GameController* sdl_gamecontroller = nullptr;
231
245 if (SDL_IsGameController(joystick_index)) { 232 if (SDL_IsGameController(joystick_index)) {
246 sdl_gamecontroller = SDL_GameControllerOpen(joystick_index); 233 sdl_gamecontroller = SDL_GameControllerOpen(joystick_index);
247 } 234 }
235
248 if (!sdl_joystick) { 236 if (!sdl_joystick) {
249 LOG_ERROR(Input, "Failed to open joystick {}", joystick_index); 237 LOG_ERROR(Input, "Failed to open joystick {}", joystick_index);
250 return; 238 return;
251 } 239 }
240
252 const std::string guid = GetGUID(sdl_joystick); 241 const std::string guid = GetGUID(sdl_joystick);
253 242
254 std::lock_guard lock{joystick_map_mutex}; 243 std::lock_guard lock{joystick_map_mutex};
@@ -257,14 +246,17 @@ void SDLState::InitJoystick(int joystick_index) {
257 joystick_map[guid].emplace_back(std::move(joystick)); 246 joystick_map[guid].emplace_back(std::move(joystick));
258 return; 247 return;
259 } 248 }
249
260 auto& joystick_guid_list = joystick_map[guid]; 250 auto& joystick_guid_list = joystick_map[guid];
261 const auto it = std::find_if( 251 const auto joystick_it =
262 joystick_guid_list.begin(), joystick_guid_list.end(), 252 std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(),
263 [](const std::shared_ptr<SDLJoystick>& joystick) { return !joystick->GetSDLJoystick(); }); 253 [](const auto& joystick) { return !joystick->GetSDLJoystick(); });
264 if (it != joystick_guid_list.end()) { 254
265 (*it)->SetSDLJoystick(sdl_joystick, sdl_gamecontroller); 255 if (joystick_it != joystick_guid_list.end()) {
256 (*joystick_it)->SetSDLJoystick(sdl_joystick, sdl_gamecontroller);
266 return; 257 return;
267 } 258 }
259
268 const int port = static_cast<int>(joystick_guid_list.size()); 260 const int port = static_cast<int>(joystick_guid_list.size());
269 auto joystick = std::make_shared<SDLJoystick>(guid, port, sdl_joystick, sdl_gamecontroller); 261 auto joystick = std::make_shared<SDLJoystick>(guid, port, sdl_joystick, sdl_gamecontroller);
270 joystick_guid_list.emplace_back(std::move(joystick)); 262 joystick_guid_list.emplace_back(std::move(joystick));
@@ -274,18 +266,14 @@ void SDLState::CloseJoystick(SDL_Joystick* sdl_joystick) {
274 const std::string guid = GetGUID(sdl_joystick); 266 const std::string guid = GetGUID(sdl_joystick);
275 267
276 std::lock_guard lock{joystick_map_mutex}; 268 std::lock_guard lock{joystick_map_mutex};
277 auto& joystick_guid_list = joystick_map[guid]; 269 // This call to guid is safe since the joystick is guaranteed to be in the map
278 auto joystick_it = std::find_if( 270 const auto& joystick_guid_list = joystick_map[guid];
279 joystick_guid_list.begin(), joystick_guid_list.end(), 271 const auto joystick_it = std::find_if(joystick_guid_list.begin(), joystick_guid_list.end(),
280 [&sdl_joystick](auto& joystick) { return joystick->GetSDLJoystick() == sdl_joystick; }); 272 [&sdl_joystick](const auto& joystick) {
281 273 return joystick->GetSDLJoystick() == sdl_joystick;
282 if (joystick_it != joystick_guid_list.end()) { 274 });
283 (*joystick_it)->SetSDLJoystick(nullptr, nullptr); 275
284 joystick_guid_list.erase(joystick_it); 276 (*joystick_it)->SetSDLJoystick(nullptr, nullptr);
285 if (joystick_guid_list.empty()) {
286 joystick_map.erase(guid);
287 }
288 }
289} 277}
290 278
291void SDLState::HandleGameControllerEvent(const SDL_Event& event) { 279void SDLState::HandleGameControllerEvent(const SDL_Event& event) {
@@ -720,8 +708,7 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() {
720 std::vector<Common::ParamPackage> devices; 708 std::vector<Common::ParamPackage> devices;
721 for (const auto& [key, value] : joystick_map) { 709 for (const auto& [key, value] : joystick_map) {
722 for (const auto& joystick : value) { 710 for (const auto& joystick : value) {
723 auto* joy = joystick->GetSDLJoystick(); 711 if (auto* const controller = joystick->GetSDLGameController()) {
724 if (auto* controller = joystick->GetSDLGameController()) {
725 std::string name = 712 std::string name =
726 fmt::format("{} {}", SDL_GameControllerName(controller), joystick->GetPort()); 713 fmt::format("{} {}", SDL_GameControllerName(controller), joystick->GetPort());
727 devices.emplace_back(Common::ParamPackage{ 714 devices.emplace_back(Common::ParamPackage{
@@ -730,7 +717,7 @@ std::vector<Common::ParamPackage> SDLState::GetInputDevices() {
730 {"guid", joystick->GetGUID()}, 717 {"guid", joystick->GetGUID()},
731 {"port", std::to_string(joystick->GetPort())}, 718 {"port", std::to_string(joystick->GetPort())},
732 }); 719 });
733 } else if (joy) { 720 } else if (auto* const joy = joystick->GetSDLJoystick()) {
734 std::string name = fmt::format("{} {}", SDL_JoystickName(joy), joystick->GetPort()); 721 std::string name = fmt::format("{} {}", SDL_JoystickName(joy), joystick->GetPort());
735 devices.emplace_back(Common::ParamPackage{ 722 devices.emplace_back(Common::ParamPackage{
736 {"class", "sdl"}, 723 {"class", "sdl"},
@@ -797,21 +784,27 @@ Common::ParamPackage BuildHatParamPackageForButton(int port, std::string guid, s
797Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Event& event) { 784Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Event& event) {
798 switch (event.type) { 785 switch (event.type) {
799 case SDL_JOYAXISMOTION: { 786 case SDL_JOYAXISMOTION: {
800 const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); 787 if (const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which)) {
801 return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), 788 return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
802 static_cast<s32>(event.jaxis.axis), 789 static_cast<s32>(event.jaxis.axis),
803 event.jaxis.value); 790 event.jaxis.value);
791 }
792 break;
804 } 793 }
805 case SDL_JOYBUTTONUP: { 794 case SDL_JOYBUTTONUP: {
806 const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); 795 if (const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which)) {
807 return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), 796 return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
808 static_cast<s32>(event.jbutton.button)); 797 static_cast<s32>(event.jbutton.button));
798 }
799 break;
809 } 800 }
810 case SDL_JOYHATMOTION: { 801 case SDL_JOYHATMOTION: {
811 const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); 802 if (const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which)) {
812 return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), 803 return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
813 static_cast<s32>(event.jhat.hat), 804 static_cast<s32>(event.jhat.hat),
814 static_cast<s32>(event.jhat.value)); 805 static_cast<s32>(event.jhat.value));
806 }
807 break;
815 } 808 }
816 } 809 }
817 return {}; 810 return {};
@@ -820,21 +813,27 @@ Common::ParamPackage SDLEventToButtonParamPackage(SDLState& state, const SDL_Eve
820Common::ParamPackage SDLEventToMotionParamPackage(SDLState& state, const SDL_Event& event) { 813Common::ParamPackage SDLEventToMotionParamPackage(SDLState& state, const SDL_Event& event) {
821 switch (event.type) { 814 switch (event.type) {
822 case SDL_JOYAXISMOTION: { 815 case SDL_JOYAXISMOTION: {
823 const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); 816 if (const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which)) {
824 return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), 817 return BuildAnalogParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
825 static_cast<s32>(event.jaxis.axis), 818 static_cast<s32>(event.jaxis.axis),
826 event.jaxis.value); 819 event.jaxis.value);
820 }
821 break;
827 } 822 }
828 case SDL_JOYBUTTONUP: { 823 case SDL_JOYBUTTONUP: {
829 const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which); 824 if (const auto joystick = state.GetSDLJoystickBySDLID(event.jbutton.which)) {
830 return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), 825 return BuildButtonParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
831 static_cast<s32>(event.jbutton.button)); 826 static_cast<s32>(event.jbutton.button));
827 }
828 break;
832 } 829 }
833 case SDL_JOYHATMOTION: { 830 case SDL_JOYHATMOTION: {
834 const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which); 831 if (const auto joystick = state.GetSDLJoystickBySDLID(event.jhat.which)) {
835 return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(), 832 return BuildHatParamPackageForButton(joystick->GetPort(), joystick->GetGUID(),
836 static_cast<s32>(event.jhat.hat), 833 static_cast<s32>(event.jhat.hat),
837 static_cast<s32>(event.jhat.value)); 834 static_cast<s32>(event.jhat.value));
835 }
836 break;
838 } 837 }
839 } 838 }
840 return {}; 839 return {};
@@ -1062,9 +1061,8 @@ public:
1062 // Simplify controller config by testing if game controller support is enabled. 1061 // Simplify controller config by testing if game controller support is enabled.
1063 if (event.type == SDL_JOYAXISMOTION) { 1062 if (event.type == SDL_JOYAXISMOTION) {
1064 const auto axis = event.jaxis.axis; 1063 const auto axis = event.jaxis.axis;
1065 const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); 1064 if (const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which);
1066 auto* const controller = joystick->GetSDLGameController(); 1065 auto* const controller = joystick->GetSDLGameController()) {
1067 if (controller) {
1068 const auto axis_left_x = 1066 const auto axis_left_x =
1069 SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX) 1067 SDL_GameControllerGetBindForAxis(controller, SDL_CONTROLLER_AXIS_LEFTX)
1070 .value.axis; 1068 .value.axis;
@@ -1098,12 +1096,13 @@ public:
1098 } 1096 }
1099 1097
1100 if (analog_x_axis != -1 && analog_y_axis != -1) { 1098 if (analog_x_axis != -1 && analog_y_axis != -1) {
1101 const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which); 1099 if (const auto joystick = state.GetSDLJoystickBySDLID(event.jaxis.which)) {
1102 auto params = BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(), 1100 auto params = BuildParamPackageForAnalog(joystick->GetPort(), joystick->GetGUID(),
1103 analog_x_axis, analog_y_axis); 1101 analog_x_axis, analog_y_axis);
1104 analog_x_axis = -1; 1102 analog_x_axis = -1;
1105 analog_y_axis = -1; 1103 analog_y_axis = -1;
1106 return params; 1104 return params;
1105 }
1107 } 1106 }
1108 return {}; 1107 return {};
1109 } 1108 }
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt
index aa62363a7..c157724a9 100644
--- a/src/video_core/host_shaders/CMakeLists.txt
+++ b/src/video_core/host_shaders/CMakeLists.txt
@@ -1,23 +1,16 @@
1set(SHADER_FILES 1set(SHADER_SOURCES
2 opengl_present.frag 2 opengl_present.frag
3 opengl_present.vert 3 opengl_present.vert
4) 4)
5 5
6set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) 6set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include)
7set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE)
8
9set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) 7set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders)
10add_custom_command( 8set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE)
11 OUTPUT
12 ${SHADER_DIR}
13 COMMAND
14 ${CMAKE_COMMAND} -E make_directory ${SHADER_DIR}
15)
16 9
17set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in) 10set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in)
18set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake) 11set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake)
19 12
20foreach(FILENAME IN ITEMS ${SHADER_FILES}) 13foreach(FILENAME IN ITEMS ${SHADER_SOURCES})
21 string(REPLACE "." "_" SHADER_NAME ${FILENAME}) 14 string(REPLACE "." "_" SHADER_NAME ${FILENAME})
22 set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}) 15 set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME})
23 set(HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}.h) 16 set(HEADER_FILE ${SHADER_DIR}/${SHADER_NAME}.h)
@@ -29,8 +22,8 @@ foreach(FILENAME IN ITEMS ${SHADER_FILES})
29 MAIN_DEPENDENCY 22 MAIN_DEPENDENCY
30 ${SOURCE_FILE} 23 ${SOURCE_FILE}
31 DEPENDS 24 DEPENDS
32 ${HEADER_GENERATOR}
33 ${INPUT_FILE} 25 ${INPUT_FILE}
26 # HEADER_GENERATOR should be included here but msbuild seems to assume it's always modified
34 ) 27 )
35 set(SHADER_HEADERS ${SHADER_HEADERS} ${HEADER_FILE}) 28 set(SHADER_HEADERS ${SHADER_HEADERS} ${HEADER_FILE})
36endforeach() 29endforeach()
@@ -39,5 +32,5 @@ add_custom_target(host_shaders
39 DEPENDS 32 DEPENDS
40 ${SHADER_HEADERS} 33 ${SHADER_HEADERS}
41 SOURCES 34 SOURCES
42 ${SHADER_FILES} 35 ${SHADER_SOURCES}
43) 36)
diff --git a/src/video_core/host_shaders/StringShaderHeader.cmake b/src/video_core/host_shaders/StringShaderHeader.cmake
index 368bce0ed..c0fc49768 100644
--- a/src/video_core/host_shaders/StringShaderHeader.cmake
+++ b/src/video_core/host_shaders/StringShaderHeader.cmake
@@ -8,4 +8,6 @@ string(TOUPPER ${CONTENTS_NAME} CONTENTS_NAME)
8 8
9file(READ ${SOURCE_FILE} CONTENTS) 9file(READ ${SOURCE_FILE} CONTENTS)
10 10
11get_filename_component(OUTPUT_DIR ${HEADER_FILE} DIRECTORY)
12make_directory(${OUTPUT_DIR})
11configure_file(${INPUT_FILE} ${HEADER_FILE} @ONLY) 13configure_file(${INPUT_FILE} ${HEADER_FILE} @ONLY)
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/controller.cpp
index 8063909ff..d6fbbbf2b 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/controller.cpp
@@ -596,6 +596,6 @@ void QtControllerSelector::ReconfigureControllers(
596 596
597void QtControllerSelector::MainWindowReconfigureFinished() { 597void QtControllerSelector::MainWindowReconfigureFinished() {
598 // Acquire the HLE mutex 598 // Acquire the HLE mutex
599 std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); 599 std::lock_guard lock(HLE::g_hle_lock);
600 callback(); 600 callback();
601} 601}
diff --git a/src/yuzu/applets/profile_select.cpp b/src/yuzu/applets/profile_select.cpp
index dca8835ed..c9a2f8601 100644
--- a/src/yuzu/applets/profile_select.cpp
+++ b/src/yuzu/applets/profile_select.cpp
@@ -114,6 +114,15 @@ QtProfileSelectionDialog::QtProfileSelectionDialog(QWidget* parent)
114 114
115QtProfileSelectionDialog::~QtProfileSelectionDialog() = default; 115QtProfileSelectionDialog::~QtProfileSelectionDialog() = default;
116 116
117int QtProfileSelectionDialog::exec() {
118 // Skip profile selection when there's only one.
119 if (profile_manager->GetUserCount() == 1) {
120 user_index = 0;
121 return QDialog::Accepted;
122 }
123 return QDialog::exec();
124}
125
117void QtProfileSelectionDialog::accept() { 126void QtProfileSelectionDialog::accept() {
118 QDialog::accept(); 127 QDialog::accept();
119} 128}
diff --git a/src/yuzu/applets/profile_select.h b/src/yuzu/applets/profile_select.h
index cee886a77..29c33cca0 100644
--- a/src/yuzu/applets/profile_select.h
+++ b/src/yuzu/applets/profile_select.h
@@ -27,6 +27,7 @@ public:
27 explicit QtProfileSelectionDialog(QWidget* parent); 27 explicit QtProfileSelectionDialog(QWidget* parent);
28 ~QtProfileSelectionDialog() override; 28 ~QtProfileSelectionDialog() override;
29 29
30 int exec() override;
30 void accept() override; 31 void accept() override;
31 void reject() override; 32 void reject() override;
32 33
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 9ad43ed8f..5e8e201dc 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -12,6 +12,7 @@
12#include "common/assert.h" 12#include "common/assert.h"
13#include "common/file_util.h" 13#include "common/file_util.h"
14#include "core/core.h" 14#include "core/core.h"
15#include "core/hle/service/time/time.h"
15#include "core/settings.h" 16#include "core/settings.h"
16#include "ui_configure_system.h" 17#include "ui_configure_system.h"
17#include "yuzu/configuration/configuration_shared.h" 18#include "yuzu/configuration/configuration_shared.h"
@@ -104,6 +105,22 @@ void ConfigureSystem::SetConfiguration() {
104void ConfigureSystem::ReadSystemSettings() {} 105void ConfigureSystem::ReadSystemSettings() {}
105 106
106void ConfigureSystem::ApplyConfiguration() { 107void ConfigureSystem::ApplyConfiguration() {
108 // Allow setting custom RTC even if system is powered on, to allow in-game time to be fast
109 // forwared
110 if (Settings::values.custom_rtc.UsingGlobal()) {
111 if (ui->custom_rtc_checkbox->isChecked()) {
112 Settings::values.custom_rtc.SetValue(
113 std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
114 if (Core::System::GetInstance().IsPoweredOn()) {
115 const s64 posix_time{Settings::values.custom_rtc.GetValue()->count() +
116 Service::Time::TimeManager::GetExternalTimeZoneOffset()};
117 Core::System::GetInstance().GetTimeManager().UpdateLocalSystemClockTime(posix_time);
118 }
119 } else {
120 Settings::values.custom_rtc.SetValue(std::nullopt);
121 }
122 }
123
107 if (!enabled) { 124 if (!enabled) {
108 return; 125 return;
109 } 126 }
@@ -131,15 +148,6 @@ void ConfigureSystem::ApplyConfiguration() {
131 Settings::values.rng_seed.SetValue(std::nullopt); 148 Settings::values.rng_seed.SetValue(std::nullopt);
132 } 149 }
133 } 150 }
134
135 if (Settings::values.custom_rtc.UsingGlobal()) {
136 if (ui->custom_rtc_checkbox->isChecked()) {
137 Settings::values.custom_rtc.SetValue(
138 std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()));
139 } else {
140 Settings::values.custom_rtc.SetValue(std::nullopt);
141 }
142 }
143 } else { 151 } else {
144 ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index, 152 ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index,
145 ui->combo_language); 153 ui->combo_language);
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index e3de0f0e1..18e68e590 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -303,24 +303,18 @@ void GMainWindow::ControllerSelectorReconfigureControllers(
303} 303}
304 304
305void GMainWindow::ProfileSelectorSelectProfile() { 305void GMainWindow::ProfileSelectorSelectProfile() {
306 const Service::Account::ProfileManager manager; 306 QtProfileSelectionDialog dialog(this);
307 int index = 0; 307 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint |
308 if (manager.GetUserCount() != 1) { 308 Qt::WindowTitleHint | Qt::WindowSystemMenuHint |
309 QtProfileSelectionDialog dialog(this); 309 Qt::WindowCloseButtonHint);
310 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowStaysOnTopHint | 310 dialog.setWindowModality(Qt::WindowModal);
311 Qt::WindowTitleHint | Qt::WindowSystemMenuHint | 311 if (dialog.exec() == QDialog::Rejected) {
312 Qt::WindowCloseButtonHint); 312 emit ProfileSelectorFinishedSelection(std::nullopt);
313 dialog.setWindowModality(Qt::WindowModal); 313 return;
314
315 if (dialog.exec() == QDialog::Rejected) {
316 emit ProfileSelectorFinishedSelection(std::nullopt);
317 return;
318 }
319
320 index = dialog.GetIndex();
321 } 314 }
322 315
323 const auto uuid = manager.GetUser(static_cast<std::size_t>(index)); 316 const Service::Account::ProfileManager manager;
317 const auto uuid = manager.GetUser(static_cast<std::size_t>(dialog.GetIndex()));
324 if (!uuid.has_value()) { 318 if (!uuid.has_value()) {
325 emit ProfileSelectorFinishedSelection(std::nullopt); 319 emit ProfileSelectorFinishedSelection(std::nullopt);
326 return; 320 return;