summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/file_sys/control_metadata.cpp4
-rw-r--r--src/core/file_sys/control_metadata.h1
-rw-r--r--src/core/file_sys/savedata_factory.cpp9
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp38
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.h1
-rw-r--r--src/core/hle/service/hid/controllers/keyboard.cpp7
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp4
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.h10
-rw-r--r--src/video_core/dma_pusher.cpp9
-rw-r--r--src/video_core/dma_pusher.h1
-rw-r--r--src/yuzu/game_list.cpp8
-rw-r--r--src/yuzu/game_list.h2
-rw-r--r--src/yuzu/main.cpp64
-rw-r--r--src/yuzu/main.h2
14 files changed, 114 insertions, 46 deletions
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp
index f155a1341..63cd2eead 100644
--- a/src/core/file_sys/control_metadata.cpp
+++ b/src/core/file_sys/control_metadata.cpp
@@ -95,6 +95,10 @@ u32 NACP::GetSupportedLanguages() const {
95 return raw.supported_languages; 95 return raw.supported_languages;
96} 96}
97 97
98u64 NACP::GetDeviceSaveDataSize() const {
99 return raw.device_save_data_size;
100}
101
98std::vector<u8> NACP::GetRawBytes() const { 102std::vector<u8> NACP::GetRawBytes() const {
99 std::vector<u8> out(sizeof(RawNACP)); 103 std::vector<u8> out(sizeof(RawNACP));
100 std::memcpy(out.data(), &raw, sizeof(RawNACP)); 104 std::memcpy(out.data(), &raw, sizeof(RawNACP));
diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h
index 2d8c251ac..e37b2fadf 100644
--- a/src/core/file_sys/control_metadata.h
+++ b/src/core/file_sys/control_metadata.h
@@ -113,6 +113,7 @@ public:
113 u32 GetSupportedLanguages() const; 113 u32 GetSupportedLanguages() const;
114 std::vector<u8> GetRawBytes() const; 114 std::vector<u8> GetRawBytes() const;
115 bool GetUserAccountSwitchLock() const; 115 bool GetUserAccountSwitchLock() const;
116 u64 GetDeviceSaveDataSize() const;
116 117
117private: 118private:
118 RawNACP raw{}; 119 RawNACP raw{};
diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp
index f3def93ab..adfd2c1a4 100644
--- a/src/core/file_sys/savedata_factory.cpp
+++ b/src/core/file_sys/savedata_factory.cpp
@@ -57,7 +57,8 @@ void PrintSaveDataDescriptorWarnings(SaveDataDescriptor meta) {
57bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataDescriptor& desc) { 57bool ShouldSaveDataBeAutomaticallyCreated(SaveDataSpaceId space, const SaveDataDescriptor& desc) {
58 return desc.type == SaveDataType::CacheStorage || desc.type == SaveDataType::TemporaryStorage || 58 return desc.type == SaveDataType::CacheStorage || desc.type == SaveDataType::TemporaryStorage ||
59 (space == SaveDataSpaceId::NandUser && ///< Normal Save Data -- Current Title & User 59 (space == SaveDataSpaceId::NandUser && ///< Normal Save Data -- Current Title & User
60 desc.type == SaveDataType::SaveData && desc.title_id == 0 && desc.save_id == 0); 60 (desc.type == SaveDataType::SaveData || desc.type == SaveDataType::DeviceSaveData) &&
61 desc.title_id == 0 && desc.save_id == 0);
61} 62}
62 63
63} // Anonymous namespace 64} // Anonymous namespace
@@ -139,8 +140,10 @@ std::string SaveDataFactory::GetFullPath(SaveDataSpaceId space, SaveDataType typ
139 u128 user_id, u64 save_id) { 140 u128 user_id, u64 save_id) {
140 // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should 141 // According to switchbrew, if a save is of type SaveData and the title id field is 0, it should
141 // be interpreted as the title id of the current process. 142 // be interpreted as the title id of the current process.
142 if (type == SaveDataType::SaveData && title_id == 0) { 143 if (type == SaveDataType::SaveData || type == SaveDataType::DeviceSaveData) {
143 title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID(); 144 if (title_id == 0) {
145 title_id = Core::System::GetInstance().CurrentProcess()->GetTitleID();
146 }
144 } 147 }
145 148
146 std::string out = GetSaveDataSpaceIdPath(space); 149 std::string out = GetSaveDataSpaceIdPath(space);
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index f6503fe2f..20c331b77 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -767,7 +767,7 @@ FSP_SRV::FSP_SRV(FileSystemController& fsc, const Core::Reporter& reporter)
767 {1014, nullptr, "OutputMultiProgramTagAccessLog"}, 767 {1014, nullptr, "OutputMultiProgramTagAccessLog"},
768 {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"}, 768 {1100, nullptr, "OverrideSaveDataTransferTokenSignVerificationKey"},
769 {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"}, 769 {1110, nullptr, "CorruptSaveDataFileSystemBySaveDataSpaceId2"},
770 {1200, nullptr, "OpenMultiCommitManager"}, 770 {1200, &FSP_SRV::OpenMultiCommitManager, "OpenMultiCommitManager"},
771 {1300, nullptr, "OpenBisWiper"}, 771 {1300, nullptr, "OpenBisWiper"},
772 }; 772 };
773 // clang-format on 773 // clang-format on
@@ -988,4 +988,40 @@ void FSP_SRV::GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx) {
988 rb.Push(access_log_program_index); 988 rb.Push(access_log_program_index);
989} 989}
990 990
991class IMultiCommitManager final : public ServiceFramework<IMultiCommitManager> {
992public:
993 explicit IMultiCommitManager() : ServiceFramework("IMultiCommitManager") {
994 static const FunctionInfo functions[] = {
995 {1, &IMultiCommitManager::Add, "Add"},
996 {2, &IMultiCommitManager::Commit, "Commit"},
997 };
998 RegisterHandlers(functions);
999 }
1000
1001private:
1002 FileSys::VirtualFile backend;
1003
1004 void Add(Kernel::HLERequestContext& ctx) {
1005 LOG_WARNING(Service_FS, "(STUBBED) called");
1006
1007 IPC::ResponseBuilder rb{ctx, 2};
1008 rb.Push(RESULT_SUCCESS);
1009 }
1010
1011 void Commit(Kernel::HLERequestContext& ctx) {
1012 LOG_WARNING(Service_FS, "(STUBBED) called");
1013
1014 IPC::ResponseBuilder rb{ctx, 2};
1015 rb.Push(RESULT_SUCCESS);
1016 }
1017};
1018
1019void FSP_SRV::OpenMultiCommitManager(Kernel::HLERequestContext& ctx) {
1020 LOG_DEBUG(Service_FS, "called");
1021
1022 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
1023 rb.Push(RESULT_SUCCESS);
1024 rb.PushIpcInterface<IMultiCommitManager>(std::make_shared<IMultiCommitManager>());
1025}
1026
991} // namespace Service::FileSystem 1027} // namespace Service::FileSystem
diff --git a/src/core/hle/service/filesystem/fsp_srv.h b/src/core/hle/service/filesystem/fsp_srv.h
index d52b55999..dfb3e395b 100644
--- a/src/core/hle/service/filesystem/fsp_srv.h
+++ b/src/core/hle/service/filesystem/fsp_srv.h
@@ -50,6 +50,7 @@ private:
50 void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx); 50 void OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx);
51 void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx); 51 void OutputAccessLogToSdCard(Kernel::HLERequestContext& ctx);
52 void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx); 52 void GetAccessLogVersionInfo(Kernel::HLERequestContext& ctx);
53 void OpenMultiCommitManager(Kernel::HLERequestContext& ctx);
53 54
54 FileSystemController& fsc; 55 FileSystemController& fsc;
55 56
diff --git a/src/core/hle/service/hid/controllers/keyboard.cpp b/src/core/hle/service/hid/controllers/keyboard.cpp
index 358cb9329..9a8d354ba 100644
--- a/src/core/hle/service/hid/controllers/keyboard.cpp
+++ b/src/core/hle/service/hid/controllers/keyboard.cpp
@@ -38,10 +38,11 @@ void Controller_Keyboard::OnUpdate(const Core::Timing::CoreTiming& core_timing,
38 cur_entry.sampling_number = last_entry.sampling_number + 1; 38 cur_entry.sampling_number = last_entry.sampling_number + 1;
39 cur_entry.sampling_number2 = cur_entry.sampling_number; 39 cur_entry.sampling_number2 = cur_entry.sampling_number;
40 40
41 cur_entry.key.fill(0);
42 cur_entry.modifier = 0;
43
41 for (std::size_t i = 0; i < keyboard_keys.size(); ++i) { 44 for (std::size_t i = 0; i < keyboard_keys.size(); ++i) {
42 for (std::size_t k = 0; k < KEYS_PER_BYTE; ++k) { 45 cur_entry.key[i / KEYS_PER_BYTE] |= (keyboard_keys[i]->GetStatus() << (i % KEYS_PER_BYTE));
43 cur_entry.key[i / KEYS_PER_BYTE] |= (keyboard_keys[i]->GetStatus() << k);
44 }
45 } 46 }
46 47
47 for (std::size_t i = 0; i < keyboard_mods.size(); ++i) { 48 for (std::size_t i = 0; i < keyboard_mods.size(); ++i) {
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index f1e3d832a..caca80dde 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -138,9 +138,7 @@ u32 BufferQueue::Query(QueryType type) {
138 138
139 switch (type) { 139 switch (type) {
140 case QueryType::NativeWindowFormat: 140 case QueryType::NativeWindowFormat:
141 // TODO(Subv): Use an enum for this 141 return static_cast<u32>(PixelFormat::RGBA8888);
142 static constexpr u32 FormatABGR8 = 1;
143 return FormatABGR8;
144 } 142 }
145 143
146 UNIMPLEMENTED(); 144 UNIMPLEMENTED();
diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h
index d5f31e567..8a837e5aa 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.h
+++ b/src/core/hle/service/nvflinger/buffer_queue.h
@@ -66,6 +66,16 @@ public:
66 Rotate270 = 0x07, 66 Rotate270 = 0x07,
67 }; 67 };
68 68
69 enum class PixelFormat : u32 {
70 RGBA8888 = 1,
71 RGBX8888 = 2,
72 RGB888 = 3,
73 RGB565 = 4,
74 BGRA8888 = 5,
75 RGBA5551 = 6,
76 RRGBA4444 = 7,
77 };
78
69 struct Buffer { 79 struct Buffer {
70 enum class Status { Free = 0, Queued = 1, Dequeued = 2, Acquired = 3 }; 80 enum class Status { Free = 0, Queued = 1, Dequeued = 2, Acquired = 3 };
71 81
diff --git a/src/video_core/dma_pusher.cpp b/src/video_core/dma_pusher.cpp
index bdc023d54..f2f96ac33 100644
--- a/src/video_core/dma_pusher.cpp
+++ b/src/video_core/dma_pusher.cpp
@@ -54,9 +54,7 @@ bool DmaPusher::Step() {
54 return true; 54 return true;
55 }); 55 });
56 const CommandListHeader command_list_header{command_list[dma_pushbuffer_subindex++]}; 56 const CommandListHeader command_list_header{command_list[dma_pushbuffer_subindex++]};
57 GPUVAddr dma_get = command_list_header.addr; 57 const GPUVAddr dma_get = command_list_header.addr;
58 GPUVAddr dma_put = dma_get + command_list_header.size * sizeof(u32);
59 bool non_main = command_list_header.is_non_main;
60 58
61 if (dma_pushbuffer_subindex >= command_list.size()) { 59 if (dma_pushbuffer_subindex >= command_list.size()) {
62 // We've gone through the current list, remove it from the queue 60 // We've gone through the current list, remove it from the queue
@@ -133,11 +131,6 @@ bool DmaPusher::Step() {
133 index++; 131 index++;
134 } 132 }
135 133
136 if (!non_main) {
137 // TODO (degasus): This is dead code, as dma_mget is never read.
138 dma_mget = dma_put;
139 }
140
141 return true; 134 return true;
142} 135}
143 136
diff --git a/src/video_core/dma_pusher.h b/src/video_core/dma_pusher.h
index e8b714e94..efa90d170 100644
--- a/src/video_core/dma_pusher.h
+++ b/src/video_core/dma_pusher.h
@@ -102,7 +102,6 @@ private:
102 DmaState dma_state{}; 102 DmaState dma_state{};
103 bool dma_increment_once{}; 103 bool dma_increment_once{};
104 104
105 GPUVAddr dma_mget{}; ///< main pushbuffer last read address
106 bool ib_enable{true}; ///< IB mode enabled 105 bool ib_enable{true}; ///< IB mode enabled
107 106
108 std::array<Tegra::Engines::EngineInterface*, max_subchannels> subchannels{}; 107 std::array<Tegra::Engines::EngineInterface*, max_subchannels> subchannels{};
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index dccbabcbf..bfb600df0 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -488,11 +488,11 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, std::string pat
488 auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); 488 auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
489 navigate_to_gamedb_entry->setVisible(it != compatibility_list.end() && program_id != 0); 489 navigate_to_gamedb_entry->setVisible(it != compatibility_list.end() && program_id != 0);
490 490
491 connect(open_save_location, &QAction::triggered, [this, program_id]() { 491 connect(open_save_location, &QAction::triggered, [this, program_id, path]() {
492 emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData); 492 emit OpenFolderRequested(GameListOpenTarget::SaveData, path);
493 }); 493 });
494 connect(open_lfs_location, &QAction::triggered, [this, program_id]() { 494 connect(open_lfs_location, &QAction::triggered, [this, program_id, path]() {
495 emit OpenFolderRequested(program_id, GameListOpenTarget::ModData); 495 emit OpenFolderRequested(GameListOpenTarget::ModData, path);
496 }); 496 });
497 connect(open_transferable_shader_cache, &QAction::triggered, 497 connect(open_transferable_shader_cache, &QAction::triggered,
498 [this, program_id]() { emit OpenTransferableShaderCacheRequested(program_id); }); 498 [this, program_id]() { emit OpenTransferableShaderCacheRequested(program_id); });
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index 878d94413..a38cb2fc3 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -73,7 +73,7 @@ public:
73signals: 73signals:
74 void GameChosen(QString game_path); 74 void GameChosen(QString game_path);
75 void ShouldCancelWorker(); 75 void ShouldCancelWorker();
76 void OpenFolderRequested(u64 program_id, GameListOpenTarget target); 76 void OpenFolderRequested(GameListOpenTarget target, const std::string& game_path);
77 void OpenTransferableShaderCacheRequested(u64 program_id); 77 void OpenTransferableShaderCacheRequested(u64 program_id);
78 void DumpRomFSRequested(u64 program_id, const std::string& game_path); 78 void DumpRomFSRequested(u64 program_id, const std::string& game_path);
79 void CopyTIDRequested(u64 program_id); 79 void CopyTIDRequested(u64 program_id);
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index dd6e5173e..0b291c7d0 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1155,39 +1155,61 @@ void GMainWindow::OnGameListLoadFile(QString game_path) {
1155 BootGame(game_path); 1155 BootGame(game_path);
1156} 1156}
1157 1157
1158void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target) { 1158void GMainWindow::OnGameListOpenFolder(GameListOpenTarget target, const std::string& game_path) {
1159 std::string path; 1159 std::string path;
1160 QString open_target; 1160 QString open_target;
1161
1162 const auto v_file = Core::GetGameFileFromPath(vfs, game_path);
1163 const auto loader = Loader::GetLoader(v_file);
1164 FileSys::NACP control{};
1165 u64 program_id{};
1166
1167 loader->ReadControlData(control);
1168 loader->ReadProgramId(program_id);
1169
1170 const bool has_user_save{control.GetDefaultNormalSaveSize() > 0};
1171 const bool has_device_save{control.GetDeviceSaveDataSize() > 0};
1172
1173 ASSERT_MSG(has_user_save != has_device_save, "Game uses both user and device savedata?");
1174
1161 switch (target) { 1175 switch (target) {
1162 case GameListOpenTarget::SaveData: { 1176 case GameListOpenTarget::SaveData: {
1163 open_target = tr("Save Data"); 1177 open_target = tr("Save Data");
1164 const std::string nand_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir); 1178 const std::string nand_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
1165 ASSERT(program_id != 0); 1179 ASSERT(program_id != 0);
1166 1180
1167 const auto select_profile = [this] { 1181 if (has_user_save) {
1168 QtProfileSelectionDialog dialog(this); 1182 // User save data
1169 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint | 1183 const auto select_profile = [this] {
1170 Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint); 1184 QtProfileSelectionDialog dialog(this);
1171 dialog.setWindowModality(Qt::WindowModal); 1185 dialog.setWindowFlags(Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowTitleHint |
1186 Qt::WindowSystemMenuHint | Qt::WindowCloseButtonHint);
1187 dialog.setWindowModality(Qt::WindowModal);
1172 1188
1173 if (dialog.exec() == QDialog::Rejected) { 1189 if (dialog.exec() == QDialog::Rejected) {
1174 return -1; 1190 return -1;
1175 } 1191 }
1176 1192
1177 return dialog.GetIndex(); 1193 return dialog.GetIndex();
1178 }; 1194 };
1179 1195
1180 const auto index = select_profile(); 1196 const auto index = select_profile();
1181 if (index == -1) { 1197 if (index == -1) {
1182 return; 1198 return;
1183 } 1199 }
1184 1200
1185 Service::Account::ProfileManager manager; 1201 Service::Account::ProfileManager manager;
1186 const auto user_id = manager.GetUser(static_cast<std::size_t>(index)); 1202 const auto user_id = manager.GetUser(static_cast<std::size_t>(index));
1187 ASSERT(user_id); 1203 ASSERT(user_id);
1188 path = nand_dir + FileSys::SaveDataFactory::GetFullPath(FileSys::SaveDataSpaceId::NandUser, 1204 path = nand_dir + FileSys::SaveDataFactory::GetFullPath(
1189 FileSys::SaveDataType::SaveData, 1205 FileSys::SaveDataSpaceId::NandUser,
1190 program_id, user_id->uuid, 0); 1206 FileSys::SaveDataType::SaveData, program_id, user_id->uuid, 0);
1207 } else {
1208 // Device save data
1209 path = nand_dir + FileSys::SaveDataFactory::GetFullPath(
1210 FileSys::SaveDataSpaceId::NandUser,
1211 FileSys::SaveDataType::SaveData, program_id, {}, 0);
1212 }
1191 1213
1192 if (!FileUtil::Exists(path)) { 1214 if (!FileUtil::Exists(path)) {
1193 FileUtil::CreateFullPath(path); 1215 FileUtil::CreateFullPath(path);
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 4bff4330c..4f4c8ddbe 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -183,7 +183,7 @@ private slots:
183 void OnMenuReportCompatibility(); 183 void OnMenuReportCompatibility();
184 /// Called whenever a user selects a game in the game list widget. 184 /// Called whenever a user selects a game in the game list widget.
185 void OnGameListLoadFile(QString game_path); 185 void OnGameListLoadFile(QString game_path);
186 void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target); 186 void OnGameListOpenFolder(GameListOpenTarget target, const std::string& game_path);
187 void OnTransferableShaderCacheOpenFile(u64 program_id); 187 void OnTransferableShaderCacheOpenFile(u64 program_id);
188 void OnGameListDumpRomFS(u64 program_id, const std::string& game_path); 188 void OnGameListDumpRomFS(u64 program_id, const std::string& game_path);
189 void OnGameListCopyTID(u64 program_id); 189 void OnGameListCopyTID(u64 program_id);