summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/ipc_helpers.h2
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp2
-rw-r--r--src/core/hle/kernel/object.h4
-rw-r--r--src/core/hle/kernel/readable_event.cpp3
-rw-r--r--src/core/hle/kernel/svc.cpp10
-rw-r--r--src/core/hle/service/am/am.cpp8
-rw-r--r--src/core/hle/service/am/applets/applets.cpp6
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp2
-rw-r--r--src/core/hle/service/audio/audout_u.cpp2
-rw-r--r--src/core/hle/service/audio/audren_u.cpp4
-rw-r--r--src/core/hle/service/btdrv/btdrv.cpp4
-rw-r--r--src/core/hle/service/btm/btm.cpp8
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp2
-rw-r--r--src/core/hle/service/nfp/nfp.cpp6
-rw-r--r--src/core/hle/service/nifm/nifm.cpp4
-rw-r--r--src/core/hle/service/nim/nim.cpp2
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp2
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp2
-rw-r--r--src/core/hle/service/set/set.cpp56
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp2
-rw-r--r--src/video_core/engines/engine_upload.cpp6
-rw-r--r--src/video_core/engines/engine_upload.h8
-rw-r--r--src/video_core/engines/maxwell_3d.cpp38
-rw-r--r--src/video_core/engines/maxwell_3d.h2
-rw-r--r--src/video_core/gpu_thread.cpp2
-rw-r--r--src/video_core/gpu_thread.h2
-rw-r--r--src/video_core/macro_interpreter.cpp6
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp8
-rw-r--r--src/video_core/renderer_opengl/gl_shader_gen.cpp14
-rw-r--r--src/video_core/renderer_opengl/maxwell_to_gl.h2
-rw-r--r--src/yuzu/CMakeLists.txt2
-rw-r--r--src/yuzu/about_dialog.cpp8
-rw-r--r--src/yuzu/applets/error.cpp2
-rw-r--r--src/yuzu/applets/profile_select.cpp4
-rw-r--r--src/yuzu/bootmanager.cpp1
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp8
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoints.cpp2
-rw-r--r--src/yuzu/debugger/profiler.cpp4
-rw-r--r--src/yuzu/debugger/wait_tree.cpp39
-rw-r--r--src/yuzu/main.cpp25
-rw-r--r--src/yuzu/main.h1
-rw-r--r--src/yuzu/util/spinbox.cpp278
-rw-r--r--src/yuzu/util/spinbox.h86
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp6
-rw-r--r--src/yuzu_cmd/yuzu.cpp1
45 files changed, 172 insertions, 514 deletions
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index ac0e1d796..5bb139483 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -438,7 +438,7 @@ inline float RequestParser::Pop() {
438template <> 438template <>
439inline double RequestParser::Pop() { 439inline double RequestParser::Pop() {
440 const u64 value = Pop<u64>(); 440 const u64 value = Pop<u64>();
441 float real; 441 double real;
442 std::memcpy(&real, &value, sizeof(real)); 442 std::memcpy(&real, &value, sizeof(real));
443 return real; 443 return real;
444} 444}
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index fe710eb6e..42d9dd844 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -58,7 +58,7 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
58 auto& kernel = Core::System::GetInstance().Kernel(); 58 auto& kernel = Core::System::GetInstance().Kernel();
59 if (!writable_event) { 59 if (!writable_event) {
60 // Create event if not provided 60 // Create event if not provided
61 const auto pair = WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, 61 const auto pair = WritableEvent::CreateEventPair(kernel, ResetType::Automatic,
62 "HLE Pause Event: " + reason); 62 "HLE Pause Event: " + reason);
63 writable_event = pair.writable; 63 writable_event = pair.writable;
64 } 64 }
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 332876c27..2821176a7 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -33,8 +33,8 @@ enum class HandleType : u32 {
33}; 33};
34 34
35enum class ResetType { 35enum class ResetType {
36 OneShot, ///< Reset automatically on object acquisition 36 Automatic, ///< Reset automatically on object acquisition
37 Sticky, ///< Never reset automatically 37 Manual, ///< Never reset automatically
38}; 38};
39 39
40class Object : NonCopyable { 40class Object : NonCopyable {
diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp
index c2b798a4e..06463cd26 100644
--- a/src/core/hle/kernel/readable_event.cpp
+++ b/src/core/hle/kernel/readable_event.cpp
@@ -21,8 +21,9 @@ bool ReadableEvent::ShouldWait(const Thread* thread) const {
21void ReadableEvent::Acquire(Thread* thread) { 21void ReadableEvent::Acquire(Thread* thread) {
22 ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); 22 ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
23 23
24 if (reset_type == ResetType::OneShot) 24 if (reset_type == ResetType::Automatic) {
25 signaled = false; 25 signaled = false;
26 }
26} 27}
27 28
28void ReadableEvent::Signal() { 29void ReadableEvent::Signal() {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 2dcf174c5..c23106299 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1255,8 +1255,8 @@ static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_hand
1255 return vm_manager.MapCodeMemory(dst_address, src_address, size); 1255 return vm_manager.MapCodeMemory(dst_address, src_address, size);
1256} 1256}
1257 1257
1258ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address, 1258static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_handle,
1259 u64 src_address, u64 size) { 1259 u64 dst_address, u64 src_address, u64 size) {
1260 LOG_DEBUG(Kernel_SVC, 1260 LOG_DEBUG(Kernel_SVC,
1261 "called. process_handle=0x{:08X}, dst_address=0x{:016X}, src_address=0x{:016X}, " 1261 "called. process_handle=0x{:08X}, dst_address=0x{:016X}, src_address=0x{:016X}, "
1262 "size=0x{:016X}", 1262 "size=0x{:016X}",
@@ -1980,7 +1980,7 @@ static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle
1980 1980
1981 auto& kernel = system.Kernel(); 1981 auto& kernel = system.Kernel();
1982 const auto [readable_event, writable_event] = 1982 const auto [readable_event, writable_event] =
1983 WritableEvent::CreateEventPair(kernel, ResetType::Sticky, "CreateEvent"); 1983 WritableEvent::CreateEventPair(kernel, ResetType::Manual, "CreateEvent");
1984 1984
1985 HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); 1985 HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
1986 1986
@@ -2183,8 +2183,8 @@ static ResultCode GetProcessList(Core::System& system, u32* out_num_processes,
2183 return RESULT_SUCCESS; 2183 return RESULT_SUCCESS;
2184} 2184}
2185 2185
2186ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids, 2186static ResultCode GetThreadList(Core::System& system, u32* out_num_threads, VAddr out_thread_ids,
2187 u32 out_thread_ids_size, Handle debug_handle) { 2187 u32 out_thread_ids_size, Handle debug_handle) {
2188 // TODO: Handle this case when debug events are supported. 2188 // TODO: Handle this case when debug events are supported.
2189 UNIMPLEMENTED_IF(debug_handle != InvalidHandle); 2189 UNIMPLEMENTED_IF(debug_handle != InvalidHandle);
2190 2190
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 26a665bfd..1a32a109f 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -276,7 +276,7 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
276 RegisterHandlers(functions); 276 RegisterHandlers(functions);
277 277
278 auto& kernel = Core::System::GetInstance().Kernel(); 278 auto& kernel = Core::System::GetInstance().Kernel();
279 launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, 279 launchable_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
280 "ISelfController:LaunchableEvent"); 280 "ISelfController:LaunchableEvent");
281} 281}
282 282
@@ -442,10 +442,10 @@ void ISelfController::GetIdleTimeDetectionExtension(Kernel::HLERequestContext& c
442 442
443AppletMessageQueue::AppletMessageQueue() { 443AppletMessageQueue::AppletMessageQueue() {
444 auto& kernel = Core::System::GetInstance().Kernel(); 444 auto& kernel = Core::System::GetInstance().Kernel();
445 on_new_message = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, 445 on_new_message = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
446 "AMMessageQueue:OnMessageRecieved"); 446 "AMMessageQueue:OnMessageRecieved");
447 on_operation_mode_changed = Kernel::WritableEvent::CreateEventPair( 447 on_operation_mode_changed = Kernel::WritableEvent::CreateEventPair(
448 kernel, Kernel::ResetType::OneShot, "AMMessageQueue:OperationModeChanged"); 448 kernel, Kernel::ResetType::Automatic, "AMMessageQueue:OperationModeChanged");
449} 449}
450 450
451AppletMessageQueue::~AppletMessageQueue() = default; 451AppletMessageQueue::~AppletMessageQueue() = default;
@@ -835,6 +835,7 @@ void IStorageAccessor::Write(Kernel::HLERequestContext& ctx) {
835 835
836 IPC::ResponseBuilder rb{ctx, 2}; 836 IPC::ResponseBuilder rb{ctx, 2};
837 rb.Push(ERR_SIZE_OUT_OF_BOUNDS); 837 rb.Push(ERR_SIZE_OUT_OF_BOUNDS);
838 return;
838 } 839 }
839 840
840 std::memcpy(backing.buffer.data() + offset, data.data(), data.size()); 841 std::memcpy(backing.buffer.data() + offset, data.data(), data.size());
@@ -857,6 +858,7 @@ void IStorageAccessor::Read(Kernel::HLERequestContext& ctx) {
857 858
858 IPC::ResponseBuilder rb{ctx, 2}; 859 IPC::ResponseBuilder rb{ctx, 2};
859 rb.Push(ERR_SIZE_OUT_OF_BOUNDS); 860 rb.Push(ERR_SIZE_OUT_OF_BOUNDS);
861 return;
860 } 862 }
861 863
862 ctx.WriteBuffer(backing.buffer.data() + offset, size); 864 ctx.WriteBuffer(backing.buffer.data() + offset, size);
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index 7f70b10df..e812c66e9 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -26,11 +26,11 @@ namespace Service::AM::Applets {
26AppletDataBroker::AppletDataBroker() { 26AppletDataBroker::AppletDataBroker() {
27 auto& kernel = Core::System::GetInstance().Kernel(); 27 auto& kernel = Core::System::GetInstance().Kernel();
28 state_changed_event = Kernel::WritableEvent::CreateEventPair( 28 state_changed_event = Kernel::WritableEvent::CreateEventPair(
29 kernel, Kernel::ResetType::Sticky, "ILibraryAppletAccessor:StateChangedEvent"); 29 kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:StateChangedEvent");
30 pop_out_data_event = Kernel::WritableEvent::CreateEventPair( 30 pop_out_data_event = Kernel::WritableEvent::CreateEventPair(
31 kernel, Kernel::ResetType::Sticky, "ILibraryAppletAccessor:PopDataOutEvent"); 31 kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:PopDataOutEvent");
32 pop_interactive_out_data_event = Kernel::WritableEvent::CreateEventPair( 32 pop_interactive_out_data_event = Kernel::WritableEvent::CreateEventPair(
33 kernel, Kernel::ResetType::Sticky, "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); 33 kernel, Kernel::ResetType::Manual, "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
34} 34}
35 35
36AppletDataBroker::~AppletDataBroker() = default; 36AppletDataBroker::~AppletDataBroker() = default;
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index 51d8c26b4..bd4e38461 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -68,7 +68,7 @@ AOC_U::AOC_U() : ServiceFramework("aoc:u"), add_on_content(AccumulateAOCTitleIDs
68 RegisterHandlers(functions); 68 RegisterHandlers(functions);
69 69
70 auto& kernel = Core::System::GetInstance().Kernel(); 70 auto& kernel = Core::System::GetInstance().Kernel();
71 aoc_change_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, 71 aoc_change_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
72 "GetAddOnContentListChanged:Event"); 72 "GetAddOnContentListChanged:Event");
73} 73}
74 74
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 12875fb42..6ba41b20a 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -67,7 +67,7 @@ public:
67 // This is the event handle used to check if the audio buffer was released 67 // This is the event handle used to check if the audio buffer was released
68 auto& system = Core::System::GetInstance(); 68 auto& system = Core::System::GetInstance();
69 buffer_event = Kernel::WritableEvent::CreateEventPair( 69 buffer_event = Kernel::WritableEvent::CreateEventPair(
70 system.Kernel(), Kernel::ResetType::Sticky, "IAudioOutBufferReleased"); 70 system.Kernel(), Kernel::ResetType::Manual, "IAudioOutBufferReleased");
71 71
72 stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate, 72 stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate,
73 audio_params.channel_count, std::move(unique_name), 73 audio_params.channel_count, std::move(unique_name),
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 1dde6edb7..e69f6cf7f 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -46,7 +46,7 @@ public:
46 46
47 auto& system = Core::System::GetInstance(); 47 auto& system = Core::System::GetInstance();
48 system_event = Kernel::WritableEvent::CreateEventPair( 48 system_event = Kernel::WritableEvent::CreateEventPair(
49 system.Kernel(), Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent"); 49 system.Kernel(), Kernel::ResetType::Manual, "IAudioRenderer:SystemEvent");
50 renderer = std::make_unique<AudioCore::AudioRenderer>(system.CoreTiming(), audren_params, 50 renderer = std::make_unique<AudioCore::AudioRenderer>(system.CoreTiming(), audren_params,
51 system_event.writable); 51 system_event.writable);
52 } 52 }
@@ -178,7 +178,7 @@ public:
178 RegisterHandlers(functions); 178 RegisterHandlers(functions);
179 179
180 auto& kernel = Core::System::GetInstance().Kernel(); 180 auto& kernel = Core::System::GetInstance().Kernel();
181 buffer_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, 181 buffer_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
182 "IAudioOutBufferReleasedEvent"); 182 "IAudioOutBufferReleasedEvent");
183 } 183 }
184 184
diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp
index 974ff8e1a..3c7ca2c44 100644
--- a/src/core/hle/service/btdrv/btdrv.cpp
+++ b/src/core/hle/service/btdrv/btdrv.cpp
@@ -34,8 +34,8 @@ public:
34 RegisterHandlers(functions); 34 RegisterHandlers(functions);
35 35
36 auto& kernel = Core::System::GetInstance().Kernel(); 36 auto& kernel = Core::System::GetInstance().Kernel();
37 register_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, 37 register_event = Kernel::WritableEvent::CreateEventPair(
38 "BT:RegisterEvent"); 38 kernel, Kernel::ResetType::Automatic, "BT:RegisterEvent");
39 } 39 }
40 40
41private: 41private:
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index 4f15c3f19..b439ee7ec 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -57,13 +57,13 @@ public:
57 RegisterHandlers(functions); 57 RegisterHandlers(functions);
58 58
59 auto& kernel = Core::System::GetInstance().Kernel(); 59 auto& kernel = Core::System::GetInstance().Kernel();
60 scan_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, 60 scan_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
61 "IBtmUserCore:ScanEvent"); 61 "IBtmUserCore:ScanEvent");
62 connection_event = Kernel::WritableEvent::CreateEventPair( 62 connection_event = Kernel::WritableEvent::CreateEventPair(
63 kernel, Kernel::ResetType::OneShot, "IBtmUserCore:ConnectionEvent"); 63 kernel, Kernel::ResetType::Automatic, "IBtmUserCore:ConnectionEvent");
64 service_discovery = Kernel::WritableEvent::CreateEventPair( 64 service_discovery = Kernel::WritableEvent::CreateEventPair(
65 kernel, Kernel::ResetType::OneShot, "IBtmUserCore:Discovery"); 65 kernel, Kernel::ResetType::Automatic, "IBtmUserCore:Discovery");
66 config_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, 66 config_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
67 "IBtmUserCore:ConfigEvent"); 67 "IBtmUserCore:ConfigEvent");
68 } 68 }
69 69
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index e7fc7a619..fdd6d79a2 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -170,7 +170,7 @@ void Controller_NPad::InitNewlyAddedControler(std::size_t controller_idx) {
170void Controller_NPad::OnInit() { 170void Controller_NPad::OnInit() {
171 auto& kernel = Core::System::GetInstance().Kernel(); 171 auto& kernel = Core::System::GetInstance().Kernel();
172 styleset_changed_event = Kernel::WritableEvent::CreateEventPair( 172 styleset_changed_event = Kernel::WritableEvent::CreateEventPair(
173 kernel, Kernel::ResetType::OneShot, "npad:NpadStyleSetChanged"); 173 kernel, Kernel::ResetType::Automatic, "npad:NpadStyleSetChanged");
174 174
175 if (!IsControllerActivated()) { 175 if (!IsControllerActivated()) {
176 return; 176 return;
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index c6babdd4d..a5cb06f8a 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -26,7 +26,7 @@ constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152);
26Module::Interface::Interface(std::shared_ptr<Module> module, const char* name) 26Module::Interface::Interface(std::shared_ptr<Module> module, const char* name)
27 : ServiceFramework(name), module(std::move(module)) { 27 : ServiceFramework(name), module(std::move(module)) {
28 auto& kernel = Core::System::GetInstance().Kernel(); 28 auto& kernel = Core::System::GetInstance().Kernel();
29 nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, 29 nfc_tag_load = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
30 "IUser:NFCTagDetected"); 30 "IUser:NFCTagDetected");
31} 31}
32 32
@@ -67,9 +67,9 @@ public:
67 67
68 auto& kernel = Core::System::GetInstance().Kernel(); 68 auto& kernel = Core::System::GetInstance().Kernel();
69 deactivate_event = Kernel::WritableEvent::CreateEventPair( 69 deactivate_event = Kernel::WritableEvent::CreateEventPair(
70 kernel, Kernel::ResetType::OneShot, "IUser:DeactivateEvent"); 70 kernel, Kernel::ResetType::Automatic, "IUser:DeactivateEvent");
71 availability_change_event = Kernel::WritableEvent::CreateEventPair( 71 availability_change_event = Kernel::WritableEvent::CreateEventPair(
72 kernel, Kernel::ResetType::OneShot, "IUser:AvailabilityChangeEvent"); 72 kernel, Kernel::ResetType::Automatic, "IUser:AvailabilityChangeEvent");
73 } 73 }
74 74
75private: 75private:
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index f92571008..76b12b482 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -62,9 +62,9 @@ public:
62 RegisterHandlers(functions); 62 RegisterHandlers(functions);
63 63
64 auto& kernel = Core::System::GetInstance().Kernel(); 64 auto& kernel = Core::System::GetInstance().Kernel();
65 event1 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, 65 event1 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
66 "IRequest:Event1"); 66 "IRequest:Event1");
67 event2 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, 67 event2 = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
68 "IRequest:Event2"); 68 "IRequest:Event2");
69 } 69 }
70 70
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index 0dabcd23b..f319a3ca1 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -141,7 +141,7 @@ public:
141 141
142 auto& kernel = Core::System::GetInstance().Kernel(); 142 auto& kernel = Core::System::GetInstance().Kernel();
143 finished_event = Kernel::WritableEvent::CreateEventPair( 143 finished_event = Kernel::WritableEvent::CreateEventPair(
144 kernel, Kernel::ResetType::OneShot, 144 kernel, Kernel::ResetType::Automatic,
145 "IEnsureNetworkClockAvailabilityService:FinishEvent"); 145 "IEnsureNetworkClockAvailabilityService:FinishEvent");
146 } 146 }
147 147
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index 3b9ab4b14..b60fc748b 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -129,7 +129,7 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name)
129 RegisterHandlers(functions); 129 RegisterHandlers(functions);
130 130
131 auto& kernel = Core::System::GetInstance().Kernel(); 131 auto& kernel = Core::System::GetInstance().Kernel();
132 query_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot, 132 query_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Automatic,
133 "NVDRV::query_event"); 133 "NVDRV::query_event");
134} 134}
135 135
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index 4d150fc71..5731e815f 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -16,7 +16,7 @@ namespace Service::NVFlinger {
16 16
17BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { 17BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {
18 auto& kernel = Core::System::GetInstance().Kernel(); 18 auto& kernel = Core::System::GetInstance().Kernel();
19 buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, 19 buffer_wait_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
20 "BufferQueue NativeHandle"); 20 "BufferQueue NativeHandle");
21} 21}
22 22
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index 4ecb6bcef..298d85011 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -2,16 +2,15 @@
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
5#include <algorithm>
5#include <chrono> 6#include <chrono>
6#include "common/logging/log.h" 7#include "common/logging/log.h"
7#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/client_port.h"
9#include "core/hle/kernel/client_session.h"
10#include "core/hle/service/set/set.h" 9#include "core/hle/service/set/set.h"
11#include "core/settings.h" 10#include "core/settings.h"
12 11
13namespace Service::Set { 12namespace Service::Set {
14 13namespace {
15constexpr std::array<LanguageCode, 17> available_language_codes = {{ 14constexpr std::array<LanguageCode, 17> available_language_codes = {{
16 LanguageCode::JA, 15 LanguageCode::JA,
17 LanguageCode::EN_US, 16 LanguageCode::EN_US,
@@ -32,41 +31,35 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{
32 LanguageCode::ZH_HANT, 31 LanguageCode::ZH_HANT,
33}}; 32}};
34 33
35constexpr std::size_t pre4_0_0_max_entries = 0xF; 34constexpr std::size_t pre4_0_0_max_entries = 15;
36constexpr std::size_t post4_0_0_max_entries = 0x40; 35constexpr std::size_t post4_0_0_max_entries = 17;
37 36
38constexpr ResultCode ERR_INVALID_LANGUAGE{ErrorModule::Settings, 625}; 37constexpr ResultCode ERR_INVALID_LANGUAGE{ErrorModule::Settings, 625};
39 38
40LanguageCode GetLanguageCodeFromIndex(std::size_t index) { 39void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t num_language_codes) {
41 return available_language_codes.at(index); 40 IPC::ResponseBuilder rb{ctx, 3};
41 rb.Push(RESULT_SUCCESS);
42 rb.Push(static_cast<u32>(num_language_codes));
42} 43}
43 44
44template <std::size_t size> 45void GetAvailableLanguageCodesImpl(Kernel::HLERequestContext& ctx, std::size_t max_size) {
45static std::array<LanguageCode, size> MakeLanguageCodeSubset() { 46 const std::size_t requested_amount = ctx.GetWriteBufferSize() / sizeof(LanguageCode);
46 std::array<LanguageCode, size> arr; 47 const std::size_t copy_amount = std::min(requested_amount, max_size);
47 std::copy_n(available_language_codes.begin(), size, arr.begin()); 48 const std::size_t copy_size = copy_amount * sizeof(LanguageCode);
48 return arr; 49
50 ctx.WriteBuffer(available_language_codes.data(), copy_size);
51 PushResponseLanguageCode(ctx, copy_amount);
49} 52}
53} // Anonymous namespace
50 54
51static void PushResponseLanguageCode(Kernel::HLERequestContext& ctx, std::size_t max_size) { 55LanguageCode GetLanguageCodeFromIndex(std::size_t index) {
52 IPC::ResponseBuilder rb{ctx, 3}; 56 return available_language_codes.at(index);
53 rb.Push(RESULT_SUCCESS);
54 if (available_language_codes.size() > max_size) {
55 rb.Push(static_cast<u32>(max_size));
56 } else {
57 rb.Push(static_cast<u32>(available_language_codes.size()));
58 }
59} 57}
60 58
61void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) { 59void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
62 LOG_DEBUG(Service_SET, "called"); 60 LOG_DEBUG(Service_SET, "called");
63 61
64 if (available_language_codes.size() > pre4_0_0_max_entries) { 62 GetAvailableLanguageCodesImpl(ctx, pre4_0_0_max_entries);
65 ctx.WriteBuffer(MakeLanguageCodeSubset<pre4_0_0_max_entries>());
66 } else {
67 ctx.WriteBuffer(available_language_codes);
68 }
69 PushResponseLanguageCode(ctx, pre4_0_0_max_entries);
70} 63}
71 64
72void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) { 65void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) {
@@ -87,12 +80,7 @@ void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) {
87void SET::GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx) { 80void SET::GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx) {
88 LOG_DEBUG(Service_SET, "called"); 81 LOG_DEBUG(Service_SET, "called");
89 82
90 if (available_language_codes.size() > post4_0_0_max_entries) { 83 GetAvailableLanguageCodesImpl(ctx, post4_0_0_max_entries);
91 ctx.WriteBuffer(MakeLanguageCodeSubset<post4_0_0_max_entries>());
92 } else {
93 ctx.WriteBuffer(available_language_codes);
94 }
95 PushResponseLanguageCode(ctx, post4_0_0_max_entries);
96} 84}
97 85
98void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) { 86void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) {
@@ -102,9 +90,9 @@ void SET::GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx) {
102} 90}
103 91
104void SET::GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx) { 92void SET::GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx) {
105 PushResponseLanguageCode(ctx, post4_0_0_max_entries);
106
107 LOG_DEBUG(Service_SET, "called"); 93 LOG_DEBUG(Service_SET, "called");
94
95 PushResponseLanguageCode(ctx, post4_0_0_max_entries);
108} 96}
109 97
110void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) { 98void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index 01d80311b..a8d088305 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -17,7 +17,7 @@ namespace Service::VI {
17 17
18Display::Display(u64 id, std::string name) : id{id}, name{std::move(name)} { 18Display::Display(u64 id, std::string name) : id{id}, name{std::move(name)} {
19 auto& kernel = Core::System::GetInstance().Kernel(); 19 auto& kernel = Core::System::GetInstance().Kernel();
20 vsync_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Sticky, 20 vsync_event = Kernel::WritableEvent::CreateEventPair(kernel, Kernel::ResetType::Manual,
21 fmt::format("Display VSync Event {}", id)); 21 fmt::format("Display VSync Event {}", id));
22} 22}
23 23
diff --git a/src/video_core/engines/engine_upload.cpp b/src/video_core/engines/engine_upload.cpp
index f8aa4ff55..082a40cd9 100644
--- a/src/video_core/engines/engine_upload.cpp
+++ b/src/video_core/engines/engine_upload.cpp
@@ -2,6 +2,8 @@
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
5#include <cstring>
6
5#include "common/assert.h" 7#include "common/assert.h"
6#include "video_core/engines/engine_upload.h" 8#include "video_core/engines/engine_upload.h"
7#include "video_core/memory_manager.h" 9#include "video_core/memory_manager.h"
@@ -10,7 +12,9 @@
10namespace Tegra::Engines::Upload { 12namespace Tegra::Engines::Upload {
11 13
12State::State(MemoryManager& memory_manager, Registers& regs) 14State::State(MemoryManager& memory_manager, Registers& regs)
13 : memory_manager(memory_manager), regs(regs) {} 15 : regs{regs}, memory_manager{memory_manager} {}
16
17State::~State() = default;
14 18
15void State::ProcessExec(const bool is_linear) { 19void State::ProcessExec(const bool is_linear) {
16 write_offset = 0; 20 write_offset = 0;
diff --git a/src/video_core/engines/engine_upload.h b/src/video_core/engines/engine_upload.h
index 9c6e0d21c..ef4f5839a 100644
--- a/src/video_core/engines/engine_upload.h
+++ b/src/video_core/engines/engine_upload.h
@@ -4,10 +4,8 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <cstddef>
8#include <vector> 7#include <vector>
9#include "common/bit_field.h" 8#include "common/bit_field.h"
10#include "common/common_funcs.h"
11#include "common/common_types.h" 9#include "common/common_types.h"
12 10
13namespace Tegra { 11namespace Tegra {
@@ -57,10 +55,10 @@ struct Registers {
57class State { 55class State {
58public: 56public:
59 State(MemoryManager& memory_manager, Registers& regs); 57 State(MemoryManager& memory_manager, Registers& regs);
60 ~State() = default; 58 ~State();
61 59
62 void ProcessExec(const bool is_linear); 60 void ProcessExec(bool is_linear);
63 void ProcessData(const u32 data, const bool is_last_call); 61 void ProcessData(u32 data, bool is_last_call);
64 62
65private: 63private:
66 u32 write_offset = 0; 64 u32 write_offset = 0;
diff --git a/src/video_core/engines/maxwell_3d.cpp b/src/video_core/engines/maxwell_3d.cpp
index d7b586db9..39968d403 100644
--- a/src/video_core/engines/maxwell_3d.cpp
+++ b/src/video_core/engines/maxwell_3d.cpp
@@ -34,9 +34,9 @@ void Maxwell3D::InitializeRegisterDefaults() {
34 34
35 // Depth range near/far is not always set, but is expected to be the default 0.0f, 1.0f. This is 35 // Depth range near/far is not always set, but is expected to be the default 0.0f, 1.0f. This is
36 // needed for ARMS. 36 // needed for ARMS.
37 for (std::size_t viewport{}; viewport < Regs::NumViewports; ++viewport) { 37 for (auto& viewport : regs.viewports) {
38 regs.viewports[viewport].depth_range_near = 0.0f; 38 viewport.depth_range_near = 0.0f;
39 regs.viewports[viewport].depth_range_far = 1.0f; 39 viewport.depth_range_far = 1.0f;
40 } 40 }
41 41
42 // Doom and Bomberman seems to use the uninitialized registers and just enable blend 42 // Doom and Bomberman seems to use the uninitialized registers and just enable blend
@@ -47,13 +47,13 @@ void Maxwell3D::InitializeRegisterDefaults() {
47 regs.blend.equation_a = Regs::Blend::Equation::Add; 47 regs.blend.equation_a = Regs::Blend::Equation::Add;
48 regs.blend.factor_source_a = Regs::Blend::Factor::One; 48 regs.blend.factor_source_a = Regs::Blend::Factor::One;
49 regs.blend.factor_dest_a = Regs::Blend::Factor::Zero; 49 regs.blend.factor_dest_a = Regs::Blend::Factor::Zero;
50 for (std::size_t blend_index = 0; blend_index < Regs::NumRenderTargets; blend_index++) { 50 for (auto& blend : regs.independent_blend) {
51 regs.independent_blend[blend_index].equation_rgb = Regs::Blend::Equation::Add; 51 blend.equation_rgb = Regs::Blend::Equation::Add;
52 regs.independent_blend[blend_index].factor_source_rgb = Regs::Blend::Factor::One; 52 blend.factor_source_rgb = Regs::Blend::Factor::One;
53 regs.independent_blend[blend_index].factor_dest_rgb = Regs::Blend::Factor::Zero; 53 blend.factor_dest_rgb = Regs::Blend::Factor::Zero;
54 regs.independent_blend[blend_index].equation_a = Regs::Blend::Equation::Add; 54 blend.equation_a = Regs::Blend::Equation::Add;
55 regs.independent_blend[blend_index].factor_source_a = Regs::Blend::Factor::One; 55 blend.factor_source_a = Regs::Blend::Factor::One;
56 regs.independent_blend[blend_index].factor_dest_a = Regs::Blend::Factor::Zero; 56 blend.factor_dest_a = Regs::Blend::Factor::Zero;
57 } 57 }
58 regs.stencil_front_op_fail = Regs::StencilOp::Keep; 58 regs.stencil_front_op_fail = Regs::StencilOp::Keep;
59 regs.stencil_front_op_zfail = Regs::StencilOp::Keep; 59 regs.stencil_front_op_zfail = Regs::StencilOp::Keep;
@@ -75,11 +75,11 @@ void Maxwell3D::InitializeRegisterDefaults() {
75 75
76 // TODO(bunnei): Some games do not initialize the color masks (e.g. Sonic Mania). Assuming a 76 // TODO(bunnei): Some games do not initialize the color masks (e.g. Sonic Mania). Assuming a
77 // default of enabled fixes rendering here. 77 // default of enabled fixes rendering here.
78 for (std::size_t color_mask = 0; color_mask < Regs::NumRenderTargets; color_mask++) { 78 for (auto& color_mask : regs.color_mask) {
79 regs.color_mask[color_mask].R.Assign(1); 79 color_mask.R.Assign(1);
80 regs.color_mask[color_mask].G.Assign(1); 80 color_mask.G.Assign(1);
81 regs.color_mask[color_mask].B.Assign(1); 81 color_mask.B.Assign(1);
82 regs.color_mask[color_mask].A.Assign(1); 82 color_mask.A.Assign(1);
83 } 83 }
84 84
85 // Commercial games seem to assume this value is enabled and nouveau sets this value manually. 85 // Commercial games seem to assume this value is enabled and nouveau sets this value manually.
@@ -178,13 +178,13 @@ void Maxwell3D::CallMethod(const GPU::MethodCall& method_call) {
178 178
179 // Vertex buffer 179 // Vertex buffer
180 if (method >= MAXWELL3D_REG_INDEX(vertex_array) && 180 if (method >= MAXWELL3D_REG_INDEX(vertex_array) &&
181 method < MAXWELL3D_REG_INDEX(vertex_array) + 4 * 32) { 181 method < MAXWELL3D_REG_INDEX(vertex_array) + 4 * Regs::NumVertexArrays) {
182 dirty_flags.vertex_array.set((method - MAXWELL3D_REG_INDEX(vertex_array)) >> 2); 182 dirty_flags.vertex_array.set((method - MAXWELL3D_REG_INDEX(vertex_array)) >> 2);
183 } else if (method >= MAXWELL3D_REG_INDEX(vertex_array_limit) && 183 } else if (method >= MAXWELL3D_REG_INDEX(vertex_array_limit) &&
184 method < MAXWELL3D_REG_INDEX(vertex_array_limit) + 2 * 32) { 184 method < MAXWELL3D_REG_INDEX(vertex_array_limit) + 2 * Regs::NumVertexArrays) {
185 dirty_flags.vertex_array.set((method - MAXWELL3D_REG_INDEX(vertex_array_limit)) >> 1); 185 dirty_flags.vertex_array.set((method - MAXWELL3D_REG_INDEX(vertex_array_limit)) >> 1);
186 } else if (method >= MAXWELL3D_REG_INDEX(instanced_arrays) && 186 } else if (method >= MAXWELL3D_REG_INDEX(instanced_arrays) &&
187 method < MAXWELL3D_REG_INDEX(instanced_arrays) + 32) { 187 method < MAXWELL3D_REG_INDEX(instanced_arrays) + Regs::NumVertexArrays) {
188 dirty_flags.vertex_array.set(method - MAXWELL3D_REG_INDEX(instanced_arrays)); 188 dirty_flags.vertex_array.set(method - MAXWELL3D_REG_INDEX(instanced_arrays));
189 } 189 }
190 } 190 }
@@ -442,7 +442,7 @@ Texture::TICEntry Maxwell3D::GetTICEntry(u32 tic_index) const {
442 const auto a_type = tic_entry.a_type.Value(); 442 const auto a_type = tic_entry.a_type.Value();
443 443
444 // TODO(Subv): Different data types for separate components are not supported 444 // TODO(Subv): Different data types for separate components are not supported
445 ASSERT(r_type == g_type && r_type == b_type && r_type == a_type); 445 DEBUG_ASSERT(r_type == g_type && r_type == b_type && r_type == a_type);
446 446
447 return tic_entry; 447 return tic_entry;
448} 448}
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index 4883b582a..48e4fec33 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -6,6 +6,7 @@
6 6
7#include <array> 7#include <array>
8#include <bitset> 8#include <bitset>
9#include <type_traits>
9#include <unordered_map> 10#include <unordered_map>
10#include <vector> 11#include <vector>
11 12
@@ -1107,6 +1108,7 @@ public:
1107 } regs{}; 1108 } regs{};
1108 1109
1109 static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size"); 1110 static_assert(sizeof(Regs) == Regs::NUM_REGS * sizeof(u32), "Maxwell3D Regs has wrong size");
1111 static_assert(std::is_trivially_copyable_v<Regs>, "Maxwell3D Regs must be trivially copyable");
1110 1112
1111 struct State { 1113 struct State {
1112 struct ConstBufferInfo { 1114 struct ConstBufferInfo {
diff --git a/src/video_core/gpu_thread.cpp b/src/video_core/gpu_thread.cpp
index 03856013f..1e2ff46b0 100644
--- a/src/video_core/gpu_thread.cpp
+++ b/src/video_core/gpu_thread.cpp
@@ -118,7 +118,7 @@ void SynchState::WaitForSynchronization(u64 fence) {
118 // Wait for the GPU to be idle (all commands to be executed) 118 // Wait for the GPU to be idle (all commands to be executed)
119 { 119 {
120 MICROPROFILE_SCOPE(GPU_wait); 120 MICROPROFILE_SCOPE(GPU_wait);
121 std::unique_lock<std::mutex> lock{synchronization_mutex}; 121 std::unique_lock lock{synchronization_mutex};
122 synchronization_condition.wait(lock, [this, fence] { return signaled_fence >= fence; }); 122 synchronization_condition.wait(lock, [this, fence] { return signaled_fence >= fence; });
123 } 123 }
124} 124}
diff --git a/src/video_core/gpu_thread.h b/src/video_core/gpu_thread.h
index 64a3335ba..05a168a72 100644
--- a/src/video_core/gpu_thread.h
+++ b/src/video_core/gpu_thread.h
@@ -103,7 +103,7 @@ struct SynchState final {
103 103
104 void TrySynchronize() { 104 void TrySynchronize() {
105 if (IsSynchronized()) { 105 if (IsSynchronized()) {
106 std::lock_guard<std::mutex> lock{synchronization_mutex}; 106 std::lock_guard lock{synchronization_mutex};
107 synchronization_condition.notify_one(); 107 synchronization_condition.notify_one();
108 } 108 }
109 } 109 }
diff --git a/src/video_core/macro_interpreter.cpp b/src/video_core/macro_interpreter.cpp
index 524d9ea5a..fbea107ca 100644
--- a/src/video_core/macro_interpreter.cpp
+++ b/src/video_core/macro_interpreter.cpp
@@ -118,10 +118,10 @@ bool MacroInterpreter::Step(u32 offset, bool is_delay_slot) {
118 static_cast<u32>(opcode.operation.Value())); 118 static_cast<u32>(opcode.operation.Value()));
119 } 119 }
120 120
121 if (opcode.is_exit) { 121 // An instruction with the Exit flag will not actually
122 // cause an exit if it's executed inside a delay slot.
123 if (opcode.is_exit && !is_delay_slot) {
122 // Exit has a delay slot, execute the next instruction 124 // Exit has a delay slot, execute the next instruction
123 // Note: Executing an exit during a branch delay slot will cause the instruction at the
124 // branch target to be executed before exiting.
125 Step(offset, true); 125 Step(offset, true);
126 return false; 126 return false;
127 } 127 }
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 3cc945235..dbd8049f5 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -261,8 +261,8 @@ DrawParameters RasterizerOpenGL::SetupDraw() {
261 // MakeQuadArray always generates u32 indexes 261 // MakeQuadArray always generates u32 indexes
262 params.index_format = GL_UNSIGNED_INT; 262 params.index_format = GL_UNSIGNED_INT;
263 params.count = (regs.vertex_buffer.count / 4) * 6; 263 params.count = (regs.vertex_buffer.count / 4) * 6;
264 params.index_buffer_offset = 264 params.index_buffer_offset = primitive_assembler.MakeQuadArray(
265 primitive_assembler.MakeQuadArray(regs.vertex_buffer.first, params.count); 265 regs.vertex_buffer.first, regs.vertex_buffer.count);
266 } 266 }
267 return params; 267 return params;
268 } 268 }
@@ -1135,7 +1135,9 @@ void RasterizerOpenGL::SyncTransformFeedback() {
1135 1135
1136void RasterizerOpenGL::SyncPointState() { 1136void RasterizerOpenGL::SyncPointState() {
1137 const auto& regs = system.GPU().Maxwell3D().regs; 1137 const auto& regs = system.GPU().Maxwell3D().regs;
1138 state.point.size = regs.point_size; 1138 // Limit the point size to 1 since nouveau sometimes sets a point size of 0 (and that's invalid
1139 // in OpenGL).
1140 state.point.size = std::max(1.0f, regs.point_size);
1139} 1141}
1140 1142
1141void RasterizerOpenGL::SyncPolygonOffset() { 1143void RasterizerOpenGL::SyncPolygonOffset() {
diff --git a/src/video_core/renderer_opengl/gl_shader_gen.cpp b/src/video_core/renderer_opengl/gl_shader_gen.cpp
index 6abf948f8..7ab0b4553 100644
--- a/src/video_core/renderer_opengl/gl_shader_gen.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_gen.cpp
@@ -33,14 +33,14 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform vs_config {
33}; 33};
34 34
35)"; 35)";
36 ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 36 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET);
37 ProgramResult program = 37 ProgramResult program =
38 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Vertex, "vertex"); 38 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Vertex, "vertex");
39 39
40 out += program.first; 40 out += program.first;
41 41
42 if (setup.IsDualProgram()) { 42 if (setup.IsDualProgram()) {
43 ShaderIR program_ir_b(setup.program.code_b, PROGRAM_OFFSET); 43 const ShaderIR program_ir_b(setup.program.code_b, PROGRAM_OFFSET);
44 ProgramResult program_b = 44 ProgramResult program_b =
45 Decompile(device, program_ir_b, Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b"); 45 Decompile(device, program_ir_b, Maxwell3D::Regs::ShaderStage::Vertex, "vertex_b");
46 46
@@ -76,7 +76,7 @@ void main() {
76 } 76 }
77})"; 77})";
78 78
79 return {out, program.second}; 79 return {std::move(out), std::move(program.second)};
80} 80}
81 81
82ProgramResult GenerateGeometryShader(const Device& device, const ShaderSetup& setup) { 82ProgramResult GenerateGeometryShader(const Device& device, const ShaderSetup& setup) {
@@ -97,7 +97,7 @@ layout (std140, binding = EMULATION_UBO_BINDING) uniform gs_config {
97}; 97};
98 98
99)"; 99)";
100 ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 100 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET);
101 ProgramResult program = 101 ProgramResult program =
102 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Geometry, "geometry"); 102 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Geometry, "geometry");
103 out += program.first; 103 out += program.first;
@@ -107,7 +107,7 @@ void main() {
107 execute_geometry(); 107 execute_geometry();
108};)"; 108};)";
109 109
110 return {out, program.second}; 110 return {std::move(out), std::move(program.second)};
111} 111}
112 112
113ProgramResult GenerateFragmentShader(const Device& device, const ShaderSetup& setup) { 113ProgramResult GenerateFragmentShader(const Device& device, const ShaderSetup& setup) {
@@ -160,7 +160,7 @@ bool AlphaFunc(in float value) {
160} 160}
161 161
162)"; 162)";
163 ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET); 163 const ShaderIR program_ir(setup.program.code, PROGRAM_OFFSET);
164 ProgramResult program = 164 ProgramResult program =
165 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Fragment, "fragment"); 165 Decompile(device, program_ir, Maxwell3D::Regs::ShaderStage::Fragment, "fragment");
166 166
@@ -172,7 +172,7 @@ void main() {
172} 172}
173 173
174)"; 174)";
175 return {out, program.second}; 175 return {std::move(out), std::move(program.second)};
176} 176}
177 177
178} // namespace OpenGL::GLShader 178} // namespace OpenGL::GLShader
diff --git a/src/video_core/renderer_opengl/maxwell_to_gl.h b/src/video_core/renderer_opengl/maxwell_to_gl.h
index 95b773135..ed7b5cff0 100644
--- a/src/video_core/renderer_opengl/maxwell_to_gl.h
+++ b/src/video_core/renderer_opengl/maxwell_to_gl.h
@@ -126,6 +126,8 @@ inline GLenum PrimitiveTopology(Maxwell::PrimitiveTopology topology) {
126 return GL_TRIANGLES; 126 return GL_TRIANGLES;
127 case Maxwell::PrimitiveTopology::TriangleStrip: 127 case Maxwell::PrimitiveTopology::TriangleStrip:
128 return GL_TRIANGLE_STRIP; 128 return GL_TRIANGLE_STRIP;
129 case Maxwell::PrimitiveTopology::TriangleFan:
130 return GL_TRIANGLE_FAN;
129 default: 131 default:
130 LOG_CRITICAL(Render_OpenGL, "Unimplemented topology={}", static_cast<u32>(topology)); 132 LOG_CRITICAL(Render_OpenGL, "Unimplemented topology={}", static_cast<u32>(topology));
131 UNREACHABLE(); 133 UNREACHABLE();
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 5138bd9a3..7e883991a 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -82,8 +82,6 @@ add_executable(yuzu
82 util/limitable_input_dialog.h 82 util/limitable_input_dialog.h
83 util/sequence_dialog/sequence_dialog.cpp 83 util/sequence_dialog/sequence_dialog.cpp
84 util/sequence_dialog/sequence_dialog.h 84 util/sequence_dialog/sequence_dialog.h
85 util/spinbox.cpp
86 util/spinbox.h
87 util/util.cpp 85 util/util.cpp
88 util/util.h 86 util/util.h
89 compatdb.cpp 87 compatdb.cpp
diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp
index 3efa65a38..d39b3f07a 100644
--- a/src/yuzu/about_dialog.cpp
+++ b/src/yuzu/about_dialog.cpp
@@ -9,10 +9,10 @@
9 9
10AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) { 10AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) {
11 ui->setupUi(this); 11 ui->setupUi(this);
12 ui->labelLogo->setPixmap(QIcon::fromTheme("yuzu").pixmap(200)); 12 ui->labelLogo->setPixmap(QIcon::fromTheme(QStringLiteral("yuzu")).pixmap(200));
13 ui->labelBuildInfo->setText( 13 ui->labelBuildInfo->setText(ui->labelBuildInfo->text().arg(
14 ui->labelBuildInfo->text().arg(Common::g_build_fullname, Common::g_scm_branch, 14 QString::fromUtf8(Common::g_build_fullname), QString::fromUtf8(Common::g_scm_branch),
15 Common::g_scm_desc, QString(Common::g_build_date).left(10))); 15 QString::fromUtf8(Common::g_scm_desc), QString::fromUtf8(Common::g_build_date).left(10)));
16} 16}
17 17
18AboutDialog::~AboutDialog() = default; 18AboutDialog::~AboutDialog() = default;
diff --git a/src/yuzu/applets/error.cpp b/src/yuzu/applets/error.cpp
index 1fb2fe277..106dde9e2 100644
--- a/src/yuzu/applets/error.cpp
+++ b/src/yuzu/applets/error.cpp
@@ -54,6 +54,6 @@ void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_te
54 54
55void QtErrorDisplay::MainWindowFinishedError() { 55void QtErrorDisplay::MainWindowFinishedError() {
56 // Acquire the HLE mutex 56 // Acquire the HLE mutex
57 std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock); 57 std::lock_guard lock{HLE::g_hle_lock};
58 callback(); 58 callback();
59} 59}
diff --git a/src/yuzu/applets/profile_select.cpp b/src/yuzu/applets/profile_select.cpp
index 743b24d76..7fbc9deeb 100644
--- a/src/yuzu/applets/profile_select.cpp
+++ b/src/yuzu/applets/profile_select.cpp
@@ -84,10 +84,10 @@ QtProfileSelectionDialog::QtProfileSelectionDialog(QWidget* parent)
84 tree_view->setContextMenuPolicy(Qt::NoContextMenu); 84 tree_view->setContextMenuPolicy(Qt::NoContextMenu);
85 85
86 item_model->insertColumns(0, 1); 86 item_model->insertColumns(0, 1);
87 item_model->setHeaderData(0, Qt::Horizontal, "Users"); 87 item_model->setHeaderData(0, Qt::Horizontal, tr("Users"));
88 88
89 // We must register all custom types with the Qt Automoc system so that we are able to use it 89 // We must register all custom types with the Qt Automoc system so that we are able to use it
90 // with signals/slots. In this case, QList falls under the umbrells of custom types. 90 // with signals/slots. In this case, QList falls under the umbrella of custom types.
91 qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>"); 91 qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>");
92 92
93 layout->setContentsMargins(0, 0, 0, 0); 93 layout->setContentsMargins(0, 0, 0, 0);
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 5c98636c5..810954b36 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -379,6 +379,7 @@ void GRenderWindow::InitRenderTarget() {
379 fmt.setVersion(4, 3); 379 fmt.setVersion(4, 3);
380 if (Settings::values.use_compatibility_profile) { 380 if (Settings::values.use_compatibility_profile) {
381 fmt.setProfile(QSurfaceFormat::CompatibilityProfile); 381 fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
382 fmt.setOption(QSurfaceFormat::FormatOption::DeprecatedFunctions);
382 } else { 383 } else {
383 fmt.setProfile(QSurfaceFormat::CoreProfile); 384 fmt.setProfile(QSurfaceFormat::CoreProfile);
384 } 385 }
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index c299c0b5b..08ea41b0f 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -69,16 +69,20 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
69ConfigureGraphics::~ConfigureGraphics() = default; 69ConfigureGraphics::~ConfigureGraphics() = default;
70 70
71void ConfigureGraphics::setConfiguration() { 71void ConfigureGraphics::setConfiguration() {
72 const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
73
72 ui->resolution_factor_combobox->setCurrentIndex( 74 ui->resolution_factor_combobox->setCurrentIndex(
73 static_cast<int>(FromResolutionFactor(Settings::values.resolution_factor))); 75 static_cast<int>(FromResolutionFactor(Settings::values.resolution_factor)));
74 ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit); 76 ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit);
75 ui->frame_limit->setValue(Settings::values.frame_limit); 77 ui->frame_limit->setValue(Settings::values.frame_limit);
78 ui->use_compatibility_profile->setEnabled(runtime_lock);
76 ui->use_compatibility_profile->setChecked(Settings::values.use_compatibility_profile); 79 ui->use_compatibility_profile->setChecked(Settings::values.use_compatibility_profile);
80 ui->use_disk_shader_cache->setEnabled(runtime_lock);
77 ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache); 81 ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache);
78 ui->use_accurate_gpu_emulation->setChecked(Settings::values.use_accurate_gpu_emulation); 82 ui->use_accurate_gpu_emulation->setChecked(Settings::values.use_accurate_gpu_emulation);
79 ui->use_asynchronous_gpu_emulation->setEnabled(!Core::System::GetInstance().IsPoweredOn()); 83 ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock);
80 ui->use_asynchronous_gpu_emulation->setChecked(Settings::values.use_asynchronous_gpu_emulation); 84 ui->use_asynchronous_gpu_emulation->setChecked(Settings::values.use_asynchronous_gpu_emulation);
81 ui->force_30fps_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn()); 85 ui->force_30fps_mode->setEnabled(runtime_lock);
82 ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode); 86 ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode);
83 UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green, 87 UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green,
84 Settings::values.bg_blue)); 88 Settings::values.bg_blue));
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
index 67ed0ba6d..1c80082a4 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
+++ b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
@@ -135,7 +135,7 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(
135 std::shared_ptr<Tegra::DebugContext> debug_context, QWidget* parent) 135 std::shared_ptr<Tegra::DebugContext> debug_context, QWidget* parent)
136 : QDockWidget(tr("Maxwell Breakpoints"), parent), Tegra::DebugContext::BreakPointObserver( 136 : QDockWidget(tr("Maxwell Breakpoints"), parent), Tegra::DebugContext::BreakPointObserver(
137 debug_context) { 137 debug_context) {
138 setObjectName("TegraBreakPointsWidget"); 138 setObjectName(QStringLiteral("TegraBreakPointsWidget"));
139 139
140 status_text = new QLabel(tr("Emulation running")); 140 status_text = new QLabel(tr("Emulation running"));
141 resume_button = new QPushButton(tr("Resume")); 141 resume_button = new QPushButton(tr("Resume"));
diff --git a/src/yuzu/debugger/profiler.cpp b/src/yuzu/debugger/profiler.cpp
index 86e03e46d..f594ef076 100644
--- a/src/yuzu/debugger/profiler.cpp
+++ b/src/yuzu/debugger/profiler.cpp
@@ -47,7 +47,7 @@ private:
47#endif 47#endif
48 48
49MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Dialog) { 49MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Dialog) {
50 setObjectName("MicroProfile"); 50 setObjectName(QStringLiteral("MicroProfile"));
51 setWindowTitle(tr("MicroProfile")); 51 setWindowTitle(tr("MicroProfile"));
52 resize(1000, 600); 52 resize(1000, 600);
53 // Remove the "?" button from the titlebar and enable the maximize button 53 // Remove the "?" button from the titlebar and enable the maximize button
@@ -191,7 +191,7 @@ void MicroProfileDrawText(int x, int y, u32 hex_color, const char* text, u32 tex
191 for (u32 i = 0; i < text_length; ++i) { 191 for (u32 i = 0; i < text_length; ++i) {
192 // Position the text baseline 1 pixel above the bottom of the text cell, this gives nice 192 // Position the text baseline 1 pixel above the bottom of the text cell, this gives nice
193 // vertical alignment of text for a wide range of tested fonts. 193 // vertical alignment of text for a wide range of tested fonts.
194 mp_painter->drawText(x, y + MICROPROFILE_TEXT_HEIGHT - 2, QChar(text[i])); 194 mp_painter->drawText(x, y + MICROPROFILE_TEXT_HEIGHT - 2, QString{QLatin1Char{text[i]}});
195 x += MICROPROFILE_TEXT_WIDTH + 1; 195 x += MICROPROFILE_TEXT_WIDTH + 1;
196 } 196 }
197} 197}
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 85b095688..cd8180f8b 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -91,19 +91,19 @@ WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTa
91WaitTreeMutexInfo::~WaitTreeMutexInfo() = default; 91WaitTreeMutexInfo::~WaitTreeMutexInfo() = default;
92 92
93QString WaitTreeMutexInfo::GetText() const { 93QString WaitTreeMutexInfo::GetText() const {
94 return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char('0')); 94 return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char{'0'});
95} 95}
96 96
97std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() const { 97std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() const {
98 std::vector<std::unique_ptr<WaitTreeItem>> list; 98 const bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0;
99
100 bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0;
101 99
100 std::vector<std::unique_ptr<WaitTreeItem>> list;
102 list.push_back(std::make_unique<WaitTreeText>(tr("has waiters: %1").arg(has_waiters))); 101 list.push_back(std::make_unique<WaitTreeText>(tr("has waiters: %1").arg(has_waiters)));
103 list.push_back(std::make_unique<WaitTreeText>( 102 list.push_back(std::make_unique<WaitTreeText>(
104 tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char('0')))); 103 tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char{'0'})));
105 if (owner != nullptr) 104 if (owner != nullptr) {
106 list.push_back(std::make_unique<WaitTreeThread>(*owner)); 105 list.push_back(std::make_unique<WaitTreeThread>(*owner));
106 }
107 return list; 107 return list;
108} 108}
109 109
@@ -121,11 +121,14 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() cons
121 u64 base_pointer = thread.GetContext().cpu_registers[BaseRegister]; 121 u64 base_pointer = thread.GetContext().cpu_registers[BaseRegister];
122 122
123 while (base_pointer != 0) { 123 while (base_pointer != 0) {
124 u64 lr = Memory::Read64(base_pointer + sizeof(u64)); 124 const u64 lr = Memory::Read64(base_pointer + sizeof(u64));
125 if (lr == 0) 125 if (lr == 0) {
126 break; 126 break;
127 list.push_back( 127 }
128 std::make_unique<WaitTreeText>(tr("0x%1").arg(lr - sizeof(u32), 16, 16, QChar('0')))); 128
129 list.push_back(std::make_unique<WaitTreeText>(
130 tr("0x%1").arg(lr - sizeof(u32), 16, 16, QLatin1Char{'0'})));
131
129 base_pointer = Memory::Read64(base_pointer); 132 base_pointer = Memory::Read64(base_pointer);
130 } 133 }
131 134
@@ -174,10 +177,10 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeWaitObject::GetChildren() con
174 177
175QString WaitTreeWaitObject::GetResetTypeQString(Kernel::ResetType reset_type) { 178QString WaitTreeWaitObject::GetResetTypeQString(Kernel::ResetType reset_type) {
176 switch (reset_type) { 179 switch (reset_type) {
177 case Kernel::ResetType::OneShot: 180 case Kernel::ResetType::Automatic:
178 return tr("one shot"); 181 return tr("automatic reset");
179 case Kernel::ResetType::Sticky: 182 case Kernel::ResetType::Manual:
180 return tr("sticky"); 183 return tr("manual reset");
181 } 184 }
182 UNREACHABLE(); 185 UNREACHABLE();
183 return {}; 186 return {};
@@ -249,9 +252,9 @@ QString WaitTreeThread::GetText() const {
249 252
250 const auto& context = thread.GetContext(); 253 const auto& context = thread.GetContext();
251 const QString pc_info = tr(" PC = 0x%1 LR = 0x%2") 254 const QString pc_info = tr(" PC = 0x%1 LR = 0x%2")
252 .arg(context.pc, 8, 16, QLatin1Char('0')) 255 .arg(context.pc, 8, 16, QLatin1Char{'0'})
253 .arg(context.cpu_registers[30], 8, 16, QLatin1Char('0')); 256 .arg(context.cpu_registers[30], 8, 16, QLatin1Char{'0'});
254 return WaitTreeWaitObject::GetText() + pc_info + " (" + status + ") "; 257 return QStringLiteral("%1%2 (%3) ").arg(WaitTreeWaitObject::GetText(), pc_info, status);
255} 258}
256 259
257QColor WaitTreeThread::GetColor() const { 260QColor WaitTreeThread::GetColor() const {
@@ -424,7 +427,7 @@ void WaitTreeModel::InitItems() {
424} 427}
425 428
426WaitTreeWidget::WaitTreeWidget(QWidget* parent) : QDockWidget(tr("Wait Tree"), parent) { 429WaitTreeWidget::WaitTreeWidget(QWidget* parent) : QDockWidget(tr("Wait Tree"), parent) {
427 setObjectName("WaitTreeWidget"); 430 setObjectName(QStringLiteral("WaitTreeWidget"));
428 view = new QTreeView(this); 431 view = new QTreeView(this);
429 view->setHeaderHidden(true); 432 view->setHeaderHidden(true);
430 setWidget(view); 433 setWidget(view);
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index e33e3aaaf..a59abf6e8 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -198,11 +198,11 @@ GMainWindow::GMainWindow()
198 198
199 ConnectMenuEvents(); 199 ConnectMenuEvents();
200 ConnectWidgetEvents(); 200 ConnectWidgetEvents();
201
201 LOG_INFO(Frontend, "yuzu Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch, 202 LOG_INFO(Frontend, "yuzu Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,
202 Common::g_scm_desc); 203 Common::g_scm_desc);
204 UpdateWindowTitle();
203 205
204 setWindowTitle(QString("yuzu %1| %2-%3")
205 .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc));
206 show(); 206 show();
207 207
208 Core::System::GetInstance().SetContentProvider( 208 Core::System::GetInstance().SetContentProvider(
@@ -936,9 +936,7 @@ void GMainWindow::BootGame(const QString& filename) {
936 title_name = FileUtil::GetFilename(filename.toStdString()); 936 title_name = FileUtil::GetFilename(filename.toStdString());
937 } 937 }
938 938
939 setWindowTitle(QString("yuzu %1| %4 | %2-%3") 939 UpdateWindowTitle(QString::fromStdString(title_name));
940 .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc,
941 QString::fromStdString(title_name)));
942 940
943 loading_screen->Prepare(Core::System::GetInstance().GetAppLoader()); 941 loading_screen->Prepare(Core::System::GetInstance().GetAppLoader());
944 loading_screen->show(); 942 loading_screen->show();
@@ -979,8 +977,8 @@ void GMainWindow::ShutdownGame() {
979 loading_screen->Clear(); 977 loading_screen->Clear();
980 game_list->show(); 978 game_list->show();
981 game_list->setFilterFocus(); 979 game_list->setFilterFocus();
982 setWindowTitle(QString("yuzu %1| %2-%3") 980
983 .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc)); 981 UpdateWindowTitle();
984 982
985 // Disable status bar updates 983 // Disable status bar updates
986 status_bar_update_timer.stop(); 984 status_bar_update_timer.stop();
@@ -1767,6 +1765,19 @@ void GMainWindow::OnCaptureScreenshot() {
1767 OnStartGame(); 1765 OnStartGame();
1768} 1766}
1769 1767
1768void GMainWindow::UpdateWindowTitle(const QString& title_name) {
1769 const QString full_name = QString::fromUtf8(Common::g_build_fullname);
1770 const QString branch_name = QString::fromUtf8(Common::g_scm_branch);
1771 const QString description = QString::fromUtf8(Common::g_scm_desc);
1772
1773 if (title_name.isEmpty()) {
1774 setWindowTitle(QStringLiteral("yuzu %1| %2-%3").arg(full_name, branch_name, description));
1775 } else {
1776 setWindowTitle(QStringLiteral("yuzu %1| %4 | %2-%3")
1777 .arg(full_name, branch_name, description, title_name));
1778 }
1779}
1780
1770void GMainWindow::UpdateStatusBar() { 1781void GMainWindow::UpdateStatusBar() {
1771 if (emu_thread == nullptr) { 1782 if (emu_thread == nullptr) {
1772 status_bar_update_timer.stop(); 1783 status_bar_update_timer.stop();
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index fb2a193cb..7bf82e665 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -209,6 +209,7 @@ private slots:
209 209
210private: 210private:
211 std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id); 211 std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id);
212 void UpdateWindowTitle(const QString& title_name = {});
212 void UpdateStatusBar(); 213 void UpdateStatusBar();
213 214
214 Ui::MainWindow ui; 215 Ui::MainWindow ui;
diff --git a/src/yuzu/util/spinbox.cpp b/src/yuzu/util/spinbox.cpp
deleted file mode 100644
index 14ef1e884..000000000
--- a/src/yuzu/util/spinbox.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
1// Licensed under GPLv2 or any later version
2// Refer to the license.txt file included.
3
4// Copyright 2014 Tony Wasserka
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are met:
9//
10// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above copyright
13// notice, this list of conditions and the following disclaimer in the
14// documentation and/or other materials provided with the distribution.
15// * Neither the name of the owner nor the names of its contributors may
16// be used to endorse or promote products derived from this software
17// without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#include <cstdlib>
32#include <QLineEdit>
33#include <QRegExpValidator>
34#include "common/assert.h"
35#include "yuzu/util/spinbox.h"
36
37CSpinBox::CSpinBox(QWidget* parent)
38 : QAbstractSpinBox(parent), min_value(-100), max_value(100), value(0), base(10), num_digits(0) {
39 // TODO: Might be nice to not immediately call the slot.
40 // Think of an address that is being replaced by a different one, in which case a lot
41 // invalid intermediate addresses would be read from during editing.
42 connect(lineEdit(), &QLineEdit::textEdited, this, &CSpinBox::OnEditingFinished);
43
44 UpdateText();
45}
46
47void CSpinBox::SetValue(qint64 val) {
48 auto old_value = value;
49 value = std::max(std::min(val, max_value), min_value);
50
51 if (old_value != value) {
52 UpdateText();
53 emit ValueChanged(value);
54 }
55}
56
57void CSpinBox::SetRange(qint64 min, qint64 max) {
58 min_value = min;
59 max_value = max;
60
61 SetValue(value);
62 UpdateText();
63}
64
65void CSpinBox::stepBy(int steps) {
66 auto new_value = value;
67 // Scale number of steps by the currently selected digit
68 // TODO: Move this code elsewhere and enable it.
69 // TODO: Support for num_digits==0, too
70 // TODO: Support base!=16, too
71 // TODO: Make the cursor not jump back to the end of the line...
72 /*if (base == 16 && num_digits > 0) {
73 int digit = num_digits - (lineEdit()->cursorPosition() - prefix.length()) - 1;
74 digit = std::max(0, std::min(digit, num_digits - 1));
75 steps <<= digit * 4;
76 }*/
77
78 // Increment "new_value" by "steps", and perform annoying overflow checks, too.
79 if (steps < 0 && new_value + steps > new_value) {
80 new_value = std::numeric_limits<qint64>::min();
81 } else if (steps > 0 && new_value + steps < new_value) {
82 new_value = std::numeric_limits<qint64>::max();
83 } else {
84 new_value += steps;
85 }
86
87 SetValue(new_value);
88 UpdateText();
89}
90
91QAbstractSpinBox::StepEnabled CSpinBox::stepEnabled() const {
92 StepEnabled ret = StepNone;
93
94 if (value > min_value)
95 ret |= StepDownEnabled;
96
97 if (value < max_value)
98 ret |= StepUpEnabled;
99
100 return ret;
101}
102
103void CSpinBox::SetBase(int base) {
104 this->base = base;
105
106 UpdateText();
107}
108
109void CSpinBox::SetNumDigits(int num_digits) {
110 this->num_digits = num_digits;
111
112 UpdateText();
113}
114
115void CSpinBox::SetPrefix(const QString& prefix) {
116 this->prefix = prefix;
117
118 UpdateText();
119}
120
121void CSpinBox::SetSuffix(const QString& suffix) {
122 this->suffix = suffix;
123
124 UpdateText();
125}
126
127static QString StringToInputMask(const QString& input) {
128 QString mask = input;
129
130 // ... replace any special characters by their escaped counterparts ...
131 mask.replace("\\", "\\\\");
132 mask.replace("A", "\\A");
133 mask.replace("a", "\\a");
134 mask.replace("N", "\\N");
135 mask.replace("n", "\\n");
136 mask.replace("X", "\\X");
137 mask.replace("x", "\\x");
138 mask.replace("9", "\\9");
139 mask.replace("0", "\\0");
140 mask.replace("D", "\\D");
141 mask.replace("d", "\\d");
142 mask.replace("#", "\\#");
143 mask.replace("H", "\\H");
144 mask.replace("h", "\\h");
145 mask.replace("B", "\\B");
146 mask.replace("b", "\\b");
147 mask.replace(">", "\\>");
148 mask.replace("<", "\\<");
149 mask.replace("!", "\\!");
150
151 return mask;
152}
153
154void CSpinBox::UpdateText() {
155 // If a fixed number of digits is used, we put the line edit in insertion mode by setting an
156 // input mask.
157 QString mask;
158 if (num_digits != 0) {
159 mask += StringToInputMask(prefix);
160
161 // For base 10 and negative range, demand a single sign character
162 if (HasSign())
163 mask += "X"; // identified as "-" or "+" in the validator
164
165 // Uppercase digits greater than 9.
166 mask += ">";
167
168 // Match num_digits digits
169 // Digits irrelevant to the chosen number base are filtered in the validator
170 mask += QString("H").repeated(std::max(num_digits, 1));
171
172 // Switch off case conversion
173 mask += "!";
174
175 mask += StringToInputMask(suffix);
176 }
177 lineEdit()->setInputMask(mask);
178
179 // Set new text without changing the cursor position. This will cause the cursor to briefly
180 // appear at the end of the line and then to jump back to its original position. That's
181 // a bit ugly, but better than having setText() move the cursor permanently all the time.
182 int cursor_position = lineEdit()->cursorPosition();
183 lineEdit()->setText(TextFromValue());
184 lineEdit()->setCursorPosition(cursor_position);
185}
186
187QString CSpinBox::TextFromValue() {
188 return prefix + QString(HasSign() ? ((value < 0) ? "-" : "+") : "") +
189 QString("%1").arg(std::abs(value), num_digits, base, QLatin1Char('0')).toUpper() +
190 suffix;
191}
192
193qint64 CSpinBox::ValueFromText() {
194 unsigned strpos = prefix.length();
195
196 QString num_string = text().mid(strpos, text().length() - strpos - suffix.length());
197 return num_string.toLongLong(nullptr, base);
198}
199
200bool CSpinBox::HasSign() const {
201 return base == 10 && min_value < 0;
202}
203
204void CSpinBox::OnEditingFinished() {
205 // Only update for valid input
206 QString input = lineEdit()->text();
207 int pos = 0;
208 if (QValidator::Acceptable == validate(input, pos))
209 SetValue(ValueFromText());
210}
211
212QValidator::State CSpinBox::validate(QString& input, int& pos) const {
213 if (!prefix.isEmpty() && input.left(prefix.length()) != prefix)
214 return QValidator::Invalid;
215
216 int strpos = prefix.length();
217
218 // Empty "numbers" allowed as intermediate values
219 if (strpos >= input.length() - HasSign() - suffix.length())
220 return QValidator::Intermediate;
221
222 DEBUG_ASSERT(base <= 10 || base == 16);
223 QString regexp;
224
225 // Demand sign character for negative ranges
226 if (HasSign())
227 regexp += "[+\\-]";
228
229 // Match digits corresponding to the chosen number base.
230 regexp += QString("[0-%1").arg(std::min(base, 9));
231 if (base == 16) {
232 regexp += "a-fA-F";
233 }
234 regexp += "]";
235
236 // Specify number of digits
237 if (num_digits > 0) {
238 regexp += QString("{%1}").arg(num_digits);
239 } else {
240 regexp += "+";
241 }
242
243 // Match string
244 QRegExp num_regexp(regexp);
245 int num_pos = strpos;
246 QString sub_input = input.mid(strpos, input.length() - strpos - suffix.length());
247
248 if (!num_regexp.exactMatch(sub_input) && num_regexp.matchedLength() == 0)
249 return QValidator::Invalid;
250
251 sub_input = sub_input.left(num_regexp.matchedLength());
252 bool ok;
253 qint64 val = sub_input.toLongLong(&ok, base);
254
255 if (!ok)
256 return QValidator::Invalid;
257
258 // Outside boundaries => don't accept
259 if (val < min_value || val > max_value)
260 return QValidator::Invalid;
261
262 // Make sure we are actually at the end of this string...
263 strpos += num_regexp.matchedLength();
264
265 if (!suffix.isEmpty() && input.mid(strpos) != suffix) {
266 return QValidator::Invalid;
267 } else {
268 strpos += suffix.length();
269 }
270
271 if (strpos != input.length())
272 return QValidator::Invalid;
273
274 // At this point we can say for sure that the input is fine. Let's fix it up a bit though
275 input.replace(num_pos, sub_input.length(), sub_input.toUpper());
276
277 return QValidator::Acceptable;
278}
diff --git a/src/yuzu/util/spinbox.h b/src/yuzu/util/spinbox.h
deleted file mode 100644
index 2fa1db3a4..000000000
--- a/src/yuzu/util/spinbox.h
+++ /dev/null
@@ -1,86 +0,0 @@
1// Licensed under GPLv2 or any later version
2// Refer to the license.txt file included.
3
4// Copyright 2014 Tony Wasserka
5// All rights reserved.
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are met:
9//
10// * Redistributions of source code must retain the above copyright
11// notice, this list of conditions and the following disclaimer.
12// * Redistributions in binary form must reproduce the above copyright
13// notice, this list of conditions and the following disclaimer in the
14// documentation and/or other materials provided with the distribution.
15// * Neither the name of the owner nor the names of its contributors may
16// be used to endorse or promote products derived from this software
17// without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31#pragma once
32
33#include <QAbstractSpinBox>
34#include <QtGlobal>
35
36class QVariant;
37
38/**
39 * A custom spin box widget with enhanced functionality over Qt's QSpinBox
40 */
41class CSpinBox : public QAbstractSpinBox {
42 Q_OBJECT
43
44public:
45 explicit CSpinBox(QWidget* parent = nullptr);
46
47 void stepBy(int steps) override;
48 StepEnabled stepEnabled() const override;
49
50 void SetValue(qint64 val);
51
52 void SetRange(qint64 min, qint64 max);
53
54 void SetBase(int base);
55
56 void SetPrefix(const QString& prefix);
57 void SetSuffix(const QString& suffix);
58
59 void SetNumDigits(int num_digits);
60
61 QValidator::State validate(QString& input, int& pos) const override;
62
63signals:
64 void ValueChanged(qint64 val);
65
66private slots:
67 void OnEditingFinished();
68
69private:
70 void UpdateText();
71
72 bool HasSign() const;
73
74 QString TextFromValue();
75 qint64 ValueFromText();
76
77 qint64 min_value, max_value;
78
79 qint64 value;
80
81 QString prefix, suffix;
82
83 int base;
84
85 int num_digits;
86};
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 68a176032..8f104062d 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -176,9 +176,13 @@ EmuWindow_SDL2::EmuWindow_SDL2(bool fullscreen) {
176 176
177 SDL_SetMainReady(); 177 SDL_SetMainReady();
178 178
179 const SDL_GLprofile profile = Settings::values.use_compatibility_profile
180 ? SDL_GL_CONTEXT_PROFILE_COMPATIBILITY
181 : SDL_GL_CONTEXT_PROFILE_CORE;
182
179 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4); 183 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
180 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); 184 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3);
181 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); 185 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, profile);
182 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); 186 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
183 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); 187 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
184 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); 188 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index a1d7879b1..d3734927b 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -222,6 +222,7 @@ int main(int argc, char** argv) {
222 222
223 system.TelemetrySession().AddField(Telemetry::FieldType::App, "Frontend", "SDL"); 223 system.TelemetrySession().AddField(Telemetry::FieldType::App, "Frontend", "SDL");
224 224
225 emu_window->MakeCurrent();
225 system.Renderer().Rasterizer().LoadDiskResources(); 226 system.Renderer().Rasterizer().LoadDiskResources();
226 227
227 while (emu_window->IsOpen()) { 228 while (emu_window->IsOpen()) {