early-access version 3961
This commit is contained in:
		| @@ -1,7 +1,7 @@ | ||||
| yuzu emulator early access | ||||
| ============= | ||||
|  | ||||
| This is the source code for early-access 3960. | ||||
| This is the source code for early-access 3961. | ||||
|  | ||||
| ## Legal Notice | ||||
|  | ||||
|   | ||||
| @@ -84,28 +84,6 @@ class HomeSettingsFragment : Fragment() { | ||||
|                     } | ||||
|                 ) | ||||
|             ) | ||||
|             add( | ||||
|                 HomeSetting( | ||||
|                     R.string.open_user_folder, | ||||
|                     R.string.open_user_folder_description, | ||||
|                     R.drawable.ic_folder_open, | ||||
|                     { openFileManager() } | ||||
|                 ) | ||||
|             ) | ||||
|             add( | ||||
|                 HomeSetting( | ||||
|                     R.string.preferences_theme, | ||||
|                     R.string.theme_and_color_description, | ||||
|                     R.drawable.ic_palette, | ||||
|                     { | ||||
|                         val action = HomeNavigationDirections.actionGlobalSettingsActivity( | ||||
|                             null, | ||||
|                             Settings.MenuTag.SECTION_THEME | ||||
|                         ) | ||||
|                         binding.root.findNavController().navigate(action) | ||||
|                     } | ||||
|                 ) | ||||
|             ) | ||||
|             add( | ||||
|                 HomeSetting( | ||||
|                     R.string.gpu_driver_manager, | ||||
| @@ -121,17 +99,6 @@ class HomeSettingsFragment : Fragment() { | ||||
|                     driverViewModel.selectedDriverMetadata | ||||
|                 ) | ||||
|             ) | ||||
|             add( | ||||
|                 HomeSetting( | ||||
|                     R.string.manage_yuzu_data, | ||||
|                     R.string.manage_yuzu_data_description, | ||||
|                     R.drawable.ic_install, | ||||
|                     { | ||||
|                         binding.root.findNavController() | ||||
|                             .navigate(R.id.action_homeSettingsFragment_to_installableFragment) | ||||
|                     } | ||||
|                 ) | ||||
|             ) | ||||
|             add( | ||||
|                 HomeSetting( | ||||
|                     R.string.applets, | ||||
| @@ -146,6 +113,17 @@ class HomeSettingsFragment : Fragment() { | ||||
|                     R.string.applets_error_description | ||||
|                 ) | ||||
|             ) | ||||
|             add( | ||||
|                 HomeSetting( | ||||
|                     R.string.manage_yuzu_data, | ||||
|                     R.string.manage_yuzu_data_description, | ||||
|                     R.drawable.ic_install, | ||||
|                     { | ||||
|                         binding.root.findNavController() | ||||
|                             .navigate(R.id.action_homeSettingsFragment_to_installableFragment) | ||||
|                     } | ||||
|                 ) | ||||
|             ) | ||||
|             add( | ||||
|                 HomeSetting( | ||||
|                     R.string.select_games_folder, | ||||
| @@ -170,6 +148,28 @@ class HomeSettingsFragment : Fragment() { | ||||
|                     { shareLog() } | ||||
|                 ) | ||||
|             ) | ||||
|             add( | ||||
|                 HomeSetting( | ||||
|                     R.string.open_user_folder, | ||||
|                     R.string.open_user_folder_description, | ||||
|                     R.drawable.ic_folder_open, | ||||
|                     { openFileManager() } | ||||
|                 ) | ||||
|             ) | ||||
|             add( | ||||
|                 HomeSetting( | ||||
|                     R.string.preferences_theme, | ||||
|                     R.string.theme_and_color_description, | ||||
|                     R.drawable.ic_palette, | ||||
|                     { | ||||
|                         val action = HomeNavigationDirections.actionGlobalSettingsActivity( | ||||
|                             null, | ||||
|                             Settings.MenuTag.SECTION_THEME | ||||
|                         ) | ||||
|                         binding.root.findNavController().navigate(action) | ||||
|                     } | ||||
|                 ) | ||||
|             ) | ||||
|             add( | ||||
|                 HomeSetting( | ||||
|                     R.string.about, | ||||
|   | ||||
| @@ -72,7 +72,7 @@ | ||||
|     <string name="invalid_keys_error">Invalid encryption keys</string> | ||||
|     <string name="dumping_keys_quickstart_link">https://yuzu-emu.org/help/quickstart/#dumping-decryption-keys</string> | ||||
|     <string name="install_keys_failure_description">The selected file is incorrect or corrupt. Please redump your keys.</string> | ||||
|     <string name="gpu_driver_manager">GPU Driver Manager</string> | ||||
|     <string name="gpu_driver_manager">GPU driver manager</string> | ||||
|     <string name="install_gpu_driver">Install GPU driver</string> | ||||
|     <string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string> | ||||
|     <string name="advanced_settings">Advanced settings</string> | ||||
|   | ||||
| @@ -35,13 +35,14 @@ struct RomFSHeader { | ||||
| static_assert(sizeof(RomFSHeader) == 0x50, "RomFSHeader has incorrect size."); | ||||
|  | ||||
| struct DirectoryEntry { | ||||
|     u32_le parent; | ||||
|     u32_le sibling; | ||||
|     u32_le child_dir; | ||||
|     u32_le child_file; | ||||
|     u32_le hash; | ||||
|     u32_le name_length; | ||||
| }; | ||||
| static_assert(sizeof(DirectoryEntry) == 0x14, "DirectoryEntry has incorrect size."); | ||||
| static_assert(sizeof(DirectoryEntry) == 0x18, "DirectoryEntry has incorrect size."); | ||||
|  | ||||
| struct FileEntry { | ||||
|     u32_le parent; | ||||
| @@ -64,25 +65,22 @@ std::pair<Entry, std::string> GetEntry(const VirtualFile& file, std::size_t offs | ||||
|     return {entry, string}; | ||||
| } | ||||
|  | ||||
| void ProcessFile(VirtualFile file, std::size_t file_offset, std::size_t data_offset, | ||||
|                  u32 this_file_offset, std::shared_ptr<VectorVfsDirectory> parent) { | ||||
|     while (true) { | ||||
| void ProcessFile(const VirtualFile& file, std::size_t file_offset, std::size_t data_offset, | ||||
|                  u32 this_file_offset, std::shared_ptr<VectorVfsDirectory>& parent) { | ||||
|     while (this_file_offset != ROMFS_ENTRY_EMPTY) { | ||||
|         auto entry = GetEntry<FileEntry>(file, file_offset + this_file_offset); | ||||
|  | ||||
|         parent->AddFile(std::make_shared<OffsetVfsFile>( | ||||
|             file, entry.first.size, entry.first.offset + data_offset, entry.second)); | ||||
|  | ||||
|         if (entry.first.sibling == ROMFS_ENTRY_EMPTY) | ||||
|             break; | ||||
|  | ||||
|         this_file_offset = entry.first.sibling; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void ProcessDirectory(VirtualFile file, std::size_t dir_offset, std::size_t file_offset, | ||||
| void ProcessDirectory(const VirtualFile& file, std::size_t dir_offset, std::size_t file_offset, | ||||
|                       std::size_t data_offset, u32 this_dir_offset, | ||||
|                       std::shared_ptr<VectorVfsDirectory> parent) { | ||||
|     while (true) { | ||||
|                       std::shared_ptr<VectorVfsDirectory>& parent) { | ||||
|     while (this_dir_offset != ROMFS_ENTRY_EMPTY) { | ||||
|         auto entry = GetEntry<DirectoryEntry>(file, dir_offset + this_dir_offset); | ||||
|         auto current = std::make_shared<VectorVfsDirectory>( | ||||
|             std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, entry.second); | ||||
| @@ -97,14 +95,12 @@ void ProcessDirectory(VirtualFile file, std::size_t dir_offset, std::size_t file | ||||
|         } | ||||
|  | ||||
|         parent->AddDirectory(current); | ||||
|         if (entry.first.sibling == ROMFS_ENTRY_EMPTY) | ||||
|             break; | ||||
|         this_dir_offset = entry.first.sibling; | ||||
|     } | ||||
| } | ||||
| } // Anonymous namespace | ||||
|  | ||||
| VirtualDir ExtractRomFS(VirtualFile file, RomFSExtractionType type) { | ||||
| VirtualDir ExtractRomFS(VirtualFile file) { | ||||
|     RomFSHeader header{}; | ||||
|     if (file->ReadObject(&header) != sizeof(RomFSHeader)) | ||||
|         return nullptr; | ||||
| @@ -113,27 +109,17 @@ VirtualDir ExtractRomFS(VirtualFile file, RomFSExtractionType type) { | ||||
|         return nullptr; | ||||
|  | ||||
|     const u64 file_offset = header.file_meta.offset; | ||||
|     const u64 dir_offset = header.directory_meta.offset + 4; | ||||
|     const u64 dir_offset = header.directory_meta.offset; | ||||
|  | ||||
|     auto root = | ||||
|         std::make_shared<VectorVfsDirectory>(std::vector<VirtualFile>{}, std::vector<VirtualDir>{}, | ||||
|                                              file->GetName(), file->GetContainingDirectory()); | ||||
|     auto root_container = std::make_shared<VectorVfsDirectory>(); | ||||
|  | ||||
|     ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root); | ||||
|     ProcessDirectory(file, dir_offset, file_offset, header.data_offset, 0, root_container); | ||||
|  | ||||
|     VirtualDir out = std::move(root); | ||||
|  | ||||
|     if (type == RomFSExtractionType::SingleDiscard) | ||||
|         return out->GetSubdirectories().front(); | ||||
|  | ||||
|     while (out->GetSubdirectories().size() == 1 && out->GetFiles().empty()) { | ||||
|         if (Common::ToLower(out->GetSubdirectories().front()->GetName()) == "data" && | ||||
|             type == RomFSExtractionType::Truncated) | ||||
|             break; | ||||
|         out = out->GetSubdirectories().front(); | ||||
|     if (auto root = root_container->GetSubdirectory(""); root) { | ||||
|         return std::make_shared<CachedVfsDirectory>(std::move(root)); | ||||
|     } | ||||
|  | ||||
|     return std::make_shared<CachedVfsDirectory>(std::move(out)); | ||||
|     return nullptr; | ||||
| } | ||||
|  | ||||
| VirtualFile CreateRomFS(VirtualDir dir, VirtualDir ext) { | ||||
|   | ||||
| @@ -7,16 +7,9 @@ | ||||
|  | ||||
| namespace FileSys { | ||||
|  | ||||
| enum class RomFSExtractionType { | ||||
|     Full,          // Includes data directory | ||||
|     Truncated,     // Traverses into data directory | ||||
|     SingleDiscard, // Traverses into the first subdirectory of root | ||||
| }; | ||||
|  | ||||
| // Converts a RomFS binary blob to VFS Filesystem | ||||
| // Returns nullptr on failure | ||||
| VirtualDir ExtractRomFS(VirtualFile file, | ||||
|                         RomFSExtractionType type = RomFSExtractionType::Truncated); | ||||
| VirtualDir ExtractRomFS(VirtualFile file); | ||||
|  | ||||
| // Converts a VFS filesystem into a RomFS binary | ||||
| // Returns nullptr on failure | ||||
|   | ||||
| @@ -330,8 +330,7 @@ void WebBrowser::ExtractOfflineRomFS() { | ||||
|     LOG_DEBUG(Service_AM, "Extracting RomFS to {}", | ||||
|               Common::FS::PathToUTF8String(offline_cache_dir)); | ||||
|  | ||||
|     const auto extracted_romfs_dir = | ||||
|         FileSys::ExtractRomFS(offline_romfs, FileSys::RomFSExtractionType::SingleDiscard); | ||||
|     const auto extracted_romfs_dir = FileSys::ExtractRomFS(offline_romfs); | ||||
|  | ||||
|     const auto temp_dir = system.GetFilesystem()->CreateDirectory( | ||||
|         Common::FS::PathToUTF8String(offline_cache_dir), FileSys::Mode::ReadWrite); | ||||
|   | ||||
| @@ -2738,7 +2738,7 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const auto extracted = FileSys::ExtractRomFS(romfs, FileSys::RomFSExtractionType::Full); | ||||
|     const auto extracted = FileSys::ExtractRomFS(romfs); | ||||
|     if (extracted == nullptr) { | ||||
|         failed(); | ||||
|         return; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user