diff options
Diffstat (limited to 'src')
90 files changed, 2311 insertions, 1047 deletions
diff --git a/src/audio_core/cubeb_sink.cpp b/src/audio_core/cubeb_sink.cpp index c4e0e30fe..41bf5cd4d 100644 --- a/src/audio_core/cubeb_sink.cpp +++ b/src/audio_core/cubeb_sink.cpp | |||
| @@ -193,7 +193,7 @@ long CubebSinkStream::DataCallback(cubeb_stream* stream, void* user_data, const | |||
| 193 | const std::size_t samples_to_write = num_channels * num_frames; | 193 | const std::size_t samples_to_write = num_channels * num_frames; |
| 194 | std::size_t samples_written; | 194 | std::size_t samples_written; |
| 195 | 195 | ||
| 196 | if (Settings::values.enable_audio_stretching) { | 196 | if (Settings::values.enable_audio_stretching.GetValue()) { |
| 197 | const std::vector<s16> in{impl->queue.Pop()}; | 197 | const std::vector<s16> in{impl->queue.Pop()}; |
| 198 | const std::size_t num_in{in.size() / num_channels}; | 198 | const std::size_t num_in{in.size() / num_channels}; |
| 199 | s16* const out{reinterpret_cast<s16*>(buffer)}; | 199 | s16* const out{reinterpret_cast<s16*>(buffer)}; |
diff --git a/src/audio_core/stream.cpp b/src/audio_core/stream.cpp index dfc4805d9..aab3e979a 100644 --- a/src/audio_core/stream.cpp +++ b/src/audio_core/stream.cpp | |||
| @@ -38,7 +38,7 @@ Stream::Stream(Core::Timing::CoreTiming& core_timing, u32 sample_rate, Format fo | |||
| 38 | sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} { | 38 | sink_stream{sink_stream}, core_timing{core_timing}, name{std::move(name_)} { |
| 39 | 39 | ||
| 40 | release_event = Core::Timing::CreateEvent( | 40 | release_event = Core::Timing::CreateEvent( |
| 41 | name, [this](u64 userdata, s64 cycles_late) { ReleaseActiveBuffer(); }); | 41 | name, [this](u64 userdata, s64 cycles_late) { ReleaseActiveBuffer(cycles_late); }); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | void Stream::Play() { | 44 | void Stream::Play() { |
| @@ -66,15 +66,6 @@ s64 Stream::GetBufferReleaseNS(const Buffer& buffer) const { | |||
| 66 | return ns.count(); | 66 | return ns.count(); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | s64 Stream::GetBufferReleaseNSHostTiming(const Buffer& buffer) const { | ||
| 70 | const std::size_t num_samples{buffer.GetSamples().size() / GetNumChannels()}; | ||
| 71 | /// DSP signals before playing the last sample, in HLE we emulate this in this way | ||
| 72 | s64 base_samples = std::max<s64>(static_cast<s64>(num_samples) - 1, 0); | ||
| 73 | const auto ns = | ||
| 74 | std::chrono::nanoseconds((static_cast<u64>(base_samples) * 1000000000ULL) / sample_rate); | ||
| 75 | return ns.count(); | ||
| 76 | } | ||
| 77 | |||
| 78 | static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) { | 69 | static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) { |
| 79 | const float volume{std::clamp(Settings::Volume() - (1.0f - game_volume), 0.0f, 1.0f)}; | 70 | const float volume{std::clamp(Settings::Volume() - (1.0f - game_volume), 0.0f, 1.0f)}; |
| 80 | 71 | ||
| @@ -89,7 +80,7 @@ static void VolumeAdjustSamples(std::vector<s16>& samples, float game_volume) { | |||
| 89 | } | 80 | } |
| 90 | } | 81 | } |
| 91 | 82 | ||
| 92 | void Stream::PlayNextBuffer() { | 83 | void Stream::PlayNextBuffer(s64 cycles_late) { |
| 93 | if (!IsPlaying()) { | 84 | if (!IsPlaying()) { |
| 94 | // Ensure we are in playing state before playing the next buffer | 85 | // Ensure we are in playing state before playing the next buffer |
| 95 | sink_stream.Flush(); | 86 | sink_stream.Flush(); |
| @@ -114,18 +105,17 @@ void Stream::PlayNextBuffer() { | |||
| 114 | 105 | ||
| 115 | sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); | 106 | sink_stream.EnqueueSamples(GetNumChannels(), active_buffer->GetSamples()); |
| 116 | 107 | ||
| 117 | if (core_timing.IsHostTiming()) { | 108 | core_timing.ScheduleEvent( |
| 118 | core_timing.ScheduleEvent(GetBufferReleaseNSHostTiming(*active_buffer), release_event, {}); | 109 | GetBufferReleaseNS(*active_buffer) - |
| 119 | } else { | 110 | (Settings::values.enable_audio_stretching.GetValue() ? 0 : cycles_late), |
| 120 | core_timing.ScheduleEvent(GetBufferReleaseNS(*active_buffer), release_event, {}); | 111 | release_event, {}); |
| 121 | } | ||
| 122 | } | 112 | } |
| 123 | 113 | ||
| 124 | void Stream::ReleaseActiveBuffer() { | 114 | void Stream::ReleaseActiveBuffer(s64 cycles_late) { |
| 125 | ASSERT(active_buffer); | 115 | ASSERT(active_buffer); |
| 126 | released_buffers.push(std::move(active_buffer)); | 116 | released_buffers.push(std::move(active_buffer)); |
| 127 | release_callback(); | 117 | release_callback(); |
| 128 | PlayNextBuffer(); | 118 | PlayNextBuffer(cycles_late); |
| 129 | } | 119 | } |
| 130 | 120 | ||
| 131 | bool Stream::QueueBuffer(BufferPtr&& buffer) { | 121 | bool Stream::QueueBuffer(BufferPtr&& buffer) { |
diff --git a/src/audio_core/stream.h b/src/audio_core/stream.h index e309d60fe..524376257 100644 --- a/src/audio_core/stream.h +++ b/src/audio_core/stream.h | |||
| @@ -90,10 +90,10 @@ public: | |||
| 90 | 90 | ||
| 91 | private: | 91 | private: |
| 92 | /// Plays the next queued buffer in the audio stream, starting playback if necessary | 92 | /// Plays the next queued buffer in the audio stream, starting playback if necessary |
| 93 | void PlayNextBuffer(); | 93 | void PlayNextBuffer(s64 cycles_late = 0); |
| 94 | 94 | ||
| 95 | /// Releases the actively playing buffer, signalling that it has been completed | 95 | /// Releases the actively playing buffer, signalling that it has been completed |
| 96 | void ReleaseActiveBuffer(); | 96 | void ReleaseActiveBuffer(s64 cycles_late = 0); |
| 97 | 97 | ||
| 98 | /// Gets the number of core cycles when the specified buffer will be released | 98 | /// Gets the number of core cycles when the specified buffer will be released |
| 99 | s64 GetBufferReleaseNS(const Buffer& buffer) const; | 99 | s64 GetBufferReleaseNS(const Buffer& buffer) const; |
diff --git a/src/core/core.cpp b/src/core/core.cpp index 1a243c515..69a1aa0a5 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp | |||
| @@ -147,8 +147,8 @@ struct System::Impl { | |||
| 147 | 147 | ||
| 148 | device_memory = std::make_unique<Core::DeviceMemory>(system); | 148 | device_memory = std::make_unique<Core::DeviceMemory>(system); |
| 149 | 149 | ||
| 150 | is_multicore = Settings::values.use_multi_core; | 150 | is_multicore = Settings::values.use_multi_core.GetValue(); |
| 151 | is_async_gpu = is_multicore || Settings::values.use_asynchronous_gpu_emulation; | 151 | is_async_gpu = is_multicore || Settings::values.use_asynchronous_gpu_emulation.GetValue(); |
| 152 | 152 | ||
| 153 | kernel.SetMulticore(is_multicore); | 153 | kernel.SetMulticore(is_multicore); |
| 154 | cpu_manager.SetMulticore(is_multicore); | 154 | cpu_manager.SetMulticore(is_multicore); |
| @@ -162,7 +162,7 @@ struct System::Impl { | |||
| 162 | const auto current_time = std::chrono::duration_cast<std::chrono::seconds>( | 162 | const auto current_time = std::chrono::duration_cast<std::chrono::seconds>( |
| 163 | std::chrono::system_clock::now().time_since_epoch()); | 163 | std::chrono::system_clock::now().time_since_epoch()); |
| 164 | Settings::values.custom_rtc_differential = | 164 | Settings::values.custom_rtc_differential = |
| 165 | Settings::values.custom_rtc.value_or(current_time) - current_time; | 165 | Settings::values.custom_rtc.GetValue().value_or(current_time) - current_time; |
| 166 | 166 | ||
| 167 | // Create a default fs if one doesn't already exist. | 167 | // Create a default fs if one doesn't already exist. |
| 168 | if (virtual_filesystem == nullptr) | 168 | if (virtual_filesystem == nullptr) |
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp index 5c83c41a4..a63e60461 100644 --- a/src/core/core_timing.cpp +++ b/src/core/core_timing.cpp | |||
| @@ -172,7 +172,7 @@ void CoreTiming::ClearPendingEvents() { | |||
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { | 174 | void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { |
| 175 | basic_lock.lock(); | 175 | std::scoped_lock lock{basic_lock}; |
| 176 | 176 | ||
| 177 | const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { | 177 | const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) { |
| 178 | return e.type.lock().get() == event_type.get(); | 178 | return e.type.lock().get() == event_type.get(); |
| @@ -183,12 +183,10 @@ void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) { | |||
| 183 | event_queue.erase(itr, event_queue.end()); | 183 | event_queue.erase(itr, event_queue.end()); |
| 184 | std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); | 184 | std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>()); |
| 185 | } | 185 | } |
| 186 | basic_lock.unlock(); | ||
| 187 | } | 186 | } |
| 188 | 187 | ||
| 189 | std::optional<s64> CoreTiming::Advance() { | 188 | std::optional<s64> CoreTiming::Advance() { |
| 190 | std::scoped_lock advance_scope{advance_lock}; | 189 | std::scoped_lock lock{advance_lock, basic_lock}; |
| 191 | std::scoped_lock basic_scope{basic_lock}; | ||
| 192 | global_timer = GetGlobalTimeNs().count(); | 190 | global_timer = GetGlobalTimeNs().count(); |
| 193 | 191 | ||
| 194 | while (!event_queue.empty() && event_queue.front().time <= global_timer) { | 192 | while (!event_queue.empty() && event_queue.front().time <= global_timer) { |
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index 8997c7082..f87fe0abc 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -695,8 +695,9 @@ void KeyManager::WriteKeyToFile(KeyCategory category, std::string_view keyname, | |||
| 695 | } | 695 | } |
| 696 | 696 | ||
| 697 | void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { | 697 | void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { |
| 698 | if (s128_keys.find({id, field1, field2}) != s128_keys.end()) | 698 | if (s128_keys.find({id, field1, field2}) != s128_keys.end() || key == Key128{}) { |
| 699 | return; | 699 | return; |
| 700 | } | ||
| 700 | if (id == S128KeyType::Titlekey) { | 701 | if (id == S128KeyType::Titlekey) { |
| 701 | Key128 rights_id; | 702 | Key128 rights_id; |
| 702 | std::memcpy(rights_id.data(), &field2, sizeof(u64)); | 703 | std::memcpy(rights_id.data(), &field2, sizeof(u64)); |
| @@ -716,8 +717,9 @@ void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { | |||
| 716 | return std::tie(elem.second.type, elem.second.field1, elem.second.field2) == | 717 | return std::tie(elem.second.type, elem.second.field1, elem.second.field2) == |
| 717 | std::tie(id, field1, field2); | 718 | std::tie(id, field1, field2); |
| 718 | }); | 719 | }); |
| 719 | if (iter2 != s128_file_id.end()) | 720 | if (iter2 != s128_file_id.end()) { |
| 720 | WriteKeyToFile(category, iter2->first, key); | 721 | WriteKeyToFile(category, iter2->first, key); |
| 722 | } | ||
| 721 | 723 | ||
| 722 | // Variable cases | 724 | // Variable cases |
| 723 | if (id == S128KeyType::KeyArea) { | 725 | if (id == S128KeyType::KeyArea) { |
| @@ -745,16 +747,18 @@ void KeyManager::SetKey(S128KeyType id, Key128 key, u64 field1, u64 field2) { | |||
| 745 | } | 747 | } |
| 746 | 748 | ||
| 747 | void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) { | 749 | void KeyManager::SetKey(S256KeyType id, Key256 key, u64 field1, u64 field2) { |
| 748 | if (s256_keys.find({id, field1, field2}) != s256_keys.end()) | 750 | if (s256_keys.find({id, field1, field2}) != s256_keys.end() || key == Key256{}) { |
| 749 | return; | 751 | return; |
| 752 | } | ||
| 750 | const auto iter = std::find_if( | 753 | const auto iter = std::find_if( |
| 751 | s256_file_id.begin(), s256_file_id.end(), | 754 | s256_file_id.begin(), s256_file_id.end(), |
| 752 | [&id, &field1, &field2](const std::pair<std::string, KeyIndex<S256KeyType>> elem) { | 755 | [&id, &field1, &field2](const std::pair<std::string, KeyIndex<S256KeyType>> elem) { |
| 753 | return std::tie(elem.second.type, elem.second.field1, elem.second.field2) == | 756 | return std::tie(elem.second.type, elem.second.field1, elem.second.field2) == |
| 754 | std::tie(id, field1, field2); | 757 | std::tie(id, field1, field2); |
| 755 | }); | 758 | }); |
| 756 | if (iter != s256_file_id.end()) | 759 | if (iter != s256_file_id.end()) { |
| 757 | WriteKeyToFile(KeyCategory::Standard, iter->first, key); | 760 | WriteKeyToFile(KeyCategory::Standard, iter->first, key); |
| 761 | } | ||
| 758 | s256_keys[{id, field1, field2}] = key; | 762 | s256_keys[{id, field1, field2}] = key; |
| 759 | } | 763 | } |
| 760 | 764 | ||
diff --git a/src/core/frontend/framebuffer_layout.cpp b/src/core/frontend/framebuffer_layout.cpp index d0c43447c..c1fbc235b 100644 --- a/src/core/frontend/framebuffer_layout.cpp +++ b/src/core/frontend/framebuffer_layout.cpp | |||
| @@ -29,7 +29,7 @@ FramebufferLayout DefaultFrameLayout(u32 width, u32 height) { | |||
| 29 | 29 | ||
| 30 | const float window_aspect_ratio = static_cast<float>(height) / width; | 30 | const float window_aspect_ratio = static_cast<float>(height) / width; |
| 31 | const float emulation_aspect_ratio = EmulationAspectRatio( | 31 | const float emulation_aspect_ratio = EmulationAspectRatio( |
| 32 | static_cast<AspectRatio>(Settings::values.aspect_ratio), window_aspect_ratio); | 32 | static_cast<AspectRatio>(Settings::values.aspect_ratio.GetValue()), window_aspect_ratio); |
| 33 | 33 | ||
| 34 | const Common::Rectangle<u32> screen_window_area{0, 0, width, height}; | 34 | const Common::Rectangle<u32> screen_window_area{0, 0, width, height}; |
| 35 | Common::Rectangle<u32> screen = MaxRectangle(screen_window_area, emulation_aspect_ratio); | 35 | Common::Rectangle<u32> screen = MaxRectangle(screen_window_area, emulation_aspect_ratio); |
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index f9d7c024d..c6fcb56ad 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -123,7 +123,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, | |||
| 123 | : kernel.CreateNewUserProcessID(); | 123 | : kernel.CreateNewUserProcessID(); |
| 124 | process->capabilities.InitializeForMetadatalessProcess(); | 124 | process->capabilities.InitializeForMetadatalessProcess(); |
| 125 | 125 | ||
| 126 | std::mt19937 rng(Settings::values.rng_seed.value_or(0)); | 126 | std::mt19937 rng(Settings::values.rng_seed.GetValue().value_or(0)); |
| 127 | std::uniform_int_distribution<u64> distribution; | 127 | std::uniform_int_distribution<u64> distribution; |
| 128 | std::generate(process->random_entropy.begin(), process->random_entropy.end(), | 128 | std::generate(process->random_entropy.begin(), process->random_entropy.end(), |
| 129 | [&] { return distribution(rng); }); | 129 | [&] { return distribution(rng); }); |
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 2b12c0dbf..7b929781c 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | // licensed under GPLv2 or later under exception provided by the author. | 6 | // licensed under GPLv2 or later under exception provided by the author. |
| 7 | 7 | ||
| 8 | #include <algorithm> | 8 | #include <algorithm> |
| 9 | #include <mutex> | ||
| 9 | #include <set> | 10 | #include <set> |
| 10 | #include <unordered_set> | 11 | #include <unordered_set> |
| 11 | #include <utility> | 12 | #include <utility> |
| @@ -31,22 +32,20 @@ GlobalScheduler::GlobalScheduler(KernelCore& kernel) : kernel{kernel} {} | |||
| 31 | GlobalScheduler::~GlobalScheduler() = default; | 32 | GlobalScheduler::~GlobalScheduler() = default; |
| 32 | 33 | ||
| 33 | void GlobalScheduler::AddThread(std::shared_ptr<Thread> thread) { | 34 | void GlobalScheduler::AddThread(std::shared_ptr<Thread> thread) { |
| 34 | global_list_guard.lock(); | 35 | std::scoped_lock lock{global_list_guard}; |
| 35 | thread_list.push_back(std::move(thread)); | 36 | thread_list.push_back(std::move(thread)); |
| 36 | global_list_guard.unlock(); | ||
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void GlobalScheduler::RemoveThread(std::shared_ptr<Thread> thread) { | 39 | void GlobalScheduler::RemoveThread(std::shared_ptr<Thread> thread) { |
| 40 | global_list_guard.lock(); | 40 | std::scoped_lock lock{global_list_guard}; |
| 41 | thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread), | 41 | thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread), |
| 42 | thread_list.end()); | 42 | thread_list.end()); |
| 43 | global_list_guard.unlock(); | ||
| 44 | } | 43 | } |
| 45 | 44 | ||
| 46 | u32 GlobalScheduler::SelectThreads() { | 45 | u32 GlobalScheduler::SelectThreads() { |
| 47 | ASSERT(is_locked); | 46 | ASSERT(is_locked); |
| 48 | const auto update_thread = [](Thread* thread, Scheduler& sched) { | 47 | const auto update_thread = [](Thread* thread, Scheduler& sched) { |
| 49 | sched.guard.lock(); | 48 | std::scoped_lock lock{sched.guard}; |
| 50 | if (thread != sched.selected_thread_set.get()) { | 49 | if (thread != sched.selected_thread_set.get()) { |
| 51 | if (thread == nullptr) { | 50 | if (thread == nullptr) { |
| 52 | ++sched.idle_selection_count; | 51 | ++sched.idle_selection_count; |
| @@ -57,7 +56,6 @@ u32 GlobalScheduler::SelectThreads() { | |||
| 57 | sched.is_context_switch_pending || (sched.selected_thread_set != sched.current_thread); | 56 | sched.is_context_switch_pending || (sched.selected_thread_set != sched.current_thread); |
| 58 | sched.is_context_switch_pending = reschedule_pending; | 57 | sched.is_context_switch_pending = reschedule_pending; |
| 59 | std::atomic_thread_fence(std::memory_order_seq_cst); | 58 | std::atomic_thread_fence(std::memory_order_seq_cst); |
| 60 | sched.guard.unlock(); | ||
| 61 | return reschedule_pending; | 59 | return reschedule_pending; |
| 62 | }; | 60 | }; |
| 63 | if (!is_reselection_pending.load()) { | 61 | if (!is_reselection_pending.load()) { |
| @@ -757,11 +755,12 @@ void Scheduler::OnSwitch(void* this_scheduler) { | |||
| 757 | 755 | ||
| 758 | void Scheduler::SwitchToCurrent() { | 756 | void Scheduler::SwitchToCurrent() { |
| 759 | while (true) { | 757 | while (true) { |
| 760 | guard.lock(); | 758 | { |
| 761 | selected_thread = selected_thread_set; | 759 | std::scoped_lock lock{guard}; |
| 762 | current_thread = selected_thread; | 760 | selected_thread = selected_thread_set; |
| 763 | is_context_switch_pending = false; | 761 | current_thread = selected_thread; |
| 764 | guard.unlock(); | 762 | is_context_switch_pending = false; |
| 763 | } | ||
| 765 | while (!is_context_switch_pending) { | 764 | while (!is_context_switch_pending) { |
| 766 | if (current_thread != nullptr && !current_thread->IsHLEThread()) { | 765 | if (current_thread != nullptr && !current_thread->IsHLEThread()) { |
| 767 | current_thread->context_guard.lock(); | 766 | current_thread->context_guard.lock(); |
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 32fad35f3..4e7a0bec9 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp | |||
| @@ -272,7 +272,7 @@ ISelfController::ISelfController(Core::System& system, | |||
| 272 | {41, nullptr, "IsSystemBufferSharingEnabled"}, | 272 | {41, nullptr, "IsSystemBufferSharingEnabled"}, |
| 273 | {42, nullptr, "GetSystemSharedLayerHandle"}, | 273 | {42, nullptr, "GetSystemSharedLayerHandle"}, |
| 274 | {43, nullptr, "GetSystemSharedBufferHandle"}, | 274 | {43, nullptr, "GetSystemSharedBufferHandle"}, |
| 275 | {44, nullptr, "CreateManagedDisplaySeparableLayer"}, | 275 | {44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"}, |
| 276 | {45, nullptr, "SetManagedDisplayLayerSeparationMode"}, | 276 | {45, nullptr, "SetManagedDisplayLayerSeparationMode"}, |
| 277 | {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"}, | 277 | {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"}, |
| 278 | {51, nullptr, "ApproveToDisplay"}, | 278 | {51, nullptr, "ApproveToDisplay"}, |
| @@ -462,6 +462,24 @@ void ISelfController::CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx) | |||
| 462 | rb.Push(*layer_id); | 462 | rb.Push(*layer_id); |
| 463 | } | 463 | } |
| 464 | 464 | ||
| 465 | void ISelfController::CreateManagedDisplaySeparableLayer(Kernel::HLERequestContext& ctx) { | ||
| 466 | LOG_WARNING(Service_AM, "(STUBBED) called"); | ||
| 467 | |||
| 468 | // TODO(Subv): Find out how AM determines the display to use, for now just | ||
| 469 | // create the layer in the Default display. | ||
| 470 | // This calls nn::vi::CreateRecordingLayer() which creates another layer. | ||
| 471 | // Currently we do not support more than 1 layer per display, output 1 layer id for now. | ||
| 472 | // Outputting 1 layer id instead of the expected 2 has not been observed to cause any adverse | ||
| 473 | // side effects. | ||
| 474 | // TODO: Support multiple layers | ||
| 475 | const auto display_id = nvflinger->OpenDisplay("Default"); | ||
| 476 | const auto layer_id = nvflinger->CreateLayer(*display_id); | ||
| 477 | |||
| 478 | IPC::ResponseBuilder rb{ctx, 4}; | ||
| 479 | rb.Push(RESULT_SUCCESS); | ||
| 480 | rb.Push(*layer_id); | ||
| 481 | } | ||
| 482 | |||
| 465 | void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) { | 483 | void ISelfController::SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx) { |
| 466 | LOG_WARNING(Service_AM, "(STUBBED) called"); | 484 | LOG_WARNING(Service_AM, "(STUBBED) called"); |
| 467 | 485 | ||
| @@ -731,14 +749,14 @@ void ICommonStateGetter::GetDefaultDisplayResolution(Kernel::HLERequestContext& | |||
| 731 | 749 | ||
| 732 | if (Settings::values.use_docked_mode) { | 750 | if (Settings::values.use_docked_mode) { |
| 733 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) * | 751 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) * |
| 734 | static_cast<u32>(Settings::values.resolution_factor)); | 752 | static_cast<u32>(Settings::values.resolution_factor.GetValue())); |
| 735 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) * | 753 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) * |
| 736 | static_cast<u32>(Settings::values.resolution_factor)); | 754 | static_cast<u32>(Settings::values.resolution_factor.GetValue())); |
| 737 | } else { | 755 | } else { |
| 738 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth) * | 756 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth) * |
| 739 | static_cast<u32>(Settings::values.resolution_factor)); | 757 | static_cast<u32>(Settings::values.resolution_factor.GetValue())); |
| 740 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight) * | 758 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight) * |
| 741 | static_cast<u32>(Settings::values.resolution_factor)); | 759 | static_cast<u32>(Settings::values.resolution_factor.GetValue())); |
| 742 | } | 760 | } |
| 743 | } | 761 | } |
| 744 | 762 | ||
diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 2f69466ec..6cfb11b48 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h | |||
| @@ -140,6 +140,7 @@ private: | |||
| 140 | void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx); | 140 | void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx); |
| 141 | void SetAlbumImageOrientation(Kernel::HLERequestContext& ctx); | 141 | void SetAlbumImageOrientation(Kernel::HLERequestContext& ctx); |
| 142 | void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx); | 142 | void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx); |
| 143 | void CreateManagedDisplaySeparableLayer(Kernel::HLERequestContext& ctx); | ||
| 143 | void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx); | 144 | void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx); |
| 144 | void SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx); | 145 | void SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx); |
| 145 | void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx); | 146 | void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx); |
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index f19affce7..11aa74828 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp | |||
| @@ -121,11 +121,83 @@ public: | |||
| 121 | {39, nullptr, "PrepareShutdown"}, | 121 | {39, nullptr, "PrepareShutdown"}, |
| 122 | {40, nullptr, "ListApplyDeltaTask"}, | 122 | {40, nullptr, "ListApplyDeltaTask"}, |
| 123 | {41, nullptr, "ClearNotEnoughSpaceStateOfApplyDeltaTask"}, | 123 | {41, nullptr, "ClearNotEnoughSpaceStateOfApplyDeltaTask"}, |
| 124 | {42, nullptr, "Unknown1"}, | 124 | {42, nullptr, "Unknown42"}, |
| 125 | {43, nullptr, "Unknown2"}, | 125 | {43, nullptr, "Unknown43"}, |
| 126 | {44, nullptr, "Unknown3"}, | 126 | {44, nullptr, "Unknown44"}, |
| 127 | {45, nullptr, "Unknown4"}, | 127 | {45, nullptr, "Unknown45"}, |
| 128 | {46, nullptr, "Unknown5"}, | 128 | {46, nullptr, "Unknown46"}, |
| 129 | {47, nullptr, "Unknown47"}, | ||
| 130 | {48, nullptr, "Unknown48"}, | ||
| 131 | {49, nullptr, "Unknown49"}, | ||
| 132 | {50, nullptr, "Unknown50"}, | ||
| 133 | {51, nullptr, "Unknown51"}, | ||
| 134 | {52, nullptr, "Unknown52"}, | ||
| 135 | {53, nullptr, "Unknown53"}, | ||
| 136 | {54, nullptr, "Unknown54"}, | ||
| 137 | {55, nullptr, "Unknown55"}, | ||
| 138 | {56, nullptr, "Unknown56"}, | ||
| 139 | {57, nullptr, "Unknown57"}, | ||
| 140 | {58, nullptr, "Unknown58"}, | ||
| 141 | {59, nullptr, "Unknown59"}, | ||
| 142 | {60, nullptr, "Unknown60"}, | ||
| 143 | {61, nullptr, "Unknown61"}, | ||
| 144 | {62, nullptr, "Unknown62"}, | ||
| 145 | {63, nullptr, "Unknown63"}, | ||
| 146 | {64, nullptr, "Unknown64"}, | ||
| 147 | {65, nullptr, "Unknown65"}, | ||
| 148 | {66, nullptr, "Unknown66"}, | ||
| 149 | {67, nullptr, "Unknown67"}, | ||
| 150 | {68, nullptr, "Unknown68"}, | ||
| 151 | {69, nullptr, "Unknown69"}, | ||
| 152 | {70, nullptr, "Unknown70"}, | ||
| 153 | {71, nullptr, "Unknown71"}, | ||
| 154 | {72, nullptr, "Unknown72"}, | ||
| 155 | {73, nullptr, "Unknown73"}, | ||
| 156 | {74, nullptr, "Unknown74"}, | ||
| 157 | {75, nullptr, "Unknown75"}, | ||
| 158 | {76, nullptr, "Unknown76"}, | ||
| 159 | {77, nullptr, "Unknown77"}, | ||
| 160 | {78, nullptr, "Unknown78"}, | ||
| 161 | {79, nullptr, "Unknown79"}, | ||
| 162 | {80, nullptr, "Unknown80"}, | ||
| 163 | {81, nullptr, "Unknown81"}, | ||
| 164 | {82, nullptr, "Unknown82"}, | ||
| 165 | {83, nullptr, "Unknown83"}, | ||
| 166 | {84, nullptr, "Unknown84"}, | ||
| 167 | {85, nullptr, "Unknown85"}, | ||
| 168 | {86, nullptr, "Unknown86"}, | ||
| 169 | {87, nullptr, "Unknown87"}, | ||
| 170 | {88, nullptr, "Unknown88"}, | ||
| 171 | {89, nullptr, "Unknown89"}, | ||
| 172 | {90, nullptr, "Unknown90"}, | ||
| 173 | {91, nullptr, "Unknown91"}, | ||
| 174 | {92, nullptr, "Unknown92"}, | ||
| 175 | {93, nullptr, "Unknown93"}, | ||
| 176 | {94, nullptr, "Unknown94"}, | ||
| 177 | {95, nullptr, "Unknown95"}, | ||
| 178 | {96, nullptr, "Unknown96"}, | ||
| 179 | {97, nullptr, "Unknown97"}, | ||
| 180 | {98, nullptr, "Unknown98"}, | ||
| 181 | {99, nullptr, "Unknown99"}, | ||
| 182 | {100, nullptr, "Unknown100"}, | ||
| 183 | {101, nullptr, "Unknown101"}, | ||
| 184 | {102, nullptr, "Unknown102"}, | ||
| 185 | {103, nullptr, "Unknown103"}, | ||
| 186 | {104, nullptr, "Unknown104"}, | ||
| 187 | {105, nullptr, "Unknown105"}, | ||
| 188 | {106, nullptr, "Unknown106"}, | ||
| 189 | {107, nullptr, "Unknown107"}, | ||
| 190 | {108, nullptr, "Unknown108"}, | ||
| 191 | {109, nullptr, "Unknown109"}, | ||
| 192 | {110, nullptr, "Unknown110"}, | ||
| 193 | {111, nullptr, "Unknown111"}, | ||
| 194 | {112, nullptr, "Unknown112"}, | ||
| 195 | {113, nullptr, "Unknown113"}, | ||
| 196 | {114, nullptr, "Unknown114"}, | ||
| 197 | {115, nullptr, "Unknown115"}, | ||
| 198 | {116, nullptr, "Unknown116"}, | ||
| 199 | {117, nullptr, "Unknown117"}, | ||
| 200 | {118, nullptr, "Unknown118"}, | ||
| 129 | }; | 201 | }; |
| 130 | // clang-format on | 202 | // clang-format on |
| 131 | 203 | ||
| @@ -142,6 +214,7 @@ public: | |||
| 142 | {1, nullptr, "RefreshDebugAvailability"}, | 214 | {1, nullptr, "RefreshDebugAvailability"}, |
| 143 | {2, nullptr, "ClearDebugResponse"}, | 215 | {2, nullptr, "ClearDebugResponse"}, |
| 144 | {3, nullptr, "RegisterDebugResponse"}, | 216 | {3, nullptr, "RegisterDebugResponse"}, |
| 217 | {4, nullptr, "IsLargeResourceAvailable"}, | ||
| 145 | }; | 218 | }; |
| 146 | // clang-format on | 219 | // clang-format on |
| 147 | 220 | ||
| @@ -164,6 +237,8 @@ public: | |||
| 164 | static const FunctionInfo functions[] = { | 237 | static const FunctionInfo functions[] = { |
| 165 | {0, nullptr, "RequestDeviceAuthenticationToken"}, | 238 | {0, nullptr, "RequestDeviceAuthenticationToken"}, |
| 166 | {1, nullptr, "RequestCachedDeviceAuthenticationToken"}, | 239 | {1, nullptr, "RequestCachedDeviceAuthenticationToken"}, |
| 240 | {2, nullptr, "RequestEdgeToken"}, | ||
| 241 | {3, nullptr, "RequestCachedEdgeToken"}, | ||
| 167 | {100, nullptr, "RequestRegisterDeviceAccount"}, | 242 | {100, nullptr, "RequestRegisterDeviceAccount"}, |
| 168 | {101, nullptr, "RequestUnregisterDeviceAccount"}, | 243 | {101, nullptr, "RequestUnregisterDeviceAccount"}, |
| 169 | {102, nullptr, "RequestDeviceAccountStatus"}, | 244 | {102, nullptr, "RequestDeviceAccountStatus"}, |
| @@ -181,7 +256,8 @@ public: | |||
| 181 | {305, nullptr, "RequestCreateVirtualAccount"}, | 256 | {305, nullptr, "RequestCreateVirtualAccount"}, |
| 182 | {306, nullptr, "RequestDeviceLinkStatus"}, | 257 | {306, nullptr, "RequestDeviceLinkStatus"}, |
| 183 | {400, nullptr, "GetAccountByVirtualAccount"}, | 258 | {400, nullptr, "GetAccountByVirtualAccount"}, |
| 184 | {500, nullptr, "RequestSyncTicket"}, | 259 | {401, nullptr, "GetVirtualAccount"}, |
| 260 | {500, nullptr, "RequestSyncTicketLegacy"}, | ||
| 185 | {501, nullptr, "RequestDownloadTicket"}, | 261 | {501, nullptr, "RequestDownloadTicket"}, |
| 186 | {502, nullptr, "RequestDownloadTicketForPrepurchasedContents"}, | 262 | {502, nullptr, "RequestDownloadTicketForPrepurchasedContents"}, |
| 187 | {503, nullptr, "RequestSyncTicket"}, | 263 | {503, nullptr, "RequestSyncTicket"}, |
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp index f38d01084..8fa16fb08 100644 --- a/src/core/hle/service/npns/npns.cpp +++ b/src/core/hle/service/npns/npns.cpp | |||
| @@ -30,6 +30,7 @@ public: | |||
| 30 | {23, nullptr, "DestroyToken"}, | 30 | {23, nullptr, "DestroyToken"}, |
| 31 | {24, nullptr, "DestroyTokenWithApplicationId"}, | 31 | {24, nullptr, "DestroyTokenWithApplicationId"}, |
| 32 | {25, nullptr, "QueryIsTokenValid"}, | 32 | {25, nullptr, "QueryIsTokenValid"}, |
| 33 | {26, nullptr, "ListenToMyApplicationId"}, | ||
| 33 | {31, nullptr, "UploadTokenToBaaS"}, | 34 | {31, nullptr, "UploadTokenToBaaS"}, |
| 34 | {32, nullptr, "DestroyTokenForBaaS"}, | 35 | {32, nullptr, "DestroyTokenForBaaS"}, |
| 35 | {33, nullptr, "CreateTokenForBaaS"}, | 36 | {33, nullptr, "CreateTokenForBaaS"}, |
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index 7e5ceccdb..886450be2 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp | |||
| @@ -104,7 +104,7 @@ IApplicationManagerInterface::IApplicationManagerInterface() | |||
| 104 | {94, nullptr, "LaunchApplication"}, | 104 | {94, nullptr, "LaunchApplication"}, |
| 105 | {95, nullptr, "GetApplicationLaunchInfo"}, | 105 | {95, nullptr, "GetApplicationLaunchInfo"}, |
| 106 | {96, nullptr, "AcquireApplicationLaunchInfo"}, | 106 | {96, nullptr, "AcquireApplicationLaunchInfo"}, |
| 107 | {97, nullptr, "GetMainApplicationProgramIndex2"}, | 107 | {97, nullptr, "GetMainApplicationProgramIndexByApplicationLaunchInfo"}, |
| 108 | {98, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, | 108 | {98, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, |
| 109 | {99, nullptr, "LaunchDevMenu"}, | 109 | {99, nullptr, "LaunchDevMenu"}, |
| 110 | {100, nullptr, "ResetToFactorySettings"}, | 110 | {100, nullptr, "ResetToFactorySettings"}, |
| @@ -254,7 +254,7 @@ IApplicationManagerInterface::IApplicationManagerInterface() | |||
| 254 | {2170, nullptr, "GetRightsEnvironmentStatus"}, | 254 | {2170, nullptr, "GetRightsEnvironmentStatus"}, |
| 255 | {2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"}, | 255 | {2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"}, |
| 256 | {2180, nullptr, "RequestExtendRightsInRightsEnvironment"}, | 256 | {2180, nullptr, "RequestExtendRightsInRightsEnvironment"}, |
| 257 | {2181, nullptr, "GetLastResultOfExtendRightsInRightsEnvironment"}, | 257 | {2181, nullptr, "GetResultOfExtendRightsInRightsEnvironment"}, |
| 258 | {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"}, | 258 | {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"}, |
| 259 | {2190, nullptr, "GetRightsEnvironmentHandleForApplication"}, | 259 | {2190, nullptr, "GetRightsEnvironmentHandleForApplication"}, |
| 260 | {2199, nullptr, "GetRightsEnvironmentCountForDebug"}, | 260 | {2199, nullptr, "GetRightsEnvironmentCountForDebug"}, |
| @@ -366,7 +366,8 @@ ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage( | |||
| 366 | LOG_DEBUG(Service_NS, "called with supported_languages={:08X}", supported_languages); | 366 | LOG_DEBUG(Service_NS, "called with supported_languages={:08X}", supported_languages); |
| 367 | 367 | ||
| 368 | // Get language code from settings | 368 | // Get language code from settings |
| 369 | const auto language_code = Set::GetLanguageCodeFromIndex(Settings::values.language_index); | 369 | const auto language_code = |
| 370 | Set::GetLanguageCodeFromIndex(Settings::values.language_index.GetValue()); | ||
| 370 | 371 | ||
| 371 | // Convert to application language, get priority list | 372 | // Convert to application language, get priority list |
| 372 | const auto application_language = ConvertToApplicationLanguage(language_code); | 373 | const auto application_language = ConvertToApplicationLanguage(language_code); |
| @@ -445,8 +446,8 @@ IApplicationVersionInterface::IApplicationVersionInterface() | |||
| 445 | 446 | ||
| 446 | IApplicationVersionInterface::~IApplicationVersionInterface() = default; | 447 | IApplicationVersionInterface::~IApplicationVersionInterface() = default; |
| 447 | 448 | ||
| 448 | IContentManagerInterface::IContentManagerInterface() | 449 | IContentManagementInterface::IContentManagementInterface() |
| 449 | : ServiceFramework{"IContentManagerInterface"} { | 450 | : ServiceFramework{"IContentManagementInterface"} { |
| 450 | // clang-format off | 451 | // clang-format off |
| 451 | static const FunctionInfo functions[] = { | 452 | static const FunctionInfo functions[] = { |
| 452 | {11, nullptr, "CalculateApplicationOccupiedSize"}, | 453 | {11, nullptr, "CalculateApplicationOccupiedSize"}, |
| @@ -463,7 +464,7 @@ IContentManagerInterface::IContentManagerInterface() | |||
| 463 | RegisterHandlers(functions); | 464 | RegisterHandlers(functions); |
| 464 | } | 465 | } |
| 465 | 466 | ||
| 466 | IContentManagerInterface::~IContentManagerInterface() = default; | 467 | IContentManagementInterface::~IContentManagementInterface() = default; |
| 467 | 468 | ||
| 468 | IDocumentInterface::IDocumentInterface() : ServiceFramework{"IDocumentInterface"} { | 469 | IDocumentInterface::IDocumentInterface() : ServiceFramework{"IDocumentInterface"} { |
| 469 | // clang-format off | 470 | // clang-format off |
| @@ -545,7 +546,7 @@ NS::NS(const char* name) : ServiceFramework{name} { | |||
| 545 | {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"}, | 546 | {7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"}, |
| 546 | {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"}, | 547 | {7996, &NS::PushInterface<IApplicationManagerInterface>, "GetApplicationManagerInterface"}, |
| 547 | {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"}, | 548 | {7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"}, |
| 548 | {7998, &NS::PushInterface<IContentManagerInterface>, "GetContentManagementInterface"}, | 549 | {7998, &NS::PushInterface<IContentManagementInterface>, "GetContentManagementInterface"}, |
| 549 | {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"}, | 550 | {7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"}, |
| 550 | }; | 551 | }; |
| 551 | // clang-format on | 552 | // clang-format on |
| @@ -572,9 +573,9 @@ public: | |||
| 572 | {6, nullptr, "TerminateApplication"}, | 573 | {6, nullptr, "TerminateApplication"}, |
| 573 | {7, nullptr, "PrepareLaunchProgramFromHost"}, | 574 | {7, nullptr, "PrepareLaunchProgramFromHost"}, |
| 574 | {8, nullptr, "LaunchApplication"}, | 575 | {8, nullptr, "LaunchApplication"}, |
| 575 | {9, nullptr, "LaunchApplicationWithStorageId"}, | 576 | {9, nullptr, "LaunchApplicationWithStorageIdForDevelop"}, |
| 576 | {10, nullptr, "TerminateApplication2"}, | 577 | {10, nullptr, "IsSystemMemoryResourceLimitBoosted"}, |
| 577 | {11, nullptr, "GetRunningApplicationProcessId"}, | 578 | {11, nullptr, "GetRunningApplicationProcessIdForDevelop"}, |
| 578 | {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActive"}, | 579 | {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActive"}, |
| 579 | {13, nullptr, "CreateApplicationResourceForDevelop"}, | 580 | {13, nullptr, "CreateApplicationResourceForDevelop"}, |
| 580 | {14, nullptr, "IsPreomiaForDevelop"}, | 581 | {14, nullptr, "IsPreomiaForDevelop"}, |
| @@ -636,6 +637,10 @@ public: | |||
| 636 | {9, nullptr, "GetSystemUpdateNotificationEventForContentDelivery"}, | 637 | {9, nullptr, "GetSystemUpdateNotificationEventForContentDelivery"}, |
| 637 | {10, nullptr, "NotifySystemUpdateForContentDelivery"}, | 638 | {10, nullptr, "NotifySystemUpdateForContentDelivery"}, |
| 638 | {11, nullptr, "PrepareShutdown"}, | 639 | {11, nullptr, "PrepareShutdown"}, |
| 640 | {12, nullptr, "Unknown12"}, | ||
| 641 | {13, nullptr, "Unknown13"}, | ||
| 642 | {14, nullptr, "Unknown14"}, | ||
| 643 | {15, nullptr, "Unknown15"}, | ||
| 639 | {16, nullptr, "DestroySystemUpdateTask"}, | 644 | {16, nullptr, "DestroySystemUpdateTask"}, |
| 640 | {17, nullptr, "RequestSendSystemUpdate"}, | 645 | {17, nullptr, "RequestSendSystemUpdate"}, |
| 641 | {18, nullptr, "GetSendSystemUpdateProgress"}, | 646 | {18, nullptr, "GetSendSystemUpdateProgress"}, |
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h index 13a64ad88..c2554b878 100644 --- a/src/core/hle/service/ns/ns.h +++ b/src/core/hle/service/ns/ns.h | |||
| @@ -40,10 +40,10 @@ public: | |||
| 40 | ~IApplicationVersionInterface() override; | 40 | ~IApplicationVersionInterface() override; |
| 41 | }; | 41 | }; |
| 42 | 42 | ||
| 43 | class IContentManagerInterface final : public ServiceFramework<IContentManagerInterface> { | 43 | class IContentManagementInterface final : public ServiceFramework<IContentManagementInterface> { |
| 44 | public: | 44 | public: |
| 45 | explicit IContentManagerInterface(); | 45 | explicit IContentManagementInterface(); |
| 46 | ~IContentManagerInterface() override; | 46 | ~IContentManagementInterface() override; |
| 47 | }; | 47 | }; |
| 48 | 48 | ||
| 49 | class IDocumentInterface final : public ServiceFramework<IDocumentInterface> { | 49 | class IDocumentInterface final : public ServiceFramework<IDocumentInterface> { |
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 6efdf1606..40838a225 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp | |||
| @@ -163,7 +163,7 @@ PL_U::PL_U(Core::System& system) | |||
| 163 | {5, &PL_U::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"}, | 163 | {5, &PL_U::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"}, |
| 164 | {6, nullptr, "GetSharedFontInOrderOfPriorityForSystem"}, | 164 | {6, nullptr, "GetSharedFontInOrderOfPriorityForSystem"}, |
| 165 | {100, nullptr, "RequestApplicationFunctionAuthorization"}, | 165 | {100, nullptr, "RequestApplicationFunctionAuthorization"}, |
| 166 | {101, nullptr, "RequestApplicationFunctionAuthorizationForSystem"}, | 166 | {101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"}, |
| 167 | {102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"}, | 167 | {102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"}, |
| 168 | {1000, nullptr, "LoadNgWordDataForPlatformRegionChina"}, | 168 | {1000, nullptr, "LoadNgWordDataForPlatformRegionChina"}, |
| 169 | {1001, nullptr, "GetNgWordDataSizeForPlatformRegionChina"}, | 169 | {1001, nullptr, "GetNgWordDataSizeForPlatformRegionChina"}, |
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index c8ea6c661..deaf0808b 100644 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp | |||
| @@ -144,7 +144,7 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) { | |||
| 144 | } | 144 | } |
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) { | 147 | void NVDRV::SetAruid(Kernel::HLERequestContext& ctx) { |
| 148 | IPC::RequestParser rp{ctx}; | 148 | IPC::RequestParser rp{ctx}; |
| 149 | pid = rp.Pop<u64>(); | 149 | pid = rp.Pop<u64>(); |
| 150 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x{:X}", pid); | 150 | LOG_WARNING(Service_NVDRV, "(STUBBED) called, pid=0x{:X}", pid); |
| @@ -154,7 +154,7 @@ void NVDRV::SetClientPID(Kernel::HLERequestContext& ctx) { | |||
| 154 | rb.Push<u32>(0); | 154 | rb.Push<u32>(0); |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | void NVDRV::FinishInitialize(Kernel::HLERequestContext& ctx) { | 157 | void NVDRV::SetGraphicsFirmwareMemoryMarginEnabled(Kernel::HLERequestContext& ctx) { |
| 158 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); | 158 | LOG_WARNING(Service_NVDRV, "(STUBBED) called"); |
| 159 | 159 | ||
| 160 | IPC::ResponseBuilder rb{ctx, 2}; | 160 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -187,13 +187,14 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name) | |||
| 187 | {4, &NVDRV::QueryEvent, "QueryEvent"}, | 187 | {4, &NVDRV::QueryEvent, "QueryEvent"}, |
| 188 | {5, nullptr, "MapSharedMem"}, | 188 | {5, nullptr, "MapSharedMem"}, |
| 189 | {6, &NVDRV::GetStatus, "GetStatus"}, | 189 | {6, &NVDRV::GetStatus, "GetStatus"}, |
| 190 | {7, nullptr, "ForceSetClientPID"}, | 190 | {7, nullptr, "SetAruidForTest"}, |
| 191 | {8, &NVDRV::SetClientPID, "SetClientPID"}, | 191 | {8, &NVDRV::SetAruid, "SetAruid"}, |
| 192 | {9, &NVDRV::DumpGraphicsMemoryInfo, "DumpGraphicsMemoryInfo"}, | 192 | {9, &NVDRV::DumpGraphicsMemoryInfo, "DumpGraphicsMemoryInfo"}, |
| 193 | {10, nullptr, "InitializeDevtools"}, | 193 | {10, nullptr, "InitializeDevtools"}, |
| 194 | {11, &NVDRV::Ioctl2, "Ioctl2"}, | 194 | {11, &NVDRV::Ioctl2, "Ioctl2"}, |
| 195 | {12, &NVDRV::Ioctl3, "Ioctl3"}, | 195 | {12, &NVDRV::Ioctl3, "Ioctl3"}, |
| 196 | {13, &NVDRV::FinishInitialize, "FinishInitialize"}, | 196 | {13, &NVDRV::SetGraphicsFirmwareMemoryMarginEnabled, |
| 197 | "SetGraphicsFirmwareMemoryMarginEnabled"}, | ||
| 197 | }; | 198 | }; |
| 198 | RegisterHandlers(functions); | 199 | RegisterHandlers(functions); |
| 199 | } | 200 | } |
diff --git a/src/core/hle/service/nvdrv/interface.h b/src/core/hle/service/nvdrv/interface.h index 9269ce00c..72e17a728 100644 --- a/src/core/hle/service/nvdrv/interface.h +++ b/src/core/hle/service/nvdrv/interface.h | |||
| @@ -29,8 +29,8 @@ private: | |||
| 29 | void Close(Kernel::HLERequestContext& ctx); | 29 | void Close(Kernel::HLERequestContext& ctx); |
| 30 | void Initialize(Kernel::HLERequestContext& ctx); | 30 | void Initialize(Kernel::HLERequestContext& ctx); |
| 31 | void QueryEvent(Kernel::HLERequestContext& ctx); | 31 | void QueryEvent(Kernel::HLERequestContext& ctx); |
| 32 | void SetClientPID(Kernel::HLERequestContext& ctx); | 32 | void SetAruid(Kernel::HLERequestContext& ctx); |
| 33 | void FinishInitialize(Kernel::HLERequestContext& ctx); | 33 | void SetGraphicsFirmwareMemoryMarginEnabled(Kernel::HLERequestContext& ctx); |
| 34 | void GetStatus(Kernel::HLERequestContext& ctx); | 34 | void GetStatus(Kernel::HLERequestContext& ctx); |
| 35 | void DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx); | 35 | void DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx); |
| 36 | void IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version); | 36 | void IoctlBase(Kernel::HLERequestContext& ctx, IoctlVersion version); |
diff --git a/src/core/hle/service/nvdrv/nvmemp.cpp b/src/core/hle/service/nvdrv/nvmemp.cpp index b7b8b7a1b..73b37e805 100644 --- a/src/core/hle/service/nvdrv/nvmemp.cpp +++ b/src/core/hle/service/nvdrv/nvmemp.cpp | |||
| @@ -10,19 +10,19 @@ namespace Service::Nvidia { | |||
| 10 | 10 | ||
| 11 | NVMEMP::NVMEMP() : ServiceFramework("nvmemp") { | 11 | NVMEMP::NVMEMP() : ServiceFramework("nvmemp") { |
| 12 | static const FunctionInfo functions[] = { | 12 | static const FunctionInfo functions[] = { |
| 13 | {0, &NVMEMP::Cmd0, "Cmd0"}, | 13 | {0, &NVMEMP::Open, "Open"}, |
| 14 | {1, &NVMEMP::Cmd1, "Cmd1"}, | 14 | {1, &NVMEMP::GetAruid, "GetAruid"}, |
| 15 | }; | 15 | }; |
| 16 | RegisterHandlers(functions); | 16 | RegisterHandlers(functions); |
| 17 | } | 17 | } |
| 18 | 18 | ||
| 19 | NVMEMP::~NVMEMP() = default; | 19 | NVMEMP::~NVMEMP() = default; |
| 20 | 20 | ||
| 21 | void NVMEMP::Cmd0(Kernel::HLERequestContext& ctx) { | 21 | void NVMEMP::Open(Kernel::HLERequestContext& ctx) { |
| 22 | UNIMPLEMENTED(); | 22 | UNIMPLEMENTED(); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void NVMEMP::Cmd1(Kernel::HLERequestContext& ctx) { | 25 | void NVMEMP::GetAruid(Kernel::HLERequestContext& ctx) { |
| 26 | UNIMPLEMENTED(); | 26 | UNIMPLEMENTED(); |
| 27 | } | 27 | } |
| 28 | 28 | ||
diff --git a/src/core/hle/service/nvdrv/nvmemp.h b/src/core/hle/service/nvdrv/nvmemp.h index 6eafb1346..c453ee4db 100644 --- a/src/core/hle/service/nvdrv/nvmemp.h +++ b/src/core/hle/service/nvdrv/nvmemp.h | |||
| @@ -14,8 +14,8 @@ public: | |||
| 14 | ~NVMEMP() override; | 14 | ~NVMEMP() override; |
| 15 | 15 | ||
| 16 | private: | 16 | private: |
| 17 | void Cmd0(Kernel::HLERequestContext& ctx); | 17 | void Open(Kernel::HLERequestContext& ctx); |
| 18 | void Cmd1(Kernel::HLERequestContext& ctx); | 18 | void GetAruid(Kernel::HLERequestContext& ctx); |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | } // namespace Service::Nvidia | 21 | } // namespace Service::Nvidia |
diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp index 39cf05eba..c568a0adc 100644 --- a/src/core/hle/service/pcie/pcie.cpp +++ b/src/core/hle/service/pcie/pcie.cpp | |||
| @@ -36,6 +36,9 @@ public: | |||
| 36 | {18, nullptr, "ReleaseIrq"}, | 36 | {18, nullptr, "ReleaseIrq"}, |
| 37 | {19, nullptr, "SetIrqEnable"}, | 37 | {19, nullptr, "SetIrqEnable"}, |
| 38 | {20, nullptr, "SetAspmEnable"}, | 38 | {20, nullptr, "SetAspmEnable"}, |
| 39 | {21, nullptr, "SetResetUponResumeEnable"}, | ||
| 40 | {22, nullptr, "Unknown22"}, | ||
| 41 | {23, nullptr, "Unknown23"}, | ||
| 39 | }; | 42 | }; |
| 40 | // clang-format on | 43 | // clang-format on |
| 41 | 44 | ||
diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp index d6891a659..8bfc0276e 100644 --- a/src/core/hle/service/pcv/pcv.cpp +++ b/src/core/hle/service/pcv/pcv.cpp | |||
| @@ -42,6 +42,9 @@ public: | |||
| 42 | {24, nullptr, "GetModuleStateTable"}, | 42 | {24, nullptr, "GetModuleStateTable"}, |
| 43 | {25, nullptr, "GetPowerDomainStateTable"}, | 43 | {25, nullptr, "GetPowerDomainStateTable"}, |
| 44 | {26, nullptr, "GetFuseInfo"}, | 44 | {26, nullptr, "GetFuseInfo"}, |
| 45 | {27, nullptr, "GetDramId"}, | ||
| 46 | {28, nullptr, "IsPoweredOn"}, | ||
| 47 | {29, nullptr, "GetVoltage"}, | ||
| 45 | }; | 48 | }; |
| 46 | // clang-format on | 49 | // clang-format on |
| 47 | 50 | ||
diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp index 809eca0ab..f43122ad2 100644 --- a/src/core/hle/service/pm/pm.cpp +++ b/src/core/hle/service/pm/pm.cpp | |||
| @@ -78,13 +78,13 @@ public: | |||
| 78 | : ServiceFramework{"pm:dmnt"}, kernel(kernel) { | 78 | : ServiceFramework{"pm:dmnt"}, kernel(kernel) { |
| 79 | // clang-format off | 79 | // clang-format off |
| 80 | static const FunctionInfo functions[] = { | 80 | static const FunctionInfo functions[] = { |
| 81 | {0, nullptr, "GetDebugProcesses"}, | 81 | {0, nullptr, "GetJitDebugProcessIdList"}, |
| 82 | {1, nullptr, "StartDebugProcess"}, | 82 | {1, nullptr, "StartProcess"}, |
| 83 | {2, &DebugMonitor::GetTitlePid, "GetTitlePid"}, | 83 | {2, &DebugMonitor::GetProcessId, "GetProcessId"}, |
| 84 | {3, nullptr, "EnableDebugForTitleId"}, | 84 | {3, nullptr, "HookToCreateProcess"}, |
| 85 | {4, &DebugMonitor::GetApplicationPid, "GetApplicationPid"}, | 85 | {4, &DebugMonitor::GetApplicationProcessId, "GetApplicationProcessId"}, |
| 86 | {5, nullptr, "EnableDebugForApplication"}, | 86 | {5, nullptr, "HookToCreateApplicationProgress"}, |
| 87 | {6, nullptr, "DisableDebug"}, | 87 | {6, nullptr, "ClearHook"}, |
| 88 | }; | 88 | }; |
| 89 | // clang-format on | 89 | // clang-format on |
| 90 | 90 | ||
| @@ -92,7 +92,7 @@ public: | |||
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | private: | 94 | private: |
| 95 | void GetTitlePid(Kernel::HLERequestContext& ctx) { | 95 | void GetProcessId(Kernel::HLERequestContext& ctx) { |
| 96 | IPC::RequestParser rp{ctx}; | 96 | IPC::RequestParser rp{ctx}; |
| 97 | const auto title_id = rp.PopRaw<u64>(); | 97 | const auto title_id = rp.PopRaw<u64>(); |
| 98 | 98 | ||
| @@ -114,7 +114,7 @@ private: | |||
| 114 | rb.Push((*process)->GetProcessID()); | 114 | rb.Push((*process)->GetProcessID()); |
| 115 | } | 115 | } |
| 116 | 116 | ||
| 117 | void GetApplicationPid(Kernel::HLERequestContext& ctx) { | 117 | void GetApplicationProcessId(Kernel::HLERequestContext& ctx) { |
| 118 | LOG_DEBUG(Service_PM, "called"); | 118 | LOG_DEBUG(Service_PM, "called"); |
| 119 | GetApplicationPidGeneric(ctx, kernel.GetProcessList()); | 119 | GetApplicationPidGeneric(ctx, kernel.GetProcessList()); |
| 120 | } | 120 | } |
| @@ -163,15 +163,15 @@ public: | |||
| 163 | : ServiceFramework{"pm:shell"}, kernel(kernel) { | 163 | : ServiceFramework{"pm:shell"}, kernel(kernel) { |
| 164 | // clang-format off | 164 | // clang-format off |
| 165 | static const FunctionInfo functions[] = { | 165 | static const FunctionInfo functions[] = { |
| 166 | {0, nullptr, "LaunchProcess"}, | 166 | {0, nullptr, "LaunchProgram"}, |
| 167 | {1, nullptr, "TerminateProcessByPid"}, | 167 | {1, nullptr, "TerminateProcess"}, |
| 168 | {2, nullptr, "TerminateProcessByTitleId"}, | 168 | {2, nullptr, "TerminateProgram"}, |
| 169 | {3, nullptr, "GetProcessEventWaiter"}, | 169 | {3, nullptr, "GetProcessEventHandle"}, |
| 170 | {4, nullptr, "GetProcessEventType"}, | 170 | {4, nullptr, "GetProcessEventInfo"}, |
| 171 | {5, nullptr, "NotifyBootFinished"}, | 171 | {5, nullptr, "NotifyBootFinished"}, |
| 172 | {6, &Shell::GetApplicationPid, "GetApplicationPid"}, | 172 | {6, &Shell::GetApplicationProcessIdForShell, "GetApplicationProcessIdForShell"}, |
| 173 | {7, nullptr, "BoostSystemMemoryResourceLimit"}, | 173 | {7, nullptr, "BoostSystemMemoryResourceLimit"}, |
| 174 | {8, nullptr, "EnableAdditionalSystemThreads"}, | 174 | {8, nullptr, "BoostApplicationThreadResourceLimit"}, |
| 175 | {9, nullptr, "GetBootFinishedEventHandle"}, | 175 | {9, nullptr, "GetBootFinishedEventHandle"}, |
| 176 | }; | 176 | }; |
| 177 | // clang-format on | 177 | // clang-format on |
| @@ -180,7 +180,7 @@ public: | |||
| 180 | } | 180 | } |
| 181 | 181 | ||
| 182 | private: | 182 | private: |
| 183 | void GetApplicationPid(Kernel::HLERequestContext& ctx) { | 183 | void GetApplicationProcessIdForShell(Kernel::HLERequestContext& ctx) { |
| 184 | LOG_DEBUG(Service_PM, "called"); | 184 | LOG_DEBUG(Service_PM, "called"); |
| 185 | GetApplicationPidGeneric(ctx, kernel.GetProcessList()); | 185 | GetApplicationPidGeneric(ctx, kernel.GetProcessList()); |
| 186 | } | 186 | } |
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index 67833d9af..cde3312da 100644 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp | |||
| @@ -42,6 +42,11 @@ public: | |||
| 42 | {40101, nullptr, "SetUserAgreementCheckEnabled"}, | 42 | {40101, nullptr, "SetUserAgreementCheckEnabled"}, |
| 43 | {50100, nullptr, "ReadAllApplicationReportFiles"}, | 43 | {50100, nullptr, "ReadAllApplicationReportFiles"}, |
| 44 | {90100, nullptr, "ReadAllReportFiles"}, | 44 | {90100, nullptr, "ReadAllReportFiles"}, |
| 45 | {90101, nullptr, "Unknown90101"}, | ||
| 46 | {90102, nullptr, "Unknown90102"}, | ||
| 47 | {90200, nullptr, "GetStatistics"}, | ||
| 48 | {90201, nullptr, "GetThroughputHistory"}, | ||
| 49 | {90300, nullptr, "GetLastUploadError"}, | ||
| 45 | }; | 50 | }; |
| 46 | // clang-format on | 51 | // clang-format on |
| 47 | 52 | ||
diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp index 53ec6b031..99e1c9042 100644 --- a/src/core/hle/service/psc/psc.cpp +++ b/src/core/hle/service/psc/psc.cpp | |||
| @@ -24,6 +24,8 @@ public: | |||
| 24 | {4, nullptr, "Cancel"}, | 24 | {4, nullptr, "Cancel"}, |
| 25 | {5, nullptr, "PrintModuleInformation"}, | 25 | {5, nullptr, "PrintModuleInformation"}, |
| 26 | {6, nullptr, "GetModuleInformation"}, | 26 | {6, nullptr, "GetModuleInformation"}, |
| 27 | {10, nullptr, "Unknown10"}, | ||
| 28 | {11, nullptr, "Unknown11"}, | ||
| 27 | }; | 29 | }; |
| 28 | // clang-format on | 30 | // clang-format on |
| 29 | 31 | ||
diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp index 12d154ecf..6d9e6bd09 100644 --- a/src/core/hle/service/ptm/psm.cpp +++ b/src/core/hle/service/ptm/psm.cpp | |||
| @@ -35,6 +35,7 @@ public: | |||
| 35 | {15, nullptr, "GetBatteryAgePercentage"}, | 35 | {15, nullptr, "GetBatteryAgePercentage"}, |
| 36 | {16, nullptr, "GetBatteryChargeInfoEvent"}, | 36 | {16, nullptr, "GetBatteryChargeInfoEvent"}, |
| 37 | {17, nullptr, "GetBatteryChargeInfoFields"}, | 37 | {17, nullptr, "GetBatteryChargeInfoFields"}, |
| 38 | {18, nullptr, "GetBatteryChargeCalibratedEvent"}, | ||
| 38 | }; | 39 | }; |
| 39 | // clang-format on | 40 | // clang-format on |
| 40 | 41 | ||
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp index e5cfd2101..34fe2fd82 100644 --- a/src/core/hle/service/set/set.cpp +++ b/src/core/hle/service/set/set.cpp | |||
| @@ -91,7 +91,7 @@ void GetAvailableLanguageCodesImpl(Kernel::HLERequestContext& ctx, std::size_t m | |||
| 91 | } | 91 | } |
| 92 | 92 | ||
| 93 | void GetKeyCodeMapImpl(Kernel::HLERequestContext& ctx) { | 93 | void GetKeyCodeMapImpl(Kernel::HLERequestContext& ctx) { |
| 94 | const auto language_code = available_language_codes[Settings::values.language_index]; | 94 | const auto language_code = available_language_codes[Settings::values.language_index.GetValue()]; |
| 95 | const auto key_code = | 95 | const auto key_code = |
| 96 | std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), | 96 | std::find_if(language_to_layout.cbegin(), language_to_layout.cend(), |
| 97 | [=](const auto& element) { return element.first == language_code; }); | 97 | [=](const auto& element) { return element.first == language_code; }); |
| @@ -99,7 +99,7 @@ void GetKeyCodeMapImpl(Kernel::HLERequestContext& ctx) { | |||
| 99 | if (key_code == language_to_layout.cend()) { | 99 | if (key_code == language_to_layout.cend()) { |
| 100 | LOG_ERROR(Service_SET, | 100 | LOG_ERROR(Service_SET, |
| 101 | "Could not find keyboard layout for language index {}, defaulting to English us", | 101 | "Could not find keyboard layout for language index {}, defaulting to English us", |
| 102 | Settings::values.language_index); | 102 | Settings::values.language_index.GetValue()); |
| 103 | } else { | 103 | } else { |
| 104 | layout = key_code->second; | 104 | layout = key_code->second; |
| 105 | } | 105 | } |
| @@ -163,11 +163,11 @@ void SET::GetQuestFlag(Kernel::HLERequestContext& ctx) { | |||
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { | 165 | void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { |
| 166 | LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index); | 166 | LOG_DEBUG(Service_SET, "called {}", Settings::values.language_index.GetValue()); |
| 167 | 167 | ||
| 168 | IPC::ResponseBuilder rb{ctx, 4}; | 168 | IPC::ResponseBuilder rb{ctx, 4}; |
| 169 | rb.Push(RESULT_SUCCESS); | 169 | rb.Push(RESULT_SUCCESS); |
| 170 | rb.PushEnum(available_language_codes[Settings::values.language_index]); | 170 | rb.PushEnum(available_language_codes[Settings::values.language_index.GetValue()]); |
| 171 | } | 171 | } |
| 172 | 172 | ||
| 173 | void SET::GetRegionCode(Kernel::HLERequestContext& ctx) { | 173 | void SET::GetRegionCode(Kernel::HLERequestContext& ctx) { |
| @@ -175,7 +175,7 @@ void SET::GetRegionCode(Kernel::HLERequestContext& ctx) { | |||
| 175 | 175 | ||
| 176 | IPC::ResponseBuilder rb{ctx, 3}; | 176 | IPC::ResponseBuilder rb{ctx, 3}; |
| 177 | rb.Push(RESULT_SUCCESS); | 177 | rb.Push(RESULT_SUCCESS); |
| 178 | rb.Push(Settings::values.region_index); | 178 | rb.Push(Settings::values.region_index.GetValue()); |
| 179 | } | 179 | } |
| 180 | 180 | ||
| 181 | void SET::GetKeyCodeMap(Kernel::HLERequestContext& ctx) { | 181 | void SET::GetKeyCodeMap(Kernel::HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index 9cca84b31..972aaa6d9 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp | |||
| @@ -12,7 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | namespace Service::SM { | 13 | namespace Service::SM { |
| 14 | 14 | ||
| 15 | void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) { | 15 | void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) { |
| 16 | ASSERT_MSG(ctx.Session()->IsSession(), "Session is already a domain"); | 16 | ASSERT_MSG(ctx.Session()->IsSession(), "Session is already a domain"); |
| 17 | LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId()); | 17 | LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId()); |
| 18 | ctx.Session()->ConvertToDomain(); | 18 | ctx.Session()->ConvertToDomain(); |
| @@ -22,7 +22,7 @@ void Controller::ConvertSessionToDomain(Kernel::HLERequestContext& ctx) { | |||
| 22 | rb.Push<u32>(1); // Converted sessions start with 1 request handler | 22 | rb.Push<u32>(1); // Converted sessions start with 1 request handler |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { | 25 | void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { |
| 26 | // TODO(bunnei): This is just creating a new handle to the same Session. I assume this is wrong | 26 | // TODO(bunnei): This is just creating a new handle to the same Session. I assume this is wrong |
| 27 | // and that we probably want to actually make an entirely new Session, but we still need to | 27 | // and that we probably want to actually make an entirely new Session, but we still need to |
| 28 | // verify this on hardware. | 28 | // verify this on hardware. |
| @@ -33,10 +33,10 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { | |||
| 33 | rb.PushMoveObjects(ctx.Session()->GetParent()->Client()); | 33 | rb.PushMoveObjects(ctx.Session()->GetParent()->Client()); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) { | 36 | void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { |
| 37 | LOG_WARNING(Service, "(STUBBED) called, using DuplicateSession"); | 37 | LOG_WARNING(Service, "(STUBBED) called, using CloneCurrentObject"); |
| 38 | 38 | ||
| 39 | DuplicateSession(ctx); | 39 | CloneCurrentObject(ctx); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { | 42 | void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { |
| @@ -47,13 +47,14 @@ void Controller::QueryPointerBufferSize(Kernel::HLERequestContext& ctx) { | |||
| 47 | rb.Push<u16>(0x1000); | 47 | rb.Push<u16>(0x1000); |
| 48 | } | 48 | } |
| 49 | 49 | ||
| 50 | // https://switchbrew.org/wiki/IPC_Marshalling | ||
| 50 | Controller::Controller() : ServiceFramework("IpcController") { | 51 | Controller::Controller() : ServiceFramework("IpcController") { |
| 51 | static const FunctionInfo functions[] = { | 52 | static const FunctionInfo functions[] = { |
| 52 | {0x00000000, &Controller::ConvertSessionToDomain, "ConvertSessionToDomain"}, | 53 | {0, &Controller::ConvertCurrentObjectToDomain, "ConvertCurrentObjectToDomain"}, |
| 53 | {0x00000001, nullptr, "ConvertDomainToSession"}, | 54 | {1, nullptr, "CopyFromCurrentDomain"}, |
| 54 | {0x00000002, &Controller::DuplicateSession, "DuplicateSession"}, | 55 | {2, &Controller::CloneCurrentObject, "CloneCurrentObject"}, |
| 55 | {0x00000003, &Controller::QueryPointerBufferSize, "QueryPointerBufferSize"}, | 56 | {3, &Controller::QueryPointerBufferSize, "QueryPointerBufferSize"}, |
| 56 | {0x00000004, &Controller::DuplicateSessionEx, "DuplicateSessionEx"}, | 57 | {4, &Controller::CloneCurrentObjectEx, "CloneCurrentObjectEx"}, |
| 57 | }; | 58 | }; |
| 58 | RegisterHandlers(functions); | 59 | RegisterHandlers(functions); |
| 59 | } | 60 | } |
diff --git a/src/core/hle/service/sm/controller.h b/src/core/hle/service/sm/controller.h index dc66c9e37..180c6da50 100644 --- a/src/core/hle/service/sm/controller.h +++ b/src/core/hle/service/sm/controller.h | |||
| @@ -14,9 +14,9 @@ public: | |||
| 14 | ~Controller() override; | 14 | ~Controller() override; |
| 15 | 15 | ||
| 16 | private: | 16 | private: |
| 17 | void ConvertSessionToDomain(Kernel::HLERequestContext& ctx); | 17 | void ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx); |
| 18 | void DuplicateSession(Kernel::HLERequestContext& ctx); | 18 | void CloneCurrentObject(Kernel::HLERequestContext& ctx); |
| 19 | void DuplicateSessionEx(Kernel::HLERequestContext& ctx); | 19 | void CloneCurrentObjectEx(Kernel::HLERequestContext& ctx); |
| 20 | void QueryPointerBufferSize(Kernel::HLERequestContext& ctx); | 20 | void QueryPointerBufferSize(Kernel::HLERequestContext& ctx); |
| 21 | }; | 21 | }; |
| 22 | 22 | ||
diff --git a/src/core/hle/service/sockets/nsd.cpp b/src/core/hle/service/sockets/nsd.cpp index dc70fd6fe..40d781124 100644 --- a/src/core/hle/service/sockets/nsd.cpp +++ b/src/core/hle/service/sockets/nsd.cpp | |||
| @@ -14,6 +14,7 @@ NSD::NSD(const char* name) : ServiceFramework(name) { | |||
| 14 | {12, nullptr, "GetDeviceId"}, | 14 | {12, nullptr, "GetDeviceId"}, |
| 15 | {13, nullptr, "DeleteSettings"}, | 15 | {13, nullptr, "DeleteSettings"}, |
| 16 | {14, nullptr, "ImportSettings"}, | 16 | {14, nullptr, "ImportSettings"}, |
| 17 | {15, nullptr, "SetChangeEnvironmentIdentifierDisabled"}, | ||
| 17 | {20, nullptr, "Resolve"}, | 18 | {20, nullptr, "Resolve"}, |
| 18 | {21, nullptr, "ResolveEx"}, | 19 | {21, nullptr, "ResolveEx"}, |
| 19 | {30, nullptr, "GetNasServiceSetting"}, | 20 | {30, nullptr, "GetNasServiceSetting"}, |
| @@ -28,6 +29,11 @@ NSD::NSD(const char* name) : ServiceFramework(name) { | |||
| 28 | {60, nullptr, "ReadSaveDataFromFsForTest"}, | 29 | {60, nullptr, "ReadSaveDataFromFsForTest"}, |
| 29 | {61, nullptr, "WriteSaveDataToFsForTest"}, | 30 | {61, nullptr, "WriteSaveDataToFsForTest"}, |
| 30 | {62, nullptr, "DeleteSaveDataOfFsForTest"}, | 31 | {62, nullptr, "DeleteSaveDataOfFsForTest"}, |
| 32 | {63, nullptr, "IsChangeEnvironmentIdentifierDisabled"}, | ||
| 33 | {64, nullptr, "SetWithoutDomainExchangeFqdns"}, | ||
| 34 | {100, nullptr, "GetApplicationServerEnvironmentType"}, | ||
| 35 | {101, nullptr, "SetApplicationServerEnvironmentType"}, | ||
| 36 | {102, nullptr, "DeleteApplicationServerEnvironmentType"}, | ||
| 31 | }; | 37 | }; |
| 32 | // clang-format on | 38 | // clang-format on |
| 33 | 39 | ||
diff --git a/src/core/hle/service/sockets/sfdnsres.cpp b/src/core/hle/service/sockets/sfdnsres.cpp index 852e71e4b..e3017451f 100644 --- a/src/core/hle/service/sockets/sfdnsres.cpp +++ b/src/core/hle/service/sockets/sfdnsres.cpp | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | 7 | ||
| 8 | namespace Service::Sockets { | 8 | namespace Service::Sockets { |
| 9 | 9 | ||
| 10 | void SFDNSRES::GetAddrInfo(Kernel::HLERequestContext& ctx) { | 10 | void SFDNSRES::GetAddrInfoRequest(Kernel::HLERequestContext& ctx) { |
| 11 | struct Parameters { | 11 | struct Parameters { |
| 12 | u8 use_nsd_resolve; | 12 | u8 use_nsd_resolve; |
| 13 | u32 unknown; | 13 | u32 unknown; |
| @@ -29,15 +29,20 @@ SFDNSRES::SFDNSRES() : ServiceFramework("sfdnsres") { | |||
| 29 | static const FunctionInfo functions[] = { | 29 | static const FunctionInfo functions[] = { |
| 30 | {0, nullptr, "SetDnsAddressesPrivate"}, | 30 | {0, nullptr, "SetDnsAddressesPrivate"}, |
| 31 | {1, nullptr, "GetDnsAddressPrivate"}, | 31 | {1, nullptr, "GetDnsAddressPrivate"}, |
| 32 | {2, nullptr, "GetHostByName"}, | 32 | {2, nullptr, "GetHostByNameRequest"}, |
| 33 | {3, nullptr, "GetHostByAddr"}, | 33 | {3, nullptr, "GetHostByAddrRequest"}, |
| 34 | {4, nullptr, "GetHostStringError"}, | 34 | {4, nullptr, "GetHostStringErrorRequest"}, |
| 35 | {5, nullptr, "GetGaiStringError"}, | 35 | {5, nullptr, "GetGaiStringErrorRequest"}, |
| 36 | {6, &SFDNSRES::GetAddrInfo, "GetAddrInfo"}, | 36 | {6, &SFDNSRES::GetAddrInfoRequest, "GetAddrInfoRequest"}, |
| 37 | {7, nullptr, "GetNameInfo"}, | 37 | {7, nullptr, "GetNameInfoRequest"}, |
| 38 | {8, nullptr, "RequestCancelHandle"}, | 38 | {8, nullptr, "RequestCancelHandleRequest"}, |
| 39 | {9, nullptr, "CancelSocketCall"}, | 39 | {9, nullptr, "CancelRequest"}, |
| 40 | {11, nullptr, "ClearDnsIpServerAddressArray"}, | 40 | {10, nullptr, "GetHostByNameRequestWithOptions"}, |
| 41 | {11, nullptr, "GetHostByAddrRequestWithOptions"}, | ||
| 42 | {12, nullptr, "GetAddrInfoRequestWithOptions"}, | ||
| 43 | {13, nullptr, "GetNameInfoRequestWithOptions"}, | ||
| 44 | {14, nullptr, "ResolverSetOptionRequest"}, | ||
| 45 | {15, nullptr, "ResolverGetOptionRequest"}, | ||
| 41 | }; | 46 | }; |
| 42 | RegisterHandlers(functions); | 47 | RegisterHandlers(functions); |
| 43 | } | 48 | } |
diff --git a/src/core/hle/service/sockets/sfdnsres.h b/src/core/hle/service/sockets/sfdnsres.h index eda432903..acd3647bb 100644 --- a/src/core/hle/service/sockets/sfdnsres.h +++ b/src/core/hle/service/sockets/sfdnsres.h | |||
| @@ -15,7 +15,7 @@ public: | |||
| 15 | ~SFDNSRES() override; | 15 | ~SFDNSRES() override; |
| 16 | 16 | ||
| 17 | private: | 17 | private: |
| 18 | void GetAddrInfo(Kernel::HLERequestContext& ctx); | 18 | void GetAddrInfoRequest(Kernel::HLERequestContext& ctx); |
| 19 | }; | 19 | }; |
| 20 | 20 | ||
| 21 | } // namespace Service::Sockets | 21 | } // namespace Service::Sockets |
diff --git a/src/core/hle/service/spl/module.cpp b/src/core/hle/service/spl/module.cpp index e724d4ab8..865ed3b91 100644 --- a/src/core/hle/service/spl/module.cpp +++ b/src/core/hle/service/spl/module.cpp | |||
| @@ -19,7 +19,7 @@ namespace Service::SPL { | |||
| 19 | 19 | ||
| 20 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) | 20 | Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) |
| 21 | : ServiceFramework(name), module(std::move(module)), | 21 | : ServiceFramework(name), module(std::move(module)), |
| 22 | rng(Settings::values.rng_seed.value_or(std::time(nullptr))) {} | 22 | rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr))) {} |
| 23 | 23 | ||
| 24 | Module::Interface::~Interface() = default; | 24 | Module::Interface::~Interface() = default; |
| 25 | 25 | ||
diff --git a/src/core/hle/service/spl/spl.cpp b/src/core/hle/service/spl/spl.cpp index 70cb41905..773551464 100644 --- a/src/core/hle/service/spl/spl.cpp +++ b/src/core/hle/service/spl/spl.cpp | |||
| @@ -9,35 +9,36 @@ namespace Service::SPL { | |||
| 9 | SPL::SPL(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "spl:") { | 9 | SPL::SPL(std::shared_ptr<Module> module) : Module::Interface(std::move(module), "spl:") { |
| 10 | static const FunctionInfo functions[] = { | 10 | static const FunctionInfo functions[] = { |
| 11 | {0, nullptr, "GetConfig"}, | 11 | {0, nullptr, "GetConfig"}, |
| 12 | {1, nullptr, "UserExpMod"}, | 12 | {1, nullptr, "ModularExponentiate"}, |
| 13 | {2, nullptr, "GenerateAesKek"}, | 13 | {2, nullptr, "GenerateAesKek"}, |
| 14 | {3, nullptr, "LoadAesKey"}, | 14 | {3, nullptr, "LoadAesKey"}, |
| 15 | {4, nullptr, "GenerateAesKey"}, | 15 | {4, nullptr, "GenerateAesKey"}, |
| 16 | {5, nullptr, "SetConfig"}, | 16 | {5, nullptr, "SetConfig"}, |
| 17 | {7, &SPL::GetRandomBytes, "GetRandomBytes"}, | 17 | {7, &SPL::GetRandomBytes, "GetRandomBytes"}, |
| 18 | {9, nullptr, "LoadSecureExpModKey"}, | 18 | {9, nullptr, "ImportLotusKey"}, |
| 19 | {10, nullptr, "SecureExpMod"}, | 19 | {10, nullptr, "DecryptLotusMessage"}, |
| 20 | {11, nullptr, "IsDevelopment"}, | 20 | {11, nullptr, "IsDevelopment"}, |
| 21 | {12, nullptr, "GenerateSpecificAesKey"}, | 21 | {12, nullptr, "GenerateSpecificAesKey"}, |
| 22 | {13, nullptr, "DecryptPrivk"}, | 22 | {13, nullptr, "DecryptDeviceUniqueData"}, |
| 23 | {14, nullptr, "DecryptAesKey"}, | 23 | {14, nullptr, "DecryptAesKey"}, |
| 24 | {15, nullptr, "DecryptAesCtr"}, | 24 | {15, nullptr, "CryptAesCtr"}, |
| 25 | {16, nullptr, "ComputeCmac"}, | 25 | {16, nullptr, "ComputeCmac"}, |
| 26 | {17, nullptr, "LoadRsaOaepKey"}, | 26 | {17, nullptr, "ImportEsKey"}, |
| 27 | {18, nullptr, "UnwrapRsaOaepWrappedTitleKey"}, | 27 | {18, nullptr, "UnwrapTitleKey"}, |
| 28 | {19, nullptr, "LoadTitleKey"}, | 28 | {19, nullptr, "LoadTitleKey"}, |
| 29 | {20, nullptr, "UnwrapAesWrappedTitleKey"}, | 29 | {20, nullptr, "PrepareEsCommonKey"}, |
| 30 | {21, nullptr, "LockAesEngine"}, | 30 | {21, nullptr, "AllocateAesKeyslot"}, |
| 31 | {22, nullptr, "UnlockAesEngine"}, | 31 | {22, nullptr, "DeallocateAesKeySlot"}, |
| 32 | {23, nullptr, "GetSplWaitEvent"}, | 32 | {23, nullptr, "GetAesKeyslotAvailableEvent"}, |
| 33 | {24, nullptr, "SetSharedData"}, | 33 | {24, nullptr, "SetBootReason"}, |
| 34 | {25, nullptr, "GetSharedData"}, | 34 | {25, nullptr, "GetBootReason"}, |
| 35 | {26, nullptr, "ImportSslRsaKey"}, | 35 | {26, nullptr, "DecryptAndStoreSslClientCertKey"}, |
| 36 | {27, nullptr, "SecureExpModWithSslKey"}, | 36 | {27, nullptr, "ModularExponentiateWithSslClientCertKey"}, |
| 37 | {28, nullptr, "ImportEsRsaKey"}, | 37 | {28, nullptr, "DecryptAndStoreDrmDeviceCertKey"}, |
| 38 | {29, nullptr, "SecureExpModWithEsKey"}, | 38 | {29, nullptr, "ModularExponentiateWithDrmDeviceCertKey"}, |
| 39 | {30, nullptr, "EncryptManuRsaKeyForImport"}, | 39 | {30, nullptr, "ReencryptDeviceUniqueData "}, |
| 40 | {31, nullptr, "GetPackage2Hash"}, | 40 | {31, nullptr, "PrepareEsArchiveKey"}, // This is also GetPackage2Hash? |
| 41 | {32, nullptr, "LoadPreparedAesKey"}, | ||
| 41 | }; | 42 | }; |
| 42 | RegisterHandlers(functions); | 43 | RegisterHandlers(functions); |
| 43 | } | 44 | } |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 4cf58a61a..13e4b3818 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -90,6 +90,13 @@ public: | |||
| 90 | : ServiceFramework("ISteadyClock"), clock_core{clock_core}, system{system} { | 90 | : ServiceFramework("ISteadyClock"), clock_core{clock_core}, system{system} { |
| 91 | static const FunctionInfo functions[] = { | 91 | static const FunctionInfo functions[] = { |
| 92 | {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"}, | 92 | {0, &ISteadyClock::GetCurrentTimePoint, "GetCurrentTimePoint"}, |
| 93 | {2, nullptr, "GetTestOffset"}, | ||
| 94 | {3, nullptr, "SetTestOffset"}, | ||
| 95 | {100, nullptr, "GetRtcValue"}, | ||
| 96 | {101, nullptr, "IsRtcResetDetected"}, | ||
| 97 | {102, nullptr, "GetSetupResultValue"}, | ||
| 98 | {200, nullptr, "GetInternalOffset"}, | ||
| 99 | {201, nullptr, "SetInternalOffset"}, | ||
| 93 | }; | 100 | }; |
| 94 | RegisterHandlers(functions); | 101 | RegisterHandlers(functions); |
| 95 | } | 102 | } |
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp index 58a9845fc..d033f8603 100644 --- a/src/core/hle/service/usb/usb.cpp +++ b/src/core/hle/service/usb/usb.cpp | |||
| @@ -20,7 +20,7 @@ public: | |||
| 20 | static const FunctionInfo functions[] = { | 20 | static const FunctionInfo functions[] = { |
| 21 | {0, nullptr, "GetDsEndpoint"}, | 21 | {0, nullptr, "GetDsEndpoint"}, |
| 22 | {1, nullptr, "GetSetupEvent"}, | 22 | {1, nullptr, "GetSetupEvent"}, |
| 23 | {2, nullptr, "Unknown"}, | 23 | {2, nullptr, "Unknown2"}, |
| 24 | {3, nullptr, "EnableInterface"}, | 24 | {3, nullptr, "EnableInterface"}, |
| 25 | {4, nullptr, "DisableInterface"}, | 25 | {4, nullptr, "DisableInterface"}, |
| 26 | {5, nullptr, "CtrlInPostBufferAsync"}, | 26 | {5, nullptr, "CtrlInPostBufferAsync"}, |
| @@ -55,6 +55,7 @@ public: | |||
| 55 | {9, nullptr, "SetBinaryObjectStore"}, | 55 | {9, nullptr, "SetBinaryObjectStore"}, |
| 56 | {10, nullptr, "Enable"}, | 56 | {10, nullptr, "Enable"}, |
| 57 | {11, nullptr, "Disable"}, | 57 | {11, nullptr, "Disable"}, |
| 58 | {12, nullptr, "Unknown12"}, | ||
| 58 | }; | 59 | }; |
| 59 | // clang-format on | 60 | // clang-format on |
| 60 | 61 | ||
| @@ -69,13 +70,13 @@ public: | |||
| 69 | static const FunctionInfo functions[] = { | 70 | static const FunctionInfo functions[] = { |
| 70 | {0, nullptr, "Open"}, | 71 | {0, nullptr, "Open"}, |
| 71 | {1, nullptr, "Close"}, | 72 | {1, nullptr, "Close"}, |
| 72 | {2, nullptr, "Unknown1"}, | 73 | {2, nullptr, "Unknown2"}, |
| 73 | {3, nullptr, "Populate"}, | 74 | {3, nullptr, "Populate"}, |
| 74 | {4, nullptr, "PostBufferAsync"}, | 75 | {4, nullptr, "PostBufferAsync"}, |
| 75 | {5, nullptr, "GetXferReport"}, | 76 | {5, nullptr, "GetXferReport"}, |
| 76 | {6, nullptr, "PostBufferMultiAsync"}, | 77 | {6, nullptr, "PostBufferMultiAsync"}, |
| 77 | {7, nullptr, "Unknown3"}, | 78 | {7, nullptr, "Unknown7"}, |
| 78 | {8, nullptr, "Unknown4"}, | 79 | {8, nullptr, "Unknown8"}, |
| 79 | }; | 80 | }; |
| 80 | // clang-format on | 81 | // clang-format on |
| 81 | 82 | ||
| @@ -88,13 +89,13 @@ public: | |||
| 88 | explicit IClientIfSession() : ServiceFramework{"IClientIfSession"} { | 89 | explicit IClientIfSession() : ServiceFramework{"IClientIfSession"} { |
| 89 | // clang-format off | 90 | // clang-format off |
| 90 | static const FunctionInfo functions[] = { | 91 | static const FunctionInfo functions[] = { |
| 91 | {0, nullptr, "Unknown1"}, | 92 | {0, nullptr, "Unknown0"}, |
| 92 | {1, nullptr, "SetInterface"}, | 93 | {1, nullptr, "SetInterface"}, |
| 93 | {2, nullptr, "GetInterface"}, | 94 | {2, nullptr, "GetInterface"}, |
| 94 | {3, nullptr, "GetAlternateInterface"}, | 95 | {3, nullptr, "GetAlternateInterface"}, |
| 95 | {4, nullptr, "GetCurrentFrame"}, | 96 | {4, nullptr, "GetCurrentFrame"}, |
| 96 | {5, nullptr, "CtrlXferAsync"}, | 97 | {5, nullptr, "CtrlXferAsync"}, |
| 97 | {6, nullptr, "Unknown2"}, | 98 | {6, nullptr, "Unknown6"}, |
| 98 | {7, nullptr, "GetCtrlXferReport"}, | 99 | {7, nullptr, "GetCtrlXferReport"}, |
| 99 | {8, nullptr, "ResetDevice"}, | 100 | {8, nullptr, "ResetDevice"}, |
| 100 | {9, nullptr, "OpenUsbEp"}, | 101 | {9, nullptr, "OpenUsbEp"}, |
| @@ -118,7 +119,7 @@ public: | |||
| 118 | {5, nullptr, "DestroyInterfaceAvailableEvent"}, | 119 | {5, nullptr, "DestroyInterfaceAvailableEvent"}, |
| 119 | {6, nullptr, "GetInterfaceStateChangeEvent"}, | 120 | {6, nullptr, "GetInterfaceStateChangeEvent"}, |
| 120 | {7, nullptr, "AcquireUsbIf"}, | 121 | {7, nullptr, "AcquireUsbIf"}, |
| 121 | {8, nullptr, "Unknown1"}, | 122 | {8, nullptr, "Unknown8"}, |
| 122 | }; | 123 | }; |
| 123 | // clang-format on | 124 | // clang-format on |
| 124 | 125 | ||
| @@ -179,8 +180,8 @@ public: | |||
| 179 | {4, nullptr, "GetFwRevision"}, | 180 | {4, nullptr, "GetFwRevision"}, |
| 180 | {5, nullptr, "GetManufacturerId"}, | 181 | {5, nullptr, "GetManufacturerId"}, |
| 181 | {6, nullptr, "GetDeviceId"}, | 182 | {6, nullptr, "GetDeviceId"}, |
| 182 | {7, nullptr, "Unknown1"}, | 183 | {7, nullptr, "Unknown7"}, |
| 183 | {8, nullptr, "Unknown2"}, | 184 | {8, nullptr, "Unknown8"}, |
| 184 | }; | 185 | }; |
| 185 | // clang-format on | 186 | // clang-format on |
| 186 | 187 | ||
| @@ -215,12 +216,12 @@ public: | |||
| 215 | explicit USB_PM() : ServiceFramework{"usb:pm"} { | 216 | explicit USB_PM() : ServiceFramework{"usb:pm"} { |
| 216 | // clang-format off | 217 | // clang-format off |
| 217 | static const FunctionInfo functions[] = { | 218 | static const FunctionInfo functions[] = { |
| 218 | {0, nullptr, "Unknown1"}, | 219 | {0, nullptr, "Unknown0"}, |
| 219 | {1, nullptr, "Unknown2"}, | 220 | {1, nullptr, "Unknown1"}, |
| 220 | {2, nullptr, "Unknown3"}, | 221 | {2, nullptr, "Unknown2"}, |
| 221 | {3, nullptr, "Unknown4"}, | 222 | {3, nullptr, "Unknown3"}, |
| 222 | {4, nullptr, "Unknown5"}, | 223 | {4, nullptr, "Unknown4"}, |
| 223 | {5, nullptr, "Unknown6"}, | 224 | {5, nullptr, "Unknown5"}, |
| 224 | }; | 225 | }; |
| 225 | // clang-format on | 226 | // clang-format on |
| 226 | 227 | ||
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 157092074..ea7b4ae13 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp | |||
| @@ -519,9 +519,9 @@ private: | |||
| 519 | IGBPConnectRequestParcel request{ctx.ReadBuffer()}; | 519 | IGBPConnectRequestParcel request{ctx.ReadBuffer()}; |
| 520 | IGBPConnectResponseParcel response{ | 520 | IGBPConnectResponseParcel response{ |
| 521 | static_cast<u32>(static_cast<u32>(DisplayResolution::UndockedWidth) * | 521 | static_cast<u32>(static_cast<u32>(DisplayResolution::UndockedWidth) * |
| 522 | Settings::values.resolution_factor), | 522 | Settings::values.resolution_factor.GetValue()), |
| 523 | static_cast<u32>(static_cast<u32>(DisplayResolution::UndockedHeight) * | 523 | static_cast<u32>(static_cast<u32>(DisplayResolution::UndockedHeight) * |
| 524 | Settings::values.resolution_factor)}; | 524 | Settings::values.resolution_factor.GetValue())}; |
| 525 | ctx.WriteBuffer(response.Serialize()); | 525 | ctx.WriteBuffer(response.Serialize()); |
| 526 | break; | 526 | break; |
| 527 | } | 527 | } |
| @@ -700,6 +700,7 @@ public: | |||
| 700 | {3215, nullptr, "SetDisplayGamma"}, | 700 | {3215, nullptr, "SetDisplayGamma"}, |
| 701 | {3216, nullptr, "GetDisplayCmuLuma"}, | 701 | {3216, nullptr, "GetDisplayCmuLuma"}, |
| 702 | {3217, nullptr, "SetDisplayCmuLuma"}, | 702 | {3217, nullptr, "SetDisplayCmuLuma"}, |
| 703 | {6013, nullptr, "GetLayerPresentationSubmissionTimestamps"}, | ||
| 703 | {8225, nullptr, "GetSharedBufferMemoryHandleId"}, | 704 | {8225, nullptr, "GetSharedBufferMemoryHandleId"}, |
| 704 | {8250, nullptr, "OpenSharedLayer"}, | 705 | {8250, nullptr, "OpenSharedLayer"}, |
| 705 | {8251, nullptr, "CloseSharedLayer"}, | 706 | {8251, nullptr, "CloseSharedLayer"}, |
| @@ -748,14 +749,14 @@ private: | |||
| 748 | 749 | ||
| 749 | if (Settings::values.use_docked_mode) { | 750 | if (Settings::values.use_docked_mode) { |
| 750 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) * | 751 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedWidth) * |
| 751 | static_cast<u32>(Settings::values.resolution_factor)); | 752 | static_cast<u32>(Settings::values.resolution_factor.GetValue())); |
| 752 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) * | 753 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::DockedHeight) * |
| 753 | static_cast<u32>(Settings::values.resolution_factor)); | 754 | static_cast<u32>(Settings::values.resolution_factor.GetValue())); |
| 754 | } else { | 755 | } else { |
| 755 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth) * | 756 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedWidth) * |
| 756 | static_cast<u32>(Settings::values.resolution_factor)); | 757 | static_cast<u32>(Settings::values.resolution_factor.GetValue())); |
| 757 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight) * | 758 | rb.Push(static_cast<u32>(Service::VI::DisplayResolution::UndockedHeight) * |
| 758 | static_cast<u32>(Settings::values.resolution_factor)); | 759 | static_cast<u32>(Settings::values.resolution_factor.GetValue())); |
| 759 | } | 760 | } |
| 760 | 761 | ||
| 761 | rb.PushRaw<float>(60.0f); // This wouldn't seem to be correct for 30 fps games. | 762 | rb.PushRaw<float>(60.0f); // This wouldn't seem to be correct for 30 fps games. |
| @@ -785,6 +786,7 @@ public: | |||
| 785 | {2300, nullptr, "AcquireLayerTexturePresentingEvent"}, | 786 | {2300, nullptr, "AcquireLayerTexturePresentingEvent"}, |
| 786 | {2301, nullptr, "ReleaseLayerTexturePresentingEvent"}, | 787 | {2301, nullptr, "ReleaseLayerTexturePresentingEvent"}, |
| 787 | {2302, nullptr, "GetDisplayHotplugEvent"}, | 788 | {2302, nullptr, "GetDisplayHotplugEvent"}, |
| 789 | {2303, nullptr, "GetDisplayModeChangedEvent"}, | ||
| 788 | {2402, nullptr, "GetDisplayHotplugState"}, | 790 | {2402, nullptr, "GetDisplayHotplugState"}, |
| 789 | {2501, nullptr, "GetCompositorErrorInfo"}, | 791 | {2501, nullptr, "GetCompositorErrorInfo"}, |
| 790 | {2601, nullptr, "GetDisplayErrorEvent"}, | 792 | {2601, nullptr, "GetDisplayErrorEvent"}, |
| @@ -1029,9 +1031,9 @@ private: | |||
| 1029 | // between docked and undocked dimensions. We take the liberty of applying | 1031 | // between docked and undocked dimensions. We take the liberty of applying |
| 1030 | // the resolution scaling factor here. | 1032 | // the resolution scaling factor here. |
| 1031 | rb.Push(static_cast<u64>(DisplayResolution::UndockedWidth) * | 1033 | rb.Push(static_cast<u64>(DisplayResolution::UndockedWidth) * |
| 1032 | static_cast<u32>(Settings::values.resolution_factor)); | 1034 | static_cast<u32>(Settings::values.resolution_factor.GetValue())); |
| 1033 | rb.Push(static_cast<u64>(DisplayResolution::UndockedHeight) * | 1035 | rb.Push(static_cast<u64>(DisplayResolution::UndockedHeight) * |
| 1034 | static_cast<u32>(Settings::values.resolution_factor)); | 1036 | static_cast<u32>(Settings::values.resolution_factor.GetValue())); |
| 1035 | } | 1037 | } |
| 1036 | 1038 | ||
| 1037 | void SetLayerScalingMode(Kernel::HLERequestContext& ctx) { | 1039 | void SetLayerScalingMode(Kernel::HLERequestContext& ctx) { |
| @@ -1064,8 +1066,8 @@ private: | |||
| 1064 | LOG_WARNING(Service_VI, "(STUBBED) called"); | 1066 | LOG_WARNING(Service_VI, "(STUBBED) called"); |
| 1065 | 1067 | ||
| 1066 | DisplayInfo display_info; | 1068 | DisplayInfo display_info; |
| 1067 | display_info.width *= static_cast<u64>(Settings::values.resolution_factor); | 1069 | display_info.width *= static_cast<u64>(Settings::values.resolution_factor.GetValue()); |
| 1068 | display_info.height *= static_cast<u64>(Settings::values.resolution_factor); | 1070 | display_info.height *= static_cast<u64>(Settings::values.resolution_factor.GetValue()); |
| 1069 | ctx.WriteBuffer(&display_info, sizeof(DisplayInfo)); | 1071 | ctx.WriteBuffer(&display_info, sizeof(DisplayInfo)); |
| 1070 | IPC::ResponseBuilder rb{ctx, 4}; | 1072 | IPC::ResponseBuilder rb{ctx, 4}; |
| 1071 | rb.Push(RESULT_SUCCESS); | 1073 | rb.Push(RESULT_SUCCESS); |
diff --git a/src/core/hle/service/vi/vi_u.cpp b/src/core/hle/service/vi/vi_u.cpp index 9d5ceb608..6b7329345 100644 --- a/src/core/hle/service/vi/vi_u.cpp +++ b/src/core/hle/service/vi/vi_u.cpp | |||
| @@ -12,6 +12,7 @@ VI_U::VI_U(std::shared_ptr<NVFlinger::NVFlinger> nv_flinger) | |||
| 12 | : ServiceFramework{"vi:u"}, nv_flinger{std::move(nv_flinger)} { | 12 | : ServiceFramework{"vi:u"}, nv_flinger{std::move(nv_flinger)} { |
| 13 | static const FunctionInfo functions[] = { | 13 | static const FunctionInfo functions[] = { |
| 14 | {0, &VI_U::GetDisplayService, "GetDisplayService"}, | 14 | {0, &VI_U::GetDisplayService, "GetDisplayService"}, |
| 15 | {1, nullptr, "GetDisplayServiceWithProxyNameExchange"}, | ||
| 15 | }; | 16 | }; |
| 16 | RegisterHandlers(functions); | 17 | RegisterHandlers(functions); |
| 17 | } | 18 | } |
diff --git a/src/core/hle/service/wlan/wlan.cpp b/src/core/hle/service/wlan/wlan.cpp index 2654594c1..0260d7dcf 100644 --- a/src/core/hle/service/wlan/wlan.cpp +++ b/src/core/hle/service/wlan/wlan.cpp | |||
| @@ -15,34 +15,37 @@ public: | |||
| 15 | explicit WLANInfra() : ServiceFramework{"wlan:inf"} { | 15 | explicit WLANInfra() : ServiceFramework{"wlan:inf"} { |
| 16 | // clang-format off | 16 | // clang-format off |
| 17 | static const FunctionInfo functions[] = { | 17 | static const FunctionInfo functions[] = { |
| 18 | {0, nullptr, "Unknown1"}, | 18 | {0, nullptr, "OpenMode"}, |
| 19 | {1, nullptr, "Unknown2"}, | 19 | {1, nullptr, "CloseMode"}, |
| 20 | {2, nullptr, "GetMacAddress"}, | 20 | {2, nullptr, "GetMacAddress"}, |
| 21 | {3, nullptr, "StartScan"}, | 21 | {3, nullptr, "StartScan"}, |
| 22 | {4, nullptr, "StopScan"}, | 22 | {4, nullptr, "StopScan"}, |
| 23 | {5, nullptr, "Connect"}, | 23 | {5, nullptr, "Connect"}, |
| 24 | {6, nullptr, "CancelConnect"}, | 24 | {6, nullptr, "CancelConnect"}, |
| 25 | {7, nullptr, "Disconnect"}, | 25 | {7, nullptr, "Disconnect"}, |
| 26 | {8, nullptr, "Unknown3"}, | 26 | {8, nullptr, "GetConnectionEvent"}, |
| 27 | {9, nullptr, "Unknown4"}, | 27 | {9, nullptr, "GetConnectionStatus"}, |
| 28 | {10, nullptr, "GetState"}, | 28 | {10, nullptr, "GetState"}, |
| 29 | {11, nullptr, "GetScanResult"}, | 29 | {11, nullptr, "GetScanResult"}, |
| 30 | {12, nullptr, "GetRssi"}, | 30 | {12, nullptr, "GetRssi"}, |
| 31 | {13, nullptr, "ChangeRxAntenna"}, | 31 | {13, nullptr, "ChangeRxAntenna"}, |
| 32 | {14, nullptr, "Unknown5"}, | 32 | {14, nullptr, "GetFwVersion"}, |
| 33 | {15, nullptr, "Unknown6"}, | 33 | {15, nullptr, "RequestSleep"}, |
| 34 | {16, nullptr, "RequestWakeUp"}, | 34 | {16, nullptr, "RequestWakeUp"}, |
| 35 | {17, nullptr, "RequestIfUpDown"}, | 35 | {17, nullptr, "RequestIfUpDown"}, |
| 36 | {18, nullptr, "Unknown7"}, | 36 | {18, nullptr, "Unknown18"}, |
| 37 | {19, nullptr, "Unknown8"}, | 37 | {19, nullptr, "Unknown19"}, |
| 38 | {20, nullptr, "Unknown9"}, | 38 | {20, nullptr, "Unknown20"}, |
| 39 | {21, nullptr, "Unknown10"}, | 39 | {21, nullptr, "Unknown21"}, |
| 40 | {22, nullptr, "Unknown11"}, | 40 | {22, nullptr, "Unknown22"}, |
| 41 | {23, nullptr, "Unknown12"}, | 41 | {23, nullptr, "Unknown23"}, |
| 42 | {24, nullptr, "Unknown13"}, | 42 | {24, nullptr, "Unknown24"}, |
| 43 | {25, nullptr, "Unknown14"}, | 43 | {25, nullptr, "Unknown25"}, |
| 44 | {26, nullptr, "Unknown15"}, | 44 | {26, nullptr, "Unknown26"}, |
| 45 | {27, nullptr, "Unknown16"}, | 45 | {27, nullptr, "Unknown27"}, |
| 46 | {28, nullptr, "Unknown28"}, | ||
| 47 | {29, nullptr, "Unknown29"}, | ||
| 48 | {30, nullptr, "Unknown30"}, | ||
| 46 | }; | 49 | }; |
| 47 | // clang-format on | 50 | // clang-format on |
| 48 | 51 | ||
| @@ -55,12 +58,12 @@ public: | |||
| 55 | explicit WLANLocal() : ServiceFramework{"wlan:lcl"} { | 58 | explicit WLANLocal() : ServiceFramework{"wlan:lcl"} { |
| 56 | // clang-format off | 59 | // clang-format off |
| 57 | static const FunctionInfo functions[] = { | 60 | static const FunctionInfo functions[] = { |
| 58 | {0, nullptr, "Unknown1"}, | 61 | {0, nullptr, "Unknown0"}, |
| 59 | {1, nullptr, "Unknown2"}, | 62 | {1, nullptr, "Unknown1"}, |
| 60 | {2, nullptr, "Unknown3"}, | 63 | {2, nullptr, "Unknown2"}, |
| 61 | {3, nullptr, "Unknown4"}, | 64 | {3, nullptr, "Unknown3"}, |
| 62 | {4, nullptr, "Unknown5"}, | 65 | {4, nullptr, "Unknown4"}, |
| 63 | {5, nullptr, "Unknown6"}, | 66 | {5, nullptr, "Unknown5"}, |
| 64 | {6, nullptr, "GetMacAddress"}, | 67 | {6, nullptr, "GetMacAddress"}, |
| 65 | {7, nullptr, "CreateBss"}, | 68 | {7, nullptr, "CreateBss"}, |
| 66 | {8, nullptr, "DestroyBss"}, | 69 | {8, nullptr, "DestroyBss"}, |
| @@ -72,38 +75,42 @@ public: | |||
| 72 | {14, nullptr, "CancelJoin"}, | 75 | {14, nullptr, "CancelJoin"}, |
| 73 | {15, nullptr, "Disconnect"}, | 76 | {15, nullptr, "Disconnect"}, |
| 74 | {16, nullptr, "SetBeaconLostCount"}, | 77 | {16, nullptr, "SetBeaconLostCount"}, |
| 75 | {17, nullptr, "Unknown7"}, | 78 | {17, nullptr, "Unknown17"}, |
| 76 | {18, nullptr, "Unknown8"}, | 79 | {18, nullptr, "Unknown18"}, |
| 77 | {19, nullptr, "Unknown9"}, | 80 | {19, nullptr, "Unknown19"}, |
| 78 | {20, nullptr, "GetBssIndicationEvent"}, | 81 | {20, nullptr, "GetBssIndicationEvent"}, |
| 79 | {21, nullptr, "GetBssIndicationInfo"}, | 82 | {21, nullptr, "GetBssIndicationInfo"}, |
| 80 | {22, nullptr, "GetState"}, | 83 | {22, nullptr, "GetState"}, |
| 81 | {23, nullptr, "GetAllowedChannels"}, | 84 | {23, nullptr, "GetAllowedChannels"}, |
| 82 | {24, nullptr, "AddIe"}, | 85 | {24, nullptr, "AddIe"}, |
| 83 | {25, nullptr, "DeleteIe"}, | 86 | {25, nullptr, "DeleteIe"}, |
| 84 | {26, nullptr, "Unknown10"}, | 87 | {26, nullptr, "Unknown26"}, |
| 85 | {27, nullptr, "Unknown11"}, | 88 | {27, nullptr, "Unknown27"}, |
| 86 | {28, nullptr, "CreateRxEntry"}, | 89 | {28, nullptr, "CreateRxEntry"}, |
| 87 | {29, nullptr, "DeleteRxEntry"}, | 90 | {29, nullptr, "DeleteRxEntry"}, |
| 88 | {30, nullptr, "Unknown12"}, | 91 | {30, nullptr, "Unknown30"}, |
| 89 | {31, nullptr, "Unknown13"}, | 92 | {31, nullptr, "Unknown31"}, |
| 90 | {32, nullptr, "AddMatchingDataToRxEntry"}, | 93 | {32, nullptr, "AddMatchingDataToRxEntry"}, |
| 91 | {33, nullptr, "RemoveMatchingDataFromRxEntry"}, | 94 | {33, nullptr, "RemoveMatchingDataFromRxEntry"}, |
| 92 | {34, nullptr, "GetScanResult"}, | 95 | {34, nullptr, "GetScanResult"}, |
| 93 | {35, nullptr, "Unknown14"}, | 96 | {35, nullptr, "Unknown35"}, |
| 94 | {36, nullptr, "SetActionFrameWithBeacon"}, | 97 | {36, nullptr, "SetActionFrameWithBeacon"}, |
| 95 | {37, nullptr, "CancelActionFrameWithBeacon"}, | 98 | {37, nullptr, "CancelActionFrameWithBeacon"}, |
| 96 | {38, nullptr, "CreateRxEntryForActionFrame"}, | 99 | {38, nullptr, "CreateRxEntryForActionFrame"}, |
| 97 | {39, nullptr, "DeleteRxEntryForActionFrame"}, | 100 | {39, nullptr, "DeleteRxEntryForActionFrame"}, |
| 98 | {40, nullptr, "Unknown15"}, | 101 | {40, nullptr, "Unknown40"}, |
| 99 | {41, nullptr, "Unknown16"}, | 102 | {41, nullptr, "Unknown41"}, |
| 100 | {42, nullptr, "CancelGetActionFrame"}, | 103 | {42, nullptr, "CancelGetActionFrame"}, |
| 101 | {43, nullptr, "GetRssi"}, | 104 | {43, nullptr, "GetRssi"}, |
| 102 | {44, nullptr, "Unknown17"}, | 105 | {44, nullptr, "Unknown44"}, |
| 103 | {45, nullptr, "Unknown18"}, | 106 | {45, nullptr, "Unknown45"}, |
| 104 | {46, nullptr, "Unknown19"}, | 107 | {46, nullptr, "Unknown46"}, |
| 105 | {47, nullptr, "Unknown20"}, | 108 | {47, nullptr, "Unknown47"}, |
| 106 | {48, nullptr, "Unknown21"}, | 109 | {48, nullptr, "Unknown48"}, |
| 110 | {49, nullptr, "Unknown49"}, | ||
| 111 | {50, nullptr, "Unknown50"}, | ||
| 112 | {51, nullptr, "Unknown51"}, | ||
| 113 | {52, nullptr, "Unknown52"}, | ||
| 107 | }; | 114 | }; |
| 108 | // clang-format on | 115 | // clang-format on |
| 109 | 116 | ||
| @@ -142,18 +149,19 @@ public: | |||
| 142 | explicit WLANSocketManager() : ServiceFramework{"wlan:soc"} { | 149 | explicit WLANSocketManager() : ServiceFramework{"wlan:soc"} { |
| 143 | // clang-format off | 150 | // clang-format off |
| 144 | static const FunctionInfo functions[] = { | 151 | static const FunctionInfo functions[] = { |
| 145 | {0, nullptr, "Unknown1"}, | 152 | {0, nullptr, "Unknown0"}, |
| 146 | {1, nullptr, "Unknown2"}, | 153 | {1, nullptr, "Unknown1"}, |
| 147 | {2, nullptr, "Unknown3"}, | 154 | {2, nullptr, "Unknown2"}, |
| 148 | {3, nullptr, "Unknown4"}, | 155 | {3, nullptr, "Unknown3"}, |
| 149 | {4, nullptr, "Unknown5"}, | 156 | {4, nullptr, "Unknown4"}, |
| 150 | {5, nullptr, "Unknown6"}, | 157 | {5, nullptr, "Unknown5"}, |
| 151 | {6, nullptr, "GetMacAddress"}, | 158 | {6, nullptr, "GetMacAddress"}, |
| 152 | {7, nullptr, "SwitchTsfTimerFunction"}, | 159 | {7, nullptr, "SwitchTsfTimerFunction"}, |
| 153 | {8, nullptr, "Unknown7"}, | 160 | {8, nullptr, "Unknown8"}, |
| 154 | {9, nullptr, "Unknown8"}, | 161 | {9, nullptr, "Unknown9"}, |
| 155 | {10, nullptr, "Unknown9"}, | 162 | {10, nullptr, "Unknown10"}, |
| 156 | {11, nullptr, "Unknown10"}, | 163 | {11, nullptr, "Unknown11"}, |
| 164 | {12, nullptr, "Unknown12"}, | ||
| 157 | }; | 165 | }; |
| 158 | // clang-format on | 166 | // clang-format on |
| 159 | 167 | ||
diff --git a/src/core/perf_stats.cpp b/src/core/perf_stats.cpp index 9f3a6b811..29339ead7 100644 --- a/src/core/perf_stats.cpp +++ b/src/core/perf_stats.cpp | |||
| @@ -119,13 +119,14 @@ double PerfStats::GetLastFrameTimeScale() { | |||
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) { | 121 | void FrameLimiter::DoFrameLimiting(microseconds current_system_time_us) { |
| 122 | if (!Settings::values.use_frame_limit || Settings::values.use_multi_core) { | 122 | if (!Settings::values.use_frame_limit.GetValue() || |
| 123 | Settings::values.use_multi_core.GetValue()) { | ||
| 123 | return; | 124 | return; |
| 124 | } | 125 | } |
| 125 | 126 | ||
| 126 | auto now = Clock::now(); | 127 | auto now = Clock::now(); |
| 127 | 128 | ||
| 128 | const double sleep_scale = Settings::values.frame_limit / 100.0; | 129 | const double sleep_scale = Settings::values.frame_limit.GetValue() / 100.0; |
| 129 | 130 | ||
| 130 | // Max lag caused by slow frames. Shouldn't be more than the length of a frame at the current | 131 | // Max lag caused by slow frames. Shouldn't be more than the length of a frame at the current |
| 131 | // speed percent or it will clamp too much and prevent this from properly limiting to that | 132 | // speed percent or it will clamp too much and prevent this from properly limiting to that |
diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 56df5e925..d3886c4ec 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp | |||
| @@ -62,6 +62,7 @@ const std::array<const char*, NumMouseButtons> mapping = {{ | |||
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | Values values = {}; | 64 | Values values = {}; |
| 65 | bool configuring_global = true; | ||
| 65 | 66 | ||
| 66 | std::string GetTimeZoneString() { | 67 | std::string GetTimeZoneString() { |
| 67 | static constexpr std::array<const char*, 46> timezones{{ | 68 | static constexpr std::array<const char*, 46> timezones{{ |
| @@ -73,9 +74,9 @@ std::string GetTimeZoneString() { | |||
| 73 | "UCT", "Universal", "UTC", "W-SU", "WET", "Zulu", | 74 | "UCT", "Universal", "UTC", "W-SU", "WET", "Zulu", |
| 74 | }}; | 75 | }}; |
| 75 | 76 | ||
| 76 | ASSERT(Settings::values.time_zone_index < timezones.size()); | 77 | ASSERT(Settings::values.time_zone_index.GetValue() < timezones.size()); |
| 77 | 78 | ||
| 78 | return timezones[Settings::values.time_zone_index]; | 79 | return timezones[Settings::values.time_zone_index.GetValue()]; |
| 79 | } | 80 | } |
| 80 | 81 | ||
| 81 | void Apply() { | 82 | void Apply() { |
| @@ -97,25 +98,25 @@ void LogSetting(const std::string& name, const T& value) { | |||
| 97 | 98 | ||
| 98 | void LogSettings() { | 99 | void LogSettings() { |
| 99 | LOG_INFO(Config, "yuzu Configuration:"); | 100 | LOG_INFO(Config, "yuzu Configuration:"); |
| 100 | LogSetting("System_UseDockedMode", Settings::values.use_docked_mode); | 101 | LogSetting("Controls_UseDockedMode", Settings::values.use_docked_mode); |
| 101 | LogSetting("System_RngSeed", Settings::values.rng_seed.value_or(0)); | 102 | LogSetting("System_RngSeed", Settings::values.rng_seed.GetValue().value_or(0)); |
| 102 | LogSetting("System_CurrentUser", Settings::values.current_user); | 103 | LogSetting("System_CurrentUser", Settings::values.current_user); |
| 103 | LogSetting("System_LanguageIndex", Settings::values.language_index); | 104 | LogSetting("System_LanguageIndex", Settings::values.language_index.GetValue()); |
| 104 | LogSetting("System_RegionIndex", Settings::values.region_index); | 105 | LogSetting("System_RegionIndex", Settings::values.region_index.GetValue()); |
| 105 | LogSetting("System_TimeZoneIndex", Settings::values.time_zone_index); | 106 | LogSetting("System_TimeZoneIndex", Settings::values.time_zone_index.GetValue()); |
| 106 | LogSetting("Core_UseMultiCore", Settings::values.use_multi_core); | 107 | LogSetting("Core_UseMultiCore", Settings::values.use_multi_core.GetValue()); |
| 107 | LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor); | 108 | LogSetting("Renderer_UseResolutionFactor", Settings::values.resolution_factor.GetValue()); |
| 108 | LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit); | 109 | LogSetting("Renderer_UseFrameLimit", Settings::values.use_frame_limit.GetValue()); |
| 109 | LogSetting("Renderer_FrameLimit", Settings::values.frame_limit); | 110 | LogSetting("Renderer_FrameLimit", Settings::values.frame_limit.GetValue()); |
| 110 | LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache); | 111 | LogSetting("Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache.GetValue()); |
| 111 | LogSetting("Renderer_GPUAccuracyLevel", Settings::values.gpu_accuracy); | 112 | LogSetting("Renderer_GPUAccuracyLevel", Settings::values.gpu_accuracy.GetValue()); |
| 112 | LogSetting("Renderer_UseAsynchronousGpuEmulation", | 113 | LogSetting("Renderer_UseAsynchronousGpuEmulation", |
| 113 | Settings::values.use_asynchronous_gpu_emulation); | 114 | Settings::values.use_asynchronous_gpu_emulation.GetValue()); |
| 114 | LogSetting("Renderer_UseVsync", Settings::values.use_vsync); | 115 | LogSetting("Renderer_UseVsync", Settings::values.use_vsync.GetValue()); |
| 115 | LogSetting("Renderer_UseAssemblyShaders", Settings::values.use_assembly_shaders); | 116 | LogSetting("Renderer_UseAssemblyShaders", Settings::values.use_assembly_shaders.GetValue()); |
| 116 | LogSetting("Renderer_AnisotropicFilteringLevel", Settings::values.max_anisotropy); | 117 | LogSetting("Renderer_AnisotropicFilteringLevel", Settings::values.max_anisotropy.GetValue()); |
| 117 | LogSetting("Audio_OutputEngine", Settings::values.sink_id); | 118 | LogSetting("Audio_OutputEngine", Settings::values.sink_id); |
| 118 | LogSetting("Audio_EnableAudioStretching", Settings::values.enable_audio_stretching); | 119 | LogSetting("Audio_EnableAudioStretching", Settings::values.enable_audio_stretching.GetValue()); |
| 119 | LogSetting("Audio_OutputDevice", Settings::values.audio_device_id); | 120 | LogSetting("Audio_OutputDevice", Settings::values.audio_device_id); |
| 120 | LogSetting("DataStorage_UseVirtualSd", Settings::values.use_virtual_sd); | 121 | LogSetting("DataStorage_UseVirtualSd", Settings::values.use_virtual_sd); |
| 121 | LogSetting("DataStorage_NandDir", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)); | 122 | LogSetting("DataStorage_NandDir", FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)); |
| @@ -131,15 +132,56 @@ float Volume() { | |||
| 131 | if (values.audio_muted) { | 132 | if (values.audio_muted) { |
| 132 | return 0.0f; | 133 | return 0.0f; |
| 133 | } | 134 | } |
| 134 | return values.volume; | 135 | return values.volume.GetValue(); |
| 135 | } | 136 | } |
| 136 | 137 | ||
| 137 | bool IsGPULevelExtreme() { | 138 | bool IsGPULevelExtreme() { |
| 138 | return values.gpu_accuracy == GPUAccuracy::Extreme; | 139 | return values.gpu_accuracy.GetValue() == GPUAccuracy::Extreme; |
| 139 | } | 140 | } |
| 140 | 141 | ||
| 141 | bool IsGPULevelHigh() { | 142 | bool IsGPULevelHigh() { |
| 142 | return values.gpu_accuracy == GPUAccuracy::Extreme || values.gpu_accuracy == GPUAccuracy::High; | 143 | return values.gpu_accuracy.GetValue() == GPUAccuracy::Extreme || |
| 144 | values.gpu_accuracy.GetValue() == GPUAccuracy::High; | ||
| 145 | } | ||
| 146 | |||
| 147 | void RestoreGlobalState() { | ||
| 148 | // If a game is running, DO NOT restore the global settings state | ||
| 149 | if (Core::System::GetInstance().IsPoweredOn()) { | ||
| 150 | return; | ||
| 151 | } | ||
| 152 | |||
| 153 | // Audio | ||
| 154 | values.enable_audio_stretching.SetGlobal(true); | ||
| 155 | values.volume.SetGlobal(true); | ||
| 156 | |||
| 157 | // Core | ||
| 158 | values.use_multi_core.SetGlobal(true); | ||
| 159 | |||
| 160 | // Renderer | ||
| 161 | values.renderer_backend.SetGlobal(true); | ||
| 162 | values.vulkan_device.SetGlobal(true); | ||
| 163 | values.aspect_ratio.SetGlobal(true); | ||
| 164 | values.max_anisotropy.SetGlobal(true); | ||
| 165 | values.use_frame_limit.SetGlobal(true); | ||
| 166 | values.frame_limit.SetGlobal(true); | ||
| 167 | values.use_disk_shader_cache.SetGlobal(true); | ||
| 168 | values.gpu_accuracy.SetGlobal(true); | ||
| 169 | values.use_asynchronous_gpu_emulation.SetGlobal(true); | ||
| 170 | values.use_vsync.SetGlobal(true); | ||
| 171 | values.use_assembly_shaders.SetGlobal(true); | ||
| 172 | values.use_fast_gpu_time.SetGlobal(true); | ||
| 173 | values.force_30fps_mode.SetGlobal(true); | ||
| 174 | values.bg_red.SetGlobal(true); | ||
| 175 | values.bg_green.SetGlobal(true); | ||
| 176 | values.bg_blue.SetGlobal(true); | ||
| 177 | |||
| 178 | // System | ||
| 179 | values.language_index.SetGlobal(true); | ||
| 180 | values.region_index.SetGlobal(true); | ||
| 181 | values.time_zone_index.SetGlobal(true); | ||
| 182 | values.rng_seed.SetGlobal(true); | ||
| 183 | values.custom_rtc.SetGlobal(true); | ||
| 184 | values.sound_index.SetGlobal(true); | ||
| 143 | } | 185 | } |
| 144 | 186 | ||
| 145 | } // namespace Settings | 187 | } // namespace Settings |
diff --git a/src/core/settings.h b/src/core/settings.h index a598ccbc1..850ca4072 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -382,20 +382,85 @@ enum class GPUAccuracy : u32 { | |||
| 382 | Extreme = 2, | 382 | Extreme = 2, |
| 383 | }; | 383 | }; |
| 384 | 384 | ||
| 385 | extern bool configuring_global; | ||
| 386 | |||
| 387 | template <typename Type> | ||
| 388 | class Setting final { | ||
| 389 | public: | ||
| 390 | Setting() = default; | ||
| 391 | explicit Setting(Type val) : global{val} {} | ||
| 392 | ~Setting() = default; | ||
| 393 | void SetGlobal(bool to_global) { | ||
| 394 | use_global = to_global; | ||
| 395 | } | ||
| 396 | bool UsingGlobal() const { | ||
| 397 | return use_global; | ||
| 398 | } | ||
| 399 | Type GetValue(bool need_global = false) const { | ||
| 400 | if (use_global || need_global) { | ||
| 401 | return global; | ||
| 402 | } | ||
| 403 | return local; | ||
| 404 | } | ||
| 405 | void SetValue(const Type& value) { | ||
| 406 | if (use_global) { | ||
| 407 | global = value; | ||
| 408 | } else { | ||
| 409 | local = value; | ||
| 410 | } | ||
| 411 | } | ||
| 412 | |||
| 413 | private: | ||
| 414 | bool use_global = true; | ||
| 415 | Type global{}; | ||
| 416 | Type local{}; | ||
| 417 | }; | ||
| 418 | |||
| 385 | struct Values { | 419 | struct Values { |
| 420 | // Audio | ||
| 421 | std::string audio_device_id; | ||
| 422 | std::string sink_id; | ||
| 423 | bool audio_muted; | ||
| 424 | Setting<bool> enable_audio_stretching; | ||
| 425 | Setting<float> volume; | ||
| 426 | |||
| 427 | // Core | ||
| 428 | Setting<bool> use_multi_core; | ||
| 429 | |||
| 430 | // Renderer | ||
| 431 | Setting<RendererBackend> renderer_backend; | ||
| 432 | bool renderer_debug; | ||
| 433 | Setting<int> vulkan_device; | ||
| 434 | |||
| 435 | Setting<u16> resolution_factor = Setting(static_cast<u16>(1)); | ||
| 436 | Setting<int> aspect_ratio; | ||
| 437 | Setting<int> max_anisotropy; | ||
| 438 | Setting<bool> use_frame_limit; | ||
| 439 | Setting<u16> frame_limit; | ||
| 440 | Setting<bool> use_disk_shader_cache; | ||
| 441 | Setting<GPUAccuracy> gpu_accuracy; | ||
| 442 | Setting<bool> use_asynchronous_gpu_emulation; | ||
| 443 | Setting<bool> use_vsync; | ||
| 444 | Setting<bool> use_assembly_shaders; | ||
| 445 | Setting<bool> force_30fps_mode; | ||
| 446 | Setting<bool> use_fast_gpu_time; | ||
| 447 | |||
| 448 | Setting<float> bg_red; | ||
| 449 | Setting<float> bg_green; | ||
| 450 | Setting<float> bg_blue; | ||
| 451 | |||
| 386 | // System | 452 | // System |
| 387 | bool use_docked_mode; | 453 | Setting<std::optional<u32>> rng_seed; |
| 388 | std::optional<u32> rng_seed; | ||
| 389 | // Measured in seconds since epoch | 454 | // Measured in seconds since epoch |
| 390 | std::optional<std::chrono::seconds> custom_rtc; | 455 | Setting<std::optional<std::chrono::seconds>> custom_rtc; |
| 391 | // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` | 456 | // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` |
| 392 | std::chrono::seconds custom_rtc_differential; | 457 | std::chrono::seconds custom_rtc_differential; |
| 393 | 458 | ||
| 394 | s32 current_user; | 459 | s32 current_user; |
| 395 | s32 language_index; | 460 | Setting<s32> language_index; |
| 396 | s32 region_index; | 461 | Setting<s32> region_index; |
| 397 | s32 time_zone_index; | 462 | Setting<s32> time_zone_index; |
| 398 | s32 sound_index; | 463 | Setting<s32> sound_index; |
| 399 | 464 | ||
| 400 | // Controls | 465 | // Controls |
| 401 | std::array<PlayerInput, 10> players; | 466 | std::array<PlayerInput, 10> players; |
| @@ -419,8 +484,7 @@ struct Values { | |||
| 419 | u16 udp_input_port; | 484 | u16 udp_input_port; |
| 420 | u8 udp_pad_index; | 485 | u8 udp_pad_index; |
| 421 | 486 | ||
| 422 | // Core | 487 | bool use_docked_mode; |
| 423 | bool use_multi_core; | ||
| 424 | 488 | ||
| 425 | // Data Storage | 489 | // Data Storage |
| 426 | bool use_virtual_sd; | 490 | bool use_virtual_sd; |
| @@ -432,39 +496,6 @@ struct Values { | |||
| 432 | NANDUserSize nand_user_size; | 496 | NANDUserSize nand_user_size; |
| 433 | SDMCSize sdmc_size; | 497 | SDMCSize sdmc_size; |
| 434 | 498 | ||
| 435 | // Renderer | ||
| 436 | RendererBackend renderer_backend; | ||
| 437 | bool renderer_debug; | ||
| 438 | int vulkan_device; | ||
| 439 | |||
| 440 | u16 resolution_factor{1}; | ||
| 441 | int aspect_ratio; | ||
| 442 | int max_anisotropy; | ||
| 443 | bool use_frame_limit; | ||
| 444 | u16 frame_limit; | ||
| 445 | bool use_disk_shader_cache; | ||
| 446 | GPUAccuracy gpu_accuracy; | ||
| 447 | bool use_asynchronous_gpu_emulation; | ||
| 448 | bool use_vsync; | ||
| 449 | bool use_assembly_shaders; | ||
| 450 | bool force_30fps_mode; | ||
| 451 | bool use_fast_gpu_time; | ||
| 452 | |||
| 453 | float bg_red; | ||
| 454 | float bg_green; | ||
| 455 | float bg_blue; | ||
| 456 | |||
| 457 | std::string log_filter; | ||
| 458 | |||
| 459 | bool use_dev_keys; | ||
| 460 | |||
| 461 | // Audio | ||
| 462 | bool audio_muted; | ||
| 463 | std::string sink_id; | ||
| 464 | bool enable_audio_stretching; | ||
| 465 | std::string audio_device_id; | ||
| 466 | float volume; | ||
| 467 | |||
| 468 | // Debugging | 499 | // Debugging |
| 469 | bool record_frame_times; | 500 | bool record_frame_times; |
| 470 | bool use_gdbstub; | 501 | bool use_gdbstub; |
| @@ -477,7 +508,11 @@ struct Values { | |||
| 477 | bool disable_cpu_opt; | 508 | bool disable_cpu_opt; |
| 478 | bool disable_macro_jit; | 509 | bool disable_macro_jit; |
| 479 | 510 | ||
| 480 | // BCAT | 511 | // Misceallaneous |
| 512 | std::string log_filter; | ||
| 513 | bool use_dev_keys; | ||
| 514 | |||
| 515 | // Services | ||
| 481 | std::string bcat_backend; | 516 | std::string bcat_backend; |
| 482 | bool bcat_boxcat_local; | 517 | bool bcat_boxcat_local; |
| 483 | 518 | ||
| @@ -501,4 +536,7 @@ std::string GetTimeZoneString(); | |||
| 501 | void Apply(); | 536 | void Apply(); |
| 502 | void LogSettings(); | 537 | void LogSettings(); |
| 503 | 538 | ||
| 539 | // Restore the global state of all applicable settings in the Values struct | ||
| 540 | void RestoreGlobalState(); | ||
| 541 | |||
| 504 | } // namespace Settings | 542 | } // namespace Settings |
diff --git a/src/core/telemetry_session.cpp b/src/core/telemetry_session.cpp index c781b3cfc..78915e6db 100644 --- a/src/core/telemetry_session.cpp +++ b/src/core/telemetry_session.cpp | |||
| @@ -189,19 +189,24 @@ void TelemetrySession::AddInitialInfo(Loader::AppLoader& app_loader) { | |||
| 189 | // Log user configuration information | 189 | // Log user configuration information |
| 190 | constexpr auto field_type = Telemetry::FieldType::UserConfig; | 190 | constexpr auto field_type = Telemetry::FieldType::UserConfig; |
| 191 | AddField(field_type, "Audio_SinkId", Settings::values.sink_id); | 191 | AddField(field_type, "Audio_SinkId", Settings::values.sink_id); |
| 192 | AddField(field_type, "Audio_EnableAudioStretching", Settings::values.enable_audio_stretching); | 192 | AddField(field_type, "Audio_EnableAudioStretching", |
| 193 | AddField(field_type, "Core_UseMultiCore", Settings::values.use_multi_core); | 193 | Settings::values.enable_audio_stretching.GetValue()); |
| 194 | AddField(field_type, "Renderer_Backend", TranslateRenderer(Settings::values.renderer_backend)); | 194 | AddField(field_type, "Core_UseMultiCore", Settings::values.use_multi_core.GetValue()); |
| 195 | AddField(field_type, "Renderer_ResolutionFactor", Settings::values.resolution_factor); | 195 | AddField(field_type, "Renderer_Backend", |
| 196 | AddField(field_type, "Renderer_UseFrameLimit", Settings::values.use_frame_limit); | 196 | TranslateRenderer(Settings::values.renderer_backend.GetValue())); |
| 197 | AddField(field_type, "Renderer_FrameLimit", Settings::values.frame_limit); | 197 | AddField(field_type, "Renderer_ResolutionFactor", |
| 198 | AddField(field_type, "Renderer_UseDiskShaderCache", Settings::values.use_disk_shader_cache); | 198 | Settings::values.resolution_factor.GetValue()); |
| 199 | AddField(field_type, "Renderer_UseFrameLimit", Settings::values.use_frame_limit.GetValue()); | ||
| 200 | AddField(field_type, "Renderer_FrameLimit", Settings::values.frame_limit.GetValue()); | ||
| 201 | AddField(field_type, "Renderer_UseDiskShaderCache", | ||
| 202 | Settings::values.use_disk_shader_cache.GetValue()); | ||
| 199 | AddField(field_type, "Renderer_GPUAccuracyLevel", | 203 | AddField(field_type, "Renderer_GPUAccuracyLevel", |
| 200 | TranslateGPUAccuracyLevel(Settings::values.gpu_accuracy)); | 204 | TranslateGPUAccuracyLevel(Settings::values.gpu_accuracy.GetValue())); |
| 201 | AddField(field_type, "Renderer_UseAsynchronousGpuEmulation", | 205 | AddField(field_type, "Renderer_UseAsynchronousGpuEmulation", |
| 202 | Settings::values.use_asynchronous_gpu_emulation); | 206 | Settings::values.use_asynchronous_gpu_emulation.GetValue()); |
| 203 | AddField(field_type, "Renderer_UseVsync", Settings::values.use_vsync); | 207 | AddField(field_type, "Renderer_UseVsync", Settings::values.use_vsync.GetValue()); |
| 204 | AddField(field_type, "Renderer_UseAssemblyShaders", Settings::values.use_assembly_shaders); | 208 | AddField(field_type, "Renderer_UseAssemblyShaders", |
| 209 | Settings::values.use_assembly_shaders.GetValue()); | ||
| 205 | AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode); | 210 | AddField(field_type, "System_UseDockedMode", Settings::values.use_docked_mode); |
| 206 | } | 211 | } |
| 207 | 212 | ||
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp index b39d2a3fb..6d9f4d9eb 100644 --- a/src/input_common/gcadapter/gc_adapter.cpp +++ b/src/input_common/gcadapter/gc_adapter.cpp | |||
| @@ -24,9 +24,13 @@ Adapter::Adapter() { | |||
| 24 | LOG_INFO(Input, "GC Adapter Initialization started"); | 24 | LOG_INFO(Input, "GC Adapter Initialization started"); |
| 25 | 25 | ||
| 26 | current_status = NO_ADAPTER_DETECTED; | 26 | current_status = NO_ADAPTER_DETECTED; |
| 27 | libusb_init(&libusb_ctx); | ||
| 28 | 27 | ||
| 29 | StartScanThread(); | 28 | const int init_res = libusb_init(&libusb_ctx); |
| 29 | if (init_res == LIBUSB_SUCCESS) { | ||
| 30 | StartScanThread(); | ||
| 31 | } else { | ||
| 32 | LOG_ERROR(Input, "libusb could not be initialized. failed with error = {}", init_res); | ||
| 33 | } | ||
| 30 | } | 34 | } |
| 31 | 35 | ||
| 32 | GCPadStatus Adapter::GetPadStatus(int port, const std::array<u8, 37>& adapter_payload) { | 36 | GCPadStatus Adapter::GetPadStatus(int port, const std::array<u8, 37>& adapter_payload) { |
| @@ -211,17 +215,26 @@ void Adapter::Setup() { | |||
| 211 | adapter_controllers_status.fill(ControllerTypes::None); | 215 | adapter_controllers_status.fill(ControllerTypes::None); |
| 212 | 216 | ||
| 213 | // pointer to list of connected usb devices | 217 | // pointer to list of connected usb devices |
| 214 | libusb_device** devices; | 218 | libusb_device** devices{}; |
| 215 | 219 | ||
| 216 | // populate the list of devices, get the count | 220 | // populate the list of devices, get the count |
| 217 | const std::size_t device_count = libusb_get_device_list(libusb_ctx, &devices); | 221 | const ssize_t device_count = libusb_get_device_list(libusb_ctx, &devices); |
| 222 | if (device_count < 0) { | ||
| 223 | LOG_ERROR(Input, "libusb_get_device_list failed with error: {}", device_count); | ||
| 224 | detect_thread_running = false; // Stop the loop constantly checking for gc adapter | ||
| 225 | // TODO: For hotplug+gc adapter checkbox implementation, revert this. | ||
| 226 | return; | ||
| 227 | } | ||
| 218 | 228 | ||
| 219 | for (std::size_t index = 0; index < device_count; ++index) { | 229 | if (devices != nullptr) { |
| 220 | if (CheckDeviceAccess(devices[index])) { | 230 | for (std::size_t index = 0; index < device_count; ++index) { |
| 221 | // GC Adapter found and accessible, registering it | 231 | if (CheckDeviceAccess(devices[index])) { |
| 222 | GetGCEndpoint(devices[index]); | 232 | // GC Adapter found and accessible, registering it |
| 223 | break; | 233 | GetGCEndpoint(devices[index]); |
| 234 | break; | ||
| 235 | } | ||
| 224 | } | 236 | } |
| 237 | libusb_free_device_list(devices, 1); | ||
| 225 | } | 238 | } |
| 226 | } | 239 | } |
| 227 | 240 | ||
| @@ -279,7 +292,13 @@ bool Adapter::CheckDeviceAccess(libusb_device* device) { | |||
| 279 | 292 | ||
| 280 | void Adapter::GetGCEndpoint(libusb_device* device) { | 293 | void Adapter::GetGCEndpoint(libusb_device* device) { |
| 281 | libusb_config_descriptor* config = nullptr; | 294 | libusb_config_descriptor* config = nullptr; |
| 282 | libusb_get_config_descriptor(device, 0, &config); | 295 | const int config_descriptor_return = libusb_get_config_descriptor(device, 0, &config); |
| 296 | if (config_descriptor_return != LIBUSB_SUCCESS) { | ||
| 297 | LOG_ERROR(Input, "libusb_get_config_descriptor failed with error = {}", | ||
| 298 | config_descriptor_return); | ||
| 299 | return; | ||
| 300 | } | ||
| 301 | |||
| 283 | for (u8 ic = 0; ic < config->bNumInterfaces; ic++) { | 302 | for (u8 ic = 0; ic < config->bNumInterfaces; ic++) { |
| 284 | const libusb_interface* interfaceContainer = &config->interface[ic]; | 303 | const libusb_interface* interfaceContainer = &config->interface[ic]; |
| 285 | for (int i = 0; i < interfaceContainer->num_altsetting; i++) { | 304 | for (int i = 0; i < interfaceContainer->num_altsetting; i++) { |
diff --git a/src/input_common/gcadapter/gc_adapter.h b/src/input_common/gcadapter/gc_adapter.h index 0ea6263eb..b1c2a1958 100644 --- a/src/input_common/gcadapter/gc_adapter.h +++ b/src/input_common/gcadapter/gc_adapter.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <functional> | 7 | #include <functional> |
| 8 | #include <mutex> | 8 | #include <mutex> |
| 9 | #include <thread> | 9 | #include <thread> |
| 10 | #include <unordered_map> | ||
| 10 | #include <libusb.h> | 11 | #include <libusb.h> |
| 11 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 12 | #include "common/threadsafe_queue.h" | 13 | #include "common/threadsafe_queue.h" |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index c6479af9f..dd7ce8c99 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -96,7 +96,8 @@ public: | |||
| 96 | } | 96 | } |
| 97 | if (is_written) { | 97 | if (is_written) { |
| 98 | map->MarkAsModified(true, GetModifiedTicks()); | 98 | map->MarkAsModified(true, GetModifiedTicks()); |
| 99 | if (Settings::IsGPULevelHigh() && Settings::values.use_asynchronous_gpu_emulation) { | 99 | if (Settings::IsGPULevelHigh() && |
| 100 | Settings::values.use_asynchronous_gpu_emulation.GetValue()) { | ||
| 100 | MarkForAsyncFlush(map); | 101 | MarkForAsyncFlush(map); |
| 101 | } | 102 | } |
| 102 | if (!map->is_written) { | 103 | if (!map->is_written) { |
| @@ -369,7 +370,8 @@ private: | |||
| 369 | } | 370 | } |
| 370 | if (modified_inheritance) { | 371 | if (modified_inheritance) { |
| 371 | map->MarkAsModified(true, GetModifiedTicks()); | 372 | map->MarkAsModified(true, GetModifiedTicks()); |
| 372 | if (Settings::IsGPULevelHigh() && Settings::values.use_asynchronous_gpu_emulation) { | 373 | if (Settings::IsGPULevelHigh() && |
| 374 | Settings::values.use_asynchronous_gpu_emulation.GetValue()) { | ||
| 373 | MarkForAsyncFlush(map); | 375 | MarkForAsyncFlush(map); |
| 374 | } | 376 | } |
| 375 | } | 377 | } |
diff --git a/src/video_core/gpu.cpp b/src/video_core/gpu.cpp index 482e49711..758bfe148 100644 --- a/src/video_core/gpu.cpp +++ b/src/video_core/gpu.cpp | |||
| @@ -157,7 +157,7 @@ u64 GPU::GetTicks() const { | |||
| 157 | constexpr u64 gpu_ticks_den = 625; | 157 | constexpr u64 gpu_ticks_den = 625; |
| 158 | 158 | ||
| 159 | u64 nanoseconds = system.CoreTiming().GetGlobalTimeNs().count(); | 159 | u64 nanoseconds = system.CoreTiming().GetGlobalTimeNs().count(); |
| 160 | if (Settings::values.use_fast_gpu_time) { | 160 | if (Settings::values.use_fast_gpu_time.GetValue()) { |
| 161 | nanoseconds /= 256; | 161 | nanoseconds /= 256; |
| 162 | } | 162 | } |
| 163 | const u64 nanoseconds_num = nanoseconds / gpu_ticks_den; | 163 | const u64 nanoseconds_num = nanoseconds / gpu_ticks_den; |
diff --git a/src/video_core/query_cache.h b/src/video_core/query_cache.h index e12dab899..0d3a88765 100644 --- a/src/video_core/query_cache.h +++ b/src/video_core/query_cache.h | |||
| @@ -132,7 +132,7 @@ public: | |||
| 132 | } | 132 | } |
| 133 | 133 | ||
| 134 | query->BindCounter(Stream(type).Current(), timestamp); | 134 | query->BindCounter(Stream(type).Current(), timestamp); |
| 135 | if (Settings::values.use_asynchronous_gpu_emulation) { | 135 | if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) { |
| 136 | AsyncFlushQuery(cpu_addr); | 136 | AsyncFlushQuery(cpu_addr); |
| 137 | } | 137 | } |
| 138 | } | 138 | } |
diff --git a/src/video_core/renderer_base.cpp b/src/video_core/renderer_base.cpp index 919d1f2d4..dfb06e87e 100644 --- a/src/video_core/renderer_base.cpp +++ b/src/video_core/renderer_base.cpp | |||
| @@ -18,7 +18,7 @@ RendererBase::~RendererBase() = default; | |||
| 18 | void RendererBase::RefreshBaseSettings() { | 18 | void RendererBase::RefreshBaseSettings() { |
| 19 | UpdateCurrentFramebufferLayout(); | 19 | UpdateCurrentFramebufferLayout(); |
| 20 | 20 | ||
| 21 | renderer_settings.use_framelimiter = Settings::values.use_frame_limit; | 21 | renderer_settings.use_framelimiter = Settings::values.use_frame_limit.GetValue(); |
| 22 | renderer_settings.set_background_color = true; | 22 | renderer_settings.set_background_color = true; |
| 23 | } | 23 | } |
| 24 | 24 | ||
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp index 208fc6167..c1f20f0ab 100644 --- a/src/video_core/renderer_opengl/gl_device.cpp +++ b/src/video_core/renderer_opengl/gl_device.cpp | |||
| @@ -229,15 +229,15 @@ Device::Device() | |||
| 229 | // uniform buffers as "push constants" | 229 | // uniform buffers as "push constants" |
| 230 | has_fast_buffer_sub_data = is_nvidia && !disable_fast_buffer_sub_data; | 230 | has_fast_buffer_sub_data = is_nvidia && !disable_fast_buffer_sub_data; |
| 231 | 231 | ||
| 232 | use_assembly_shaders = Settings::values.use_assembly_shaders && GLAD_GL_NV_gpu_program5 && | 232 | use_assembly_shaders = Settings::values.use_assembly_shaders.GetValue() && |
| 233 | GLAD_GL_NV_compute_program5 && GLAD_GL_NV_transform_feedback && | 233 | GLAD_GL_NV_gpu_program5 && GLAD_GL_NV_compute_program5 && |
| 234 | GLAD_GL_NV_transform_feedback2; | 234 | GLAD_GL_NV_transform_feedback && GLAD_GL_NV_transform_feedback2; |
| 235 | 235 | ||
| 236 | LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); | 236 | LOG_INFO(Render_OpenGL, "Renderer_VariableAOFFI: {}", has_variable_aoffi); |
| 237 | LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); | 237 | LOG_INFO(Render_OpenGL, "Renderer_ComponentIndexingBug: {}", has_component_indexing_bug); |
| 238 | LOG_INFO(Render_OpenGL, "Renderer_PreciseBug: {}", has_precise_bug); | 238 | LOG_INFO(Render_OpenGL, "Renderer_PreciseBug: {}", has_precise_bug); |
| 239 | 239 | ||
| 240 | if (Settings::values.use_assembly_shaders && !use_assembly_shaders) { | 240 | if (Settings::values.use_assembly_shaders.GetValue() && !use_assembly_shaders) { |
| 241 | LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported"); | 241 | LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported"); |
| 242 | } | 242 | } |
| 243 | } | 243 | } |
diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp index 653c3f2f9..2dcc2b0eb 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp | |||
| @@ -213,7 +213,7 @@ ShaderDiskCacheOpenGL::~ShaderDiskCacheOpenGL() = default; | |||
| 213 | std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTransferable() { | 213 | std::optional<std::vector<ShaderDiskCacheEntry>> ShaderDiskCacheOpenGL::LoadTransferable() { |
| 214 | // Skip games without title id | 214 | // Skip games without title id |
| 215 | const bool has_title_id = system.CurrentProcess()->GetTitleID() != 0; | 215 | const bool has_title_id = system.CurrentProcess()->GetTitleID() != 0; |
| 216 | if (!Settings::values.use_disk_shader_cache || !has_title_id) { | 216 | if (!Settings::values.use_disk_shader_cache.GetValue() || !has_title_id) { |
| 217 | return {}; | 217 | return {}; |
| 218 | } | 218 | } |
| 219 | 219 | ||
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp index c40adb6e7..e66cdc083 100644 --- a/src/video_core/renderer_opengl/renderer_opengl.cpp +++ b/src/video_core/renderer_opengl/renderer_opengl.cpp | |||
| @@ -455,8 +455,8 @@ void RendererOpenGL::LoadColorToActiveGLTexture(u8 color_r, u8 color_g, u8 color | |||
| 455 | void RendererOpenGL::InitOpenGLObjects() { | 455 | void RendererOpenGL::InitOpenGLObjects() { |
| 456 | frame_mailbox = std::make_unique<FrameMailbox>(); | 456 | frame_mailbox = std::make_unique<FrameMailbox>(); |
| 457 | 457 | ||
| 458 | glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, | 458 | glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(), |
| 459 | 0.0f); | 459 | Settings::values.bg_blue.GetValue(), 0.0f); |
| 460 | 460 | ||
| 461 | // Create shader programs | 461 | // Create shader programs |
| 462 | OGLShader vertex_shader; | 462 | OGLShader vertex_shader; |
| @@ -561,8 +561,8 @@ void RendererOpenGL::ConfigureFramebufferTexture(TextureInfo& texture, | |||
| 561 | void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { | 561 | void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) { |
| 562 | if (renderer_settings.set_background_color) { | 562 | if (renderer_settings.set_background_color) { |
| 563 | // Update background color before drawing | 563 | // Update background color before drawing |
| 564 | glClearColor(Settings::values.bg_red, Settings::values.bg_green, Settings::values.bg_blue, | 564 | glClearColor(Settings::values.bg_red.GetValue(), Settings::values.bg_green.GetValue(), |
| 565 | 0.0f); | 565 | Settings::values.bg_blue.GetValue(), 0.0f); |
| 566 | } | 566 | } |
| 567 | 567 | ||
| 568 | // Set projection matrix | 568 | // Set projection matrix |
diff --git a/src/video_core/renderer_vulkan/renderer_vulkan.cpp b/src/video_core/renderer_vulkan/renderer_vulkan.cpp index 2d9b18ed9..2258479f5 100644 --- a/src/video_core/renderer_vulkan/renderer_vulkan.cpp +++ b/src/video_core/renderer_vulkan/renderer_vulkan.cpp | |||
| @@ -409,7 +409,7 @@ bool RendererVulkan::PickDevices() { | |||
| 409 | return false; | 409 | return false; |
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | const s32 device_index = Settings::values.vulkan_device; | 412 | const s32 device_index = Settings::values.vulkan_device.GetValue(); |
| 413 | if (device_index < 0 || device_index >= static_cast<s32>(devices->size())) { | 413 | if (device_index < 0 || device_index >= static_cast<s32>(devices->size())) { |
| 414 | LOG_ERROR(Render_Vulkan, "Invalid device index {}!", device_index); | 414 | LOG_ERROR(Render_Vulkan, "Invalid device index {}!", device_index); |
| 415 | return false; | 415 | return false; |
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index 380ed532b..7625871c2 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp | |||
| @@ -332,23 +332,23 @@ private: | |||
| 332 | 332 | ||
| 333 | if constexpr (has_extended_dynamic_state) { | 333 | if constexpr (has_extended_dynamic_state) { |
| 334 | // With extended dynamic states we can specify the length and stride of a vertex buffer | 334 | // With extended dynamic states we can specify the length and stride of a vertex buffer |
| 335 | // std::array<VkDeviceSize, N> sizes; | 335 | std::array<VkDeviceSize, N> sizes; |
| 336 | std::array<u16, N> strides; | 336 | std::array<u16, N> strides; |
| 337 | // std::copy(vertex.sizes.begin(), vertex.sizes.begin() + N, sizes.begin()); | 337 | std::copy(vertex.sizes.begin(), vertex.sizes.begin() + N, sizes.begin()); |
| 338 | std::copy(vertex.strides.begin(), vertex.strides.begin() + N, strides.begin()); | 338 | std::copy(vertex.strides.begin(), vertex.strides.begin() + N, strides.begin()); |
| 339 | 339 | ||
| 340 | if constexpr (is_indexed) { | 340 | if constexpr (is_indexed) { |
| 341 | scheduler.Record( | 341 | scheduler.Record( |
| 342 | [buffers, offsets, strides, index = index](vk::CommandBuffer cmdbuf) { | 342 | [buffers, offsets, sizes, strides, index = index](vk::CommandBuffer cmdbuf) { |
| 343 | cmdbuf.BindIndexBuffer(index.buffer, index.offset, index.type); | 343 | cmdbuf.BindIndexBuffer(index.buffer, index.offset, index.type); |
| 344 | cmdbuf.BindVertexBuffers2EXT(0, static_cast<u32>(N), buffers.data(), | 344 | cmdbuf.BindVertexBuffers2EXT(0, static_cast<u32>(N), buffers.data(), |
| 345 | offsets.data(), nullptr, | 345 | offsets.data(), sizes.data(), |
| 346 | ExpandStrides(strides).data()); | 346 | ExpandStrides(strides).data()); |
| 347 | }); | 347 | }); |
| 348 | } else { | 348 | } else { |
| 349 | scheduler.Record([buffers, offsets, strides](vk::CommandBuffer cmdbuf) { | 349 | scheduler.Record([buffers, offsets, sizes, strides](vk::CommandBuffer cmdbuf) { |
| 350 | cmdbuf.BindVertexBuffers2EXT(0, static_cast<u32>(N), buffers.data(), | 350 | cmdbuf.BindVertexBuffers2EXT(0, static_cast<u32>(N), buffers.data(), |
| 351 | offsets.data(), nullptr, | 351 | offsets.data(), sizes.data(), |
| 352 | ExpandStrides(strides).data()); | 352 | ExpandStrides(strides).data()); |
| 353 | }); | 353 | }); |
| 354 | } | 354 | } |
diff --git a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp index 868447af2..2d28a6c47 100644 --- a/src/video_core/renderer_vulkan/vk_stream_buffer.cpp +++ b/src/video_core/renderer_vulkan/vk_stream_buffer.cpp | |||
| @@ -121,7 +121,7 @@ void VKStreamBuffer::CreateBuffers(VkBufferUsageFlags usage) { | |||
| 121 | 121 | ||
| 122 | // Substract from the preferred heap size some bytes to avoid getting out of memory. | 122 | // Substract from the preferred heap size some bytes to avoid getting out of memory. |
| 123 | const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size; | 123 | const VkDeviceSize heap_size = memory_properties.memoryHeaps[preferred_heap].size; |
| 124 | const VkDeviceSize allocable_size = heap_size - 4 * 1024 * 1024; | 124 | const VkDeviceSize allocable_size = heap_size - 9 * 1024 * 1024; |
| 125 | 125 | ||
| 126 | VkBufferCreateInfo buffer_ci; | 126 | VkBufferCreateInfo buffer_ci; |
| 127 | buffer_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; | 127 | buffer_ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO; |
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h index 6207d8dfe..cdcddb225 100644 --- a/src/video_core/texture_cache/texture_cache.h +++ b/src/video_core/texture_cache/texture_cache.h | |||
| @@ -249,7 +249,7 @@ public: | |||
| 249 | auto& surface = render_targets[index].target; | 249 | auto& surface = render_targets[index].target; |
| 250 | surface->MarkAsRenderTarget(false, NO_RT); | 250 | surface->MarkAsRenderTarget(false, NO_RT); |
| 251 | const auto& cr_params = surface->GetSurfaceParams(); | 251 | const auto& cr_params = surface->GetSurfaceParams(); |
| 252 | if (!cr_params.is_tiled && Settings::values.use_asynchronous_gpu_emulation) { | 252 | if (!cr_params.is_tiled && Settings::values.use_asynchronous_gpu_emulation.GetValue()) { |
| 253 | AsyncFlushSurface(surface); | 253 | AsyncFlushSurface(surface); |
| 254 | } | 254 | } |
| 255 | } | 255 | } |
diff --git a/src/video_core/textures/texture.cpp b/src/video_core/textures/texture.cpp index d1939d744..4171e3ef2 100644 --- a/src/video_core/textures/texture.cpp +++ b/src/video_core/textures/texture.cpp | |||
| @@ -48,7 +48,7 @@ constexpr std::array<float, 256> SRGB_CONVERSION_LUT = { | |||
| 48 | }; | 48 | }; |
| 49 | 49 | ||
| 50 | unsigned SettingsMinimumAnisotropy() noexcept { | 50 | unsigned SettingsMinimumAnisotropy() noexcept { |
| 51 | switch (static_cast<Anisotropy>(Settings::values.max_anisotropy)) { | 51 | switch (static_cast<Anisotropy>(Settings::values.max_anisotropy.GetValue())) { |
| 52 | default: | 52 | default: |
| 53 | case Anisotropy::Default: | 53 | case Anisotropy::Default: |
| 54 | return 1U; | 54 | return 1U; |
diff --git a/src/video_core/video_core.cpp b/src/video_core/video_core.cpp index f60bdc60a..45f360bdd 100644 --- a/src/video_core/video_core.cpp +++ b/src/video_core/video_core.cpp | |||
| @@ -19,7 +19,7 @@ namespace { | |||
| 19 | std::unique_ptr<VideoCore::RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_window, | 19 | std::unique_ptr<VideoCore::RendererBase> CreateRenderer(Core::Frontend::EmuWindow& emu_window, |
| 20 | Core::System& system, | 20 | Core::System& system, |
| 21 | Core::Frontend::GraphicsContext& context) { | 21 | Core::Frontend::GraphicsContext& context) { |
| 22 | switch (Settings::values.renderer_backend) { | 22 | switch (Settings::values.renderer_backend.GetValue()) { |
| 23 | case Settings::RendererBackend::OpenGL: | 23 | case Settings::RendererBackend::OpenGL: |
| 24 | return std::make_unique<OpenGL::RendererOpenGL>(emu_window, system, context); | 24 | return std::make_unique<OpenGL::RendererOpenGL>(emu_window, system, context); |
| 25 | #ifdef HAS_VULKAN | 25 | #ifdef HAS_VULKAN |
| @@ -42,7 +42,7 @@ std::unique_ptr<Tegra::GPU> CreateGPU(Core::Frontend::EmuWindow& emu_window, Cor | |||
| 42 | return nullptr; | 42 | return nullptr; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | if (Settings::values.use_asynchronous_gpu_emulation) { | 45 | if (Settings::values.use_asynchronous_gpu_emulation.GetValue()) { |
| 46 | return std::make_unique<VideoCommon::GPUAsynch>(system, std::move(renderer), | 46 | return std::make_unique<VideoCommon::GPUAsynch>(system, std::move(renderer), |
| 47 | std::move(context)); | 47 | std::move(context)); |
| 48 | } | 48 | } |
| @@ -51,8 +51,8 @@ std::unique_ptr<Tegra::GPU> CreateGPU(Core::Frontend::EmuWindow& emu_window, Cor | |||
| 51 | 51 | ||
| 52 | u16 GetResolutionScaleFactor(const RendererBase& renderer) { | 52 | u16 GetResolutionScaleFactor(const RendererBase& renderer) { |
| 53 | return static_cast<u16>( | 53 | return static_cast<u16>( |
| 54 | Settings::values.resolution_factor != 0 | 54 | Settings::values.resolution_factor.GetValue() != 0 |
| 55 | ? Settings::values.resolution_factor | 55 | ? Settings::values.resolution_factor.GetValue() |
| 56 | : renderer.GetRenderWindow().GetFramebufferLayout().GetScalingRatio()); | 56 | : renderer.GetRenderWindow().GetFramebufferLayout().GetScalingRatio()); |
| 57 | } | 57 | } |
| 58 | 58 | ||
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index 75c27e39e..6b25a7fa0 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -24,6 +24,8 @@ add_executable(yuzu | |||
| 24 | compatibility_list.h | 24 | compatibility_list.h |
| 25 | configuration/config.cpp | 25 | configuration/config.cpp |
| 26 | configuration/config.h | 26 | configuration/config.h |
| 27 | configuration/configuration_shared.cpp | ||
| 28 | configuration/configuration_shared.h | ||
| 27 | configuration/configure.ui | 29 | configuration/configure.ui |
| 28 | configuration/configure_audio.cpp | 30 | configuration/configure_audio.cpp |
| 29 | configuration/configure_audio.h | 31 | configuration/configure_audio.h |
| @@ -60,9 +62,12 @@ add_executable(yuzu | |||
| 60 | configuration/configure_mouse_advanced.cpp | 62 | configuration/configure_mouse_advanced.cpp |
| 61 | configuration/configure_mouse_advanced.h | 63 | configuration/configure_mouse_advanced.h |
| 62 | configuration/configure_mouse_advanced.ui | 64 | configuration/configure_mouse_advanced.ui |
| 63 | configuration/configure_per_general.cpp | 65 | configuration/configure_per_game.cpp |
| 64 | configuration/configure_per_general.h | 66 | configuration/configure_per_game.h |
| 65 | configuration/configure_per_general.ui | 67 | configuration/configure_per_game.ui |
| 68 | configuration/configure_per_game_addons.cpp | ||
| 69 | configuration/configure_per_game_addons.h | ||
| 70 | configuration/configure_per_game_addons.ui | ||
| 66 | configuration/configure_profile_manager.cpp | 71 | configuration/configure_profile_manager.cpp |
| 67 | configuration/configure_profile_manager.h | 72 | configuration/configure_profile_manager.h |
| 68 | configuration/configure_profile_manager.ui | 73 | configuration/configure_profile_manager.ui |
| @@ -147,7 +152,7 @@ endif() | |||
| 147 | create_target_directory_groups(yuzu) | 152 | create_target_directory_groups(yuzu) |
| 148 | 153 | ||
| 149 | target_link_libraries(yuzu PRIVATE common core input_common video_core) | 154 | target_link_libraries(yuzu PRIVATE common core input_common video_core) |
| 150 | target_link_libraries(yuzu PRIVATE Boost::boost glad Qt5::OpenGL Qt5::Widgets) | 155 | target_link_libraries(yuzu PRIVATE Boost::boost glad Qt5::Widgets) |
| 151 | target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) | 156 | target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) |
| 152 | 157 | ||
| 153 | if (ENABLE_VULKAN AND NOT WIN32) | 158 | if (ENABLE_VULKAN AND NOT WIN32) |
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 4bfce48a4..5738787ac 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp | |||
| @@ -145,7 +145,7 @@ public: | |||
| 145 | 145 | ||
| 146 | // disable vsync for any shared contexts | 146 | // disable vsync for any shared contexts |
| 147 | auto format = share_context->format(); | 147 | auto format = share_context->format(); |
| 148 | format.setSwapInterval(main_surface ? Settings::values.use_vsync : 0); | 148 | format.setSwapInterval(main_surface ? Settings::values.use_vsync.GetValue() : 0); |
| 149 | 149 | ||
| 150 | context = std::make_unique<QOpenGLContext>(); | 150 | context = std::make_unique<QOpenGLContext>(); |
| 151 | context->setShareContext(share_context); | 151 | context->setShareContext(share_context); |
| @@ -495,7 +495,7 @@ void GRenderWindow::resizeEvent(QResizeEvent* event) { | |||
| 495 | 495 | ||
| 496 | std::unique_ptr<Core::Frontend::GraphicsContext> GRenderWindow::CreateSharedContext() const { | 496 | std::unique_ptr<Core::Frontend::GraphicsContext> GRenderWindow::CreateSharedContext() const { |
| 497 | #ifdef HAS_OPENGL | 497 | #ifdef HAS_OPENGL |
| 498 | if (Settings::values.renderer_backend == Settings::RendererBackend::OpenGL) { | 498 | if (Settings::values.renderer_backend.GetValue() == Settings::RendererBackend::OpenGL) { |
| 499 | auto c = static_cast<OpenGLSharedContext*>(main_context.get()); | 499 | auto c = static_cast<OpenGLSharedContext*>(main_context.get()); |
| 500 | // Bind the shared contexts to the main surface in case the backend wants to take over | 500 | // Bind the shared contexts to the main surface in case the backend wants to take over |
| 501 | // presentation | 501 | // presentation |
| @@ -511,7 +511,7 @@ bool GRenderWindow::InitRenderTarget() { | |||
| 511 | 511 | ||
| 512 | first_frame = false; | 512 | first_frame = false; |
| 513 | 513 | ||
| 514 | switch (Settings::values.renderer_backend) { | 514 | switch (Settings::values.renderer_backend.GetValue()) { |
| 515 | case Settings::RendererBackend::OpenGL: | 515 | case Settings::RendererBackend::OpenGL: |
| 516 | if (!InitializeOpenGL()) { | 516 | if (!InitializeOpenGL()) { |
| 517 | return false; | 517 | return false; |
| @@ -538,7 +538,7 @@ bool GRenderWindow::InitRenderTarget() { | |||
| 538 | OnFramebufferSizeChanged(); | 538 | OnFramebufferSizeChanged(); |
| 539 | BackupGeometry(); | 539 | BackupGeometry(); |
| 540 | 540 | ||
| 541 | if (Settings::values.renderer_backend == Settings::RendererBackend::OpenGL) { | 541 | if (Settings::values.renderer_backend.GetValue() == Settings::RendererBackend::OpenGL) { |
| 542 | if (!LoadOpenGL()) { | 542 | if (!LoadOpenGL()) { |
| 543 | return false; | 543 | return false; |
| 544 | } | 544 | } |
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 5e0d0e7af..1b2b1b2bb 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -13,17 +13,20 @@ | |||
| 13 | #include "input_common/udp/client.h" | 13 | #include "input_common/udp/client.h" |
| 14 | #include "yuzu/configuration/config.h" | 14 | #include "yuzu/configuration/config.h" |
| 15 | 15 | ||
| 16 | Config::Config() { | 16 | Config::Config(const std::string& config_file, bool is_global) { |
| 17 | // TODO: Don't hardcode the path; let the frontend decide where to put the config files. | 17 | // TODO: Don't hardcode the path; let the frontend decide where to put the config files. |
| 18 | qt_config_loc = FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + "qt-config.ini"; | 18 | qt_config_loc = FileUtil::GetUserPath(FileUtil::UserPath::ConfigDir) + config_file; |
| 19 | FileUtil::CreateFullPath(qt_config_loc); | 19 | FileUtil::CreateFullPath(qt_config_loc); |
| 20 | qt_config = | 20 | qt_config = |
| 21 | std::make_unique<QSettings>(QString::fromStdString(qt_config_loc), QSettings::IniFormat); | 21 | std::make_unique<QSettings>(QString::fromStdString(qt_config_loc), QSettings::IniFormat); |
| 22 | global = is_global; | ||
| 22 | Reload(); | 23 | Reload(); |
| 23 | } | 24 | } |
| 24 | 25 | ||
| 25 | Config::~Config() { | 26 | Config::~Config() { |
| 26 | Save(); | 27 | if (global) { |
| 28 | Save(); | ||
| 29 | } | ||
| 27 | } | 30 | } |
| 28 | 31 | ||
| 29 | const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = { | 32 | const std::array<int, Settings::NativeButton::NumButtons> Config::default_buttons = { |
| @@ -402,16 +405,19 @@ void Config::ApplyDefaultProfileIfInputInvalid() { | |||
| 402 | void Config::ReadAudioValues() { | 405 | void Config::ReadAudioValues() { |
| 403 | qt_config->beginGroup(QStringLiteral("Audio")); | 406 | qt_config->beginGroup(QStringLiteral("Audio")); |
| 404 | 407 | ||
| 405 | Settings::values.sink_id = ReadSetting(QStringLiteral("output_engine"), QStringLiteral("auto")) | 408 | if (global) { |
| 406 | .toString() | 409 | Settings::values.sink_id = |
| 407 | .toStdString(); | 410 | ReadSetting(QStringLiteral("output_engine"), QStringLiteral("auto")) |
| 408 | Settings::values.enable_audio_stretching = | 411 | .toString() |
| 409 | ReadSetting(QStringLiteral("enable_audio_stretching"), true).toBool(); | 412 | .toStdString(); |
| 410 | Settings::values.audio_device_id = | 413 | Settings::values.audio_device_id = |
| 411 | ReadSetting(QStringLiteral("output_device"), QStringLiteral("auto")) | 414 | ReadSetting(QStringLiteral("output_device"), QStringLiteral("auto")) |
| 412 | .toString() | 415 | .toString() |
| 413 | .toStdString(); | 416 | .toStdString(); |
| 414 | Settings::values.volume = ReadSetting(QStringLiteral("volume"), 1).toFloat(); | 417 | } |
| 418 | ReadSettingGlobal(Settings::values.enable_audio_stretching, | ||
| 419 | QStringLiteral("enable_audio_stretching"), true); | ||
| 420 | ReadSettingGlobal(Settings::values.volume, QStringLiteral("volume"), 1); | ||
| 415 | 421 | ||
| 416 | qt_config->endGroup(); | 422 | qt_config->endGroup(); |
| 417 | } | 423 | } |
| @@ -440,6 +446,8 @@ void Config::ReadControlValues() { | |||
| 440 | .toInt()); | 446 | .toInt()); |
| 441 | Settings::values.udp_pad_index = | 447 | Settings::values.udp_pad_index = |
| 442 | static_cast<u8>(ReadSetting(QStringLiteral("udp_pad_index"), 0).toUInt()); | 448 | static_cast<u8>(ReadSetting(QStringLiteral("udp_pad_index"), 0).toUInt()); |
| 449 | Settings::values.use_docked_mode = | ||
| 450 | ReadSetting(QStringLiteral("use_docked_mode"), false).toBool(); | ||
| 443 | 451 | ||
| 444 | qt_config->endGroup(); | 452 | qt_config->endGroup(); |
| 445 | } | 453 | } |
| @@ -447,7 +455,7 @@ void Config::ReadControlValues() { | |||
| 447 | void Config::ReadCoreValues() { | 455 | void Config::ReadCoreValues() { |
| 448 | qt_config->beginGroup(QStringLiteral("Core")); | 456 | qt_config->beginGroup(QStringLiteral("Core")); |
| 449 | 457 | ||
| 450 | Settings::values.use_multi_core = ReadSetting(QStringLiteral("use_multi_core"), false).toBool(); | 458 | ReadSettingGlobal(Settings::values.use_multi_core, QStringLiteral("use_multi_core"), false); |
| 451 | 459 | ||
| 452 | qt_config->endGroup(); | 460 | qt_config->endGroup(); |
| 453 | } | 461 | } |
| @@ -628,32 +636,28 @@ void Config::ReadPathValues() { | |||
| 628 | void Config::ReadRendererValues() { | 636 | void Config::ReadRendererValues() { |
| 629 | qt_config->beginGroup(QStringLiteral("Renderer")); | 637 | qt_config->beginGroup(QStringLiteral("Renderer")); |
| 630 | 638 | ||
| 631 | Settings::values.renderer_backend = | 639 | ReadSettingGlobal(Settings::values.renderer_backend, QStringLiteral("backend"), 0); |
| 632 | static_cast<Settings::RendererBackend>(ReadSetting(QStringLiteral("backend"), 0).toInt()); | 640 | ReadSettingGlobal(Settings::values.renderer_debug, QStringLiteral("debug"), false); |
| 633 | Settings::values.renderer_debug = ReadSetting(QStringLiteral("debug"), false).toBool(); | 641 | ReadSettingGlobal(Settings::values.vulkan_device, QStringLiteral("vulkan_device"), 0); |
| 634 | Settings::values.vulkan_device = ReadSetting(QStringLiteral("vulkan_device"), 0).toInt(); | 642 | ReadSettingGlobal(Settings::values.aspect_ratio, QStringLiteral("aspect_ratio"), 0); |
| 635 | Settings::values.aspect_ratio = ReadSetting(QStringLiteral("aspect_ratio"), 0).toInt(); | 643 | ReadSettingGlobal(Settings::values.max_anisotropy, QStringLiteral("max_anisotropy"), 0); |
| 636 | Settings::values.max_anisotropy = ReadSetting(QStringLiteral("max_anisotropy"), 0).toInt(); | 644 | ReadSettingGlobal(Settings::values.use_frame_limit, QStringLiteral("use_frame_limit"), true); |
| 637 | Settings::values.use_frame_limit = | 645 | ReadSettingGlobal(Settings::values.frame_limit, QStringLiteral("frame_limit"), 100); |
| 638 | ReadSetting(QStringLiteral("use_frame_limit"), true).toBool(); | 646 | ReadSettingGlobal(Settings::values.use_disk_shader_cache, |
| 639 | Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toUInt(); | 647 | QStringLiteral("use_disk_shader_cache"), true); |
| 640 | Settings::values.use_disk_shader_cache = | 648 | ReadSettingGlobal(Settings::values.gpu_accuracy, QStringLiteral("gpu_accuracy"), 0); |
| 641 | ReadSetting(QStringLiteral("use_disk_shader_cache"), true).toBool(); | 649 | ReadSettingGlobal(Settings::values.use_asynchronous_gpu_emulation, |
| 642 | const int gpu_accuracy_level = ReadSetting(QStringLiteral("gpu_accuracy"), 0).toInt(); | 650 | QStringLiteral("use_asynchronous_gpu_emulation"), false); |
| 643 | Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level); | 651 | ReadSettingGlobal(Settings::values.use_vsync, QStringLiteral("use_vsync"), true); |
| 644 | Settings::values.use_asynchronous_gpu_emulation = | 652 | ReadSettingGlobal(Settings::values.use_assembly_shaders, QStringLiteral("use_assembly_shaders"), |
| 645 | ReadSetting(QStringLiteral("use_asynchronous_gpu_emulation"), false).toBool(); | 653 | false); |
| 646 | Settings::values.use_vsync = ReadSetting(QStringLiteral("use_vsync"), true).toBool(); | 654 | ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time"), |
| 647 | Settings::values.use_assembly_shaders = | 655 | true); |
| 648 | ReadSetting(QStringLiteral("use_assembly_shaders"), false).toBool(); | 656 | ReadSettingGlobal(Settings::values.force_30fps_mode, QStringLiteral("force_30fps_mode"), false); |
| 649 | Settings::values.use_fast_gpu_time = | 657 | |
| 650 | ReadSetting(QStringLiteral("use_fast_gpu_time"), true).toBool(); | 658 | ReadSettingGlobal(Settings::values.bg_red, QStringLiteral("bg_red"), 0.0); |
| 651 | Settings::values.force_30fps_mode = | 659 | ReadSettingGlobal(Settings::values.bg_green, QStringLiteral("bg_green"), 0.0); |
| 652 | ReadSetting(QStringLiteral("force_30fps_mode"), false).toBool(); | 660 | ReadSettingGlobal(Settings::values.bg_blue, QStringLiteral("bg_blue"), 0.0); |
| 653 | |||
| 654 | Settings::values.bg_red = ReadSetting(QStringLiteral("bg_red"), 0.0).toFloat(); | ||
| 655 | Settings::values.bg_green = ReadSetting(QStringLiteral("bg_green"), 0.0).toFloat(); | ||
| 656 | Settings::values.bg_blue = ReadSetting(QStringLiteral("bg_blue"), 0.0).toFloat(); | ||
| 657 | 661 | ||
| 658 | qt_config->endGroup(); | 662 | qt_config->endGroup(); |
| 659 | } | 663 | } |
| @@ -682,35 +686,45 @@ void Config::ReadShortcutValues() { | |||
| 682 | void Config::ReadSystemValues() { | 686 | void Config::ReadSystemValues() { |
| 683 | qt_config->beginGroup(QStringLiteral("System")); | 687 | qt_config->beginGroup(QStringLiteral("System")); |
| 684 | 688 | ||
| 685 | Settings::values.use_docked_mode = | 689 | ReadSettingGlobal(Settings::values.current_user, QStringLiteral("current_user"), 0); |
| 686 | ReadSetting(QStringLiteral("use_docked_mode"), false).toBool(); | 690 | Settings::values.current_user = |
| 687 | 691 | std::clamp<int>(Settings::values.current_user, 0, Service::Account::MAX_USERS - 1); | |
| 688 | Settings::values.current_user = std::clamp<int>( | ||
| 689 | ReadSetting(QStringLiteral("current_user"), 0).toInt(), 0, Service::Account::MAX_USERS - 1); | ||
| 690 | 692 | ||
| 691 | Settings::values.language_index = ReadSetting(QStringLiteral("language_index"), 1).toInt(); | 693 | ReadSettingGlobal(Settings::values.language_index, QStringLiteral("language_index"), 1); |
| 692 | 694 | ||
| 693 | Settings::values.region_index = ReadSetting(QStringLiteral("region_index"), 1).toInt(); | 695 | ReadSettingGlobal(Settings::values.region_index, QStringLiteral("region_index"), 1); |
| 694 | 696 | ||
| 695 | Settings::values.time_zone_index = ReadSetting(QStringLiteral("time_zone_index"), 0).toInt(); | 697 | ReadSettingGlobal(Settings::values.time_zone_index, QStringLiteral("time_zone_index"), 0); |
| 696 | 698 | ||
| 697 | const auto rng_seed_enabled = ReadSetting(QStringLiteral("rng_seed_enabled"), false).toBool(); | 699 | bool rng_seed_enabled; |
| 698 | if (rng_seed_enabled) { | 700 | ReadSettingGlobal(rng_seed_enabled, QStringLiteral("rng_seed_enabled"), false); |
| 699 | Settings::values.rng_seed = ReadSetting(QStringLiteral("rng_seed"), 0).toULongLong(); | 701 | bool rng_seed_global = |
| 700 | } else { | 702 | global || qt_config->value(QStringLiteral("rng_seed/use_global"), true).toBool(); |
| 701 | Settings::values.rng_seed = std::nullopt; | 703 | Settings::values.rng_seed.SetGlobal(rng_seed_global); |
| 704 | if (global || !rng_seed_global) { | ||
| 705 | if (rng_seed_enabled) { | ||
| 706 | Settings::values.rng_seed.SetValue( | ||
| 707 | ReadSetting(QStringLiteral("rng_seed"), 0).toULongLong()); | ||
| 708 | } else { | ||
| 709 | Settings::values.rng_seed.SetValue(std::nullopt); | ||
| 710 | } | ||
| 702 | } | 711 | } |
| 703 | 712 | ||
| 704 | const auto custom_rtc_enabled = | 713 | bool custom_rtc_enabled; |
| 705 | ReadSetting(QStringLiteral("custom_rtc_enabled"), false).toBool(); | 714 | ReadSettingGlobal(custom_rtc_enabled, QStringLiteral("custom_rtc_enabled"), false); |
| 706 | if (custom_rtc_enabled) { | 715 | bool custom_rtc_global = |
| 707 | Settings::values.custom_rtc = | 716 | global || qt_config->value(QStringLiteral("custom_rtc/use_global"), true).toBool(); |
| 708 | std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong()); | 717 | Settings::values.custom_rtc.SetGlobal(custom_rtc_global); |
| 709 | } else { | 718 | if (global || !custom_rtc_global) { |
| 710 | Settings::values.custom_rtc = std::nullopt; | 719 | if (custom_rtc_enabled) { |
| 720 | Settings::values.custom_rtc.SetValue( | ||
| 721 | std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong())); | ||
| 722 | } else { | ||
| 723 | Settings::values.custom_rtc.SetValue(std::nullopt); | ||
| 724 | } | ||
| 711 | } | 725 | } |
| 712 | 726 | ||
| 713 | Settings::values.sound_index = ReadSetting(QStringLiteral("sound_index"), 1).toInt(); | 727 | ReadSettingGlobal(Settings::values.sound_index, QStringLiteral("sound_index"), 1); |
| 714 | 728 | ||
| 715 | qt_config->endGroup(); | 729 | qt_config->endGroup(); |
| 716 | } | 730 | } |
| @@ -804,18 +818,20 @@ void Config::ReadWebServiceValues() { | |||
| 804 | } | 818 | } |
| 805 | 819 | ||
| 806 | void Config::ReadValues() { | 820 | void Config::ReadValues() { |
| 807 | ReadControlValues(); | 821 | if (global) { |
| 822 | ReadControlValues(); | ||
| 823 | ReadDataStorageValues(); | ||
| 824 | ReadDebuggingValues(); | ||
| 825 | ReadDisabledAddOnValues(); | ||
| 826 | ReadServiceValues(); | ||
| 827 | ReadUIValues(); | ||
| 828 | ReadWebServiceValues(); | ||
| 829 | ReadMiscellaneousValues(); | ||
| 830 | } | ||
| 808 | ReadCoreValues(); | 831 | ReadCoreValues(); |
| 809 | ReadRendererValues(); | 832 | ReadRendererValues(); |
| 810 | ReadAudioValues(); | 833 | ReadAudioValues(); |
| 811 | ReadDataStorageValues(); | ||
| 812 | ReadSystemValues(); | 834 | ReadSystemValues(); |
| 813 | ReadMiscellaneousValues(); | ||
| 814 | ReadDebuggingValues(); | ||
| 815 | ReadWebServiceValues(); | ||
| 816 | ReadServiceValues(); | ||
| 817 | ReadDisabledAddOnValues(); | ||
| 818 | ReadUIValues(); | ||
| 819 | } | 835 | } |
| 820 | 836 | ||
| 821 | void Config::SavePlayerValues() { | 837 | void Config::SavePlayerValues() { |
| @@ -902,30 +918,35 @@ void Config::SaveTouchscreenValues() { | |||
| 902 | } | 918 | } |
| 903 | 919 | ||
| 904 | void Config::SaveValues() { | 920 | void Config::SaveValues() { |
| 905 | SaveControlValues(); | 921 | if (global) { |
| 922 | SaveControlValues(); | ||
| 923 | SaveDataStorageValues(); | ||
| 924 | SaveDebuggingValues(); | ||
| 925 | SaveDisabledAddOnValues(); | ||
| 926 | SaveServiceValues(); | ||
| 927 | SaveUIValues(); | ||
| 928 | SaveWebServiceValues(); | ||
| 929 | SaveMiscellaneousValues(); | ||
| 930 | } | ||
| 906 | SaveCoreValues(); | 931 | SaveCoreValues(); |
| 907 | SaveRendererValues(); | 932 | SaveRendererValues(); |
| 908 | SaveAudioValues(); | 933 | SaveAudioValues(); |
| 909 | SaveDataStorageValues(); | ||
| 910 | SaveSystemValues(); | 934 | SaveSystemValues(); |
| 911 | SaveMiscellaneousValues(); | ||
| 912 | SaveDebuggingValues(); | ||
| 913 | SaveWebServiceValues(); | ||
| 914 | SaveServiceValues(); | ||
| 915 | SaveDisabledAddOnValues(); | ||
| 916 | SaveUIValues(); | ||
| 917 | } | 935 | } |
| 918 | 936 | ||
| 919 | void Config::SaveAudioValues() { | 937 | void Config::SaveAudioValues() { |
| 920 | qt_config->beginGroup(QStringLiteral("Audio")); | 938 | qt_config->beginGroup(QStringLiteral("Audio")); |
| 921 | 939 | ||
| 922 | WriteSetting(QStringLiteral("output_engine"), QString::fromStdString(Settings::values.sink_id), | 940 | if (global) { |
| 923 | QStringLiteral("auto")); | 941 | WriteSetting(QStringLiteral("output_engine"), |
| 924 | WriteSetting(QStringLiteral("enable_audio_stretching"), | 942 | QString::fromStdString(Settings::values.sink_id), QStringLiteral("auto")); |
| 925 | Settings::values.enable_audio_stretching, true); | 943 | WriteSetting(QStringLiteral("output_device"), |
| 926 | WriteSetting(QStringLiteral("output_device"), | 944 | QString::fromStdString(Settings::values.audio_device_id), |
| 927 | QString::fromStdString(Settings::values.audio_device_id), QStringLiteral("auto")); | 945 | QStringLiteral("auto")); |
| 928 | WriteSetting(QStringLiteral("volume"), Settings::values.volume, 1.0f); | 946 | } |
| 947 | WriteSettingGlobal(QStringLiteral("enable_audio_stretching"), | ||
| 948 | Settings::values.enable_audio_stretching, true); | ||
| 949 | WriteSettingGlobal(QStringLiteral("volume"), Settings::values.volume, 1.0f); | ||
| 929 | 950 | ||
| 930 | qt_config->endGroup(); | 951 | qt_config->endGroup(); |
| 931 | } | 952 | } |
| @@ -948,6 +969,7 @@ void Config::SaveControlValues() { | |||
| 948 | WriteSetting(QStringLiteral("udp_input_port"), Settings::values.udp_input_port, | 969 | WriteSetting(QStringLiteral("udp_input_port"), Settings::values.udp_input_port, |
| 949 | InputCommon::CemuhookUDP::DEFAULT_PORT); | 970 | InputCommon::CemuhookUDP::DEFAULT_PORT); |
| 950 | WriteSetting(QStringLiteral("udp_pad_index"), Settings::values.udp_pad_index, 0); | 971 | WriteSetting(QStringLiteral("udp_pad_index"), Settings::values.udp_pad_index, 0); |
| 972 | WriteSetting(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false); | ||
| 951 | 973 | ||
| 952 | qt_config->endGroup(); | 974 | qt_config->endGroup(); |
| 953 | } | 975 | } |
| @@ -955,7 +977,7 @@ void Config::SaveControlValues() { | |||
| 955 | void Config::SaveCoreValues() { | 977 | void Config::SaveCoreValues() { |
| 956 | qt_config->beginGroup(QStringLiteral("Core")); | 978 | qt_config->beginGroup(QStringLiteral("Core")); |
| 957 | 979 | ||
| 958 | WriteSetting(QStringLiteral("use_multi_core"), Settings::values.use_multi_core, false); | 980 | WriteSettingGlobal(QStringLiteral("use_multi_core"), Settings::values.use_multi_core, false); |
| 959 | 981 | ||
| 960 | qt_config->endGroup(); | 982 | qt_config->endGroup(); |
| 961 | } | 983 | } |
| @@ -1078,29 +1100,34 @@ void Config::SavePathValues() { | |||
| 1078 | void Config::SaveRendererValues() { | 1100 | void Config::SaveRendererValues() { |
| 1079 | qt_config->beginGroup(QStringLiteral("Renderer")); | 1101 | qt_config->beginGroup(QStringLiteral("Renderer")); |
| 1080 | 1102 | ||
| 1081 | WriteSetting(QStringLiteral("backend"), static_cast<int>(Settings::values.renderer_backend), 0); | 1103 | WriteSettingGlobal(QStringLiteral("backend"), |
| 1104 | static_cast<int>(Settings::values.renderer_backend.GetValue(global)), | ||
| 1105 | Settings::values.renderer_backend.UsingGlobal(), 0); | ||
| 1082 | WriteSetting(QStringLiteral("debug"), Settings::values.renderer_debug, false); | 1106 | WriteSetting(QStringLiteral("debug"), Settings::values.renderer_debug, false); |
| 1083 | WriteSetting(QStringLiteral("vulkan_device"), Settings::values.vulkan_device, 0); | 1107 | WriteSettingGlobal(QStringLiteral("vulkan_device"), Settings::values.vulkan_device, 0); |
| 1084 | WriteSetting(QStringLiteral("aspect_ratio"), Settings::values.aspect_ratio, 0); | 1108 | WriteSettingGlobal(QStringLiteral("aspect_ratio"), Settings::values.aspect_ratio, 0); |
| 1085 | WriteSetting(QStringLiteral("max_anisotropy"), Settings::values.max_anisotropy, 0); | 1109 | WriteSettingGlobal(QStringLiteral("max_anisotropy"), Settings::values.max_anisotropy, 0); |
| 1086 | WriteSetting(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true); | 1110 | WriteSettingGlobal(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true); |
| 1087 | WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100); | 1111 | WriteSettingGlobal(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100); |
| 1088 | WriteSetting(QStringLiteral("use_disk_shader_cache"), Settings::values.use_disk_shader_cache, | 1112 | WriteSettingGlobal(QStringLiteral("use_disk_shader_cache"), |
| 1089 | true); | 1113 | Settings::values.use_disk_shader_cache, true); |
| 1090 | WriteSetting(QStringLiteral("gpu_accuracy"), static_cast<int>(Settings::values.gpu_accuracy), | 1114 | WriteSettingGlobal(QStringLiteral("gpu_accuracy"), |
| 1091 | 0); | 1115 | static_cast<int>(Settings::values.gpu_accuracy.GetValue(global)), |
| 1092 | WriteSetting(QStringLiteral("use_asynchronous_gpu_emulation"), | 1116 | Settings::values.gpu_accuracy.UsingGlobal(), 0); |
| 1093 | Settings::values.use_asynchronous_gpu_emulation, false); | 1117 | WriteSettingGlobal(QStringLiteral("use_asynchronous_gpu_emulation"), |
| 1094 | WriteSetting(QStringLiteral("use_vsync"), Settings::values.use_vsync, true); | 1118 | Settings::values.use_asynchronous_gpu_emulation, false); |
| 1095 | WriteSetting(QStringLiteral("use_assembly_shaders"), Settings::values.use_assembly_shaders, | 1119 | WriteSettingGlobal(QStringLiteral("use_vsync"), Settings::values.use_vsync, true); |
| 1096 | false); | 1120 | WriteSettingGlobal(QStringLiteral("use_assembly_shaders"), |
| 1097 | WriteSetting(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time, true); | 1121 | Settings::values.use_assembly_shaders, false); |
| 1098 | WriteSetting(QStringLiteral("force_30fps_mode"), Settings::values.force_30fps_mode, false); | 1122 | WriteSettingGlobal(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time, |
| 1123 | true); | ||
| 1124 | WriteSettingGlobal(QStringLiteral("force_30fps_mode"), Settings::values.force_30fps_mode, | ||
| 1125 | false); | ||
| 1099 | 1126 | ||
| 1100 | // Cast to double because Qt's written float values are not human-readable | 1127 | // Cast to double because Qt's written float values are not human-readable |
| 1101 | WriteSetting(QStringLiteral("bg_red"), static_cast<double>(Settings::values.bg_red), 0.0); | 1128 | WriteSettingGlobal(QStringLiteral("bg_red"), Settings::values.bg_red, 0.0); |
| 1102 | WriteSetting(QStringLiteral("bg_green"), static_cast<double>(Settings::values.bg_green), 0.0); | 1129 | WriteSettingGlobal(QStringLiteral("bg_green"), Settings::values.bg_green, 0.0); |
| 1103 | WriteSetting(QStringLiteral("bg_blue"), static_cast<double>(Settings::values.bg_blue), 0.0); | 1130 | WriteSettingGlobal(QStringLiteral("bg_blue"), Settings::values.bg_blue, 0.0); |
| 1104 | 1131 | ||
| 1105 | qt_config->endGroup(); | 1132 | qt_config->endGroup(); |
| 1106 | } | 1133 | } |
| @@ -1128,23 +1155,28 @@ void Config::SaveShortcutValues() { | |||
| 1128 | void Config::SaveSystemValues() { | 1155 | void Config::SaveSystemValues() { |
| 1129 | qt_config->beginGroup(QStringLiteral("System")); | 1156 | qt_config->beginGroup(QStringLiteral("System")); |
| 1130 | 1157 | ||
| 1131 | WriteSetting(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false); | ||
| 1132 | WriteSetting(QStringLiteral("current_user"), Settings::values.current_user, 0); | 1158 | WriteSetting(QStringLiteral("current_user"), Settings::values.current_user, 0); |
| 1133 | WriteSetting(QStringLiteral("language_index"), Settings::values.language_index, 1); | 1159 | WriteSettingGlobal(QStringLiteral("language_index"), Settings::values.language_index, 1); |
| 1134 | WriteSetting(QStringLiteral("region_index"), Settings::values.region_index, 1); | 1160 | WriteSettingGlobal(QStringLiteral("region_index"), Settings::values.region_index, 1); |
| 1135 | WriteSetting(QStringLiteral("time_zone_index"), Settings::values.time_zone_index, 0); | 1161 | WriteSettingGlobal(QStringLiteral("time_zone_index"), Settings::values.time_zone_index, 0); |
| 1136 | 1162 | ||
| 1137 | WriteSetting(QStringLiteral("rng_seed_enabled"), Settings::values.rng_seed.has_value(), false); | 1163 | WriteSettingGlobal(QStringLiteral("rng_seed_enabled"), |
| 1138 | WriteSetting(QStringLiteral("rng_seed"), Settings::values.rng_seed.value_or(0), 0); | 1164 | Settings::values.rng_seed.GetValue(global).has_value(), |
| 1139 | 1165 | Settings::values.rng_seed.UsingGlobal(), false); | |
| 1140 | WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(), | 1166 | WriteSettingGlobal(QStringLiteral("rng_seed"), |
| 1141 | false); | 1167 | Settings::values.rng_seed.GetValue(global).value_or(0), |
| 1142 | WriteSetting(QStringLiteral("custom_rtc"), | 1168 | Settings::values.rng_seed.UsingGlobal(), 0); |
| 1143 | QVariant::fromValue<long long>( | 1169 | |
| 1144 | Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()), | 1170 | WriteSettingGlobal(QStringLiteral("custom_rtc_enabled"), |
| 1145 | 0); | 1171 | Settings::values.custom_rtc.GetValue(global).has_value(), |
| 1146 | 1172 | Settings::values.custom_rtc.UsingGlobal(), false); | |
| 1147 | WriteSetting(QStringLiteral("sound_index"), Settings::values.sound_index, 1); | 1173 | WriteSettingGlobal( |
| 1174 | QStringLiteral("custom_rtc"), | ||
| 1175 | QVariant::fromValue<long long>( | ||
| 1176 | Settings::values.custom_rtc.GetValue(global).value_or(std::chrono::seconds{}).count()), | ||
| 1177 | Settings::values.custom_rtc.UsingGlobal(), 0); | ||
| 1178 | |||
| 1179 | WriteSettingGlobal(QStringLiteral("sound_index"), Settings::values.sound_index, 1); | ||
| 1148 | 1180 | ||
| 1149 | qt_config->endGroup(); | 1181 | qt_config->endGroup(); |
| 1150 | } | 1182 | } |
| @@ -1236,6 +1268,34 @@ QVariant Config::ReadSetting(const QString& name, const QVariant& default_value) | |||
| 1236 | return result; | 1268 | return result; |
| 1237 | } | 1269 | } |
| 1238 | 1270 | ||
| 1271 | template <typename Type> | ||
| 1272 | void Config::ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name) { | ||
| 1273 | const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool(); | ||
| 1274 | setting.SetGlobal(use_global); | ||
| 1275 | if (global || !use_global) { | ||
| 1276 | setting.SetValue(ReadSetting(name).value<Type>()); | ||
| 1277 | } | ||
| 1278 | } | ||
| 1279 | |||
| 1280 | template <typename Type> | ||
| 1281 | void Config::ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name, | ||
| 1282 | const QVariant& default_value) { | ||
| 1283 | const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool(); | ||
| 1284 | setting.SetGlobal(use_global); | ||
| 1285 | if (global || !use_global) { | ||
| 1286 | setting.SetValue(ReadSetting(name, default_value).value<Type>()); | ||
| 1287 | } | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | template <typename Type> | ||
| 1291 | void Config::ReadSettingGlobal(Type& setting, const QString& name, | ||
| 1292 | const QVariant& default_value) const { | ||
| 1293 | const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool(); | ||
| 1294 | if (global || !use_global) { | ||
| 1295 | setting = ReadSetting(name, default_value).value<Type>(); | ||
| 1296 | } | ||
| 1297 | } | ||
| 1298 | |||
| 1239 | void Config::WriteSetting(const QString& name, const QVariant& value) { | 1299 | void Config::WriteSetting(const QString& name, const QVariant& value) { |
| 1240 | qt_config->setValue(name, value); | 1300 | qt_config->setValue(name, value); |
| 1241 | } | 1301 | } |
| @@ -1246,6 +1306,40 @@ void Config::WriteSetting(const QString& name, const QVariant& value, | |||
| 1246 | qt_config->setValue(name, value); | 1306 | qt_config->setValue(name, value); |
| 1247 | } | 1307 | } |
| 1248 | 1308 | ||
| 1309 | template <typename Type> | ||
| 1310 | void Config::WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting) { | ||
| 1311 | if (!global) { | ||
| 1312 | qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal()); | ||
| 1313 | } | ||
| 1314 | if (global || !setting.UsingGlobal()) { | ||
| 1315 | qt_config->setValue(name, setting.GetValue(global)); | ||
| 1316 | } | ||
| 1317 | } | ||
| 1318 | |||
| 1319 | template <typename Type> | ||
| 1320 | void Config::WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting, | ||
| 1321 | const QVariant& default_value) { | ||
| 1322 | if (!global) { | ||
| 1323 | qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal()); | ||
| 1324 | } | ||
| 1325 | if (global || !setting.UsingGlobal()) { | ||
| 1326 | qt_config->setValue(name + QStringLiteral("/default"), | ||
| 1327 | setting.GetValue(global) == default_value.value<Type>()); | ||
| 1328 | qt_config->setValue(name, setting.GetValue(global)); | ||
| 1329 | } | ||
| 1330 | } | ||
| 1331 | |||
| 1332 | void Config::WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global, | ||
| 1333 | const QVariant& default_value) { | ||
| 1334 | if (!global) { | ||
| 1335 | qt_config->setValue(name + QStringLiteral("/use_global"), use_global); | ||
| 1336 | } | ||
| 1337 | if (global || !use_global) { | ||
| 1338 | qt_config->setValue(name + QStringLiteral("/default"), value == default_value); | ||
| 1339 | qt_config->setValue(name, value); | ||
| 1340 | } | ||
| 1341 | } | ||
| 1342 | |||
| 1249 | void Config::Reload() { | 1343 | void Config::Reload() { |
| 1250 | ReadValues(); | 1344 | ReadValues(); |
| 1251 | // To apply default value changes | 1345 | // To apply default value changes |
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 09316382c..681f0bca5 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include <array> | 7 | #include <array> |
| 8 | #include <memory> | 8 | #include <memory> |
| 9 | #include <string> | 9 | #include <string> |
| 10 | #include <QMetaType> | ||
| 10 | #include <QVariant> | 11 | #include <QVariant> |
| 11 | #include "core/settings.h" | 12 | #include "core/settings.h" |
| 12 | #include "yuzu/uisettings.h" | 13 | #include "yuzu/uisettings.h" |
| @@ -15,7 +16,7 @@ class QSettings; | |||
| 15 | 16 | ||
| 16 | class Config { | 17 | class Config { |
| 17 | public: | 18 | public: |
| 18 | Config(); | 19 | explicit Config(const std::string& config_loc = "qt-config.ini", bool is_global = true); |
| 19 | ~Config(); | 20 | ~Config(); |
| 20 | 21 | ||
| 21 | void Reload(); | 22 | void Reload(); |
| @@ -82,9 +83,33 @@ private: | |||
| 82 | 83 | ||
| 83 | QVariant ReadSetting(const QString& name) const; | 84 | QVariant ReadSetting(const QString& name) const; |
| 84 | QVariant ReadSetting(const QString& name, const QVariant& default_value) const; | 85 | QVariant ReadSetting(const QString& name, const QVariant& default_value) const; |
| 86 | // Templated ReadSettingGlobal functions will also look for the use_global setting and set | ||
| 87 | // both the value and the global state properly | ||
| 88 | template <typename Type> | ||
| 89 | void ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name); | ||
| 90 | template <typename Type> | ||
| 91 | void ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name, | ||
| 92 | const QVariant& default_value); | ||
| 93 | template <typename Type> | ||
| 94 | void ReadSettingGlobal(Type& setting, const QString& name, const QVariant& default_value) const; | ||
| 95 | // Templated WriteSettingGlobal functions will also write the global state if needed and will | ||
| 96 | // skip writing the actual setting if it defers to the global value | ||
| 85 | void WriteSetting(const QString& name, const QVariant& value); | 97 | void WriteSetting(const QString& name, const QVariant& value); |
| 86 | void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value); | 98 | void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value); |
| 99 | template <typename Type> | ||
| 100 | void WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting); | ||
| 101 | template <typename Type> | ||
| 102 | void WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting, | ||
| 103 | const QVariant& default_value); | ||
| 104 | void WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global, | ||
| 105 | const QVariant& default_value); | ||
| 87 | 106 | ||
| 88 | std::unique_ptr<QSettings> qt_config; | 107 | std::unique_ptr<QSettings> qt_config; |
| 89 | std::string qt_config_loc; | 108 | std::string qt_config_loc; |
| 109 | |||
| 110 | bool global; | ||
| 90 | }; | 111 | }; |
| 112 | |||
| 113 | // These metatype declarations cannot be in core/settings.h because core is devoid of QT | ||
| 114 | Q_DECLARE_METATYPE(Settings::RendererBackend); | ||
| 115 | Q_DECLARE_METATYPE(Settings::GPUAccuracy); | ||
diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp new file mode 100644 index 000000000..bb47c3933 --- /dev/null +++ b/src/yuzu/configuration/configuration_shared.cpp | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | // Copyright 2016 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <QCheckBox> | ||
| 6 | #include <QComboBox> | ||
| 7 | #include "core/settings.h" | ||
| 8 | #include "yuzu/configuration/configuration_shared.h" | ||
| 9 | #include "yuzu/configuration/configure_per_game.h" | ||
| 10 | |||
| 11 | void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting, | ||
| 12 | const QCheckBox* checkbox) { | ||
| 13 | if (checkbox->checkState() == Qt::PartiallyChecked) { | ||
| 14 | setting->SetGlobal(true); | ||
| 15 | } else { | ||
| 16 | setting->SetGlobal(false); | ||
| 17 | setting->SetValue(checkbox->checkState() == Qt::Checked); | ||
| 18 | } | ||
| 19 | } | ||
| 20 | |||
| 21 | void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<int>* setting, | ||
| 22 | const QComboBox* combobox) { | ||
| 23 | if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { | ||
| 24 | setting->SetGlobal(true); | ||
| 25 | } else { | ||
| 26 | setting->SetGlobal(false); | ||
| 27 | setting->SetValue(combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET); | ||
| 28 | } | ||
| 29 | } | ||
| 30 | |||
| 31 | void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<Settings::RendererBackend>* setting, | ||
| 32 | const QComboBox* combobox) { | ||
| 33 | if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { | ||
| 34 | setting->SetGlobal(true); | ||
| 35 | } else { | ||
| 36 | setting->SetGlobal(false); | ||
| 37 | setting->SetValue(static_cast<Settings::RendererBackend>( | ||
| 38 | combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET)); | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox, | ||
| 43 | const Settings::Setting<bool>* setting) { | ||
| 44 | if (setting->UsingGlobal()) { | ||
| 45 | checkbox->setCheckState(Qt::PartiallyChecked); | ||
| 46 | } else { | ||
| 47 | checkbox->setCheckState(setting->GetValue() ? Qt::Checked : Qt::Unchecked); | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | void ConfigurationShared::SetPerGameSetting(QComboBox* combobox, | ||
| 52 | const Settings::Setting<int>* setting) { | ||
| 53 | combobox->setCurrentIndex(setting->UsingGlobal() | ||
| 54 | ? ConfigurationShared::USE_GLOBAL_INDEX | ||
| 55 | : setting->GetValue() + ConfigurationShared::USE_GLOBAL_OFFSET); | ||
| 56 | } | ||
| 57 | |||
| 58 | void ConfigurationShared::SetPerGameSetting( | ||
| 59 | QComboBox* combobox, const Settings::Setting<Settings::RendererBackend>* setting) { | ||
| 60 | combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX | ||
| 61 | : static_cast<int>(setting->GetValue()) + | ||
| 62 | ConfigurationShared::USE_GLOBAL_OFFSET); | ||
| 63 | } | ||
| 64 | |||
| 65 | void ConfigurationShared::SetPerGameSetting( | ||
| 66 | QComboBox* combobox, const Settings::Setting<Settings::GPUAccuracy>* setting) { | ||
| 67 | combobox->setCurrentIndex(setting->UsingGlobal() ? ConfigurationShared::USE_GLOBAL_INDEX | ||
| 68 | : static_cast<int>(setting->GetValue()) + | ||
| 69 | ConfigurationShared::USE_GLOBAL_OFFSET); | ||
| 70 | } | ||
| 71 | |||
| 72 | void ConfigurationShared::InsertGlobalItem(QComboBox* combobox) { | ||
| 73 | const QString use_global_text = ConfigurePerGame::tr("Use global configuration"); | ||
| 74 | combobox->insertItem(ConfigurationShared::USE_GLOBAL_INDEX, use_global_text); | ||
| 75 | combobox->insertSeparator(ConfigurationShared::USE_GLOBAL_SEPARATOR_INDEX); | ||
| 76 | } | ||
diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h new file mode 100644 index 000000000..b11b1b950 --- /dev/null +++ b/src/yuzu/configuration/configuration_shared.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | // Copyright 2016 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <QCheckBox> | ||
| 8 | #include <QComboBox> | ||
| 9 | #include <QString> | ||
| 10 | #include "core/settings.h" | ||
| 11 | |||
| 12 | namespace ConfigurationShared { | ||
| 13 | |||
| 14 | constexpr int USE_GLOBAL_INDEX = 0; | ||
| 15 | constexpr int USE_GLOBAL_SEPARATOR_INDEX = 1; | ||
| 16 | constexpr int USE_GLOBAL_OFFSET = 2; | ||
| 17 | |||
| 18 | // Global-aware apply and set functions | ||
| 19 | |||
| 20 | void ApplyPerGameSetting(Settings::Setting<bool>* setting, const QCheckBox* checkbox); | ||
| 21 | void ApplyPerGameSetting(Settings::Setting<int>* setting, const QComboBox* combobox); | ||
| 22 | void ApplyPerGameSetting(Settings::Setting<Settings::RendererBackend>* setting, | ||
| 23 | const QComboBox* combobox); | ||
| 24 | void ApplyPerGameSetting(Settings::Setting<Settings::GPUAccuracy>* setting, | ||
| 25 | const QComboBox* combobox); | ||
| 26 | |||
| 27 | void SetPerGameSetting(QCheckBox* checkbox, const Settings::Setting<bool>* setting); | ||
| 28 | void SetPerGameSetting(QComboBox* combobox, const Settings::Setting<int>* setting); | ||
| 29 | void SetPerGameSetting(QComboBox* combobox, | ||
| 30 | const Settings::Setting<Settings::RendererBackend>* setting); | ||
| 31 | void SetPerGameSetting(QComboBox* combobox, | ||
| 32 | const Settings::Setting<Settings::GPUAccuracy>* setting); | ||
| 33 | |||
| 34 | void InsertGlobalItem(QComboBox* combobox); | ||
| 35 | |||
| 36 | } // namespace ConfigurationShared | ||
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp index f370c690f..cc021beec 100644 --- a/src/yuzu/configuration/configure_audio.cpp +++ b/src/yuzu/configuration/configure_audio.cpp | |||
| @@ -11,6 +11,7 @@ | |||
| 11 | #include "core/core.h" | 11 | #include "core/core.h" |
| 12 | #include "core/settings.h" | 12 | #include "core/settings.h" |
| 13 | #include "ui_configure_audio.h" | 13 | #include "ui_configure_audio.h" |
| 14 | #include "yuzu/configuration/configuration_shared.h" | ||
| 14 | #include "yuzu/configuration/configure_audio.h" | 15 | #include "yuzu/configuration/configure_audio.h" |
| 15 | 16 | ||
| 16 | ConfigureAudio::ConfigureAudio(QWidget* parent) | 17 | ConfigureAudio::ConfigureAudio(QWidget* parent) |
| @@ -24,6 +25,11 @@ ConfigureAudio::ConfigureAudio(QWidget* parent) | |||
| 24 | connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this, | 25 | connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this, |
| 25 | &ConfigureAudio::UpdateAudioDevices); | 26 | &ConfigureAudio::UpdateAudioDevices); |
| 26 | 27 | ||
| 28 | ui->volume_label->setVisible(Settings::configuring_global); | ||
| 29 | ui->volume_combo_box->setVisible(!Settings::configuring_global); | ||
| 30 | |||
| 31 | SetupPerGameUI(); | ||
| 32 | |||
| 27 | SetConfiguration(); | 33 | SetConfiguration(); |
| 28 | 34 | ||
| 29 | const bool is_powered_on = Core::System::GetInstance().IsPoweredOn(); | 35 | const bool is_powered_on = Core::System::GetInstance().IsPoweredOn(); |
| @@ -41,8 +47,22 @@ void ConfigureAudio::SetConfiguration() { | |||
| 41 | 47 | ||
| 42 | SetAudioDeviceFromDeviceID(); | 48 | SetAudioDeviceFromDeviceID(); |
| 43 | 49 | ||
| 44 | ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching); | 50 | ui->volume_slider->setValue(Settings::values.volume.GetValue() * ui->volume_slider->maximum()); |
| 45 | ui->volume_slider->setValue(Settings::values.volume * ui->volume_slider->maximum()); | 51 | |
| 52 | if (Settings::configuring_global) { | ||
| 53 | ui->toggle_audio_stretching->setChecked( | ||
| 54 | Settings::values.enable_audio_stretching.GetValue()); | ||
| 55 | } else { | ||
| 56 | ConfigurationShared::SetPerGameSetting(ui->toggle_audio_stretching, | ||
| 57 | &Settings::values.enable_audio_stretching); | ||
| 58 | if (Settings::values.volume.UsingGlobal()) { | ||
| 59 | ui->volume_combo_box->setCurrentIndex(0); | ||
| 60 | ui->volume_slider->setEnabled(false); | ||
| 61 | } else { | ||
| 62 | ui->volume_combo_box->setCurrentIndex(1); | ||
| 63 | ui->volume_slider->setEnabled(true); | ||
| 64 | } | ||
| 65 | } | ||
| 46 | SetVolumeIndicatorText(ui->volume_slider->sliderPosition()); | 66 | SetVolumeIndicatorText(ui->volume_slider->sliderPosition()); |
| 47 | } | 67 | } |
| 48 | 68 | ||
| @@ -80,15 +100,36 @@ void ConfigureAudio::SetVolumeIndicatorText(int percentage) { | |||
| 80 | } | 100 | } |
| 81 | 101 | ||
| 82 | void ConfigureAudio::ApplyConfiguration() { | 102 | void ConfigureAudio::ApplyConfiguration() { |
| 83 | Settings::values.sink_id = | 103 | if (Settings::configuring_global) { |
| 84 | ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex()) | 104 | Settings::values.sink_id = |
| 85 | .toStdString(); | 105 | ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex()) |
| 86 | Settings::values.enable_audio_stretching = ui->toggle_audio_stretching->isChecked(); | 106 | .toStdString(); |
| 87 | Settings::values.audio_device_id = | 107 | Settings::values.audio_device_id = |
| 88 | ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex()) | 108 | ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex()) |
| 89 | .toStdString(); | 109 | .toStdString(); |
| 90 | Settings::values.volume = | 110 | |
| 91 | static_cast<float>(ui->volume_slider->sliderPosition()) / ui->volume_slider->maximum(); | 111 | // Guard if during game and set to game-specific value |
| 112 | if (Settings::values.enable_audio_stretching.UsingGlobal()) { | ||
| 113 | Settings::values.enable_audio_stretching.SetValue( | ||
| 114 | ui->toggle_audio_stretching->isChecked()); | ||
| 115 | } | ||
| 116 | if (Settings::values.volume.UsingGlobal()) { | ||
| 117 | Settings::values.volume.SetValue( | ||
| 118 | static_cast<float>(ui->volume_slider->sliderPosition()) / | ||
| 119 | ui->volume_slider->maximum()); | ||
| 120 | } | ||
| 121 | } else { | ||
| 122 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.enable_audio_stretching, | ||
| 123 | ui->toggle_audio_stretching); | ||
| 124 | if (ui->volume_combo_box->currentIndex() == 0) { | ||
| 125 | Settings::values.volume.SetGlobal(true); | ||
| 126 | } else { | ||
| 127 | Settings::values.volume.SetGlobal(false); | ||
| 128 | Settings::values.volume.SetValue( | ||
| 129 | static_cast<float>(ui->volume_slider->sliderPosition()) / | ||
| 130 | ui->volume_slider->maximum()); | ||
| 131 | } | ||
| 132 | } | ||
| 92 | } | 133 | } |
| 93 | 134 | ||
| 94 | void ConfigureAudio::changeEvent(QEvent* event) { | 135 | void ConfigureAudio::changeEvent(QEvent* event) { |
| @@ -122,3 +163,22 @@ void ConfigureAudio::RetranslateUI() { | |||
| 122 | ui->retranslateUi(this); | 163 | ui->retranslateUi(this); |
| 123 | SetVolumeIndicatorText(ui->volume_slider->sliderPosition()); | 164 | SetVolumeIndicatorText(ui->volume_slider->sliderPosition()); |
| 124 | } | 165 | } |
| 166 | |||
| 167 | void ConfigureAudio::SetupPerGameUI() { | ||
| 168 | if (Settings::configuring_global) { | ||
| 169 | ui->volume_slider->setEnabled(Settings::values.volume.UsingGlobal()); | ||
| 170 | ui->toggle_audio_stretching->setEnabled( | ||
| 171 | Settings::values.enable_audio_stretching.UsingGlobal()); | ||
| 172 | |||
| 173 | return; | ||
| 174 | } | ||
| 175 | |||
| 176 | ui->toggle_audio_stretching->setTristate(true); | ||
| 177 | connect(ui->volume_combo_box, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), | ||
| 178 | this, [this](int index) { ui->volume_slider->setEnabled(index == 1); }); | ||
| 179 | |||
| 180 | ui->output_sink_combo_box->setVisible(false); | ||
| 181 | ui->output_sink_label->setVisible(false); | ||
| 182 | ui->audio_device_combo_box->setVisible(false); | ||
| 183 | ui->audio_device_label->setVisible(false); | ||
| 184 | } | ||
diff --git a/src/yuzu/configuration/configure_audio.h b/src/yuzu/configuration/configure_audio.h index ea83bd72d..d84f4a682 100644 --- a/src/yuzu/configuration/configure_audio.h +++ b/src/yuzu/configuration/configure_audio.h | |||
| @@ -34,5 +34,7 @@ private: | |||
| 34 | void SetAudioDeviceFromDeviceID(); | 34 | void SetAudioDeviceFromDeviceID(); |
| 35 | void SetVolumeIndicatorText(int percentage); | 35 | void SetVolumeIndicatorText(int percentage); |
| 36 | 36 | ||
| 37 | void SetupPerGameUI(); | ||
| 38 | |||
| 37 | std::unique_ptr<Ui::ConfigureAudio> ui; | 39 | std::unique_ptr<Ui::ConfigureAudio> ui; |
| 38 | }; | 40 | }; |
diff --git a/src/yuzu/configuration/configure_audio.ui b/src/yuzu/configuration/configure_audio.ui index a098b9acc..862ccb988 100644 --- a/src/yuzu/configuration/configure_audio.ui +++ b/src/yuzu/configuration/configure_audio.ui | |||
| @@ -6,8 +6,8 @@ | |||
| 6 | <rect> | 6 | <rect> |
| 7 | <x>0</x> | 7 | <x>0</x> |
| 8 | <y>0</y> | 8 | <y>0</y> |
| 9 | <width>188</width> | 9 | <width>367</width> |
| 10 | <height>246</height> | 10 | <height>368</height> |
| 11 | </rect> | 11 | </rect> |
| 12 | </property> | 12 | </property> |
| 13 | <layout class="QVBoxLayout"> | 13 | <layout class="QVBoxLayout"> |
| @@ -18,9 +18,9 @@ | |||
| 18 | </property> | 18 | </property> |
| 19 | <layout class="QVBoxLayout"> | 19 | <layout class="QVBoxLayout"> |
| 20 | <item> | 20 | <item> |
| 21 | <layout class="QHBoxLayout"> | 21 | <layout class="QHBoxLayout" name="_3"> |
| 22 | <item> | 22 | <item> |
| 23 | <widget class="QLabel" name="label_1"> | 23 | <widget class="QLabel" name="output_sink_label"> |
| 24 | <property name="text"> | 24 | <property name="text"> |
| 25 | <string>Output Engine:</string> | 25 | <string>Output Engine:</string> |
| 26 | </property> | 26 | </property> |
| @@ -31,20 +31,20 @@ | |||
| 31 | </item> | 31 | </item> |
| 32 | </layout> | 32 | </layout> |
| 33 | </item> | 33 | </item> |
| 34 | <item> | ||
| 35 | <widget class="QCheckBox" name="toggle_audio_stretching"> | ||
| 36 | <property name="toolTip"> | ||
| 37 | <string>This post-processing effect adjusts audio speed to match emulation speed and helps prevent audio stutter. This however increases audio latency.</string> | ||
| 38 | </property> | ||
| 39 | <property name="text"> | ||
| 40 | <string>Enable audio stretching</string> | ||
| 41 | </property> | ||
| 42 | </widget> | ||
| 43 | </item> | ||
| 44 | <item> | 34 | <item> |
| 45 | <layout class="QHBoxLayout"> | 35 | <widget class="QCheckBox" name="toggle_audio_stretching"> |
| 36 | <property name="toolTip"> | ||
| 37 | <string>This post-processing effect adjusts audio speed to match emulation speed and helps prevent audio stutter. This however increases audio latency.</string> | ||
| 38 | </property> | ||
| 39 | <property name="text"> | ||
| 40 | <string>Enable audio stretching</string> | ||
| 41 | </property> | ||
| 42 | </widget> | ||
| 43 | </item> | ||
| 44 | <item> | ||
| 45 | <layout class="QHBoxLayout" name="_2"> | ||
| 46 | <item> | 46 | <item> |
| 47 | <widget class="QLabel" name="label_2"> | 47 | <widget class="QLabel" name="audio_device_label"> |
| 48 | <property name="text"> | 48 | <property name="text"> |
| 49 | <string>Audio Device:</string> | 49 | <string>Audio Device:</string> |
| 50 | </property> | 50 | </property> |
| @@ -61,7 +61,21 @@ | |||
| 61 | <number>0</number> | 61 | <number>0</number> |
| 62 | </property> | 62 | </property> |
| 63 | <item> | 63 | <item> |
| 64 | <widget class="QLabel" name="label_3"> | 64 | <widget class="QComboBox" name="volume_combo_box"> |
| 65 | <item> | ||
| 66 | <property name="text"> | ||
| 67 | <string>Use global volume</string> | ||
| 68 | </property> | ||
| 69 | </item> | ||
| 70 | <item> | ||
| 71 | <property name="text"> | ||
| 72 | <string>Set volume:</string> | ||
| 73 | </property> | ||
| 74 | </item> | ||
| 75 | </widget> | ||
| 76 | </item> | ||
| 77 | <item> | ||
| 78 | <widget class="QLabel" name="volume_label"> | ||
| 65 | <property name="text"> | 79 | <property name="text"> |
| 66 | <string>Volume:</string> | 80 | <string>Volume:</string> |
| 67 | </property> | 81 | </property> |
| @@ -74,7 +88,7 @@ | |||
| 74 | </property> | 88 | </property> |
| 75 | <property name="sizeHint" stdset="0"> | 89 | <property name="sizeHint" stdset="0"> |
| 76 | <size> | 90 | <size> |
| 77 | <width>40</width> | 91 | <width>30</width> |
| 78 | <height>20</height> | 92 | <height>20</height> |
| 79 | </size> | 93 | </size> |
| 80 | </property> | 94 | </property> |
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index df4473b46..5918e9972 100644 --- a/src/yuzu/configuration/configure_dialog.cpp +++ b/src/yuzu/configuration/configure_dialog.cpp | |||
| @@ -14,6 +14,8 @@ | |||
| 14 | 14 | ||
| 15 | ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry) | 15 | ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry) |
| 16 | : QDialog(parent), ui(new Ui::ConfigureDialog), registry(registry) { | 16 | : QDialog(parent), ui(new Ui::ConfigureDialog), registry(registry) { |
| 17 | Settings::configuring_global = true; | ||
| 18 | |||
| 17 | ui->setupUi(this); | 19 | ui->setupUi(this); |
| 18 | ui->hotkeysTab->Populate(registry); | 20 | ui->hotkeysTab->Populate(registry); |
| 19 | setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); | 21 | setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); |
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index 74b2ad537..1fb62d1cf 100644 --- a/src/yuzu/configuration/configure_general.cpp +++ b/src/yuzu/configuration/configure_general.cpp | |||
| @@ -7,17 +7,21 @@ | |||
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/settings.h" | 8 | #include "core/settings.h" |
| 9 | #include "ui_configure_general.h" | 9 | #include "ui_configure_general.h" |
| 10 | #include "yuzu/configuration/configuration_shared.h" | ||
| 10 | #include "yuzu/configuration/configure_general.h" | 11 | #include "yuzu/configuration/configure_general.h" |
| 11 | #include "yuzu/uisettings.h" | 12 | #include "yuzu/uisettings.h" |
| 12 | 13 | ||
| 13 | ConfigureGeneral::ConfigureGeneral(QWidget* parent) | 14 | ConfigureGeneral::ConfigureGeneral(QWidget* parent) |
| 14 | : QWidget(parent), ui(new Ui::ConfigureGeneral) { | 15 | : QWidget(parent), ui(new Ui::ConfigureGeneral) { |
| 15 | |||
| 16 | ui->setupUi(this); | 16 | ui->setupUi(this); |
| 17 | 17 | ||
| 18 | SetupPerGameUI(); | ||
| 19 | |||
| 18 | SetConfiguration(); | 20 | SetConfiguration(); |
| 19 | 21 | ||
| 20 | connect(ui->toggle_frame_limit, &QCheckBox::toggled, ui->frame_limit, &QSpinBox::setEnabled); | 22 | connect(ui->toggle_frame_limit, &QCheckBox::stateChanged, ui->frame_limit, [this]() { |
| 23 | ui->frame_limit->setEnabled(ui->toggle_frame_limit->checkState() == Qt::Checked); | ||
| 24 | }); | ||
| 21 | } | 25 | } |
| 22 | 26 | ||
| 23 | ConfigureGeneral::~ConfigureGeneral() = default; | 27 | ConfigureGeneral::~ConfigureGeneral() = default; |
| @@ -26,27 +30,56 @@ void ConfigureGeneral::SetConfiguration() { | |||
| 26 | const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); | 30 | const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); |
| 27 | 31 | ||
| 28 | ui->use_multi_core->setEnabled(runtime_lock); | 32 | ui->use_multi_core->setEnabled(runtime_lock); |
| 29 | ui->use_multi_core->setChecked(Settings::values.use_multi_core); | 33 | ui->use_multi_core->setChecked(Settings::values.use_multi_core.GetValue()); |
| 30 | 34 | ||
| 31 | ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing); | 35 | ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing); |
| 32 | ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot); | 36 | ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot); |
| 33 | ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background); | 37 | ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background); |
| 34 | ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse); | 38 | ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse); |
| 35 | 39 | ||
| 36 | ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit); | 40 | ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit.GetValue()); |
| 37 | ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked()); | 41 | ui->frame_limit->setValue(Settings::values.frame_limit.GetValue()); |
| 38 | ui->frame_limit->setValue(Settings::values.frame_limit); | 42 | |
| 43 | if (!Settings::configuring_global) { | ||
| 44 | if (Settings::values.use_multi_core.UsingGlobal()) { | ||
| 45 | ui->use_multi_core->setCheckState(Qt::PartiallyChecked); | ||
| 46 | } | ||
| 47 | if (Settings::values.use_frame_limit.UsingGlobal()) { | ||
| 48 | ui->toggle_frame_limit->setCheckState(Qt::PartiallyChecked); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
| 52 | ui->frame_limit->setEnabled(ui->toggle_frame_limit->checkState() == Qt::Checked && | ||
| 53 | ui->toggle_frame_limit->isEnabled()); | ||
| 39 | } | 54 | } |
| 40 | 55 | ||
| 41 | void ConfigureGeneral::ApplyConfiguration() { | 56 | void ConfigureGeneral::ApplyConfiguration() { |
| 42 | UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked(); | 57 | if (Settings::configuring_global) { |
| 43 | UISettings::values.select_user_on_boot = ui->toggle_user_on_boot->isChecked(); | 58 | UISettings::values.confirm_before_closing = ui->toggle_check_exit->isChecked(); |
| 44 | UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked(); | 59 | UISettings::values.select_user_on_boot = ui->toggle_user_on_boot->isChecked(); |
| 45 | UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked(); | 60 | UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked(); |
| 46 | 61 | UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked(); | |
| 47 | Settings::values.use_frame_limit = ui->toggle_frame_limit->isChecked(); | 62 | |
| 48 | Settings::values.frame_limit = ui->frame_limit->value(); | 63 | // Guard if during game and set to game-specific value |
| 49 | Settings::values.use_multi_core = ui->use_multi_core->isChecked(); | 64 | if (Settings::values.use_frame_limit.UsingGlobal()) { |
| 65 | Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() == | ||
| 66 | Qt::Checked); | ||
| 67 | Settings::values.frame_limit.SetValue(ui->frame_limit->value()); | ||
| 68 | Settings::values.use_multi_core.SetValue(ui->use_multi_core->isChecked()); | ||
| 69 | } | ||
| 70 | } else { | ||
| 71 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core, | ||
| 72 | ui->use_multi_core); | ||
| 73 | |||
| 74 | bool global_frame_limit = ui->toggle_frame_limit->checkState() == Qt::PartiallyChecked; | ||
| 75 | Settings::values.use_frame_limit.SetGlobal(global_frame_limit); | ||
| 76 | Settings::values.frame_limit.SetGlobal(global_frame_limit); | ||
| 77 | if (!global_frame_limit) { | ||
| 78 | Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() == | ||
| 79 | Qt::Checked); | ||
| 80 | Settings::values.frame_limit.SetValue(ui->frame_limit->value()); | ||
| 81 | } | ||
| 82 | } | ||
| 50 | } | 83 | } |
| 51 | 84 | ||
| 52 | void ConfigureGeneral::changeEvent(QEvent* event) { | 85 | void ConfigureGeneral::changeEvent(QEvent* event) { |
| @@ -60,3 +93,20 @@ void ConfigureGeneral::changeEvent(QEvent* event) { | |||
| 60 | void ConfigureGeneral::RetranslateUI() { | 93 | void ConfigureGeneral::RetranslateUI() { |
| 61 | ui->retranslateUi(this); | 94 | ui->retranslateUi(this); |
| 62 | } | 95 | } |
| 96 | |||
| 97 | void ConfigureGeneral::SetupPerGameUI() { | ||
| 98 | if (Settings::configuring_global) { | ||
| 99 | ui->toggle_frame_limit->setEnabled(Settings::values.use_frame_limit.UsingGlobal()); | ||
| 100 | ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal()); | ||
| 101 | |||
| 102 | return; | ||
| 103 | } | ||
| 104 | |||
| 105 | ui->toggle_check_exit->setVisible(false); | ||
| 106 | ui->toggle_user_on_boot->setVisible(false); | ||
| 107 | ui->toggle_background_pause->setVisible(false); | ||
| 108 | ui->toggle_hide_mouse->setVisible(false); | ||
| 109 | |||
| 110 | ui->toggle_frame_limit->setTristate(true); | ||
| 111 | ui->use_multi_core->setTristate(true); | ||
| 112 | } | ||
diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h index ef05ce065..9c785c22e 100644 --- a/src/yuzu/configuration/configure_general.h +++ b/src/yuzu/configuration/configure_general.h | |||
| @@ -28,5 +28,7 @@ private: | |||
| 28 | 28 | ||
| 29 | void SetConfiguration(); | 29 | void SetConfiguration(); |
| 30 | 30 | ||
| 31 | void SetupPerGameUI(); | ||
| 32 | |||
| 31 | std::unique_ptr<Ui::ConfigureGeneral> ui; | 33 | std::unique_ptr<Ui::ConfigureGeneral> ui; |
| 32 | }; | 34 | }; |
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp index 304625cd7..cb4706bd6 100644 --- a/src/yuzu/configuration/configure_graphics.cpp +++ b/src/yuzu/configuration/configure_graphics.cpp | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "core/core.h" | 13 | #include "core/core.h" |
| 14 | #include "core/settings.h" | 14 | #include "core/settings.h" |
| 15 | #include "ui_configure_graphics.h" | 15 | #include "ui_configure_graphics.h" |
| 16 | #include "yuzu/configuration/configuration_shared.h" | ||
| 16 | #include "yuzu/configuration/configure_graphics.h" | 17 | #include "yuzu/configuration/configure_graphics.h" |
| 17 | 18 | ||
| 18 | #ifdef HAS_VULKAN | 19 | #ifdef HAS_VULKAN |
| @@ -21,16 +22,18 @@ | |||
| 21 | 22 | ||
| 22 | ConfigureGraphics::ConfigureGraphics(QWidget* parent) | 23 | ConfigureGraphics::ConfigureGraphics(QWidget* parent) |
| 23 | : QWidget(parent), ui(new Ui::ConfigureGraphics) { | 24 | : QWidget(parent), ui(new Ui::ConfigureGraphics) { |
| 24 | vulkan_device = Settings::values.vulkan_device; | 25 | vulkan_device = Settings::values.vulkan_device.GetValue(); |
| 25 | RetrieveVulkanDevices(); | 26 | RetrieveVulkanDevices(); |
| 26 | 27 | ||
| 27 | ui->setupUi(this); | 28 | ui->setupUi(this); |
| 28 | 29 | ||
| 30 | SetupPerGameUI(); | ||
| 31 | |||
| 29 | SetConfiguration(); | 32 | SetConfiguration(); |
| 30 | 33 | ||
| 31 | connect(ui->api, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, | 34 | connect(ui->api, qOverload<int>(&QComboBox::currentIndexChanged), this, |
| 32 | [this] { UpdateDeviceComboBox(); }); | 35 | [this] { UpdateDeviceComboBox(); }); |
| 33 | connect(ui->device, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, | 36 | connect(ui->device, qOverload<int>(&QComboBox::activated), this, |
| 34 | [this](int device) { UpdateDeviceSelection(device); }); | 37 | [this](int device) { UpdateDeviceSelection(device); }); |
| 35 | 38 | ||
| 36 | connect(ui->bg_button, &QPushButton::clicked, this, [this] { | 39 | connect(ui->bg_button, &QPushButton::clicked, this, [this] { |
| @@ -40,6 +43,9 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent) | |||
| 40 | } | 43 | } |
| 41 | UpdateBackgroundColorButton(new_bg_color); | 44 | UpdateBackgroundColorButton(new_bg_color); |
| 42 | }); | 45 | }); |
| 46 | |||
| 47 | ui->bg_label->setVisible(Settings::configuring_global); | ||
| 48 | ui->bg_combobox->setVisible(!Settings::configuring_global); | ||
| 43 | } | 49 | } |
| 44 | 50 | ||
| 45 | void ConfigureGraphics::UpdateDeviceSelection(int device) { | 51 | void ConfigureGraphics::UpdateDeviceSelection(int device) { |
| @@ -57,27 +63,95 @@ void ConfigureGraphics::SetConfiguration() { | |||
| 57 | const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); | 63 | const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); |
| 58 | 64 | ||
| 59 | ui->api->setEnabled(runtime_lock); | 65 | ui->api->setEnabled(runtime_lock); |
| 60 | ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend)); | ||
| 61 | ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio); | ||
| 62 | ui->use_disk_shader_cache->setEnabled(runtime_lock); | ||
| 63 | ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache); | ||
| 64 | ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock); | 66 | ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock); |
| 65 | ui->use_asynchronous_gpu_emulation->setChecked(Settings::values.use_asynchronous_gpu_emulation); | 67 | ui->use_disk_shader_cache->setEnabled(runtime_lock); |
| 66 | UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green, | 68 | |
| 67 | Settings::values.bg_blue)); | 69 | if (Settings::configuring_global) { |
| 70 | ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue())); | ||
| 71 | ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue()); | ||
| 72 | ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache.GetValue()); | ||
| 73 | ui->use_asynchronous_gpu_emulation->setChecked( | ||
| 74 | Settings::values.use_asynchronous_gpu_emulation.GetValue()); | ||
| 75 | } else { | ||
| 76 | ConfigurationShared::SetPerGameSetting(ui->use_disk_shader_cache, | ||
| 77 | &Settings::values.use_disk_shader_cache); | ||
| 78 | ConfigurationShared::SetPerGameSetting(ui->use_asynchronous_gpu_emulation, | ||
| 79 | &Settings::values.use_asynchronous_gpu_emulation); | ||
| 80 | |||
| 81 | ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend); | ||
| 82 | ConfigurationShared::SetPerGameSetting(ui->aspect_ratio_combobox, | ||
| 83 | &Settings::values.aspect_ratio); | ||
| 84 | |||
| 85 | ui->bg_combobox->setCurrentIndex(Settings::values.bg_red.UsingGlobal() ? 0 : 1); | ||
| 86 | ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal()); | ||
| 87 | } | ||
| 88 | |||
| 89 | UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red.GetValue(), | ||
| 90 | Settings::values.bg_green.GetValue(), | ||
| 91 | Settings::values.bg_blue.GetValue())); | ||
| 68 | UpdateDeviceComboBox(); | 92 | UpdateDeviceComboBox(); |
| 69 | } | 93 | } |
| 70 | 94 | ||
| 71 | void ConfigureGraphics::ApplyConfiguration() { | 95 | void ConfigureGraphics::ApplyConfiguration() { |
| 72 | Settings::values.renderer_backend = GetCurrentGraphicsBackend(); | 96 | if (Settings::configuring_global) { |
| 73 | Settings::values.vulkan_device = vulkan_device; | 97 | // Guard if during game and set to game-specific value |
| 74 | Settings::values.aspect_ratio = ui->aspect_ratio_combobox->currentIndex(); | 98 | if (Settings::values.renderer_backend.UsingGlobal()) { |
| 75 | Settings::values.use_disk_shader_cache = ui->use_disk_shader_cache->isChecked(); | 99 | Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend()); |
| 76 | Settings::values.use_asynchronous_gpu_emulation = | 100 | } |
| 77 | ui->use_asynchronous_gpu_emulation->isChecked(); | 101 | if (Settings::values.vulkan_device.UsingGlobal()) { |
| 78 | Settings::values.bg_red = static_cast<float>(bg_color.redF()); | 102 | Settings::values.vulkan_device.SetValue(vulkan_device); |
| 79 | Settings::values.bg_green = static_cast<float>(bg_color.greenF()); | 103 | } |
| 80 | Settings::values.bg_blue = static_cast<float>(bg_color.blueF()); | 104 | if (Settings::values.aspect_ratio.UsingGlobal()) { |
| 105 | Settings::values.aspect_ratio.SetValue(ui->aspect_ratio_combobox->currentIndex()); | ||
| 106 | } | ||
| 107 | if (Settings::values.use_disk_shader_cache.UsingGlobal()) { | ||
| 108 | Settings::values.use_disk_shader_cache.SetValue(ui->use_disk_shader_cache->isChecked()); | ||
| 109 | } | ||
| 110 | if (Settings::values.use_asynchronous_gpu_emulation.UsingGlobal()) { | ||
| 111 | Settings::values.use_asynchronous_gpu_emulation.SetValue( | ||
| 112 | ui->use_asynchronous_gpu_emulation->isChecked()); | ||
| 113 | } | ||
| 114 | if (Settings::values.bg_red.UsingGlobal()) { | ||
| 115 | Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF())); | ||
| 116 | Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF())); | ||
| 117 | Settings::values.bg_blue.SetValue(static_cast<float>(bg_color.blueF())); | ||
| 118 | } | ||
| 119 | } else { | ||
| 120 | if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { | ||
| 121 | Settings::values.renderer_backend.SetGlobal(true); | ||
| 122 | Settings::values.vulkan_device.SetGlobal(true); | ||
| 123 | } else { | ||
| 124 | Settings::values.renderer_backend.SetGlobal(false); | ||
| 125 | Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend()); | ||
| 126 | if (GetCurrentGraphicsBackend() == Settings::RendererBackend::Vulkan) { | ||
| 127 | Settings::values.vulkan_device.SetGlobal(false); | ||
| 128 | Settings::values.vulkan_device.SetValue(vulkan_device); | ||
| 129 | } else { | ||
| 130 | Settings::values.vulkan_device.SetGlobal(true); | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.aspect_ratio, | ||
| 135 | ui->aspect_ratio_combobox); | ||
| 136 | |||
| 137 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_disk_shader_cache, | ||
| 138 | ui->use_disk_shader_cache); | ||
| 139 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_gpu_emulation, | ||
| 140 | ui->use_asynchronous_gpu_emulation); | ||
| 141 | |||
| 142 | if (ui->bg_combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { | ||
| 143 | Settings::values.bg_red.SetGlobal(true); | ||
| 144 | Settings::values.bg_green.SetGlobal(true); | ||
| 145 | Settings::values.bg_blue.SetGlobal(true); | ||
| 146 | } else { | ||
| 147 | Settings::values.bg_red.SetGlobal(false); | ||
| 148 | Settings::values.bg_green.SetGlobal(false); | ||
| 149 | Settings::values.bg_blue.SetGlobal(false); | ||
| 150 | Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF())); | ||
| 151 | Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF())); | ||
| 152 | Settings::values.bg_blue.SetValue(static_cast<float>(bg_color.blueF())); | ||
| 153 | } | ||
| 154 | } | ||
| 81 | } | 155 | } |
| 82 | 156 | ||
| 83 | void ConfigureGraphics::changeEvent(QEvent* event) { | 157 | void ConfigureGraphics::changeEvent(QEvent* event) { |
| @@ -106,19 +180,27 @@ void ConfigureGraphics::UpdateDeviceComboBox() { | |||
| 106 | ui->device->clear(); | 180 | ui->device->clear(); |
| 107 | 181 | ||
| 108 | bool enabled = false; | 182 | bool enabled = false; |
| 183 | |||
| 184 | if (!Settings::configuring_global && | ||
| 185 | ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { | ||
| 186 | vulkan_device = Settings::values.vulkan_device.GetValue(); | ||
| 187 | } | ||
| 109 | switch (GetCurrentGraphicsBackend()) { | 188 | switch (GetCurrentGraphicsBackend()) { |
| 110 | case Settings::RendererBackend::OpenGL: | 189 | case Settings::RendererBackend::OpenGL: |
| 111 | ui->device->addItem(tr("OpenGL Graphics Device")); | 190 | ui->device->addItem(tr("OpenGL Graphics Device")); |
| 112 | enabled = false; | 191 | enabled = false; |
| 113 | break; | 192 | break; |
| 114 | case Settings::RendererBackend::Vulkan: | 193 | case Settings::RendererBackend::Vulkan: |
| 115 | for (const auto device : vulkan_devices) { | 194 | for (const auto& device : vulkan_devices) { |
| 116 | ui->device->addItem(device); | 195 | ui->device->addItem(device); |
| 117 | } | 196 | } |
| 118 | ui->device->setCurrentIndex(vulkan_device); | 197 | ui->device->setCurrentIndex(vulkan_device); |
| 119 | enabled = !vulkan_devices.empty(); | 198 | enabled = !vulkan_devices.empty(); |
| 120 | break; | 199 | break; |
| 121 | } | 200 | } |
| 201 | // If in per-game config and use global is selected, don't enable. | ||
| 202 | enabled &= !(!Settings::configuring_global && | ||
| 203 | ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX); | ||
| 122 | ui->device->setEnabled(enabled && !Core::System::GetInstance().IsPoweredOn()); | 204 | ui->device->setEnabled(enabled && !Core::System::GetInstance().IsPoweredOn()); |
| 123 | } | 205 | } |
| 124 | 206 | ||
| @@ -132,5 +214,37 @@ void ConfigureGraphics::RetrieveVulkanDevices() { | |||
| 132 | } | 214 | } |
| 133 | 215 | ||
| 134 | Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const { | 216 | Settings::RendererBackend ConfigureGraphics::GetCurrentGraphicsBackend() const { |
| 135 | return static_cast<Settings::RendererBackend>(ui->api->currentIndex()); | 217 | if (Settings::configuring_global) { |
| 218 | return static_cast<Settings::RendererBackend>(ui->api->currentIndex()); | ||
| 219 | } | ||
| 220 | |||
| 221 | if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { | ||
| 222 | Settings::values.renderer_backend.SetGlobal(true); | ||
| 223 | return Settings::values.renderer_backend.GetValue(); | ||
| 224 | } | ||
| 225 | Settings::values.renderer_backend.SetGlobal(false); | ||
| 226 | return static_cast<Settings::RendererBackend>(ui->api->currentIndex() - | ||
| 227 | ConfigurationShared::USE_GLOBAL_OFFSET); | ||
| 228 | } | ||
| 229 | |||
| 230 | void ConfigureGraphics::SetupPerGameUI() { | ||
| 231 | if (Settings::configuring_global) { | ||
| 232 | ui->api->setEnabled(Settings::values.renderer_backend.UsingGlobal()); | ||
| 233 | ui->device->setEnabled(Settings::values.renderer_backend.UsingGlobal()); | ||
| 234 | ui->aspect_ratio_combobox->setEnabled(Settings::values.aspect_ratio.UsingGlobal()); | ||
| 235 | ui->use_asynchronous_gpu_emulation->setEnabled( | ||
| 236 | Settings::values.use_asynchronous_gpu_emulation.UsingGlobal()); | ||
| 237 | ui->use_disk_shader_cache->setEnabled(Settings::values.use_disk_shader_cache.UsingGlobal()); | ||
| 238 | ui->bg_button->setEnabled(Settings::values.bg_red.UsingGlobal()); | ||
| 239 | |||
| 240 | return; | ||
| 241 | } | ||
| 242 | |||
| 243 | connect(ui->bg_combobox, static_cast<void (QComboBox::*)(int)>(&QComboBox::activated), this, | ||
| 244 | [this](int index) { ui->bg_button->setEnabled(index == 1); }); | ||
| 245 | |||
| 246 | ui->use_disk_shader_cache->setTristate(true); | ||
| 247 | ui->use_asynchronous_gpu_emulation->setTristate(true); | ||
| 248 | ConfigurationShared::InsertGlobalItem(ui->aspect_ratio_combobox); | ||
| 249 | ConfigurationShared::InsertGlobalItem(ui->api); | ||
| 136 | } | 250 | } |
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h index 7e0596d9c..24f01c739 100644 --- a/src/yuzu/configuration/configure_graphics.h +++ b/src/yuzu/configuration/configure_graphics.h | |||
| @@ -35,6 +35,8 @@ private: | |||
| 35 | 35 | ||
| 36 | void RetrieveVulkanDevices(); | 36 | void RetrieveVulkanDevices(); |
| 37 | 37 | ||
| 38 | void SetupPerGameUI(); | ||
| 39 | |||
| 38 | Settings::RendererBackend GetCurrentGraphicsBackend() const; | 40 | Settings::RendererBackend GetCurrentGraphicsBackend() const; |
| 39 | 41 | ||
| 40 | std::unique_ptr<Ui::ConfigureGraphics> ui; | 42 | std::unique_ptr<Ui::ConfigureGraphics> ui; |
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui index 6e75447a5..62418fc14 100644 --- a/src/yuzu/configuration/configure_graphics.ui +++ b/src/yuzu/configuration/configure_graphics.ui | |||
| @@ -122,6 +122,29 @@ | |||
| 122 | <item> | 122 | <item> |
| 123 | <layout class="QHBoxLayout" name="horizontalLayout_3"> | 123 | <layout class="QHBoxLayout" name="horizontalLayout_3"> |
| 124 | <item> | 124 | <item> |
| 125 | <widget class="QComboBox" name="bg_combobox"> | ||
| 126 | <property name="currentText"> | ||
| 127 | <string>Use global background color</string> | ||
| 128 | </property> | ||
| 129 | <property name="currentIndex"> | ||
| 130 | <number>0</number> | ||
| 131 | </property> | ||
| 132 | <property name="maxVisibleItems"> | ||
| 133 | <number>10</number> | ||
| 134 | </property> | ||
| 135 | <item> | ||
| 136 | <property name="text"> | ||
| 137 | <string>Use global background color</string> | ||
| 138 | </property> | ||
| 139 | </item> | ||
| 140 | <item> | ||
| 141 | <property name="text"> | ||
| 142 | <string>Set background color:</string> | ||
| 143 | </property> | ||
| 144 | </item> | ||
| 145 | </widget> | ||
| 146 | </item> | ||
| 147 | <item> | ||
| 125 | <widget class="QLabel" name="bg_label"> | 148 | <widget class="QLabel" name="bg_label"> |
| 126 | <property name="text"> | 149 | <property name="text"> |
| 127 | <string>Background Color:</string> | 150 | <string>Background Color:</string> |
| @@ -129,6 +152,19 @@ | |||
| 129 | </widget> | 152 | </widget> |
| 130 | </item> | 153 | </item> |
| 131 | <item> | 154 | <item> |
| 155 | <spacer name="horizontalSpacer"> | ||
| 156 | <property name="orientation"> | ||
| 157 | <enum>Qt::Horizontal</enum> | ||
| 158 | </property> | ||
| 159 | <property name="sizeHint" stdset="0"> | ||
| 160 | <size> | ||
| 161 | <width>40</width> | ||
| 162 | <height>20</height> | ||
| 163 | </size> | ||
| 164 | </property> | ||
| 165 | </spacer> | ||
| 166 | </item> | ||
| 167 | <item> | ||
| 132 | <widget class="QPushButton" name="bg_button"> | 168 | <widget class="QPushButton" name="bg_button"> |
| 133 | <property name="maximumSize"> | 169 | <property name="maximumSize"> |
| 134 | <size> | 170 | <size> |
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index be5006ad3..7c0fa7ec5 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "core/core.h" | 5 | #include "core/core.h" |
| 6 | #include "core/settings.h" | 6 | #include "core/settings.h" |
| 7 | #include "ui_configure_graphics_advanced.h" | 7 | #include "ui_configure_graphics_advanced.h" |
| 8 | #include "yuzu/configuration/configuration_shared.h" | ||
| 8 | #include "yuzu/configuration/configure_graphics_advanced.h" | 9 | #include "yuzu/configuration/configure_graphics_advanced.h" |
| 9 | 10 | ||
| 10 | ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(QWidget* parent) | 11 | ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(QWidget* parent) |
| @@ -12,6 +13,8 @@ ConfigureGraphicsAdvanced::ConfigureGraphicsAdvanced(QWidget* parent) | |||
| 12 | 13 | ||
| 13 | ui->setupUi(this); | 14 | ui->setupUi(this); |
| 14 | 15 | ||
| 16 | SetupPerGameUI(); | ||
| 17 | |||
| 15 | SetConfiguration(); | 18 | SetConfiguration(); |
| 16 | } | 19 | } |
| 17 | 20 | ||
| @@ -19,26 +22,81 @@ ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default; | |||
| 19 | 22 | ||
| 20 | void ConfigureGraphicsAdvanced::SetConfiguration() { | 23 | void ConfigureGraphicsAdvanced::SetConfiguration() { |
| 21 | const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); | 24 | const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); |
| 22 | ui->gpu_accuracy->setCurrentIndex(static_cast<int>(Settings::values.gpu_accuracy)); | ||
| 23 | ui->use_vsync->setEnabled(runtime_lock); | 25 | ui->use_vsync->setEnabled(runtime_lock); |
| 24 | ui->use_vsync->setChecked(Settings::values.use_vsync); | ||
| 25 | ui->use_assembly_shaders->setEnabled(runtime_lock); | 26 | ui->use_assembly_shaders->setEnabled(runtime_lock); |
| 26 | ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders); | ||
| 27 | ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time); | ||
| 28 | ui->force_30fps_mode->setEnabled(runtime_lock); | 27 | ui->force_30fps_mode->setEnabled(runtime_lock); |
| 29 | ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode); | ||
| 30 | ui->anisotropic_filtering_combobox->setEnabled(runtime_lock); | 28 | ui->anisotropic_filtering_combobox->setEnabled(runtime_lock); |
| 31 | ui->anisotropic_filtering_combobox->setCurrentIndex(Settings::values.max_anisotropy); | 29 | |
| 30 | if (Settings::configuring_global) { | ||
| 31 | ui->gpu_accuracy->setCurrentIndex( | ||
| 32 | static_cast<int>(Settings::values.gpu_accuracy.GetValue())); | ||
| 33 | ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue()); | ||
| 34 | ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue()); | ||
| 35 | ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue()); | ||
| 36 | ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode.GetValue()); | ||
| 37 | ui->anisotropic_filtering_combobox->setCurrentIndex( | ||
| 38 | Settings::values.max_anisotropy.GetValue()); | ||
| 39 | } else { | ||
| 40 | ConfigurationShared::SetPerGameSetting(ui->gpu_accuracy, &Settings::values.gpu_accuracy); | ||
| 41 | ConfigurationShared::SetPerGameSetting(ui->use_vsync, &Settings::values.use_vsync); | ||
| 42 | ConfigurationShared::SetPerGameSetting(ui->use_assembly_shaders, | ||
| 43 | &Settings::values.use_assembly_shaders); | ||
| 44 | ConfigurationShared::SetPerGameSetting(ui->use_fast_gpu_time, | ||
| 45 | &Settings::values.use_fast_gpu_time); | ||
| 46 | ConfigurationShared::SetPerGameSetting(ui->force_30fps_mode, | ||
| 47 | &Settings::values.force_30fps_mode); | ||
| 48 | ConfigurationShared::SetPerGameSetting(ui->anisotropic_filtering_combobox, | ||
| 49 | &Settings::values.max_anisotropy); | ||
| 50 | } | ||
| 32 | } | 51 | } |
| 33 | 52 | ||
| 34 | void ConfigureGraphicsAdvanced::ApplyConfiguration() { | 53 | void ConfigureGraphicsAdvanced::ApplyConfiguration() { |
| 35 | auto gpu_accuracy = static_cast<Settings::GPUAccuracy>(ui->gpu_accuracy->currentIndex()); | 54 | // Subtract 2 if configuring per-game (separator and "use global configuration" take 2 slots) |
| 36 | Settings::values.gpu_accuracy = gpu_accuracy; | 55 | const auto gpu_accuracy = static_cast<Settings::GPUAccuracy>( |
| 37 | Settings::values.use_vsync = ui->use_vsync->isChecked(); | 56 | ui->gpu_accuracy->currentIndex() - |
| 38 | Settings::values.use_assembly_shaders = ui->use_assembly_shaders->isChecked(); | 57 | ((Settings::configuring_global) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET)); |
| 39 | Settings::values.use_fast_gpu_time = ui->use_fast_gpu_time->isChecked(); | 58 | |
| 40 | Settings::values.force_30fps_mode = ui->force_30fps_mode->isChecked(); | 59 | if (Settings::configuring_global) { |
| 41 | Settings::values.max_anisotropy = ui->anisotropic_filtering_combobox->currentIndex(); | 60 | // Must guard in case of a during-game configuration when set to be game-specific. |
| 61 | if (Settings::values.gpu_accuracy.UsingGlobal()) { | ||
| 62 | Settings::values.gpu_accuracy.SetValue(gpu_accuracy); | ||
| 63 | } | ||
| 64 | if (Settings::values.use_vsync.UsingGlobal()) { | ||
| 65 | Settings::values.use_vsync.SetValue(ui->use_vsync->isChecked()); | ||
| 66 | } | ||
| 67 | if (Settings::values.use_assembly_shaders.UsingGlobal()) { | ||
| 68 | Settings::values.use_assembly_shaders.SetValue(ui->use_assembly_shaders->isChecked()); | ||
| 69 | } | ||
| 70 | if (Settings::values.use_fast_gpu_time.UsingGlobal()) { | ||
| 71 | Settings::values.use_fast_gpu_time.SetValue(ui->use_fast_gpu_time->isChecked()); | ||
| 72 | } | ||
| 73 | if (Settings::values.force_30fps_mode.UsingGlobal()) { | ||
| 74 | Settings::values.force_30fps_mode.SetValue(ui->force_30fps_mode->isChecked()); | ||
| 75 | } | ||
| 76 | if (Settings::values.max_anisotropy.UsingGlobal()) { | ||
| 77 | Settings::values.max_anisotropy.SetValue( | ||
| 78 | ui->anisotropic_filtering_combobox->currentIndex()); | ||
| 79 | } | ||
| 80 | } else { | ||
| 81 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, | ||
| 82 | ui->anisotropic_filtering_combobox); | ||
| 83 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync); | ||
| 84 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders, | ||
| 85 | ui->use_assembly_shaders); | ||
| 86 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time, | ||
| 87 | ui->use_fast_gpu_time); | ||
| 88 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.force_30fps_mode, | ||
| 89 | ui->force_30fps_mode); | ||
| 90 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, | ||
| 91 | ui->anisotropic_filtering_combobox); | ||
| 92 | |||
| 93 | if (ui->gpu_accuracy->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { | ||
| 94 | Settings::values.gpu_accuracy.SetGlobal(true); | ||
| 95 | } else { | ||
| 96 | Settings::values.gpu_accuracy.SetGlobal(false); | ||
| 97 | Settings::values.gpu_accuracy.SetValue(gpu_accuracy); | ||
| 98 | } | ||
| 99 | } | ||
| 42 | } | 100 | } |
| 43 | 101 | ||
| 44 | void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { | 102 | void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { |
| @@ -52,3 +110,25 @@ void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { | |||
| 52 | void ConfigureGraphicsAdvanced::RetranslateUI() { | 110 | void ConfigureGraphicsAdvanced::RetranslateUI() { |
| 53 | ui->retranslateUi(this); | 111 | ui->retranslateUi(this); |
| 54 | } | 112 | } |
| 113 | |||
| 114 | void ConfigureGraphicsAdvanced::SetupPerGameUI() { | ||
| 115 | // Disable if not global (only happens during game) | ||
| 116 | if (Settings::configuring_global) { | ||
| 117 | ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal()); | ||
| 118 | ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal()); | ||
| 119 | ui->use_assembly_shaders->setEnabled(Settings::values.use_assembly_shaders.UsingGlobal()); | ||
| 120 | ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal()); | ||
| 121 | ui->force_30fps_mode->setEnabled(Settings::values.force_30fps_mode.UsingGlobal()); | ||
| 122 | ui->anisotropic_filtering_combobox->setEnabled( | ||
| 123 | Settings::values.max_anisotropy.UsingGlobal()); | ||
| 124 | |||
| 125 | return; | ||
| 126 | } | ||
| 127 | |||
| 128 | ConfigurationShared::InsertGlobalItem(ui->gpu_accuracy); | ||
| 129 | ui->use_vsync->setTristate(true); | ||
| 130 | ui->use_assembly_shaders->setTristate(true); | ||
| 131 | ui->use_fast_gpu_time->setTristate(true); | ||
| 132 | ui->force_30fps_mode->setTristate(true); | ||
| 133 | ConfigurationShared::InsertGlobalItem(ui->anisotropic_filtering_combobox); | ||
| 134 | } | ||
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h index bbc9d4355..c043588ff 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.h +++ b/src/yuzu/configuration/configure_graphics_advanced.h | |||
| @@ -26,5 +26,7 @@ private: | |||
| 26 | 26 | ||
| 27 | void SetConfiguration(); | 27 | void SetConfiguration(); |
| 28 | 28 | ||
| 29 | void SetupPerGameUI(); | ||
| 30 | |||
| 29 | std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui; | 31 | std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui; |
| 30 | }; | 32 | }; |
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp new file mode 100644 index 000000000..1e49f0787 --- /dev/null +++ b/src/yuzu/configuration/configure_per_game.cpp | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <memory> | ||
| 7 | #include <utility> | ||
| 8 | |||
| 9 | #include <QCheckBox> | ||
| 10 | #include <QHeaderView> | ||
| 11 | #include <QMenu> | ||
| 12 | #include <QStandardItemModel> | ||
| 13 | #include <QString> | ||
| 14 | #include <QTimer> | ||
| 15 | #include <QTreeView> | ||
| 16 | |||
| 17 | #include "common/common_paths.h" | ||
| 18 | #include "common/file_util.h" | ||
| 19 | #include "core/file_sys/control_metadata.h" | ||
| 20 | #include "core/file_sys/patch_manager.h" | ||
| 21 | #include "core/file_sys/xts_archive.h" | ||
| 22 | #include "core/loader/loader.h" | ||
| 23 | #include "ui_configure_per_game.h" | ||
| 24 | #include "yuzu/configuration/config.h" | ||
| 25 | #include "yuzu/configuration/configure_input.h" | ||
| 26 | #include "yuzu/configuration/configure_per_game.h" | ||
| 27 | #include "yuzu/uisettings.h" | ||
| 28 | #include "yuzu/util/util.h" | ||
| 29 | |||
| 30 | ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id) | ||
| 31 | : QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGame>()), title_id(title_id) { | ||
| 32 | game_config = std::make_unique<Config>(fmt::format("{:016X}.ini", title_id), false); | ||
| 33 | |||
| 34 | Settings::configuring_global = false; | ||
| 35 | |||
| 36 | ui->setupUi(this); | ||
| 37 | setFocusPolicy(Qt::ClickFocus); | ||
| 38 | setWindowTitle(tr("Properties")); | ||
| 39 | |||
| 40 | ui->addonsTab->SetTitleId(title_id); | ||
| 41 | |||
| 42 | scene = new QGraphicsScene; | ||
| 43 | ui->icon_view->setScene(scene); | ||
| 44 | |||
| 45 | LoadConfiguration(); | ||
| 46 | } | ||
| 47 | |||
| 48 | ConfigurePerGame::~ConfigurePerGame() = default; | ||
| 49 | |||
| 50 | void ConfigurePerGame::ApplyConfiguration() { | ||
| 51 | ui->addonsTab->ApplyConfiguration(); | ||
| 52 | ui->generalTab->ApplyConfiguration(); | ||
| 53 | ui->systemTab->ApplyConfiguration(); | ||
| 54 | ui->graphicsTab->ApplyConfiguration(); | ||
| 55 | ui->graphicsAdvancedTab->ApplyConfiguration(); | ||
| 56 | ui->audioTab->ApplyConfiguration(); | ||
| 57 | |||
| 58 | Settings::Apply(); | ||
| 59 | Settings::LogSettings(); | ||
| 60 | |||
| 61 | game_config->Save(); | ||
| 62 | } | ||
| 63 | |||
| 64 | void ConfigurePerGame::changeEvent(QEvent* event) { | ||
| 65 | if (event->type() == QEvent::LanguageChange) { | ||
| 66 | RetranslateUI(); | ||
| 67 | } | ||
| 68 | |||
| 69 | QDialog::changeEvent(event); | ||
| 70 | } | ||
| 71 | |||
| 72 | void ConfigurePerGame::RetranslateUI() { | ||
| 73 | ui->retranslateUi(this); | ||
| 74 | } | ||
| 75 | |||
| 76 | void ConfigurePerGame::LoadFromFile(FileSys::VirtualFile file) { | ||
| 77 | this->file = std::move(file); | ||
| 78 | LoadConfiguration(); | ||
| 79 | } | ||
| 80 | |||
| 81 | void ConfigurePerGame::LoadConfiguration() { | ||
| 82 | if (file == nullptr) { | ||
| 83 | return; | ||
| 84 | } | ||
| 85 | |||
| 86 | ui->addonsTab->LoadFromFile(file); | ||
| 87 | |||
| 88 | ui->display_title_id->setText( | ||
| 89 | QStringLiteral("%1").arg(title_id, 16, 16, QLatin1Char{'0'}).toUpper()); | ||
| 90 | |||
| 91 | FileSys::PatchManager pm{title_id}; | ||
| 92 | const auto control = pm.GetControlMetadata(); | ||
| 93 | const auto loader = Loader::GetLoader(file); | ||
| 94 | |||
| 95 | if (control.first != nullptr) { | ||
| 96 | ui->display_version->setText(QString::fromStdString(control.first->GetVersionString())); | ||
| 97 | ui->display_name->setText(QString::fromStdString(control.first->GetApplicationName())); | ||
| 98 | ui->display_developer->setText(QString::fromStdString(control.first->GetDeveloperName())); | ||
| 99 | } else { | ||
| 100 | std::string title; | ||
| 101 | if (loader->ReadTitle(title) == Loader::ResultStatus::Success) | ||
| 102 | ui->display_name->setText(QString::fromStdString(title)); | ||
| 103 | |||
| 104 | FileSys::NACP nacp; | ||
| 105 | if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success) | ||
| 106 | ui->display_developer->setText(QString::fromStdString(nacp.GetDeveloperName())); | ||
| 107 | |||
| 108 | ui->display_version->setText(QStringLiteral("1.0.0")); | ||
| 109 | } | ||
| 110 | |||
| 111 | if (control.second != nullptr) { | ||
| 112 | scene->clear(); | ||
| 113 | |||
| 114 | QPixmap map; | ||
| 115 | const auto bytes = control.second->ReadAllBytes(); | ||
| 116 | map.loadFromData(bytes.data(), static_cast<u32>(bytes.size())); | ||
| 117 | |||
| 118 | scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(), | ||
| 119 | Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); | ||
| 120 | } else { | ||
| 121 | std::vector<u8> bytes; | ||
| 122 | if (loader->ReadIcon(bytes) == Loader::ResultStatus::Success) { | ||
| 123 | scene->clear(); | ||
| 124 | |||
| 125 | QPixmap map; | ||
| 126 | map.loadFromData(bytes.data(), static_cast<u32>(bytes.size())); | ||
| 127 | |||
| 128 | scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(), | ||
| 129 | Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); | ||
| 130 | } | ||
| 131 | } | ||
| 132 | |||
| 133 | ui->display_filename->setText(QString::fromStdString(file->GetName())); | ||
| 134 | |||
| 135 | ui->display_format->setText( | ||
| 136 | QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))); | ||
| 137 | |||
| 138 | const auto valueText = ReadableByteSize(file->GetSize()); | ||
| 139 | ui->display_size->setText(valueText); | ||
| 140 | } | ||
diff --git a/src/yuzu/configuration/configure_per_game.h b/src/yuzu/configuration/configure_per_game.h new file mode 100644 index 000000000..5f9a08cef --- /dev/null +++ b/src/yuzu/configuration/configure_per_game.h | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <vector> | ||
| 9 | |||
| 10 | #include <QDialog> | ||
| 11 | #include <QList> | ||
| 12 | |||
| 13 | #include "core/file_sys/vfs_types.h" | ||
| 14 | #include "yuzu/configuration/config.h" | ||
| 15 | |||
| 16 | class QGraphicsScene; | ||
| 17 | class QStandardItem; | ||
| 18 | class QStandardItemModel; | ||
| 19 | class QTreeView; | ||
| 20 | class QVBoxLayout; | ||
| 21 | |||
| 22 | namespace Ui { | ||
| 23 | class ConfigurePerGame; | ||
| 24 | } | ||
| 25 | |||
| 26 | class ConfigurePerGame : public QDialog { | ||
| 27 | Q_OBJECT | ||
| 28 | |||
| 29 | public: | ||
| 30 | explicit ConfigurePerGame(QWidget* parent, u64 title_id); | ||
| 31 | ~ConfigurePerGame() override; | ||
| 32 | |||
| 33 | /// Save all button configurations to settings file | ||
| 34 | void ApplyConfiguration(); | ||
| 35 | |||
| 36 | void LoadFromFile(FileSys::VirtualFile file); | ||
| 37 | |||
| 38 | private: | ||
| 39 | void changeEvent(QEvent* event) override; | ||
| 40 | void RetranslateUI(); | ||
| 41 | |||
| 42 | void LoadConfiguration(); | ||
| 43 | |||
| 44 | std::unique_ptr<Ui::ConfigurePerGame> ui; | ||
| 45 | FileSys::VirtualFile file; | ||
| 46 | u64 title_id; | ||
| 47 | |||
| 48 | QGraphicsScene* scene; | ||
| 49 | |||
| 50 | std::unique_ptr<Config> game_config; | ||
| 51 | }; | ||
diff --git a/src/yuzu/configuration/configure_per_game.ui b/src/yuzu/configuration/configure_per_game.ui new file mode 100644 index 000000000..d2057c4ab --- /dev/null +++ b/src/yuzu/configuration/configure_per_game.ui | |||
| @@ -0,0 +1,350 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <ui version="4.0"> | ||
| 3 | <class>ConfigurePerGame</class> | ||
| 4 | <widget class="QDialog" name="ConfigurePerGame"> | ||
| 5 | <property name="geometry"> | ||
| 6 | <rect> | ||
| 7 | <x>0</x> | ||
| 8 | <y>0</y> | ||
| 9 | <width>800</width> | ||
| 10 | <height>600</height> | ||
| 11 | </rect> | ||
| 12 | </property> | ||
| 13 | <property name="windowTitle"> | ||
| 14 | <string>Dialog</string> | ||
| 15 | </property> | ||
| 16 | <layout class="QVBoxLayout" name="verticalLayout_3"> | ||
| 17 | <item> | ||
| 18 | <layout class="QHBoxLayout" name="horizontalLayout"> | ||
| 19 | <item> | ||
| 20 | <widget class="QGroupBox" name="groupBox"> | ||
| 21 | <property name="sizePolicy"> | ||
| 22 | <sizepolicy hsizetype="Maximum" vsizetype="Preferred"> | ||
| 23 | <horstretch>0</horstretch> | ||
| 24 | <verstretch>0</verstretch> | ||
| 25 | </sizepolicy> | ||
| 26 | </property> | ||
| 27 | <property name="title"> | ||
| 28 | <string>Info</string> | ||
| 29 | </property> | ||
| 30 | <layout class="QVBoxLayout" name="verticalLayout"> | ||
| 31 | <item alignment="Qt::AlignHCenter"> | ||
| 32 | <widget class="QGraphicsView" name="icon_view"> | ||
| 33 | <property name="sizePolicy"> | ||
| 34 | <sizepolicy hsizetype="Maximum" vsizetype="Maximum"> | ||
| 35 | <horstretch>0</horstretch> | ||
| 36 | <verstretch>0</verstretch> | ||
| 37 | </sizepolicy> | ||
| 38 | </property> | ||
| 39 | <property name="minimumSize"> | ||
| 40 | <size> | ||
| 41 | <width>256</width> | ||
| 42 | <height>256</height> | ||
| 43 | </size> | ||
| 44 | </property> | ||
| 45 | <property name="maximumSize"> | ||
| 46 | <size> | ||
| 47 | <width>256</width> | ||
| 48 | <height>256</height> | ||
| 49 | </size> | ||
| 50 | </property> | ||
| 51 | <property name="verticalScrollBarPolicy"> | ||
| 52 | <enum>Qt::ScrollBarAlwaysOff</enum> | ||
| 53 | </property> | ||
| 54 | <property name="horizontalScrollBarPolicy"> | ||
| 55 | <enum>Qt::ScrollBarAlwaysOff</enum> | ||
| 56 | </property> | ||
| 57 | <property name="interactive"> | ||
| 58 | <bool>false</bool> | ||
| 59 | </property> | ||
| 60 | </widget> | ||
| 61 | </item> | ||
| 62 | <item> | ||
| 63 | <layout class="QGridLayout" name="gridLayout_2"> | ||
| 64 | <item row="6" column="1"> | ||
| 65 | <widget class="QLineEdit" name="display_size"> | ||
| 66 | <property name="enabled"> | ||
| 67 | <bool>true</bool> | ||
| 68 | </property> | ||
| 69 | <property name="readOnly"> | ||
| 70 | <bool>true</bool> | ||
| 71 | </property> | ||
| 72 | </widget> | ||
| 73 | </item> | ||
| 74 | <item row="3" column="1"> | ||
| 75 | <widget class="QLineEdit" name="display_version"> | ||
| 76 | <property name="enabled"> | ||
| 77 | <bool>true</bool> | ||
| 78 | </property> | ||
| 79 | <property name="readOnly"> | ||
| 80 | <bool>true</bool> | ||
| 81 | </property> | ||
| 82 | </widget> | ||
| 83 | </item> | ||
| 84 | <item row="1" column="0"> | ||
| 85 | <widget class="QLabel" name="label"> | ||
| 86 | <property name="text"> | ||
| 87 | <string>Name</string> | ||
| 88 | </property> | ||
| 89 | </widget> | ||
| 90 | </item> | ||
| 91 | <item row="4" column="0"> | ||
| 92 | <widget class="QLabel" name="label_4"> | ||
| 93 | <property name="text"> | ||
| 94 | <string>Title ID</string> | ||
| 95 | </property> | ||
| 96 | </widget> | ||
| 97 | </item> | ||
| 98 | <item row="4" column="1"> | ||
| 99 | <widget class="QLineEdit" name="display_title_id"> | ||
| 100 | <property name="enabled"> | ||
| 101 | <bool>true</bool> | ||
| 102 | </property> | ||
| 103 | <property name="readOnly"> | ||
| 104 | <bool>true</bool> | ||
| 105 | </property> | ||
| 106 | </widget> | ||
| 107 | </item> | ||
| 108 | <item row="7" column="1"> | ||
| 109 | <widget class="QLineEdit" name="display_filename"> | ||
| 110 | <property name="enabled"> | ||
| 111 | <bool>true</bool> | ||
| 112 | </property> | ||
| 113 | <property name="readOnly"> | ||
| 114 | <bool>true</bool> | ||
| 115 | </property> | ||
| 116 | </widget> | ||
| 117 | </item> | ||
| 118 | <item row="5" column="1"> | ||
| 119 | <widget class="QLineEdit" name="display_format"> | ||
| 120 | <property name="enabled"> | ||
| 121 | <bool>true</bool> | ||
| 122 | </property> | ||
| 123 | <property name="readOnly"> | ||
| 124 | <bool>true</bool> | ||
| 125 | </property> | ||
| 126 | </widget> | ||
| 127 | </item> | ||
| 128 | <item row="7" column="0"> | ||
| 129 | <widget class="QLabel" name="label_7"> | ||
| 130 | <property name="text"> | ||
| 131 | <string>Filename</string> | ||
| 132 | </property> | ||
| 133 | </widget> | ||
| 134 | </item> | ||
| 135 | <item row="1" column="1"> | ||
| 136 | <widget class="QLineEdit" name="display_name"> | ||
| 137 | <property name="enabled"> | ||
| 138 | <bool>true</bool> | ||
| 139 | </property> | ||
| 140 | <property name="readOnly"> | ||
| 141 | <bool>true</bool> | ||
| 142 | </property> | ||
| 143 | </widget> | ||
| 144 | </item> | ||
| 145 | <item row="2" column="1"> | ||
| 146 | <widget class="QLineEdit" name="display_developer"> | ||
| 147 | <property name="enabled"> | ||
| 148 | <bool>true</bool> | ||
| 149 | </property> | ||
| 150 | <property name="readOnly"> | ||
| 151 | <bool>true</bool> | ||
| 152 | </property> | ||
| 153 | </widget> | ||
| 154 | </item> | ||
| 155 | <item row="5" column="0"> | ||
| 156 | <widget class="QLabel" name="label_5"> | ||
| 157 | <property name="text"> | ||
| 158 | <string>Format</string> | ||
| 159 | </property> | ||
| 160 | </widget> | ||
| 161 | </item> | ||
| 162 | <item row="3" column="0"> | ||
| 163 | <widget class="QLabel" name="label_3"> | ||
| 164 | <property name="text"> | ||
| 165 | <string>Version</string> | ||
| 166 | </property> | ||
| 167 | </widget> | ||
| 168 | </item> | ||
| 169 | <item row="6" column="0"> | ||
| 170 | <widget class="QLabel" name="label_6"> | ||
| 171 | <property name="text"> | ||
| 172 | <string>Size</string> | ||
| 173 | </property> | ||
| 174 | </widget> | ||
| 175 | </item> | ||
| 176 | <item row="2" column="0"> | ||
| 177 | <widget class="QLabel" name="label_2"> | ||
| 178 | <property name="text"> | ||
| 179 | <string>Developer</string> | ||
| 180 | </property> | ||
| 181 | </widget> | ||
| 182 | </item> | ||
| 183 | </layout> | ||
| 184 | </item> | ||
| 185 | <item> | ||
| 186 | <spacer name="verticalSpacer"> | ||
| 187 | <property name="orientation"> | ||
| 188 | <enum>Qt::Vertical</enum> | ||
| 189 | </property> | ||
| 190 | <property name="sizeHint" stdset="0"> | ||
| 191 | <size> | ||
| 192 | <width>20</width> | ||
| 193 | <height>40</height> | ||
| 194 | </size> | ||
| 195 | </property> | ||
| 196 | </spacer> | ||
| 197 | </item> | ||
| 198 | </layout> | ||
| 199 | </widget> | ||
| 200 | </item> | ||
| 201 | <item> | ||
| 202 | <layout class="QVBoxLayout" name="VerticalLayout"> | ||
| 203 | <item> | ||
| 204 | <layout class="QVBoxLayout" name="verticalLayout_2"/> | ||
| 205 | </item> | ||
| 206 | <item> | ||
| 207 | <widget class="QTabWidget" name="tabWidget"> | ||
| 208 | <property name="enabled"> | ||
| 209 | <bool>true</bool> | ||
| 210 | </property> | ||
| 211 | <property name="currentIndex"> | ||
| 212 | <number>0</number> | ||
| 213 | </property> | ||
| 214 | <property name="usesScrollButtons"> | ||
| 215 | <bool>true</bool> | ||
| 216 | </property> | ||
| 217 | <property name="documentMode"> | ||
| 218 | <bool>false</bool> | ||
| 219 | </property> | ||
| 220 | <property name="tabsClosable"> | ||
| 221 | <bool>false</bool> | ||
| 222 | </property> | ||
| 223 | <widget class="ConfigurePerGameAddons" name="addonsTab"> | ||
| 224 | <attribute name="title"> | ||
| 225 | <string>Add-Ons</string> | ||
| 226 | </attribute> | ||
| 227 | </widget> | ||
| 228 | <widget class="ConfigureGeneral" name="generalTab"> | ||
| 229 | <attribute name="title"> | ||
| 230 | <string>General</string> | ||
| 231 | </attribute> | ||
| 232 | </widget> | ||
| 233 | <widget class="ConfigureSystem" name="systemTab"> | ||
| 234 | <attribute name="title"> | ||
| 235 | <string>System</string> | ||
| 236 | </attribute> | ||
| 237 | </widget> | ||
| 238 | <widget class="ConfigureGraphics" name="graphicsTab"> | ||
| 239 | <attribute name="title"> | ||
| 240 | <string>Graphics</string> | ||
| 241 | </attribute> | ||
| 242 | </widget> | ||
| 243 | <widget class="ConfigureGraphicsAdvanced" name="graphicsAdvancedTab"> | ||
| 244 | <attribute name="title"> | ||
| 245 | <string>Adv. Graphics</string> | ||
| 246 | </attribute> | ||
| 247 | </widget> | ||
| 248 | <widget class="ConfigureAudio" name="audioTab"> | ||
| 249 | <attribute name="title"> | ||
| 250 | <string>Audio</string> | ||
| 251 | </attribute> | ||
| 252 | </widget> | ||
| 253 | </widget> | ||
| 254 | </item> | ||
| 255 | </layout> | ||
| 256 | </item> | ||
| 257 | </layout> | ||
| 258 | </item> | ||
| 259 | <item> | ||
| 260 | <widget class="QDialogButtonBox" name="buttonBox"> | ||
| 261 | <property name="sizePolicy"> | ||
| 262 | <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> | ||
| 263 | <horstretch>0</horstretch> | ||
| 264 | <verstretch>0</verstretch> | ||
| 265 | </sizepolicy> | ||
| 266 | </property> | ||
| 267 | <property name="orientation"> | ||
| 268 | <enum>Qt::Horizontal</enum> | ||
| 269 | </property> | ||
| 270 | <property name="standardButtons"> | ||
| 271 | <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> | ||
| 272 | </property> | ||
| 273 | </widget> | ||
| 274 | </item> | ||
| 275 | </layout> | ||
| 276 | </widget> | ||
| 277 | <customwidgets> | ||
| 278 | <customwidget> | ||
| 279 | <class>ConfigureGeneral</class> | ||
| 280 | <extends>QWidget</extends> | ||
| 281 | <header>configuration/configure_general.h</header> | ||
| 282 | <container>1</container> | ||
| 283 | </customwidget> | ||
| 284 | <customwidget> | ||
| 285 | <class>ConfigureSystem</class> | ||
| 286 | <extends>QWidget</extends> | ||
| 287 | <header>configuration/configure_system.h</header> | ||
| 288 | <container>1</container> | ||
| 289 | </customwidget> | ||
| 290 | <customwidget> | ||
| 291 | <class>ConfigureAudio</class> | ||
| 292 | <extends>QWidget</extends> | ||
| 293 | <header>configuration/configure_audio.h</header> | ||
| 294 | <container>1</container> | ||
| 295 | </customwidget> | ||
| 296 | <customwidget> | ||
| 297 | <class>ConfigureGraphics</class> | ||
| 298 | <extends>QWidget</extends> | ||
| 299 | <header>configuration/configure_graphics.h</header> | ||
| 300 | <container>1</container> | ||
| 301 | </customwidget> | ||
| 302 | <customwidget> | ||
| 303 | <class>ConfigureGraphicsAdvanced</class> | ||
| 304 | <extends>QWidget</extends> | ||
| 305 | <header>configuration/configure_graphics_advanced.h</header> | ||
| 306 | <container>1</container> | ||
| 307 | </customwidget> | ||
| 308 | <customwidget> | ||
| 309 | <class>ConfigurePerGameAddons</class> | ||
| 310 | <extends>QWidget</extends> | ||
| 311 | <header>configuration/configure_per_game_addons.h</header> | ||
| 312 | <container>1</container> | ||
| 313 | </customwidget> | ||
| 314 | </customwidgets> | ||
| 315 | <resources/> | ||
| 316 | <connections> | ||
| 317 | <connection> | ||
| 318 | <sender>buttonBox</sender> | ||
| 319 | <signal>accepted()</signal> | ||
| 320 | <receiver>ConfigurePerGame</receiver> | ||
| 321 | <slot>accept()</slot> | ||
| 322 | <hints> | ||
| 323 | <hint type="sourcelabel"> | ||
| 324 | <x>248</x> | ||
| 325 | <y>254</y> | ||
| 326 | </hint> | ||
| 327 | <hint type="destinationlabel"> | ||
| 328 | <x>157</x> | ||
| 329 | <y>274</y> | ||
| 330 | </hint> | ||
| 331 | </hints> | ||
| 332 | </connection> | ||
| 333 | <connection> | ||
| 334 | <sender>buttonBox</sender> | ||
| 335 | <signal>rejected()</signal> | ||
| 336 | <receiver>ConfigurePerGame</receiver> | ||
| 337 | <slot>reject()</slot> | ||
| 338 | <hints> | ||
| 339 | <hint type="sourcelabel"> | ||
| 340 | <x>316</x> | ||
| 341 | <y>260</y> | ||
| 342 | </hint> | ||
| 343 | <hint type="destinationlabel"> | ||
| 344 | <x>286</x> | ||
| 345 | <y>274</y> | ||
| 346 | </hint> | ||
| 347 | </hints> | ||
| 348 | </connection> | ||
| 349 | </connections> | ||
| 350 | </ui> | ||
diff --git a/src/yuzu/configuration/configure_per_general.cpp b/src/yuzu/configuration/configure_per_game_addons.cpp index d7f259f12..478d5d3a1 100644 --- a/src/yuzu/configuration/configure_per_general.cpp +++ b/src/yuzu/configuration/configure_per_game_addons.cpp | |||
| @@ -15,23 +15,20 @@ | |||
| 15 | 15 | ||
| 16 | #include "common/common_paths.h" | 16 | #include "common/common_paths.h" |
| 17 | #include "common/file_util.h" | 17 | #include "common/file_util.h" |
| 18 | #include "core/file_sys/control_metadata.h" | 18 | #include "core/core.h" |
| 19 | #include "core/file_sys/patch_manager.h" | 19 | #include "core/file_sys/patch_manager.h" |
| 20 | #include "core/file_sys/xts_archive.h" | 20 | #include "core/file_sys/xts_archive.h" |
| 21 | #include "core/loader/loader.h" | 21 | #include "core/loader/loader.h" |
| 22 | #include "ui_configure_per_general.h" | 22 | #include "ui_configure_per_game_addons.h" |
| 23 | #include "yuzu/configuration/config.h" | 23 | #include "yuzu/configuration/config.h" |
| 24 | #include "yuzu/configuration/configure_input.h" | 24 | #include "yuzu/configuration/configure_input.h" |
| 25 | #include "yuzu/configuration/configure_per_general.h" | 25 | #include "yuzu/configuration/configure_per_game_addons.h" |
| 26 | #include "yuzu/uisettings.h" | 26 | #include "yuzu/uisettings.h" |
| 27 | #include "yuzu/util/util.h" | 27 | #include "yuzu/util/util.h" |
| 28 | 28 | ||
| 29 | ConfigurePerGameGeneral::ConfigurePerGameGeneral(QWidget* parent, u64 title_id) | 29 | ConfigurePerGameAddons::ConfigurePerGameAddons(QWidget* parent) |
| 30 | : QDialog(parent), ui(std::make_unique<Ui::ConfigurePerGameGeneral>()), title_id(title_id) { | 30 | : QWidget(parent), ui(new Ui::ConfigurePerGameAddons) { |
| 31 | |||
| 32 | ui->setupUi(this); | 31 | ui->setupUi(this); |
| 33 | setFocusPolicy(Qt::ClickFocus); | ||
| 34 | setWindowTitle(tr("Properties")); | ||
| 35 | 32 | ||
| 36 | layout = new QVBoxLayout; | 33 | layout = new QVBoxLayout; |
| 37 | tree_view = new QTreeView; | 34 | tree_view = new QTreeView; |
| @@ -52,7 +49,7 @@ ConfigurePerGameGeneral::ConfigurePerGameGeneral(QWidget* parent, u64 title_id) | |||
| 52 | item_model->setHeaderData(1, Qt::Horizontal, tr("Version")); | 49 | item_model->setHeaderData(1, Qt::Horizontal, tr("Version")); |
| 53 | 50 | ||
| 54 | // We must register all custom types with the Qt Automoc system so that we are able to use it | 51 | // We must register all custom types with the Qt Automoc system so that we are able to use it |
| 55 | // with signals/slots. In this case, QList falls under the umbrells of custom types. | 52 | // with signals/slots. In this case, QList falls under the umbrella of custom types. |
| 56 | qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>"); | 53 | qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>"); |
| 57 | 54 | ||
| 58 | layout->setContentsMargins(0, 0, 0, 0); | 55 | layout->setContentsMargins(0, 0, 0, 0); |
| @@ -61,18 +58,15 @@ ConfigurePerGameGeneral::ConfigurePerGameGeneral(QWidget* parent, u64 title_id) | |||
| 61 | 58 | ||
| 62 | ui->scrollArea->setLayout(layout); | 59 | ui->scrollArea->setLayout(layout); |
| 63 | 60 | ||
| 64 | scene = new QGraphicsScene; | 61 | ui->scrollArea->setEnabled(!Core::System::GetInstance().IsPoweredOn()); |
| 65 | ui->icon_view->setScene(scene); | ||
| 66 | 62 | ||
| 67 | connect(item_model, &QStandardItemModel::itemChanged, | 63 | connect(item_model, &QStandardItemModel::itemChanged, |
| 68 | [] { UISettings::values.is_game_list_reload_pending.exchange(true); }); | 64 | [] { UISettings::values.is_game_list_reload_pending.exchange(true); }); |
| 69 | |||
| 70 | LoadConfiguration(); | ||
| 71 | } | 65 | } |
| 72 | 66 | ||
| 73 | ConfigurePerGameGeneral::~ConfigurePerGameGeneral() = default; | 67 | ConfigurePerGameAddons::~ConfigurePerGameAddons() = default; |
| 74 | 68 | ||
| 75 | void ConfigurePerGameGeneral::ApplyConfiguration() { | 69 | void ConfigurePerGameAddons::ApplyConfiguration() { |
| 76 | std::vector<std::string> disabled_addons; | 70 | std::vector<std::string> disabled_addons; |
| 77 | 71 | ||
| 78 | for (const auto& item : list_items) { | 72 | for (const auto& item : list_items) { |
| @@ -92,72 +86,35 @@ void ConfigurePerGameGeneral::ApplyConfiguration() { | |||
| 92 | Settings::values.disabled_addons[title_id] = disabled_addons; | 86 | Settings::values.disabled_addons[title_id] = disabled_addons; |
| 93 | } | 87 | } |
| 94 | 88 | ||
| 95 | void ConfigurePerGameGeneral::changeEvent(QEvent* event) { | 89 | void ConfigurePerGameAddons::LoadFromFile(FileSys::VirtualFile file) { |
| 90 | this->file = std::move(file); | ||
| 91 | LoadConfiguration(); | ||
| 92 | } | ||
| 93 | |||
| 94 | void ConfigurePerGameAddons::SetTitleId(u64 id) { | ||
| 95 | this->title_id = id; | ||
| 96 | } | ||
| 97 | |||
| 98 | void ConfigurePerGameAddons::changeEvent(QEvent* event) { | ||
| 96 | if (event->type() == QEvent::LanguageChange) { | 99 | if (event->type() == QEvent::LanguageChange) { |
| 97 | RetranslateUI(); | 100 | RetranslateUI(); |
| 98 | } | 101 | } |
| 99 | 102 | ||
| 100 | QDialog::changeEvent(event); | 103 | QWidget::changeEvent(event); |
| 101 | } | 104 | } |
| 102 | 105 | ||
| 103 | void ConfigurePerGameGeneral::RetranslateUI() { | 106 | void ConfigurePerGameAddons::RetranslateUI() { |
| 104 | ui->retranslateUi(this); | 107 | ui->retranslateUi(this); |
| 105 | } | 108 | } |
| 106 | 109 | ||
| 107 | void ConfigurePerGameGeneral::LoadFromFile(FileSys::VirtualFile file) { | 110 | void ConfigurePerGameAddons::LoadConfiguration() { |
| 108 | this->file = std::move(file); | ||
| 109 | LoadConfiguration(); | ||
| 110 | } | ||
| 111 | |||
| 112 | void ConfigurePerGameGeneral::LoadConfiguration() { | ||
| 113 | if (file == nullptr) { | 111 | if (file == nullptr) { |
| 114 | return; | 112 | return; |
| 115 | } | 113 | } |
| 116 | 114 | ||
| 117 | ui->display_title_id->setText(QString::fromStdString(fmt::format("{:016X}", title_id))); | ||
| 118 | |||
| 119 | FileSys::PatchManager pm{title_id}; | 115 | FileSys::PatchManager pm{title_id}; |
| 120 | const auto control = pm.GetControlMetadata(); | ||
| 121 | const auto loader = Loader::GetLoader(file); | 116 | const auto loader = Loader::GetLoader(file); |
| 122 | 117 | ||
| 123 | if (control.first != nullptr) { | ||
| 124 | ui->display_version->setText(QString::fromStdString(control.first->GetVersionString())); | ||
| 125 | ui->display_name->setText(QString::fromStdString(control.first->GetApplicationName())); | ||
| 126 | ui->display_developer->setText(QString::fromStdString(control.first->GetDeveloperName())); | ||
| 127 | } else { | ||
| 128 | std::string title; | ||
| 129 | if (loader->ReadTitle(title) == Loader::ResultStatus::Success) | ||
| 130 | ui->display_name->setText(QString::fromStdString(title)); | ||
| 131 | |||
| 132 | FileSys::NACP nacp; | ||
| 133 | if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success) | ||
| 134 | ui->display_developer->setText(QString::fromStdString(nacp.GetDeveloperName())); | ||
| 135 | |||
| 136 | ui->display_version->setText(QStringLiteral("1.0.0")); | ||
| 137 | } | ||
| 138 | |||
| 139 | if (control.second != nullptr) { | ||
| 140 | scene->clear(); | ||
| 141 | |||
| 142 | QPixmap map; | ||
| 143 | const auto bytes = control.second->ReadAllBytes(); | ||
| 144 | map.loadFromData(bytes.data(), static_cast<u32>(bytes.size())); | ||
| 145 | |||
| 146 | scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(), | ||
| 147 | Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); | ||
| 148 | } else { | ||
| 149 | std::vector<u8> bytes; | ||
| 150 | if (loader->ReadIcon(bytes) == Loader::ResultStatus::Success) { | ||
| 151 | scene->clear(); | ||
| 152 | |||
| 153 | QPixmap map; | ||
| 154 | map.loadFromData(bytes.data(), static_cast<u32>(bytes.size())); | ||
| 155 | |||
| 156 | scene->addPixmap(map.scaled(ui->icon_view->width(), ui->icon_view->height(), | ||
| 157 | Qt::IgnoreAspectRatio, Qt::SmoothTransformation)); | ||
| 158 | } | ||
| 159 | } | ||
| 160 | |||
| 161 | FileSys::VirtualFile update_raw; | 118 | FileSys::VirtualFile update_raw; |
| 162 | loader->ReadUpdateRaw(update_raw); | 119 | loader->ReadUpdateRaw(update_raw); |
| 163 | 120 | ||
| @@ -182,12 +139,4 @@ void ConfigurePerGameGeneral::LoadConfiguration() { | |||
| 182 | } | 139 | } |
| 183 | 140 | ||
| 184 | tree_view->setColumnWidth(0, 5 * tree_view->width() / 16); | 141 | tree_view->setColumnWidth(0, 5 * tree_view->width() / 16); |
| 185 | |||
| 186 | ui->display_filename->setText(QString::fromStdString(file->GetName())); | ||
| 187 | |||
| 188 | ui->display_format->setText( | ||
| 189 | QString::fromStdString(Loader::GetFileTypeString(loader->GetFileType()))); | ||
| 190 | |||
| 191 | const auto valueText = ReadableByteSize(file->GetSize()); | ||
| 192 | ui->display_size->setText(valueText); | ||
| 193 | } | 142 | } |
diff --git a/src/yuzu/configuration/configure_per_general.h b/src/yuzu/configuration/configure_per_game_addons.h index a3b2cdeff..a00ec3539 100644 --- a/src/yuzu/configuration/configure_per_general.h +++ b/src/yuzu/configuration/configure_per_game_addons.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // Copyright 2016 Citra Emulator Project | 1 | // Copyright 2016 Citra Emulator Project |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| @@ -7,7 +7,6 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | 9 | ||
| 10 | #include <QDialog> | ||
| 11 | #include <QList> | 10 | #include <QList> |
| 12 | 11 | ||
| 13 | #include "core/file_sys/vfs_types.h" | 12 | #include "core/file_sys/vfs_types.h" |
| @@ -19,35 +18,36 @@ class QTreeView; | |||
| 19 | class QVBoxLayout; | 18 | class QVBoxLayout; |
| 20 | 19 | ||
| 21 | namespace Ui { | 20 | namespace Ui { |
| 22 | class ConfigurePerGameGeneral; | 21 | class ConfigurePerGameAddons; |
| 23 | } | 22 | } |
| 24 | 23 | ||
| 25 | class ConfigurePerGameGeneral : public QDialog { | 24 | class ConfigurePerGameAddons : public QWidget { |
| 26 | Q_OBJECT | 25 | Q_OBJECT |
| 27 | 26 | ||
| 28 | public: | 27 | public: |
| 29 | explicit ConfigurePerGameGeneral(QWidget* parent, u64 title_id); | 28 | explicit ConfigurePerGameAddons(QWidget* parent = nullptr); |
| 30 | ~ConfigurePerGameGeneral() override; | 29 | ~ConfigurePerGameAddons() override; |
| 31 | 30 | ||
| 32 | /// Save all button configurations to settings file | 31 | /// Save all button configurations to settings file |
| 33 | void ApplyConfiguration(); | 32 | void ApplyConfiguration(); |
| 34 | 33 | ||
| 35 | void LoadFromFile(FileSys::VirtualFile file); | 34 | void LoadFromFile(FileSys::VirtualFile file); |
| 36 | 35 | ||
| 36 | void SetTitleId(u64 id); | ||
| 37 | |||
| 37 | private: | 38 | private: |
| 38 | void changeEvent(QEvent* event) override; | 39 | void changeEvent(QEvent* event) override; |
| 39 | void RetranslateUI(); | 40 | void RetranslateUI(); |
| 40 | 41 | ||
| 41 | void LoadConfiguration(); | 42 | void LoadConfiguration(); |
| 42 | 43 | ||
| 43 | std::unique_ptr<Ui::ConfigurePerGameGeneral> ui; | 44 | std::unique_ptr<Ui::ConfigurePerGameAddons> ui; |
| 44 | FileSys::VirtualFile file; | 45 | FileSys::VirtualFile file; |
| 45 | u64 title_id; | 46 | u64 title_id; |
| 46 | 47 | ||
| 47 | QVBoxLayout* layout; | 48 | QVBoxLayout* layout; |
| 48 | QTreeView* tree_view; | 49 | QTreeView* tree_view; |
| 49 | QStandardItemModel* item_model; | 50 | QStandardItemModel* item_model; |
| 50 | QGraphicsScene* scene; | ||
| 51 | 51 | ||
| 52 | std::vector<QList<QStandardItem*>> list_items; | 52 | std::vector<QList<QStandardItem*>> list_items; |
| 53 | }; | 53 | }; |
diff --git a/src/yuzu/configuration/configure_per_game_addons.ui b/src/yuzu/configuration/configure_per_game_addons.ui new file mode 100644 index 000000000..aefdebfcd --- /dev/null +++ b/src/yuzu/configuration/configure_per_game_addons.ui | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <ui version="4.0"> | ||
| 3 | <class>ConfigurePerGameAddons</class> | ||
| 4 | <widget class="QWidget" name="ConfigurePerGameAddons"> | ||
| 5 | <property name="geometry"> | ||
| 6 | <rect> | ||
| 7 | <x>0</x> | ||
| 8 | <y>0</y> | ||
| 9 | <width>400</width> | ||
| 10 | <height>300</height> | ||
| 11 | </rect> | ||
| 12 | </property> | ||
| 13 | <property name="windowTitle"> | ||
| 14 | <string>Form</string> | ||
| 15 | </property> | ||
| 16 | <layout class="QGridLayout" name="gridLayout"> | ||
| 17 | <item row="0" column="0"> | ||
| 18 | <widget class="QScrollArea" name="scrollArea"> | ||
| 19 | <property name="widgetResizable"> | ||
| 20 | <bool>true</bool> | ||
| 21 | </property> | ||
| 22 | <widget class="QWidget" name="scrollAreaWidgetContents"> | ||
| 23 | <property name="geometry"> | ||
| 24 | <rect> | ||
| 25 | <x>0</x> | ||
| 26 | <y>0</y> | ||
| 27 | <width>380</width> | ||
| 28 | <height>280</height> | ||
| 29 | </rect> | ||
| 30 | </property> | ||
| 31 | </widget> | ||
| 32 | </widget> | ||
| 33 | </item> | ||
| 34 | </layout> | ||
| 35 | </widget> | ||
| 36 | <resources/> | ||
| 37 | <connections/> | ||
| 38 | </ui> | ||
diff --git a/src/yuzu/configuration/configure_per_general.ui b/src/yuzu/configuration/configure_per_general.ui deleted file mode 100644 index 8fdd96fa4..000000000 --- a/src/yuzu/configuration/configure_per_general.ui +++ /dev/null | |||
| @@ -1,276 +0,0 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <ui version="4.0"> | ||
| 3 | <class>ConfigurePerGameGeneral</class> | ||
| 4 | <widget class="QDialog" name="ConfigurePerGameGeneral"> | ||
| 5 | <property name="geometry"> | ||
| 6 | <rect> | ||
| 7 | <x>0</x> | ||
| 8 | <y>0</y> | ||
| 9 | <width>400</width> | ||
| 10 | <height>520</height> | ||
| 11 | </rect> | ||
| 12 | </property> | ||
| 13 | <property name="windowTitle"> | ||
| 14 | <string>ConfigurePerGameGeneral</string> | ||
| 15 | </property> | ||
| 16 | <layout class="QHBoxLayout" name="HorizontalLayout"> | ||
| 17 | <item> | ||
| 18 | <layout class="QVBoxLayout" name="VerticalLayout"> | ||
| 19 | <item> | ||
| 20 | <widget class="QGroupBox" name="GeneralGroupBox"> | ||
| 21 | <property name="title"> | ||
| 22 | <string>Info</string> | ||
| 23 | </property> | ||
| 24 | <layout class="QHBoxLayout" name="GeneralHorizontalLayout"> | ||
| 25 | <item> | ||
| 26 | <layout class="QGridLayout" name="gridLayout_2"> | ||
| 27 | <item row="6" column="1" colspan="2"> | ||
| 28 | <widget class="QLineEdit" name="display_filename"> | ||
| 29 | <property name="enabled"> | ||
| 30 | <bool>true</bool> | ||
| 31 | </property> | ||
| 32 | <property name="readOnly"> | ||
| 33 | <bool>true</bool> | ||
| 34 | </property> | ||
| 35 | </widget> | ||
| 36 | </item> | ||
| 37 | <item row="0" column="1"> | ||
| 38 | <widget class="QLineEdit" name="display_name"> | ||
| 39 | <property name="enabled"> | ||
| 40 | <bool>true</bool> | ||
| 41 | </property> | ||
| 42 | <property name="readOnly"> | ||
| 43 | <bool>true</bool> | ||
| 44 | </property> | ||
| 45 | </widget> | ||
| 46 | </item> | ||
| 47 | <item row="1" column="0"> | ||
| 48 | <widget class="QLabel" name="label_2"> | ||
| 49 | <property name="text"> | ||
| 50 | <string>Developer</string> | ||
| 51 | </property> | ||
| 52 | </widget> | ||
| 53 | </item> | ||
| 54 | <item row="5" column="1" colspan="2"> | ||
| 55 | <widget class="QLineEdit" name="display_size"> | ||
| 56 | <property name="enabled"> | ||
| 57 | <bool>true</bool> | ||
| 58 | </property> | ||
| 59 | <property name="readOnly"> | ||
| 60 | <bool>true</bool> | ||
| 61 | </property> | ||
| 62 | </widget> | ||
| 63 | </item> | ||
| 64 | <item row="0" column="0"> | ||
| 65 | <widget class="QLabel" name="label"> | ||
| 66 | <property name="text"> | ||
| 67 | <string>Name</string> | ||
| 68 | </property> | ||
| 69 | </widget> | ||
| 70 | </item> | ||
| 71 | <item row="6" column="0"> | ||
| 72 | <widget class="QLabel" name="label_7"> | ||
| 73 | <property name="text"> | ||
| 74 | <string>Filename</string> | ||
| 75 | </property> | ||
| 76 | </widget> | ||
| 77 | </item> | ||
| 78 | <item row="2" column="0"> | ||
| 79 | <widget class="QLabel" name="label_3"> | ||
| 80 | <property name="text"> | ||
| 81 | <string>Version</string> | ||
| 82 | </property> | ||
| 83 | </widget> | ||
| 84 | </item> | ||
| 85 | <item row="4" column="0"> | ||
| 86 | <widget class="QLabel" name="label_5"> | ||
| 87 | <property name="text"> | ||
| 88 | <string>Format</string> | ||
| 89 | </property> | ||
| 90 | </widget> | ||
| 91 | </item> | ||
| 92 | <item row="2" column="1"> | ||
| 93 | <widget class="QLineEdit" name="display_version"> | ||
| 94 | <property name="enabled"> | ||
| 95 | <bool>true</bool> | ||
| 96 | </property> | ||
| 97 | <property name="readOnly"> | ||
| 98 | <bool>true</bool> | ||
| 99 | </property> | ||
| 100 | </widget> | ||
| 101 | </item> | ||
| 102 | <item row="4" column="1"> | ||
| 103 | <widget class="QLineEdit" name="display_format"> | ||
| 104 | <property name="enabled"> | ||
| 105 | <bool>true</bool> | ||
| 106 | </property> | ||
| 107 | <property name="readOnly"> | ||
| 108 | <bool>true</bool> | ||
| 109 | </property> | ||
| 110 | </widget> | ||
| 111 | </item> | ||
| 112 | <item row="5" column="0"> | ||
| 113 | <widget class="QLabel" name="label_6"> | ||
| 114 | <property name="text"> | ||
| 115 | <string>Size</string> | ||
| 116 | </property> | ||
| 117 | </widget> | ||
| 118 | </item> | ||
| 119 | <item row="1" column="1"> | ||
| 120 | <widget class="QLineEdit" name="display_developer"> | ||
| 121 | <property name="enabled"> | ||
| 122 | <bool>true</bool> | ||
| 123 | </property> | ||
| 124 | <property name="readOnly"> | ||
| 125 | <bool>true</bool> | ||
| 126 | </property> | ||
| 127 | </widget> | ||
| 128 | </item> | ||
| 129 | <item row="3" column="0"> | ||
| 130 | <widget class="QLabel" name="label_4"> | ||
| 131 | <property name="text"> | ||
| 132 | <string>Title ID</string> | ||
| 133 | </property> | ||
| 134 | </widget> | ||
| 135 | </item> | ||
| 136 | <item row="3" column="1"> | ||
| 137 | <widget class="QLineEdit" name="display_title_id"> | ||
| 138 | <property name="enabled"> | ||
| 139 | <bool>true</bool> | ||
| 140 | </property> | ||
| 141 | <property name="readOnly"> | ||
| 142 | <bool>true</bool> | ||
| 143 | </property> | ||
| 144 | </widget> | ||
| 145 | </item> | ||
| 146 | <item row="0" column="2" rowspan="5"> | ||
| 147 | <widget class="QGraphicsView" name="icon_view"> | ||
| 148 | <property name="sizePolicy"> | ||
| 149 | <sizepolicy hsizetype="Maximum" vsizetype="Maximum"> | ||
| 150 | <horstretch>0</horstretch> | ||
| 151 | <verstretch>0</verstretch> | ||
| 152 | </sizepolicy> | ||
| 153 | </property> | ||
| 154 | <property name="minimumSize"> | ||
| 155 | <size> | ||
| 156 | <width>128</width> | ||
| 157 | <height>128</height> | ||
| 158 | </size> | ||
| 159 | </property> | ||
| 160 | <property name="maximumSize"> | ||
| 161 | <size> | ||
| 162 | <width>128</width> | ||
| 163 | <height>128</height> | ||
| 164 | </size> | ||
| 165 | </property> | ||
| 166 | <property name="verticalScrollBarPolicy"> | ||
| 167 | <enum>Qt::ScrollBarAlwaysOff</enum> | ||
| 168 | </property> | ||
| 169 | <property name="horizontalScrollBarPolicy"> | ||
| 170 | <enum>Qt::ScrollBarAlwaysOff</enum> | ||
| 171 | </property> | ||
| 172 | <property name="sizeAdjustPolicy"> | ||
| 173 | <enum>QAbstractScrollArea::AdjustToContents</enum> | ||
| 174 | </property> | ||
| 175 | <property name="interactive"> | ||
| 176 | <bool>false</bool> | ||
| 177 | </property> | ||
| 178 | </widget> | ||
| 179 | </item> | ||
| 180 | </layout> | ||
| 181 | </item> | ||
| 182 | </layout> | ||
| 183 | </widget> | ||
| 184 | </item> | ||
| 185 | <item> | ||
| 186 | <widget class="QGroupBox" name="PerformanceGroupBox"> | ||
| 187 | <property name="title"> | ||
| 188 | <string>Add-Ons</string> | ||
| 189 | </property> | ||
| 190 | <layout class="QHBoxLayout" name="PerformanceHorizontalLayout"> | ||
| 191 | <item> | ||
| 192 | <widget class="QScrollArea" name="scrollArea"> | ||
| 193 | <property name="widgetResizable"> | ||
| 194 | <bool>true</bool> | ||
| 195 | </property> | ||
| 196 | <widget class="QWidget" name="scrollAreaWidgetContents"> | ||
| 197 | <property name="geometry"> | ||
| 198 | <rect> | ||
| 199 | <x>0</x> | ||
| 200 | <y>0</y> | ||
| 201 | <width>350</width> | ||
| 202 | <height>169</height> | ||
| 203 | </rect> | ||
| 204 | </property> | ||
| 205 | </widget> | ||
| 206 | </widget> | ||
| 207 | </item> | ||
| 208 | <item> | ||
| 209 | <layout class="QVBoxLayout" name="PerformanceVerticalLayout"/> | ||
| 210 | </item> | ||
| 211 | </layout> | ||
| 212 | </widget> | ||
| 213 | </item> | ||
| 214 | <item> | ||
| 215 | <spacer name="verticalSpacer"> | ||
| 216 | <property name="orientation"> | ||
| 217 | <enum>Qt::Vertical</enum> | ||
| 218 | </property> | ||
| 219 | <property name="sizeType"> | ||
| 220 | <enum>QSizePolicy::Fixed</enum> | ||
| 221 | </property> | ||
| 222 | <property name="sizeHint" stdset="0"> | ||
| 223 | <size> | ||
| 224 | <width>20</width> | ||
| 225 | <height>40</height> | ||
| 226 | </size> | ||
| 227 | </property> | ||
| 228 | </spacer> | ||
| 229 | </item> | ||
| 230 | <item> | ||
| 231 | <widget class="QDialogButtonBox" name="buttonBox"> | ||
| 232 | <property name="standardButtons"> | ||
| 233 | <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set> | ||
| 234 | </property> | ||
| 235 | </widget> | ||
| 236 | </item> | ||
| 237 | </layout> | ||
| 238 | </item> | ||
| 239 | </layout> | ||
| 240 | </widget> | ||
| 241 | <resources/> | ||
| 242 | <connections> | ||
| 243 | <connection> | ||
| 244 | <sender>buttonBox</sender> | ||
| 245 | <signal>accepted()</signal> | ||
| 246 | <receiver>ConfigurePerGameGeneral</receiver> | ||
| 247 | <slot>accept()</slot> | ||
| 248 | <hints> | ||
| 249 | <hint type="sourcelabel"> | ||
| 250 | <x>269</x> | ||
| 251 | <y>567</y> | ||
| 252 | </hint> | ||
| 253 | <hint type="destinationlabel"> | ||
| 254 | <x>269</x> | ||
| 255 | <y>294</y> | ||
| 256 | </hint> | ||
| 257 | </hints> | ||
| 258 | </connection> | ||
| 259 | <connection> | ||
| 260 | <sender>buttonBox</sender> | ||
| 261 | <signal>rejected()</signal> | ||
| 262 | <receiver>ConfigurePerGameGeneral</receiver> | ||
| 263 | <slot>reject()</slot> | ||
| 264 | <hints> | ||
| 265 | <hint type="sourcelabel"> | ||
| 266 | <x>269</x> | ||
| 267 | <y>567</y> | ||
| 268 | </hint> | ||
| 269 | <hint type="destinationlabel"> | ||
| 270 | <x>269</x> | ||
| 271 | <y>294</y> | ||
| 272 | </hint> | ||
| 273 | </hints> | ||
| 274 | </connection> | ||
| 275 | </connections> | ||
| 276 | </ui> | ||
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index 10315e7a6..68e02738b 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "core/core.h" | 14 | #include "core/core.h" |
| 15 | #include "core/settings.h" | 15 | #include "core/settings.h" |
| 16 | #include "ui_configure_system.h" | 16 | #include "ui_configure_system.h" |
| 17 | #include "yuzu/configuration/configuration_shared.h" | ||
| 17 | #include "yuzu/configuration/configure_system.h" | 18 | #include "yuzu/configuration/configure_system.h" |
| 18 | 19 | ||
| 19 | ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureSystem) { | 20 | ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureSystem) { |
| @@ -21,20 +22,25 @@ ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui:: | |||
| 21 | connect(ui->button_regenerate_console_id, &QPushButton::clicked, this, | 22 | connect(ui->button_regenerate_console_id, &QPushButton::clicked, this, |
| 22 | &ConfigureSystem::RefreshConsoleID); | 23 | &ConfigureSystem::RefreshConsoleID); |
| 23 | 24 | ||
| 24 | connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](bool checked) { | 25 | connect(ui->rng_seed_checkbox, &QCheckBox::stateChanged, this, [this](int state) { |
| 25 | ui->rng_seed_edit->setEnabled(checked); | 26 | ui->rng_seed_edit->setEnabled(state == Qt::Checked); |
| 26 | if (!checked) { | 27 | if (state != Qt::Checked) { |
| 27 | ui->rng_seed_edit->setText(QStringLiteral("00000000")); | 28 | ui->rng_seed_edit->setText(QStringLiteral("00000000")); |
| 28 | } | 29 | } |
| 29 | }); | 30 | }); |
| 30 | 31 | ||
| 31 | connect(ui->custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](bool checked) { | 32 | connect(ui->custom_rtc_checkbox, &QCheckBox::stateChanged, this, [this](int state) { |
| 32 | ui->custom_rtc_edit->setEnabled(checked); | 33 | ui->custom_rtc_edit->setEnabled(state == Qt::Checked); |
| 33 | if (!checked) { | 34 | if (state != Qt::Checked) { |
| 34 | ui->custom_rtc_edit->setDateTime(QDateTime::currentDateTime()); | 35 | ui->custom_rtc_edit->setDateTime(QDateTime::currentDateTime()); |
| 35 | } | 36 | } |
| 36 | }); | 37 | }); |
| 37 | 38 | ||
| 39 | ui->label_console_id->setVisible(Settings::configuring_global); | ||
| 40 | ui->button_regenerate_console_id->setVisible(Settings::configuring_global); | ||
| 41 | |||
| 42 | SetupPerGameUI(); | ||
| 43 | |||
| 38 | SetConfiguration(); | 44 | SetConfiguration(); |
| 39 | } | 45 | } |
| 40 | 46 | ||
| @@ -54,26 +60,58 @@ void ConfigureSystem::RetranslateUI() { | |||
| 54 | 60 | ||
| 55 | void ConfigureSystem::SetConfiguration() { | 61 | void ConfigureSystem::SetConfiguration() { |
| 56 | enabled = !Core::System::GetInstance().IsPoweredOn(); | 62 | enabled = !Core::System::GetInstance().IsPoweredOn(); |
| 63 | const auto rng_seed = | ||
| 64 | QStringLiteral("%1") | ||
| 65 | .arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'}) | ||
| 66 | .toUpper(); | ||
| 67 | const auto rtc_time = Settings::values.custom_rtc.GetValue().value_or( | ||
| 68 | std::chrono::seconds(QDateTime::currentSecsSinceEpoch())); | ||
| 57 | 69 | ||
| 58 | ui->combo_language->setCurrentIndex(Settings::values.language_index); | 70 | if (Settings::configuring_global) { |
| 59 | ui->combo_region->setCurrentIndex(Settings::values.region_index); | 71 | ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue()); |
| 60 | ui->combo_time_zone->setCurrentIndex(Settings::values.time_zone_index); | 72 | ui->combo_region->setCurrentIndex(Settings::values.region_index.GetValue()); |
| 61 | ui->combo_sound->setCurrentIndex(Settings::values.sound_index); | 73 | ui->combo_time_zone->setCurrentIndex(Settings::values.time_zone_index.GetValue()); |
| 62 | 74 | ui->combo_sound->setCurrentIndex(Settings::values.sound_index.GetValue()); | |
| 63 | ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.has_value()); | 75 | |
| 64 | ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.has_value()); | 76 | ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value()); |
| 65 | 77 | ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() && | |
| 66 | const auto rng_seed = QStringLiteral("%1") | 78 | Settings::values.rng_seed.UsingGlobal()); |
| 67 | .arg(Settings::values.rng_seed.value_or(0), 8, 16, QLatin1Char{'0'}) | 79 | ui->rng_seed_edit->setText(rng_seed); |
| 68 | .toUpper(); | 80 | |
| 69 | ui->rng_seed_edit->setText(rng_seed); | 81 | ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.GetValue().has_value()); |
| 70 | 82 | ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.GetValue().has_value() && | |
| 71 | ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value()); | 83 | Settings::values.rng_seed.UsingGlobal()); |
| 72 | ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value()); | 84 | ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count())); |
| 85 | } else { | ||
| 86 | ConfigurationShared::SetPerGameSetting(ui->combo_language, | ||
| 87 | &Settings::values.language_index); | ||
| 88 | ConfigurationShared::SetPerGameSetting(ui->combo_region, &Settings::values.region_index); | ||
| 89 | ConfigurationShared::SetPerGameSetting(ui->combo_time_zone, | ||
| 90 | &Settings::values.time_zone_index); | ||
| 91 | ConfigurationShared::SetPerGameSetting(ui->combo_sound, &Settings::values.sound_index); | ||
| 92 | |||
| 93 | if (Settings::values.rng_seed.UsingGlobal()) { | ||
| 94 | ui->rng_seed_checkbox->setCheckState(Qt::PartiallyChecked); | ||
| 95 | } else { | ||
| 96 | ui->rng_seed_checkbox->setCheckState( | ||
| 97 | Settings::values.rng_seed.GetValue().has_value() ? Qt::Checked : Qt::Unchecked); | ||
| 98 | ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value()); | ||
| 99 | if (Settings::values.rng_seed.GetValue().has_value()) { | ||
| 100 | ui->rng_seed_edit->setText(rng_seed); | ||
| 101 | } | ||
| 102 | } | ||
| 73 | 103 | ||
| 74 | const auto rtc_time = Settings::values.custom_rtc.value_or( | 104 | if (Settings::values.custom_rtc.UsingGlobal()) { |
| 75 | std::chrono::seconds(QDateTime::currentSecsSinceEpoch())); | 105 | ui->custom_rtc_checkbox->setCheckState(Qt::PartiallyChecked); |
| 76 | ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count())); | 106 | } else { |
| 107 | ui->custom_rtc_checkbox->setCheckState( | ||
| 108 | Settings::values.custom_rtc.GetValue().has_value() ? Qt::Checked : Qt::Unchecked); | ||
| 109 | ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.GetValue().has_value()); | ||
| 110 | if (Settings::values.custom_rtc.GetValue().has_value()) { | ||
| 111 | ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count())); | ||
| 112 | } | ||
| 113 | } | ||
| 114 | } | ||
| 77 | } | 115 | } |
| 78 | 116 | ||
| 79 | void ConfigureSystem::ReadSystemSettings() {} | 117 | void ConfigureSystem::ReadSystemSettings() {} |
| @@ -83,22 +121,78 @@ void ConfigureSystem::ApplyConfiguration() { | |||
| 83 | return; | 121 | return; |
| 84 | } | 122 | } |
| 85 | 123 | ||
| 86 | Settings::values.language_index = ui->combo_language->currentIndex(); | 124 | if (Settings::configuring_global) { |
| 87 | Settings::values.region_index = ui->combo_region->currentIndex(); | 125 | // Guard if during game and set to game-specific value |
| 88 | Settings::values.time_zone_index = ui->combo_time_zone->currentIndex(); | 126 | if (Settings::values.language_index.UsingGlobal()) { |
| 89 | Settings::values.sound_index = ui->combo_sound->currentIndex(); | 127 | Settings::values.language_index.SetValue(ui->combo_language->currentIndex()); |
| 128 | } | ||
| 129 | if (Settings::values.region_index.UsingGlobal()) { | ||
| 130 | Settings::values.region_index.SetValue(ui->combo_region->currentIndex()); | ||
| 131 | } | ||
| 132 | if (Settings::values.time_zone_index.UsingGlobal()) { | ||
| 133 | Settings::values.time_zone_index.SetValue(ui->combo_time_zone->currentIndex()); | ||
| 134 | } | ||
| 135 | if (Settings::values.sound_index.UsingGlobal()) { | ||
| 136 | Settings::values.sound_index.SetValue(ui->combo_sound->currentIndex()); | ||
| 137 | } | ||
| 138 | |||
| 139 | if (Settings::values.rng_seed.UsingGlobal()) { | ||
| 140 | if (ui->rng_seed_checkbox->isChecked()) { | ||
| 141 | Settings::values.rng_seed.SetValue( | ||
| 142 | ui->rng_seed_edit->text().toULongLong(nullptr, 16)); | ||
| 143 | } else { | ||
| 144 | Settings::values.rng_seed.SetValue(std::nullopt); | ||
| 145 | } | ||
| 146 | } | ||
| 90 | 147 | ||
| 91 | if (ui->rng_seed_checkbox->isChecked()) { | 148 | if (Settings::values.custom_rtc.UsingGlobal()) { |
| 92 | Settings::values.rng_seed = ui->rng_seed_edit->text().toULongLong(nullptr, 16); | 149 | if (ui->custom_rtc_checkbox->isChecked()) { |
| 150 | Settings::values.custom_rtc.SetValue( | ||
| 151 | std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch())); | ||
| 152 | } else { | ||
| 153 | Settings::values.custom_rtc.SetValue(std::nullopt); | ||
| 154 | } | ||
| 155 | } | ||
| 93 | } else { | 156 | } else { |
| 94 | Settings::values.rng_seed = std::nullopt; | 157 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.language_index, |
| 95 | } | 158 | ui->combo_language); |
| 159 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.region_index, ui->combo_region); | ||
| 160 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.time_zone_index, | ||
| 161 | ui->combo_time_zone); | ||
| 162 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.sound_index, ui->combo_sound); | ||
| 163 | |||
| 164 | switch (ui->rng_seed_checkbox->checkState()) { | ||
| 165 | case Qt::Checked: | ||
| 166 | Settings::values.rng_seed.SetGlobal(false); | ||
| 167 | Settings::values.rng_seed.SetValue(ui->rng_seed_edit->text().toULongLong(nullptr, 16)); | ||
| 168 | break; | ||
| 169 | case Qt::Unchecked: | ||
| 170 | Settings::values.rng_seed.SetGlobal(false); | ||
| 171 | Settings::values.rng_seed.SetValue(std::nullopt); | ||
| 172 | break; | ||
| 173 | case Qt::PartiallyChecked: | ||
| 174 | Settings::values.rng_seed.SetGlobal(false); | ||
| 175 | Settings::values.rng_seed.SetValue(std::nullopt); | ||
| 176 | Settings::values.rng_seed.SetGlobal(true); | ||
| 177 | break; | ||
| 178 | } | ||
| 96 | 179 | ||
| 97 | if (ui->custom_rtc_checkbox->isChecked()) { | 180 | switch (ui->custom_rtc_checkbox->checkState()) { |
| 98 | Settings::values.custom_rtc = | 181 | case Qt::Checked: |
| 99 | std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch()); | 182 | Settings::values.custom_rtc.SetGlobal(false); |
| 100 | } else { | 183 | Settings::values.custom_rtc.SetValue( |
| 101 | Settings::values.custom_rtc = std::nullopt; | 184 | std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch())); |
| 185 | break; | ||
| 186 | case Qt::Unchecked: | ||
| 187 | Settings::values.custom_rtc.SetGlobal(false); | ||
| 188 | Settings::values.custom_rtc.SetValue(std::nullopt); | ||
| 189 | break; | ||
| 190 | case Qt::PartiallyChecked: | ||
| 191 | Settings::values.custom_rtc.SetGlobal(false); | ||
| 192 | Settings::values.custom_rtc.SetValue(std::nullopt); | ||
| 193 | Settings::values.custom_rtc.SetGlobal(true); | ||
| 194 | break; | ||
| 195 | } | ||
| 102 | } | 196 | } |
| 103 | 197 | ||
| 104 | Settings::Apply(); | 198 | Settings::Apply(); |
| @@ -120,3 +214,25 @@ void ConfigureSystem::RefreshConsoleID() { | |||
| 120 | ui->label_console_id->setText( | 214 | ui->label_console_id->setText( |
| 121 | tr("Console ID: 0x%1").arg(QString::number(console_id, 16).toUpper())); | 215 | tr("Console ID: 0x%1").arg(QString::number(console_id, 16).toUpper())); |
| 122 | } | 216 | } |
| 217 | |||
| 218 | void ConfigureSystem::SetupPerGameUI() { | ||
| 219 | if (Settings::configuring_global) { | ||
| 220 | ui->combo_language->setEnabled(Settings::values.language_index.UsingGlobal()); | ||
| 221 | ui->combo_region->setEnabled(Settings::values.region_index.UsingGlobal()); | ||
| 222 | ui->combo_time_zone->setEnabled(Settings::values.time_zone_index.UsingGlobal()); | ||
| 223 | ui->combo_sound->setEnabled(Settings::values.sound_index.UsingGlobal()); | ||
| 224 | ui->rng_seed_checkbox->setEnabled(Settings::values.rng_seed.UsingGlobal()); | ||
| 225 | ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.UsingGlobal()); | ||
| 226 | ui->custom_rtc_checkbox->setEnabled(Settings::values.custom_rtc.UsingGlobal()); | ||
| 227 | ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.UsingGlobal()); | ||
| 228 | |||
| 229 | return; | ||
| 230 | } | ||
| 231 | |||
| 232 | ConfigurationShared::InsertGlobalItem(ui->combo_language); | ||
| 233 | ConfigurationShared::InsertGlobalItem(ui->combo_region); | ||
| 234 | ConfigurationShared::InsertGlobalItem(ui->combo_time_zone); | ||
| 235 | ConfigurationShared::InsertGlobalItem(ui->combo_sound); | ||
| 236 | ui->rng_seed_checkbox->setTristate(true); | ||
| 237 | ui->custom_rtc_checkbox->setTristate(true); | ||
| 238 | } | ||
diff --git a/src/yuzu/configuration/configure_system.h b/src/yuzu/configuration/configure_system.h index 26d42d5c5..f317ef8b5 100644 --- a/src/yuzu/configuration/configure_system.h +++ b/src/yuzu/configuration/configure_system.h | |||
| @@ -32,6 +32,8 @@ private: | |||
| 32 | 32 | ||
| 33 | void RefreshConsoleID(); | 33 | void RefreshConsoleID(); |
| 34 | 34 | ||
| 35 | void SetupPerGameUI(); | ||
| 36 | |||
| 35 | std::unique_ptr<Ui::ConfigureSystem> ui; | 37 | std::unique_ptr<Ui::ConfigureSystem> ui; |
| 36 | bool enabled = false; | 38 | bool enabled = false; |
| 37 | 39 | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 9844e4764..4d501a8f9 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -16,7 +16,7 @@ | |||
| 16 | #include "applets/software_keyboard.h" | 16 | #include "applets/software_keyboard.h" |
| 17 | #include "applets/web_browser.h" | 17 | #include "applets/web_browser.h" |
| 18 | #include "configuration/configure_input.h" | 18 | #include "configuration/configure_input.h" |
| 19 | #include "configuration/configure_per_general.h" | 19 | #include "configuration/configure_per_game.h" |
| 20 | #include "core/file_sys/vfs.h" | 20 | #include "core/file_sys/vfs.h" |
| 21 | #include "core/file_sys/vfs_real.h" | 21 | #include "core/file_sys/vfs_real.h" |
| 22 | #include "core/frontend/applets/general_frontend.h" | 22 | #include "core/frontend/applets/general_frontend.h" |
| @@ -534,15 +534,15 @@ void GMainWindow::InitializeWidgets() { | |||
| 534 | if (emulation_running) { | 534 | if (emulation_running) { |
| 535 | return; | 535 | return; |
| 536 | } | 536 | } |
| 537 | bool is_async = | 537 | bool is_async = !Settings::values.use_asynchronous_gpu_emulation.GetValue() || |
| 538 | !Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core; | 538 | Settings::values.use_multi_core.GetValue(); |
| 539 | Settings::values.use_asynchronous_gpu_emulation = is_async; | 539 | Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async); |
| 540 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | 540 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); |
| 541 | Settings::Apply(); | 541 | Settings::Apply(); |
| 542 | }); | 542 | }); |
| 543 | async_status_button->setText(tr("ASYNC")); | 543 | async_status_button->setText(tr("ASYNC")); |
| 544 | async_status_button->setCheckable(true); | 544 | async_status_button->setCheckable(true); |
| 545 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | 545 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); |
| 546 | 546 | ||
| 547 | // Setup Multicore button | 547 | // Setup Multicore button |
| 548 | multicore_status_button = new QPushButton(); | 548 | multicore_status_button = new QPushButton(); |
| @@ -552,17 +552,17 @@ void GMainWindow::InitializeWidgets() { | |||
| 552 | if (emulation_running) { | 552 | if (emulation_running) { |
| 553 | return; | 553 | return; |
| 554 | } | 554 | } |
| 555 | Settings::values.use_multi_core = !Settings::values.use_multi_core; | 555 | Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue()); |
| 556 | bool is_async = | 556 | bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue() || |
| 557 | Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core; | 557 | Settings::values.use_multi_core.GetValue(); |
| 558 | Settings::values.use_asynchronous_gpu_emulation = is_async; | 558 | Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async); |
| 559 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | 559 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); |
| 560 | multicore_status_button->setChecked(Settings::values.use_multi_core); | 560 | multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); |
| 561 | Settings::Apply(); | 561 | Settings::Apply(); |
| 562 | }); | 562 | }); |
| 563 | multicore_status_button->setText(tr("MULTICORE")); | 563 | multicore_status_button->setText(tr("MULTICORE")); |
| 564 | multicore_status_button->setCheckable(true); | 564 | multicore_status_button->setCheckable(true); |
| 565 | multicore_status_button->setChecked(Settings::values.use_multi_core); | 565 | multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); |
| 566 | statusBar()->insertPermanentWidget(0, multicore_status_button); | 566 | statusBar()->insertPermanentWidget(0, multicore_status_button); |
| 567 | statusBar()->insertPermanentWidget(0, async_status_button); | 567 | statusBar()->insertPermanentWidget(0, async_status_button); |
| 568 | 568 | ||
| @@ -581,16 +581,16 @@ void GMainWindow::InitializeWidgets() { | |||
| 581 | renderer_status_button->setCheckable(false); | 581 | renderer_status_button->setCheckable(false); |
| 582 | renderer_status_button->setDisabled(true); | 582 | renderer_status_button->setDisabled(true); |
| 583 | #else | 583 | #else |
| 584 | renderer_status_button->setChecked(Settings::values.renderer_backend == | 584 | renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() == |
| 585 | Settings::RendererBackend::Vulkan); | 585 | Settings::RendererBackend::Vulkan); |
| 586 | connect(renderer_status_button, &QPushButton::clicked, [=] { | 586 | connect(renderer_status_button, &QPushButton::clicked, [=] { |
| 587 | if (emulation_running) { | 587 | if (emulation_running) { |
| 588 | return; | 588 | return; |
| 589 | } | 589 | } |
| 590 | if (renderer_status_button->isChecked()) { | 590 | if (renderer_status_button->isChecked()) { |
| 591 | Settings::values.renderer_backend = Settings::RendererBackend::Vulkan; | 591 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::Vulkan); |
| 592 | } else { | 592 | } else { |
| 593 | Settings::values.renderer_backend = Settings::RendererBackend::OpenGL; | 593 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL); |
| 594 | } | 594 | } |
| 595 | 595 | ||
| 596 | Settings::Apply(); | 596 | Settings::Apply(); |
| @@ -727,21 +727,24 @@ void GMainWindow::InitializeHotkeys() { | |||
| 727 | }); | 727 | }); |
| 728 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this), | 728 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this), |
| 729 | &QShortcut::activated, this, [&] { | 729 | &QShortcut::activated, this, [&] { |
| 730 | Settings::values.use_frame_limit = !Settings::values.use_frame_limit; | 730 | Settings::values.use_frame_limit.SetValue( |
| 731 | !Settings::values.use_frame_limit.GetValue()); | ||
| 731 | UpdateStatusBar(); | 732 | UpdateStatusBar(); |
| 732 | }); | 733 | }); |
| 733 | constexpr u16 SPEED_LIMIT_STEP = 5; | 734 | constexpr u16 SPEED_LIMIT_STEP = 5; |
| 734 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this), | 735 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this), |
| 735 | &QShortcut::activated, this, [&] { | 736 | &QShortcut::activated, this, [&] { |
| 736 | if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) { | 737 | if (Settings::values.frame_limit.GetValue() < 9999 - SPEED_LIMIT_STEP) { |
| 737 | Settings::values.frame_limit += SPEED_LIMIT_STEP; | 738 | Settings::values.frame_limit.SetValue(SPEED_LIMIT_STEP + |
| 739 | Settings::values.frame_limit.GetValue()); | ||
| 738 | UpdateStatusBar(); | 740 | UpdateStatusBar(); |
| 739 | } | 741 | } |
| 740 | }); | 742 | }); |
| 741 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this), | 743 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this), |
| 742 | &QShortcut::activated, this, [&] { | 744 | &QShortcut::activated, this, [&] { |
| 743 | if (Settings::values.frame_limit > SPEED_LIMIT_STEP) { | 745 | if (Settings::values.frame_limit.GetValue() > SPEED_LIMIT_STEP) { |
| 744 | Settings::values.frame_limit -= SPEED_LIMIT_STEP; | 746 | Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() - |
| 747 | SPEED_LIMIT_STEP); | ||
| 745 | UpdateStatusBar(); | 748 | UpdateStatusBar(); |
| 746 | } | 749 | } |
| 747 | }); | 750 | }); |
| @@ -1039,6 +1042,17 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1039 | LOG_INFO(Frontend, "yuzu starting..."); | 1042 | LOG_INFO(Frontend, "yuzu starting..."); |
| 1040 | StoreRecentFile(filename); // Put the filename on top of the list | 1043 | StoreRecentFile(filename); // Put the filename on top of the list |
| 1041 | 1044 | ||
| 1045 | u64 title_id{0}; | ||
| 1046 | |||
| 1047 | const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); | ||
| 1048 | const auto loader = Loader::GetLoader(v_file); | ||
| 1049 | if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) { | ||
| 1050 | // Load per game settings | ||
| 1051 | Config per_game_config(fmt::format("{:016X}.ini", title_id), false); | ||
| 1052 | } | ||
| 1053 | |||
| 1054 | Settings::LogSettings(); | ||
| 1055 | |||
| 1042 | if (UISettings::values.select_user_on_boot) { | 1056 | if (UISettings::values.select_user_on_boot) { |
| 1043 | SelectAndSetCurrentUser(); | 1057 | SelectAndSetCurrentUser(); |
| 1044 | } | 1058 | } |
| @@ -1063,6 +1077,7 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1063 | &LoadingScreen::OnLoadProgress, Qt::QueuedConnection); | 1077 | &LoadingScreen::OnLoadProgress, Qt::QueuedConnection); |
| 1064 | 1078 | ||
| 1065 | // Update the GUI | 1079 | // Update the GUI |
| 1080 | UpdateStatusButtons(); | ||
| 1066 | if (ui.action_Single_Window_Mode->isChecked()) { | 1081 | if (ui.action_Single_Window_Mode->isChecked()) { |
| 1067 | game_list->hide(); | 1082 | game_list->hide(); |
| 1068 | game_list_placeholder->hide(); | 1083 | game_list_placeholder->hide(); |
| @@ -1078,8 +1093,6 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1078 | ui.centralwidget->setMouseTracking(true); | 1093 | ui.centralwidget->setMouseTracking(true); |
| 1079 | } | 1094 | } |
| 1080 | 1095 | ||
| 1081 | const u64 title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID(); | ||
| 1082 | |||
| 1083 | std::string title_name; | 1096 | std::string title_name; |
| 1084 | std::string title_version; | 1097 | std::string title_version; |
| 1085 | const auto res = Core::System::GetInstance().GetGameName(title_name); | 1098 | const auto res = Core::System::GetInstance().GetGameName(title_name); |
| @@ -1521,7 +1534,7 @@ void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) { | |||
| 1521 | return; | 1534 | return; |
| 1522 | } | 1535 | } |
| 1523 | 1536 | ||
| 1524 | ConfigurePerGameGeneral dialog(this, title_id); | 1537 | ConfigurePerGame dialog(this, title_id); |
| 1525 | dialog.LoadFromFile(v_file); | 1538 | dialog.LoadFromFile(v_file); |
| 1526 | auto result = dialog.exec(); | 1539 | auto result = dialog.exec(); |
| 1527 | if (result == QDialog::Accepted) { | 1540 | if (result == QDialog::Accepted) { |
| @@ -1532,7 +1545,14 @@ void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) { | |||
| 1532 | game_list->PopulateAsync(UISettings::values.game_dirs); | 1545 | game_list->PopulateAsync(UISettings::values.game_dirs); |
| 1533 | } | 1546 | } |
| 1534 | 1547 | ||
| 1535 | config->Save(); | 1548 | // Do not cause the global config to write local settings into the config file |
| 1549 | Settings::RestoreGlobalState(); | ||
| 1550 | |||
| 1551 | if (!Core::System::GetInstance().IsPoweredOn()) { | ||
| 1552 | config->Save(); | ||
| 1553 | } | ||
| 1554 | } else { | ||
| 1555 | Settings::RestoreGlobalState(); | ||
| 1536 | } | 1556 | } |
| 1537 | } | 1557 | } |
| 1538 | 1558 | ||
| @@ -1819,6 +1839,9 @@ void GMainWindow::OnStopGame() { | |||
| 1819 | } | 1839 | } |
| 1820 | 1840 | ||
| 1821 | ShutdownGame(); | 1841 | ShutdownGame(); |
| 1842 | |||
| 1843 | Settings::RestoreGlobalState(); | ||
| 1844 | UpdateStatusButtons(); | ||
| 1822 | } | 1845 | } |
| 1823 | 1846 | ||
| 1824 | void GMainWindow::OnLoadComplete() { | 1847 | void GMainWindow::OnLoadComplete() { |
| @@ -1926,7 +1949,7 @@ void GMainWindow::ToggleWindowMode() { | |||
| 1926 | 1949 | ||
| 1927 | void GMainWindow::ResetWindowSize() { | 1950 | void GMainWindow::ResetWindowSize() { |
| 1928 | const auto aspect_ratio = Layout::EmulationAspectRatio( | 1951 | const auto aspect_ratio = Layout::EmulationAspectRatio( |
| 1929 | static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio), | 1952 | static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio.GetValue()), |
| 1930 | static_cast<float>(Layout::ScreenUndocked::Height) / Layout::ScreenUndocked::Width); | 1953 | static_cast<float>(Layout::ScreenUndocked::Height) / Layout::ScreenUndocked::Width); |
| 1931 | if (!ui.action_Single_Window_Mode->isChecked()) { | 1954 | if (!ui.action_Single_Window_Mode->isChecked()) { |
| 1932 | render_window->resize(Layout::ScreenUndocked::Height / aspect_ratio, | 1955 | render_window->resize(Layout::ScreenUndocked::Height / aspect_ratio, |
| @@ -1974,16 +1997,7 @@ void GMainWindow::OnConfigure() { | |||
| 1974 | ui.centralwidget->setMouseTracking(false); | 1997 | ui.centralwidget->setMouseTracking(false); |
| 1975 | } | 1998 | } |
| 1976 | 1999 | ||
| 1977 | dock_status_button->setChecked(Settings::values.use_docked_mode); | 2000 | UpdateStatusButtons(); |
| 1978 | multicore_status_button->setChecked(Settings::values.use_multi_core); | ||
| 1979 | Settings::values.use_asynchronous_gpu_emulation = | ||
| 1980 | Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core; | ||
| 1981 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | ||
| 1982 | |||
| 1983 | #ifdef HAS_VULKAN | ||
| 1984 | renderer_status_button->setChecked(Settings::values.renderer_backend == | ||
| 1985 | Settings::RendererBackend::Vulkan); | ||
| 1986 | #endif | ||
| 1987 | } | 2001 | } |
| 1988 | 2002 | ||
| 1989 | void GMainWindow::OnLoadAmiibo() { | 2003 | void GMainWindow::OnLoadAmiibo() { |
| @@ -2097,21 +2111,34 @@ void GMainWindow::UpdateStatusBar() { | |||
| 2097 | 2111 | ||
| 2098 | auto results = Core::System::GetInstance().GetAndResetPerfStats(); | 2112 | auto results = Core::System::GetInstance().GetAndResetPerfStats(); |
| 2099 | 2113 | ||
| 2100 | if (Settings::values.use_frame_limit) { | 2114 | if (Settings::values.use_frame_limit.GetValue()) { |
| 2101 | emu_speed_label->setText(tr("Speed: %1% / %2%") | 2115 | emu_speed_label->setText(tr("Speed: %1% / %2%") |
| 2102 | .arg(results.emulation_speed * 100.0, 0, 'f', 0) | 2116 | .arg(results.emulation_speed * 100.0, 0, 'f', 0) |
| 2103 | .arg(Settings::values.frame_limit)); | 2117 | .arg(Settings::values.frame_limit.GetValue())); |
| 2104 | } else { | 2118 | } else { |
| 2105 | emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); | 2119 | emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); |
| 2106 | } | 2120 | } |
| 2107 | game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0)); | 2121 | game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0)); |
| 2108 | emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2)); | 2122 | emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2)); |
| 2109 | 2123 | ||
| 2110 | emu_speed_label->setVisible(!Settings::values.use_multi_core); | 2124 | emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue()); |
| 2111 | game_fps_label->setVisible(true); | 2125 | game_fps_label->setVisible(true); |
| 2112 | emu_frametime_label->setVisible(true); | 2126 | emu_frametime_label->setVisible(true); |
| 2113 | } | 2127 | } |
| 2114 | 2128 | ||
| 2129 | void GMainWindow::UpdateStatusButtons() { | ||
| 2130 | dock_status_button->setChecked(Settings::values.use_docked_mode); | ||
| 2131 | multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); | ||
| 2132 | Settings::values.use_asynchronous_gpu_emulation.SetValue( | ||
| 2133 | Settings::values.use_asynchronous_gpu_emulation.GetValue() || | ||
| 2134 | Settings::values.use_multi_core.GetValue()); | ||
| 2135 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); | ||
| 2136 | #ifdef HAS_VULKAN | ||
| 2137 | renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() == | ||
| 2138 | Settings::RendererBackend::Vulkan); | ||
| 2139 | #endif | ||
| 2140 | } | ||
| 2141 | |||
| 2115 | void GMainWindow::HideMouseCursor() { | 2142 | void GMainWindow::HideMouseCursor() { |
| 2116 | if (emu_thread == nullptr || UISettings::values.hide_mouse == false) { | 2143 | if (emu_thread == nullptr || UISettings::values.hide_mouse == false) { |
| 2117 | mouse_hide_timer.stop(); | 2144 | mouse_hide_timer.stop(); |
| @@ -2195,6 +2222,9 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det | |||
| 2195 | if (answer == QMessageBox::Yes) { | 2222 | if (answer == QMessageBox::Yes) { |
| 2196 | if (emu_thread) { | 2223 | if (emu_thread) { |
| 2197 | ShutdownGame(); | 2224 | ShutdownGame(); |
| 2225 | |||
| 2226 | Settings::RestoreGlobalState(); | ||
| 2227 | UpdateStatusButtons(); | ||
| 2198 | } | 2228 | } |
| 2199 | } else { | 2229 | } else { |
| 2200 | // Only show the message if the game is still running. | 2230 | // Only show the message if the game is still running. |
| @@ -2357,9 +2387,13 @@ void GMainWindow::closeEvent(QCloseEvent* event) { | |||
| 2357 | hotkey_registry.SaveHotkeys(); | 2387 | hotkey_registry.SaveHotkeys(); |
| 2358 | 2388 | ||
| 2359 | // Shutdown session if the emu thread is active... | 2389 | // Shutdown session if the emu thread is active... |
| 2360 | if (emu_thread != nullptr) | 2390 | if (emu_thread != nullptr) { |
| 2361 | ShutdownGame(); | 2391 | ShutdownGame(); |
| 2362 | 2392 | ||
| 2393 | Settings::RestoreGlobalState(); | ||
| 2394 | UpdateStatusButtons(); | ||
| 2395 | } | ||
| 2396 | |||
| 2363 | render_window->close(); | 2397 | render_window->close(); |
| 2364 | 2398 | ||
| 2365 | QWidget::closeEvent(event); | 2399 | QWidget::closeEvent(event); |
| @@ -2539,8 +2573,6 @@ int main(int argc, char* argv[]) { | |||
| 2539 | QObject::connect(&app, &QGuiApplication::applicationStateChanged, &main_window, | 2573 | QObject::connect(&app, &QGuiApplication::applicationStateChanged, &main_window, |
| 2540 | &GMainWindow::OnAppFocusStateChanged); | 2574 | &GMainWindow::OnAppFocusStateChanged); |
| 2541 | 2575 | ||
| 2542 | Settings::LogSettings(); | ||
| 2543 | |||
| 2544 | int result = app.exec(); | 2576 | int result = app.exec(); |
| 2545 | detached_tasks.WaitForAllTasks(); | 2577 | detached_tasks.WaitForAllTasks(); |
| 2546 | return result; | 2578 | return result; |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 66c84e5c0..8e3d39c38 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -221,6 +221,7 @@ private: | |||
| 221 | void UpdateWindowTitle(const std::string& title_name = {}, | 221 | void UpdateWindowTitle(const std::string& title_name = {}, |
| 222 | const std::string& title_version = {}); | 222 | const std::string& title_version = {}); |
| 223 | void UpdateStatusBar(); | 223 | void UpdateStatusBar(); |
| 224 | void UpdateStatusButtons(); | ||
| 224 | void HideMouseCursor(); | 225 | void HideMouseCursor(); |
| 225 | void ShowMouseCursor(); | 226 | void ShowMouseCursor(); |
| 226 | void OpenURL(const QUrl& url); | 227 | void OpenURL(const QUrl& url); |
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 659b9f701..23763144f 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -354,63 +354,72 @@ void Config::ReadValues() { | |||
| 354 | 354 | ||
| 355 | const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false); | 355 | const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false); |
| 356 | if (rng_seed_enabled) { | 356 | if (rng_seed_enabled) { |
| 357 | Settings::values.rng_seed = sdl2_config->GetInteger("System", "rng_seed", 0); | 357 | Settings::values.rng_seed.SetValue(sdl2_config->GetInteger("System", "rng_seed", 0)); |
| 358 | } else { | 358 | } else { |
| 359 | Settings::values.rng_seed = std::nullopt; | 359 | Settings::values.rng_seed.SetValue(std::nullopt); |
| 360 | } | 360 | } |
| 361 | 361 | ||
| 362 | const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); | 362 | const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); |
| 363 | if (custom_rtc_enabled) { | 363 | if (custom_rtc_enabled) { |
| 364 | Settings::values.custom_rtc = | 364 | Settings::values.custom_rtc.SetValue( |
| 365 | std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0)); | 365 | std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0))); |
| 366 | } else { | 366 | } else { |
| 367 | Settings::values.custom_rtc = std::nullopt; | 367 | Settings::values.custom_rtc.SetValue(std::nullopt); |
| 368 | } | 368 | } |
| 369 | 369 | ||
| 370 | Settings::values.language_index = sdl2_config->GetInteger("System", "language_index", 1); | 370 | Settings::values.language_index.SetValue( |
| 371 | Settings::values.time_zone_index = sdl2_config->GetInteger("System", "time_zone_index", 0); | 371 | sdl2_config->GetInteger("System", "language_index", 1)); |
| 372 | Settings::values.time_zone_index.SetValue( | ||
| 373 | sdl2_config->GetInteger("System", "time_zone_index", 0)); | ||
| 372 | 374 | ||
| 373 | // Core | 375 | // Core |
| 374 | Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false); | 376 | Settings::values.use_multi_core.SetValue( |
| 377 | sdl2_config->GetBoolean("Core", "use_multi_core", false)); | ||
| 375 | 378 | ||
| 376 | // Renderer | 379 | // Renderer |
| 377 | const int renderer_backend = sdl2_config->GetInteger( | 380 | const int renderer_backend = sdl2_config->GetInteger( |
| 378 | "Renderer", "backend", static_cast<int>(Settings::RendererBackend::OpenGL)); | 381 | "Renderer", "backend", static_cast<int>(Settings::RendererBackend::OpenGL)); |
| 379 | Settings::values.renderer_backend = static_cast<Settings::RendererBackend>(renderer_backend); | 382 | Settings::values.renderer_backend.SetValue( |
| 383 | static_cast<Settings::RendererBackend>(renderer_backend)); | ||
| 380 | Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "debug", false); | 384 | Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "debug", false); |
| 381 | Settings::values.vulkan_device = sdl2_config->GetInteger("Renderer", "vulkan_device", 0); | 385 | Settings::values.vulkan_device.SetValue( |
| 382 | 386 | sdl2_config->GetInteger("Renderer", "vulkan_device", 0)); | |
| 383 | Settings::values.aspect_ratio = | 387 | |
| 384 | static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0)); | 388 | Settings::values.aspect_ratio.SetValue( |
| 385 | Settings::values.max_anisotropy = | 389 | static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0))); |
| 386 | static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0)); | 390 | Settings::values.max_anisotropy.SetValue( |
| 387 | Settings::values.use_frame_limit = sdl2_config->GetBoolean("Renderer", "use_frame_limit", true); | 391 | static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0))); |
| 388 | Settings::values.frame_limit = | 392 | Settings::values.use_frame_limit.SetValue( |
| 389 | static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); | 393 | sdl2_config->GetBoolean("Renderer", "use_frame_limit", true)); |
| 390 | Settings::values.use_disk_shader_cache = | 394 | Settings::values.frame_limit.SetValue( |
| 391 | sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false); | 395 | static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100))); |
| 396 | Settings::values.use_disk_shader_cache.SetValue( | ||
| 397 | sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false)); | ||
| 392 | const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0); | 398 | const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0); |
| 393 | Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level); | 399 | Settings::values.gpu_accuracy.SetValue(static_cast<Settings::GPUAccuracy>(gpu_accuracy_level)); |
| 394 | Settings::values.use_asynchronous_gpu_emulation = | 400 | Settings::values.use_asynchronous_gpu_emulation.SetValue( |
| 395 | sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false); | 401 | sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false)); |
| 396 | Settings::values.use_vsync = | 402 | Settings::values.use_vsync.SetValue( |
| 397 | static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1)); | 403 | static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1))); |
| 398 | Settings::values.use_assembly_shaders = | 404 | Settings::values.use_assembly_shaders.SetValue( |
| 399 | sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", false); | 405 | sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", false)); |
| 400 | Settings::values.use_fast_gpu_time = | 406 | Settings::values.use_fast_gpu_time.SetValue( |
| 401 | sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true); | 407 | sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true)); |
| 402 | 408 | ||
| 403 | Settings::values.bg_red = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0)); | 409 | Settings::values.bg_red.SetValue( |
| 404 | Settings::values.bg_green = | 410 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0))); |
| 405 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0)); | 411 | Settings::values.bg_green.SetValue( |
| 406 | Settings::values.bg_blue = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)); | 412 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0))); |
| 413 | Settings::values.bg_blue.SetValue( | ||
| 414 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0))); | ||
| 407 | 415 | ||
| 408 | // Audio | 416 | // Audio |
| 409 | Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto"); | 417 | Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto"); |
| 410 | Settings::values.enable_audio_stretching = | 418 | Settings::values.enable_audio_stretching.SetValue( |
| 411 | sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true); | 419 | sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true)); |
| 412 | Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto"); | 420 | Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto"); |
| 413 | Settings::values.volume = static_cast<float>(sdl2_config->GetReal("Audio", "volume", 1)); | 421 | Settings::values.volume.SetValue( |
| 422 | static_cast<float>(sdl2_config->GetReal("Audio", "volume", 1))); | ||
| 414 | 423 | ||
| 415 | // Miscellaneous | 424 | // Miscellaneous |
| 416 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); | 425 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); |
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp index 09cc0a3b5..e78025737 100644 --- a/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2_gl.cpp | |||
| @@ -165,7 +165,7 @@ std::unique_ptr<Core::Frontend::GraphicsContext> EmuWindow_SDL2_GL::CreateShared | |||
| 165 | 165 | ||
| 166 | void EmuWindow_SDL2_GL::Present() { | 166 | void EmuWindow_SDL2_GL::Present() { |
| 167 | SDL_GL_MakeCurrent(render_window, window_context); | 167 | SDL_GL_MakeCurrent(render_window, window_context); |
| 168 | SDL_GL_SetSwapInterval(Settings::values.use_vsync ? 1 : 0); | 168 | SDL_GL_SetSwapInterval(Settings::values.use_vsync.GetValue() ? 1 : 0); |
| 169 | while (IsOpen()) { | 169 | while (IsOpen()) { |
| 170 | system.Renderer().TryPresent(100); | 170 | system.Renderer().TryPresent(100); |
| 171 | SDL_GL_SwapWindow(render_window); | 171 | SDL_GL_SwapWindow(render_window); |
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index e6c6a839d..512b060a7 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp | |||
| @@ -181,7 +181,7 @@ int main(int argc, char** argv) { | |||
| 181 | Core::System& system{Core::System::GetInstance()}; | 181 | Core::System& system{Core::System::GetInstance()}; |
| 182 | 182 | ||
| 183 | std::unique_ptr<EmuWindow_SDL2> emu_window; | 183 | std::unique_ptr<EmuWindow_SDL2> emu_window; |
| 184 | switch (Settings::values.renderer_backend) { | 184 | switch (Settings::values.renderer_backend.GetValue()) { |
| 185 | case Settings::RendererBackend::OpenGL: | 185 | case Settings::RendererBackend::OpenGL: |
| 186 | emu_window = std::make_unique<EmuWindow_SDL2_GL>(system, fullscreen); | 186 | emu_window = std::make_unique<EmuWindow_SDL2_GL>(system, fullscreen); |
| 187 | break; | 187 | break; |
diff --git a/src/yuzu_tester/config.cpp b/src/yuzu_tester/config.cpp index 1566c2e3f..acb22885e 100644 --- a/src/yuzu_tester/config.cpp +++ b/src/yuzu_tester/config.cpp | |||
| @@ -81,6 +81,9 @@ void Config::ReadValues() { | |||
| 81 | Settings::values.touchscreen.diameter_x = 15; | 81 | Settings::values.touchscreen.diameter_x = 15; |
| 82 | Settings::values.touchscreen.diameter_y = 15; | 82 | Settings::values.touchscreen.diameter_y = 15; |
| 83 | 83 | ||
| 84 | Settings::values.use_docked_mode = | ||
| 85 | sdl2_config->GetBoolean("Controls", "use_docked_mode", false); | ||
| 86 | |||
| 84 | // Data Storage | 87 | // Data Storage |
| 85 | Settings::values.use_virtual_sd = | 88 | Settings::values.use_virtual_sd = |
| 86 | sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); | 89 | sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); |
| @@ -92,57 +95,59 @@ void Config::ReadValues() { | |||
| 92 | FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir))); | 95 | FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir))); |
| 93 | 96 | ||
| 94 | // System | 97 | // System |
| 95 | Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false); | ||
| 96 | |||
| 97 | Settings::values.current_user = std::clamp<int>( | 98 | Settings::values.current_user = std::clamp<int>( |
| 98 | sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1); | 99 | sdl2_config->GetInteger("System", "current_user", 0), 0, Service::Account::MAX_USERS - 1); |
| 99 | 100 | ||
| 100 | const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false); | 101 | const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false); |
| 101 | if (rng_seed_enabled) { | 102 | if (rng_seed_enabled) { |
| 102 | Settings::values.rng_seed = sdl2_config->GetInteger("System", "rng_seed", 0); | 103 | Settings::values.rng_seed.SetValue(sdl2_config->GetInteger("System", "rng_seed", 0)); |
| 103 | } else { | 104 | } else { |
| 104 | Settings::values.rng_seed = std::nullopt; | 105 | Settings::values.rng_seed.SetValue(std::nullopt); |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 107 | const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); | 108 | const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); |
| 108 | if (custom_rtc_enabled) { | 109 | if (custom_rtc_enabled) { |
| 109 | Settings::values.custom_rtc = | 110 | Settings::values.custom_rtc.SetValue( |
| 110 | std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0)); | 111 | std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0))); |
| 111 | } else { | 112 | } else { |
| 112 | Settings::values.custom_rtc = std::nullopt; | 113 | Settings::values.custom_rtc.SetValue(std::nullopt); |
| 113 | } | 114 | } |
| 114 | 115 | ||
| 115 | // Core | 116 | // Core |
| 116 | Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false); | 117 | Settings::values.use_multi_core.SetValue( |
| 118 | sdl2_config->GetBoolean("Core", "use_multi_core", false)); | ||
| 117 | 119 | ||
| 118 | // Renderer | 120 | // Renderer |
| 119 | Settings::values.aspect_ratio = | 121 | Settings::values.aspect_ratio.SetValue( |
| 120 | static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0)); | 122 | static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0))); |
| 121 | Settings::values.max_anisotropy = | 123 | Settings::values.max_anisotropy.SetValue( |
| 122 | static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0)); | 124 | static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0))); |
| 123 | Settings::values.use_frame_limit = false; | 125 | Settings::values.use_frame_limit.SetValue(false); |
| 124 | Settings::values.frame_limit = 100; | 126 | Settings::values.frame_limit.SetValue(100); |
| 125 | Settings::values.use_disk_shader_cache = | 127 | Settings::values.use_disk_shader_cache.SetValue( |
| 126 | sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false); | 128 | sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false)); |
| 127 | const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0); | 129 | const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0); |
| 128 | Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level); | 130 | Settings::values.gpu_accuracy.SetValue(static_cast<Settings::GPUAccuracy>(gpu_accuracy_level)); |
| 129 | Settings::values.use_asynchronous_gpu_emulation = | 131 | Settings::values.use_asynchronous_gpu_emulation.SetValue( |
| 130 | sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false); | 132 | sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false)); |
| 131 | Settings::values.use_fast_gpu_time = | 133 | Settings::values.use_fast_gpu_time.SetValue( |
| 132 | sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true); | 134 | sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true)); |
| 133 | 135 | ||
| 134 | Settings::values.bg_red = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0)); | 136 | Settings::values.bg_red.SetValue( |
| 135 | Settings::values.bg_green = | 137 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0))); |
| 136 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0)); | 138 | Settings::values.bg_green.SetValue( |
| 137 | Settings::values.bg_blue = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)); | 139 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0))); |
| 140 | Settings::values.bg_blue.SetValue( | ||
| 141 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0))); | ||
| 138 | 142 | ||
| 139 | // Audio | 143 | // Audio |
| 140 | Settings::values.sink_id = "null"; | 144 | Settings::values.sink_id = "null"; |
| 141 | Settings::values.enable_audio_stretching = false; | 145 | Settings::values.enable_audio_stretching.SetValue(false); |
| 142 | Settings::values.audio_device_id = "auto"; | 146 | Settings::values.audio_device_id = "auto"; |
| 143 | Settings::values.volume = 0; | 147 | Settings::values.volume.SetValue(0); |
| 144 | 148 | ||
| 145 | Settings::values.language_index = sdl2_config->GetInteger("System", "language_index", 1); | 149 | Settings::values.language_index.SetValue( |
| 150 | sdl2_config->GetInteger("System", "language_index", 1)); | ||
| 146 | 151 | ||
| 147 | // Miscellaneous | 152 | // Miscellaneous |
| 148 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); | 153 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); |