summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/yuzu/game_list_worker.cpp106
1 files changed, 99 insertions, 7 deletions
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index 82d2826ba..bc1833289 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -9,6 +9,7 @@
9 9
10#include <QDir> 10#include <QDir>
11#include <QFileInfo> 11#include <QFileInfo>
12#include <QSettings>
12 13
13#include "common/common_paths.h" 14#include "common/common_paths.h"
14#include "common/file_util.h" 15#include "common/file_util.h"
@@ -30,13 +31,101 @@
30#include "yuzu/ui_settings.h" 31#include "yuzu/ui_settings.h"
31 32
32namespace { 33namespace {
34
35template <typename T>
36T GetGameListCachedObject(const std::string& filename, const std::string& ext,
37 const std::function<T()>& generator);
38
39template <>
40QString GetGameListCachedObject(const std::string& filename, const std::string& ext,
41 const std::function<QString()>& generator) {
42 if (!UISettings::values.cache_game_list || filename == "0000000000000000")
43 return generator();
44
45 const auto& path = FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP + "game_list" +
46 DIR_SEP + filename + "." + ext;
47
48 FileUtil::CreateFullPath(path);
49
50 if (!FileUtil::Exists(path)) {
51 const auto str = generator();
52
53 std::ofstream stream(path);
54 if (stream)
55 stream << str.toStdString();
56
57 stream.close();
58 return str;
59 }
60
61 std::ifstream stream(path);
62
63 if (stream) {
64 const std::string out(std::istreambuf_iterator<char>{stream},
65 std::istreambuf_iterator<char>{});
66 stream.close();
67 return QString::fromStdString(out);
68 }
69
70 return generator();
71}
72
73template <>
74std::pair<std::vector<u8>, std::string> GetGameListCachedObject(
75 const std::string& filename, const std::string& ext,
76 const std::function<std::pair<std::vector<u8>, std::string>()>& generator) {
77 if (!UISettings::values.cache_game_list || filename == "0000000000000000")
78 return generator();
79
80 const auto& path1 = FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP +
81 "game_list" + DIR_SEP + filename + ".jpeg";
82 const auto& path2 = FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP +
83 "game_list" + DIR_SEP + filename + ".appname.txt";
84
85 FileUtil::CreateFullPath(path1);
86
87 if (!FileUtil::Exists(path1) || !FileUtil::Exists(path2)) {
88 const auto [icon, nacp] = generator();
89
90 FileUtil::IOFile file1(path1, "wb");
91 file1.Resize(icon.size());
92 file1.WriteBytes(icon.data(), icon.size());
93
94 std::ofstream stream2(path2, std::ios::out);
95 if (stream2)
96 stream2 << nacp;
97
98 file1.Close();
99 stream2.close();
100 return std::make_pair(icon, nacp);
101 }
102
103 FileUtil::IOFile file1(path1, "rb");
104 std::ifstream stream2(path2);
105
106 std::vector<u8> vec(file1.GetSize());
107 file1.ReadBytes(vec.data(), vec.size());
108
109 if (stream2 && !vec.empty()) {
110 const std::string out(std::istreambuf_iterator<char>{stream2},
111 std::istreambuf_iterator<char>{});
112 stream2.close();
113 return std::make_pair(vec, out);
114 }
115
116 return generator();
117}
118
33void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager, const FileSys::NCA& nca, 119void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager, const FileSys::NCA& nca,
34 std::vector<u8>& icon, std::string& name) { 120 std::vector<u8>& icon, std::string& name) {
35 auto [nacp, icon_file] = patch_manager.ParseControlNCA(nca); 121 auto res = GetGameListCachedObject<std::pair<std::vector<u8>, std::string>>(
36 if (icon_file != nullptr) 122 fmt::format("{:016X}", patch_manager.GetTitleID()), {}, [&patch_manager, &nca] {
37 icon = icon_file->ReadAllBytes(); 123 const auto [nacp, icon_f] = patch_manager.ParseControlNCA(nca);
38 if (nacp != nullptr) 124 return std::make_pair(icon_f->ReadAllBytes(), nacp->GetApplicationName());
39 name = nacp->GetApplicationName(); 125 });
126
127 icon = std::move(res.first);
128 name = std::move(res.second);
40} 129}
41 130
42bool HasSupportedFileExtension(const std::string& file_name) { 131bool HasSupportedFileExtension(const std::string& file_name) {
@@ -114,8 +203,11 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri
114 }; 203 };
115 204
116 if (UISettings::values.show_add_ons) { 205 if (UISettings::values.show_add_ons) {
117 list.insert( 206 const auto patch_versions = GetGameListCachedObject<QString>(
118 2, new GameListItem(FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable()))); 207 fmt::format("{:016X}", patch.GetTitleID()), "pv.txt", [&patch, &loader] {
208 return FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable());
209 });
210 list.insert(2, new GameListItem(patch_versions));
119 } 211 }
120 212
121 return list; 213 return list;