summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/common/uint128.h1
-rw-r--r--src/core/file_sys/ips_layer.cpp4
-rw-r--r--src/core/file_sys/patch_manager.cpp14
-rw-r--r--src/core/hle/service/pcv/pcv.cpp93
-rw-r--r--src/core/hle/service/pcv/pcv.h91
-rw-r--r--src/video_core/renderer_opengl/renderer_opengl.cpp19
-rw-r--r--src/video_core/renderer_vulkan/maxwell_to_vk.cpp2
-rw-r--r--src/video_core/renderer_vulkan/vk_blit_screen.cpp18
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp2
-rw-r--r--src/yuzu/game_list.cpp38
-rw-r--r--src/yuzu/game_list.h3
-rw-r--r--src/yuzu/game_list_p.h3
12 files changed, 255 insertions, 33 deletions
diff --git a/src/common/uint128.h b/src/common/uint128.h
index f890ffec2..f450a6db9 100644
--- a/src/common/uint128.h
+++ b/src/common/uint128.h
@@ -12,7 +12,6 @@
12#pragma intrinsic(_udiv128) 12#pragma intrinsic(_udiv128)
13#else 13#else
14#include <cstring> 14#include <cstring>
15#include <x86intrin.h>
16#endif 15#endif
17 16
18#include "common/common_types.h" 17#include "common/common_types.h"
diff --git a/src/core/file_sys/ips_layer.cpp b/src/core/file_sys/ips_layer.cpp
index a33dbe94b..c1a484497 100644
--- a/src/core/file_sys/ips_layer.cpp
+++ b/src/core/file_sys/ips_layer.cpp
@@ -217,9 +217,7 @@ void IPSwitchCompiler::Parse() {
217 break; 217 break;
218 } else if (StartsWith(line, "@nsobid-")) { 218 } else if (StartsWith(line, "@nsobid-")) {
219 // NSO Build ID Specifier 219 // NSO Build ID Specifier
220 auto raw_build_id = line.substr(8); 220 const auto raw_build_id = fmt::format("{:0>64}", line.substr(8));
221 if (raw_build_id.size() != 0x40)
222 raw_build_id.resize(0x40, '0');
223 nso_build_id = Common::HexStringToArray<0x20>(raw_build_id); 221 nso_build_id = Common::HexStringToArray<0x20>(raw_build_id);
224 } else if (StartsWith(line, "#")) { 222 } else if (StartsWith(line, "#")) {
225 // Mandatory Comment 223 // Mandatory Comment
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index bd525b26c..41348ab26 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -191,6 +191,7 @@ VirtualDir PatchManager::PatchExeFS(VirtualDir exefs) const {
191std::vector<VirtualFile> PatchManager::CollectPatches(const std::vector<VirtualDir>& patch_dirs, 191std::vector<VirtualFile> PatchManager::CollectPatches(const std::vector<VirtualDir>& patch_dirs,
192 const std::string& build_id) const { 192 const std::string& build_id) const {
193 const auto& disabled = Settings::values.disabled_addons[title_id]; 193 const auto& disabled = Settings::values.disabled_addons[title_id];
194 const auto nso_build_id = fmt::format("{:0>64}", build_id);
194 195
195 std::vector<VirtualFile> out; 196 std::vector<VirtualFile> out;
196 out.reserve(patch_dirs.size()); 197 out.reserve(patch_dirs.size());
@@ -203,21 +204,18 @@ std::vector<VirtualFile> PatchManager::CollectPatches(const std::vector<VirtualD
203 for (const auto& file : exefs_dir->GetFiles()) { 204 for (const auto& file : exefs_dir->GetFiles()) {
204 if (file->GetExtension() == "ips") { 205 if (file->GetExtension() == "ips") {
205 auto name = file->GetName(); 206 auto name = file->GetName();
206 const auto p1 = name.substr(0, name.find('.'));
207 const auto this_build_id = p1.substr(0, p1.find_last_not_of('0') + 1);
208 207
209 if (build_id == this_build_id) 208 const auto this_build_id =
209 fmt::format("{:0>64}", name.substr(0, name.find('.')));
210 if (nso_build_id == this_build_id)
210 out.push_back(file); 211 out.push_back(file);
211 } else if (file->GetExtension() == "pchtxt") { 212 } else if (file->GetExtension() == "pchtxt") {
212 IPSwitchCompiler compiler{file}; 213 IPSwitchCompiler compiler{file};
213 if (!compiler.IsValid()) 214 if (!compiler.IsValid())
214 continue; 215 continue;
215 216
216 auto this_build_id = Common::HexToString(compiler.GetBuildID()); 217 const auto this_build_id = Common::HexToString(compiler.GetBuildID());
217 this_build_id = 218 if (nso_build_id == this_build_id)
218 this_build_id.substr(0, this_build_id.find_last_not_of('0') + 1);
219
220 if (build_id == this_build_id)
221 out.push_back(file); 219 out.push_back(file);
222 } 220 }
223 } 221 }
diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp
index 0989474be..f7a497a14 100644
--- a/src/core/hle/service/pcv/pcv.cpp
+++ b/src/core/hle/service/pcv/pcv.cpp
@@ -3,6 +3,7 @@
3 3
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/pcv/pcv.h" 7#include "core/hle/service/pcv/pcv.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h" 9#include "core/hle/service/sm/sm.h"
@@ -77,10 +78,102 @@ public:
77 } 78 }
78}; 79};
79 80
81class IClkrstSession final : public ServiceFramework<IClkrstSession> {
82public:
83 explicit IClkrstSession(Core::System& system_, DeviceCode deivce_code_)
84 : ServiceFramework{system_, "IClkrstSession"}, deivce_code(deivce_code_) {
85 // clang-format off
86 static const FunctionInfo functions[] = {
87 {0, nullptr, "SetClockEnabled"},
88 {1, nullptr, "SetClockDisabled"},
89 {2, nullptr, "SetResetAsserted"},
90 {3, nullptr, "SetResetDeasserted"},
91 {4, nullptr, "SetPowerEnabled"},
92 {5, nullptr, "SetPowerDisabled"},
93 {6, nullptr, "GetState"},
94 {7, &IClkrstSession::SetClockRate, "SetClockRate"},
95 {8, &IClkrstSession::GetClockRate, "GetClockRate"},
96 {9, nullptr, "SetMinVClockRate"},
97 {10, nullptr, "GetPossibleClockRates"},
98 {11, nullptr, "GetDvfsTable"},
99 };
100 // clang-format on
101 RegisterHandlers(functions);
102 }
103
104private:
105 void SetClockRate(Kernel::HLERequestContext& ctx) {
106 IPC::RequestParser rp{ctx};
107 clock_rate = rp.Pop<u32>();
108 LOG_DEBUG(Service_PCV, "(STUBBED) called, clock_rate={}", clock_rate);
109
110 IPC::ResponseBuilder rb{ctx, 2};
111 rb.Push(ResultSuccess);
112 }
113
114 void GetClockRate(Kernel::HLERequestContext& ctx) {
115 LOG_DEBUG(Service_PCV, "(STUBBED) called");
116
117 IPC::ResponseBuilder rb{ctx, 3};
118 rb.Push(ResultSuccess);
119 rb.Push<u32>(clock_rate);
120 }
121
122 DeviceCode deivce_code;
123 u32 clock_rate{};
124};
125
126class CLKRST final : public ServiceFramework<CLKRST> {
127public:
128 explicit CLKRST(Core::System& system_, const char* name) : ServiceFramework{system_, name} {
129 // clang-format off
130 static const FunctionInfo functions[] = {
131 {0, &CLKRST::OpenSession, "OpenSession"},
132 {1, nullptr, "GetTemperatureThresholds"},
133 {2, nullptr, "SetTemperature"},
134 {3, nullptr, "GetModuleStateTable"},
135 {4, nullptr, "GetModuleStateTableEvent"},
136 {5, nullptr, "GetModuleStateTableMaxCount"},
137 };
138 // clang-format on
139
140 RegisterHandlers(functions);
141 }
142
143private:
144 void OpenSession(Kernel::HLERequestContext& ctx) {
145 IPC::RequestParser rp{ctx};
146 const auto device_code = static_cast<DeviceCode>(rp.Pop<u32>());
147 const auto unkonwn_input = rp.Pop<u32>();
148
149 LOG_DEBUG(Service_PCV, "called, device_code={}, input={}", device_code, unkonwn_input);
150
151 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
152 rb.Push(ResultSuccess);
153 rb.PushIpcInterface<IClkrstSession>(system, device_code);
154 }
155};
156
157class CLKRST_A final : public ServiceFramework<CLKRST_A> {
158public:
159 explicit CLKRST_A(Core::System& system_) : ServiceFramework{system_, "clkrst:a"} {
160 // clang-format off
161 static const FunctionInfo functions[] = {
162 {0, nullptr, "ReleaseControl"},
163 };
164 // clang-format on
165
166 RegisterHandlers(functions);
167 }
168};
169
80void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 170void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) {
81 std::make_shared<PCV>(system)->InstallAsService(sm); 171 std::make_shared<PCV>(system)->InstallAsService(sm);
82 std::make_shared<PCV_ARB>(system)->InstallAsService(sm); 172 std::make_shared<PCV_ARB>(system)->InstallAsService(sm);
83 std::make_shared<PCV_IMM>(system)->InstallAsService(sm); 173 std::make_shared<PCV_IMM>(system)->InstallAsService(sm);
174 std::make_shared<CLKRST>(system, "clkrst")->InstallAsService(sm);
175 std::make_shared<CLKRST>(system, "clkrst:i")->InstallAsService(sm);
176 std::make_shared<CLKRST_A>(system)->InstallAsService(sm);
84} 177}
85 178
86} // namespace Service::PCV 179} // namespace Service::PCV
diff --git a/src/core/hle/service/pcv/pcv.h b/src/core/hle/service/pcv/pcv.h
index a42e6f8f6..6b26b6fa7 100644
--- a/src/core/hle/service/pcv/pcv.h
+++ b/src/core/hle/service/pcv/pcv.h
@@ -13,6 +13,97 @@ class ServiceManager;
13 13
14namespace Service::PCV { 14namespace Service::PCV {
15 15
16enum class DeviceCode : u32 {
17 Cpu = 0x40000001,
18 Gpu = 0x40000002,
19 I2s1 = 0x40000003,
20 I2s2 = 0x40000004,
21 I2s3 = 0x40000005,
22 Pwm = 0x40000006,
23 I2c1 = 0x02000001,
24 I2c2 = 0x02000002,
25 I2c3 = 0x02000003,
26 I2c4 = 0x02000004,
27 I2c5 = 0x02000005,
28 I2c6 = 0x02000006,
29 Spi1 = 0x07000000,
30 Spi2 = 0x07000001,
31 Spi3 = 0x07000002,
32 Spi4 = 0x07000003,
33 Disp1 = 0x40000011,
34 Disp2 = 0x40000012,
35 Isp = 0x40000013,
36 Vi = 0x40000014,
37 Sdmmc1 = 0x40000015,
38 Sdmmc2 = 0x40000016,
39 Sdmmc3 = 0x40000017,
40 Sdmmc4 = 0x40000018,
41 Owr = 0x40000019,
42 Csite = 0x4000001A,
43 Tsec = 0x4000001B,
44 Mselect = 0x4000001C,
45 Hda2codec2x = 0x4000001D,
46 Actmon = 0x4000001E,
47 I2cSlow = 0x4000001F,
48 Sor1 = 0x40000020,
49 Sata = 0x40000021,
50 Hda = 0x40000022,
51 XusbCoreHostSrc = 0x40000023,
52 XusbFalconSrc = 0x40000024,
53 XusbFsSrc = 0x40000025,
54 XusbCoreDevSrc = 0x40000026,
55 XusbSsSrc = 0x40000027,
56 UartA = 0x03000001,
57 UartB = 0x35000405,
58 UartC = 0x3500040F,
59 UartD = 0x37000001,
60 Host1x = 0x4000002C,
61 Entropy = 0x4000002D,
62 SocTherm = 0x4000002E,
63 Vic = 0x4000002F,
64 Nvenc = 0x40000030,
65 Nvjpg = 0x40000031,
66 Nvdec = 0x40000032,
67 Qspi = 0x40000033,
68 ViI2c = 0x40000034,
69 Tsecb = 0x40000035,
70 Ape = 0x40000036,
71 AudioDsp = 0x40000037,
72 AudioUart = 0x40000038,
73 Emc = 0x40000039,
74 Plle = 0x4000003A,
75 PlleHwSeq = 0x4000003B,
76 Dsi = 0x4000003C,
77 Maud = 0x4000003D,
78 Dpaux1 = 0x4000003E,
79 MipiCal = 0x4000003F,
80 UartFstMipiCal = 0x40000040,
81 Osc = 0x40000041,
82 SysBus = 0x40000042,
83 SorSafe = 0x40000043,
84 XusbSs = 0x40000044,
85 XusbHost = 0x40000045,
86 XusbDevice = 0x40000046,
87 Extperiph1 = 0x40000047,
88 Ahub = 0x40000048,
89 Hda2hdmicodec = 0x40000049,
90 Gpuaux = 0x4000004A,
91 UsbD = 0x4000004B,
92 Usb2 = 0x4000004C,
93 Pcie = 0x4000004D,
94 Afi = 0x4000004E,
95 PciExClk = 0x4000004F,
96 PExUsbPhy = 0x40000050,
97 XUsbPadCtl = 0x40000051,
98 Apbdma = 0x40000052,
99 Usb2TrkClk = 0x40000053,
100 XUsbIoPll = 0x40000054,
101 XUsbIoPllHwSeq = 0x40000055,
102 Cec = 0x40000056,
103 Extperiph2 = 0x40000057,
104 OscClk = 0x40000080
105};
106
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 107void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
17 108
18} // namespace Service::PCV 109} // namespace Service::PCV
diff --git a/src/video_core/renderer_opengl/renderer_opengl.cpp b/src/video_core/renderer_opengl/renderer_opengl.cpp
index 01028cee0..34f3f7a67 100644
--- a/src/video_core/renderer_opengl/renderer_opengl.cpp
+++ b/src/video_core/renderer_opengl/renderer_opengl.cpp
@@ -478,13 +478,16 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
478 } 478 }
479 } 479 }
480 480
481 ASSERT_MSG(framebuffer_crop_rect.top == 0, "Unimplemented");
482 ASSERT_MSG(framebuffer_crop_rect.left == 0, "Unimplemented"); 481 ASSERT_MSG(framebuffer_crop_rect.left == 0, "Unimplemented");
483 482
483 f32 left_start{};
484 if (framebuffer_crop_rect.Top() > 0) {
485 left_start = static_cast<f32>(framebuffer_crop_rect.Top()) /
486 static_cast<f32>(framebuffer_crop_rect.Bottom());
487 }
484 f32 scale_u = static_cast<f32>(framebuffer_width) / static_cast<f32>(screen_info.texture.width); 488 f32 scale_u = static_cast<f32>(framebuffer_width) / static_cast<f32>(screen_info.texture.width);
485 f32 scale_v = 489 f32 scale_v =
486 static_cast<f32>(framebuffer_height) / static_cast<f32>(screen_info.texture.height); 490 static_cast<f32>(framebuffer_height) / static_cast<f32>(screen_info.texture.height);
487
488 // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering 491 // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering
489 // (e.g. handheld mode) on a 1920x1080 framebuffer. 492 // (e.g. handheld mode) on a 1920x1080 framebuffer.
490 if (framebuffer_crop_rect.GetWidth() > 0) { 493 if (framebuffer_crop_rect.GetWidth() > 0) {
@@ -503,10 +506,14 @@ void RendererOpenGL::DrawScreen(const Layout::FramebufferLayout& layout) {
503 506
504 const auto& screen = layout.screen; 507 const auto& screen = layout.screen;
505 const std::array vertices = { 508 const std::array vertices = {
506 ScreenRectVertex(screen.left, screen.top, texcoords.top * scale_u, left * scale_v), 509 ScreenRectVertex(screen.left, screen.top, texcoords.top * scale_u,
507 ScreenRectVertex(screen.right, screen.top, texcoords.bottom * scale_u, left * scale_v), 510 left_start + left * scale_v),
508 ScreenRectVertex(screen.left, screen.bottom, texcoords.top * scale_u, right * scale_v), 511 ScreenRectVertex(screen.right, screen.top, texcoords.bottom * scale_u,
509 ScreenRectVertex(screen.right, screen.bottom, texcoords.bottom * scale_u, right * scale_v), 512 left_start + left * scale_v),
513 ScreenRectVertex(screen.left, screen.bottom, texcoords.top * scale_u,
514 left_start + right * scale_v),
515 ScreenRectVertex(screen.right, screen.bottom, texcoords.bottom * scale_u,
516 left_start + right * scale_v),
510 }; 517 };
511 glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices)); 518 glNamedBufferSubData(vertex_buffer.handle, 0, sizeof(vertices), std::data(vertices));
512 519
diff --git a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
index 7d1431b6d..bdb71dc53 100644
--- a/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
+++ b/src/video_core/renderer_vulkan/maxwell_to_vk.cpp
@@ -172,7 +172,7 @@ struct FormatTuple {
172 {VK_FORMAT_R8G8_SINT, Attachable | Storage}, // R8G8_SINT 172 {VK_FORMAT_R8G8_SINT, Attachable | Storage}, // R8G8_SINT
173 {VK_FORMAT_R8G8_UINT, Attachable | Storage}, // R8G8_UINT 173 {VK_FORMAT_R8G8_UINT, Attachable | Storage}, // R8G8_UINT
174 {VK_FORMAT_R32G32_UINT, Attachable | Storage}, // R32G32_UINT 174 {VK_FORMAT_R32G32_UINT, Attachable | Storage}, // R32G32_UINT
175 {VK_FORMAT_UNDEFINED}, // R16G16B16X16_FLOAT 175 {VK_FORMAT_R16G16B16A16_SFLOAT, Attachable | Storage}, // R16G16B16X16_FLOAT
176 {VK_FORMAT_R32_UINT, Attachable | Storage}, // R32_UINT 176 {VK_FORMAT_R32_UINT, Attachable | Storage}, // R32_UINT
177 {VK_FORMAT_R32_SINT, Attachable | Storage}, // R32_SINT 177 {VK_FORMAT_R32_SINT, Attachable | Storage}, // R32_SINT
178 {VK_FORMAT_ASTC_8x8_UNORM_BLOCK}, // ASTC_2D_8X8_UNORM 178 {VK_FORMAT_ASTC_8x8_UNORM_BLOCK}, // ASTC_2D_8X8_UNORM
diff --git a/src/video_core/renderer_vulkan/vk_blit_screen.cpp b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
index 27e6ebf94..444c29f68 100644
--- a/src/video_core/renderer_vulkan/vk_blit_screen.cpp
+++ b/src/video_core/renderer_vulkan/vk_blit_screen.cpp
@@ -1402,12 +1402,15 @@ void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig&
1402 break; 1402 break;
1403 } 1403 }
1404 1404
1405 UNIMPLEMENTED_IF(framebuffer_crop_rect.top != 0);
1406 UNIMPLEMENTED_IF(framebuffer_crop_rect.left != 0); 1405 UNIMPLEMENTED_IF(framebuffer_crop_rect.left != 0);
1407 1406
1407 f32 left_start{};
1408 if (framebuffer_crop_rect.Top() > 0) {
1409 left_start = static_cast<f32>(framebuffer_crop_rect.Top()) /
1410 static_cast<f32>(framebuffer_crop_rect.Bottom());
1411 }
1408 f32 scale_u = static_cast<f32>(framebuffer.width) / static_cast<f32>(screen_info.width); 1412 f32 scale_u = static_cast<f32>(framebuffer.width) / static_cast<f32>(screen_info.width);
1409 f32 scale_v = static_cast<f32>(framebuffer.height) / static_cast<f32>(screen_info.height); 1413 f32 scale_v = static_cast<f32>(framebuffer.height) / static_cast<f32>(screen_info.height);
1410
1411 // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering 1414 // Scale the output by the crop width/height. This is commonly used with 1280x720 rendering
1412 // (e.g. handheld mode) on a 1920x1080 framebuffer. 1415 // (e.g. handheld mode) on a 1920x1080 framebuffer.
1413 if (!fsr) { 1416 if (!fsr) {
@@ -1426,10 +1429,13 @@ void BlitScreen::SetVertexData(BufferData& data, const Tegra::FramebufferConfig&
1426 const auto y = static_cast<f32>(screen.top); 1429 const auto y = static_cast<f32>(screen.top);
1427 const auto w = static_cast<f32>(screen.GetWidth()); 1430 const auto w = static_cast<f32>(screen.GetWidth());
1428 const auto h = static_cast<f32>(screen.GetHeight()); 1431 const auto h = static_cast<f32>(screen.GetHeight());
1429 data.vertices[0] = ScreenRectVertex(x, y, texcoords.top * scale_u, left * scale_v); 1432 data.vertices[0] = ScreenRectVertex(x, y, texcoords.top * scale_u, left_start + left * scale_v);
1430 data.vertices[1] = ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left * scale_v); 1433 data.vertices[1] =
1431 data.vertices[2] = ScreenRectVertex(x, y + h, texcoords.top * scale_u, right * scale_v); 1434 ScreenRectVertex(x + w, y, texcoords.bottom * scale_u, left_start + left * scale_v);
1432 data.vertices[3] = ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, right * scale_v); 1435 data.vertices[2] =
1436 ScreenRectVertex(x, y + h, texcoords.top * scale_u, left_start + right * scale_v);
1437 data.vertices[3] =
1438 ScreenRectVertex(x + w, y + h, texcoords.bottom * scale_u, left_start + right * scale_v);
1433} 1439}
1434 1440
1435void BlitScreen::CreateFSR() { 1441void BlitScreen::CreateFSR() {
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index 00bee85b2..109689c88 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -1475,7 +1475,7 @@ void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) {
1475 1475
1476void ConfigureInputPlayer::CreateProfile() { 1476void ConfigureInputPlayer::CreateProfile() {
1477 const auto profile_name = 1477 const auto profile_name =
1478 LimitableInputDialog::GetText(this, tr("New Profile"), tr("Enter a profile name:"), 1, 20, 1478 LimitableInputDialog::GetText(this, tr("New Profile"), tr("Enter a profile name:"), 1, 30,
1479 LimitableInputDialog::InputLimiter::Filesystem); 1479 LimitableInputDialog::InputLimiter::Filesystem);
1480 1480
1481 if (profile_name.isEmpty()) { 1481 if (profile_name.isEmpty()) {
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index c4b1f65bd..b127badc2 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -126,10 +126,8 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
126 layout_filter = new QHBoxLayout; 126 layout_filter = new QHBoxLayout;
127 layout_filter->setContentsMargins(8, 8, 8, 8); 127 layout_filter->setContentsMargins(8, 8, 8, 8);
128 label_filter = new QLabel; 128 label_filter = new QLabel;
129 label_filter->setText(tr("Filter:"));
130 edit_filter = new QLineEdit; 129 edit_filter = new QLineEdit;
131 edit_filter->clear(); 130 edit_filter->clear();
132 edit_filter->setPlaceholderText(tr("Enter pattern to filter"));
133 edit_filter->installEventFilter(key_release_eater); 131 edit_filter->installEventFilter(key_release_eater);
134 edit_filter->setClearButtonEnabled(true); 132 edit_filter->setClearButtonEnabled(true);
135 connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::OnTextChanged); 133 connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::OnTextChanged);
@@ -149,6 +147,7 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
149 layout_filter->addWidget(label_filter_result); 147 layout_filter->addWidget(label_filter_result);
150 layout_filter->addWidget(button_filter_close); 148 layout_filter->addWidget(button_filter_close);
151 setLayout(layout_filter); 149 setLayout(layout_filter);
150 RetranslateUI();
152} 151}
153 152
154/** 153/**
@@ -333,13 +332,9 @@ GameList::GameList(FileSys::VirtualFilesystem vfs_, FileSys::ManualContentProvid
333 tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }")); 332 tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }"));
334 333
335 item_model->insertColumns(0, COLUMN_COUNT); 334 item_model->insertColumns(0, COLUMN_COUNT);
336 item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name")); 335 RetranslateUI();
337 item_model->setHeaderData(COLUMN_COMPATIBILITY, Qt::Horizontal, tr("Compatibility"));
338 336
339 item_model->setHeaderData(COLUMN_ADD_ONS, Qt::Horizontal, tr("Add-ons"));
340 tree_view->setColumnHidden(COLUMN_ADD_ONS, !UISettings::values.show_add_ons); 337 tree_view->setColumnHidden(COLUMN_ADD_ONS, !UISettings::values.show_add_ons);
341 item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, tr("File type"));
342 item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, tr("Size"));
343 item_model->setSortRole(GameListItemPath::SortRole); 338 item_model->setSortRole(GameListItemPath::SortRole);
344 339
345 connect(main_window, &GMainWindow::UpdateThemedIcons, this, &GameList::OnUpdateThemedIcons); 340 connect(main_window, &GMainWindow::UpdateThemedIcons, this, &GameList::OnUpdateThemedIcons);
@@ -753,6 +748,35 @@ void GameList::LoadCompatibilityList() {
753 } 748 }
754} 749}
755 750
751void GameList::changeEvent(QEvent* event) {
752 if (event->type() == QEvent::LanguageChange) {
753 RetranslateUI();
754 }
755
756 QWidget::changeEvent(event);
757}
758
759void GameList::RetranslateUI() {
760 item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name"));
761 item_model->setHeaderData(COLUMN_COMPATIBILITY, Qt::Horizontal, tr("Compatibility"));
762 item_model->setHeaderData(COLUMN_ADD_ONS, Qt::Horizontal, tr("Add-ons"));
763 item_model->setHeaderData(COLUMN_FILE_TYPE, Qt::Horizontal, tr("File type"));
764 item_model->setHeaderData(COLUMN_SIZE, Qt::Horizontal, tr("Size"));
765}
766
767void GameListSearchField::changeEvent(QEvent* event) {
768 if (event->type() == QEvent::LanguageChange) {
769 RetranslateUI();
770 }
771
772 QWidget::changeEvent(event);
773}
774
775void GameListSearchField::RetranslateUI() {
776 label_filter->setText(tr("Filter:"));
777 edit_filter->setPlaceholderText(tr("Enter pattern to filter"));
778}
779
756QStandardItemModel* GameList::GetModel() const { 780QStandardItemModel* GameList::GetModel() const {
757 return item_model; 781 return item_model;
758} 782}
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index f783283c9..cdf085019 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -140,6 +140,9 @@ private:
140 void AddPermDirPopup(QMenu& context_menu, QModelIndex selected); 140 void AddPermDirPopup(QMenu& context_menu, QModelIndex selected);
141 void AddFavoritesPopup(QMenu& context_menu); 141 void AddFavoritesPopup(QMenu& context_menu);
142 142
143 void changeEvent(QEvent*) override;
144 void RetranslateUI();
145
143 std::shared_ptr<FileSys::VfsFilesystem> vfs; 146 std::shared_ptr<FileSys::VfsFilesystem> vfs;
144 FileSys::ManualContentProvider* provider; 147 FileSys::ManualContentProvider* provider;
145 GameListSearchField* search_field; 148 GameListSearchField* search_field;
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index 0e19be22d..6198d1e4e 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -353,6 +353,9 @@ public:
353 void setFocus(); 353 void setFocus();
354 354
355private: 355private:
356 void changeEvent(QEvent*) override;
357 void RetranslateUI();
358
356 class KeyReleaseEater : public QObject { 359 class KeyReleaseEater : public QObject {
357 public: 360 public:
358 explicit KeyReleaseEater(GameList* gamelist_, QObject* parent = nullptr); 361 explicit KeyReleaseEater(GameList* gamelist_, QObject* parent = nullptr);