diff options
Diffstat (limited to 'src')
118 files changed, 3408 insertions, 1479 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/common/alignment.h b/src/common/alignment.h index f8c49e079..b37044bb6 100644 --- a/src/common/alignment.h +++ b/src/common/alignment.h | |||
| @@ -11,7 +11,9 @@ namespace Common { | |||
| 11 | template <typename T> | 11 | template <typename T> |
| 12 | constexpr T AlignUp(T value, std::size_t size) { | 12 | constexpr T AlignUp(T value, std::size_t size) { |
| 13 | static_assert(std::is_unsigned_v<T>, "T must be an unsigned value."); | 13 | static_assert(std::is_unsigned_v<T>, "T must be an unsigned value."); |
| 14 | return static_cast<T>(value + (size - value % size) % size); | 14 | auto mod{static_cast<T>(value % size)}; |
| 15 | value -= mod; | ||
| 16 | return static_cast<T>(mod == T{0} ? value : value + size); | ||
| 15 | } | 17 | } |
| 16 | 18 | ||
| 17 | template <typename T> | 19 | template <typename T> |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_32.cpp b/src/core/arm/dynarmic/arm_dynarmic_32.cpp index 0d4ab95b7..443ca72eb 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_32.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_32.cpp | |||
| @@ -142,10 +142,32 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable& | |||
| 142 | // Timing | 142 | // Timing |
| 143 | config.wall_clock_cntpct = uses_wall_clock; | 143 | config.wall_clock_cntpct = uses_wall_clock; |
| 144 | 144 | ||
| 145 | // Optimizations | 145 | // Safe optimizations |
| 146 | if (Settings::values.disable_cpu_opt) { | 146 | if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) { |
| 147 | config.enable_optimizations = false; | 147 | if (!Settings::values.cpuopt_page_tables) { |
| 148 | config.enable_fast_dispatch = false; | 148 | config.page_table = nullptr; |
| 149 | } | ||
| 150 | if (!Settings::values.cpuopt_block_linking) { | ||
| 151 | config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking; | ||
| 152 | } | ||
| 153 | if (!Settings::values.cpuopt_return_stack_buffer) { | ||
| 154 | config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer; | ||
| 155 | } | ||
| 156 | if (!Settings::values.cpuopt_fast_dispatcher) { | ||
| 157 | config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch; | ||
| 158 | } | ||
| 159 | if (!Settings::values.cpuopt_context_elimination) { | ||
| 160 | config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination; | ||
| 161 | } | ||
| 162 | if (!Settings::values.cpuopt_const_prop) { | ||
| 163 | config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp; | ||
| 164 | } | ||
| 165 | if (!Settings::values.cpuopt_misc_ir) { | ||
| 166 | config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt; | ||
| 167 | } | ||
| 168 | if (!Settings::values.cpuopt_reduce_misalign_checks) { | ||
| 169 | config.only_detect_misalignment_via_page_table_on_page_boundary = false; | ||
| 170 | } | ||
| 149 | } | 171 | } |
| 150 | 172 | ||
| 151 | return std::make_unique<Dynarmic::A32::Jit>(config); | 173 | return std::make_unique<Dynarmic::A32::Jit>(config); |
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 790981034..a63a04a25 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp | |||
| @@ -191,15 +191,37 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable& | |||
| 191 | // Unpredictable instructions | 191 | // Unpredictable instructions |
| 192 | config.define_unpredictable_behaviour = true; | 192 | config.define_unpredictable_behaviour = true; |
| 193 | 193 | ||
| 194 | // Optimizations | ||
| 195 | if (Settings::values.disable_cpu_opt) { | ||
| 196 | config.enable_optimizations = false; | ||
| 197 | config.enable_fast_dispatch = false; | ||
| 198 | } | ||
| 199 | |||
| 200 | // Timing | 194 | // Timing |
| 201 | config.wall_clock_cntpct = uses_wall_clock; | 195 | config.wall_clock_cntpct = uses_wall_clock; |
| 202 | 196 | ||
| 197 | // Safe optimizations | ||
| 198 | if (Settings::values.cpu_accuracy != Settings::CPUAccuracy::Accurate) { | ||
| 199 | if (!Settings::values.cpuopt_page_tables) { | ||
| 200 | config.page_table = nullptr; | ||
| 201 | } | ||
| 202 | if (!Settings::values.cpuopt_block_linking) { | ||
| 203 | config.optimizations &= ~Dynarmic::OptimizationFlag::BlockLinking; | ||
| 204 | } | ||
| 205 | if (!Settings::values.cpuopt_return_stack_buffer) { | ||
| 206 | config.optimizations &= ~Dynarmic::OptimizationFlag::ReturnStackBuffer; | ||
| 207 | } | ||
| 208 | if (!Settings::values.cpuopt_fast_dispatcher) { | ||
| 209 | config.optimizations &= ~Dynarmic::OptimizationFlag::FastDispatch; | ||
| 210 | } | ||
| 211 | if (!Settings::values.cpuopt_context_elimination) { | ||
| 212 | config.optimizations &= ~Dynarmic::OptimizationFlag::GetSetElimination; | ||
| 213 | } | ||
| 214 | if (!Settings::values.cpuopt_const_prop) { | ||
| 215 | config.optimizations &= ~Dynarmic::OptimizationFlag::ConstProp; | ||
| 216 | } | ||
| 217 | if (!Settings::values.cpuopt_misc_ir) { | ||
| 218 | config.optimizations &= ~Dynarmic::OptimizationFlag::MiscIROpt; | ||
| 219 | } | ||
| 220 | if (!Settings::values.cpuopt_reduce_misalign_checks) { | ||
| 221 | config.only_detect_misalignment_via_page_table_on_page_boundary = false; | ||
| 222 | } | ||
| 223 | } | ||
| 224 | |||
| 203 | return std::make_shared<Dynarmic::A64::Jit>(config); | 225 | return std::make_shared<Dynarmic::A64::Jit>(config); |
| 204 | } | 226 | } |
| 205 | 227 | ||
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/file_sys/bis_factory.cpp b/src/core/file_sys/bis_factory.cpp index 8935a62c3..285277ef8 100644 --- a/src/core/file_sys/bis_factory.cpp +++ b/src/core/file_sys/bis_factory.cpp | |||
| @@ -12,6 +12,10 @@ | |||
| 12 | 12 | ||
| 13 | namespace FileSys { | 13 | namespace FileSys { |
| 14 | 14 | ||
| 15 | constexpr u64 NAND_USER_SIZE = 0x680000000; // 26624 MiB | ||
| 16 | constexpr u64 NAND_SYSTEM_SIZE = 0xA0000000; // 2560 MiB | ||
| 17 | constexpr u64 NAND_TOTAL_SIZE = 0x747C00000; // 29820 MiB | ||
| 18 | |||
| 15 | BISFactory::BISFactory(VirtualDir nand_root_, VirtualDir load_root_, VirtualDir dump_root_) | 19 | BISFactory::BISFactory(VirtualDir nand_root_, VirtualDir load_root_, VirtualDir dump_root_) |
| 16 | : nand_root(std::move(nand_root_)), load_root(std::move(load_root_)), | 20 | : nand_root(std::move(nand_root_)), load_root(std::move(load_root_)), |
| 17 | dump_root(std::move(dump_root_)), | 21 | dump_root(std::move(dump_root_)), |
| @@ -110,30 +114,29 @@ VirtualDir BISFactory::GetImageDirectory() const { | |||
| 110 | 114 | ||
| 111 | u64 BISFactory::GetSystemNANDFreeSpace() const { | 115 | u64 BISFactory::GetSystemNANDFreeSpace() const { |
| 112 | const auto sys_dir = GetOrCreateDirectoryRelative(nand_root, "/system"); | 116 | const auto sys_dir = GetOrCreateDirectoryRelative(nand_root, "/system"); |
| 113 | if (sys_dir == nullptr) | 117 | if (sys_dir == nullptr) { |
| 114 | return 0; | 118 | return GetSystemNANDTotalSpace(); |
| 119 | } | ||
| 115 | 120 | ||
| 116 | return GetSystemNANDTotalSpace() - sys_dir->GetSize(); | 121 | return GetSystemNANDTotalSpace() - sys_dir->GetSize(); |
| 117 | } | 122 | } |
| 118 | 123 | ||
| 119 | u64 BISFactory::GetSystemNANDTotalSpace() const { | 124 | u64 BISFactory::GetSystemNANDTotalSpace() const { |
| 120 | return static_cast<u64>(Settings::values.nand_system_size); | 125 | return NAND_SYSTEM_SIZE; |
| 121 | } | 126 | } |
| 122 | 127 | ||
| 123 | u64 BISFactory::GetUserNANDFreeSpace() const { | 128 | u64 BISFactory::GetUserNANDFreeSpace() const { |
| 124 | const auto usr_dir = GetOrCreateDirectoryRelative(nand_root, "/user"); | 129 | // For some reason games such as BioShock 1 checks whether this is exactly 0x680000000 bytes. |
| 125 | if (usr_dir == nullptr) | 130 | // Set the free space to be 1 MiB less than the total as a workaround to this issue. |
| 126 | return 0; | 131 | return GetUserNANDTotalSpace() - 0x100000; |
| 127 | |||
| 128 | return GetUserNANDTotalSpace() - usr_dir->GetSize(); | ||
| 129 | } | 132 | } |
| 130 | 133 | ||
| 131 | u64 BISFactory::GetUserNANDTotalSpace() const { | 134 | u64 BISFactory::GetUserNANDTotalSpace() const { |
| 132 | return static_cast<u64>(Settings::values.nand_user_size); | 135 | return NAND_USER_SIZE; |
| 133 | } | 136 | } |
| 134 | 137 | ||
| 135 | u64 BISFactory::GetFullNANDTotalSpace() const { | 138 | u64 BISFactory::GetFullNANDTotalSpace() const { |
| 136 | return static_cast<u64>(Settings::values.nand_total_size); | 139 | return NAND_TOTAL_SIZE; |
| 137 | } | 140 | } |
| 138 | 141 | ||
| 139 | VirtualDir BISFactory::GetBCATDirectory(u64 title_id) const { | 142 | VirtualDir BISFactory::GetBCATDirectory(u64 title_id) const { |
diff --git a/src/core/file_sys/sdmc_factory.cpp b/src/core/file_sys/sdmc_factory.cpp index 5113a1ca6..6f732e4d8 100644 --- a/src/core/file_sys/sdmc_factory.cpp +++ b/src/core/file_sys/sdmc_factory.cpp | |||
| @@ -10,6 +10,8 @@ | |||
| 10 | 10 | ||
| 11 | namespace FileSys { | 11 | namespace FileSys { |
| 12 | 12 | ||
| 13 | constexpr u64 SDMC_TOTAL_SIZE = 0x10000000000; // 1 TiB | ||
| 14 | |||
| 13 | SDMCFactory::SDMCFactory(VirtualDir dir_) | 15 | SDMCFactory::SDMCFactory(VirtualDir dir_) |
| 14 | : dir(std::move(dir_)), contents(std::make_unique<RegisteredCache>( | 16 | : dir(std::move(dir_)), contents(std::make_unique<RegisteredCache>( |
| 15 | GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/registered"), | 17 | GetOrCreateDirectoryRelative(dir, "/Nintendo/Contents/registered"), |
| @@ -46,7 +48,7 @@ u64 SDMCFactory::GetSDMCFreeSpace() const { | |||
| 46 | } | 48 | } |
| 47 | 49 | ||
| 48 | u64 SDMCFactory::GetSDMCTotalSpace() const { | 50 | u64 SDMCFactory::GetSDMCTotalSpace() const { |
| 49 | return static_cast<u64>(Settings::values.sdmc_size); | 51 | return SDMC_TOTAL_SIZE; |
| 50 | } | 52 | } |
| 51 | 53 | ||
| 52 | } // namespace FileSys | 54 | } // namespace FileSys |
diff --git a/src/core/file_sys/vfs_real.cpp b/src/core/file_sys/vfs_real.cpp index e21300a7c..96ce5957c 100644 --- a/src/core/file_sys/vfs_real.cpp +++ b/src/core/file_sys/vfs_real.cpp | |||
| @@ -112,19 +112,26 @@ VirtualFile RealVfsFilesystem::MoveFile(std::string_view old_path_, std::string_ | |||
| 112 | const auto new_path = | 112 | const auto new_path = |
| 113 | FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault); | 113 | FileUtil::SanitizePath(new_path_, FileUtil::DirectorySeparator::PlatformDefault); |
| 114 | 114 | ||
| 115 | if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) || | ||
| 116 | FileUtil::IsDirectory(old_path) || !FileUtil::Rename(old_path, new_path)) | ||
| 117 | return nullptr; | ||
| 118 | |||
| 119 | if (cache.find(old_path) != cache.end()) { | 115 | if (cache.find(old_path) != cache.end()) { |
| 120 | auto cached = cache[old_path]; | 116 | auto file = cache[old_path].lock(); |
| 121 | if (!cached.expired()) { | 117 | |
| 122 | auto file = cached.lock(); | 118 | if (!cache[old_path].expired()) { |
| 123 | file->Open(new_path, "r+b"); | 119 | file->Close(); |
| 124 | cache.erase(old_path); | 120 | } |
| 125 | cache[new_path] = file; | 121 | |
| 122 | if (!FileUtil::Exists(old_path) || FileUtil::Exists(new_path) || | ||
| 123 | FileUtil::IsDirectory(old_path) || !FileUtil::Rename(old_path, new_path)) { | ||
| 124 | return nullptr; | ||
| 126 | } | 125 | } |
| 126 | |||
| 127 | cache.erase(old_path); | ||
| 128 | file->Open(new_path, "r+b"); | ||
| 129 | cache[new_path] = file; | ||
| 130 | } else { | ||
| 131 | UNREACHABLE(); | ||
| 132 | return nullptr; | ||
| 127 | } | 133 | } |
| 134 | |||
| 128 | return OpenFile(new_path, Mode::ReadWrite); | 135 | return OpenFile(new_path, Mode::ReadWrite); |
| 129 | } | 136 | } |
| 130 | 137 | ||
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 24cfb370b..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 | ||
| @@ -1389,7 +1407,19 @@ void IApplicationFunctions::GetDesiredLanguage(Kernel::HLERequestContext& ctx) { | |||
| 1389 | u32 supported_languages = 0; | 1407 | u32 supported_languages = 0; |
| 1390 | FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()}; | 1408 | FileSys::PatchManager pm{system.CurrentProcess()->GetTitleID()}; |
| 1391 | 1409 | ||
| 1392 | const auto res = pm.GetControlMetadata(); | 1410 | const auto res = [this] { |
| 1411 | const auto title_id = system.CurrentProcess()->GetTitleID(); | ||
| 1412 | |||
| 1413 | FileSys::PatchManager pm{title_id}; | ||
| 1414 | auto res = pm.GetControlMetadata(); | ||
| 1415 | if (res.first != nullptr) { | ||
| 1416 | return res; | ||
| 1417 | } | ||
| 1418 | |||
| 1419 | FileSys::PatchManager pm_update{FileSys::GetUpdateTitleID(title_id)}; | ||
| 1420 | return pm_update.GetControlMetadata(); | ||
| 1421 | }(); | ||
| 1422 | |||
| 1393 | if (res.first != nullptr) { | 1423 | if (res.first != nullptr) { |
| 1394 | supported_languages = res.first->GetSupportedLanguages(); | 1424 | supported_languages = res.first->GetSupportedLanguages(); |
| 1395 | } | 1425 | } |
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..3eb336f75 100644 --- a/src/core/settings.h +++ b/src/core/settings.h | |||
| @@ -346,31 +346,6 @@ struct TouchscreenInput { | |||
| 346 | u32 rotation_angle; | 346 | u32 rotation_angle; |
| 347 | }; | 347 | }; |
| 348 | 348 | ||
| 349 | enum class NANDTotalSize : u64 { | ||
| 350 | S29_1GB = 0x747C00000ULL, | ||
| 351 | }; | ||
| 352 | |||
| 353 | enum class NANDUserSize : u64 { | ||
| 354 | S26GB = 0x680000000ULL, | ||
| 355 | }; | ||
| 356 | |||
| 357 | enum class NANDSystemSize : u64 { | ||
| 358 | S2_5GB = 0xA0000000, | ||
| 359 | }; | ||
| 360 | |||
| 361 | enum class SDMCSize : u64 { | ||
| 362 | S1GB = 0x40000000, | ||
| 363 | S2GB = 0x80000000, | ||
| 364 | S4GB = 0x100000000ULL, | ||
| 365 | S8GB = 0x200000000ULL, | ||
| 366 | S16GB = 0x400000000ULL, | ||
| 367 | S32GB = 0x800000000ULL, | ||
| 368 | S64GB = 0x1000000000ULL, | ||
| 369 | S128GB = 0x2000000000ULL, | ||
| 370 | S256GB = 0x4000000000ULL, | ||
| 371 | S1TB = 0x10000000000ULL, | ||
| 372 | }; | ||
| 373 | |||
| 374 | enum class RendererBackend { | 349 | enum class RendererBackend { |
| 375 | OpenGL = 0, | 350 | OpenGL = 0, |
| 376 | Vulkan = 1, | 351 | Vulkan = 1, |
| @@ -382,20 +357,102 @@ enum class GPUAccuracy : u32 { | |||
| 382 | Extreme = 2, | 357 | Extreme = 2, |
| 383 | }; | 358 | }; |
| 384 | 359 | ||
| 360 | enum class CPUAccuracy { | ||
| 361 | Accurate = 0, | ||
| 362 | DebugMode = 1, | ||
| 363 | }; | ||
| 364 | |||
| 365 | extern bool configuring_global; | ||
| 366 | |||
| 367 | template <typename Type> | ||
| 368 | class Setting final { | ||
| 369 | public: | ||
| 370 | Setting() = default; | ||
| 371 | explicit Setting(Type val) : global{val} {} | ||
| 372 | ~Setting() = default; | ||
| 373 | void SetGlobal(bool to_global) { | ||
| 374 | use_global = to_global; | ||
| 375 | } | ||
| 376 | bool UsingGlobal() const { | ||
| 377 | return use_global; | ||
| 378 | } | ||
| 379 | Type GetValue(bool need_global = false) const { | ||
| 380 | if (use_global || need_global) { | ||
| 381 | return global; | ||
| 382 | } | ||
| 383 | return local; | ||
| 384 | } | ||
| 385 | void SetValue(const Type& value) { | ||
| 386 | if (use_global) { | ||
| 387 | global = value; | ||
| 388 | } else { | ||
| 389 | local = value; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | private: | ||
| 394 | bool use_global = true; | ||
| 395 | Type global{}; | ||
| 396 | Type local{}; | ||
| 397 | }; | ||
| 398 | |||
| 385 | struct Values { | 399 | struct Values { |
| 400 | // Audio | ||
| 401 | std::string audio_device_id; | ||
| 402 | std::string sink_id; | ||
| 403 | bool audio_muted; | ||
| 404 | Setting<bool> enable_audio_stretching; | ||
| 405 | Setting<float> volume; | ||
| 406 | |||
| 407 | // Core | ||
| 408 | Setting<bool> use_multi_core; | ||
| 409 | |||
| 410 | // Cpu | ||
| 411 | CPUAccuracy cpu_accuracy; | ||
| 412 | |||
| 413 | bool cpuopt_page_tables; | ||
| 414 | bool cpuopt_block_linking; | ||
| 415 | bool cpuopt_return_stack_buffer; | ||
| 416 | bool cpuopt_fast_dispatcher; | ||
| 417 | bool cpuopt_context_elimination; | ||
| 418 | bool cpuopt_const_prop; | ||
| 419 | bool cpuopt_misc_ir; | ||
| 420 | bool cpuopt_reduce_misalign_checks; | ||
| 421 | |||
| 422 | // Renderer | ||
| 423 | Setting<RendererBackend> renderer_backend; | ||
| 424 | bool renderer_debug; | ||
| 425 | Setting<int> vulkan_device; | ||
| 426 | |||
| 427 | Setting<u16> resolution_factor = Setting(static_cast<u16>(1)); | ||
| 428 | Setting<int> aspect_ratio; | ||
| 429 | Setting<int> max_anisotropy; | ||
| 430 | Setting<bool> use_frame_limit; | ||
| 431 | Setting<u16> frame_limit; | ||
| 432 | Setting<bool> use_disk_shader_cache; | ||
| 433 | Setting<GPUAccuracy> gpu_accuracy; | ||
| 434 | Setting<bool> use_asynchronous_gpu_emulation; | ||
| 435 | Setting<bool> use_vsync; | ||
| 436 | Setting<bool> use_assembly_shaders; | ||
| 437 | Setting<bool> force_30fps_mode; | ||
| 438 | Setting<bool> use_fast_gpu_time; | ||
| 439 | |||
| 440 | Setting<float> bg_red; | ||
| 441 | Setting<float> bg_green; | ||
| 442 | Setting<float> bg_blue; | ||
| 443 | |||
| 386 | // System | 444 | // System |
| 387 | bool use_docked_mode; | 445 | Setting<std::optional<u32>> rng_seed; |
| 388 | std::optional<u32> rng_seed; | ||
| 389 | // Measured in seconds since epoch | 446 | // Measured in seconds since epoch |
| 390 | std::optional<std::chrono::seconds> custom_rtc; | 447 | Setting<std::optional<std::chrono::seconds>> custom_rtc; |
| 391 | // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` | 448 | // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` |
| 392 | std::chrono::seconds custom_rtc_differential; | 449 | std::chrono::seconds custom_rtc_differential; |
| 393 | 450 | ||
| 394 | s32 current_user; | 451 | s32 current_user; |
| 395 | s32 language_index; | 452 | Setting<s32> language_index; |
| 396 | s32 region_index; | 453 | Setting<s32> region_index; |
| 397 | s32 time_zone_index; | 454 | Setting<s32> time_zone_index; |
| 398 | s32 sound_index; | 455 | Setting<s32> sound_index; |
| 399 | 456 | ||
| 400 | // Controls | 457 | // Controls |
| 401 | std::array<PlayerInput, 10> players; | 458 | std::array<PlayerInput, 10> players; |
| @@ -419,51 +476,13 @@ struct Values { | |||
| 419 | u16 udp_input_port; | 476 | u16 udp_input_port; |
| 420 | u8 udp_pad_index; | 477 | u8 udp_pad_index; |
| 421 | 478 | ||
| 422 | // Core | 479 | bool use_docked_mode; |
| 423 | bool use_multi_core; | ||
| 424 | 480 | ||
| 425 | // Data Storage | 481 | // Data Storage |
| 426 | bool use_virtual_sd; | 482 | bool use_virtual_sd; |
| 427 | bool gamecard_inserted; | 483 | bool gamecard_inserted; |
| 428 | bool gamecard_current_game; | 484 | bool gamecard_current_game; |
| 429 | std::string gamecard_path; | 485 | std::string gamecard_path; |
| 430 | NANDTotalSize nand_total_size; | ||
| 431 | NANDSystemSize nand_system_size; | ||
| 432 | NANDUserSize nand_user_size; | ||
| 433 | SDMCSize sdmc_size; | ||
| 434 | |||
| 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 | 486 | ||
| 468 | // Debugging | 487 | // Debugging |
| 469 | bool record_frame_times; | 488 | bool record_frame_times; |
| @@ -474,10 +493,13 @@ struct Values { | |||
| 474 | bool dump_nso; | 493 | bool dump_nso; |
| 475 | bool reporting_services; | 494 | bool reporting_services; |
| 476 | bool quest_flag; | 495 | bool quest_flag; |
| 477 | bool disable_cpu_opt; | ||
| 478 | bool disable_macro_jit; | 496 | bool disable_macro_jit; |
| 479 | 497 | ||
| 480 | // BCAT | 498 | // Misceallaneous |
| 499 | std::string log_filter; | ||
| 500 | bool use_dev_keys; | ||
| 501 | |||
| 502 | // Services | ||
| 481 | std::string bcat_backend; | 503 | std::string bcat_backend; |
| 482 | bool bcat_boxcat_local; | 504 | bool bcat_boxcat_local; |
| 483 | 505 | ||
| @@ -501,4 +523,7 @@ std::string GetTimeZoneString(); | |||
| 501 | void Apply(); | 523 | void Apply(); |
| 502 | void LogSettings(); | 524 | void LogSettings(); |
| 503 | 525 | ||
| 526 | // Restore the global state of all applicable settings in the Values struct | ||
| 527 | void RestoreGlobalState(); | ||
| 528 | |||
| 504 | } // namespace Settings | 529 | } // 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/CMakeLists.txt b/src/input_common/CMakeLists.txt index 3bd76dd23..317c25bad 100644 --- a/src/input_common/CMakeLists.txt +++ b/src/input_common/CMakeLists.txt | |||
| @@ -30,7 +30,8 @@ if(SDL2_FOUND) | |||
| 30 | target_compile_definitions(input_common PRIVATE HAVE_SDL2) | 30 | target_compile_definitions(input_common PRIVATE HAVE_SDL2) |
| 31 | endif() | 31 | endif() |
| 32 | 32 | ||
| 33 | target_link_libraries(input_common PUBLIC ${LIBUSB_LIBRARIES}) | 33 | target_include_directories(input_common SYSTEM PRIVATE ${LIBUSB_INCLUDE_DIR}) |
| 34 | target_link_libraries(input_common PRIVATE ${LIBUSB_LIBRARIES}) | ||
| 34 | 35 | ||
| 35 | create_target_directory_groups(input_common) | 36 | create_target_directory_groups(input_common) |
| 36 | target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost) | 37 | target_link_libraries(input_common PUBLIC core PRIVATE common Boost::boost) |
diff --git a/src/input_common/gcadapter/gc_adapter.cpp b/src/input_common/gcadapter/gc_adapter.cpp index 05607e033..898a278a9 100644 --- a/src/input_common/gcadapter/gc_adapter.cpp +++ b/src/input_common/gcadapter/gc_adapter.cpp | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | 4 | ||
| 5 | #include <chrono> | 5 | #include <chrono> |
| 6 | #include <thread> | 6 | #include <thread> |
| 7 | #include <libusb.h> | ||
| 7 | #include "common/logging/log.h" | 8 | #include "common/logging/log.h" |
| 8 | #include "input_common/gcadapter/gc_adapter.h" | 9 | #include "input_common/gcadapter/gc_adapter.h" |
| 9 | 10 | ||
| @@ -34,7 +35,7 @@ Adapter::Adapter() { | |||
| 34 | } | 35 | } |
| 35 | } | 36 | } |
| 36 | 37 | ||
| 37 | GCPadStatus Adapter::GetPadStatus(int port, const std::array<u8, 37>& adapter_payload) { | 38 | GCPadStatus Adapter::GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload) { |
| 38 | GCPadStatus pad = {}; | 39 | GCPadStatus pad = {}; |
| 39 | 40 | ||
| 40 | ControllerTypes type = ControllerTypes(adapter_payload[1 + (9 * port)] >> 4); | 41 | ControllerTypes type = ControllerTypes(adapter_payload[1 + (9 * port)] >> 4); |
| @@ -205,7 +206,7 @@ void Adapter::StartScanThread() { | |||
| 205 | } | 206 | } |
| 206 | 207 | ||
| 207 | detect_thread_running = true; | 208 | detect_thread_running = true; |
| 208 | detect_thread = std::thread([=] { ScanThreadFunc(); }); | 209 | detect_thread = std::thread(&Adapter::ScanThreadFunc, this); |
| 209 | } | 210 | } |
| 210 | 211 | ||
| 211 | void Adapter::StopScanThread() { | 212 | void Adapter::StopScanThread() { |
| @@ -234,7 +235,7 @@ void Adapter::Setup() { | |||
| 234 | } | 235 | } |
| 235 | 236 | ||
| 236 | if (devices != nullptr) { | 237 | if (devices != nullptr) { |
| 237 | for (std::size_t index = 0; index < device_count; ++index) { | 238 | for (std::size_t index = 0; index < static_cast<std::size_t>(device_count); ++index) { |
| 238 | if (CheckDeviceAccess(devices[index])) { | 239 | if (CheckDeviceAccess(devices[index])) { |
| 239 | // GC Adapter found and accessible, registering it | 240 | // GC Adapter found and accessible, registering it |
| 240 | GetGCEndpoint(devices[index]); | 241 | GetGCEndpoint(devices[index]); |
| @@ -368,11 +369,11 @@ void Adapter::Reset() { | |||
| 368 | } | 369 | } |
| 369 | } | 370 | } |
| 370 | 371 | ||
| 371 | bool Adapter::DeviceConnected(int port) { | 372 | bool Adapter::DeviceConnected(std::size_t port) { |
| 372 | return adapter_controllers_status[port] != ControllerTypes::None; | 373 | return adapter_controllers_status[port] != ControllerTypes::None; |
| 373 | } | 374 | } |
| 374 | 375 | ||
| 375 | void Adapter::ResetDeviceType(int port) { | 376 | void Adapter::ResetDeviceType(std::size_t port) { |
| 376 | adapter_controllers_status[port] = ControllerTypes::None; | 377 | adapter_controllers_status[port] = ControllerTypes::None; |
| 377 | } | 378 | } |
| 378 | 379 | ||
diff --git a/src/input_common/gcadapter/gc_adapter.h b/src/input_common/gcadapter/gc_adapter.h index a67485586..3586c8bda 100644 --- a/src/input_common/gcadapter/gc_adapter.h +++ b/src/input_common/gcadapter/gc_adapter.h | |||
| @@ -8,10 +8,13 @@ | |||
| 8 | #include <mutex> | 8 | #include <mutex> |
| 9 | #include <thread> | 9 | #include <thread> |
| 10 | #include <unordered_map> | 10 | #include <unordered_map> |
| 11 | #include <libusb.h> | ||
| 12 | #include "common/common_types.h" | 11 | #include "common/common_types.h" |
| 13 | #include "common/threadsafe_queue.h" | 12 | #include "common/threadsafe_queue.h" |
| 14 | 13 | ||
| 14 | struct libusb_context; | ||
| 15 | struct libusb_device; | ||
| 16 | struct libusb_device_handle; | ||
| 17 | |||
| 15 | namespace GCAdapter { | 18 | namespace GCAdapter { |
| 16 | 19 | ||
| 17 | enum class PadButton { | 20 | enum class PadButton { |
| @@ -91,6 +94,9 @@ public: | |||
| 91 | void BeginConfiguration(); | 94 | void BeginConfiguration(); |
| 92 | void EndConfiguration(); | 95 | void EndConfiguration(); |
| 93 | 96 | ||
| 97 | /// Returns true if there is a device connected to port | ||
| 98 | bool DeviceConnected(std::size_t port); | ||
| 99 | |||
| 94 | std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue(); | 100 | std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue(); |
| 95 | const std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue() const; | 101 | const std::array<Common::SPSCQueue<GCPadStatus>, 4>& GetPadQueue() const; |
| 96 | 102 | ||
| @@ -100,7 +106,7 @@ public: | |||
| 100 | int GetOriginValue(int port, int axis) const; | 106 | int GetOriginValue(int port, int axis) const; |
| 101 | 107 | ||
| 102 | private: | 108 | private: |
| 103 | GCPadStatus GetPadStatus(int port, const std::array<u8, 37>& adapter_payload); | 109 | GCPadStatus GetPadStatus(std::size_t port, const std::array<u8, 37>& adapter_payload); |
| 104 | 110 | ||
| 105 | void PadToState(const GCPadStatus& pad, GCState& state); | 111 | void PadToState(const GCPadStatus& pad, GCState& state); |
| 106 | 112 | ||
| @@ -112,11 +118,8 @@ private: | |||
| 112 | /// Stop scanning for the adapter | 118 | /// Stop scanning for the adapter |
| 113 | void StopScanThread(); | 119 | void StopScanThread(); |
| 114 | 120 | ||
| 115 | /// Returns true if there is a device connected to port | ||
| 116 | bool DeviceConnected(int port); | ||
| 117 | |||
| 118 | /// Resets status of device connected to port | 121 | /// Resets status of device connected to port |
| 119 | void ResetDeviceType(int port); | 122 | void ResetDeviceType(std::size_t port); |
| 120 | 123 | ||
| 121 | /// Returns true if we successfully gain access to GC Adapter | 124 | /// Returns true if we successfully gain access to GC Adapter |
| 122 | bool CheckDeviceAccess(libusb_device* device); | 125 | bool CheckDeviceAccess(libusb_device* device); |
diff --git a/src/input_common/gcadapter/gc_poller.cpp b/src/input_common/gcadapter/gc_poller.cpp index ad321e933..96e22d3ad 100644 --- a/src/input_common/gcadapter/gc_poller.cpp +++ b/src/input_common/gcadapter/gc_poller.cpp | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | #include <list> | 6 | #include <list> |
| 7 | #include <mutex> | 7 | #include <mutex> |
| 8 | #include <utility> | 8 | #include <utility> |
| 9 | #include "common/assert.h" | ||
| 9 | #include "common/threadsafe_queue.h" | 10 | #include "common/threadsafe_queue.h" |
| 10 | #include "input_common/gcadapter/gc_adapter.h" | 11 | #include "input_common/gcadapter/gc_adapter.h" |
| 11 | #include "input_common/gcadapter/gc_poller.h" | 12 | #include "input_common/gcadapter/gc_poller.h" |
| @@ -20,7 +21,10 @@ public: | |||
| 20 | ~GCButton() override; | 21 | ~GCButton() override; |
| 21 | 22 | ||
| 22 | bool GetStatus() const override { | 23 | bool GetStatus() const override { |
| 23 | return gcadapter->GetPadState()[port].buttons.at(button); | 24 | if (gcadapter->DeviceConnected(port)) { |
| 25 | return gcadapter->GetPadState()[port].buttons.at(button); | ||
| 26 | } | ||
| 27 | return false; | ||
| 24 | } | 28 | } |
| 25 | 29 | ||
| 26 | private: | 30 | private: |
| @@ -37,14 +41,17 @@ public: | |||
| 37 | gcadapter(adapter), origin_value(adapter->GetOriginValue(port_, axis_)) {} | 41 | gcadapter(adapter), origin_value(adapter->GetOriginValue(port_, axis_)) {} |
| 38 | 42 | ||
| 39 | bool GetStatus() const override { | 43 | bool GetStatus() const override { |
| 40 | const float current_axis_value = gcadapter->GetPadState()[port].axes.at(axis); | 44 | if (gcadapter->DeviceConnected(port)) { |
| 41 | const float axis_value = (current_axis_value - origin_value) / 128.0f; | 45 | const float current_axis_value = gcadapter->GetPadState()[port].axes.at(axis); |
| 42 | if (trigger_if_greater) { | 46 | const float axis_value = (current_axis_value - origin_value) / 128.0f; |
| 43 | // TODO: Might be worthwile to set a slider for the trigger threshold. It is currently | 47 | if (trigger_if_greater) { |
| 44 | // always set to 0.5 in configure_input_player.cpp ZL/ZR HandleClick | 48 | // TODO: Might be worthwile to set a slider for the trigger threshold. It is |
| 45 | return axis_value > threshold; | 49 | // currently always set to 0.5 in configure_input_player.cpp ZL/ZR HandleClick |
| 50 | return axis_value > threshold; | ||
| 51 | } | ||
| 52 | return axis_value < -threshold; | ||
| 46 | } | 53 | } |
| 47 | return axis_value < -threshold; | 54 | return false; |
| 48 | } | 55 | } |
| 49 | 56 | ||
| 50 | private: | 57 | private: |
| @@ -90,9 +97,12 @@ std::unique_ptr<Input::ButtonDevice> GCButtonFactory::Create(const Common::Param | |||
| 90 | return std::make_unique<GCAxisButton>(port, axis, threshold, trigger_if_greater, | 97 | return std::make_unique<GCAxisButton>(port, axis, threshold, trigger_if_greater, |
| 91 | adapter.get()); | 98 | adapter.get()); |
| 92 | } | 99 | } |
| 100 | |||
| 101 | UNREACHABLE(); | ||
| 102 | return nullptr; | ||
| 93 | } | 103 | } |
| 94 | 104 | ||
| 95 | Common::ParamPackage GCButtonFactory::GetNextInput() { | 105 | Common::ParamPackage GCButtonFactory::GetNextInput() const { |
| 96 | Common::ParamPackage params; | 106 | Common::ParamPackage params; |
| 97 | GCAdapter::GCPadStatus pad; | 107 | GCAdapter::GCPadStatus pad; |
| 98 | auto& queue = adapter->GetPadQueue(); | 108 | auto& queue = adapter->GetPadQueue(); |
| @@ -145,12 +155,15 @@ public: | |||
| 145 | origin_value_y(adapter->GetOriginValue(port_, axis_y_)) {} | 155 | origin_value_y(adapter->GetOriginValue(port_, axis_y_)) {} |
| 146 | 156 | ||
| 147 | float GetAxis(int axis) const { | 157 | float GetAxis(int axis) const { |
| 148 | std::lock_guard lock{mutex}; | 158 | if (gcadapter->DeviceConnected(port)) { |
| 149 | const auto origin_value = axis % 2 == 0 ? origin_value_x : origin_value_y; | 159 | std::lock_guard lock{mutex}; |
| 150 | // division is not by a perfect 128 to account for some variance in center location | 160 | const auto origin_value = axis % 2 == 0 ? origin_value_x : origin_value_y; |
| 151 | // e.g. my device idled at 131 in X, 120 in Y, and full range of motion was in range | 161 | // division is not by a perfect 128 to account for some variance in center location |
| 152 | // [20-230] | 162 | // e.g. my device idled at 131 in X, 120 in Y, and full range of motion was in range |
| 153 | return (gcadapter->GetPadState()[port].axes.at(axis) - origin_value) / 95.0f; | 163 | // [20-230] |
| 164 | return (gcadapter->GetPadState()[port].axes.at(axis) - origin_value) / 95.0f; | ||
| 165 | } | ||
| 166 | return 0.0f; | ||
| 154 | } | 167 | } |
| 155 | 168 | ||
| 156 | std::pair<float, float> GetAnalog(int axis_x, int axis_y) const { | 169 | std::pair<float, float> GetAnalog(int axis_x, int axis_y) const { |
| @@ -250,7 +263,7 @@ Common::ParamPackage GCAnalogFactory::GetNextInput() { | |||
| 250 | const u8 axis = static_cast<u8>(pad.axis); | 263 | const u8 axis = static_cast<u8>(pad.axis); |
| 251 | if (analog_x_axis == -1) { | 264 | if (analog_x_axis == -1) { |
| 252 | analog_x_axis = axis; | 265 | analog_x_axis = axis; |
| 253 | controller_number = port; | 266 | controller_number = static_cast<int>(port); |
| 254 | } else if (analog_y_axis == -1 && analog_x_axis != axis && controller_number == port) { | 267 | } else if (analog_y_axis == -1 && analog_x_axis != axis && controller_number == port) { |
| 255 | analog_y_axis = axis; | 268 | analog_y_axis = axis; |
| 256 | } | 269 | } |
diff --git a/src/input_common/gcadapter/gc_poller.h b/src/input_common/gcadapter/gc_poller.h index e96af7d51..0527f328f 100644 --- a/src/input_common/gcadapter/gc_poller.h +++ b/src/input_common/gcadapter/gc_poller.h | |||
| @@ -25,7 +25,7 @@ public: | |||
| 25 | */ | 25 | */ |
| 26 | std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override; | 26 | std::unique_ptr<Input::ButtonDevice> Create(const Common::ParamPackage& params) override; |
| 27 | 27 | ||
| 28 | Common::ParamPackage GetNextInput(); | 28 | Common::ParamPackage GetNextInput() const; |
| 29 | 29 | ||
| 30 | /// For device input configuration/polling | 30 | /// For device input configuration/polling |
| 31 | void BeginConfiguration(); | 31 | void BeginConfiguration(); |
diff --git a/src/input_common/main.cpp b/src/input_common/main.cpp index fd0af1019..b9d5d0ec3 100644 --- a/src/input_common/main.cpp +++ b/src/input_common/main.cpp | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #include <memory> | 5 | #include <memory> |
| 6 | #include <thread> | 6 | #include <thread> |
| 7 | #include <libusb.h> | ||
| 8 | #include "common/param_package.h" | 7 | #include "common/param_package.h" |
| 9 | #include "input_common/analog_from_button.h" | 8 | #include "input_common/analog_from_button.h" |
| 10 | #include "input_common/gcadapter/gc_adapter.h" | 9 | #include "input_common/gcadapter/gc_adapter.h" |
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp index da5227058..e63c73c4f 100644 --- a/src/input_common/udp/client.cpp +++ b/src/input_common/udp/client.cpp | |||
| @@ -234,7 +234,7 @@ CalibrationConfigurationJob::CalibrationConfigurationJob( | |||
| 234 | std::function<void(Status)> status_callback, | 234 | std::function<void(Status)> status_callback, |
| 235 | std::function<void(u16, u16, u16, u16)> data_callback) { | 235 | std::function<void(u16, u16, u16, u16)> data_callback) { |
| 236 | 236 | ||
| 237 | std::thread([=] { | 237 | std::thread([=, this] { |
| 238 | constexpr u16 CALIBRATION_THRESHOLD = 100; | 238 | constexpr u16 CALIBRATION_THRESHOLD = 100; |
| 239 | 239 | ||
| 240 | u16 min_x{UINT16_MAX}; | 240 | u16 min_x{UINT16_MAX}; |
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..a862b2610 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt | |||
| @@ -24,10 +24,18 @@ 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 |
| 30 | configuration/configure_audio.ui | 32 | configuration/configure_audio.ui |
| 33 | configuration/configure_cpu.cpp | ||
| 34 | configuration/configure_cpu.h | ||
| 35 | configuration/configure_cpu.ui | ||
| 36 | configuration/configure_cpu_debug.cpp | ||
| 37 | configuration/configure_cpu_debug.h | ||
| 38 | configuration/configure_cpu_debug.ui | ||
| 31 | configuration/configure_debug.cpp | 39 | configuration/configure_debug.cpp |
| 32 | configuration/configure_debug.h | 40 | configuration/configure_debug.h |
| 33 | configuration/configure_debug.ui | 41 | configuration/configure_debug.ui |
| @@ -60,9 +68,12 @@ add_executable(yuzu | |||
| 60 | configuration/configure_mouse_advanced.cpp | 68 | configuration/configure_mouse_advanced.cpp |
| 61 | configuration/configure_mouse_advanced.h | 69 | configuration/configure_mouse_advanced.h |
| 62 | configuration/configure_mouse_advanced.ui | 70 | configuration/configure_mouse_advanced.ui |
| 63 | configuration/configure_per_general.cpp | 71 | configuration/configure_per_game.cpp |
| 64 | configuration/configure_per_general.h | 72 | configuration/configure_per_game.h |
| 65 | configuration/configure_per_general.ui | 73 | configuration/configure_per_game.ui |
| 74 | configuration/configure_per_game_addons.cpp | ||
| 75 | configuration/configure_per_game_addons.h | ||
| 76 | configuration/configure_per_game_addons.ui | ||
| 66 | configuration/configure_profile_manager.cpp | 77 | configuration/configure_profile_manager.cpp |
| 67 | configuration/configure_profile_manager.h | 78 | configuration/configure_profile_manager.h |
| 68 | configuration/configure_profile_manager.ui | 79 | configuration/configure_profile_manager.ui |
| @@ -93,11 +104,13 @@ add_executable(yuzu | |||
| 93 | game_list_p.h | 104 | game_list_p.h |
| 94 | game_list_worker.cpp | 105 | game_list_worker.cpp |
| 95 | game_list_worker.h | 106 | game_list_worker.h |
| 107 | hotkeys.cpp | ||
| 108 | hotkeys.h | ||
| 109 | install_dialog.cpp | ||
| 110 | install_dialog.h | ||
| 96 | loading_screen.cpp | 111 | loading_screen.cpp |
| 97 | loading_screen.h | 112 | loading_screen.h |
| 98 | loading_screen.ui | 113 | loading_screen.ui |
| 99 | hotkeys.cpp | ||
| 100 | hotkeys.h | ||
| 101 | main.cpp | 114 | main.cpp |
| 102 | main.h | 115 | main.h |
| 103 | main.ui | 116 | main.ui |
| @@ -147,7 +160,7 @@ endif() | |||
| 147 | create_target_directory_groups(yuzu) | 160 | create_target_directory_groups(yuzu) |
| 148 | 161 | ||
| 149 | target_link_libraries(yuzu PRIVATE common core input_common video_core) | 162 | target_link_libraries(yuzu PRIVATE common core input_common video_core) |
| 150 | target_link_libraries(yuzu PRIVATE Boost::boost glad Qt5::OpenGL Qt5::Widgets) | 163 | target_link_libraries(yuzu PRIVATE Boost::boost glad Qt5::Widgets) |
| 151 | target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) | 164 | target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads) |
| 152 | 165 | ||
| 153 | if (ENABLE_VULKAN AND NOT WIN32) | 166 | 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..9e9b38214 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 | } |
| @@ -497,22 +505,6 @@ void Config::ReadDataStorageValues() { | |||
| 497 | ReadSetting(QStringLiteral("gamecard_current_game"), false).toBool(); | 505 | ReadSetting(QStringLiteral("gamecard_current_game"), false).toBool(); |
| 498 | Settings::values.gamecard_path = | 506 | Settings::values.gamecard_path = |
| 499 | ReadSetting(QStringLiteral("gamecard_path"), QStringLiteral("")).toString().toStdString(); | 507 | ReadSetting(QStringLiteral("gamecard_path"), QStringLiteral("")).toString().toStdString(); |
| 500 | Settings::values.nand_total_size = static_cast<Settings::NANDTotalSize>( | ||
| 501 | ReadSetting(QStringLiteral("nand_total_size"), | ||
| 502 | QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDTotalSize::S29_1GB))) | ||
| 503 | .toULongLong()); | ||
| 504 | Settings::values.nand_user_size = static_cast<Settings::NANDUserSize>( | ||
| 505 | ReadSetting(QStringLiteral("nand_user_size"), | ||
| 506 | QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDUserSize::S26GB))) | ||
| 507 | .toULongLong()); | ||
| 508 | Settings::values.nand_system_size = static_cast<Settings::NANDSystemSize>( | ||
| 509 | ReadSetting(QStringLiteral("nand_system_size"), | ||
| 510 | QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDSystemSize::S2_5GB))) | ||
| 511 | .toULongLong()); | ||
| 512 | Settings::values.sdmc_size = static_cast<Settings::SDMCSize>( | ||
| 513 | ReadSetting(QStringLiteral("sdmc_size"), | ||
| 514 | QVariant::fromValue<u64>(static_cast<u64>(Settings::SDMCSize::S16GB))) | ||
| 515 | .toULongLong()); | ||
| 516 | 508 | ||
| 517 | qt_config->endGroup(); | 509 | qt_config->endGroup(); |
| 518 | } | 510 | } |
| @@ -532,8 +524,6 @@ void Config::ReadDebuggingValues() { | |||
| 532 | Settings::values.reporting_services = | 524 | Settings::values.reporting_services = |
| 533 | ReadSetting(QStringLiteral("reporting_services"), false).toBool(); | 525 | ReadSetting(QStringLiteral("reporting_services"), false).toBool(); |
| 534 | Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool(); | 526 | Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool(); |
| 535 | Settings::values.disable_cpu_opt = | ||
| 536 | ReadSetting(QStringLiteral("disable_cpu_opt"), false).toBool(); | ||
| 537 | Settings::values.disable_macro_jit = | 527 | Settings::values.disable_macro_jit = |
| 538 | ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool(); | 528 | ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool(); |
| 539 | 529 | ||
| @@ -625,35 +615,59 @@ void Config::ReadPathValues() { | |||
| 625 | qt_config->endGroup(); | 615 | qt_config->endGroup(); |
| 626 | } | 616 | } |
| 627 | 617 | ||
| 618 | void Config::ReadCpuValues() { | ||
| 619 | qt_config->beginGroup(QStringLiteral("Cpu")); | ||
| 620 | |||
| 621 | if (global) { | ||
| 622 | Settings::values.cpu_accuracy = static_cast<Settings::CPUAccuracy>( | ||
| 623 | ReadSetting(QStringLiteral("cpu_accuracy"), 0).toInt()); | ||
| 624 | |||
| 625 | Settings::values.cpuopt_page_tables = | ||
| 626 | ReadSetting(QStringLiteral("cpuopt_page_tables"), true).toBool(); | ||
| 627 | Settings::values.cpuopt_block_linking = | ||
| 628 | ReadSetting(QStringLiteral("cpuopt_block_linking"), true).toBool(); | ||
| 629 | Settings::values.cpuopt_return_stack_buffer = | ||
| 630 | ReadSetting(QStringLiteral("cpuopt_return_stack_buffer"), true).toBool(); | ||
| 631 | Settings::values.cpuopt_fast_dispatcher = | ||
| 632 | ReadSetting(QStringLiteral("cpuopt_fast_dispatcher"), true).toBool(); | ||
| 633 | Settings::values.cpuopt_context_elimination = | ||
| 634 | ReadSetting(QStringLiteral("cpuopt_context_elimination"), true).toBool(); | ||
| 635 | Settings::values.cpuopt_const_prop = | ||
| 636 | ReadSetting(QStringLiteral("cpuopt_const_prop"), true).toBool(); | ||
| 637 | Settings::values.cpuopt_misc_ir = | ||
| 638 | ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool(); | ||
| 639 | Settings::values.cpuopt_reduce_misalign_checks = | ||
| 640 | ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool(); | ||
| 641 | } | ||
| 642 | |||
| 643 | qt_config->endGroup(); | ||
| 644 | } | ||
| 645 | |||
| 628 | void Config::ReadRendererValues() { | 646 | void Config::ReadRendererValues() { |
| 629 | qt_config->beginGroup(QStringLiteral("Renderer")); | 647 | qt_config->beginGroup(QStringLiteral("Renderer")); |
| 630 | 648 | ||
| 631 | Settings::values.renderer_backend = | 649 | ReadSettingGlobal(Settings::values.renderer_backend, QStringLiteral("backend"), 0); |
| 632 | static_cast<Settings::RendererBackend>(ReadSetting(QStringLiteral("backend"), 0).toInt()); | 650 | ReadSettingGlobal(Settings::values.renderer_debug, QStringLiteral("debug"), false); |
| 633 | Settings::values.renderer_debug = ReadSetting(QStringLiteral("debug"), false).toBool(); | 651 | ReadSettingGlobal(Settings::values.vulkan_device, QStringLiteral("vulkan_device"), 0); |
| 634 | Settings::values.vulkan_device = ReadSetting(QStringLiteral("vulkan_device"), 0).toInt(); | 652 | ReadSettingGlobal(Settings::values.aspect_ratio, QStringLiteral("aspect_ratio"), 0); |
| 635 | Settings::values.aspect_ratio = ReadSetting(QStringLiteral("aspect_ratio"), 0).toInt(); | 653 | ReadSettingGlobal(Settings::values.max_anisotropy, QStringLiteral("max_anisotropy"), 0); |
| 636 | Settings::values.max_anisotropy = ReadSetting(QStringLiteral("max_anisotropy"), 0).toInt(); | 654 | ReadSettingGlobal(Settings::values.use_frame_limit, QStringLiteral("use_frame_limit"), true); |
| 637 | Settings::values.use_frame_limit = | 655 | ReadSettingGlobal(Settings::values.frame_limit, QStringLiteral("frame_limit"), 100); |
| 638 | ReadSetting(QStringLiteral("use_frame_limit"), true).toBool(); | 656 | ReadSettingGlobal(Settings::values.use_disk_shader_cache, |
| 639 | Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toUInt(); | 657 | QStringLiteral("use_disk_shader_cache"), true); |
| 640 | Settings::values.use_disk_shader_cache = | 658 | ReadSettingGlobal(Settings::values.gpu_accuracy, QStringLiteral("gpu_accuracy"), 0); |
| 641 | ReadSetting(QStringLiteral("use_disk_shader_cache"), true).toBool(); | 659 | ReadSettingGlobal(Settings::values.use_asynchronous_gpu_emulation, |
| 642 | const int gpu_accuracy_level = ReadSetting(QStringLiteral("gpu_accuracy"), 0).toInt(); | 660 | QStringLiteral("use_asynchronous_gpu_emulation"), false); |
| 643 | Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level); | 661 | ReadSettingGlobal(Settings::values.use_vsync, QStringLiteral("use_vsync"), true); |
| 644 | Settings::values.use_asynchronous_gpu_emulation = | 662 | ReadSettingGlobal(Settings::values.use_assembly_shaders, QStringLiteral("use_assembly_shaders"), |
| 645 | ReadSetting(QStringLiteral("use_asynchronous_gpu_emulation"), false).toBool(); | 663 | false); |
| 646 | Settings::values.use_vsync = ReadSetting(QStringLiteral("use_vsync"), true).toBool(); | 664 | ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time"), |
| 647 | Settings::values.use_assembly_shaders = | 665 | true); |
| 648 | ReadSetting(QStringLiteral("use_assembly_shaders"), false).toBool(); | 666 | ReadSettingGlobal(Settings::values.force_30fps_mode, QStringLiteral("force_30fps_mode"), false); |
| 649 | Settings::values.use_fast_gpu_time = | 667 | |
| 650 | ReadSetting(QStringLiteral("use_fast_gpu_time"), true).toBool(); | 668 | ReadSettingGlobal(Settings::values.bg_red, QStringLiteral("bg_red"), 0.0); |
| 651 | Settings::values.force_30fps_mode = | 669 | ReadSettingGlobal(Settings::values.bg_green, QStringLiteral("bg_green"), 0.0); |
| 652 | ReadSetting(QStringLiteral("force_30fps_mode"), false).toBool(); | 670 | 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 | 671 | ||
| 658 | qt_config->endGroup(); | 672 | qt_config->endGroup(); |
| 659 | } | 673 | } |
| @@ -682,35 +696,45 @@ void Config::ReadShortcutValues() { | |||
| 682 | void Config::ReadSystemValues() { | 696 | void Config::ReadSystemValues() { |
| 683 | qt_config->beginGroup(QStringLiteral("System")); | 697 | qt_config->beginGroup(QStringLiteral("System")); |
| 684 | 698 | ||
| 685 | Settings::values.use_docked_mode = | 699 | ReadSettingGlobal(Settings::values.current_user, QStringLiteral("current_user"), 0); |
| 686 | ReadSetting(QStringLiteral("use_docked_mode"), false).toBool(); | 700 | Settings::values.current_user = |
| 687 | 701 | 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 | 702 | ||
| 691 | Settings::values.language_index = ReadSetting(QStringLiteral("language_index"), 1).toInt(); | 703 | ReadSettingGlobal(Settings::values.language_index, QStringLiteral("language_index"), 1); |
| 692 | 704 | ||
| 693 | Settings::values.region_index = ReadSetting(QStringLiteral("region_index"), 1).toInt(); | 705 | ReadSettingGlobal(Settings::values.region_index, QStringLiteral("region_index"), 1); |
| 694 | 706 | ||
| 695 | Settings::values.time_zone_index = ReadSetting(QStringLiteral("time_zone_index"), 0).toInt(); | 707 | ReadSettingGlobal(Settings::values.time_zone_index, QStringLiteral("time_zone_index"), 0); |
| 696 | 708 | ||
| 697 | const auto rng_seed_enabled = ReadSetting(QStringLiteral("rng_seed_enabled"), false).toBool(); | 709 | bool rng_seed_enabled; |
| 698 | if (rng_seed_enabled) { | 710 | ReadSettingGlobal(rng_seed_enabled, QStringLiteral("rng_seed_enabled"), false); |
| 699 | Settings::values.rng_seed = ReadSetting(QStringLiteral("rng_seed"), 0).toULongLong(); | 711 | bool rng_seed_global = |
| 700 | } else { | 712 | global || qt_config->value(QStringLiteral("rng_seed/use_global"), true).toBool(); |
| 701 | Settings::values.rng_seed = std::nullopt; | 713 | Settings::values.rng_seed.SetGlobal(rng_seed_global); |
| 714 | if (global || !rng_seed_global) { | ||
| 715 | if (rng_seed_enabled) { | ||
| 716 | Settings::values.rng_seed.SetValue( | ||
| 717 | ReadSetting(QStringLiteral("rng_seed"), 0).toULongLong()); | ||
| 718 | } else { | ||
| 719 | Settings::values.rng_seed.SetValue(std::nullopt); | ||
| 720 | } | ||
| 702 | } | 721 | } |
| 703 | 722 | ||
| 704 | const auto custom_rtc_enabled = | 723 | bool custom_rtc_enabled; |
| 705 | ReadSetting(QStringLiteral("custom_rtc_enabled"), false).toBool(); | 724 | ReadSettingGlobal(custom_rtc_enabled, QStringLiteral("custom_rtc_enabled"), false); |
| 706 | if (custom_rtc_enabled) { | 725 | bool custom_rtc_global = |
| 707 | Settings::values.custom_rtc = | 726 | global || qt_config->value(QStringLiteral("custom_rtc/use_global"), true).toBool(); |
| 708 | std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong()); | 727 | Settings::values.custom_rtc.SetGlobal(custom_rtc_global); |
| 709 | } else { | 728 | if (global || !custom_rtc_global) { |
| 710 | Settings::values.custom_rtc = std::nullopt; | 729 | if (custom_rtc_enabled) { |
| 730 | Settings::values.custom_rtc.SetValue( | ||
| 731 | std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong())); | ||
| 732 | } else { | ||
| 733 | Settings::values.custom_rtc.SetValue(std::nullopt); | ||
| 734 | } | ||
| 711 | } | 735 | } |
| 712 | 736 | ||
| 713 | Settings::values.sound_index = ReadSetting(QStringLiteral("sound_index"), 1).toInt(); | 737 | ReadSettingGlobal(Settings::values.sound_index, QStringLiteral("sound_index"), 1); |
| 714 | 738 | ||
| 715 | qt_config->endGroup(); | 739 | qt_config->endGroup(); |
| 716 | } | 740 | } |
| @@ -804,18 +828,21 @@ void Config::ReadWebServiceValues() { | |||
| 804 | } | 828 | } |
| 805 | 829 | ||
| 806 | void Config::ReadValues() { | 830 | void Config::ReadValues() { |
| 807 | ReadControlValues(); | 831 | if (global) { |
| 832 | ReadControlValues(); | ||
| 833 | ReadDataStorageValues(); | ||
| 834 | ReadDebuggingValues(); | ||
| 835 | ReadDisabledAddOnValues(); | ||
| 836 | ReadServiceValues(); | ||
| 837 | ReadUIValues(); | ||
| 838 | ReadWebServiceValues(); | ||
| 839 | ReadMiscellaneousValues(); | ||
| 840 | } | ||
| 808 | ReadCoreValues(); | 841 | ReadCoreValues(); |
| 842 | ReadCpuValues(); | ||
| 809 | ReadRendererValues(); | 843 | ReadRendererValues(); |
| 810 | ReadAudioValues(); | 844 | ReadAudioValues(); |
| 811 | ReadDataStorageValues(); | ||
| 812 | ReadSystemValues(); | 845 | ReadSystemValues(); |
| 813 | ReadMiscellaneousValues(); | ||
| 814 | ReadDebuggingValues(); | ||
| 815 | ReadWebServiceValues(); | ||
| 816 | ReadServiceValues(); | ||
| 817 | ReadDisabledAddOnValues(); | ||
| 818 | ReadUIValues(); | ||
| 819 | } | 846 | } |
| 820 | 847 | ||
| 821 | void Config::SavePlayerValues() { | 848 | void Config::SavePlayerValues() { |
| @@ -902,30 +929,36 @@ void Config::SaveTouchscreenValues() { | |||
| 902 | } | 929 | } |
| 903 | 930 | ||
| 904 | void Config::SaveValues() { | 931 | void Config::SaveValues() { |
| 905 | SaveControlValues(); | 932 | if (global) { |
| 933 | SaveControlValues(); | ||
| 934 | SaveDataStorageValues(); | ||
| 935 | SaveDebuggingValues(); | ||
| 936 | SaveDisabledAddOnValues(); | ||
| 937 | SaveServiceValues(); | ||
| 938 | SaveUIValues(); | ||
| 939 | SaveWebServiceValues(); | ||
| 940 | SaveMiscellaneousValues(); | ||
| 941 | } | ||
| 906 | SaveCoreValues(); | 942 | SaveCoreValues(); |
| 943 | SaveCpuValues(); | ||
| 907 | SaveRendererValues(); | 944 | SaveRendererValues(); |
| 908 | SaveAudioValues(); | 945 | SaveAudioValues(); |
| 909 | SaveDataStorageValues(); | ||
| 910 | SaveSystemValues(); | 946 | SaveSystemValues(); |
| 911 | SaveMiscellaneousValues(); | ||
| 912 | SaveDebuggingValues(); | ||
| 913 | SaveWebServiceValues(); | ||
| 914 | SaveServiceValues(); | ||
| 915 | SaveDisabledAddOnValues(); | ||
| 916 | SaveUIValues(); | ||
| 917 | } | 947 | } |
| 918 | 948 | ||
| 919 | void Config::SaveAudioValues() { | 949 | void Config::SaveAudioValues() { |
| 920 | qt_config->beginGroup(QStringLiteral("Audio")); | 950 | qt_config->beginGroup(QStringLiteral("Audio")); |
| 921 | 951 | ||
| 922 | WriteSetting(QStringLiteral("output_engine"), QString::fromStdString(Settings::values.sink_id), | 952 | if (global) { |
| 923 | QStringLiteral("auto")); | 953 | WriteSetting(QStringLiteral("output_engine"), |
| 924 | WriteSetting(QStringLiteral("enable_audio_stretching"), | 954 | QString::fromStdString(Settings::values.sink_id), QStringLiteral("auto")); |
| 925 | Settings::values.enable_audio_stretching, true); | 955 | WriteSetting(QStringLiteral("output_device"), |
| 926 | WriteSetting(QStringLiteral("output_device"), | 956 | QString::fromStdString(Settings::values.audio_device_id), |
| 927 | QString::fromStdString(Settings::values.audio_device_id), QStringLiteral("auto")); | 957 | QStringLiteral("auto")); |
| 928 | WriteSetting(QStringLiteral("volume"), Settings::values.volume, 1.0f); | 958 | } |
| 959 | WriteSettingGlobal(QStringLiteral("enable_audio_stretching"), | ||
| 960 | Settings::values.enable_audio_stretching, true); | ||
| 961 | WriteSettingGlobal(QStringLiteral("volume"), Settings::values.volume, 1.0f); | ||
| 929 | 962 | ||
| 930 | qt_config->endGroup(); | 963 | qt_config->endGroup(); |
| 931 | } | 964 | } |
| @@ -948,6 +981,7 @@ void Config::SaveControlValues() { | |||
| 948 | WriteSetting(QStringLiteral("udp_input_port"), Settings::values.udp_input_port, | 981 | WriteSetting(QStringLiteral("udp_input_port"), Settings::values.udp_input_port, |
| 949 | InputCommon::CemuhookUDP::DEFAULT_PORT); | 982 | InputCommon::CemuhookUDP::DEFAULT_PORT); |
| 950 | WriteSetting(QStringLiteral("udp_pad_index"), Settings::values.udp_pad_index, 0); | 983 | WriteSetting(QStringLiteral("udp_pad_index"), Settings::values.udp_pad_index, 0); |
| 984 | WriteSetting(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false); | ||
| 951 | 985 | ||
| 952 | qt_config->endGroup(); | 986 | qt_config->endGroup(); |
| 953 | } | 987 | } |
| @@ -955,7 +989,7 @@ void Config::SaveControlValues() { | |||
| 955 | void Config::SaveCoreValues() { | 989 | void Config::SaveCoreValues() { |
| 956 | qt_config->beginGroup(QStringLiteral("Core")); | 990 | qt_config->beginGroup(QStringLiteral("Core")); |
| 957 | 991 | ||
| 958 | WriteSetting(QStringLiteral("use_multi_core"), Settings::values.use_multi_core, false); | 992 | WriteSettingGlobal(QStringLiteral("use_multi_core"), Settings::values.use_multi_core, false); |
| 959 | 993 | ||
| 960 | qt_config->endGroup(); | 994 | qt_config->endGroup(); |
| 961 | } | 995 | } |
| @@ -984,18 +1018,7 @@ void Config::SaveDataStorageValues() { | |||
| 984 | false); | 1018 | false); |
| 985 | WriteSetting(QStringLiteral("gamecard_path"), | 1019 | WriteSetting(QStringLiteral("gamecard_path"), |
| 986 | QString::fromStdString(Settings::values.gamecard_path), QStringLiteral("")); | 1020 | QString::fromStdString(Settings::values.gamecard_path), QStringLiteral("")); |
| 987 | WriteSetting(QStringLiteral("nand_total_size"), | 1021 | |
| 988 | QVariant::fromValue<u64>(static_cast<u64>(Settings::values.nand_total_size)), | ||
| 989 | QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDTotalSize::S29_1GB))); | ||
| 990 | WriteSetting(QStringLiteral("nand_user_size"), | ||
| 991 | QVariant::fromValue<u64>(static_cast<u64>(Settings::values.nand_user_size)), | ||
| 992 | QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDUserSize::S26GB))); | ||
| 993 | WriteSetting(QStringLiteral("nand_system_size"), | ||
| 994 | QVariant::fromValue<u64>(static_cast<u64>(Settings::values.nand_system_size)), | ||
| 995 | QVariant::fromValue<u64>(static_cast<u64>(Settings::NANDSystemSize::S2_5GB))); | ||
| 996 | WriteSetting(QStringLiteral("sdmc_size"), | ||
| 997 | QVariant::fromValue<u64>(static_cast<u64>(Settings::values.sdmc_size)), | ||
| 998 | QVariant::fromValue<u64>(static_cast<u64>(Settings::SDMCSize::S16GB))); | ||
| 999 | qt_config->endGroup(); | 1022 | qt_config->endGroup(); |
| 1000 | } | 1023 | } |
| 1001 | 1024 | ||
| @@ -1011,7 +1034,6 @@ void Config::SaveDebuggingValues() { | |||
| 1011 | WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false); | 1034 | WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false); |
| 1012 | WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false); | 1035 | WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false); |
| 1013 | WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false); | 1036 | WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false); |
| 1014 | WriteSetting(QStringLiteral("disable_cpu_opt"), Settings::values.disable_cpu_opt, false); | ||
| 1015 | WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false); | 1037 | WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false); |
| 1016 | 1038 | ||
| 1017 | qt_config->endGroup(); | 1039 | qt_config->endGroup(); |
| @@ -1075,32 +1097,63 @@ void Config::SavePathValues() { | |||
| 1075 | qt_config->endGroup(); | 1097 | qt_config->endGroup(); |
| 1076 | } | 1098 | } |
| 1077 | 1099 | ||
| 1100 | void Config::SaveCpuValues() { | ||
| 1101 | qt_config->beginGroup(QStringLiteral("Cpu")); | ||
| 1102 | |||
| 1103 | if (global) { | ||
| 1104 | WriteSetting(QStringLiteral("cpu_accuracy"), | ||
| 1105 | static_cast<int>(Settings::values.cpu_accuracy), 0); | ||
| 1106 | |||
| 1107 | WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables, | ||
| 1108 | true); | ||
| 1109 | WriteSetting(QStringLiteral("cpuopt_block_linking"), Settings::values.cpuopt_block_linking, | ||
| 1110 | true); | ||
| 1111 | WriteSetting(QStringLiteral("cpuopt_return_stack_buffer"), | ||
| 1112 | Settings::values.cpuopt_return_stack_buffer, true); | ||
| 1113 | WriteSetting(QStringLiteral("cpuopt_fast_dispatcher"), | ||
| 1114 | Settings::values.cpuopt_fast_dispatcher, true); | ||
| 1115 | WriteSetting(QStringLiteral("cpuopt_context_elimination"), | ||
| 1116 | Settings::values.cpuopt_context_elimination, true); | ||
| 1117 | WriteSetting(QStringLiteral("cpuopt_const_prop"), Settings::values.cpuopt_const_prop, true); | ||
| 1118 | WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true); | ||
| 1119 | WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), | ||
| 1120 | Settings::values.cpuopt_reduce_misalign_checks, true); | ||
| 1121 | } | ||
| 1122 | |||
| 1123 | qt_config->endGroup(); | ||
| 1124 | } | ||
| 1125 | |||
| 1078 | void Config::SaveRendererValues() { | 1126 | void Config::SaveRendererValues() { |
| 1079 | qt_config->beginGroup(QStringLiteral("Renderer")); | 1127 | qt_config->beginGroup(QStringLiteral("Renderer")); |
| 1080 | 1128 | ||
| 1081 | WriteSetting(QStringLiteral("backend"), static_cast<int>(Settings::values.renderer_backend), 0); | 1129 | WriteSettingGlobal(QStringLiteral("backend"), |
| 1130 | static_cast<int>(Settings::values.renderer_backend.GetValue(global)), | ||
| 1131 | Settings::values.renderer_backend.UsingGlobal(), 0); | ||
| 1082 | WriteSetting(QStringLiteral("debug"), Settings::values.renderer_debug, false); | 1132 | WriteSetting(QStringLiteral("debug"), Settings::values.renderer_debug, false); |
| 1083 | WriteSetting(QStringLiteral("vulkan_device"), Settings::values.vulkan_device, 0); | 1133 | WriteSettingGlobal(QStringLiteral("vulkan_device"), Settings::values.vulkan_device, 0); |
| 1084 | WriteSetting(QStringLiteral("aspect_ratio"), Settings::values.aspect_ratio, 0); | 1134 | WriteSettingGlobal(QStringLiteral("aspect_ratio"), Settings::values.aspect_ratio, 0); |
| 1085 | WriteSetting(QStringLiteral("max_anisotropy"), Settings::values.max_anisotropy, 0); | 1135 | WriteSettingGlobal(QStringLiteral("max_anisotropy"), Settings::values.max_anisotropy, 0); |
| 1086 | WriteSetting(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true); | 1136 | WriteSettingGlobal(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true); |
| 1087 | WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100); | 1137 | WriteSettingGlobal(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100); |
| 1088 | WriteSetting(QStringLiteral("use_disk_shader_cache"), Settings::values.use_disk_shader_cache, | 1138 | WriteSettingGlobal(QStringLiteral("use_disk_shader_cache"), |
| 1089 | true); | 1139 | Settings::values.use_disk_shader_cache, true); |
| 1090 | WriteSetting(QStringLiteral("gpu_accuracy"), static_cast<int>(Settings::values.gpu_accuracy), | 1140 | WriteSettingGlobal(QStringLiteral("gpu_accuracy"), |
| 1091 | 0); | 1141 | static_cast<int>(Settings::values.gpu_accuracy.GetValue(global)), |
| 1092 | WriteSetting(QStringLiteral("use_asynchronous_gpu_emulation"), | 1142 | Settings::values.gpu_accuracy.UsingGlobal(), 0); |
| 1093 | Settings::values.use_asynchronous_gpu_emulation, false); | 1143 | WriteSettingGlobal(QStringLiteral("use_asynchronous_gpu_emulation"), |
| 1094 | WriteSetting(QStringLiteral("use_vsync"), Settings::values.use_vsync, true); | 1144 | Settings::values.use_asynchronous_gpu_emulation, false); |
| 1095 | WriteSetting(QStringLiteral("use_assembly_shaders"), Settings::values.use_assembly_shaders, | 1145 | WriteSettingGlobal(QStringLiteral("use_vsync"), Settings::values.use_vsync, true); |
| 1096 | false); | 1146 | WriteSettingGlobal(QStringLiteral("use_assembly_shaders"), |
| 1097 | WriteSetting(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time, true); | 1147 | Settings::values.use_assembly_shaders, false); |
| 1098 | WriteSetting(QStringLiteral("force_30fps_mode"), Settings::values.force_30fps_mode, false); | 1148 | WriteSettingGlobal(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time, |
| 1149 | true); | ||
| 1150 | WriteSettingGlobal(QStringLiteral("force_30fps_mode"), Settings::values.force_30fps_mode, | ||
| 1151 | false); | ||
| 1099 | 1152 | ||
| 1100 | // Cast to double because Qt's written float values are not human-readable | 1153 | // 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); | 1154 | WriteSettingGlobal(QStringLiteral("bg_red"), Settings::values.bg_red, 0.0); |
| 1102 | WriteSetting(QStringLiteral("bg_green"), static_cast<double>(Settings::values.bg_green), 0.0); | 1155 | WriteSettingGlobal(QStringLiteral("bg_green"), Settings::values.bg_green, 0.0); |
| 1103 | WriteSetting(QStringLiteral("bg_blue"), static_cast<double>(Settings::values.bg_blue), 0.0); | 1156 | WriteSettingGlobal(QStringLiteral("bg_blue"), Settings::values.bg_blue, 0.0); |
| 1104 | 1157 | ||
| 1105 | qt_config->endGroup(); | 1158 | qt_config->endGroup(); |
| 1106 | } | 1159 | } |
| @@ -1128,23 +1181,28 @@ void Config::SaveShortcutValues() { | |||
| 1128 | void Config::SaveSystemValues() { | 1181 | void Config::SaveSystemValues() { |
| 1129 | qt_config->beginGroup(QStringLiteral("System")); | 1182 | qt_config->beginGroup(QStringLiteral("System")); |
| 1130 | 1183 | ||
| 1131 | WriteSetting(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false); | ||
| 1132 | WriteSetting(QStringLiteral("current_user"), Settings::values.current_user, 0); | 1184 | WriteSetting(QStringLiteral("current_user"), Settings::values.current_user, 0); |
| 1133 | WriteSetting(QStringLiteral("language_index"), Settings::values.language_index, 1); | 1185 | WriteSettingGlobal(QStringLiteral("language_index"), Settings::values.language_index, 1); |
| 1134 | WriteSetting(QStringLiteral("region_index"), Settings::values.region_index, 1); | 1186 | WriteSettingGlobal(QStringLiteral("region_index"), Settings::values.region_index, 1); |
| 1135 | WriteSetting(QStringLiteral("time_zone_index"), Settings::values.time_zone_index, 0); | 1187 | WriteSettingGlobal(QStringLiteral("time_zone_index"), Settings::values.time_zone_index, 0); |
| 1136 | 1188 | ||
| 1137 | WriteSetting(QStringLiteral("rng_seed_enabled"), Settings::values.rng_seed.has_value(), false); | 1189 | WriteSettingGlobal(QStringLiteral("rng_seed_enabled"), |
| 1138 | WriteSetting(QStringLiteral("rng_seed"), Settings::values.rng_seed.value_or(0), 0); | 1190 | Settings::values.rng_seed.GetValue(global).has_value(), |
| 1139 | 1191 | Settings::values.rng_seed.UsingGlobal(), false); | |
| 1140 | WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(), | 1192 | WriteSettingGlobal(QStringLiteral("rng_seed"), |
| 1141 | false); | 1193 | Settings::values.rng_seed.GetValue(global).value_or(0), |
| 1142 | WriteSetting(QStringLiteral("custom_rtc"), | 1194 | Settings::values.rng_seed.UsingGlobal(), 0); |
| 1143 | QVariant::fromValue<long long>( | 1195 | |
| 1144 | Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()), | 1196 | WriteSettingGlobal(QStringLiteral("custom_rtc_enabled"), |
| 1145 | 0); | 1197 | Settings::values.custom_rtc.GetValue(global).has_value(), |
| 1146 | 1198 | Settings::values.custom_rtc.UsingGlobal(), false); | |
| 1147 | WriteSetting(QStringLiteral("sound_index"), Settings::values.sound_index, 1); | 1199 | WriteSettingGlobal( |
| 1200 | QStringLiteral("custom_rtc"), | ||
| 1201 | QVariant::fromValue<long long>( | ||
| 1202 | Settings::values.custom_rtc.GetValue(global).value_or(std::chrono::seconds{}).count()), | ||
| 1203 | Settings::values.custom_rtc.UsingGlobal(), 0); | ||
| 1204 | |||
| 1205 | WriteSettingGlobal(QStringLiteral("sound_index"), Settings::values.sound_index, 1); | ||
| 1148 | 1206 | ||
| 1149 | qt_config->endGroup(); | 1207 | qt_config->endGroup(); |
| 1150 | } | 1208 | } |
| @@ -1236,6 +1294,34 @@ QVariant Config::ReadSetting(const QString& name, const QVariant& default_value) | |||
| 1236 | return result; | 1294 | return result; |
| 1237 | } | 1295 | } |
| 1238 | 1296 | ||
| 1297 | template <typename Type> | ||
| 1298 | void Config::ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name) { | ||
| 1299 | const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool(); | ||
| 1300 | setting.SetGlobal(use_global); | ||
| 1301 | if (global || !use_global) { | ||
| 1302 | setting.SetValue(ReadSetting(name).value<Type>()); | ||
| 1303 | } | ||
| 1304 | } | ||
| 1305 | |||
| 1306 | template <typename Type> | ||
| 1307 | void Config::ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name, | ||
| 1308 | const QVariant& default_value) { | ||
| 1309 | const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool(); | ||
| 1310 | setting.SetGlobal(use_global); | ||
| 1311 | if (global || !use_global) { | ||
| 1312 | setting.SetValue(ReadSetting(name, default_value).value<Type>()); | ||
| 1313 | } | ||
| 1314 | } | ||
| 1315 | |||
| 1316 | template <typename Type> | ||
| 1317 | void Config::ReadSettingGlobal(Type& setting, const QString& name, | ||
| 1318 | const QVariant& default_value) const { | ||
| 1319 | const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool(); | ||
| 1320 | if (global || !use_global) { | ||
| 1321 | setting = ReadSetting(name, default_value).value<Type>(); | ||
| 1322 | } | ||
| 1323 | } | ||
| 1324 | |||
| 1239 | void Config::WriteSetting(const QString& name, const QVariant& value) { | 1325 | void Config::WriteSetting(const QString& name, const QVariant& value) { |
| 1240 | qt_config->setValue(name, value); | 1326 | qt_config->setValue(name, value); |
| 1241 | } | 1327 | } |
| @@ -1246,6 +1332,40 @@ void Config::WriteSetting(const QString& name, const QVariant& value, | |||
| 1246 | qt_config->setValue(name, value); | 1332 | qt_config->setValue(name, value); |
| 1247 | } | 1333 | } |
| 1248 | 1334 | ||
| 1335 | template <typename Type> | ||
| 1336 | void Config::WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting) { | ||
| 1337 | if (!global) { | ||
| 1338 | qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal()); | ||
| 1339 | } | ||
| 1340 | if (global || !setting.UsingGlobal()) { | ||
| 1341 | qt_config->setValue(name, setting.GetValue(global)); | ||
| 1342 | } | ||
| 1343 | } | ||
| 1344 | |||
| 1345 | template <typename Type> | ||
| 1346 | void Config::WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting, | ||
| 1347 | const QVariant& default_value) { | ||
| 1348 | if (!global) { | ||
| 1349 | qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal()); | ||
| 1350 | } | ||
| 1351 | if (global || !setting.UsingGlobal()) { | ||
| 1352 | qt_config->setValue(name + QStringLiteral("/default"), | ||
| 1353 | setting.GetValue(global) == default_value.value<Type>()); | ||
| 1354 | qt_config->setValue(name, setting.GetValue(global)); | ||
| 1355 | } | ||
| 1356 | } | ||
| 1357 | |||
| 1358 | void Config::WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global, | ||
| 1359 | const QVariant& default_value) { | ||
| 1360 | if (!global) { | ||
| 1361 | qt_config->setValue(name + QStringLiteral("/use_global"), use_global); | ||
| 1362 | } | ||
| 1363 | if (global || !use_global) { | ||
| 1364 | qt_config->setValue(name + QStringLiteral("/default"), value == default_value); | ||
| 1365 | qt_config->setValue(name, value); | ||
| 1366 | } | ||
| 1367 | } | ||
| 1368 | |||
| 1249 | void Config::Reload() { | 1369 | void Config::Reload() { |
| 1250 | ReadValues(); | 1370 | ReadValues(); |
| 1251 | // To apply default value changes | 1371 | // To apply default value changes |
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 09316382c..8e815f829 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(); |
| @@ -48,6 +49,7 @@ private: | |||
| 48 | void ReadDisabledAddOnValues(); | 49 | void ReadDisabledAddOnValues(); |
| 49 | void ReadMiscellaneousValues(); | 50 | void ReadMiscellaneousValues(); |
| 50 | void ReadPathValues(); | 51 | void ReadPathValues(); |
| 52 | void ReadCpuValues(); | ||
| 51 | void ReadRendererValues(); | 53 | void ReadRendererValues(); |
| 52 | void ReadShortcutValues(); | 54 | void ReadShortcutValues(); |
| 53 | void ReadSystemValues(); | 55 | void ReadSystemValues(); |
| @@ -72,6 +74,7 @@ private: | |||
| 72 | void SaveDisabledAddOnValues(); | 74 | void SaveDisabledAddOnValues(); |
| 73 | void SaveMiscellaneousValues(); | 75 | void SaveMiscellaneousValues(); |
| 74 | void SavePathValues(); | 76 | void SavePathValues(); |
| 77 | void SaveCpuValues(); | ||
| 75 | void SaveRendererValues(); | 78 | void SaveRendererValues(); |
| 76 | void SaveShortcutValues(); | 79 | void SaveShortcutValues(); |
| 77 | void SaveSystemValues(); | 80 | void SaveSystemValues(); |
| @@ -82,9 +85,33 @@ private: | |||
| 82 | 85 | ||
| 83 | QVariant ReadSetting(const QString& name) const; | 86 | QVariant ReadSetting(const QString& name) const; |
| 84 | QVariant ReadSetting(const QString& name, const QVariant& default_value) const; | 87 | QVariant ReadSetting(const QString& name, const QVariant& default_value) const; |
| 88 | // Templated ReadSettingGlobal functions will also look for the use_global setting and set | ||
| 89 | // both the value and the global state properly | ||
| 90 | template <typename Type> | ||
| 91 | void ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name); | ||
| 92 | template <typename Type> | ||
| 93 | void ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name, | ||
| 94 | const QVariant& default_value); | ||
| 95 | template <typename Type> | ||
| 96 | void ReadSettingGlobal(Type& setting, const QString& name, const QVariant& default_value) const; | ||
| 97 | // Templated WriteSettingGlobal functions will also write the global state if needed and will | ||
| 98 | // skip writing the actual setting if it defers to the global value | ||
| 85 | void WriteSetting(const QString& name, const QVariant& value); | 99 | void WriteSetting(const QString& name, const QVariant& value); |
| 86 | void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value); | 100 | void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value); |
| 101 | template <typename Type> | ||
| 102 | void WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting); | ||
| 103 | template <typename Type> | ||
| 104 | void WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting, | ||
| 105 | const QVariant& default_value); | ||
| 106 | void WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global, | ||
| 107 | const QVariant& default_value); | ||
| 87 | 108 | ||
| 88 | std::unique_ptr<QSettings> qt_config; | 109 | std::unique_ptr<QSettings> qt_config; |
| 89 | std::string qt_config_loc; | 110 | std::string qt_config_loc; |
| 111 | |||
| 112 | bool global; | ||
| 90 | }; | 113 | }; |
| 114 | |||
| 115 | // These metatype declarations cannot be in core/settings.h because core is devoid of QT | ||
| 116 | Q_DECLARE_METATYPE(Settings::RendererBackend); | ||
| 117 | 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.ui b/src/yuzu/configuration/configure.ui index 9aec1bd09..5f5d8e571 100644 --- a/src/yuzu/configuration/configure.ui +++ b/src/yuzu/configuration/configure.ui | |||
| @@ -78,6 +78,16 @@ | |||
| 78 | <string>Hotkeys</string> | 78 | <string>Hotkeys</string> |
| 79 | </attribute> | 79 | </attribute> |
| 80 | </widget> | 80 | </widget> |
| 81 | <widget class="ConfigureCpu" name="cpuTab"> | ||
| 82 | <attribute name="title"> | ||
| 83 | <string>CPU</string> | ||
| 84 | </attribute> | ||
| 85 | </widget> | ||
| 86 | <widget class="ConfigureCpuDebug" name="cpuDebugTab"> | ||
| 87 | <attribute name="title"> | ||
| 88 | <string>Debug</string> | ||
| 89 | </attribute> | ||
| 90 | </widget> | ||
| 81 | <widget class="ConfigureGraphics" name="graphicsTab"> | 91 | <widget class="ConfigureGraphics" name="graphicsTab"> |
| 82 | <attribute name="title"> | 92 | <attribute name="title"> |
| 83 | <string>Graphics</string> | 93 | <string>Graphics</string> |
| @@ -159,6 +169,18 @@ | |||
| 159 | <container>1</container> | 169 | <container>1</container> |
| 160 | </customwidget> | 170 | </customwidget> |
| 161 | <customwidget> | 171 | <customwidget> |
| 172 | <class>ConfigureCpu</class> | ||
| 173 | <extends>QWidget</extends> | ||
| 174 | <header>configuration/configure_cpu.h</header> | ||
| 175 | <container>1</container> | ||
| 176 | </customwidget> | ||
| 177 | <customwidget> | ||
| 178 | <class>ConfigureCpuDebug</class> | ||
| 179 | <extends>QWidget</extends> | ||
| 180 | <header>configuration/configure_cpu_debug.h</header> | ||
| 181 | <container>1</container> | ||
| 182 | </customwidget> | ||
| 183 | <customwidget> | ||
| 162 | <class>ConfigureGraphics</class> | 184 | <class>ConfigureGraphics</class> |
| 163 | <extends>QWidget</extends> | 185 | <extends>QWidget</extends> |
| 164 | <header>configuration/configure_graphics.h</header> | 186 | <header>configuration/configure_graphics.h</header> |
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_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp new file mode 100644 index 000000000..7493e5ffb --- /dev/null +++ b/src/yuzu/configuration/configure_cpu.cpp | |||
| @@ -0,0 +1,61 @@ | |||
| 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 <QComboBox> | ||
| 6 | #include <QMessageBox> | ||
| 7 | |||
| 8 | #include "common/common_types.h" | ||
| 9 | #include "common/logging/log.h" | ||
| 10 | #include "core/core.h" | ||
| 11 | #include "core/settings.h" | ||
| 12 | #include "ui_configure_cpu.h" | ||
| 13 | #include "yuzu/configuration/configure_cpu.h" | ||
| 14 | |||
| 15 | ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureCpu) { | ||
| 16 | ui->setupUi(this); | ||
| 17 | |||
| 18 | SetConfiguration(); | ||
| 19 | |||
| 20 | connect(ui->accuracy, qOverload<int>(&QComboBox::activated), this, | ||
| 21 | &ConfigureCpu::AccuracyUpdated); | ||
| 22 | } | ||
| 23 | |||
| 24 | ConfigureCpu::~ConfigureCpu() = default; | ||
| 25 | |||
| 26 | void ConfigureCpu::SetConfiguration() { | ||
| 27 | const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); | ||
| 28 | |||
| 29 | ui->accuracy->setEnabled(runtime_lock); | ||
| 30 | ui->accuracy->setCurrentIndex(static_cast<int>(Settings::values.cpu_accuracy)); | ||
| 31 | } | ||
| 32 | |||
| 33 | void ConfigureCpu::AccuracyUpdated(int index) { | ||
| 34 | if (static_cast<Settings::CPUAccuracy>(index) == Settings::CPUAccuracy::DebugMode) { | ||
| 35 | const auto result = QMessageBox::warning(this, tr("Setting CPU to Debug Mode"), | ||
| 36 | tr("CPU Debug Mode is only intended for developer " | ||
| 37 | "use. Are you sure you want to enable this?"), | ||
| 38 | QMessageBox::Yes | QMessageBox::No); | ||
| 39 | if (result == QMessageBox::No) { | ||
| 40 | ui->accuracy->setCurrentIndex(static_cast<int>(Settings::CPUAccuracy::Accurate)); | ||
| 41 | return; | ||
| 42 | } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | void ConfigureCpu::ApplyConfiguration() { | ||
| 47 | Settings::values.cpu_accuracy = | ||
| 48 | static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex()); | ||
| 49 | } | ||
| 50 | |||
| 51 | void ConfigureCpu::changeEvent(QEvent* event) { | ||
| 52 | if (event->type() == QEvent::LanguageChange) { | ||
| 53 | RetranslateUI(); | ||
| 54 | } | ||
| 55 | |||
| 56 | QWidget::changeEvent(event); | ||
| 57 | } | ||
| 58 | |||
| 59 | void ConfigureCpu::RetranslateUI() { | ||
| 60 | ui->retranslateUi(this); | ||
| 61 | } | ||
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h new file mode 100644 index 000000000..e4741d3a4 --- /dev/null +++ b/src/yuzu/configuration/configure_cpu.h | |||
| @@ -0,0 +1,33 @@ | |||
| 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 <QWidget> | ||
| 9 | #include "core/settings.h" | ||
| 10 | |||
| 11 | namespace Ui { | ||
| 12 | class ConfigureCpu; | ||
| 13 | } | ||
| 14 | |||
| 15 | class ConfigureCpu : public QWidget { | ||
| 16 | Q_OBJECT | ||
| 17 | |||
| 18 | public: | ||
| 19 | explicit ConfigureCpu(QWidget* parent = nullptr); | ||
| 20 | ~ConfigureCpu() override; | ||
| 21 | |||
| 22 | void ApplyConfiguration(); | ||
| 23 | |||
| 24 | private: | ||
| 25 | void changeEvent(QEvent* event) override; | ||
| 26 | void RetranslateUI(); | ||
| 27 | |||
| 28 | void AccuracyUpdated(int index); | ||
| 29 | |||
| 30 | void SetConfiguration(); | ||
| 31 | |||
| 32 | std::unique_ptr<Ui::ConfigureCpu> ui; | ||
| 33 | }; | ||
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui new file mode 100644 index 000000000..bf6ea79bb --- /dev/null +++ b/src/yuzu/configuration/configure_cpu.ui | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <ui version="4.0"> | ||
| 3 | <class>ConfigureCpu</class> | ||
| 4 | <widget class="QWidget" name="ConfigureCpu"> | ||
| 5 | <property name="geometry"> | ||
| 6 | <rect> | ||
| 7 | <x>0</x> | ||
| 8 | <y>0</y> | ||
| 9 | <width>400</width> | ||
| 10 | <height>321</height> | ||
| 11 | </rect> | ||
| 12 | </property> | ||
| 13 | <property name="windowTitle"> | ||
| 14 | <string>Form</string> | ||
| 15 | </property> | ||
| 16 | <layout class="QVBoxLayout"> | ||
| 17 | <item> | ||
| 18 | <layout class="QVBoxLayout"> | ||
| 19 | <item> | ||
| 20 | <widget class="QGroupBox"> | ||
| 21 | <property name="title"> | ||
| 22 | <string>General</string> | ||
| 23 | </property> | ||
| 24 | <layout class="QVBoxLayout"> | ||
| 25 | <item> | ||
| 26 | <layout class="QHBoxLayout"> | ||
| 27 | <item> | ||
| 28 | <widget class="QLabel"> | ||
| 29 | <property name="text"> | ||
| 30 | <string>Accuracy:</string> | ||
| 31 | </property> | ||
| 32 | </widget> | ||
| 33 | </item> | ||
| 34 | <item> | ||
| 35 | <widget class="QComboBox" name="accuracy"> | ||
| 36 | <item> | ||
| 37 | <property name="text"> | ||
| 38 | <string>Accurate</string> | ||
| 39 | </property> | ||
| 40 | </item> | ||
| 41 | <item> | ||
| 42 | <property name="text"> | ||
| 43 | <string>Enable Debug Mode</string> | ||
| 44 | </property> | ||
| 45 | </item> | ||
| 46 | </widget> | ||
| 47 | </item> | ||
| 48 | </layout> | ||
| 49 | </item> | ||
| 50 | <item> | ||
| 51 | <widget class="QLabel"> | ||
| 52 | <property name="wordWrap"> | ||
| 53 | <bool>1</bool> | ||
| 54 | </property> | ||
| 55 | <property name="text"> | ||
| 56 | <string>We recommend setting accuracy to "Accurate".</string> | ||
| 57 | </property> | ||
| 58 | </widget> | ||
| 59 | </item> | ||
| 60 | </layout> | ||
| 61 | </widget> | ||
| 62 | </item> | ||
| 63 | </layout> | ||
| 64 | </item> | ||
| 65 | <item> | ||
| 66 | <spacer name="verticalSpacer"> | ||
| 67 | <property name="orientation"> | ||
| 68 | <enum>Qt::Vertical</enum> | ||
| 69 | </property> | ||
| 70 | <property name="sizeHint" stdset="0"> | ||
| 71 | <size> | ||
| 72 | <width>20</width> | ||
| 73 | <height>40</height> | ||
| 74 | </size> | ||
| 75 | </property> | ||
| 76 | </spacer> | ||
| 77 | </item> | ||
| 78 | <item> | ||
| 79 | <widget class="QLabel" name="label_disable_info"> | ||
| 80 | <property name="text"> | ||
| 81 | <string>CPU settings are available only when game is not running.</string> | ||
| 82 | </property> | ||
| 83 | <property name="wordWrap"> | ||
| 84 | <bool>true</bool> | ||
| 85 | </property> | ||
| 86 | </widget> | ||
| 87 | </item> | ||
| 88 | </layout> | ||
| 89 | </widget> | ||
| 90 | <resources/> | ||
| 91 | <connections/> | ||
| 92 | </ui> | ||
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp new file mode 100644 index 000000000..3385b2cf6 --- /dev/null +++ b/src/yuzu/configuration/configure_cpu_debug.cpp | |||
| @@ -0,0 +1,65 @@ | |||
| 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 <QComboBox> | ||
| 6 | |||
| 7 | #include "common/common_types.h" | ||
| 8 | #include "common/logging/log.h" | ||
| 9 | #include "core/core.h" | ||
| 10 | #include "core/settings.h" | ||
| 11 | #include "ui_configure_cpu_debug.h" | ||
| 12 | #include "yuzu/configuration/configure_cpu_debug.h" | ||
| 13 | |||
| 14 | ConfigureCpuDebug::ConfigureCpuDebug(QWidget* parent) | ||
| 15 | : QWidget(parent), ui(new Ui::ConfigureCpuDebug) { | ||
| 16 | ui->setupUi(this); | ||
| 17 | |||
| 18 | SetConfiguration(); | ||
| 19 | } | ||
| 20 | |||
| 21 | ConfigureCpuDebug::~ConfigureCpuDebug() = default; | ||
| 22 | |||
| 23 | void ConfigureCpuDebug::SetConfiguration() { | ||
| 24 | const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn(); | ||
| 25 | |||
| 26 | ui->cpuopt_page_tables->setEnabled(runtime_lock); | ||
| 27 | ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables); | ||
| 28 | ui->cpuopt_block_linking->setEnabled(runtime_lock); | ||
| 29 | ui->cpuopt_block_linking->setChecked(Settings::values.cpuopt_block_linking); | ||
| 30 | ui->cpuopt_return_stack_buffer->setEnabled(runtime_lock); | ||
| 31 | ui->cpuopt_return_stack_buffer->setChecked(Settings::values.cpuopt_return_stack_buffer); | ||
| 32 | ui->cpuopt_fast_dispatcher->setEnabled(runtime_lock); | ||
| 33 | ui->cpuopt_fast_dispatcher->setChecked(Settings::values.cpuopt_fast_dispatcher); | ||
| 34 | ui->cpuopt_context_elimination->setEnabled(runtime_lock); | ||
| 35 | ui->cpuopt_context_elimination->setChecked(Settings::values.cpuopt_context_elimination); | ||
| 36 | ui->cpuopt_const_prop->setEnabled(runtime_lock); | ||
| 37 | ui->cpuopt_const_prop->setChecked(Settings::values.cpuopt_const_prop); | ||
| 38 | ui->cpuopt_misc_ir->setEnabled(runtime_lock); | ||
| 39 | ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir); | ||
| 40 | ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock); | ||
| 41 | ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks); | ||
| 42 | } | ||
| 43 | |||
| 44 | void ConfigureCpuDebug::ApplyConfiguration() { | ||
| 45 | Settings::values.cpuopt_page_tables = ui->cpuopt_page_tables->isChecked(); | ||
| 46 | Settings::values.cpuopt_block_linking = ui->cpuopt_block_linking->isChecked(); | ||
| 47 | Settings::values.cpuopt_return_stack_buffer = ui->cpuopt_return_stack_buffer->isChecked(); | ||
| 48 | Settings::values.cpuopt_fast_dispatcher = ui->cpuopt_fast_dispatcher->isChecked(); | ||
| 49 | Settings::values.cpuopt_context_elimination = ui->cpuopt_context_elimination->isChecked(); | ||
| 50 | Settings::values.cpuopt_const_prop = ui->cpuopt_const_prop->isChecked(); | ||
| 51 | Settings::values.cpuopt_misc_ir = ui->cpuopt_misc_ir->isChecked(); | ||
| 52 | Settings::values.cpuopt_reduce_misalign_checks = ui->cpuopt_reduce_misalign_checks->isChecked(); | ||
| 53 | } | ||
| 54 | |||
| 55 | void ConfigureCpuDebug::changeEvent(QEvent* event) { | ||
| 56 | if (event->type() == QEvent::LanguageChange) { | ||
| 57 | RetranslateUI(); | ||
| 58 | } | ||
| 59 | |||
| 60 | QWidget::changeEvent(event); | ||
| 61 | } | ||
| 62 | |||
| 63 | void ConfigureCpuDebug::RetranslateUI() { | ||
| 64 | ui->retranslateUi(this); | ||
| 65 | } | ||
diff --git a/src/yuzu/configuration/configure_cpu_debug.h b/src/yuzu/configuration/configure_cpu_debug.h new file mode 100644 index 000000000..c9941ef3b --- /dev/null +++ b/src/yuzu/configuration/configure_cpu_debug.h | |||
| @@ -0,0 +1,31 @@ | |||
| 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 <QWidget> | ||
| 9 | #include "core/settings.h" | ||
| 10 | |||
| 11 | namespace Ui { | ||
| 12 | class ConfigureCpuDebug; | ||
| 13 | } | ||
| 14 | |||
| 15 | class ConfigureCpuDebug : public QWidget { | ||
| 16 | Q_OBJECT | ||
| 17 | |||
| 18 | public: | ||
| 19 | explicit ConfigureCpuDebug(QWidget* parent = nullptr); | ||
| 20 | ~ConfigureCpuDebug() override; | ||
| 21 | |||
| 22 | void ApplyConfiguration(); | ||
| 23 | |||
| 24 | private: | ||
| 25 | void changeEvent(QEvent* event) override; | ||
| 26 | void RetranslateUI(); | ||
| 27 | |||
| 28 | void SetConfiguration(); | ||
| 29 | |||
| 30 | std::unique_ptr<Ui::ConfigureCpuDebug> ui; | ||
| 31 | }; | ||
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui new file mode 100644 index 000000000..a90dc64fe --- /dev/null +++ b/src/yuzu/configuration/configure_cpu_debug.ui | |||
| @@ -0,0 +1,174 @@ | |||
| 1 | <?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | <ui version="4.0"> | ||
| 3 | <class>ConfigureCpuDebug</class> | ||
| 4 | <widget class="QWidget" name="ConfigureCpuDebug"> | ||
| 5 | <property name="geometry"> | ||
| 6 | <rect> | ||
| 7 | <x>0</x> | ||
| 8 | <y>0</y> | ||
| 9 | <width>400</width> | ||
| 10 | <height>321</height> | ||
| 11 | </rect> | ||
| 12 | </property> | ||
| 13 | <property name="windowTitle"> | ||
| 14 | <string>Form</string> | ||
| 15 | </property> | ||
| 16 | <layout class="QVBoxLayout"> | ||
| 17 | <item> | ||
| 18 | <layout class="QVBoxLayout"> | ||
| 19 | <item> | ||
| 20 | <widget class="QGroupBox"> | ||
| 21 | <property name="title"> | ||
| 22 | <string>Toggle CPU Optimizations</string> | ||
| 23 | </property> | ||
| 24 | <layout class="QVBoxLayout"> | ||
| 25 | <item> | ||
| 26 | <widget class="QLabel"> | ||
| 27 | <property name="wordWrap"> | ||
| 28 | <bool>1</bool> | ||
| 29 | </property> | ||
| 30 | <property name="text"> | ||
| 31 | <string> | ||
| 32 | <div> | ||
| 33 | <b>For debugging only.</b> | ||
| 34 | <br> | ||
| 35 | If you're not sure what these do, keep all of these enabled. | ||
| 36 | <br> | ||
| 37 | These settings only take effect when CPU Accuracy is "Debug Mode". | ||
| 38 | </div> | ||
| 39 | </string> | ||
| 40 | </property> | ||
| 41 | </widget> | ||
| 42 | </item> | ||
| 43 | <item> | ||
| 44 | <widget class="QCheckBox" name="cpuopt_page_tables"> | ||
| 45 | <property name="text"> | ||
| 46 | <string>Enable inline page tables</string> | ||
| 47 | </property> | ||
| 48 | <property name="toolTip"> | ||
| 49 | <string> | ||
| 50 | <div style="white-space: nowrap">This optimization speeds up memory accesses by the guest program.</div> | ||
| 51 | <div style="white-space: nowrap">Enabling it inlines accesses to PageTable::pointers into emitted code.</div> | ||
| 52 | <div style="white-space: nowrap">Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.</div> | ||
| 53 | </string> | ||
| 54 | </property> | ||
| 55 | </widget> | ||
| 56 | </item> | ||
| 57 | <item> | ||
| 58 | <widget class="QCheckBox" name="cpuopt_block_linking"> | ||
| 59 | <property name="text"> | ||
| 60 | <string>Enable block linking</string> | ||
| 61 | </property> | ||
| 62 | <property name="toolTip"> | ||
| 63 | <string> | ||
| 64 | <div>This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.</div> | ||
| 65 | </string> | ||
| 66 | </property> | ||
| 67 | </widget> | ||
| 68 | </item> | ||
| 69 | <item> | ||
| 70 | <widget class="QCheckBox" name="cpuopt_return_stack_buffer"> | ||
| 71 | <property name="text"> | ||
| 72 | <string>Enable return stack buffer</string> | ||
| 73 | </property> | ||
| 74 | <property name="toolTip"> | ||
| 75 | <string> | ||
| 76 | <div>This optimization avoids dispatcher lookups by keeping track potential return addresses of BL instructions. This approximates what happens with a return stack buffer on a real CPU.</div> | ||
| 77 | </string> | ||
| 78 | </property> | ||
| 79 | </widget> | ||
| 80 | </item> | ||
| 81 | <item> | ||
| 82 | <widget class="QCheckBox" name="cpuopt_fast_dispatcher"> | ||
| 83 | <property name="text"> | ||
| 84 | <string>Enable fast dispatcher</string> | ||
| 85 | </property> | ||
| 86 | <property name="toolTip"> | ||
| 87 | <string> | ||
| 88 | <div>Enable a two-tiered dispatch system. A faster dispatcher written in assembly has a small MRU cache of jump destinations is used first. If that fails, dispatch falls back to the slower C++ dispatcher.</div> | ||
| 89 | </string> | ||
| 90 | </property> | ||
| 91 | </widget> | ||
| 92 | </item> | ||
| 93 | <item> | ||
| 94 | <widget class="QCheckBox" name="cpuopt_context_elimination"> | ||
| 95 | <property name="text"> | ||
| 96 | <string>Enable context elimination</string> | ||
| 97 | </property> | ||
| 98 | <property name="toolTip"> | ||
| 99 | <string> | ||
| 100 | <div>Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.</div> | ||
| 101 | </string> | ||
| 102 | </property> | ||
| 103 | </widget> | ||
| 104 | </item> | ||
| 105 | <item> | ||
| 106 | <widget class="QCheckBox" name="cpuopt_const_prop"> | ||
| 107 | <property name="text"> | ||
| 108 | <string>Enable constant propagation</string> | ||
| 109 | </property> | ||
| 110 | <property name="toolTip"> | ||
| 111 | <string> | ||
| 112 | <div>Enables IR optimizations that involve constant propagation.</div> | ||
| 113 | </string> | ||
| 114 | </property> | ||
| 115 | </widget> | ||
| 116 | </item> | ||
| 117 | <item> | ||
| 118 | <widget class="QCheckBox" name="cpuopt_misc_ir"> | ||
| 119 | <property name="text"> | ||
| 120 | <string>Enable miscellaneous optimizations</string> | ||
| 121 | </property> | ||
| 122 | <property name="toolTip"> | ||
| 123 | <string> | ||
| 124 | <div>Enables miscellaneous IR optimizations.</div> | ||
| 125 | </string> | ||
| 126 | </property> | ||
| 127 | </widget> | ||
| 128 | </item> | ||
| 129 | <item> | ||
| 130 | <widget class="QCheckBox" name="cpuopt_reduce_misalign_checks"> | ||
| 131 | <property name="text"> | ||
| 132 | <string>Enable misalignment check reduction</string> | ||
| 133 | </property> | ||
| 134 | <property name="toolTip"> | ||
| 135 | <string> | ||
| 136 | <div style="white-space: nowrap">When enabled, a misalignment is only triggered when an access crosses a page boundary.</div> | ||
| 137 | <div style="white-space: nowrap">When disabled, a misalignment is triggered on all misaligned accesses.</div> | ||
| 138 | </string> | ||
| 139 | </property> | ||
| 140 | </widget> | ||
| 141 | </item> | ||
| 142 | </layout> | ||
| 143 | </widget> | ||
| 144 | </item> | ||
| 145 | </layout> | ||
| 146 | </item> | ||
| 147 | <item> | ||
| 148 | <spacer name="verticalSpacer"> | ||
| 149 | <property name="orientation"> | ||
| 150 | <enum>Qt::Vertical</enum> | ||
| 151 | </property> | ||
| 152 | <property name="sizeHint" stdset="0"> | ||
| 153 | <size> | ||
| 154 | <width>20</width> | ||
| 155 | <height>40</height> | ||
| 156 | </size> | ||
| 157 | </property> | ||
| 158 | </spacer> | ||
| 159 | </item> | ||
| 160 | <item> | ||
| 161 | <widget class="QLabel" name="label_disable_info"> | ||
| 162 | <property name="text"> | ||
| 163 | <string>CPU settings are available only when game is not running.</string> | ||
| 164 | </property> | ||
| 165 | <property name="wordWrap"> | ||
| 166 | <bool>true</bool> | ||
| 167 | </property> | ||
| 168 | </widget> | ||
| 169 | </item> | ||
| 170 | </layout> | ||
| 171 | </widget> | ||
| 172 | <resources/> | ||
| 173 | <connections/> | ||
| 174 | </ui> | ||
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp index 2c77441fd..d0e71dd60 100644 --- a/src/yuzu/configuration/configure_debug.cpp +++ b/src/yuzu/configuration/configure_debug.cpp | |||
| @@ -36,7 +36,6 @@ void ConfigureDebug::SetConfiguration() { | |||
| 36 | ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args)); | 36 | ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args)); |
| 37 | ui->reporting_services->setChecked(Settings::values.reporting_services); | 37 | ui->reporting_services->setChecked(Settings::values.reporting_services); |
| 38 | ui->quest_flag->setChecked(Settings::values.quest_flag); | 38 | ui->quest_flag->setChecked(Settings::values.quest_flag); |
| 39 | ui->disable_cpu_opt->setChecked(Settings::values.disable_cpu_opt); | ||
| 40 | ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | 39 | ui->enable_graphics_debugging->setEnabled(!Core::System::GetInstance().IsPoweredOn()); |
| 41 | ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug); | 40 | ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug); |
| 42 | ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); | 41 | ui->disable_macro_jit->setEnabled(!Core::System::GetInstance().IsPoweredOn()); |
| @@ -51,7 +50,6 @@ void ConfigureDebug::ApplyConfiguration() { | |||
| 51 | Settings::values.program_args = ui->homebrew_args_edit->text().toStdString(); | 50 | Settings::values.program_args = ui->homebrew_args_edit->text().toStdString(); |
| 52 | Settings::values.reporting_services = ui->reporting_services->isChecked(); | 51 | Settings::values.reporting_services = ui->reporting_services->isChecked(); |
| 53 | Settings::values.quest_flag = ui->quest_flag->isChecked(); | 52 | Settings::values.quest_flag = ui->quest_flag->isChecked(); |
| 54 | Settings::values.disable_cpu_opt = ui->disable_cpu_opt->isChecked(); | ||
| 55 | Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked(); | 53 | Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked(); |
| 56 | Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); | 54 | Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked(); |
| 57 | Debugger::ToggleConsole(); | 55 | Debugger::ToggleConsole(); |
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui index 46f0208c6..272bdd6b8 100644 --- a/src/yuzu/configuration/configure_debug.ui +++ b/src/yuzu/configuration/configure_debug.ui | |||
| @@ -228,13 +228,6 @@ | |||
| 228 | </property> | 228 | </property> |
| 229 | </widget> | 229 | </widget> |
| 230 | </item> | 230 | </item> |
| 231 | <item> | ||
| 232 | <widget class="QCheckBox" name="disable_cpu_opt"> | ||
| 233 | <property name="text"> | ||
| 234 | <string>Disable CPU JIT optimizations</string> | ||
| 235 | </property> | ||
| 236 | </widget> | ||
| 237 | </item> | ||
| 238 | </layout> | 231 | </layout> |
| 239 | </widget> | 232 | </widget> |
| 240 | </item> | 233 | </item> |
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp index df4473b46..a5afb354f 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); |
| @@ -40,6 +42,8 @@ void ConfigureDialog::ApplyConfiguration() { | |||
| 40 | ui->filesystemTab->applyConfiguration(); | 42 | ui->filesystemTab->applyConfiguration(); |
| 41 | ui->inputTab->ApplyConfiguration(); | 43 | ui->inputTab->ApplyConfiguration(); |
| 42 | ui->hotkeysTab->ApplyConfiguration(registry); | 44 | ui->hotkeysTab->ApplyConfiguration(registry); |
| 45 | ui->cpuTab->ApplyConfiguration(); | ||
| 46 | ui->cpuDebugTab->ApplyConfiguration(); | ||
| 43 | ui->graphicsTab->ApplyConfiguration(); | 47 | ui->graphicsTab->ApplyConfiguration(); |
| 44 | ui->graphicsAdvancedTab->ApplyConfiguration(); | 48 | ui->graphicsAdvancedTab->ApplyConfiguration(); |
| 45 | ui->audioTab->ApplyConfiguration(); | 49 | ui->audioTab->ApplyConfiguration(); |
| @@ -74,9 +78,10 @@ void ConfigureDialog::RetranslateUI() { | |||
| 74 | Q_DECLARE_METATYPE(QList<QWidget*>); | 78 | Q_DECLARE_METATYPE(QList<QWidget*>); |
| 75 | 79 | ||
| 76 | void ConfigureDialog::PopulateSelectionList() { | 80 | void ConfigureDialog::PopulateSelectionList() { |
| 77 | const std::array<std::pair<QString, QList<QWidget*>>, 5> items{ | 81 | const std::array<std::pair<QString, QList<QWidget*>>, 6> items{ |
| 78 | {{tr("General"), {ui->generalTab, ui->webTab, ui->debugTab, ui->uiTab}}, | 82 | {{tr("General"), {ui->generalTab, ui->webTab, ui->debugTab, ui->uiTab}}, |
| 79 | {tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}}, | 83 | {tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}}, |
| 84 | {tr("CPU"), {ui->cpuTab, ui->cpuDebugTab}}, | ||
| 80 | {tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}}, | 85 | {tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}}, |
| 81 | {tr("Audio"), {ui->audioTab}}, | 86 | {tr("Audio"), {ui->audioTab}}, |
| 82 | {tr("Controls"), {ui->inputTab, ui->hotkeysTab}}}, | 87 | {tr("Controls"), {ui->inputTab, ui->hotkeysTab}}}, |
| @@ -105,6 +110,8 @@ void ConfigureDialog::UpdateVisibleTabs() { | |||
| 105 | {ui->profileManagerTab, tr("Profiles")}, | 110 | {ui->profileManagerTab, tr("Profiles")}, |
| 106 | {ui->inputTab, tr("Input")}, | 111 | {ui->inputTab, tr("Input")}, |
| 107 | {ui->hotkeysTab, tr("Hotkeys")}, | 112 | {ui->hotkeysTab, tr("Hotkeys")}, |
| 113 | {ui->cpuTab, tr("CPU")}, | ||
| 114 | {ui->cpuDebugTab, tr("Debug")}, | ||
| 108 | {ui->graphicsTab, tr("Graphics")}, | 115 | {ui->graphicsTab, tr("Graphics")}, |
| 109 | {ui->graphicsAdvancedTab, tr("Advanced")}, | 116 | {ui->graphicsAdvancedTab, tr("Advanced")}, |
| 110 | {ui->audioTab, tr("Audio")}, | 117 | {ui->audioTab, tr("Audio")}, |
diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp index 835ee821c..a089f5733 100644 --- a/src/yuzu/configuration/configure_filesystem.cpp +++ b/src/yuzu/configuration/configure_filesystem.cpp | |||
| @@ -11,19 +11,6 @@ | |||
| 11 | #include "yuzu/configuration/configure_filesystem.h" | 11 | #include "yuzu/configuration/configure_filesystem.h" |
| 12 | #include "yuzu/uisettings.h" | 12 | #include "yuzu/uisettings.h" |
| 13 | 13 | ||
| 14 | namespace { | ||
| 15 | |||
| 16 | template <typename T> | ||
| 17 | void SetComboBoxFromData(QComboBox* combo_box, T data) { | ||
| 18 | const auto index = combo_box->findData(QVariant::fromValue(static_cast<u64>(data))); | ||
| 19 | if (index >= combo_box->count() || index < 0) | ||
| 20 | return; | ||
| 21 | |||
| 22 | combo_box->setCurrentIndex(index); | ||
| 23 | } | ||
| 24 | |||
| 25 | } // Anonymous namespace | ||
| 26 | |||
| 27 | ConfigureFilesystem::ConfigureFilesystem(QWidget* parent) | 14 | ConfigureFilesystem::ConfigureFilesystem(QWidget* parent) |
| 28 | : QWidget(parent), ui(std::make_unique<Ui::ConfigureFilesystem>()) { | 15 | : QWidget(parent), ui(std::make_unique<Ui::ConfigureFilesystem>()) { |
| 29 | ui->setupUi(this); | 16 | ui->setupUi(this); |
| @@ -73,11 +60,6 @@ void ConfigureFilesystem::setConfiguration() { | |||
| 73 | 60 | ||
| 74 | ui->cache_game_list->setChecked(UISettings::values.cache_game_list); | 61 | ui->cache_game_list->setChecked(UISettings::values.cache_game_list); |
| 75 | 62 | ||
| 76 | SetComboBoxFromData(ui->nand_size, Settings::values.nand_total_size); | ||
| 77 | SetComboBoxFromData(ui->usrnand_size, Settings::values.nand_user_size); | ||
| 78 | SetComboBoxFromData(ui->sysnand_size, Settings::values.nand_system_size); | ||
| 79 | SetComboBoxFromData(ui->sdmc_size, Settings::values.sdmc_size); | ||
| 80 | |||
| 81 | UpdateEnabledControls(); | 63 | UpdateEnabledControls(); |
| 82 | } | 64 | } |
| 83 | 65 | ||
| @@ -98,15 +80,6 @@ void ConfigureFilesystem::applyConfiguration() { | |||
| 98 | Settings::values.dump_nso = ui->dump_nso->isChecked(); | 80 | Settings::values.dump_nso = ui->dump_nso->isChecked(); |
| 99 | 81 | ||
| 100 | UISettings::values.cache_game_list = ui->cache_game_list->isChecked(); | 82 | UISettings::values.cache_game_list = ui->cache_game_list->isChecked(); |
| 101 | |||
| 102 | Settings::values.nand_total_size = static_cast<Settings::NANDTotalSize>( | ||
| 103 | ui->nand_size->itemData(ui->nand_size->currentIndex()).toULongLong()); | ||
| 104 | Settings::values.nand_system_size = static_cast<Settings::NANDSystemSize>( | ||
| 105 | ui->nand_size->itemData(ui->sysnand_size->currentIndex()).toULongLong()); | ||
| 106 | Settings::values.nand_user_size = static_cast<Settings::NANDUserSize>( | ||
| 107 | ui->nand_size->itemData(ui->usrnand_size->currentIndex()).toULongLong()); | ||
| 108 | Settings::values.sdmc_size = static_cast<Settings::SDMCSize>( | ||
| 109 | ui->nand_size->itemData(ui->sdmc_size->currentIndex()).toULongLong()); | ||
| 110 | } | 83 | } |
| 111 | 84 | ||
| 112 | void ConfigureFilesystem::SetDirectory(DirectoryTarget target, QLineEdit* edit) { | 85 | void ConfigureFilesystem::SetDirectory(DirectoryTarget target, QLineEdit* edit) { |
diff --git a/src/yuzu/configuration/configure_filesystem.ui b/src/yuzu/configuration/configure_filesystem.ui index 58cd07f52..84bea0600 100644 --- a/src/yuzu/configuration/configure_filesystem.ui +++ b/src/yuzu/configuration/configure_filesystem.ui | |||
| @@ -116,127 +116,6 @@ | |||
| 116 | </widget> | 116 | </widget> |
| 117 | </item> | 117 | </item> |
| 118 | <item> | 118 | <item> |
| 119 | <widget class="QGroupBox" name="groupBox_3"> | ||
| 120 | <property name="title"> | ||
| 121 | <string>Storage Sizes</string> | ||
| 122 | </property> | ||
| 123 | <layout class="QGridLayout" name="gridLayout_3"> | ||
| 124 | <item row="3" column="0"> | ||
| 125 | <widget class="QLabel" name="label_5"> | ||
| 126 | <property name="text"> | ||
| 127 | <string>SD Card</string> | ||
| 128 | </property> | ||
| 129 | </widget> | ||
| 130 | </item> | ||
| 131 | <item row="1" column="0"> | ||
| 132 | <widget class="QLabel" name="label_4"> | ||
| 133 | <property name="text"> | ||
| 134 | <string>System NAND</string> | ||
| 135 | </property> | ||
| 136 | </widget> | ||
| 137 | </item> | ||
| 138 | <item row="1" column="1"> | ||
| 139 | <widget class="QComboBox" name="sysnand_size"> | ||
| 140 | <item> | ||
| 141 | <property name="text"> | ||
| 142 | <string>2.5 GB</string> | ||
| 143 | </property> | ||
| 144 | </item> | ||
| 145 | </widget> | ||
| 146 | </item> | ||
| 147 | <item row="3" column="1"> | ||
| 148 | <widget class="QComboBox" name="sdmc_size"> | ||
| 149 | <property name="currentText"> | ||
| 150 | <string>32 GB</string> | ||
| 151 | </property> | ||
| 152 | <item> | ||
| 153 | <property name="text"> | ||
| 154 | <string>1 GB</string> | ||
| 155 | </property> | ||
| 156 | </item> | ||
| 157 | <item> | ||
| 158 | <property name="text"> | ||
| 159 | <string>2 GB</string> | ||
| 160 | </property> | ||
| 161 | </item> | ||
| 162 | <item> | ||
| 163 | <property name="text"> | ||
| 164 | <string>4 GB</string> | ||
| 165 | </property> | ||
| 166 | </item> | ||
| 167 | <item> | ||
| 168 | <property name="text"> | ||
| 169 | <string>8 GB</string> | ||
| 170 | </property> | ||
| 171 | </item> | ||
| 172 | <item> | ||
| 173 | <property name="text"> | ||
| 174 | <string>16 GB</string> | ||
| 175 | </property> | ||
| 176 | </item> | ||
| 177 | <item> | ||
| 178 | <property name="text"> | ||
| 179 | <string>32 GB</string> | ||
| 180 | </property> | ||
| 181 | </item> | ||
| 182 | <item> | ||
| 183 | <property name="text"> | ||
| 184 | <string>64 GB</string> | ||
| 185 | </property> | ||
| 186 | </item> | ||
| 187 | <item> | ||
| 188 | <property name="text"> | ||
| 189 | <string>128 GB</string> | ||
| 190 | </property> | ||
| 191 | </item> | ||
| 192 | <item> | ||
| 193 | <property name="text"> | ||
| 194 | <string>256 GB</string> | ||
| 195 | </property> | ||
| 196 | </item> | ||
| 197 | <item> | ||
| 198 | <property name="text"> | ||
| 199 | <string>1 TB</string> | ||
| 200 | </property> | ||
| 201 | </item> | ||
| 202 | </widget> | ||
| 203 | </item> | ||
| 204 | <item row="2" column="1"> | ||
| 205 | <widget class="QComboBox" name="usrnand_size"> | ||
| 206 | <item> | ||
| 207 | <property name="text"> | ||
| 208 | <string>26 GB</string> | ||
| 209 | </property> | ||
| 210 | </item> | ||
| 211 | </widget> | ||
| 212 | </item> | ||
| 213 | <item row="2" column="0"> | ||
| 214 | <widget class="QLabel" name="label_6"> | ||
| 215 | <property name="text"> | ||
| 216 | <string>User NAND</string> | ||
| 217 | </property> | ||
| 218 | </widget> | ||
| 219 | </item> | ||
| 220 | <item row="0" column="0"> | ||
| 221 | <widget class="QLabel" name="label_7"> | ||
| 222 | <property name="text"> | ||
| 223 | <string>NAND</string> | ||
| 224 | </property> | ||
| 225 | </widget> | ||
| 226 | </item> | ||
| 227 | <item row="0" column="1"> | ||
| 228 | <widget class="QComboBox" name="nand_size"> | ||
| 229 | <item> | ||
| 230 | <property name="text"> | ||
| 231 | <string>29.1 GB</string> | ||
| 232 | </property> | ||
| 233 | </item> | ||
| 234 | </widget> | ||
| 235 | </item> | ||
| 236 | </layout> | ||
| 237 | </widget> | ||
| 238 | </item> | ||
| 239 | <item> | ||
| 240 | <widget class="QGroupBox" name="groupBox_4"> | 119 | <widget class="QGroupBox" name="groupBox_4"> |
| 241 | <property name="title"> | 120 | <property name="title"> |
| 242 | <string>Patch Manager</string> | 121 | <string>Patch Manager</string> |
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp index 74b2ad537..20316c9cc 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,58 @@ 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 | } | ||
| 69 | if (Settings::values.use_multi_core.UsingGlobal()) { | ||
| 70 | Settings::values.use_multi_core.SetValue(ui->use_multi_core->isChecked()); | ||
| 71 | } | ||
| 72 | } else { | ||
| 73 | ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_multi_core, | ||
| 74 | ui->use_multi_core); | ||
| 75 | |||
| 76 | bool global_frame_limit = ui->toggle_frame_limit->checkState() == Qt::PartiallyChecked; | ||
| 77 | Settings::values.use_frame_limit.SetGlobal(global_frame_limit); | ||
| 78 | Settings::values.frame_limit.SetGlobal(global_frame_limit); | ||
| 79 | if (!global_frame_limit) { | ||
| 80 | Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() == | ||
| 81 | Qt::Checked); | ||
| 82 | Settings::values.frame_limit.SetValue(ui->frame_limit->value()); | ||
| 83 | } | ||
| 84 | } | ||
| 50 | } | 85 | } |
| 51 | 86 | ||
| 52 | void ConfigureGeneral::changeEvent(QEvent* event) { | 87 | void ConfigureGeneral::changeEvent(QEvent* event) { |
| @@ -60,3 +95,20 @@ void ConfigureGeneral::changeEvent(QEvent* event) { | |||
| 60 | void ConfigureGeneral::RetranslateUI() { | 95 | void ConfigureGeneral::RetranslateUI() { |
| 61 | ui->retranslateUi(this); | 96 | ui->retranslateUi(this); |
| 62 | } | 97 | } |
| 98 | |||
| 99 | void ConfigureGeneral::SetupPerGameUI() { | ||
| 100 | if (Settings::configuring_global) { | ||
| 101 | ui->toggle_frame_limit->setEnabled(Settings::values.use_frame_limit.UsingGlobal()); | ||
| 102 | ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal()); | ||
| 103 | |||
| 104 | return; | ||
| 105 | } | ||
| 106 | |||
| 107 | ui->toggle_check_exit->setVisible(false); | ||
| 108 | ui->toggle_user_on_boot->setVisible(false); | ||
| 109 | ui->toggle_background_pause->setVisible(false); | ||
| 110 | ui->toggle_hide_mouse->setVisible(false); | ||
| 111 | |||
| 112 | ui->toggle_frame_limit->setTristate(true); | ||
| 113 | ui->use_multi_core->setTristate(true); | ||
| 114 | } | ||
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 431f51d73..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,11 +22,13 @@ | |||
| 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, qOverload<int>(&QComboBox::currentIndexChanged), this, | 34 | connect(ui->api, qOverload<int>(&QComboBox::currentIndexChanged), 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,6 +180,11 @@ 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")); |
| @@ -119,6 +198,9 @@ void ConfigureGraphics::UpdateDeviceComboBox() { | |||
| 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/game_list.cpp b/src/yuzu/game_list.cpp index bfb600df0..ab7fc7a24 100644 --- a/src/yuzu/game_list.cpp +++ b/src/yuzu/game_list.cpp | |||
| @@ -531,8 +531,8 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) { | |||
| 531 | UISettings::GameDir& game_dir = | 531 | UISettings::GameDir& game_dir = |
| 532 | *selected.data(GameListDir::GameDirRole).value<UISettings::GameDir*>(); | 532 | *selected.data(GameListDir::GameDirRole).value<UISettings::GameDir*>(); |
| 533 | 533 | ||
| 534 | QAction* move_up = context_menu.addAction(tr(u8"\U000025b2 Move Up")); | 534 | QAction* move_up = context_menu.addAction(tr("\u25B2 Move Up")); |
| 535 | QAction* move_down = context_menu.addAction(tr(u8"\U000025bc Move Down ")); | 535 | QAction* move_down = context_menu.addAction(tr("\u25bc Move Down")); |
| 536 | QAction* open_directory_location = context_menu.addAction(tr("Open Directory Location")); | 536 | QAction* open_directory_location = context_menu.addAction(tr("Open Directory Location")); |
| 537 | 537 | ||
| 538 | const int row = selected.row(); | 538 | const int row = selected.row(); |
diff --git a/src/yuzu/install_dialog.cpp b/src/yuzu/install_dialog.cpp new file mode 100644 index 000000000..06b0b1874 --- /dev/null +++ b/src/yuzu/install_dialog.cpp | |||
| @@ -0,0 +1,72 @@ | |||
| 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 <QCheckBox> | ||
| 6 | #include <QDialogButtonBox> | ||
| 7 | #include <QFileInfo> | ||
| 8 | #include <QHBoxLayout> | ||
| 9 | #include <QLabel> | ||
| 10 | #include <QListWidget> | ||
| 11 | #include <QVBoxLayout> | ||
| 12 | #include "yuzu/install_dialog.h" | ||
| 13 | #include "yuzu/uisettings.h" | ||
| 14 | |||
| 15 | InstallDialog::InstallDialog(QWidget* parent, const QStringList& files) : QDialog(parent) { | ||
| 16 | file_list = new QListWidget(this); | ||
| 17 | |||
| 18 | for (const QString& file : files) { | ||
| 19 | QListWidgetItem* item = new QListWidgetItem(QFileInfo(file).fileName(), file_list); | ||
| 20 | item->setData(Qt::UserRole, file); | ||
| 21 | item->setFlags(item->flags() | Qt::ItemIsUserCheckable); | ||
| 22 | item->setCheckState(Qt::Checked); | ||
| 23 | } | ||
| 24 | |||
| 25 | file_list->setMinimumWidth((file_list->sizeHintForColumn(0) * 11) / 10); | ||
| 26 | |||
| 27 | vbox_layout = new QVBoxLayout; | ||
| 28 | |||
| 29 | hbox_layout = new QHBoxLayout; | ||
| 30 | |||
| 31 | description = new QLabel(tr("Please confirm these are the files you wish to install.")); | ||
| 32 | |||
| 33 | update_description = | ||
| 34 | new QLabel(tr("Installing an Update or DLC will overwrite the previously installed one.")); | ||
| 35 | |||
| 36 | buttons = new QDialogButtonBox; | ||
| 37 | buttons->addButton(QDialogButtonBox::Cancel); | ||
| 38 | buttons->addButton(tr("Install"), QDialogButtonBox::AcceptRole); | ||
| 39 | |||
| 40 | connect(buttons, &QDialogButtonBox::accepted, this, &InstallDialog::accept); | ||
| 41 | connect(buttons, &QDialogButtonBox::rejected, this, &InstallDialog::reject); | ||
| 42 | |||
| 43 | hbox_layout->addWidget(buttons); | ||
| 44 | |||
| 45 | vbox_layout->addWidget(description); | ||
| 46 | vbox_layout->addWidget(update_description); | ||
| 47 | vbox_layout->addWidget(file_list); | ||
| 48 | vbox_layout->addLayout(hbox_layout); | ||
| 49 | |||
| 50 | setLayout(vbox_layout); | ||
| 51 | setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint); | ||
| 52 | setWindowTitle(tr("Install Files to NAND")); | ||
| 53 | } | ||
| 54 | |||
| 55 | InstallDialog::~InstallDialog() = default; | ||
| 56 | |||
| 57 | QStringList InstallDialog::GetFiles() const { | ||
| 58 | QStringList files; | ||
| 59 | |||
| 60 | for (int i = 0; i < file_list->count(); ++i) { | ||
| 61 | const QListWidgetItem* item = file_list->item(i); | ||
| 62 | if (item->checkState() == Qt::Checked) { | ||
| 63 | files.append(item->data(Qt::UserRole).toString()); | ||
| 64 | } | ||
| 65 | } | ||
| 66 | |||
| 67 | return files; | ||
| 68 | } | ||
| 69 | |||
| 70 | int InstallDialog::GetMinimumWidth() const { | ||
| 71 | return file_list->width(); | ||
| 72 | } | ||
diff --git a/src/yuzu/install_dialog.h b/src/yuzu/install_dialog.h new file mode 100644 index 000000000..e4aba1b06 --- /dev/null +++ b/src/yuzu/install_dialog.h | |||
| @@ -0,0 +1,36 @@ | |||
| 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 <QDialog> | ||
| 8 | |||
| 9 | class QCheckBox; | ||
| 10 | class QDialogButtonBox; | ||
| 11 | class QHBoxLayout; | ||
| 12 | class QLabel; | ||
| 13 | class QListWidget; | ||
| 14 | class QVBoxLayout; | ||
| 15 | |||
| 16 | class InstallDialog : public QDialog { | ||
| 17 | Q_OBJECT | ||
| 18 | |||
| 19 | public: | ||
| 20 | explicit InstallDialog(QWidget* parent, const QStringList& files); | ||
| 21 | ~InstallDialog() override; | ||
| 22 | |||
| 23 | QStringList GetFiles() const; | ||
| 24 | bool ShouldOverwriteFiles() const; | ||
| 25 | int GetMinimumWidth() const; | ||
| 26 | |||
| 27 | private: | ||
| 28 | QListWidget* file_list; | ||
| 29 | |||
| 30 | QVBoxLayout* vbox_layout; | ||
| 31 | QHBoxLayout* hbox_layout; | ||
| 32 | |||
| 33 | QLabel* description; | ||
| 34 | QLabel* update_description; | ||
| 35 | QDialogButtonBox* buttons; | ||
| 36 | }; | ||
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 9844e4764..432379705 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" |
| @@ -107,6 +107,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual | |||
| 107 | #include "yuzu/game_list.h" | 107 | #include "yuzu/game_list.h" |
| 108 | #include "yuzu/game_list_p.h" | 108 | #include "yuzu/game_list_p.h" |
| 109 | #include "yuzu/hotkeys.h" | 109 | #include "yuzu/hotkeys.h" |
| 110 | #include "yuzu/install_dialog.h" | ||
| 110 | #include "yuzu/loading_screen.h" | 111 | #include "yuzu/loading_screen.h" |
| 111 | #include "yuzu/main.h" | 112 | #include "yuzu/main.h" |
| 112 | #include "yuzu/uisettings.h" | 113 | #include "yuzu/uisettings.h" |
| @@ -534,15 +535,15 @@ void GMainWindow::InitializeWidgets() { | |||
| 534 | if (emulation_running) { | 535 | if (emulation_running) { |
| 535 | return; | 536 | return; |
| 536 | } | 537 | } |
| 537 | bool is_async = | 538 | bool is_async = !Settings::values.use_asynchronous_gpu_emulation.GetValue() || |
| 538 | !Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core; | 539 | Settings::values.use_multi_core.GetValue(); |
| 539 | Settings::values.use_asynchronous_gpu_emulation = is_async; | 540 | Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async); |
| 540 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | 541 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); |
| 541 | Settings::Apply(); | 542 | Settings::Apply(); |
| 542 | }); | 543 | }); |
| 543 | async_status_button->setText(tr("ASYNC")); | 544 | async_status_button->setText(tr("ASYNC")); |
| 544 | async_status_button->setCheckable(true); | 545 | async_status_button->setCheckable(true); |
| 545 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | 546 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); |
| 546 | 547 | ||
| 547 | // Setup Multicore button | 548 | // Setup Multicore button |
| 548 | multicore_status_button = new QPushButton(); | 549 | multicore_status_button = new QPushButton(); |
| @@ -552,17 +553,17 @@ void GMainWindow::InitializeWidgets() { | |||
| 552 | if (emulation_running) { | 553 | if (emulation_running) { |
| 553 | return; | 554 | return; |
| 554 | } | 555 | } |
| 555 | Settings::values.use_multi_core = !Settings::values.use_multi_core; | 556 | Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue()); |
| 556 | bool is_async = | 557 | bool is_async = Settings::values.use_asynchronous_gpu_emulation.GetValue() || |
| 557 | Settings::values.use_asynchronous_gpu_emulation || Settings::values.use_multi_core; | 558 | Settings::values.use_multi_core.GetValue(); |
| 558 | Settings::values.use_asynchronous_gpu_emulation = is_async; | 559 | Settings::values.use_asynchronous_gpu_emulation.SetValue(is_async); |
| 559 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation); | 560 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); |
| 560 | multicore_status_button->setChecked(Settings::values.use_multi_core); | 561 | multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); |
| 561 | Settings::Apply(); | 562 | Settings::Apply(); |
| 562 | }); | 563 | }); |
| 563 | multicore_status_button->setText(tr("MULTICORE")); | 564 | multicore_status_button->setText(tr("MULTICORE")); |
| 564 | multicore_status_button->setCheckable(true); | 565 | multicore_status_button->setCheckable(true); |
| 565 | multicore_status_button->setChecked(Settings::values.use_multi_core); | 566 | multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); |
| 566 | statusBar()->insertPermanentWidget(0, multicore_status_button); | 567 | statusBar()->insertPermanentWidget(0, multicore_status_button); |
| 567 | statusBar()->insertPermanentWidget(0, async_status_button); | 568 | statusBar()->insertPermanentWidget(0, async_status_button); |
| 568 | 569 | ||
| @@ -581,16 +582,16 @@ void GMainWindow::InitializeWidgets() { | |||
| 581 | renderer_status_button->setCheckable(false); | 582 | renderer_status_button->setCheckable(false); |
| 582 | renderer_status_button->setDisabled(true); | 583 | renderer_status_button->setDisabled(true); |
| 583 | #else | 584 | #else |
| 584 | renderer_status_button->setChecked(Settings::values.renderer_backend == | 585 | renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() == |
| 585 | Settings::RendererBackend::Vulkan); | 586 | Settings::RendererBackend::Vulkan); |
| 586 | connect(renderer_status_button, &QPushButton::clicked, [=] { | 587 | connect(renderer_status_button, &QPushButton::clicked, [=] { |
| 587 | if (emulation_running) { | 588 | if (emulation_running) { |
| 588 | return; | 589 | return; |
| 589 | } | 590 | } |
| 590 | if (renderer_status_button->isChecked()) { | 591 | if (renderer_status_button->isChecked()) { |
| 591 | Settings::values.renderer_backend = Settings::RendererBackend::Vulkan; | 592 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::Vulkan); |
| 592 | } else { | 593 | } else { |
| 593 | Settings::values.renderer_backend = Settings::RendererBackend::OpenGL; | 594 | Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL); |
| 594 | } | 595 | } |
| 595 | 596 | ||
| 596 | Settings::Apply(); | 597 | Settings::Apply(); |
| @@ -727,21 +728,24 @@ void GMainWindow::InitializeHotkeys() { | |||
| 727 | }); | 728 | }); |
| 728 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this), | 729 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this), |
| 729 | &QShortcut::activated, this, [&] { | 730 | &QShortcut::activated, this, [&] { |
| 730 | Settings::values.use_frame_limit = !Settings::values.use_frame_limit; | 731 | Settings::values.use_frame_limit.SetValue( |
| 732 | !Settings::values.use_frame_limit.GetValue()); | ||
| 731 | UpdateStatusBar(); | 733 | UpdateStatusBar(); |
| 732 | }); | 734 | }); |
| 733 | constexpr u16 SPEED_LIMIT_STEP = 5; | 735 | constexpr u16 SPEED_LIMIT_STEP = 5; |
| 734 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this), | 736 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this), |
| 735 | &QShortcut::activated, this, [&] { | 737 | &QShortcut::activated, this, [&] { |
| 736 | if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) { | 738 | if (Settings::values.frame_limit.GetValue() < 9999 - SPEED_LIMIT_STEP) { |
| 737 | Settings::values.frame_limit += SPEED_LIMIT_STEP; | 739 | Settings::values.frame_limit.SetValue(SPEED_LIMIT_STEP + |
| 740 | Settings::values.frame_limit.GetValue()); | ||
| 738 | UpdateStatusBar(); | 741 | UpdateStatusBar(); |
| 739 | } | 742 | } |
| 740 | }); | 743 | }); |
| 741 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this), | 744 | connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this), |
| 742 | &QShortcut::activated, this, [&] { | 745 | &QShortcut::activated, this, [&] { |
| 743 | if (Settings::values.frame_limit > SPEED_LIMIT_STEP) { | 746 | if (Settings::values.frame_limit.GetValue() > SPEED_LIMIT_STEP) { |
| 744 | Settings::values.frame_limit -= SPEED_LIMIT_STEP; | 747 | Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() - |
| 748 | SPEED_LIMIT_STEP); | ||
| 745 | UpdateStatusBar(); | 749 | UpdateStatusBar(); |
| 746 | } | 750 | } |
| 747 | }); | 751 | }); |
| @@ -844,6 +848,9 @@ void GMainWindow::ConnectWidgetEvents() { | |||
| 844 | connect(game_list, &GameList::OpenPerGameGeneralRequested, this, | 848 | connect(game_list, &GameList::OpenPerGameGeneralRequested, this, |
| 845 | &GMainWindow::OnGameListOpenPerGameProperties); | 849 | &GMainWindow::OnGameListOpenPerGameProperties); |
| 846 | 850 | ||
| 851 | connect(this, &GMainWindow::UpdateInstallProgress, this, | ||
| 852 | &GMainWindow::IncrementInstallProgress); | ||
| 853 | |||
| 847 | connect(this, &GMainWindow::EmulationStarting, render_window, | 854 | connect(this, &GMainWindow::EmulationStarting, render_window, |
| 848 | &GRenderWindow::OnEmulationStarting); | 855 | &GRenderWindow::OnEmulationStarting); |
| 849 | connect(this, &GMainWindow::EmulationStopping, render_window, | 856 | connect(this, &GMainWindow::EmulationStopping, render_window, |
| @@ -1039,6 +1046,17 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1039 | LOG_INFO(Frontend, "yuzu starting..."); | 1046 | LOG_INFO(Frontend, "yuzu starting..."); |
| 1040 | StoreRecentFile(filename); // Put the filename on top of the list | 1047 | StoreRecentFile(filename); // Put the filename on top of the list |
| 1041 | 1048 | ||
| 1049 | u64 title_id{0}; | ||
| 1050 | |||
| 1051 | const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData()); | ||
| 1052 | const auto loader = Loader::GetLoader(v_file); | ||
| 1053 | if (!(loader == nullptr || loader->ReadProgramId(title_id) != Loader::ResultStatus::Success)) { | ||
| 1054 | // Load per game settings | ||
| 1055 | Config per_game_config(fmt::format("{:016X}.ini", title_id), false); | ||
| 1056 | } | ||
| 1057 | |||
| 1058 | Settings::LogSettings(); | ||
| 1059 | |||
| 1042 | if (UISettings::values.select_user_on_boot) { | 1060 | if (UISettings::values.select_user_on_boot) { |
| 1043 | SelectAndSetCurrentUser(); | 1061 | SelectAndSetCurrentUser(); |
| 1044 | } | 1062 | } |
| @@ -1063,6 +1081,7 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1063 | &LoadingScreen::OnLoadProgress, Qt::QueuedConnection); | 1081 | &LoadingScreen::OnLoadProgress, Qt::QueuedConnection); |
| 1064 | 1082 | ||
| 1065 | // Update the GUI | 1083 | // Update the GUI |
| 1084 | UpdateStatusButtons(); | ||
| 1066 | if (ui.action_Single_Window_Mode->isChecked()) { | 1085 | if (ui.action_Single_Window_Mode->isChecked()) { |
| 1067 | game_list->hide(); | 1086 | game_list->hide(); |
| 1068 | game_list_placeholder->hide(); | 1087 | game_list_placeholder->hide(); |
| @@ -1078,8 +1097,6 @@ void GMainWindow::BootGame(const QString& filename) { | |||
| 1078 | ui.centralwidget->setMouseTracking(true); | 1097 | ui.centralwidget->setMouseTracking(true); |
| 1079 | } | 1098 | } |
| 1080 | 1099 | ||
| 1081 | const u64 title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID(); | ||
| 1082 | |||
| 1083 | std::string title_name; | 1100 | std::string title_name; |
| 1084 | std::string title_version; | 1101 | std::string title_version; |
| 1085 | const auto res = Core::System::GetInstance().GetGameName(title_name); | 1102 | const auto res = Core::System::GetInstance().GetGameName(title_name); |
| @@ -1521,7 +1538,7 @@ void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) { | |||
| 1521 | return; | 1538 | return; |
| 1522 | } | 1539 | } |
| 1523 | 1540 | ||
| 1524 | ConfigurePerGameGeneral dialog(this, title_id); | 1541 | ConfigurePerGame dialog(this, title_id); |
| 1525 | dialog.LoadFromFile(v_file); | 1542 | dialog.LoadFromFile(v_file); |
| 1526 | auto result = dialog.exec(); | 1543 | auto result = dialog.exec(); |
| 1527 | if (result == QDialog::Accepted) { | 1544 | if (result == QDialog::Accepted) { |
| @@ -1532,7 +1549,14 @@ void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) { | |||
| 1532 | game_list->PopulateAsync(UISettings::values.game_dirs); | 1549 | game_list->PopulateAsync(UISettings::values.game_dirs); |
| 1533 | } | 1550 | } |
| 1534 | 1551 | ||
| 1535 | config->Save(); | 1552 | // Do not cause the global config to write local settings into the config file |
| 1553 | Settings::RestoreGlobalState(); | ||
| 1554 | |||
| 1555 | if (!Core::System::GetInstance().IsPoweredOn()) { | ||
| 1556 | config->Save(); | ||
| 1557 | } | ||
| 1558 | } else { | ||
| 1559 | Settings::RestoreGlobalState(); | ||
| 1536 | } | 1560 | } |
| 1537 | } | 1561 | } |
| 1538 | 1562 | ||
| @@ -1573,187 +1597,255 @@ void GMainWindow::OnMenuLoadFolder() { | |||
| 1573 | } | 1597 | } |
| 1574 | } | 1598 | } |
| 1575 | 1599 | ||
| 1600 | void GMainWindow::IncrementInstallProgress() { | ||
| 1601 | install_progress->setValue(install_progress->value() + 1); | ||
| 1602 | } | ||
| 1603 | |||
| 1576 | void GMainWindow::OnMenuInstallToNAND() { | 1604 | void GMainWindow::OnMenuInstallToNAND() { |
| 1577 | const QString file_filter = | 1605 | const QString file_filter = |
| 1578 | tr("Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive " | 1606 | tr("Installable Switch File (*.nca *.nsp *.xci);;Nintendo Content Archive " |
| 1579 | "(*.nca);;Nintendo Submissions Package (*.nsp);;NX Cartridge " | 1607 | "(*.nca);;Nintendo Submission Package (*.nsp);;NX Cartridge " |
| 1580 | "Image (*.xci)"); | 1608 | "Image (*.xci)"); |
| 1581 | QString filename = QFileDialog::getOpenFileName(this, tr("Install File"), | ||
| 1582 | UISettings::values.roms_path, file_filter); | ||
| 1583 | 1609 | ||
| 1584 | if (filename.isEmpty()) { | 1610 | QStringList filenames = QFileDialog::getOpenFileNames( |
| 1611 | this, tr("Install Files"), UISettings::values.roms_path, file_filter); | ||
| 1612 | |||
| 1613 | if (filenames.isEmpty()) { | ||
| 1614 | return; | ||
| 1615 | } | ||
| 1616 | |||
| 1617 | InstallDialog installDialog(this, filenames); | ||
| 1618 | if (installDialog.exec() == QDialog::Rejected) { | ||
| 1619 | return; | ||
| 1620 | } | ||
| 1621 | |||
| 1622 | const QStringList files = installDialog.GetFiles(); | ||
| 1623 | |||
| 1624 | if (files.isEmpty()) { | ||
| 1625 | return; | ||
| 1626 | } | ||
| 1627 | |||
| 1628 | int remaining = filenames.size(); | ||
| 1629 | |||
| 1630 | // This would only overflow above 2^43 bytes (8.796 TB) | ||
| 1631 | int total_size = 0; | ||
| 1632 | for (const QString& file : files) { | ||
| 1633 | total_size += static_cast<int>(QFile(file).size() / 0x1000); | ||
| 1634 | } | ||
| 1635 | if (total_size < 0) { | ||
| 1636 | LOG_CRITICAL(Frontend, "Attempting to install too many files, aborting."); | ||
| 1585 | return; | 1637 | return; |
| 1586 | } | 1638 | } |
| 1587 | 1639 | ||
| 1640 | QStringList new_files{}; // Newly installed files that do not yet exist in the NAND | ||
| 1641 | QStringList overwritten_files{}; // Files that overwrote those existing in the NAND | ||
| 1642 | QStringList failed_files{}; // Files that failed to install due to errors | ||
| 1643 | |||
| 1644 | ui.action_Install_File_NAND->setEnabled(false); | ||
| 1645 | |||
| 1646 | install_progress = new QProgressDialog(QStringLiteral(""), tr("Cancel"), 0, total_size, this); | ||
| 1647 | install_progress->setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint & | ||
| 1648 | ~Qt::WindowMaximizeButtonHint); | ||
| 1649 | install_progress->setAttribute(Qt::WA_DeleteOnClose, true); | ||
| 1650 | install_progress->setFixedWidth(installDialog.GetMinimumWidth() + 40); | ||
| 1651 | install_progress->show(); | ||
| 1652 | |||
| 1653 | for (const QString& file : files) { | ||
| 1654 | install_progress->setWindowTitle(tr("%n file(s) remaining", "", remaining)); | ||
| 1655 | install_progress->setLabelText( | ||
| 1656 | tr("Installing file \"%1\"...").arg(QFileInfo(file).fileName())); | ||
| 1657 | |||
| 1658 | QFuture<InstallResult> future; | ||
| 1659 | InstallResult result; | ||
| 1660 | |||
| 1661 | if (file.endsWith(QStringLiteral("xci"), Qt::CaseInsensitive) || | ||
| 1662 | file.endsWith(QStringLiteral("nsp"), Qt::CaseInsensitive)) { | ||
| 1663 | |||
| 1664 | future = QtConcurrent::run([this, &file] { return InstallNSPXCI(file); }); | ||
| 1665 | |||
| 1666 | while (!future.isFinished()) { | ||
| 1667 | QCoreApplication::processEvents(); | ||
| 1668 | } | ||
| 1669 | |||
| 1670 | result = future.result(); | ||
| 1671 | |||
| 1672 | } else { | ||
| 1673 | result = InstallNCA(file); | ||
| 1674 | } | ||
| 1675 | |||
| 1676 | std::this_thread::sleep_for(std::chrono::milliseconds(10)); | ||
| 1677 | |||
| 1678 | switch (result) { | ||
| 1679 | case InstallResult::Success: | ||
| 1680 | new_files.append(QFileInfo(file).fileName()); | ||
| 1681 | break; | ||
| 1682 | case InstallResult::Overwrite: | ||
| 1683 | overwritten_files.append(QFileInfo(file).fileName()); | ||
| 1684 | break; | ||
| 1685 | case InstallResult::Failure: | ||
| 1686 | failed_files.append(QFileInfo(file).fileName()); | ||
| 1687 | break; | ||
| 1688 | } | ||
| 1689 | |||
| 1690 | --remaining; | ||
| 1691 | } | ||
| 1692 | |||
| 1693 | install_progress->close(); | ||
| 1694 | |||
| 1695 | const QString install_results = | ||
| 1696 | (new_files.isEmpty() ? QStringLiteral("") | ||
| 1697 | : tr("%n file(s) were newly installed\n", "", new_files.size())) + | ||
| 1698 | (overwritten_files.isEmpty() | ||
| 1699 | ? QStringLiteral("") | ||
| 1700 | : tr("%n file(s) were overwritten\n", "", overwritten_files.size())) + | ||
| 1701 | (failed_files.isEmpty() ? QStringLiteral("") | ||
| 1702 | : tr("%n file(s) failed to install\n", "", failed_files.size())); | ||
| 1703 | |||
| 1704 | QMessageBox::information(this, tr("Install Results"), install_results); | ||
| 1705 | game_list->PopulateAsync(UISettings::values.game_dirs); | ||
| 1706 | FileUtil::DeleteDirRecursively(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP + | ||
| 1707 | "game_list"); | ||
| 1708 | ui.action_Install_File_NAND->setEnabled(true); | ||
| 1709 | } | ||
| 1710 | |||
| 1711 | InstallResult GMainWindow::InstallNSPXCI(const QString& filename) { | ||
| 1588 | const auto qt_raw_copy = [this](const FileSys::VirtualFile& src, | 1712 | const auto qt_raw_copy = [this](const FileSys::VirtualFile& src, |
| 1589 | const FileSys::VirtualFile& dest, std::size_t block_size) { | 1713 | const FileSys::VirtualFile& dest, std::size_t block_size) { |
| 1590 | if (src == nullptr || dest == nullptr) | 1714 | if (src == nullptr || dest == nullptr) { |
| 1591 | return false; | 1715 | return false; |
| 1592 | if (!dest->Resize(src->GetSize())) | 1716 | } |
| 1717 | if (!dest->Resize(src->GetSize())) { | ||
| 1593 | return false; | 1718 | return false; |
| 1719 | } | ||
| 1594 | 1720 | ||
| 1595 | std::array<u8, 0x1000> buffer{}; | 1721 | std::array<u8, 0x1000> buffer{}; |
| 1596 | const int progress_maximum = static_cast<int>(src->GetSize() / buffer.size()); | ||
| 1597 | |||
| 1598 | QProgressDialog progress( | ||
| 1599 | tr("Installing file \"%1\"...").arg(QString::fromStdString(src->GetName())), | ||
| 1600 | tr("Cancel"), 0, progress_maximum, this); | ||
| 1601 | progress.setWindowModality(Qt::WindowModal); | ||
| 1602 | 1722 | ||
| 1603 | for (std::size_t i = 0; i < src->GetSize(); i += buffer.size()) { | 1723 | for (std::size_t i = 0; i < src->GetSize(); i += buffer.size()) { |
| 1604 | if (progress.wasCanceled()) { | 1724 | if (install_progress->wasCanceled()) { |
| 1605 | dest->Resize(0); | 1725 | dest->Resize(0); |
| 1606 | return false; | 1726 | return false; |
| 1607 | } | 1727 | } |
| 1608 | 1728 | ||
| 1609 | const int progress_value = static_cast<int>(i / buffer.size()); | 1729 | emit UpdateInstallProgress(); |
| 1610 | progress.setValue(progress_value); | ||
| 1611 | 1730 | ||
| 1612 | const auto read = src->Read(buffer.data(), buffer.size(), i); | 1731 | const auto read = src->Read(buffer.data(), buffer.size(), i); |
| 1613 | dest->Write(buffer.data(), read, i); | 1732 | dest->Write(buffer.data(), read, i); |
| 1614 | } | 1733 | } |
| 1615 | |||
| 1616 | return true; | 1734 | return true; |
| 1617 | }; | 1735 | }; |
| 1618 | 1736 | ||
| 1619 | const auto success = [this]() { | 1737 | std::shared_ptr<FileSys::NSP> nsp; |
| 1620 | QMessageBox::information(this, tr("Successfully Installed"), | 1738 | if (filename.endsWith(QStringLiteral("nsp"), Qt::CaseInsensitive)) { |
| 1621 | tr("The file was successfully installed.")); | 1739 | nsp = std::make_shared<FileSys::NSP>( |
| 1622 | game_list->PopulateAsync(UISettings::values.game_dirs); | 1740 | vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); |
| 1623 | FileUtil::DeleteDirRecursively(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + | 1741 | if (nsp->IsExtractedType()) { |
| 1624 | DIR_SEP + "game_list"); | 1742 | return InstallResult::Failure; |
| 1625 | }; | ||
| 1626 | |||
| 1627 | const auto failed = [this]() { | ||
| 1628 | QMessageBox::warning( | ||
| 1629 | this, tr("Failed to Install"), | ||
| 1630 | tr("There was an error while attempting to install the provided file. It " | ||
| 1631 | "could have an incorrect format or be missing metadata. Please " | ||
| 1632 | "double-check your file and try again.")); | ||
| 1633 | }; | ||
| 1634 | |||
| 1635 | const auto overwrite = [this]() { | ||
| 1636 | return QMessageBox::question(this, tr("Failed to Install"), | ||
| 1637 | tr("The file you are attempting to install already exists " | ||
| 1638 | "in the cache. Would you like to overwrite it?")) == | ||
| 1639 | QMessageBox::Yes; | ||
| 1640 | }; | ||
| 1641 | |||
| 1642 | if (filename.endsWith(QStringLiteral("xci"), Qt::CaseInsensitive) || | ||
| 1643 | filename.endsWith(QStringLiteral("nsp"), Qt::CaseInsensitive)) { | ||
| 1644 | std::shared_ptr<FileSys::NSP> nsp; | ||
| 1645 | if (filename.endsWith(QStringLiteral("nsp"), Qt::CaseInsensitive)) { | ||
| 1646 | nsp = std::make_shared<FileSys::NSP>( | ||
| 1647 | vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); | ||
| 1648 | if (nsp->IsExtractedType()) | ||
| 1649 | failed(); | ||
| 1650 | } else { | ||
| 1651 | const auto xci = std::make_shared<FileSys::XCI>( | ||
| 1652 | vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); | ||
| 1653 | nsp = xci->GetSecurePartitionNSP(); | ||
| 1654 | } | ||
| 1655 | |||
| 1656 | if (nsp->GetStatus() != Loader::ResultStatus::Success) { | ||
| 1657 | failed(); | ||
| 1658 | return; | ||
| 1659 | } | ||
| 1660 | const auto res = Core::System::GetInstance() | ||
| 1661 | .GetFileSystemController() | ||
| 1662 | .GetUserNANDContents() | ||
| 1663 | ->InstallEntry(*nsp, false, qt_raw_copy); | ||
| 1664 | if (res == FileSys::InstallResult::Success) { | ||
| 1665 | success(); | ||
| 1666 | } else { | ||
| 1667 | if (res == FileSys::InstallResult::ErrorAlreadyExists) { | ||
| 1668 | if (overwrite()) { | ||
| 1669 | const auto res2 = Core::System::GetInstance() | ||
| 1670 | .GetFileSystemController() | ||
| 1671 | .GetUserNANDContents() | ||
| 1672 | ->InstallEntry(*nsp, true, qt_raw_copy); | ||
| 1673 | if (res2 == FileSys::InstallResult::Success) { | ||
| 1674 | success(); | ||
| 1675 | } else { | ||
| 1676 | failed(); | ||
| 1677 | } | ||
| 1678 | } | ||
| 1679 | } else { | ||
| 1680 | failed(); | ||
| 1681 | } | ||
| 1682 | } | 1743 | } |
| 1683 | } else { | 1744 | } else { |
| 1684 | const auto nca = std::make_shared<FileSys::NCA>( | 1745 | const auto xci = std::make_shared<FileSys::XCI>( |
| 1685 | vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); | 1746 | vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); |
| 1686 | const auto id = nca->GetStatus(); | 1747 | nsp = xci->GetSecurePartitionNSP(); |
| 1748 | } | ||
| 1687 | 1749 | ||
| 1688 | // Game updates necessary are missing base RomFS | 1750 | if (nsp->GetStatus() != Loader::ResultStatus::Success) { |
| 1689 | if (id != Loader::ResultStatus::Success && | 1751 | return InstallResult::Failure; |
| 1690 | id != Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { | 1752 | } |
| 1691 | failed(); | 1753 | const auto res = |
| 1692 | return; | 1754 | Core::System::GetInstance().GetFileSystemController().GetUserNANDContents()->InstallEntry( |
| 1693 | } | 1755 | *nsp, true, qt_raw_copy); |
| 1756 | if (res == FileSys::InstallResult::Success) { | ||
| 1757 | return InstallResult::Success; | ||
| 1758 | } else if (res == FileSys::InstallResult::ErrorAlreadyExists) { | ||
| 1759 | return InstallResult::Overwrite; | ||
| 1760 | } else { | ||
| 1761 | return InstallResult::Failure; | ||
| 1762 | } | ||
| 1763 | } | ||
| 1694 | 1764 | ||
| 1695 | const QStringList tt_options{tr("System Application"), | 1765 | InstallResult GMainWindow::InstallNCA(const QString& filename) { |
| 1696 | tr("System Archive"), | 1766 | const auto qt_raw_copy = [this](const FileSys::VirtualFile& src, |
| 1697 | tr("System Application Update"), | 1767 | const FileSys::VirtualFile& dest, std::size_t block_size) { |
| 1698 | tr("Firmware Package (Type A)"), | 1768 | if (src == nullptr || dest == nullptr) { |
| 1699 | tr("Firmware Package (Type B)"), | 1769 | return false; |
| 1700 | tr("Game"), | ||
| 1701 | tr("Game Update"), | ||
| 1702 | tr("Game DLC"), | ||
| 1703 | tr("Delta Title")}; | ||
| 1704 | bool ok; | ||
| 1705 | const auto item = QInputDialog::getItem( | ||
| 1706 | this, tr("Select NCA Install Type..."), | ||
| 1707 | tr("Please select the type of title you would like to install this NCA as:\n(In " | ||
| 1708 | "most instances, the default 'Game' is fine.)"), | ||
| 1709 | tt_options, 5, false, &ok); | ||
| 1710 | |||
| 1711 | auto index = tt_options.indexOf(item); | ||
| 1712 | if (!ok || index == -1) { | ||
| 1713 | QMessageBox::warning(this, tr("Failed to Install"), | ||
| 1714 | tr("The title type you selected for the NCA is invalid.")); | ||
| 1715 | return; | ||
| 1716 | } | 1770 | } |
| 1717 | 1771 | if (!dest->Resize(src->GetSize())) { | |
| 1718 | // If index is equal to or past Game, add the jump in TitleType. | 1772 | return false; |
| 1719 | if (index >= 5) { | ||
| 1720 | index += static_cast<size_t>(FileSys::TitleType::Application) - | ||
| 1721 | static_cast<size_t>(FileSys::TitleType::FirmwarePackageB); | ||
| 1722 | } | 1773 | } |
| 1723 | 1774 | ||
| 1724 | FileSys::InstallResult res; | 1775 | std::array<u8, 0x1000> buffer{}; |
| 1725 | if (index >= static_cast<s32>(FileSys::TitleType::Application)) { | ||
| 1726 | res = Core::System::GetInstance() | ||
| 1727 | .GetFileSystemController() | ||
| 1728 | .GetUserNANDContents() | ||
| 1729 | ->InstallEntry(*nca, static_cast<FileSys::TitleType>(index), false, | ||
| 1730 | qt_raw_copy); | ||
| 1731 | } else { | ||
| 1732 | res = Core::System::GetInstance() | ||
| 1733 | .GetFileSystemController() | ||
| 1734 | .GetSystemNANDContents() | ||
| 1735 | ->InstallEntry(*nca, static_cast<FileSys::TitleType>(index), false, | ||
| 1736 | qt_raw_copy); | ||
| 1737 | } | ||
| 1738 | 1776 | ||
| 1739 | if (res == FileSys::InstallResult::Success) { | 1777 | for (std::size_t i = 0; i < src->GetSize(); i += buffer.size()) { |
| 1740 | success(); | 1778 | if (install_progress->wasCanceled()) { |
| 1741 | } else if (res == FileSys::InstallResult::ErrorAlreadyExists) { | 1779 | dest->Resize(0); |
| 1742 | if (overwrite()) { | 1780 | return false; |
| 1743 | const auto res2 = Core::System::GetInstance() | ||
| 1744 | .GetFileSystemController() | ||
| 1745 | .GetUserNANDContents() | ||
| 1746 | ->InstallEntry(*nca, static_cast<FileSys::TitleType>(index), | ||
| 1747 | true, qt_raw_copy); | ||
| 1748 | if (res2 == FileSys::InstallResult::Success) { | ||
| 1749 | success(); | ||
| 1750 | } else { | ||
| 1751 | failed(); | ||
| 1752 | } | ||
| 1753 | } | 1781 | } |
| 1754 | } else { | 1782 | |
| 1755 | failed(); | 1783 | emit UpdateInstallProgress(); |
| 1784 | |||
| 1785 | const auto read = src->Read(buffer.data(), buffer.size(), i); | ||
| 1786 | dest->Write(buffer.data(), read, i); | ||
| 1756 | } | 1787 | } |
| 1788 | return true; | ||
| 1789 | }; | ||
| 1790 | |||
| 1791 | const auto nca = | ||
| 1792 | std::make_shared<FileSys::NCA>(vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read)); | ||
| 1793 | const auto id = nca->GetStatus(); | ||
| 1794 | |||
| 1795 | // Game updates necessary are missing base RomFS | ||
| 1796 | if (id != Loader::ResultStatus::Success && | ||
| 1797 | id != Loader::ResultStatus::ErrorMissingBKTRBaseRomFS) { | ||
| 1798 | return InstallResult::Failure; | ||
| 1799 | } | ||
| 1800 | |||
| 1801 | const QStringList tt_options{tr("System Application"), | ||
| 1802 | tr("System Archive"), | ||
| 1803 | tr("System Application Update"), | ||
| 1804 | tr("Firmware Package (Type A)"), | ||
| 1805 | tr("Firmware Package (Type B)"), | ||
| 1806 | tr("Game"), | ||
| 1807 | tr("Game Update"), | ||
| 1808 | tr("Game DLC"), | ||
| 1809 | tr("Delta Title")}; | ||
| 1810 | bool ok; | ||
| 1811 | const auto item = QInputDialog::getItem( | ||
| 1812 | this, tr("Select NCA Install Type..."), | ||
| 1813 | tr("Please select the type of title you would like to install this NCA as:\n(In " | ||
| 1814 | "most instances, the default 'Game' is fine.)"), | ||
| 1815 | tt_options, 5, false, &ok); | ||
| 1816 | |||
| 1817 | auto index = tt_options.indexOf(item); | ||
| 1818 | if (!ok || index == -1) { | ||
| 1819 | QMessageBox::warning(this, tr("Failed to Install"), | ||
| 1820 | tr("The title type you selected for the NCA is invalid.")); | ||
| 1821 | return InstallResult::Failure; | ||
| 1822 | } | ||
| 1823 | |||
| 1824 | // If index is equal to or past Game, add the jump in TitleType. | ||
| 1825 | if (index >= 5) { | ||
| 1826 | index += static_cast<size_t>(FileSys::TitleType::Application) - | ||
| 1827 | static_cast<size_t>(FileSys::TitleType::FirmwarePackageB); | ||
| 1828 | } | ||
| 1829 | |||
| 1830 | FileSys::InstallResult res; | ||
| 1831 | if (index >= static_cast<s32>(FileSys::TitleType::Application)) { | ||
| 1832 | res = Core::System::GetInstance() | ||
| 1833 | .GetFileSystemController() | ||
| 1834 | .GetUserNANDContents() | ||
| 1835 | ->InstallEntry(*nca, static_cast<FileSys::TitleType>(index), true, qt_raw_copy); | ||
| 1836 | } else { | ||
| 1837 | res = Core::System::GetInstance() | ||
| 1838 | .GetFileSystemController() | ||
| 1839 | .GetSystemNANDContents() | ||
| 1840 | ->InstallEntry(*nca, static_cast<FileSys::TitleType>(index), true, qt_raw_copy); | ||
| 1841 | } | ||
| 1842 | |||
| 1843 | if (res == FileSys::InstallResult::Success) { | ||
| 1844 | return InstallResult::Success; | ||
| 1845 | } else if (res == FileSys::InstallResult::ErrorAlreadyExists) { | ||
| 1846 | return InstallResult::Overwrite; | ||
| 1847 | } else { | ||
| 1848 | return InstallResult::Failure; | ||
| 1757 | } | 1849 | } |
| 1758 | } | 1850 | } |
| 1759 | 1851 | ||
| @@ -1819,6 +1911,9 @@ void GMainWindow::OnStopGame() { | |||
| 1819 | } | 1911 | } |
| 1820 | 1912 | ||
| 1821 | ShutdownGame(); | 1913 | ShutdownGame(); |
| 1914 | |||
| 1915 | Settings::RestoreGlobalState(); | ||
| 1916 | UpdateStatusButtons(); | ||
| 1822 | } | 1917 | } |
| 1823 | 1918 | ||
| 1824 | void GMainWindow::OnLoadComplete() { | 1919 | void GMainWindow::OnLoadComplete() { |
| @@ -1926,7 +2021,7 @@ void GMainWindow::ToggleWindowMode() { | |||
| 1926 | 2021 | ||
| 1927 | void GMainWindow::ResetWindowSize() { | 2022 | void GMainWindow::ResetWindowSize() { |
| 1928 | const auto aspect_ratio = Layout::EmulationAspectRatio( | 2023 | const auto aspect_ratio = Layout::EmulationAspectRatio( |
| 1929 | static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio), | 2024 | static_cast<Layout::AspectRatio>(Settings::values.aspect_ratio.GetValue()), |
| 1930 | static_cast<float>(Layout::ScreenUndocked::Height) / Layout::ScreenUndocked::Width); | 2025 | static_cast<float>(Layout::ScreenUndocked::Height) / Layout::ScreenUndocked::Width); |
| 1931 | if (!ui.action_Single_Window_Mode->isChecked()) { | 2026 | if (!ui.action_Single_Window_Mode->isChecked()) { |
| 1932 | render_window->resize(Layout::ScreenUndocked::Height / aspect_ratio, | 2027 | render_window->resize(Layout::ScreenUndocked::Height / aspect_ratio, |
| @@ -1974,16 +2069,7 @@ void GMainWindow::OnConfigure() { | |||
| 1974 | ui.centralwidget->setMouseTracking(false); | 2069 | ui.centralwidget->setMouseTracking(false); |
| 1975 | } | 2070 | } |
| 1976 | 2071 | ||
| 1977 | dock_status_button->setChecked(Settings::values.use_docked_mode); | 2072 | 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 | } | 2073 | } |
| 1988 | 2074 | ||
| 1989 | void GMainWindow::OnLoadAmiibo() { | 2075 | void GMainWindow::OnLoadAmiibo() { |
| @@ -2097,21 +2183,34 @@ void GMainWindow::UpdateStatusBar() { | |||
| 2097 | 2183 | ||
| 2098 | auto results = Core::System::GetInstance().GetAndResetPerfStats(); | 2184 | auto results = Core::System::GetInstance().GetAndResetPerfStats(); |
| 2099 | 2185 | ||
| 2100 | if (Settings::values.use_frame_limit) { | 2186 | if (Settings::values.use_frame_limit.GetValue()) { |
| 2101 | emu_speed_label->setText(tr("Speed: %1% / %2%") | 2187 | emu_speed_label->setText(tr("Speed: %1% / %2%") |
| 2102 | .arg(results.emulation_speed * 100.0, 0, 'f', 0) | 2188 | .arg(results.emulation_speed * 100.0, 0, 'f', 0) |
| 2103 | .arg(Settings::values.frame_limit)); | 2189 | .arg(Settings::values.frame_limit.GetValue())); |
| 2104 | } else { | 2190 | } else { |
| 2105 | emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); | 2191 | emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0)); |
| 2106 | } | 2192 | } |
| 2107 | game_fps_label->setText(tr("Game: %1 FPS").arg(results.game_fps, 0, 'f', 0)); | 2193 | 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)); | 2194 | emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2)); |
| 2109 | 2195 | ||
| 2110 | emu_speed_label->setVisible(!Settings::values.use_multi_core); | 2196 | emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue()); |
| 2111 | game_fps_label->setVisible(true); | 2197 | game_fps_label->setVisible(true); |
| 2112 | emu_frametime_label->setVisible(true); | 2198 | emu_frametime_label->setVisible(true); |
| 2113 | } | 2199 | } |
| 2114 | 2200 | ||
| 2201 | void GMainWindow::UpdateStatusButtons() { | ||
| 2202 | dock_status_button->setChecked(Settings::values.use_docked_mode); | ||
| 2203 | multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue()); | ||
| 2204 | Settings::values.use_asynchronous_gpu_emulation.SetValue( | ||
| 2205 | Settings::values.use_asynchronous_gpu_emulation.GetValue() || | ||
| 2206 | Settings::values.use_multi_core.GetValue()); | ||
| 2207 | async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue()); | ||
| 2208 | #ifdef HAS_VULKAN | ||
| 2209 | renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() == | ||
| 2210 | Settings::RendererBackend::Vulkan); | ||
| 2211 | #endif | ||
| 2212 | } | ||
| 2213 | |||
| 2115 | void GMainWindow::HideMouseCursor() { | 2214 | void GMainWindow::HideMouseCursor() { |
| 2116 | if (emu_thread == nullptr || UISettings::values.hide_mouse == false) { | 2215 | if (emu_thread == nullptr || UISettings::values.hide_mouse == false) { |
| 2117 | mouse_hide_timer.stop(); | 2216 | mouse_hide_timer.stop(); |
| @@ -2195,6 +2294,9 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det | |||
| 2195 | if (answer == QMessageBox::Yes) { | 2294 | if (answer == QMessageBox::Yes) { |
| 2196 | if (emu_thread) { | 2295 | if (emu_thread) { |
| 2197 | ShutdownGame(); | 2296 | ShutdownGame(); |
| 2297 | |||
| 2298 | Settings::RestoreGlobalState(); | ||
| 2299 | UpdateStatusButtons(); | ||
| 2198 | } | 2300 | } |
| 2199 | } else { | 2301 | } else { |
| 2200 | // Only show the message if the game is still running. | 2302 | // Only show the message if the game is still running. |
| @@ -2357,9 +2459,13 @@ void GMainWindow::closeEvent(QCloseEvent* event) { | |||
| 2357 | hotkey_registry.SaveHotkeys(); | 2459 | hotkey_registry.SaveHotkeys(); |
| 2358 | 2460 | ||
| 2359 | // Shutdown session if the emu thread is active... | 2461 | // Shutdown session if the emu thread is active... |
| 2360 | if (emu_thread != nullptr) | 2462 | if (emu_thread != nullptr) { |
| 2361 | ShutdownGame(); | 2463 | ShutdownGame(); |
| 2362 | 2464 | ||
| 2465 | Settings::RestoreGlobalState(); | ||
| 2466 | UpdateStatusButtons(); | ||
| 2467 | } | ||
| 2468 | |||
| 2363 | render_window->close(); | 2469 | render_window->close(); |
| 2364 | 2470 | ||
| 2365 | QWidget::closeEvent(event); | 2471 | QWidget::closeEvent(event); |
| @@ -2539,8 +2645,6 @@ int main(int argc, char* argv[]) { | |||
| 2539 | QObject::connect(&app, &QGuiApplication::applicationStateChanged, &main_window, | 2645 | QObject::connect(&app, &QGuiApplication::applicationStateChanged, &main_window, |
| 2540 | &GMainWindow::OnAppFocusStateChanged); | 2646 | &GMainWindow::OnAppFocusStateChanged); |
| 2541 | 2647 | ||
| 2542 | Settings::LogSettings(); | ||
| 2543 | |||
| 2544 | int result = app.exec(); | 2648 | int result = app.exec(); |
| 2545 | detached_tasks.WaitForAllTasks(); | 2649 | detached_tasks.WaitForAllTasks(); |
| 2546 | return result; | 2650 | return result; |
diff --git a/src/yuzu/main.h b/src/yuzu/main.h index 66c84e5c0..adff65fb5 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h | |||
| @@ -28,6 +28,7 @@ class MicroProfileDialog; | |||
| 28 | class ProfilerWidget; | 28 | class ProfilerWidget; |
| 29 | class QLabel; | 29 | class QLabel; |
| 30 | class QPushButton; | 30 | class QPushButton; |
| 31 | class QProgressDialog; | ||
| 31 | class WaitTreeWidget; | 32 | class WaitTreeWidget; |
| 32 | enum class GameListOpenTarget; | 33 | enum class GameListOpenTarget; |
| 33 | class GameListPlaceholder; | 34 | class GameListPlaceholder; |
| @@ -47,6 +48,12 @@ enum class EmulatedDirectoryTarget { | |||
| 47 | SDMC, | 48 | SDMC, |
| 48 | }; | 49 | }; |
| 49 | 50 | ||
| 51 | enum class InstallResult { | ||
| 52 | Success, | ||
| 53 | Overwrite, | ||
| 54 | Failure, | ||
| 55 | }; | ||
| 56 | |||
| 50 | enum class ReinitializeKeyBehavior { | 57 | enum class ReinitializeKeyBehavior { |
| 51 | NoWarning, | 58 | NoWarning, |
| 52 | Warning, | 59 | Warning, |
| @@ -102,6 +109,8 @@ signals: | |||
| 102 | // Signal that tells widgets to update icons to use the current theme | 109 | // Signal that tells widgets to update icons to use the current theme |
| 103 | void UpdateThemedIcons(); | 110 | void UpdateThemedIcons(); |
| 104 | 111 | ||
| 112 | void UpdateInstallProgress(); | ||
| 113 | |||
| 105 | void ErrorDisplayFinished(); | 114 | void ErrorDisplayFinished(); |
| 106 | 115 | ||
| 107 | void ProfileSelectorFinishedSelection(std::optional<Common::UUID> uuid); | 116 | void ProfileSelectorFinishedSelection(std::optional<Common::UUID> uuid); |
| @@ -198,6 +207,7 @@ private slots: | |||
| 198 | void OnGameListOpenPerGameProperties(const std::string& file); | 207 | void OnGameListOpenPerGameProperties(const std::string& file); |
| 199 | void OnMenuLoadFile(); | 208 | void OnMenuLoadFile(); |
| 200 | void OnMenuLoadFolder(); | 209 | void OnMenuLoadFolder(); |
| 210 | void IncrementInstallProgress(); | ||
| 201 | void OnMenuInstallToNAND(); | 211 | void OnMenuInstallToNAND(); |
| 202 | void OnMenuRecentFile(); | 212 | void OnMenuRecentFile(); |
| 203 | void OnConfigure(); | 213 | void OnConfigure(); |
| @@ -218,9 +228,12 @@ private slots: | |||
| 218 | 228 | ||
| 219 | private: | 229 | private: |
| 220 | std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id); | 230 | std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id); |
| 231 | InstallResult InstallNSPXCI(const QString& filename); | ||
| 232 | InstallResult InstallNCA(const QString& filename); | ||
| 221 | void UpdateWindowTitle(const std::string& title_name = {}, | 233 | void UpdateWindowTitle(const std::string& title_name = {}, |
| 222 | const std::string& title_version = {}); | 234 | const std::string& title_version = {}); |
| 223 | void UpdateStatusBar(); | 235 | void UpdateStatusBar(); |
| 236 | void UpdateStatusButtons(); | ||
| 224 | void HideMouseCursor(); | 237 | void HideMouseCursor(); |
| 225 | void ShowMouseCursor(); | 238 | void ShowMouseCursor(); |
| 226 | void OpenURL(const QUrl& url); | 239 | void OpenURL(const QUrl& url); |
| @@ -271,6 +284,9 @@ private: | |||
| 271 | 284 | ||
| 272 | HotkeyRegistry hotkey_registry; | 285 | HotkeyRegistry hotkey_registry; |
| 273 | 286 | ||
| 287 | // Install progress dialog | ||
| 288 | QProgressDialog* install_progress; | ||
| 289 | |||
| 274 | protected: | 290 | protected: |
| 275 | void dropEvent(QDropEvent* event) override; | 291 | void dropEvent(QDropEvent* event) override; |
| 276 | void dragEnterEvent(QDragEnterEvent* event) override; | 292 | void dragEnterEvent(QDragEnterEvent* event) override; |
diff --git a/src/yuzu/main.ui b/src/yuzu/main.ui index bee6e107e..c3a1d715e 100644 --- a/src/yuzu/main.ui +++ b/src/yuzu/main.ui | |||
| @@ -130,7 +130,7 @@ | |||
| 130 | <bool>true</bool> | 130 | <bool>true</bool> |
| 131 | </property> | 131 | </property> |
| 132 | <property name="text"> | 132 | <property name="text"> |
| 133 | <string>Install File to NAND...</string> | 133 | <string>Install Files to NAND...</string> |
| 134 | </property> | 134 | </property> |
| 135 | </action> | 135 | </action> |
| 136 | <action name="action_Load_File"> | 136 | <action name="action_Load_File"> |
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index 659b9f701..7773228c8 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -335,15 +335,6 @@ void Config::ReadValues() { | |||
| 335 | Settings::values.gamecard_current_game = | 335 | Settings::values.gamecard_current_game = |
| 336 | sdl2_config->GetBoolean("Data Storage", "gamecard_current_game", false); | 336 | sdl2_config->GetBoolean("Data Storage", "gamecard_current_game", false); |
| 337 | Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", ""); | 337 | Settings::values.gamecard_path = sdl2_config->Get("Data Storage", "gamecard_path", ""); |
| 338 | Settings::values.nand_total_size = static_cast<Settings::NANDTotalSize>(sdl2_config->GetInteger( | ||
| 339 | "Data Storage", "nand_total_size", static_cast<long>(Settings::NANDTotalSize::S29_1GB))); | ||
| 340 | Settings::values.nand_user_size = static_cast<Settings::NANDUserSize>(sdl2_config->GetInteger( | ||
| 341 | "Data Storage", "nand_user_size", static_cast<long>(Settings::NANDUserSize::S26GB))); | ||
| 342 | Settings::values.nand_system_size = static_cast<Settings::NANDSystemSize>( | ||
| 343 | sdl2_config->GetInteger("Data Storage", "nand_system_size", | ||
| 344 | static_cast<long>(Settings::NANDSystemSize::S2_5GB))); | ||
| 345 | Settings::values.sdmc_size = static_cast<Settings::SDMCSize>(sdl2_config->GetInteger( | ||
| 346 | "Data Storage", "sdmc_size", static_cast<long>(Settings::SDMCSize::S16GB))); | ||
| 347 | 338 | ||
| 348 | // System | 339 | // System |
| 349 | Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false); | 340 | Settings::values.use_docked_mode = sdl2_config->GetBoolean("System", "use_docked_mode", false); |
| @@ -354,63 +345,72 @@ void Config::ReadValues() { | |||
| 354 | 345 | ||
| 355 | const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false); | 346 | const auto rng_seed_enabled = sdl2_config->GetBoolean("System", "rng_seed_enabled", false); |
| 356 | if (rng_seed_enabled) { | 347 | if (rng_seed_enabled) { |
| 357 | Settings::values.rng_seed = sdl2_config->GetInteger("System", "rng_seed", 0); | 348 | Settings::values.rng_seed.SetValue(sdl2_config->GetInteger("System", "rng_seed", 0)); |
| 358 | } else { | 349 | } else { |
| 359 | Settings::values.rng_seed = std::nullopt; | 350 | Settings::values.rng_seed.SetValue(std::nullopt); |
| 360 | } | 351 | } |
| 361 | 352 | ||
| 362 | const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); | 353 | const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); |
| 363 | if (custom_rtc_enabled) { | 354 | if (custom_rtc_enabled) { |
| 364 | Settings::values.custom_rtc = | 355 | Settings::values.custom_rtc.SetValue( |
| 365 | std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0)); | 356 | std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0))); |
| 366 | } else { | 357 | } else { |
| 367 | Settings::values.custom_rtc = std::nullopt; | 358 | Settings::values.custom_rtc.SetValue(std::nullopt); |
| 368 | } | 359 | } |
| 369 | 360 | ||
| 370 | Settings::values.language_index = sdl2_config->GetInteger("System", "language_index", 1); | 361 | Settings::values.language_index.SetValue( |
| 371 | Settings::values.time_zone_index = sdl2_config->GetInteger("System", "time_zone_index", 0); | 362 | sdl2_config->GetInteger("System", "language_index", 1)); |
| 363 | Settings::values.time_zone_index.SetValue( | ||
| 364 | sdl2_config->GetInteger("System", "time_zone_index", 0)); | ||
| 372 | 365 | ||
| 373 | // Core | 366 | // Core |
| 374 | Settings::values.use_multi_core = sdl2_config->GetBoolean("Core", "use_multi_core", false); | 367 | Settings::values.use_multi_core.SetValue( |
| 368 | sdl2_config->GetBoolean("Core", "use_multi_core", false)); | ||
| 375 | 369 | ||
| 376 | // Renderer | 370 | // Renderer |
| 377 | const int renderer_backend = sdl2_config->GetInteger( | 371 | const int renderer_backend = sdl2_config->GetInteger( |
| 378 | "Renderer", "backend", static_cast<int>(Settings::RendererBackend::OpenGL)); | 372 | "Renderer", "backend", static_cast<int>(Settings::RendererBackend::OpenGL)); |
| 379 | Settings::values.renderer_backend = static_cast<Settings::RendererBackend>(renderer_backend); | 373 | Settings::values.renderer_backend.SetValue( |
| 374 | static_cast<Settings::RendererBackend>(renderer_backend)); | ||
| 380 | Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "debug", false); | 375 | Settings::values.renderer_debug = sdl2_config->GetBoolean("Renderer", "debug", false); |
| 381 | Settings::values.vulkan_device = sdl2_config->GetInteger("Renderer", "vulkan_device", 0); | 376 | Settings::values.vulkan_device.SetValue( |
| 382 | 377 | sdl2_config->GetInteger("Renderer", "vulkan_device", 0)); | |
| 383 | Settings::values.aspect_ratio = | 378 | |
| 384 | static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0)); | 379 | Settings::values.aspect_ratio.SetValue( |
| 385 | Settings::values.max_anisotropy = | 380 | static_cast<int>(sdl2_config->GetInteger("Renderer", "aspect_ratio", 0))); |
| 386 | static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0)); | 381 | Settings::values.max_anisotropy.SetValue( |
| 387 | Settings::values.use_frame_limit = sdl2_config->GetBoolean("Renderer", "use_frame_limit", true); | 382 | static_cast<int>(sdl2_config->GetInteger("Renderer", "max_anisotropy", 0))); |
| 388 | Settings::values.frame_limit = | 383 | Settings::values.use_frame_limit.SetValue( |
| 389 | static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100)); | 384 | sdl2_config->GetBoolean("Renderer", "use_frame_limit", true)); |
| 390 | Settings::values.use_disk_shader_cache = | 385 | Settings::values.frame_limit.SetValue( |
| 391 | sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false); | 386 | static_cast<u16>(sdl2_config->GetInteger("Renderer", "frame_limit", 100))); |
| 387 | Settings::values.use_disk_shader_cache.SetValue( | ||
| 388 | sdl2_config->GetBoolean("Renderer", "use_disk_shader_cache", false)); | ||
| 392 | const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0); | 389 | const int gpu_accuracy_level = sdl2_config->GetInteger("Renderer", "gpu_accuracy", 0); |
| 393 | Settings::values.gpu_accuracy = static_cast<Settings::GPUAccuracy>(gpu_accuracy_level); | 390 | Settings::values.gpu_accuracy.SetValue(static_cast<Settings::GPUAccuracy>(gpu_accuracy_level)); |
| 394 | Settings::values.use_asynchronous_gpu_emulation = | 391 | Settings::values.use_asynchronous_gpu_emulation.SetValue( |
| 395 | sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false); | 392 | sdl2_config->GetBoolean("Renderer", "use_asynchronous_gpu_emulation", false)); |
| 396 | Settings::values.use_vsync = | 393 | Settings::values.use_vsync.SetValue( |
| 397 | static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1)); | 394 | static_cast<u16>(sdl2_config->GetInteger("Renderer", "use_vsync", 1))); |
| 398 | Settings::values.use_assembly_shaders = | 395 | Settings::values.use_assembly_shaders.SetValue( |
| 399 | sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", false); | 396 | sdl2_config->GetBoolean("Renderer", "use_assembly_shaders", false)); |
| 400 | Settings::values.use_fast_gpu_time = | 397 | Settings::values.use_fast_gpu_time.SetValue( |
| 401 | sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true); | 398 | sdl2_config->GetBoolean("Renderer", "use_fast_gpu_time", true)); |
| 402 | 399 | ||
| 403 | Settings::values.bg_red = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0)); | 400 | Settings::values.bg_red.SetValue( |
| 404 | Settings::values.bg_green = | 401 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_red", 0.0))); |
| 405 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0)); | 402 | Settings::values.bg_green.SetValue( |
| 406 | Settings::values.bg_blue = static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0)); | 403 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_green", 0.0))); |
| 404 | Settings::values.bg_blue.SetValue( | ||
| 405 | static_cast<float>(sdl2_config->GetReal("Renderer", "bg_blue", 0.0))); | ||
| 407 | 406 | ||
| 408 | // Audio | 407 | // Audio |
| 409 | Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto"); | 408 | Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto"); |
| 410 | Settings::values.enable_audio_stretching = | 409 | Settings::values.enable_audio_stretching.SetValue( |
| 411 | sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true); | 410 | sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true)); |
| 412 | Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto"); | 411 | 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)); | 412 | Settings::values.volume.SetValue( |
| 413 | static_cast<float>(sdl2_config->GetReal("Audio", "volume", 1))); | ||
| 414 | 414 | ||
| 415 | // Miscellaneous | 415 | // Miscellaneous |
| 416 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); | 416 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Trace"); |
| @@ -428,8 +428,6 @@ void Config::ReadValues() { | |||
| 428 | Settings::values.reporting_services = | 428 | Settings::values.reporting_services = |
| 429 | sdl2_config->GetBoolean("Debugging", "reporting_services", false); | 429 | sdl2_config->GetBoolean("Debugging", "reporting_services", false); |
| 430 | Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false); | 430 | Settings::values.quest_flag = sdl2_config->GetBoolean("Debugging", "quest_flag", false); |
| 431 | Settings::values.disable_cpu_opt = | ||
| 432 | sdl2_config->GetBoolean("Debugging", "disable_cpu_opt", false); | ||
| 433 | Settings::values.disable_macro_jit = | 431 | Settings::values.disable_macro_jit = |
| 434 | sdl2_config->GetBoolean("Debugging", "disable_macro_jit", false); | 432 | sdl2_config->GetBoolean("Debugging", "disable_macro_jit", false); |
| 435 | 433 | ||
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h index 45c07ed5d..5bed47fd7 100644 --- a/src/yuzu_cmd/default_ini.h +++ b/src/yuzu_cmd/default_ini.h | |||
| @@ -97,6 +97,39 @@ udp_pad_index= | |||
| 97 | # 0 (default): Disabled, 1: Enabled | 97 | # 0 (default): Disabled, 1: Enabled |
| 98 | use_multi_core= | 98 | use_multi_core= |
| 99 | 99 | ||
| 100 | [Cpu] | ||
| 101 | # Enable inline page tables optimization (faster guest memory access) | ||
| 102 | # 0: Disabled, 1 (default): Enabled | ||
| 103 | cpuopt_page_tables = | ||
| 104 | |||
| 105 | # Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps) | ||
| 106 | # 0: Disabled, 1 (default): Enabled | ||
| 107 | cpuopt_block_linking = | ||
| 108 | |||
| 109 | # Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns) | ||
| 110 | # 0: Disabled, 1 (default): Enabled | ||
| 111 | cpuopt_return_stack_buffer = | ||
| 112 | |||
| 113 | # Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture) | ||
| 114 | # 0: Disabled, 1 (default): Enabled | ||
| 115 | cpuopt_fast_dispatcher = | ||
| 116 | |||
| 117 | # Enable context elimination CPU Optimization (reduce host memory use for guest context) | ||
| 118 | # 0: Disabled, 1 (default): Enabled | ||
| 119 | cpuopt_context_elimination = | ||
| 120 | |||
| 121 | # Enable constant propagation CPU optimization (basic IR optimization) | ||
| 122 | # 0: Disabled, 1 (default): Enabled | ||
| 123 | cpuopt_const_prop = | ||
| 124 | |||
| 125 | # Enable miscellaneous CPU optimizations (basic IR optimization) | ||
| 126 | # 0: Disabled, 1 (default): Enabled | ||
| 127 | cpuopt_misc_ir = | ||
| 128 | |||
| 129 | # Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access) | ||
| 130 | # 0: Disabled, 1 (default): Enabled | ||
| 131 | cpuopt_reduce_misalign_checks = | ||
| 132 | |||
| 100 | [Renderer] | 133 | [Renderer] |
| 101 | # Which backend API to use. | 134 | # Which backend API to use. |
| 102 | # 0 (default): OpenGL, 1: Vulkan | 135 | # 0 (default): OpenGL, 1: Vulkan |
| @@ -283,9 +316,6 @@ dump_nso=false | |||
| 283 | # Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode | 316 | # Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode |
| 284 | # false: Retail/Normal Mode (default), true: Kiosk Mode | 317 | # false: Retail/Normal Mode (default), true: Kiosk Mode |
| 285 | quest_flag = | 318 | quest_flag = |
| 286 | # Determines whether or not JIT CPU optimizations are enabled | ||
| 287 | # false: Optimizations Enabled, true: Optimizations Disabled | ||
| 288 | disable_cpu_opt = | ||
| 289 | # Enables/Disables the macro JIT compiler | 319 | # Enables/Disables the macro JIT compiler |
| 290 | disable_macro_jit=false | 320 | disable_macro_jit=false |
| 291 | 321 | ||
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"); |
diff --git a/src/yuzu_tester/default_ini.h b/src/yuzu_tester/default_ini.h index 41bbbbf60..3eb64e9d7 100644 --- a/src/yuzu_tester/default_ini.h +++ b/src/yuzu_tester/default_ini.h | |||
| @@ -12,6 +12,39 @@ const char* sdl2_config_file = R"( | |||
| 12 | # 0 (default): Disabled, 1: Enabled | 12 | # 0 (default): Disabled, 1: Enabled |
| 13 | use_multi_core= | 13 | use_multi_core= |
| 14 | 14 | ||
| 15 | [Cpu] | ||
| 16 | # Enable inline page tables optimization (faster guest memory access) | ||
| 17 | # 0: Disabled, 1 (default): Enabled | ||
| 18 | cpuopt_page_tables = | ||
| 19 | |||
| 20 | # Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps) | ||
| 21 | # 0: Disabled, 1 (default): Enabled | ||
| 22 | cpuopt_block_linking = | ||
| 23 | |||
| 24 | # Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns) | ||
| 25 | # 0: Disabled, 1 (default): Enabled | ||
| 26 | cpuopt_return_stack_buffer = | ||
| 27 | |||
| 28 | # Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture) | ||
| 29 | # 0: Disabled, 1 (default): Enabled | ||
| 30 | cpuopt_fast_dispatcher = | ||
| 31 | |||
| 32 | # Enable context elimination CPU Optimization (reduce host memory use for guest context) | ||
| 33 | # 0: Disabled, 1 (default): Enabled | ||
| 34 | cpuopt_context_elimination = | ||
| 35 | |||
| 36 | # Enable constant propagation CPU optimization (basic IR optimization) | ||
| 37 | # 0: Disabled, 1 (default): Enabled | ||
| 38 | cpuopt_const_prop = | ||
| 39 | |||
| 40 | # Enable miscellaneous CPU optimizations (basic IR optimization) | ||
| 41 | # 0: Disabled, 1 (default): Enabled | ||
| 42 | cpuopt_misc_ir = | ||
| 43 | |||
| 44 | # Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access) | ||
| 45 | # 0: Disabled, 1 (default): Enabled | ||
| 46 | cpuopt_reduce_misalign_checks = | ||
| 47 | |||
| 15 | [Renderer] | 48 | [Renderer] |
| 16 | # Whether to use software or hardware rendering. | 49 | # Whether to use software or hardware rendering. |
| 17 | # 0: Software, 1 (default): Hardware | 50 | # 0: Software, 1 (default): Hardware |