@@ -45,14 +45,15 @@ Error PackedData::add_pack(const String &p_path, bool p_replace_files, uint64_t
4545 return ERR_FILE_UNRECOGNIZED;
4646}
4747
48- void PackedData::add_path (const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted) {
48+ void PackedData::add_path (const String &p_pkg_path, const String &p_path, uint64_t p_ofs, uint64_t p_size, const uint8_t *p_md5, PackSource *p_src, bool p_replace_files, bool p_encrypted, bool p_bundle ) {
4949 String simplified_path = p_path.simplify_path ().trim_prefix (" res://" );
5050 PathMD5 pmd5 (simplified_path.md5_buffer ());
5151
5252 bool exists = files.has (pmd5);
5353
5454 PackedFile pf;
5555 pf.encrypted = p_encrypted;
56+ pf.bundle = p_bundle;
5657 pf.pack = p_pkg_path;
5758 pf.offset = p_ofs;
5859 pf.size = p_size;
@@ -268,6 +269,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
268269 uint32_t pack_flags = f->get_32 ();
269270 bool enc_directory = (pack_flags & PACK_DIR_ENCRYPTED);
270271 bool rel_filebase = (pack_flags & PACK_REL_FILEBASE); // Note: Always enabled for V3.
272+ bool sparse_bundle = (pack_flags & PACK_SPARSE_BUNDLE);
271273
272274 uint64_t file_base = f->get_64 ();
273275 if ((version == PACK_FORMAT_VERSION_V3) || (version == PACK_FORMAT_VERSION_V2 && rel_filebase)) {
@@ -320,7 +322,7 @@ bool PackedSourcePCK::try_open_pack(const String &p_path, bool p_replace_files,
320322 if (flags & PACK_FILE_REMOVAL) { // The file was removed.
321323 PackedData::get_singleton ()->remove_path (path);
322324 } else {
323- PackedData::get_singleton ()->add_path (p_path, path, file_base + ofs, size, md5, this , p_replace_files, (flags & PACK_FILE_ENCRYPTED));
325+ PackedData::get_singleton ()->add_path (p_path, path, file_base + ofs, size, md5, this , p_replace_files, (flags & PACK_FILE_ENCRYPTED), sparse_bundle );
324326 }
325327 }
326328
@@ -360,7 +362,7 @@ void PackedSourceDirectory::add_directory(const String &p_path, bool p_replace_f
360362 for (const String &file_name : da->get_files ()) {
361363 String file_path = p_path.path_join (file_name);
362364 uint8_t md5[16 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
363- PackedData::get_singleton ()->add_path (p_path, file_path, 0 , 0 , md5, this , p_replace_files, false );
365+ PackedData::get_singleton ()->add_path (p_path, file_path, 0 , 0 , md5, this , p_replace_files, false , false );
364366 }
365367
366368 for (const String &sub_dir_name : da->get_directories ()) {
@@ -467,13 +469,19 @@ void FileAccessPack::close() {
467469 f = Ref<FileAccess>();
468470}
469471
470- FileAccessPack::FileAccessPack (const String &p_path, const PackedData::PackedFile &p_file) :
471- pf(p_file),
472- f(FileAccess::open(pf.pack, FileAccess::READ)) {
473- ERR_FAIL_COND_MSG (f.is_null (), vformat (" Can't open pack-referenced file '%s'." , String (pf.pack )));
472+ FileAccessPack::FileAccessPack (const String &p_path, const PackedData::PackedFile &p_file) {
473+ pf = p_file;
474+ if (pf.bundle ) {
475+ String simplified_path = p_path.simplify_path ();
476+ f = FileAccess::open (simplified_path, FileAccess::READ | FileAccess::SKIP_PACK);
477+ off = 0 ; // For the sparse pack offset is always zero.
478+ } else {
479+ f = FileAccess::open (pf.pack , FileAccess::READ);
480+ f->seek (pf.offset );
481+ off = pf.offset ;
482+ }
474483
475- f->seek (pf.offset );
476- off = pf.offset ;
484+ ERR_FAIL_COND_MSG (f.is_null (), vformat (" Can't open pack-referenced file '%s'." , String (pf.pack )));
477485
478486 if (pf.encrypted ) {
479487 Ref<FileAccessEncrypted> fae;
0 commit comments