summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/bit_field.h2
-rw-r--r--src/core/hle/kernel/memory/memory_block.h23
-rw-r--r--src/core/hle/kernel/memory/memory_block_manager.cpp36
-rw-r--r--src/core/hle/kernel/memory/memory_block_manager.h3
-rw-r--r--src/core/hle/kernel/memory/page_table.cpp44
-rw-r--r--src/core/hle/kernel/memory/page_table.h2
-rw-r--r--src/core/hle/kernel/shared_memory.cpp8
-rw-r--r--src/core/hle/kernel/shared_memory.h2
-rw-r--r--src/core/hle/kernel/svc.cpp143
-rw-r--r--src/core/hle/service/acc/acc_su.cpp2
-rw-r--r--src/core/hle/service/acc/acc_u1.cpp1
-rw-r--r--src/core/hle/service/am/am.cpp10
-rw-r--r--src/core/hle/service/audio/audctl.cpp2
-rw-r--r--src/core/hle/service/bcat/module.cpp1
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp4
-rw-r--r--src/core/hle/service/friend/friend.cpp1
-rw-r--r--src/core/hle/service/hid/hid.cpp37
-rw-r--r--src/core/hle/service/ldr/ldr.cpp1
-rw-r--r--src/core/hle/service/ncm/ncm.cpp1
-rw-r--r--src/core/hle/service/npns/npns.cpp2
-rw-r--r--src/core/hle/service/ns/ns.cpp22
-rw-r--r--src/core/hle/service/ns/pl_u.cpp1
-rw-r--r--src/core/hle/service/pctl/module.cpp2
-rw-r--r--src/core/hle/service/prepo/prepo.cpp12
-rw-r--r--src/core/hle/service/set/set_cal.cpp2
-rw-r--r--src/core/hle/service/set/set_sys.cpp12
-rw-r--r--src/core/hle/service/sockets/bsd.cpp1
-rw-r--r--src/core/reporter.h1
-rw-r--r--src/video_core/engines/maxwell_3d.h3
-rw-r--r--src/video_core/engines/shader_bytecode.h3
-rw-r--r--src/video_core/memory_manager.cpp18
-rw-r--r--src/video_core/renderer_opengl/gl_rasterizer.cpp12
-rw-r--r--src/video_core/renderer_vulkan/fixed_pipeline_state.h2
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp42
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.h6
-rw-r--r--src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp2
-rw-r--r--src/video_core/renderer_vulkan/wrapper.cpp21
-rw-r--r--src/video_core/shader/decode/arithmetic_half.cpp51
-rw-r--r--src/video_core/shader/decode/arithmetic_integer.cpp4
-rw-r--r--src/yuzu/configuration/config.cpp7
-rw-r--r--src/yuzu/configuration/config.h2
-rw-r--r--src/yuzu/configuration/configure_filesystem.cpp2
-rw-r--r--src/yuzu/configuration/configure_hotkeys.cpp80
-rw-r--r--src/yuzu/configuration/configure_hotkeys.h6
-rw-r--r--src/yuzu/configuration/configure_hotkeys.ui39
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp60
-rw-r--r--src/yuzu/configuration/configure_input_player.h6
-rw-r--r--src/yuzu/configuration/configure_input_player.ui16
-rw-r--r--src/yuzu/game_list_p.h14
-rw-r--r--src/yuzu_cmd/emu_window/emu_window_sdl2.cpp7
50 files changed, 656 insertions, 125 deletions
diff --git a/src/common/bit_field.h b/src/common/bit_field.h
index fd2bbbd99..26ae6c7fc 100644
--- a/src/common/bit_field.h
+++ b/src/common/bit_field.h
@@ -180,7 +180,7 @@ public:
180 } 180 }
181 181
182 constexpr void Assign(const T& value) { 182 constexpr void Assign(const T& value) {
183 storage = (static_cast<StorageType>(storage) & ~mask) | FormatValue(value); 183 storage = static_cast<StorageType>((storage & ~mask) | FormatValue(value));
184 } 184 }
185 185
186 constexpr T Value() const { 186 constexpr T Value() const {
diff --git a/src/core/hle/kernel/memory/memory_block.h b/src/core/hle/kernel/memory/memory_block.h
index e11043b60..9db1f7b39 100644
--- a/src/core/hle/kernel/memory/memory_block.h
+++ b/src/core/hle/kernel/memory/memory_block.h
@@ -17,7 +17,7 @@ namespace Kernel::Memory {
17 17
18enum class MemoryState : u32 { 18enum class MemoryState : u32 {
19 None = 0, 19 None = 0,
20 Mask = 0xFFFFFFFF, // TODO(bunnei): This should probable be 0xFF 20 Mask = 0xFF,
21 All = ~None, 21 All = ~None,
22 22
23 FlagCanReprotect = (1 << 8), 23 FlagCanReprotect = (1 << 8),
@@ -253,6 +253,23 @@ public:
253 }; 253 };
254 } 254 }
255 255
256 void ShareToDevice(MemoryPermission /*new_perm*/) {
257 ASSERT((attribute & MemoryAttribute::DeviceShared) == MemoryAttribute::DeviceShared ||
258 device_use_count == 0);
259 attribute |= MemoryAttribute::DeviceShared;
260 const u16 new_use_count{++device_use_count};
261 ASSERT(new_use_count > 0);
262 }
263
264 void UnshareToDevice(MemoryPermission /*new_perm*/) {
265 ASSERT((attribute & MemoryAttribute::DeviceShared) == MemoryAttribute::DeviceShared);
266 const u16 prev_use_count{device_use_count--};
267 ASSERT(prev_use_count > 0);
268 if (prev_use_count == 1) {
269 attribute &= ~MemoryAttribute::DeviceShared;
270 }
271 }
272
256private: 273private:
257 constexpr bool HasProperties(MemoryState s, MemoryPermission p, MemoryAttribute a) const { 274 constexpr bool HasProperties(MemoryState s, MemoryPermission p, MemoryAttribute a) const {
258 constexpr MemoryAttribute AttributeIgnoreMask{MemoryAttribute::DontCareMask | 275 constexpr MemoryAttribute AttributeIgnoreMask{MemoryAttribute::DontCareMask |
@@ -287,9 +304,9 @@ private:
287 state = new_state; 304 state = new_state;
288 perm = new_perm; 305 perm = new_perm;
289 306
290 // TODO(bunnei): Is this right?
291 attribute = static_cast<MemoryAttribute>( 307 attribute = static_cast<MemoryAttribute>(
292 new_attribute /*| (attribute & (MemoryAttribute::IpcLocked | MemoryAttribute::DeviceShared))*/); 308 new_attribute |
309 (attribute & (MemoryAttribute::IpcLocked | MemoryAttribute::DeviceShared)));
293 } 310 }
294 311
295 constexpr MemoryBlock Split(VAddr split_addr) { 312 constexpr MemoryBlock Split(VAddr split_addr) {
diff --git a/src/core/hle/kernel/memory/memory_block_manager.cpp b/src/core/hle/kernel/memory/memory_block_manager.cpp
index 1ebc126c0..900395c37 100644
--- a/src/core/hle/kernel/memory/memory_block_manager.cpp
+++ b/src/core/hle/kernel/memory/memory_block_manager.cpp
@@ -143,6 +143,42 @@ void MemoryBlockManager::Update(VAddr addr, std::size_t num_pages, MemoryState s
143 } 143 }
144} 144}
145 145
146void MemoryBlockManager::UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func,
147 MemoryPermission perm) {
148 const std::size_t prev_count{memory_block_tree.size()};
149 const VAddr end_addr{addr + num_pages * PageSize};
150 iterator node{memory_block_tree.begin()};
151
152 while (node != memory_block_tree.end()) {
153 MemoryBlock* block{&(*node)};
154 iterator next_node{std::next(node)};
155 const VAddr cur_addr{block->GetAddress()};
156 const VAddr cur_end_addr{block->GetNumPages() * PageSize + cur_addr};
157
158 if (addr < cur_end_addr && cur_addr < end_addr) {
159 iterator new_node{node};
160
161 if (addr > cur_addr) {
162 memory_block_tree.insert(node, block->Split(addr));
163 }
164
165 if (end_addr < cur_end_addr) {
166 new_node = memory_block_tree.insert(node, block->Split(end_addr));
167 }
168
169 lock_func(new_node, perm);
170
171 MergeAdjacent(new_node, next_node);
172 }
173
174 if (cur_end_addr - 1 >= end_addr - 1) {
175 break;
176 }
177
178 node = next_node;
179 }
180}
181
146void MemoryBlockManager::IterateForRange(VAddr start, VAddr end, IterateFunc&& func) { 182void MemoryBlockManager::IterateForRange(VAddr start, VAddr end, IterateFunc&& func) {
147 const_iterator it{FindIterator(start)}; 183 const_iterator it{FindIterator(start)};
148 MemoryInfo info{}; 184 MemoryInfo info{};
diff --git a/src/core/hle/kernel/memory/memory_block_manager.h b/src/core/hle/kernel/memory/memory_block_manager.h
index 0f2270f0f..9451b5df6 100644
--- a/src/core/hle/kernel/memory/memory_block_manager.h
+++ b/src/core/hle/kernel/memory/memory_block_manager.h
@@ -45,6 +45,9 @@ public:
45 MemoryPermission perm = MemoryPermission::None, 45 MemoryPermission perm = MemoryPermission::None,
46 MemoryAttribute attribute = MemoryAttribute::None); 46 MemoryAttribute attribute = MemoryAttribute::None);
47 47
48 using LockFunc = std::function<void(iterator, MemoryPermission)>;
49 void UpdateLock(VAddr addr, std::size_t num_pages, LockFunc&& lock_func, MemoryPermission perm);
50
48 using IterateFunc = std::function<void(const MemoryInfo&)>; 51 using IterateFunc = std::function<void(const MemoryInfo&)>;
49 void IterateForRange(VAddr start, VAddr end, IterateFunc&& func); 52 void IterateForRange(VAddr start, VAddr end, IterateFunc&& func);
50 53
diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp
index 091e52ca4..3281611f8 100644
--- a/src/core/hle/kernel/memory/page_table.cpp
+++ b/src/core/hle/kernel/memory/page_table.cpp
@@ -840,6 +840,50 @@ ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s
840 return MakeResult<VAddr>(addr); 840 return MakeResult<VAddr>(addr);
841} 841}
842 842
843ResultCode PageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) {
844 std::lock_guard lock{page_table_lock};
845
846 MemoryPermission perm{};
847 if (const ResultCode result{CheckMemoryState(
848 nullptr, &perm, nullptr, addr, size, MemoryState::FlagCanChangeAttribute,
849 MemoryState::FlagCanChangeAttribute, MemoryPermission::None, MemoryPermission::None,
850 MemoryAttribute::LockedAndIpcLocked, MemoryAttribute::None,
851 MemoryAttribute::DeviceSharedAndUncached)};
852 result.IsError()) {
853 return result;
854 }
855
856 block_manager->UpdateLock(addr, size / PageSize,
857 [](MemoryBlockManager::iterator block, MemoryPermission perm) {
858 block->ShareToDevice(perm);
859 },
860 perm);
861
862 return RESULT_SUCCESS;
863}
864
865ResultCode PageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) {
866 std::lock_guard lock{page_table_lock};
867
868 MemoryPermission perm{};
869 if (const ResultCode result{CheckMemoryState(
870 nullptr, &perm, nullptr, addr, size, MemoryState::FlagCanChangeAttribute,
871 MemoryState::FlagCanChangeAttribute, MemoryPermission::None, MemoryPermission::None,
872 MemoryAttribute::LockedAndIpcLocked, MemoryAttribute::None,
873 MemoryAttribute::DeviceSharedAndUncached)};
874 result.IsError()) {
875 return result;
876 }
877
878 block_manager->UpdateLock(addr, size / PageSize,
879 [](MemoryBlockManager::iterator block, MemoryPermission perm) {
880 block->UnshareToDevice(perm);
881 },
882 perm);
883
884 return RESULT_SUCCESS;
885}
886
843ResultCode PageTable::InitializeMemoryLayout(VAddr start, VAddr end) { 887ResultCode PageTable::InitializeMemoryLayout(VAddr start, VAddr end) {
844 block_manager = std::make_unique<MemoryBlockManager>(start, end); 888 block_manager = std::make_unique<MemoryBlockManager>(start, end);
845 889
diff --git a/src/core/hle/kernel/memory/page_table.h b/src/core/hle/kernel/memory/page_table.h
index 80384ab0f..a867aa050 100644
--- a/src/core/hle/kernel/memory/page_table.h
+++ b/src/core/hle/kernel/memory/page_table.h
@@ -53,6 +53,8 @@ public:
53 bool is_map_only, VAddr region_start, 53 bool is_map_only, VAddr region_start,
54 std::size_t region_num_pages, MemoryState state, 54 std::size_t region_num_pages, MemoryState state,
55 MemoryPermission perm, PAddr map_addr = 0); 55 MemoryPermission perm, PAddr map_addr = 0);
56 ResultCode LockForDeviceAddressSpace(VAddr addr, std::size_t size);
57 ResultCode UnlockForDeviceAddressSpace(VAddr addr, std::size_t size);
56 58
57 Common::PageTable& PageTableImpl() { 59 Common::PageTable& PageTableImpl() {
58 return page_table_impl; 60 return page_table_impl;
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index c67696757..0cd467110 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -36,22 +36,22 @@ std::shared_ptr<SharedMemory> SharedMemory::Create(
36} 36}
37 37
38ResultCode SharedMemory::Map(Process& target_process, VAddr address, std::size_t size, 38ResultCode SharedMemory::Map(Process& target_process, VAddr address, std::size_t size,
39 Memory::MemoryPermission permission) { 39 Memory::MemoryPermission permissions) {
40 const u64 page_count{(size + Memory::PageSize - 1) / Memory::PageSize}; 40 const u64 page_count{(size + Memory::PageSize - 1) / Memory::PageSize};
41 41
42 if (page_list.GetNumPages() != page_count) { 42 if (page_list.GetNumPages() != page_count) {
43 UNIMPLEMENTED_MSG("Page count does not match"); 43 UNIMPLEMENTED_MSG("Page count does not match");
44 } 44 }
45 45
46 Memory::MemoryPermission expected = 46 const Memory::MemoryPermission expected =
47 &target_process == owner_process ? owner_permission : user_permission; 47 &target_process == owner_process ? owner_permission : user_permission;
48 48
49 if (permission != expected) { 49 if (permissions != expected) {
50 UNIMPLEMENTED_MSG("Permission does not match"); 50 UNIMPLEMENTED_MSG("Permission does not match");
51 } 51 }
52 52
53 return target_process.PageTable().MapPages(address, page_list, Memory::MemoryState::Shared, 53 return target_process.PageTable().MapPages(address, page_list, Memory::MemoryState::Shared,
54 permission); 54 permissions);
55} 55}
56 56
57} // namespace Kernel 57} // namespace Kernel
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index cd16d6412..0ef87235c 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -51,7 +51,7 @@ public:
51 * @param permissions Memory block map permissions (specified by SVC field) 51 * @param permissions Memory block map permissions (specified by SVC field)
52 */ 52 */
53 ResultCode Map(Process& target_process, VAddr address, std::size_t size, 53 ResultCode Map(Process& target_process, VAddr address, std::size_t size,
54 Memory::MemoryPermission permission); 54 Memory::MemoryPermission permissions);
55 55
56 /** 56 /**
57 * Gets a pointer to the shared memory block 57 * Gets a pointer to the shared memory block
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 4134acf65..25b4a23b4 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -55,9 +55,6 @@ constexpr bool IsValidAddressRange(VAddr address, u64 size) {
55 return address + size > address; 55 return address + size > address;
56} 56}
57 57
58// 8 GiB
59constexpr u64 MAIN_MEMORY_SIZE = 0x200000000;
60
61// Helper function that performs the common sanity checks for svcMapMemory 58// Helper function that performs the common sanity checks for svcMapMemory
62// and svcUnmapMemory. This is doable, as both functions perform their sanitizing 59// and svcUnmapMemory. This is doable, as both functions perform their sanitizing
63// in the same order. 60// in the same order.
@@ -1229,6 +1226,142 @@ static ResultCode QueryMemory32(Core::System& system, u32 memory_info_address,
1229 return QueryMemory(system, memory_info_address, page_info_address, query_address); 1226 return QueryMemory(system, memory_info_address, page_info_address, query_address);
1230} 1227}
1231 1228
1229static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst_address,
1230 u64 src_address, u64 size) {
1231 LOG_DEBUG(Kernel_SVC,
1232 "called. process_handle=0x{:08X}, dst_address=0x{:016X}, "
1233 "src_address=0x{:016X}, size=0x{:016X}",
1234 process_handle, dst_address, src_address, size);
1235
1236 if (!Common::Is4KBAligned(src_address)) {
1237 LOG_ERROR(Kernel_SVC, "src_address is not page-aligned (src_address=0x{:016X}).",
1238 src_address);
1239 return ERR_INVALID_ADDRESS;
1240 }
1241
1242 if (!Common::Is4KBAligned(dst_address)) {
1243 LOG_ERROR(Kernel_SVC, "dst_address is not page-aligned (dst_address=0x{:016X}).",
1244 dst_address);
1245 return ERR_INVALID_ADDRESS;
1246 }
1247
1248 if (size == 0 || !Common::Is4KBAligned(size)) {
1249 LOG_ERROR(Kernel_SVC, "Size is zero or not page-aligned (size=0x{:016X})", size);
1250 return ERR_INVALID_SIZE;
1251 }
1252
1253 if (!IsValidAddressRange(dst_address, size)) {
1254 LOG_ERROR(Kernel_SVC,
1255 "Destination address range overflows the address space (dst_address=0x{:016X}, "
1256 "size=0x{:016X}).",
1257 dst_address, size);
1258 return ERR_INVALID_ADDRESS_STATE;
1259 }
1260
1261 if (!IsValidAddressRange(src_address, size)) {
1262 LOG_ERROR(Kernel_SVC,
1263 "Source address range overflows the address space (src_address=0x{:016X}, "
1264 "size=0x{:016X}).",
1265 src_address, size);
1266 return ERR_INVALID_ADDRESS_STATE;
1267 }
1268
1269 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1270 auto process = handle_table.Get<Process>(process_handle);
1271 if (!process) {
1272 LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).",
1273 process_handle);
1274 return ERR_INVALID_HANDLE;
1275 }
1276
1277 auto& page_table = process->PageTable();
1278 if (!page_table.IsInsideAddressSpace(src_address, size)) {
1279 LOG_ERROR(Kernel_SVC,
1280 "Source address range is not within the address space (src_address=0x{:016X}, "
1281 "size=0x{:016X}).",
1282 src_address, size);
1283 return ERR_INVALID_ADDRESS_STATE;
1284 }
1285
1286 if (!page_table.IsInsideASLRRegion(dst_address, size)) {
1287 LOG_ERROR(Kernel_SVC,
1288 "Destination address range is not within the ASLR region (dst_address=0x{:016X}, "
1289 "size=0x{:016X}).",
1290 dst_address, size);
1291 return ERR_INVALID_MEMORY_RANGE;
1292 }
1293
1294 return page_table.MapProcessCodeMemory(dst_address, src_address, size);
1295}
1296
1297static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_handle,
1298 u64 dst_address, u64 src_address, u64 size) {
1299 LOG_DEBUG(Kernel_SVC,
1300 "called. process_handle=0x{:08X}, dst_address=0x{:016X}, src_address=0x{:016X}, "
1301 "size=0x{:016X}",
1302 process_handle, dst_address, src_address, size);
1303
1304 if (!Common::Is4KBAligned(dst_address)) {
1305 LOG_ERROR(Kernel_SVC, "dst_address is not page-aligned (dst_address=0x{:016X}).",
1306 dst_address);
1307 return ERR_INVALID_ADDRESS;
1308 }
1309
1310 if (!Common::Is4KBAligned(src_address)) {
1311 LOG_ERROR(Kernel_SVC, "src_address is not page-aligned (src_address=0x{:016X}).",
1312 src_address);
1313 return ERR_INVALID_ADDRESS;
1314 }
1315
1316 if (size == 0 || Common::Is4KBAligned(size)) {
1317 LOG_ERROR(Kernel_SVC, "Size is zero or not page-aligned (size=0x{:016X}).", size);
1318 return ERR_INVALID_SIZE;
1319 }
1320
1321 if (!IsValidAddressRange(dst_address, size)) {
1322 LOG_ERROR(Kernel_SVC,
1323 "Destination address range overflows the address space (dst_address=0x{:016X}, "
1324 "size=0x{:016X}).",
1325 dst_address, size);
1326 return ERR_INVALID_ADDRESS_STATE;
1327 }
1328
1329 if (!IsValidAddressRange(src_address, size)) {
1330 LOG_ERROR(Kernel_SVC,
1331 "Source address range overflows the address space (src_address=0x{:016X}, "
1332 "size=0x{:016X}).",
1333 src_address, size);
1334 return ERR_INVALID_ADDRESS_STATE;
1335 }
1336
1337 const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
1338 auto process = handle_table.Get<Process>(process_handle);
1339 if (!process) {
1340 LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).",
1341 process_handle);
1342 return ERR_INVALID_HANDLE;
1343 }
1344
1345 auto& page_table = process->PageTable();
1346 if (!page_table.IsInsideAddressSpace(src_address, size)) {
1347 LOG_ERROR(Kernel_SVC,
1348 "Source address range is not within the address space (src_address=0x{:016X}, "
1349 "size=0x{:016X}).",
1350 src_address, size);
1351 return ERR_INVALID_ADDRESS_STATE;
1352 }
1353
1354 if (!page_table.IsInsideASLRRegion(dst_address, size)) {
1355 LOG_ERROR(Kernel_SVC,
1356 "Destination address range is not within the ASLR region (dst_address=0x{:016X}, "
1357 "size=0x{:016X}).",
1358 dst_address, size);
1359 return ERR_INVALID_MEMORY_RANGE;
1360 }
1361
1362 return page_table.UnmapProcessCodeMemory(dst_address, src_address, size);
1363}
1364
1232/// Exits the current process 1365/// Exits the current process
1233static void ExitProcess(Core::System& system) { 1366static void ExitProcess(Core::System& system) {
1234 auto* current_process = system.Kernel().CurrentProcess(); 1367 auto* current_process = system.Kernel().CurrentProcess();
@@ -2256,8 +2389,8 @@ static const FunctionDef SVC_Table_64[] = {
2256 {0x74, nullptr, "MapProcessMemory"}, 2389 {0x74, nullptr, "MapProcessMemory"},
2257 {0x75, nullptr, "UnmapProcessMemory"}, 2390 {0x75, nullptr, "UnmapProcessMemory"},
2258 {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"}, 2391 {0x76, SvcWrap64<QueryProcessMemory>, "QueryProcessMemory"},
2259 {0x77, nullptr, "MapProcessCodeMemory"}, 2392 {0x77, SvcWrap64<MapProcessCodeMemory>, "MapProcessCodeMemory"},
2260 {0x78, nullptr, "UnmapProcessCodeMemory"}, 2393 {0x78, SvcWrap64<UnmapProcessCodeMemory>, "UnmapProcessCodeMemory"},
2261 {0x79, nullptr, "CreateProcess"}, 2394 {0x79, nullptr, "CreateProcess"},
2262 {0x7A, nullptr, "StartProcess"}, 2395 {0x7A, nullptr, "StartProcess"},
2263 {0x7B, nullptr, "TerminateProcess"}, 2396 {0x7B, nullptr, "TerminateProcess"},
diff --git a/src/core/hle/service/acc/acc_su.cpp b/src/core/hle/service/acc/acc_su.cpp
index b941c260b..ae88deda5 100644
--- a/src/core/hle/service/acc/acc_su.cpp
+++ b/src/core/hle/service/acc/acc_su.cpp
@@ -33,8 +33,10 @@ ACC_SU::ACC_SU(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
33 {111, nullptr, "ClearSaveDataThumbnail"}, 33 {111, nullptr, "ClearSaveDataThumbnail"},
34 {112, nullptr, "LoadSaveDataThumbnail"}, 34 {112, nullptr, "LoadSaveDataThumbnail"},
35 {113, nullptr, "GetSaveDataThumbnailExistence"}, 35 {113, nullptr, "GetSaveDataThumbnailExistence"},
36 {120, nullptr, "ListOpenUsersInApplication"},
36 {130, nullptr, "ActivateOpenContextRetention"}, 37 {130, nullptr, "ActivateOpenContextRetention"},
37 {140, nullptr, "ListQualifiedUsers"}, 38 {140, nullptr, "ListQualifiedUsers"},
39 {150, nullptr, "AuthenticateApplicationAsync"},
38 {190, nullptr, "GetUserLastOpenedApplication"}, 40 {190, nullptr, "GetUserLastOpenedApplication"},
39 {191, nullptr, "ActivateOpenContextHolder"}, 41 {191, nullptr, "ActivateOpenContextHolder"},
40 {200, nullptr, "BeginUserRegistration"}, 42 {200, nullptr, "BeginUserRegistration"},
diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp
index 858e91dde..2b9c11928 100644
--- a/src/core/hle/service/acc/acc_u1.cpp
+++ b/src/core/hle/service/acc/acc_u1.cpp
@@ -35,6 +35,7 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module, std::shared_ptr<ProfileManager> p
35 {113, nullptr, "GetSaveDataThumbnailExistence"}, 35 {113, nullptr, "GetSaveDataThumbnailExistence"},
36 {130, nullptr, "ActivateOpenContextRetention"}, 36 {130, nullptr, "ActivateOpenContextRetention"},
37 {140, nullptr, "ListQualifiedUsers"}, 37 {140, nullptr, "ListQualifiedUsers"},
38 {150, nullptr, "AuthenticateApplicationAsync"},
38 {190, nullptr, "GetUserLastOpenedApplication"}, 39 {190, nullptr, "GetUserLastOpenedApplication"},
39 {191, nullptr, "ActivateOpenContextHolder"}, 40 {191, nullptr, "ActivateOpenContextHolder"},
40 {997, nullptr, "DebugInvalidateTokenCacheForUser"}, 41 {997, nullptr, "DebugInvalidateTokenCacheForUser"},
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 3ece2cf3c..bee4a9d3f 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -235,6 +235,7 @@ IDebugFunctions::IDebugFunctions() : ServiceFramework{"IDebugFunctions"} {
235 {30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"}, 235 {30, nullptr, "RequestLaunchApplicationWithUserAndArgumentForDebug"},
236 {40, nullptr, "GetAppletResourceUsageInfo"}, 236 {40, nullptr, "GetAppletResourceUsageInfo"},
237 {100, nullptr, "SetCpuBoostModeForApplet"}, 237 {100, nullptr, "SetCpuBoostModeForApplet"},
238 {101, nullptr, "CancelCpuBoostModeForApplet"},
238 {110, nullptr, "PushToAppletBoundChannelForDebug"}, 239 {110, nullptr, "PushToAppletBoundChannelForDebug"},
239 {111, nullptr, "TryPopFromAppletBoundChannelForDebug"}, 240 {111, nullptr, "TryPopFromAppletBoundChannelForDebug"},
240 {120, nullptr, "AlarmSettingNotificationEnableAppEventReserve"}, 241 {120, nullptr, "AlarmSettingNotificationEnableAppEventReserve"},
@@ -277,6 +278,8 @@ ISelfController::ISelfController(Core::System& system,
277 {41, nullptr, "IsSystemBufferSharingEnabled"}, 278 {41, nullptr, "IsSystemBufferSharingEnabled"},
278 {42, nullptr, "GetSystemSharedLayerHandle"}, 279 {42, nullptr, "GetSystemSharedLayerHandle"},
279 {43, nullptr, "GetSystemSharedBufferHandle"}, 280 {43, nullptr, "GetSystemSharedBufferHandle"},
281 {44, nullptr, "CreateManagedDisplaySeparableLayer"},
282 {45, nullptr, "SetManagedDisplayLayerSeparationMode"},
280 {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"}, 283 {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
281 {51, nullptr, "ApproveToDisplay"}, 284 {51, nullptr, "ApproveToDisplay"},
282 {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"}, 285 {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
@@ -623,11 +626,15 @@ ICommonStateGetter::ICommonStateGetter(Core::System& system,
623 {64, nullptr, "SetTvPowerStateMatchingMode"}, 626 {64, nullptr, "SetTvPowerStateMatchingMode"},
624 {65, nullptr, "GetApplicationIdByContentActionName"}, 627 {65, nullptr, "GetApplicationIdByContentActionName"},
625 {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"}, 628 {66, &ICommonStateGetter::SetCpuBoostMode, "SetCpuBoostMode"},
629 {67, nullptr, "CancelCpuBoostMode"},
626 {80, nullptr, "PerformSystemButtonPressingIfInFocus"}, 630 {80, nullptr, "PerformSystemButtonPressingIfInFocus"},
627 {90, nullptr, "SetPerformanceConfigurationChangedNotification"}, 631 {90, nullptr, "SetPerformanceConfigurationChangedNotification"},
628 {91, nullptr, "GetCurrentPerformanceConfiguration"}, 632 {91, nullptr, "GetCurrentPerformanceConfiguration"},
633 {100, nullptr, "SetHandlingHomeButtonShortPressedEnabled"},
629 {200, nullptr, "GetOperationModeSystemInfo"}, 634 {200, nullptr, "GetOperationModeSystemInfo"},
630 {300, nullptr, "GetSettingsPlatformRegion"}, 635 {300, nullptr, "GetSettingsPlatformRegion"},
636 {400, nullptr, "ActivateMigrationService"},
637 {401, nullptr, "DeactivateMigrationService"},
631 }; 638 };
632 // clang-format on 639 // clang-format on
633 640
@@ -835,6 +842,7 @@ public:
835 {25, nullptr, "Terminate"}, 842 {25, nullptr, "Terminate"},
836 {30, &ILibraryAppletAccessor::GetResult, "GetResult"}, 843 {30, &ILibraryAppletAccessor::GetResult, "GetResult"},
837 {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"}, 844 {50, nullptr, "SetOutOfFocusApplicationSuspendingEnabled"},
845 {60, nullptr, "PresetLibraryAppletGpuTimeSliceZero"},
838 {100, &ILibraryAppletAccessor::PushInData, "PushInData"}, 846 {100, &ILibraryAppletAccessor::PushInData, "PushInData"},
839 {101, &ILibraryAppletAccessor::PopOutData, "PopOutData"}, 847 {101, &ILibraryAppletAccessor::PopOutData, "PopOutData"},
840 {102, nullptr, "PushExtraStorage"}, 848 {102, nullptr, "PushExtraStorage"},
@@ -1139,6 +1147,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
1139 {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"}, 1147 {31, &IApplicationFunctions::EndBlockingHomeButtonShortAndLongPressed, "EndBlockingHomeButtonShortAndLongPressed"},
1140 {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"}, 1148 {32, &IApplicationFunctions::BeginBlockingHomeButton, "BeginBlockingHomeButton"},
1141 {33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"}, 1149 {33, &IApplicationFunctions::EndBlockingHomeButton, "EndBlockingHomeButton"},
1150 {34, nullptr, "SelectApplicationLicense"},
1142 {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"}, 1151 {40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
1143 {50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"}, 1152 {50, &IApplicationFunctions::GetPseudoDeviceId, "GetPseudoDeviceId"},
1144 {60, nullptr, "SetMediaPlaybackStateForApplication"}, 1153 {60, nullptr, "SetMediaPlaybackStateForApplication"},
@@ -1148,6 +1157,7 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
1148 {68, nullptr, "RequestFlushGamePlayingMovieForDebug"}, 1157 {68, nullptr, "RequestFlushGamePlayingMovieForDebug"},
1149 {70, nullptr, "RequestToShutdown"}, 1158 {70, nullptr, "RequestToShutdown"},
1150 {71, nullptr, "RequestToReboot"}, 1159 {71, nullptr, "RequestToReboot"},
1160 {72, nullptr, "RequestToSleep"},
1151 {80, nullptr, "ExitAndRequestToShowThanksMessage"}, 1161 {80, nullptr, "ExitAndRequestToShowThanksMessage"},
1152 {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"}, 1162 {90, &IApplicationFunctions::EnableApplicationCrashReport, "EnableApplicationCrashReport"},
1153 {100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"}, 1163 {100, &IApplicationFunctions::InitializeApplicationCopyrightFrameBuffer, "InitializeApplicationCopyrightFrameBuffer"},
diff --git a/src/core/hle/service/audio/audctl.cpp b/src/core/hle/service/audio/audctl.cpp
index 9e08e5346..6ddb547fb 100644
--- a/src/core/hle/service/audio/audctl.cpp
+++ b/src/core/hle/service/audio/audctl.cpp
@@ -39,6 +39,8 @@ AudCtl::AudCtl() : ServiceFramework{"audctl"} {
39 {25, nullptr, "GetAudioVolumeDataForPlayReport"}, 39 {25, nullptr, "GetAudioVolumeDataForPlayReport"},
40 {26, nullptr, "UpdateHeadphoneSettings"}, 40 {26, nullptr, "UpdateHeadphoneSettings"},
41 {27, nullptr, "SetVolumeMappingTableForDev"}, 41 {27, nullptr, "SetVolumeMappingTableForDev"},
42 {28, nullptr, "GetAudioOutputChannelCountForPlayReport"},
43 {29, nullptr, "BindAudioOutputChannelCountUpdateEventForPlayReport"},
42 }; 44 };
43 // clang-format on 45 // clang-format on
44 46
diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp
index 7ada67130..34aba7a27 100644
--- a/src/core/hle/service/bcat/module.cpp
+++ b/src/core/hle/service/bcat/module.cpp
@@ -141,6 +141,7 @@ public:
141 {20301, nullptr, "RequestSuspendDeliveryTask"}, 141 {20301, nullptr, "RequestSuspendDeliveryTask"},
142 {20400, nullptr, "RegisterSystemApplicationDeliveryTask"}, 142 {20400, nullptr, "RegisterSystemApplicationDeliveryTask"},
143 {20401, nullptr, "UnregisterSystemApplicationDeliveryTask"}, 143 {20401, nullptr, "UnregisterSystemApplicationDeliveryTask"},
144 {20410, nullptr, "SetSystemApplicationDeliveryTaskTimer"},
144 {30100, &IBcatService::SetPassphrase, "SetPassphrase"}, 145 {30100, &IBcatService::SetPassphrase, "SetPassphrase"},
145 {30200, nullptr, "RegisterBackgroundDeliveryTask"}, 146 {30200, nullptr, "RegisterBackgroundDeliveryTask"},
146 {30201, nullptr, "UnregisterBackgroundDeliveryTask"}, 147 {30201, nullptr, "UnregisterBackgroundDeliveryTask"},
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 61045c75c..6b9b4f3b9 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -697,12 +697,14 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
697 {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"}, 697 {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"},
698 {69, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"}, 698 {69, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"},
699 {70, nullptr, "WriteSaveDataFileSystemExtraDataBySaveDataAttribute"}, 699 {70, nullptr, "WriteSaveDataFileSystemExtraDataBySaveDataAttribute"},
700 {71, nullptr, "ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute"},
700 {80, nullptr, "OpenSaveDataMetaFile"}, 701 {80, nullptr, "OpenSaveDataMetaFile"},
701 {81, nullptr, "OpenSaveDataTransferManager"}, 702 {81, nullptr, "OpenSaveDataTransferManager"},
702 {82, nullptr, "OpenSaveDataTransferManagerVersion2"}, 703 {82, nullptr, "OpenSaveDataTransferManagerVersion2"},
703 {83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"}, 704 {83, nullptr, "OpenSaveDataTransferProhibiterForCloudBackUp"},
704 {84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"}, 705 {84, nullptr, "ListApplicationAccessibleSaveDataOwnerId"},
705 {85, nullptr, "OpenSaveDataTransferManagerForSaveDataRepair"}, 706 {85, nullptr, "OpenSaveDataTransferManagerForSaveDataRepair"},
707 {86, nullptr, "OpenSaveDataMover"},
706 {100, nullptr, "OpenImageDirectoryFileSystem"}, 708 {100, nullptr, "OpenImageDirectoryFileSystem"},
707 {110, nullptr, "OpenContentStorageFileSystem"}, 709 {110, nullptr, "OpenContentStorageFileSystem"},
708 {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"}, 710 {120, nullptr, "OpenCloudBackupWorkStorageFileSystem"},
@@ -762,9 +764,11 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
762 {1011, &FSP_SRV::GetAccessLogVersionInfo, "GetAccessLogVersionInfo"}, 764 {1011, &FSP_SRV::GetAccessLogVersionInfo, "GetAccessLogVersionInfo"},
763 {1012, nullptr, "GetFsStackUsage"}, 765 {1012, nullptr, "GetFsStackUsage"},
764 {1013, nullptr, "UnsetSaveDataRootPath"}, 766 {1013, nullptr, "UnsetSaveDataRootPath"},
767 {1014, nullptr, "OutputMultiProgramTagAccessLog"},
765 {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, 768 {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
766 {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, 769 {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
767 {1200, nullptr, "OpenMultiCommitManager"}, 770 {1200, nullptr, "OpenMultiCommitManager"},
771 {1300, nullptr, "OpenBisWiper"},
768 }; 772 };
769 // clang-format on 773 // clang-format on
770 RegisterHandlers(functions); 774 RegisterHandlers(functions);
diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp
index 7938b4b80..68f259b70 100644
--- a/src/core/hle/service/friend/friend.cpp
+++ b/src/core/hle/service/friend/friend.cpp
@@ -96,6 +96,7 @@ public:
96 {30830, nullptr, "ClearPlayLog"}, 96 {30830, nullptr, "ClearPlayLog"},
97 {30900, nullptr, "SendFriendInvitation"}, 97 {30900, nullptr, "SendFriendInvitation"},
98 {30910, nullptr, "ReadFriendInvitation"}, 98 {30910, nullptr, "ReadFriendInvitation"},
99 {30911, nullptr, "ReadAllFriendInvitations"},
99 {49900, nullptr, "DeleteNetworkServiceAccountCache"}, 100 {49900, nullptr, "DeleteNetworkServiceAccountCache"},
100 }; 101 };
101 // clang-format on 102 // clang-format on
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index d6031a987..a5fa3c7c4 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -282,6 +282,7 @@ Hid::Hid(Core::System& system) : ServiceFramework("hid"), system(system) {
282 {1001, nullptr, "GetNpadCommunicationMode"}, 282 {1001, nullptr, "GetNpadCommunicationMode"},
283 {1002, nullptr, "SetTouchScreenConfiguration"}, 283 {1002, nullptr, "SetTouchScreenConfiguration"},
284 {1003, nullptr, "IsFirmwareUpdateNeededForNotification"}, 284 {1003, nullptr, "IsFirmwareUpdateNeededForNotification"},
285 {2000, nullptr, "ActivateDigitizer"},
285 }; 286 };
286 // clang-format on 287 // clang-format on
287 288
@@ -870,6 +871,7 @@ public:
870 {10, nullptr, "DeactivateTouchScreen"}, 871 {10, nullptr, "DeactivateTouchScreen"},
871 {11, nullptr, "SetTouchScreenAutoPilotState"}, 872 {11, nullptr, "SetTouchScreenAutoPilotState"},
872 {12, nullptr, "UnsetTouchScreenAutoPilotState"}, 873 {12, nullptr, "UnsetTouchScreenAutoPilotState"},
874 {13, nullptr, "GetTouchScreenConfiguration"},
873 {20, nullptr, "DeactivateMouse"}, 875 {20, nullptr, "DeactivateMouse"},
874 {21, nullptr, "SetMouseAutoPilotState"}, 876 {21, nullptr, "SetMouseAutoPilotState"},
875 {22, nullptr, "UnsetMouseAutoPilotState"}, 877 {22, nullptr, "UnsetMouseAutoPilotState"},
@@ -879,7 +881,9 @@ public:
879 {50, nullptr, "DeactivateXpad"}, 881 {50, nullptr, "DeactivateXpad"},
880 {51, nullptr, "SetXpadAutoPilotState"}, 882 {51, nullptr, "SetXpadAutoPilotState"},
881 {52, nullptr, "UnsetXpadAutoPilotState"}, 883 {52, nullptr, "UnsetXpadAutoPilotState"},
882 {60, nullptr, "DeactivateJoyXpad"}, 884 {60, nullptr, "ClearNpadSystemCommonPolicy"},
885 {61, nullptr, "DeactivateNpad"},
886 {62, nullptr, "ForceDisconnectNpad"},
883 {91, nullptr, "DeactivateGesture"}, 887 {91, nullptr, "DeactivateGesture"},
884 {110, nullptr, "DeactivateHomeButton"}, 888 {110, nullptr, "DeactivateHomeButton"},
885 {111, nullptr, "SetHomeButtonAutoPilotState"}, 889 {111, nullptr, "SetHomeButtonAutoPilotState"},
@@ -899,6 +903,15 @@ public:
899 {141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"}, 903 {141, nullptr, "GetConsoleSixAxisSensorSamplingFrequency"},
900 {142, nullptr, "DeactivateSevenSixAxisSensor"}, 904 {142, nullptr, "DeactivateSevenSixAxisSensor"},
901 {143, nullptr, "GetConsoleSixAxisSensorCountStates"}, 905 {143, nullptr, "GetConsoleSixAxisSensorCountStates"},
906 {144, nullptr, "GetAccelerometerFsr"},
907 {145, nullptr, "SetAccelerometerFsr"},
908 {146, nullptr, "GetAccelerometerOdr"},
909 {147, nullptr, "SetAccelerometerOdr"},
910 {148, nullptr, "GetGyroscopeFsr"},
911 {149, nullptr, "SetGyroscopeFsr"},
912 {150, nullptr, "GetGyroscopeOdr"},
913 {151, nullptr, "SetGyroscopeOdr"},
914 {152, nullptr, "GetWhoAmI"},
902 {201, nullptr, "ActivateFirmwareUpdate"}, 915 {201, nullptr, "ActivateFirmwareUpdate"},
903 {202, nullptr, "DeactivateFirmwareUpdate"}, 916 {202, nullptr, "DeactivateFirmwareUpdate"},
904 {203, nullptr, "StartFirmwareUpdate"}, 917 {203, nullptr, "StartFirmwareUpdate"},
@@ -927,6 +940,17 @@ public:
927 {233, nullptr, "ClearPairingInfo"}, 940 {233, nullptr, "ClearPairingInfo"},
928 {234, nullptr, "GetUniquePadDeviceTypeSetInternal"}, 941 {234, nullptr, "GetUniquePadDeviceTypeSetInternal"},
929 {235, nullptr, "EnableAnalogStickPower"}, 942 {235, nullptr, "EnableAnalogStickPower"},
943 {236, nullptr, "RequestKuinaUartClockCal"},
944 {237, nullptr, "GetKuinaUartClockCal"},
945 {238, nullptr, "SetKuinaUartClockTrim"},
946 {239, nullptr, "KuinaLoopbackTest"},
947 {240, nullptr, "RequestBatteryVoltage"},
948 {241, nullptr, "GetBatteryVoltage"},
949 {242, nullptr, "GetUniquePadPowerInfo"},
950 {243, nullptr, "RebootUniquePad"},
951 {244, nullptr, "RequestKuinaFirmwareVersion"},
952 {245, nullptr, "GetKuinaFirmwareVersion"},
953 {246, nullptr, "GetVidPid"},
930 {301, nullptr, "GetAbstractedPadHandles"}, 954 {301, nullptr, "GetAbstractedPadHandles"},
931 {302, nullptr, "GetAbstractedPadState"}, 955 {302, nullptr, "GetAbstractedPadState"},
932 {303, nullptr, "GetAbstractedPadsState"}, 956 {303, nullptr, "GetAbstractedPadsState"},
@@ -945,6 +969,17 @@ public:
945 {350, nullptr, "AddRegisteredDevice"}, 969 {350, nullptr, "AddRegisteredDevice"},
946 {400, nullptr, "DisableExternalMcuOnNxDevice"}, 970 {400, nullptr, "DisableExternalMcuOnNxDevice"},
947 {401, nullptr, "DisableRailDeviceFiltering"}, 971 {401, nullptr, "DisableRailDeviceFiltering"},
972 {402, nullptr, "EnableWiredPairing"},
973 {403, nullptr, "EnableShipmentModeAutoClear"},
974 {500, nullptr, "SetFactoryInt"},
975 {501, nullptr, "IsFactoryBootEnabled"},
976 {550, nullptr, "SetAnalogStickModelDataTemporarily"},
977 {551, nullptr, "GetAnalogStickModelData"},
978 {552, nullptr, "ResetAnalogStickModelData"},
979 {600, nullptr, "ConvertPadState"},
980 {2000, nullptr, "DeactivateDigitizer"},
981 {2001, nullptr, "SetDigitizerAutoPilotState"},
982 {2002, nullptr, "UnsetDigitizerAutoPilotState"},
948 }; 983 };
949 // clang-format on 984 // clang-format on
950 985
diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp
index 0cde7a557..6ad3be1b3 100644
--- a/src/core/hle/service/ldr/ldr.cpp
+++ b/src/core/hle/service/ldr/ldr.cpp
@@ -116,6 +116,7 @@ public:
116 {1, nullptr, "GetProgramInfo"}, 116 {1, nullptr, "GetProgramInfo"},
117 {2, nullptr, "RegisterTitle"}, 117 {2, nullptr, "RegisterTitle"},
118 {3, nullptr, "UnregisterTitle"}, 118 {3, nullptr, "UnregisterTitle"},
119 {4, nullptr, "SetEnabledProgramVerification"},
119 }; 120 };
120 // clang-format on 121 // clang-format on
121 122
diff --git a/src/core/hle/service/ncm/ncm.cpp b/src/core/hle/service/ncm/ncm.cpp
index 89e283ca5..ec9aae04a 100644
--- a/src/core/hle/service/ncm/ncm.cpp
+++ b/src/core/hle/service/ncm/ncm.cpp
@@ -122,6 +122,7 @@ public:
122 {11, nullptr, "ActivateContentMetaDatabase"}, 122 {11, nullptr, "ActivateContentMetaDatabase"},
123 {12, nullptr, "InactivateContentMetaDatabase"}, 123 {12, nullptr, "InactivateContentMetaDatabase"},
124 {13, nullptr, "InvalidateRightsIdCache"}, 124 {13, nullptr, "InvalidateRightsIdCache"},
125 {14, nullptr, "GetMemoryReport"},
125 }; 126 };
126 // clang-format on 127 // clang-format on
127 128
diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp
index aa171473b..f38d01084 100644
--- a/src/core/hle/service/npns/npns.cpp
+++ b/src/core/hle/service/npns/npns.cpp
@@ -48,6 +48,8 @@ public:
48 {151, nullptr, "GetStateWithHandover"}, 48 {151, nullptr, "GetStateWithHandover"},
49 {152, nullptr, "GetStateChangeEventWithHandover"}, 49 {152, nullptr, "GetStateChangeEventWithHandover"},
50 {153, nullptr, "GetDropEventWithHandover"}, 50 {153, nullptr, "GetDropEventWithHandover"},
51 {161, nullptr, "GetRequestChangeStateCancelEvent"},
52 {162, nullptr, "RequestChangeStateForceTimedWithCancelEvent"},
51 {201, nullptr, "RequestChangeStateForceTimed"}, 53 {201, nullptr, "RequestChangeStateForceTimed"},
52 {202, nullptr, "RequestChangeStateForceAsync"}, 54 {202, nullptr, "RequestChangeStateForceAsync"},
53 }; 55 };
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index fdab3cf78..8fb88990e 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -110,6 +110,10 @@ IApplicationManagerInterface::IApplicationManagerInterface()
110 {100, nullptr, "ResetToFactorySettings"}, 110 {100, nullptr, "ResetToFactorySettings"},
111 {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, 111 {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
112 {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, 112 {102, nullptr, "ResetToFactorySettingsForRefurbishment"},
113 {103, nullptr, "ResetToFactorySettingsWithPlatformRegion"},
114 {104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"},
115 {105, nullptr, "RequestResetToFactorySettingsSecurely"},
116 {106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"},
113 {200, nullptr, "CalculateUserSaveDataStatistics"}, 117 {200, nullptr, "CalculateUserSaveDataStatistics"},
114 {201, nullptr, "DeleteUserSaveDataAll"}, 118 {201, nullptr, "DeleteUserSaveDataAll"},
115 {210, nullptr, "DeleteUserSystemSaveData"}, 119 {210, nullptr, "DeleteUserSystemSaveData"},
@@ -191,6 +195,9 @@ IApplicationManagerInterface::IApplicationManagerInterface()
191 {1307, nullptr, "TryDeleteRunningApplicationContentEntities"}, 195 {1307, nullptr, "TryDeleteRunningApplicationContentEntities"},
192 {1308, nullptr, "DeleteApplicationCompletelyForDebug"}, 196 {1308, nullptr, "DeleteApplicationCompletelyForDebug"},
193 {1309, nullptr, "CleanupUnavailableAddOnContents"}, 197 {1309, nullptr, "CleanupUnavailableAddOnContents"},
198 {1310, nullptr, "RequestMoveApplicationEntity"},
199 {1311, nullptr, "EstimateSizeToMove"},
200 {1312, nullptr, "HasMovableEntity"},
194 {1400, nullptr, "PrepareShutdown"}, 201 {1400, nullptr, "PrepareShutdown"},
195 {1500, nullptr, "FormatSdCard"}, 202 {1500, nullptr, "FormatSdCard"},
196 {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"}, 203 {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"},
@@ -241,7 +248,7 @@ IApplicationManagerInterface::IApplicationManagerInterface()
241 {2153, nullptr, "DeactivateRightsEnvironment"}, 248 {2153, nullptr, "DeactivateRightsEnvironment"},
242 {2154, nullptr, "ForceActivateRightsContextForExit"}, 249 {2154, nullptr, "ForceActivateRightsContextForExit"},
243 {2155, nullptr, "UpdateRightsEnvironmentStatus"}, 250 {2155, nullptr, "UpdateRightsEnvironmentStatus"},
244 {2156, nullptr, "CreateRightsEnvironmentForPreomia"}, 251 {2156, nullptr, "CreateRightsEnvironmentForMicroApplication"},
245 {2160, nullptr, "AddTargetApplicationToRightsEnvironment"}, 252 {2160, nullptr, "AddTargetApplicationToRightsEnvironment"},
246 {2161, nullptr, "SetUsersToRightsEnvironment"}, 253 {2161, nullptr, "SetUsersToRightsEnvironment"},
247 {2170, nullptr, "GetRightsEnvironmentStatus"}, 254 {2170, nullptr, "GetRightsEnvironmentStatus"},
@@ -258,6 +265,7 @@ IApplicationManagerInterface::IApplicationManagerInterface()
258 {2350, nullptr, "PerformAutoUpdateByApplicationId"}, 265 {2350, nullptr, "PerformAutoUpdateByApplicationId"},
259 {2351, nullptr, "RequestNoDownloadRightsErrorResolution"}, 266 {2351, nullptr, "RequestNoDownloadRightsErrorResolution"},
260 {2352, nullptr, "RequestResolveNoDownloadRightsError"}, 267 {2352, nullptr, "RequestResolveNoDownloadRightsError"},
268 {2353, nullptr, "GetApplicationDownloadTaskInfo"},
261 {2400, nullptr, "GetPromotionInfo"}, 269 {2400, nullptr, "GetPromotionInfo"},
262 {2401, nullptr, "CountPromotionInfo"}, 270 {2401, nullptr, "CountPromotionInfo"},
263 {2402, nullptr, "ListPromotionInfo"}, 271 {2402, nullptr, "ListPromotionInfo"},
@@ -266,9 +274,12 @@ IApplicationManagerInterface::IApplicationManagerInterface()
266 {2500, nullptr, "ConfirmAvailableTime"}, 274 {2500, nullptr, "ConfirmAvailableTime"},
267 {2510, nullptr, "CreateApplicationResource"}, 275 {2510, nullptr, "CreateApplicationResource"},
268 {2511, nullptr, "GetApplicationResource"}, 276 {2511, nullptr, "GetApplicationResource"},
269 {2513, nullptr, "LaunchPreomia"}, 277 {2513, nullptr, "LaunchMicroApplication"},
270 {2514, nullptr, "ClearTaskOfAsyncTaskManager"}, 278 {2514, nullptr, "ClearTaskOfAsyncTaskManager"},
279 {2515, nullptr, "CleanupAllPlaceHolderAndFragmentsIfNoTask"},
280 {2516, nullptr, "EnsureApplicationCertificate"},
271 {2800, nullptr, "GetApplicationIdOfPreomia"}, 281 {2800, nullptr, "GetApplicationIdOfPreomia"},
282 {9999, nullptr, "GetApplicationCertificate"},
272 }; 283 };
273 // clang-format on 284 // clang-format on
274 285
@@ -505,6 +516,10 @@ IFactoryResetInterface::IFactoryResetInterface::IFactoryResetInterface()
505 {100, nullptr, "ResetToFactorySettings"}, 516 {100, nullptr, "ResetToFactorySettings"},
506 {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, 517 {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
507 {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, 518 {102, nullptr, "ResetToFactorySettingsForRefurbishment"},
519 {103, nullptr, "ResetToFactorySettingsWithPlatformRegion"},
520 {104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"},
521 {105, nullptr, "RequestResetToFactorySettingsSecurely"},
522 {106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"},
508 }; 523 };
509 // clang-format on 524 // clang-format on
510 525
@@ -553,6 +568,9 @@ public:
553 {10, nullptr, "TerminateApplication2"}, 568 {10, nullptr, "TerminateApplication2"},
554 {11, nullptr, "GetRunningApplicationProcessId"}, 569 {11, nullptr, "GetRunningApplicationProcessId"},
555 {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActive"}, 570 {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActive"},
571 {13, nullptr, "CreateApplicationResourceForDevelop"},
572 {14, nullptr, "IsPreomiaForDevelop"},
573 {15, nullptr, "GetApplicationProgramIdFromHost"},
556 }; 574 };
557 // clang-format on 575 // clang-format on
558 576
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index ab1746d28..6efdf1606 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -164,6 +164,7 @@ PL_U::PL_U(Core::System& system)
164 {6, nullptr, "GetSharedFontInOrderOfPriorityForSystem"}, 164 {6, nullptr, "GetSharedFontInOrderOfPriorityForSystem"},
165 {100, nullptr, "RequestApplicationFunctionAuthorization"}, 165 {100, nullptr, "RequestApplicationFunctionAuthorization"},
166 {101, nullptr, "RequestApplicationFunctionAuthorizationForSystem"}, 166 {101, nullptr, "RequestApplicationFunctionAuthorizationForSystem"},
167 {102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"},
167 {1000, nullptr, "LoadNgWordDataForPlatformRegionChina"}, 168 {1000, nullptr, "LoadNgWordDataForPlatformRegionChina"},
168 {1001, nullptr, "GetNgWordDataSizeForPlatformRegionChina"}, 169 {1001, nullptr, "GetNgWordDataSizeForPlatformRegionChina"},
169 }; 170 };
diff --git a/src/core/hle/service/pctl/module.cpp b/src/core/hle/service/pctl/module.cpp
index c75b4ee34..caf14ed61 100644
--- a/src/core/hle/service/pctl/module.cpp
+++ b/src/core/hle/service/pctl/module.cpp
@@ -31,6 +31,8 @@ public:
31 {1014, nullptr, "ConfirmPlayableApplicationVideoOld"}, 31 {1014, nullptr, "ConfirmPlayableApplicationVideoOld"},
32 {1015, nullptr, "ConfirmPlayableApplicationVideo"}, 32 {1015, nullptr, "ConfirmPlayableApplicationVideo"},
33 {1016, nullptr, "ConfirmShowNewsPermission"}, 33 {1016, nullptr, "ConfirmShowNewsPermission"},
34 {1017, nullptr, "EndFreeCommunication"},
35 {1018, nullptr, "IsFreeCommunicationAvailable"},
34 {1031, nullptr, "IsRestrictionEnabled"}, 36 {1031, nullptr, "IsRestrictionEnabled"},
35 {1032, nullptr, "GetSafetyLevel"}, 37 {1032, nullptr, "GetSafetyLevel"},
36 {1033, nullptr, "SetSafetyLevel"}, 38 {1033, nullptr, "SetSafetyLevel"},
diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp
index 8f1be0e48..14309c679 100644
--- a/src/core/hle/service/prepo/prepo.cpp
+++ b/src/core/hle/service/prepo/prepo.cpp
@@ -21,8 +21,10 @@ public:
21 static const FunctionInfo functions[] = { 21 static const FunctionInfo functions[] = {
22 {10100, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old>, "SaveReportOld"}, 22 {10100, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old>, "SaveReportOld"},
23 {10101, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old>, "SaveReportWithUserOld"}, 23 {10101, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old>, "SaveReportWithUserOld"},
24 {10102, &PlayReport::SaveReport<Core::Reporter::PlayReportType::New>, "SaveReport"}, 24 {10102, &PlayReport::SaveReport<Core::Reporter::PlayReportType::Old2>, "SaveReportOld2"},
25 {10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::New>, "SaveReportWithUser"}, 25 {10103, &PlayReport::SaveReportWithUser<Core::Reporter::PlayReportType::Old2>, "SaveReportWithUserOld2"},
26 {10104, nullptr, "SaveReport"},
27 {10105, nullptr, "SaveReportWithUser"},
26 {10200, nullptr, "RequestImmediateTransmission"}, 28 {10200, nullptr, "RequestImmediateTransmission"},
27 {10300, nullptr, "GetTransmissionStatus"}, 29 {10300, nullptr, "GetTransmissionStatus"},
28 {10400, nullptr, "GetSystemSessionId"}, 30 {10400, nullptr, "GetSystemSessionId"},
@@ -35,8 +37,10 @@ public:
35 {30400, nullptr, "GetStatistics"}, 37 {30400, nullptr, "GetStatistics"},
36 {30401, nullptr, "GetThroughputHistory"}, 38 {30401, nullptr, "GetThroughputHistory"},
37 {30500, nullptr, "GetLastUploadError"}, 39 {30500, nullptr, "GetLastUploadError"},
40 {30600, nullptr, "GetApplicationUploadSummary"},
38 {40100, nullptr, "IsUserAgreementCheckEnabled"}, 41 {40100, nullptr, "IsUserAgreementCheckEnabled"},
39 {40101, nullptr, "SetUserAgreementCheckEnabled"}, 42 {40101, nullptr, "SetUserAgreementCheckEnabled"},
43 {50100, nullptr, "ReadAllApplicationReportFiles"},
40 {90100, nullptr, "ReadAllReportFiles"}, 44 {90100, nullptr, "ReadAllReportFiles"},
41 }; 45 };
42 // clang-format on 46 // clang-format on
@@ -51,7 +55,7 @@ private:
51 const auto process_id = rp.PopRaw<u64>(); 55 const auto process_id = rp.PopRaw<u64>();
52 56
53 std::vector<std::vector<u8>> data{ctx.ReadBuffer(0)}; 57 std::vector<std::vector<u8>> data{ctx.ReadBuffer(0)};
54 if (Type == Core::Reporter::PlayReportType::New) { 58 if constexpr (Type == Core::Reporter::PlayReportType::Old2) {
55 data.emplace_back(ctx.ReadBuffer(1)); 59 data.emplace_back(ctx.ReadBuffer(1));
56 } 60 }
57 61
@@ -71,7 +75,7 @@ private:
71 const auto user_id = rp.PopRaw<u128>(); 75 const auto user_id = rp.PopRaw<u128>();
72 const auto process_id = rp.PopRaw<u64>(); 76 const auto process_id = rp.PopRaw<u64>();
73 std::vector<std::vector<u8>> data{ctx.ReadBuffer(0)}; 77 std::vector<std::vector<u8>> data{ctx.ReadBuffer(0)};
74 if (Type == Core::Reporter::PlayReportType::New) { 78 if constexpr (Type == Core::Reporter::PlayReportType::Old2) {
75 data.emplace_back(ctx.ReadBuffer(1)); 79 data.emplace_back(ctx.ReadBuffer(1));
76 } 80 }
77 81
diff --git a/src/core/hle/service/set/set_cal.cpp b/src/core/hle/service/set/set_cal.cpp
index 1398a4a48..3fbfecc9e 100644
--- a/src/core/hle/service/set/set_cal.cpp
+++ b/src/core/hle/service/set/set_cal.cpp
@@ -50,6 +50,8 @@ SET_CAL::SET_CAL() : ServiceFramework("set:cal") {
50 {39, nullptr, "GetConsoleSixAxisSensorModuleType"}, 50 {39, nullptr, "GetConsoleSixAxisSensorModuleType"},
51 {40, nullptr, "GetConsoleSixAxisSensorHorizontalOffset"}, 51 {40, nullptr, "GetConsoleSixAxisSensorHorizontalOffset"},
52 {41, nullptr, "GetBatteryVersion"}, 52 {41, nullptr, "GetBatteryVersion"},
53 {42, nullptr, "GetDeviceId"},
54 {43, nullptr, "GetConsoleSixAxisSensorMountType"},
53 }; 55 };
54 // clang-format on 56 // clang-format on
55 57
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index b7c9ea74b..8bd4c7e79 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -288,6 +288,18 @@ SET_SYS::SET_SYS() : ServiceFramework("set:sys") {
288 {186, nullptr, "GetMemoryUsageRateFlag"}, 288 {186, nullptr, "GetMemoryUsageRateFlag"},
289 {187, nullptr, "GetTouchScreenMode"}, 289 {187, nullptr, "GetTouchScreenMode"},
290 {188, nullptr, "SetTouchScreenMode"}, 290 {188, nullptr, "SetTouchScreenMode"},
291 {189, nullptr, "GetButtonConfigSettingsFull"},
292 {190, nullptr, "SetButtonConfigSettingsFull"},
293 {191, nullptr, "GetButtonConfigSettingsEmbedded"},
294 {192, nullptr, "SetButtonConfigSettingsEmbedded"},
295 {193, nullptr, "GetButtonConfigSettingsLeft"},
296 {194, nullptr, "SetButtonConfigSettingsLeft"},
297 {195, nullptr, "GetButtonConfigSettingsRight"},
298 {196, nullptr, "SetButtonConfigSettingsRight"},
299 {197, nullptr, "GetButtonConfigRegisteredSettingsEmbedded"},
300 {198, nullptr, "SetButtonConfigRegisteredSettingsEmbedded"},
301 {199, nullptr, "GetButtonConfigRegisteredSettings"},
302 {200, nullptr, "SetButtonConfigRegisteredSettings"},
291 }; 303 };
292 // clang-format on 304 // clang-format on
293 305
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index f67fab2f9..8d4952c0e 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -148,6 +148,7 @@ BSD::BSD(const char* name) : ServiceFramework(name) {
148 {30, nullptr, "SendMMsg"}, 148 {30, nullptr, "SendMMsg"},
149 {31, nullptr, "EventFd"}, 149 {31, nullptr, "EventFd"},
150 {32, nullptr, "RegisterResourceStatisticsName"}, 150 {32, nullptr, "RegisterResourceStatisticsName"},
151 {33, nullptr, "Initialize2"},
151 }; 152 };
152 // clang-format on 153 // clang-format on
153 154
diff --git a/src/core/reporter.h b/src/core/reporter.h
index 380941b1b..86d760cf0 100644
--- a/src/core/reporter.h
+++ b/src/core/reporter.h
@@ -56,6 +56,7 @@ public:
56 56
57 enum class PlayReportType { 57 enum class PlayReportType {
58 Old, 58 Old,
59 Old2,
59 New, 60 New,
60 System, 61 System,
61 }; 62 };
diff --git a/src/video_core/engines/maxwell_3d.h b/src/video_core/engines/maxwell_3d.h
index cfcda4f53..3dfba8197 100644
--- a/src/video_core/engines/maxwell_3d.h
+++ b/src/video_core/engines/maxwell_3d.h
@@ -1259,7 +1259,8 @@ public:
1259 1259
1260 GPUVAddr LimitAddress() const { 1260 GPUVAddr LimitAddress() const {
1261 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_high) << 32) | 1261 return static_cast<GPUVAddr>((static_cast<GPUVAddr>(limit_high) << 32) |
1262 limit_low); 1262 limit_low) +
1263 1;
1263 } 1264 }
1264 } vertex_array_limit[NumVertexArrays]; 1265 } vertex_array_limit[NumVertexArrays];
1265 1266
diff --git a/src/video_core/engines/shader_bytecode.h b/src/video_core/engines/shader_bytecode.h
index 7231597d4..cde3a26b9 100644
--- a/src/video_core/engines/shader_bytecode.h
+++ b/src/video_core/engines/shader_bytecode.h
@@ -655,6 +655,7 @@ union Instruction {
655 } 655 }
656 656
657 constexpr Instruction(u64 value) : value{value} {} 657 constexpr Instruction(u64 value) : value{value} {}
658 constexpr Instruction(const Instruction& instr) : value(instr.value) {}
658 659
659 BitField<0, 8, Register> gpr0; 660 BitField<0, 8, Register> gpr0;
660 BitField<8, 8, Register> gpr8; 661 BitField<8, 8, Register> gpr8;
@@ -817,11 +818,9 @@ union Instruction {
817 BitField<32, 1, u64> saturate; 818 BitField<32, 1, u64> saturate;
818 BitField<49, 2, HalfMerge> merge; 819 BitField<49, 2, HalfMerge> merge;
819 820
820 BitField<43, 1, u64> negate_a;
821 BitField<44, 1, u64> abs_a; 821 BitField<44, 1, u64> abs_a;
822 BitField<47, 2, HalfType> type_a; 822 BitField<47, 2, HalfType> type_a;
823 823
824 BitField<31, 1, u64> negate_b;
825 BitField<30, 1, u64> abs_b; 824 BitField<30, 1, u64> abs_b;
826 BitField<28, 2, HalfType> type_b; 825 BitField<28, 2, HalfType> type_b;
827 826
diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp
index fd49bc2a9..dbee9f634 100644
--- a/src/video_core/memory_manager.cpp
+++ b/src/video_core/memory_manager.cpp
@@ -51,11 +51,8 @@ GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, u64 size) {
51 const GPUVAddr gpu_addr{FindFreeRegion(address_space_base, aligned_size)}; 51 const GPUVAddr gpu_addr{FindFreeRegion(address_space_base, aligned_size)};
52 52
53 MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr); 53 MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr);
54 ASSERT(system.CurrentProcess() 54 ASSERT(
55 ->PageTable() 55 system.CurrentProcess()->PageTable().LockForDeviceAddressSpace(cpu_addr, size).IsSuccess());
56 .SetMemoryAttribute(cpu_addr, size, Kernel::Memory::MemoryAttribute::DeviceShared,
57 Kernel::Memory::MemoryAttribute::DeviceShared)
58 .IsSuccess());
59 56
60 return gpu_addr; 57 return gpu_addr;
61} 58}
@@ -66,11 +63,8 @@ GPUVAddr MemoryManager::MapBufferEx(VAddr cpu_addr, GPUVAddr gpu_addr, u64 size)
66 const u64 aligned_size{Common::AlignUp(size, page_size)}; 63 const u64 aligned_size{Common::AlignUp(size, page_size)};
67 64
68 MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr); 65 MapBackingMemory(gpu_addr, system.Memory().GetPointer(cpu_addr), aligned_size, cpu_addr);
69 ASSERT(system.CurrentProcess() 66 ASSERT(
70 ->PageTable() 67 system.CurrentProcess()->PageTable().LockForDeviceAddressSpace(cpu_addr, size).IsSuccess());
71 .SetMemoryAttribute(cpu_addr, size, Kernel::Memory::MemoryAttribute::DeviceShared,
72 Kernel::Memory::MemoryAttribute::DeviceShared)
73 .IsSuccess());
74 return gpu_addr; 68 return gpu_addr;
75} 69}
76 70
@@ -87,9 +81,7 @@ GPUVAddr MemoryManager::UnmapBuffer(GPUVAddr gpu_addr, u64 size) {
87 UnmapRange(gpu_addr, aligned_size); 81 UnmapRange(gpu_addr, aligned_size);
88 ASSERT(system.CurrentProcess() 82 ASSERT(system.CurrentProcess()
89 ->PageTable() 83 ->PageTable()
90 .SetMemoryAttribute(cpu_addr.value(), size, 84 .UnlockForDeviceAddressSpace(cpu_addr.value(), size)
91 Kernel::Memory::MemoryAttribute::DeviceShared,
92 Kernel::Memory::MemoryAttribute::None)
93 .IsSuccess()); 85 .IsSuccess());
94 86
95 return gpu_addr; 87 return gpu_addr;
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index 4c16c89d2..6fe155bcc 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -186,8 +186,12 @@ void RasterizerOpenGL::SetupVertexBuffer() {
186 const GPUVAddr start = vertex_array.StartAddress(); 186 const GPUVAddr start = vertex_array.StartAddress();
187 const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); 187 const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
188 188
189 ASSERT(end > start); 189 ASSERT(end >= start);
190 const u64 size = end - start + 1; 190 const u64 size = end - start;
191 if (size == 0) {
192 glBindVertexBuffer(static_cast<GLuint>(index), 0, 0, vertex_array.stride);
193 continue;
194 }
191 const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size); 195 const auto [vertex_buffer, vertex_buffer_offset] = buffer_cache.UploadMemory(start, size);
192 glBindVertexBuffer(static_cast<GLuint>(index), vertex_buffer, vertex_buffer_offset, 196 glBindVertexBuffer(static_cast<GLuint>(index), vertex_buffer, vertex_buffer_offset,
193 vertex_array.stride); 197 vertex_array.stride);
@@ -311,8 +315,8 @@ std::size_t RasterizerOpenGL::CalculateVertexArraysSize() const {
311 const GPUVAddr start = regs.vertex_array[index].StartAddress(); 315 const GPUVAddr start = regs.vertex_array[index].StartAddress();
312 const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress(); 316 const GPUVAddr end = regs.vertex_array_limit[index].LimitAddress();
313 317
314 ASSERT(end > start); 318 size += end - start;
315 size += end - start + 1; 319 ASSERT(end >= start);
316 } 320 }
317 321
318 return size; 322 return size;
diff --git a/src/video_core/renderer_vulkan/fixed_pipeline_state.h b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
index 9fe6bdbf9..9a950f4de 100644
--- a/src/video_core/renderer_vulkan/fixed_pipeline_state.h
+++ b/src/video_core/renderer_vulkan/fixed_pipeline_state.h
@@ -129,7 +129,7 @@ struct alignas(32) FixedPipelineState {
129 auto& binding = bindings[index]; 129 auto& binding = bindings[index];
130 binding.raw = 0; 130 binding.raw = 0;
131 binding.enabled.Assign(enabled ? 1 : 0); 131 binding.enabled.Assign(enabled ? 1 : 0);
132 binding.stride.Assign(stride); 132 binding.stride.Assign(static_cast<u16>(stride));
133 binding_divisors[index] = divisor; 133 binding_divisors[index] = divisor;
134 } 134 }
135 135
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 8a1f57891..68464e637 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -877,8 +877,12 @@ void RasterizerVulkan::SetupVertexArrays(FixedPipelineState::VertexInput& vertex
877 const GPUVAddr start{vertex_array.StartAddress()}; 877 const GPUVAddr start{vertex_array.StartAddress()};
878 const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()}; 878 const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()};
879 879
880 ASSERT(end > start); 880 ASSERT(end >= start);
881 const std::size_t size{end - start + 1}; 881 const std::size_t size{end - start};
882 if (size == 0) {
883 buffer_bindings.AddVertexBinding(DefaultBuffer(), 0);
884 continue;
885 }
882 const auto [buffer, offset] = buffer_cache.UploadMemory(start, size); 886 const auto [buffer, offset] = buffer_cache.UploadMemory(start, size);
883 buffer_bindings.AddVertexBinding(buffer, offset); 887 buffer_bindings.AddVertexBinding(buffer, offset);
884 } 888 }
@@ -1033,8 +1037,7 @@ void RasterizerVulkan::SetupConstBuffer(const ConstBufferEntry& entry,
1033 const Tegra::Engines::ConstBufferInfo& buffer) { 1037 const Tegra::Engines::ConstBufferInfo& buffer) {
1034 if (!buffer.enabled) { 1038 if (!buffer.enabled) {
1035 // Set values to zero to unbind buffers 1039 // Set values to zero to unbind buffers
1036 update_descriptor_queue.AddBuffer(buffer_cache.GetEmptyBuffer(sizeof(float)), 0, 1040 update_descriptor_queue.AddBuffer(DefaultBuffer(), 0, DEFAULT_BUFFER_SIZE);
1037 sizeof(float));
1038 return; 1041 return;
1039 } 1042 }
1040 1043
@@ -1057,7 +1060,9 @@ void RasterizerVulkan::SetupGlobalBuffer(const GlobalBufferEntry& entry, GPUVAdd
1057 if (size == 0) { 1060 if (size == 0) {
1058 // Sometimes global memory pointers don't have a proper size. Upload a dummy entry 1061 // Sometimes global memory pointers don't have a proper size. Upload a dummy entry
1059 // because Vulkan doesn't like empty buffers. 1062 // because Vulkan doesn't like empty buffers.
1060 constexpr std::size_t dummy_size = 4; 1063 // Note: Do *not* use DefaultBuffer() here, storage buffers can be written breaking the
1064 // default buffer.
1065 static constexpr std::size_t dummy_size = 4;
1061 const auto buffer = buffer_cache.GetEmptyBuffer(dummy_size); 1066 const auto buffer = buffer_cache.GetEmptyBuffer(dummy_size);
1062 update_descriptor_queue.AddBuffer(buffer, 0, dummy_size); 1067 update_descriptor_queue.AddBuffer(buffer, 0, dummy_size);
1063 return; 1068 return;
@@ -1222,7 +1227,7 @@ std::size_t RasterizerVulkan::CalculateVertexArraysSize() const {
1222 const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()}; 1227 const GPUVAddr end{regs.vertex_array_limit[index].LimitAddress()};
1223 DEBUG_ASSERT(end >= start); 1228 DEBUG_ASSERT(end >= start);
1224 1229
1225 size += (end - start + 1) * regs.vertex_array[index].enable; 1230 size += (end - start) * regs.vertex_array[index].enable;
1226 } 1231 }
1227 return size; 1232 return size;
1228} 1233}
@@ -1269,4 +1274,29 @@ RenderPassParams RasterizerVulkan::GetRenderPassParams(Texceptions texceptions)
1269 return renderpass_params; 1274 return renderpass_params;
1270} 1275}
1271 1276
1277VkBuffer RasterizerVulkan::DefaultBuffer() {
1278 if (default_buffer) {
1279 return *default_buffer;
1280 }
1281
1282 VkBufferCreateInfo ci;
1283 ci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
1284 ci.pNext = nullptr;
1285 ci.flags = 0;
1286 ci.size = DEFAULT_BUFFER_SIZE;
1287 ci.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT |
1288 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT;
1289 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
1290 ci.queueFamilyIndexCount = 0;
1291 ci.pQueueFamilyIndices = nullptr;
1292 default_buffer = device.GetLogical().CreateBuffer(ci);
1293 default_buffer_commit = memory_manager.Commit(default_buffer, false);
1294
1295 scheduler.RequestOutsideRenderPassOperationContext();
1296 scheduler.Record([buffer = *default_buffer](vk::CommandBuffer cmdbuf) {
1297 cmdbuf.FillBuffer(buffer, 0, DEFAULT_BUFFER_SIZE, 0);
1298 });
1299 return *default_buffer;
1300}
1301
1272} // namespace Vulkan 1302} // namespace Vulkan
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.h b/src/video_core/renderer_vulkan/vk_rasterizer.h
index 2fa46b0cc..d41a7929e 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.h
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.h
@@ -155,6 +155,7 @@ private:
155 using Texceptions = std::bitset<Maxwell::NumRenderTargets + 1>; 155 using Texceptions = std::bitset<Maxwell::NumRenderTargets + 1>;
156 156
157 static constexpr std::size_t ZETA_TEXCEPTION_INDEX = 8; 157 static constexpr std::size_t ZETA_TEXCEPTION_INDEX = 8;
158 static constexpr VkDeviceSize DEFAULT_BUFFER_SIZE = 4 * sizeof(float);
158 159
159 void FlushWork(); 160 void FlushWork();
160 161
@@ -247,6 +248,8 @@ private:
247 248
248 RenderPassParams GetRenderPassParams(Texceptions texceptions) const; 249 RenderPassParams GetRenderPassParams(Texceptions texceptions) const;
249 250
251 VkBuffer DefaultBuffer();
252
250 Core::System& system; 253 Core::System& system;
251 Core::Frontend::EmuWindow& render_window; 254 Core::Frontend::EmuWindow& render_window;
252 VKScreenInfo& screen_info; 255 VKScreenInfo& screen_info;
@@ -271,6 +274,9 @@ private:
271 VKFenceManager fence_manager; 274 VKFenceManager fence_manager;
272 VKQueryCache query_cache; 275 VKQueryCache query_cache;
273 276
277 vk::Buffer default_buffer;
278 VKMemoryCommit default_buffer_commit;
279
274 std::array<View, Maxwell::NumRenderTargets> color_attachments; 280 std::array<View, Maxwell::NumRenderTargets> color_attachments;
275 View zeta_attachment; 281 View zeta_attachment;
276 282
diff --git a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
index 94d954d7a..c76ab5c2d 100644
--- a/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
+++ b/src/video_core/renderer_vulkan/vk_staging_buffer_pool.cpp
@@ -81,7 +81,7 @@ VKBuffer& VKStagingBufferPool::CreateStagingBuffer(std::size_t size, bool host_v
81 ci.size = 1ULL << log2; 81 ci.size = 1ULL << log2;
82 ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT | 82 ci.usage = VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
83 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | 83 VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT | VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
84 VK_BUFFER_USAGE_INDEX_BUFFER_BIT; 84 VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_VERTEX_BUFFER_BIT;
85 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE; 85 ci.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
86 ci.queueFamilyIndexCount = 0; 86 ci.queueFamilyIndexCount = 0;
87 ci.pQueueFamilyIndices = nullptr; 87 ci.pQueueFamilyIndices = nullptr;
diff --git a/src/video_core/renderer_vulkan/wrapper.cpp b/src/video_core/renderer_vulkan/wrapper.cpp
index 539f3c974..7f5bc1404 100644
--- a/src/video_core/renderer_vulkan/wrapper.cpp
+++ b/src/video_core/renderer_vulkan/wrapper.cpp
@@ -2,6 +2,7 @@
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 <exception> 6#include <exception>
6#include <memory> 7#include <memory>
7#include <optional> 8#include <optional>
@@ -16,6 +17,23 @@ namespace Vulkan::vk {
16 17
17namespace { 18namespace {
18 19
20void SortPhysicalDevices(std::vector<VkPhysicalDevice>& devices, const InstanceDispatch& dld) {
21 std::stable_sort(devices.begin(), devices.end(), [&](auto lhs, auto rhs) {
22 // This will call Vulkan more than needed, but these calls are cheap.
23 const auto lhs_properties = vk::PhysicalDevice(lhs, dld).GetProperties();
24 const auto rhs_properties = vk::PhysicalDevice(rhs, dld).GetProperties();
25
26 // Prefer discrete GPUs, Nvidia over AMD, AMD over Intel, Intel over the rest.
27 const bool preferred =
28 (lhs_properties.deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU &&
29 rhs_properties.deviceType != VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU) ||
30 (lhs_properties.vendorID == 0x10DE && rhs_properties.vendorID != 0x10DE) ||
31 (lhs_properties.vendorID == 0x1002 && rhs_properties.vendorID != 0x1002) ||
32 (lhs_properties.vendorID == 0x8086 && rhs_properties.vendorID != 0x8086);
33 return !preferred;
34 });
35}
36
19template <typename T> 37template <typename T>
20bool Proc(T& result, const InstanceDispatch& dld, const char* proc_name, 38bool Proc(T& result, const InstanceDispatch& dld, const char* proc_name,
21 VkInstance instance = nullptr) noexcept { 39 VkInstance instance = nullptr) noexcept {
@@ -389,7 +407,8 @@ std::optional<std::vector<VkPhysicalDevice>> Instance::EnumeratePhysicalDevices(
389 if (dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()) != VK_SUCCESS) { 407 if (dld->vkEnumeratePhysicalDevices(handle, &num, physical_devices.data()) != VK_SUCCESS) {
390 return std::nullopt; 408 return std::nullopt;
391 } 409 }
392 return physical_devices; 410 SortPhysicalDevices(physical_devices, *dld);
411 return std::make_optional(std::move(physical_devices));
393} 412}
394 413
395DebugCallback Instance::TryCreateDebugCallback( 414DebugCallback Instance::TryCreateDebugCallback(
diff --git a/src/video_core/shader/decode/arithmetic_half.cpp b/src/video_core/shader/decode/arithmetic_half.cpp
index ee7d9a29d..a276aee44 100644
--- a/src/video_core/shader/decode/arithmetic_half.cpp
+++ b/src/video_core/shader/decode/arithmetic_half.cpp
@@ -19,22 +19,46 @@ u32 ShaderIR::DecodeArithmeticHalf(NodeBlock& bb, u32 pc) {
19 const Instruction instr = {program_code[pc]}; 19 const Instruction instr = {program_code[pc]};
20 const auto opcode = OpCode::Decode(instr); 20 const auto opcode = OpCode::Decode(instr);
21 21
22 if (opcode->get().GetId() == OpCode::Id::HADD2_C || 22 bool negate_a = false;
23 opcode->get().GetId() == OpCode::Id::HADD2_R) { 23 bool negate_b = false;
24 bool absolute_a = false;
25 bool absolute_b = false;
26
27 switch (opcode->get().GetId()) {
28 case OpCode::Id::HADD2_R:
24 if (instr.alu_half.ftz == 0) { 29 if (instr.alu_half.ftz == 0) {
25 LOG_DEBUG(HW_GPU, "{} without FTZ is not implemented", opcode->get().GetName()); 30 LOG_DEBUG(HW_GPU, "{} without FTZ is not implemented", opcode->get().GetName());
26 } 31 }
32 negate_a = ((instr.value >> 43) & 1) != 0;
33 negate_b = ((instr.value >> 31) & 1) != 0;
34 absolute_a = ((instr.value >> 44) & 1) != 0;
35 absolute_b = ((instr.value >> 30) & 1) != 0;
36 break;
37 case OpCode::Id::HADD2_C:
38 if (instr.alu_half.ftz == 0) {
39 LOG_DEBUG(HW_GPU, "{} without FTZ is not implemented", opcode->get().GetName());
40 }
41 negate_a = ((instr.value >> 43) & 1) != 0;
42 negate_b = ((instr.value >> 56) & 1) != 0;
43 absolute_a = ((instr.value >> 44) & 1) != 0;
44 absolute_b = ((instr.value >> 54) & 1) != 0;
45 break;
46 case OpCode::Id::HMUL2_R:
47 negate_a = ((instr.value >> 43) & 1) != 0;
48 absolute_a = ((instr.value >> 44) & 1) != 0;
49 absolute_b = ((instr.value >> 30) & 1) != 0;
50 break;
51 case OpCode::Id::HMUL2_C:
52 negate_b = ((instr.value >> 31) & 1) != 0;
53 absolute_a = ((instr.value >> 44) & 1) != 0;
54 absolute_b = ((instr.value >> 54) & 1) != 0;
55 break;
27 } 56 }
28 57
29 const bool negate_a =
30 opcode->get().GetId() != OpCode::Id::HMUL2_R && instr.alu_half.negate_a != 0;
31 const bool negate_b =
32 opcode->get().GetId() != OpCode::Id::HMUL2_C && instr.alu_half.negate_b != 0;
33
34 Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.alu_half.type_a); 58 Node op_a = UnpackHalfFloat(GetRegister(instr.gpr8), instr.alu_half.type_a);
35 op_a = GetOperandAbsNegHalf(op_a, instr.alu_half.abs_a, negate_a); 59 op_a = GetOperandAbsNegHalf(op_a, absolute_a, negate_a);
36 60
37 auto [type_b, op_b] = [&]() -> std::tuple<HalfType, Node> { 61 auto [type_b, op_b] = [this, instr, opcode]() -> std::pair<HalfType, Node> {
38 switch (opcode->get().GetId()) { 62 switch (opcode->get().GetId()) {
39 case OpCode::Id::HADD2_C: 63 case OpCode::Id::HADD2_C:
40 case OpCode::Id::HMUL2_C: 64 case OpCode::Id::HMUL2_C:
@@ -48,17 +72,16 @@ u32 ShaderIR::DecodeArithmeticHalf(NodeBlock& bb, u32 pc) {
48 } 72 }
49 }(); 73 }();
50 op_b = UnpackHalfFloat(op_b, type_b); 74 op_b = UnpackHalfFloat(op_b, type_b);
51 // redeclaration to avoid a bug in clang with reusing local bindings in lambdas 75 op_b = GetOperandAbsNegHalf(op_b, absolute_b, negate_b);
52 Node op_b_alt = GetOperandAbsNegHalf(op_b, instr.alu_half.abs_b, negate_b);
53 76
54 Node value = [&]() { 77 Node value = [this, opcode, op_a, op_b = op_b] {
55 switch (opcode->get().GetId()) { 78 switch (opcode->get().GetId()) {
56 case OpCode::Id::HADD2_C: 79 case OpCode::Id::HADD2_C:
57 case OpCode::Id::HADD2_R: 80 case OpCode::Id::HADD2_R:
58 return Operation(OperationCode::HAdd, PRECISE, op_a, op_b_alt); 81 return Operation(OperationCode::HAdd, PRECISE, op_a, op_b);
59 case OpCode::Id::HMUL2_C: 82 case OpCode::Id::HMUL2_C:
60 case OpCode::Id::HMUL2_R: 83 case OpCode::Id::HMUL2_R:
61 return Operation(OperationCode::HMul, PRECISE, op_a, op_b_alt); 84 return Operation(OperationCode::HMul, PRECISE, op_a, op_b);
62 default: 85 default:
63 UNIMPLEMENTED_MSG("Unhandled half float instruction: {}", opcode->get().GetName()); 86 UNIMPLEMENTED_MSG("Unhandled half float instruction: {}", opcode->get().GetName());
64 return Immediate(0); 87 return Immediate(0);
diff --git a/src/video_core/shader/decode/arithmetic_integer.cpp b/src/video_core/shader/decode/arithmetic_integer.cpp
index 0f4c3103a..9af8c606d 100644
--- a/src/video_core/shader/decode/arithmetic_integer.cpp
+++ b/src/video_core/shader/decode/arithmetic_integer.cpp
@@ -249,8 +249,8 @@ u32 ShaderIR::DecodeArithmeticInteger(NodeBlock& bb, u32 pc) {
249 } 249 }
250 case OpCode::Id::LEA_IMM: { 250 case OpCode::Id::LEA_IMM: {
251 const bool neg = instr.lea.imm.neg != 0; 251 const bool neg = instr.lea.imm.neg != 0;
252 return {Immediate(static_cast<u32>(instr.lea.imm.entry_a)), 252 return {GetOperandAbsNegInteger(GetRegister(instr.gpr8), false, neg, true),
253 GetOperandAbsNegInteger(GetRegister(instr.gpr8), false, neg, true), 253 Immediate(static_cast<u32>(instr.lea.imm.entry_a)),
254 Immediate(static_cast<u32>(instr.lea.imm.entry_b))}; 254 Immediate(static_cast<u32>(instr.lea.imm.entry_b))};
255 } 255 }
256 case OpCode::Id::LEA_RZ: { 256 case OpCode::Id::LEA_RZ: {
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 59c003f38..a44eed047 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -12,7 +12,6 @@
12#include "input_common/main.h" 12#include "input_common/main.h"
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#include "yuzu/uisettings.h"
16 15
17Config::Config() { 16Config::Config() {
18 // 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.
@@ -212,12 +211,13 @@ const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> Config::default
212// This must be in alphabetical order according to action name as it must have the same order as 211// This must be in alphabetical order according to action name as it must have the same order as
213// UISetting::values.shortcuts, which is alphabetically ordered. 212// UISetting::values.shortcuts, which is alphabetically ordered.
214// clang-format off 213// clang-format off
215const std::array<UISettings::Shortcut, 15> default_hotkeys{{ 214const std::array<UISettings::Shortcut, 15> Config::default_hotkeys{{
216 {QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::ApplicationShortcut}}, 215 {QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::ApplicationShortcut}},
216 {QStringLiteral("Change Docked Mode"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::ApplicationShortcut}},
217 {QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}}, 217 {QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}},
218 {QStringLiteral("Decrease Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("-"), Qt::ApplicationShortcut}}, 218 {QStringLiteral("Decrease Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("-"), Qt::ApplicationShortcut}},
219 {QStringLiteral("Exit yuzu"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Q"), Qt::WindowShortcut}},
220 {QStringLiteral("Exit Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("Esc"), Qt::WindowShortcut}}, 219 {QStringLiteral("Exit Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("Esc"), Qt::WindowShortcut}},
220 {QStringLiteral("Exit yuzu"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Q"), Qt::WindowShortcut}},
221 {QStringLiteral("Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("F11"), Qt::WindowShortcut}}, 221 {QStringLiteral("Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("F11"), Qt::WindowShortcut}},
222 {QStringLiteral("Increase Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("+"), Qt::ApplicationShortcut}}, 222 {QStringLiteral("Increase Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("+"), Qt::ApplicationShortcut}},
223 {QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::ApplicationShortcut}}, 223 {QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::ApplicationShortcut}},
@@ -227,7 +227,6 @@ const std::array<UISettings::Shortcut, 15> default_hotkeys{{
227 {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}}, 227 {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
228 {QStringLiteral("Toggle Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}}, 228 {QStringLiteral("Toggle Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
229 {QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}}, 229 {QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}},
230 {QStringLiteral("Change Docked Mode"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::ApplicationShortcut}},
231}}; 230}};
232// clang-format on 231// clang-format on
233 232
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index ba6888004..5cd2a5feb 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -9,6 +9,7 @@
9#include <string> 9#include <string>
10#include <QVariant> 10#include <QVariant>
11#include "core/settings.h" 11#include "core/settings.h"
12#include "yuzu/uisettings.h"
12 13
13class QSettings; 14class QSettings;
14 15
@@ -26,6 +27,7 @@ public:
26 default_mouse_buttons; 27 default_mouse_buttons;
27 static const std::array<int, Settings::NativeKeyboard::NumKeyboardKeys> default_keyboard_keys; 28 static const std::array<int, Settings::NativeKeyboard::NumKeyboardKeys> default_keyboard_keys;
28 static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods; 29 static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods;
30 static const std::array<UISettings::Shortcut, 15> default_hotkeys;
29 31
30private: 32private:
31 void ReadValues(); 33 void ReadValues();
diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp
index 29f540eb7..835ee821c 100644
--- a/src/yuzu/configuration/configure_filesystem.cpp
+++ b/src/yuzu/configuration/configure_filesystem.cpp
@@ -138,7 +138,7 @@ void ConfigureFilesystem::SetDirectory(DirectoryTarget target, QLineEdit* edit)
138 str = QFileDialog::getOpenFileName(this, caption, QFileInfo(edit->text()).dir().path(), 138 str = QFileDialog::getOpenFileName(this, caption, QFileInfo(edit->text()).dir().path(),
139 QStringLiteral("NX Gamecard;*.xci")); 139 QStringLiteral("NX Gamecard;*.xci"));
140 } else { 140 } else {
141 str = QFileDialog::getExistingDirectory(this, caption, edit->text()); 141 str = QFileDialog::getExistingDirectory(this, caption, edit->text()) + QDir::separator();
142 } 142 }
143 143
144 if (str.isEmpty()) 144 if (str.isEmpty())
diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp
index fa9052136..6f7fd4414 100644
--- a/src/yuzu/configuration/configure_hotkeys.cpp
+++ b/src/yuzu/configuration/configure_hotkeys.cpp
@@ -2,10 +2,12 @@
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 <QMenu>
5#include <QMessageBox> 6#include <QMessageBox>
6#include <QStandardItemModel> 7#include <QStandardItemModel>
7#include "core/settings.h" 8#include "core/settings.h"
8#include "ui_configure_hotkeys.h" 9#include "ui_configure_hotkeys.h"
10#include "yuzu/configuration/config.h"
9#include "yuzu/configuration/configure_hotkeys.h" 11#include "yuzu/configuration/configure_hotkeys.h"
10#include "yuzu/hotkeys.h" 12#include "yuzu/hotkeys.h"
11#include "yuzu/util/sequence_dialog/sequence_dialog.h" 13#include "yuzu/util/sequence_dialog/sequence_dialog.h"
@@ -19,6 +21,9 @@ ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
19 model->setColumnCount(3); 21 model->setColumnCount(3);
20 22
21 connect(ui->hotkey_list, &QTreeView::doubleClicked, this, &ConfigureHotkeys::Configure); 23 connect(ui->hotkey_list, &QTreeView::doubleClicked, this, &ConfigureHotkeys::Configure);
24 connect(ui->hotkey_list, &QTreeView::customContextMenuRequested, this,
25 &ConfigureHotkeys::PopupContextMenu);
26 ui->hotkey_list->setContextMenuPolicy(Qt::CustomContextMenu);
22 ui->hotkey_list->setModel(model); 27 ui->hotkey_list->setModel(model);
23 28
24 // TODO(Kloen): Make context configurable as well (hiding the column for now) 29 // TODO(Kloen): Make context configurable as well (hiding the column for now)
@@ -27,6 +32,10 @@ ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
27 ui->hotkey_list->setColumnWidth(0, 200); 32 ui->hotkey_list->setColumnWidth(0, 200);
28 ui->hotkey_list->resizeColumnToContents(1); 33 ui->hotkey_list->resizeColumnToContents(1);
29 34
35 connect(ui->button_restore_defaults, &QPushButton::clicked, this,
36 &ConfigureHotkeys::RestoreDefaults);
37 connect(ui->button_clear_all, &QPushButton::clicked, this, &ConfigureHotkeys::ClearAll);
38
30 RetranslateUI(); 39 RetranslateUI();
31} 40}
32 41
@@ -71,7 +80,6 @@ void ConfigureHotkeys::Configure(QModelIndex index) {
71 } 80 }
72 81
73 index = index.sibling(index.row(), 1); 82 index = index.sibling(index.row(), 1);
74 auto* const model = ui->hotkey_list->model();
75 const auto previous_key = model->data(index); 83 const auto previous_key = model->data(index);
76 84
77 SequenceDialog hotkey_dialog{this}; 85 SequenceDialog hotkey_dialog{this};
@@ -81,31 +89,33 @@ void ConfigureHotkeys::Configure(QModelIndex index) {
81 if (return_code == QDialog::Rejected || key_sequence.isEmpty()) { 89 if (return_code == QDialog::Rejected || key_sequence.isEmpty()) {
82 return; 90 return;
83 } 91 }
92 const auto [key_sequence_used, used_action] = IsUsedKey(key_sequence);
84 93
85 if (IsUsedKey(key_sequence) && key_sequence != QKeySequence(previous_key.toString())) { 94 if (key_sequence_used && key_sequence != QKeySequence(previous_key.toString())) {
86 QMessageBox::warning(this, tr("Conflicting Key Sequence"), 95 QMessageBox::warning(
87 tr("The entered key sequence is already assigned to another hotkey.")); 96 this, tr("Conflicting Key Sequence"),
97 tr("The entered key sequence is already assigned to: %1").arg(used_action));
88 } else { 98 } else {
89 model->setData(index, key_sequence.toString(QKeySequence::NativeText)); 99 model->setData(index, key_sequence.toString(QKeySequence::NativeText));
90 } 100 }
91} 101}
92 102
93bool ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) const { 103std::pair<bool, QString> ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) const {
94 for (int r = 0; r < model->rowCount(); r++) { 104 for (int r = 0; r < model->rowCount(); ++r) {
95 const QStandardItem* const parent = model->item(r, 0); 105 const QStandardItem* const parent = model->item(r, 0);
96 106
97 for (int r2 = 0; r2 < parent->rowCount(); r2++) { 107 for (int r2 = 0; r2 < parent->rowCount(); ++r2) {
98 const QStandardItem* const key_seq_item = parent->child(r2, 1); 108 const QStandardItem* const key_seq_item = parent->child(r2, 1);
99 const auto key_seq_str = key_seq_item->text(); 109 const auto key_seq_str = key_seq_item->text();
100 const auto key_seq = QKeySequence::fromString(key_seq_str, QKeySequence::NativeText); 110 const auto key_seq = QKeySequence::fromString(key_seq_str, QKeySequence::NativeText);
101 111
102 if (key_sequence == key_seq) { 112 if (key_sequence == key_seq) {
103 return true; 113 return std::make_pair(true, parent->child(r2, 0)->text());
104 } 114 }
105 } 115 }
106 } 116 }
107 117
108 return false; 118 return std::make_pair(false, QString());
109} 119}
110 120
111void ConfigureHotkeys::ApplyConfiguration(HotkeyRegistry& registry) { 121void ConfigureHotkeys::ApplyConfiguration(HotkeyRegistry& registry) {
@@ -128,3 +138,55 @@ void ConfigureHotkeys::ApplyConfiguration(HotkeyRegistry& registry) {
128 138
129 registry.SaveHotkeys(); 139 registry.SaveHotkeys();
130} 140}
141
142void ConfigureHotkeys::RestoreDefaults() {
143 for (int r = 0; r < model->rowCount(); ++r) {
144 const QStandardItem* parent = model->item(r, 0);
145
146 for (int r2 = 0; r2 < parent->rowCount(); ++r2) {
147 model->item(r, 0)->child(r2, 1)->setText(Config::default_hotkeys[r2].shortcut.first);
148 }
149 }
150}
151
152void ConfigureHotkeys::ClearAll() {
153 for (int r = 0; r < model->rowCount(); ++r) {
154 const QStandardItem* parent = model->item(r, 0);
155
156 for (int r2 = 0; r2 < parent->rowCount(); ++r2) {
157 model->item(r, 0)->child(r2, 1)->setText(tr(""));
158 }
159 }
160}
161
162void ConfigureHotkeys::PopupContextMenu(const QPoint& menu_location) {
163 QModelIndex index = ui->hotkey_list->indexAt(menu_location);
164 if (!index.parent().isValid()) {
165 return;
166 }
167
168 const auto selected = index.sibling(index.row(), 1);
169 QMenu context_menu;
170
171 QAction* restore_default = context_menu.addAction(tr("Restore Default"));
172 QAction* clear = context_menu.addAction(tr("Clear"));
173
174 connect(restore_default, &QAction::triggered, [this, selected] {
175 const QKeySequence& default_key_sequence = QKeySequence::fromString(
176 Config::default_hotkeys[selected.row()].shortcut.first, QKeySequence::NativeText);
177 const auto [key_sequence_used, used_action] = IsUsedKey(default_key_sequence);
178
179 if (key_sequence_used &&
180 default_key_sequence != QKeySequence(model->data(selected).toString())) {
181
182 QMessageBox::warning(
183 this, tr("Conflicting Key Sequence"),
184 tr("The default key sequence is already assigned to: %1").arg(used_action));
185 } else {
186 model->setData(selected, default_key_sequence.toString(QKeySequence::NativeText));
187 }
188 });
189 connect(clear, &QAction::triggered, [this, selected] { model->setData(selected, tr("")); });
190
191 context_menu.exec(ui->hotkey_list->viewport()->mapToGlobal(menu_location));
192}
diff --git a/src/yuzu/configuration/configure_hotkeys.h b/src/yuzu/configuration/configure_hotkeys.h
index 8f8c6173b..a2ec3323e 100644
--- a/src/yuzu/configuration/configure_hotkeys.h
+++ b/src/yuzu/configuration/configure_hotkeys.h
@@ -35,7 +35,11 @@ private:
35 void RetranslateUI(); 35 void RetranslateUI();
36 36
37 void Configure(QModelIndex index); 37 void Configure(QModelIndex index);
38 bool IsUsedKey(QKeySequence key_sequence) const; 38 std::pair<bool, QString> IsUsedKey(QKeySequence key_sequence) const;
39
40 void RestoreDefaults();
41 void ClearAll();
42 void PopupContextMenu(const QPoint& menu_location);
39 43
40 std::unique_ptr<Ui::ConfigureHotkeys> ui; 44 std::unique_ptr<Ui::ConfigureHotkeys> ui;
41 45
diff --git a/src/yuzu/configuration/configure_hotkeys.ui b/src/yuzu/configuration/configure_hotkeys.ui
index 0d0b70f38..6d9f861e3 100644
--- a/src/yuzu/configuration/configure_hotkeys.ui
+++ b/src/yuzu/configuration/configure_hotkeys.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>363</width> 9 <width>439</width>
10 <height>388</height> 10 <height>510</height>
11 </rect> 11 </rect>
12 </property> 12 </property>
13 <property name="windowTitle"> 13 <property name="windowTitle">
@@ -15,7 +15,7 @@
15 </property> 15 </property>
16 <layout class="QVBoxLayout" name="verticalLayout"> 16 <layout class="QVBoxLayout" name="verticalLayout">
17 <item> 17 <item>
18 <layout class="QVBoxLayout" name="verticalLayout_2"> 18 <layout class="QHBoxLayout" name="horizontalLayout">
19 <item> 19 <item>
20 <widget class="QLabel" name="label_2"> 20 <widget class="QLabel" name="label_2">
21 <property name="text"> 21 <property name="text">
@@ -24,6 +24,37 @@
24 </widget> 24 </widget>
25 </item> 25 </item>
26 <item> 26 <item>
27 <spacer name="horizontalSpacer">
28 <property name="orientation">
29 <enum>Qt::Horizontal</enum>
30 </property>
31 <property name="sizeHint" stdset="0">
32 <size>
33 <width>40</width>
34 <height>20</height>
35 </size>
36 </property>
37 </spacer>
38 </item>
39 <item>
40 <widget class="QPushButton" name="button_clear_all">
41 <property name="text">
42 <string>Clear All</string>
43 </property>
44 </widget>
45 </item>
46 <item>
47 <widget class="QPushButton" name="button_restore_defaults">
48 <property name="text">
49 <string>Restore Defaults</string>
50 </property>
51 </widget>
52 </item>
53 </layout>
54 </item>
55 <item>
56 <layout class="QVBoxLayout" name="verticalLayout_2">
57 <item>
27 <widget class="QTreeView" name="hotkey_list"> 58 <widget class="QTreeView" name="hotkey_list">
28 <property name="editTriggers"> 59 <property name="editTriggers">
29 <set>QAbstractItemView::NoEditTriggers</set> 60 <set>QAbstractItemView::NoEditTriggers</set>
@@ -39,4 +70,4 @@
39 </widget> 70 </widget>
40 <resources/> 71 <resources/>
41 <connections/> 72 <connections/>
42</ui> \ No newline at end of file 73</ui>
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 15ac30f12..e4eb5594b 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -56,7 +56,6 @@ static void SetAnalogButton(const Common::ParamPackage& input_param,
56 if (analog_param.Get("engine", "") != "analog_from_button") { 56 if (analog_param.Get("engine", "") != "analog_from_button") {
57 analog_param = { 57 analog_param = {
58 {"engine", "analog_from_button"}, 58 {"engine", "analog_from_button"},
59 {"modifier_scale", "0.5"},
60 }; 59 };
61 } 60 }
62 analog_param.Set(button_name, input_param.Serialize()); 61 analog_param.Set(button_name, input_param.Serialize());
@@ -236,8 +235,10 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
236 widget->setVisible(false); 235 widget->setVisible(false);
237 236
238 analog_map_stick = {ui->buttonLStickAnalog, ui->buttonRStickAnalog}; 237 analog_map_stick = {ui->buttonLStickAnalog, ui->buttonRStickAnalog};
239 analog_map_deadzone = {ui->sliderLStickDeadzone, ui->sliderRStickDeadzone}; 238 analog_map_deadzone_and_modifier_slider = {ui->sliderLStickDeadzoneAndModifier,
240 analog_map_deadzone_label = {ui->labelLStickDeadzone, ui->labelRStickDeadzone}; 239 ui->sliderRStickDeadzoneAndModifier};
240 analog_map_deadzone_and_modifier_slider_label = {ui->labelLStickDeadzoneAndModifier,
241 ui->labelRStickDeadzoneAndModifier};
241 242
242 for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) { 243 for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) {
243 auto* const button = button_map[button_id]; 244 auto* const button = button_map[button_id];
@@ -328,10 +329,18 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
328 InputCommon::Polling::DeviceType::Analog); 329 InputCommon::Polling::DeviceType::Analog);
329 } 330 }
330 }); 331 });
331 connect(analog_map_deadzone[analog_id], &QSlider::valueChanged, [=] { 332
332 const float deadzone = analog_map_deadzone[analog_id]->value() / 100.0f; 333 connect(analog_map_deadzone_and_modifier_slider[analog_id], &QSlider::valueChanged, [=] {
333 analog_map_deadzone_label[analog_id]->setText(tr("Deadzone: %1").arg(deadzone)); 334 const float slider_value = analog_map_deadzone_and_modifier_slider[analog_id]->value();
334 analogs_param[analog_id].Set("deadzone", deadzone); 335 if (analogs_param[analog_id].Get("engine", "") == "sdl") {
336 analog_map_deadzone_and_modifier_slider_label[analog_id]->setText(
337 tr("Deadzone: %1%").arg(slider_value));
338 analogs_param[analog_id].Set("deadzone", slider_value / 100.0f);
339 } else {
340 analog_map_deadzone_and_modifier_slider_label[analog_id]->setText(
341 tr("Modifier Scale: %1%").arg(slider_value));
342 analogs_param[analog_id].Set("modifier_scale", slider_value / 100.0f);
343 }
335 }); 344 });
336 } 345 }
337 346
@@ -517,20 +526,31 @@ void ConfigureInputPlayer::UpdateButtonLabels() {
517 analog_map_stick[analog_id]->setText(tr("Set Analog Stick")); 526 analog_map_stick[analog_id]->setText(tr("Set Analog Stick"));
518 527
519 auto& param = analogs_param[analog_id]; 528 auto& param = analogs_param[analog_id];
520 auto* const analog_deadzone_slider = analog_map_deadzone[analog_id]; 529 auto* const analog_stick_slider = analog_map_deadzone_and_modifier_slider[analog_id];
521 auto* const analog_deadzone_label = analog_map_deadzone_label[analog_id]; 530 auto* const analog_stick_slider_label =
522 531 analog_map_deadzone_and_modifier_slider_label[analog_id];
523 if (param.Has("engine") && param.Get("engine", "") == "sdl") { 532
524 if (!param.Has("deadzone")) { 533 if (param.Has("engine")) {
525 param.Set("deadzone", 0.1f); 534 if (param.Get("engine", "") == "sdl") {
535 if (!param.Has("deadzone")) {
536 param.Set("deadzone", 0.1f);
537 }
538
539 analog_stick_slider->setValue(static_cast<int>(param.Get("deadzone", 0.1f) * 100));
540 if (analog_stick_slider->value() == 0) {
541 analog_stick_slider_label->setText(tr("Deadzone: 0%"));
542 }
543 } else {
544 if (!param.Has("modifier_scale")) {
545 param.Set("modifier_scale", 0.5f);
546 }
547
548 analog_stick_slider->setValue(
549 static_cast<int>(param.Get("modifier_scale", 0.5f) * 100));
550 if (analog_stick_slider->value() == 0) {
551 analog_stick_slider_label->setText(tr("Modifier Scale: 0%"));
552 }
526 } 553 }
527
528 analog_deadzone_slider->setValue(static_cast<int>(param.Get("deadzone", 0.1f) * 100));
529 analog_deadzone_slider->setVisible(true);
530 analog_deadzone_label->setVisible(true);
531 } else {
532 analog_deadzone_slider->setVisible(false);
533 analog_deadzone_label->setVisible(false);
534 } 554 }
535 } 555 }
536} 556}
diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h
index 045704e47..95afa5375 100644
--- a/src/yuzu/configuration/configure_input_player.h
+++ b/src/yuzu/configuration/configure_input_player.h
@@ -97,8 +97,10 @@ private:
97 /// Analog inputs are also represented each with a single button, used to configure with an 97 /// Analog inputs are also represented each with a single button, used to configure with an
98 /// actual analog stick 98 /// actual analog stick
99 std::array<QPushButton*, Settings::NativeAnalog::NumAnalogs> analog_map_stick; 99 std::array<QPushButton*, Settings::NativeAnalog::NumAnalogs> analog_map_stick;
100 std::array<QSlider*, Settings::NativeAnalog::NumAnalogs> analog_map_deadzone; 100 std::array<QSlider*, Settings::NativeAnalog::NumAnalogs>
101 std::array<QLabel*, Settings::NativeAnalog::NumAnalogs> analog_map_deadzone_label; 101 analog_map_deadzone_and_modifier_slider;
102 std::array<QLabel*, Settings::NativeAnalog::NumAnalogs>
103 analog_map_deadzone_and_modifier_slider_label;
102 104
103 static const std::array<std::string, ANALOG_SUB_BUTTONS_NUM> analog_sub_buttons; 105 static const std::array<std::string, ANALOG_SUB_BUTTONS_NUM> analog_sub_buttons;
104 106
diff --git a/src/yuzu/configuration/configure_input_player.ui b/src/yuzu/configuration/configure_input_player.ui
index 4b37746a1..f27a77180 100644
--- a/src/yuzu/configuration/configure_input_player.ui
+++ b/src/yuzu/configuration/configure_input_player.ui
@@ -171,11 +171,11 @@
171 </layout> 171 </layout>
172 </item> 172 </item>
173 <item row="4" column="0" colspan="2"> 173 <item row="4" column="0" colspan="2">
174 <layout class="QVBoxLayout" name="sliderRStickDeadzoneVerticalLayout"> 174 <layout class="QVBoxLayout" name="sliderRStickDeadzoneAndModifierVerticalLayout">
175 <item> 175 <item>
176 <layout class="QHBoxLayout" name="sliderRStickDeadzoneHorizontalLayout"> 176 <layout class="QHBoxLayout" name="sliderRStickDeadzoneAndModifierHorizontalLayout">
177 <item> 177 <item>
178 <widget class="QLabel" name="labelRStickDeadzone"> 178 <widget class="QLabel" name="labelRStickDeadzoneAndModifier">
179 <property name="text"> 179 <property name="text">
180 <string>Deadzone: 0</string> 180 <string>Deadzone: 0</string>
181 </property> 181 </property>
@@ -187,7 +187,7 @@
187 </layout> 187 </layout>
188 </item> 188 </item>
189 <item> 189 <item>
190 <widget class="QSlider" name="sliderRStickDeadzone"> 190 <widget class="QSlider" name="sliderRStickDeadzoneAndModifier">
191 <property name="orientation"> 191 <property name="orientation">
192 <enum>Qt::Horizontal</enum> 192 <enum>Qt::Horizontal</enum>
193 </property> 193 </property>
@@ -784,14 +784,14 @@
784 </layout> 784 </layout>
785 </item> 785 </item>
786 <item row="5" column="1" colspan="2"> 786 <item row="5" column="1" colspan="2">
787 <layout class="QVBoxLayout" name="sliderLStickDeadzoneVerticalLayout"> 787 <layout class="QVBoxLayout" name="sliderLStickDeadzoneAndModifierVerticalLayout">
788 <property name="sizeConstraint"> 788 <property name="sizeConstraint">
789 <enum>QLayout::SetDefaultConstraint</enum> 789 <enum>QLayout::SetDefaultConstraint</enum>
790 </property> 790 </property>
791 <item> 791 <item>
792 <layout class="QHBoxLayout" name="sliderLStickDeadzoneHorizontalLayout"> 792 <layout class="QHBoxLayout" name="sliderLStickDeadzoneAndModifierHorizontalLayout">
793 <item> 793 <item>
794 <widget class="QLabel" name="labelLStickDeadzone"> 794 <widget class="QLabel" name="labelLStickDeadzoneAndModifier">
795 <property name="text"> 795 <property name="text">
796 <string>Deadzone: 0</string> 796 <string>Deadzone: 0</string>
797 </property> 797 </property>
@@ -803,7 +803,7 @@
803 </layout> 803 </layout>
804 </item> 804 </item>
805 <item> 805 <item>
806 <widget class="QSlider" name="sliderLStickDeadzone"> 806 <widget class="QSlider" name="sliderLStickDeadzoneAndModifier">
807 <property name="orientation"> 807 <property name="orientation">
808 <enum>Qt::Horizontal</enum> 808 <enum>Qt::Horizontal</enum>
809 </property> 809 </property>
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index 3e6d5a7cd..0cd0054c8 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -126,13 +126,6 @@ public:
126 126
127 return GameListItem::data(role); 127 return GameListItem::data(role);
128 } 128 }
129
130 /**
131 * Override to prevent automatic sorting.
132 */
133 bool operator<(const QStandardItem& other) const override {
134 return false;
135 }
136}; 129};
137 130
138class GameListItemCompat : public GameListItem { 131class GameListItemCompat : public GameListItem {
@@ -279,6 +272,13 @@ public:
279 return static_cast<int>(dir_type); 272 return static_cast<int>(dir_type);
280 } 273 }
281 274
275 /**
276 * Override to prevent automatic sorting between folders and the addDir button.
277 */
278 bool operator<(const QStandardItem& other) const override {
279 return false;
280 }
281
282private: 282private:
283 GameListItemType dir_type; 283 GameListItemType dir_type;
284}; 284};
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
index 19584360c..e5e684206 100644
--- a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
+++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp
@@ -181,9 +181,10 @@ void EmuWindow_SDL2::PollEvents() {
181 const u32 current_time = SDL_GetTicks(); 181 const u32 current_time = SDL_GetTicks();
182 if (current_time > last_time + 2000) { 182 if (current_time > last_time + 2000) {
183 const auto results = Core::System::GetInstance().GetAndResetPerfStats(); 183 const auto results = Core::System::GetInstance().GetAndResetPerfStats();
184 const auto title = fmt::format( 184 const auto title =
185 "yuzu {} | {}-{} | FPS: {:.0f} ({:.0%})", Common::g_build_fullname, 185 fmt::format("yuzu {} | {}-{} | FPS: {:.0f} ({:.0f}%)", Common::g_build_fullname,
186 Common::g_scm_branch, Common::g_scm_desc, results.game_fps, results.emulation_speed); 186 Common::g_scm_branch, Common::g_scm_desc, results.game_fps,
187 results.emulation_speed * 100.0);
187 SDL_SetWindowTitle(render_window, title.c_str()); 188 SDL_SetWindowTitle(render_window, title.c_str());
188 last_time = current_time; 189 last_time = current_time;
189 } 190 }