3DS: Batch directory reads
Vicki Pfau vi@endrift.com
Fri, 27 Nov 2020 15:18:23 -0800
2 files changed,
18 insertions(+),
8 deletions(-)
M
CHANGES
→
CHANGES
@@ -80,6 +80,7 @@ - SM83: Disassemble STOP as one byte
- Wii: Fix crash on unloading irregularly sized GBA ROMs Misc: - 3DS: Use "wide mode" where applicable for slightly better filtering + - 3DS: Batch directory reads - Core: Add savedataUpdated callback - Core: Add shutdown callback - Core: Rework thread state synchronization
M
src/platform/3ds/3ds-vfs.c
→
src/platform/3ds/3ds-vfs.c
@@ -9,6 +9,8 @@ #ifdef USE_VFS_3DS
#include <mgba-util/memory.h> #include <mgba-util/string.h> +#define MAX_ENT 4 + struct VFile3DS { struct VFile d;@@ -18,7 +20,9 @@ };
struct VDirEntry3DS { struct VDirEntry d; - FS_DirectoryEntry ent; + FS_DirectoryEntry ent[MAX_ENT]; + u32 entCount; + u32 currentEnt; char utf8Name[256]; };@@ -198,6 +202,7 @@ vd3d->d.deleteFile = _vd3dDeleteFile;
vd3d->vde.d.name = _vd3deName; vd3d->vde.d.type = _vd3deType; + vd3d->vde.entCount = 0; return &vd3d->d; }@@ -222,12 +227,16 @@ }
static struct VDirEntry* _vd3dListNext(struct VDir* vd) { struct VDir3DS* vd3d = (struct VDir3DS*) vd; - u32 n = 0; - memset(&vd3d->vde.ent, 0, sizeof(vd3d->vde.ent)); memset(vd3d->vde.utf8Name, 0, sizeof(vd3d->vde.utf8Name)); - FSDIR_Read(vd3d->handle, &n, 1, &vd3d->vde.ent); - if (!n) { - return 0; + if (!vd3d->vde.entCount || vd3d->vde.currentEnt + 1 >= vd3d->vde.entCount) { + memset(&vd3d->vde.ent, 0, sizeof(vd3d->vde.ent)); + FSDIR_Read(vd3d->handle, &vd3d->vde.entCount, MAX_ENT, vd3d->vde.ent); + vd3d->vde.currentEnt = 0; + } else { + ++vd3d->vde.currentEnt; + } + if (!vd3d->vde.entCount) { + return NULL; } return &vd3d->vde.d; }@@ -296,14 +305,14 @@
static const char* _vd3deName(struct VDirEntry* vde) { struct VDirEntry3DS* vd3de = (struct VDirEntry3DS*) vde; if (!vd3de->utf8Name[0]) { - utf16_to_utf8((uint8_t*) vd3de->utf8Name, vd3de->ent.name, sizeof(vd3de->utf8Name)); + utf16_to_utf8((uint8_t*) vd3de->utf8Name, vd3de->ent[vd3de->currentEnt].name, sizeof(vd3de->utf8Name)); } return vd3de->utf8Name; } static enum VFSType _vd3deType(struct VDirEntry* vde) { struct VDirEntry3DS* vd3de = (struct VDirEntry3DS*) vde; - if (vd3de->ent.attributes & FS_ATTRIBUTE_DIRECTORY) { + if (vd3de->ent[vd3de->currentEnt].attributes & FS_ATTRIBUTE_DIRECTORY) { return VFS_DIRECTORY; } return VFS_FILE;