3DS: Batch directory reads

This commit is contained in:
Vicki Pfau 2020-11-27 15:18:23 -08:00
parent 99e622eb43
commit 39324749f2
2 changed files with 18 additions and 8 deletions

View File

@ -80,6 +80,7 @@ Other fixes:
- Wii: Fix crash on unloading irregularly sized GBA ROMs - Wii: Fix crash on unloading irregularly sized GBA ROMs
Misc: Misc:
- 3DS: Use "wide mode" where applicable for slightly better filtering - 3DS: Use "wide mode" where applicable for slightly better filtering
- 3DS: Batch directory reads
- Core: Add savedataUpdated callback - Core: Add savedataUpdated callback
- Core: Add shutdown callback - Core: Add shutdown callback
- Core: Rework thread state synchronization - Core: Rework thread state synchronization

View File

@ -9,6 +9,8 @@
#include <mgba-util/memory.h> #include <mgba-util/memory.h>
#include <mgba-util/string.h> #include <mgba-util/string.h>
#define MAX_ENT 4
struct VFile3DS { struct VFile3DS {
struct VFile d; struct VFile d;
@ -18,7 +20,9 @@ struct VFile3DS {
struct VDirEntry3DS { struct VDirEntry3DS {
struct VDirEntry d; struct VDirEntry d;
FS_DirectoryEntry ent; FS_DirectoryEntry ent[MAX_ENT];
u32 entCount;
u32 currentEnt;
char utf8Name[256]; char utf8Name[256];
}; };
@ -198,6 +202,7 @@ struct VDir* VDirOpen(const char* path) {
vd3d->vde.d.name = _vd3deName; vd3d->vde.d.name = _vd3deName;
vd3d->vde.d.type = _vd3deType; vd3d->vde.d.type = _vd3deType;
vd3d->vde.entCount = 0;
return &vd3d->d; return &vd3d->d;
} }
@ -222,12 +227,16 @@ static void _vd3dRewind(struct VDir* vd) {
static struct VDirEntry* _vd3dListNext(struct VDir* vd) { static struct VDirEntry* _vd3dListNext(struct VDir* vd) {
struct VDir3DS* vd3d = (struct VDir3DS*) 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)); memset(vd3d->vde.utf8Name, 0, sizeof(vd3d->vde.utf8Name));
FSDIR_Read(vd3d->handle, &n, 1, &vd3d->vde.ent); if (!vd3d->vde.entCount || vd3d->vde.currentEnt + 1 >= vd3d->vde.entCount) {
if (!n) { memset(&vd3d->vde.ent, 0, sizeof(vd3d->vde.ent));
return 0; 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; return &vd3d->vde.d;
} }
@ -296,14 +305,14 @@ static bool _vd3dDeleteFile(struct VDir* vd, const char* path) {
static const char* _vd3deName(struct VDirEntry* vde) { static const char* _vd3deName(struct VDirEntry* vde) {
struct VDirEntry3DS* vd3de = (struct VDirEntry3DS*) vde; struct VDirEntry3DS* vd3de = (struct VDirEntry3DS*) vde;
if (!vd3de->utf8Name[0]) { 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; return vd3de->utf8Name;
} }
static enum VFSType _vd3deType(struct VDirEntry* vde) { static enum VFSType _vd3deType(struct VDirEntry* vde) {
struct VDirEntry3DS* vd3de = (struct VDirEntry3DS*) 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_DIRECTORY;
} }
return VFS_FILE; return VFS_FILE;