diff --git a/source/virtual/vgame.c b/source/virtual/vgame.c index 305fb1f..4a4850b 100644 --- a/source/virtual/vgame.c +++ b/source/virtual/vgame.c @@ -550,6 +550,28 @@ int ReadVGameFile(const VirtualFile* vfile, u8* buffer, u32 offset, u32 count) { return 0; } +bool FindVirtualFileInLv3Dir(VirtualFile* vfile, const VirtualDir* vdir, const char* name) { + vfile->name[0] = '\0'; + vfile->flags = vdir->flags & ~VFLAG_DIR; + + RomFsLv3FileMeta* lv3file = GetLv3FileMeta(name, vdir->offset, &lv3idx); + if (lv3file) { + vfile->offset = ((u8*) lv3file) - ((u8*) lv3idx.filemeta); + vfile->size = lv3file->size_data; + return true; + } + + RomFsLv3DirMeta* lv3dir = GetLv3DirMeta(name, vdir->offset, &lv3idx); + if (lv3dir) { + vfile->offset = ((u8*) lv3dir) - ((u8*) lv3idx.dirmeta); + vfile->size = 0; + vfile->flags |= VFLAG_DIR; + return true; + } + + return false; +} + bool GetVGameLv3Filename(char* name, const VirtualFile* vfile, u32 n_chars) { if (!(vfile->flags & VFLAG_LV3)) return false; diff --git a/source/virtual/virtual.c b/source/virtual/virtual.c index 3ea2946..11b2883 100644 --- a/source/virtual/virtual.c +++ b/source/virtual/virtual.c @@ -88,11 +88,16 @@ bool GetVirtualFile(VirtualFile* vfile, const char* path) { VirtualDir vdir; if (!OpenVirtualRoot(&vdir, virtual_src)) return false; for (name = strtok(lpath + 3, "/"); name && vdir.virtual_src; name = strtok(NULL, "/")) { - while (true) { - if (!ReadVirtualDir(vfile, &vdir)) return false; - if ((!(vfile->flags & VFLAG_LV3) && (strncasecmp(name, vfile->name, 32) == 0)) || - ((vfile->flags & VFLAG_LV3) && MatchVGameLv3Filename(name, vfile, 256))) - break; // entry found + if (!(vdir.flags & VFLAG_LV3)) { // standard method + while (true) { + if (!ReadVirtualDir(vfile, &vdir)) return false; + if ((!(vfile->flags & VFLAG_LV3) && (strncasecmp(name, vfile->name, 32) == 0)) || + ((vfile->flags & VFLAG_LV3) && MatchVGameLv3Filename(name, vfile, 256))) + break; // entry found + } + } else { // use lv3 hashes for quicker search + if (!FindVirtualFileInLv3Dir(vfile, &vdir, name)) + return false; } if (!OpenVirtualDir(&vdir, vfile)) vdir.virtual_src = 0;