Skip to content

Commit eaffd46

Browse files
committed
Aurora-allocated entry nums & dir support
1 parent 3885c01 commit eaffd46

5 files changed

Lines changed: 183 additions & 98 deletions

File tree

cmake/aurora_dvd.cmake

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,4 @@ set_target_properties(aurora_dvd PROPERTIES FOLDER "aurora")
66

77
target_compile_definitions(aurora_dvd PUBLIC AURORA TARGET_PC)
88
target_include_directories(aurora_dvd PUBLIC include)
9-
target_link_libraries(aurora_dvd PUBLIC nod::nod ${AURORA_SDL3_TARGET})
10-
target_link_libraries(aurora_dvd PRIVATE fmt::fmt)
9+
target_link_libraries(aurora_dvd PUBLIC nod::nod fmt::fmt ${AURORA_SDL3_TARGET})

include/aurora/dvd.h

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ void aurora_dvd_close(void);
2727
* The way this works is pretty simple: you provide some callbacks and a list of files.
2828
* When an overlaid file gets read, your callbacks get called instead of pulling from the underlying DVD.
2929
*
30-
* Original disc EntryNums are not touched by the overlay system, new files are added "at the end."
31-
* The EntryNums for newly-added files are assigned by the game.
30+
* Original disc EntryNums are not touched by the overlay system. New files and directories
31+
* are assigned stable EntryNums by Aurora.
3232
*/
3333

3434
/**
@@ -57,13 +57,6 @@ typedef struct AuroraOverlayFile {
5757
*/
5858
size_t size;
5959

60-
/**
61-
* \brief The observeable EntryNum of this file.
62-
*
63-
* This value is ignored when replacing files already present on the original disc.
64-
* Newly added files *must* specify a value that's above aurora_dvd_base_entry_count().
65-
*/
66-
s32 entryNum;
6760
} AuroraOverlayFile;
6861

6962
/**
@@ -115,8 +108,9 @@ void aurora_dvd_overlay_callbacks(const AuroraOverlayCallbacks* callbacks);
115108
*
116109
* @param files Array of AuroraOverlayFiles, one for every file being overlaid.
117110
* @param nFiles Amount of files in the array.
111+
* @param outEntryNums Optional output array receiving one EntryNum per input file. Unaccepted files receive -1.
118112
*/
119-
void aurora_dvd_overlay_files(const AuroraOverlayFile* files, size_t nFiles);
113+
void aurora_dvd_overlay_files(const AuroraOverlayFile* files, size_t nFiles, s32* outEntryNums);
120114

121115
/**
122116
* \brief Gets the amount of FST entries present on the loaded game disc.

lib/dolphin/dvd/dvd.cpp

Lines changed: 53 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,12 @@ using namespace aurora::dvd::impl;
2424
namespace aurora::dvd::impl {
2525
NodHandle* s_partition = nullptr;
2626
std::vector<FSTEntry> s_fstEntries;
27-
// Map from "virtual" FST entryNums (matching base disc, game-assigned for new overlay files)
28-
// To the "physical" FST entryNums (that we use for navigating the tree).
27+
// Map from public FST entryNums (matching base disc, Aurora-assigned for new overlay entries)
28+
// To the current FST indexes (that we use for navigating the tree).
2929
// Unfilled spots are given the k_invalidFstEntry value.
30-
std::vector<PhysicalEntryNum> s_fstEntryMap;
31-
s32 s_baseEntryCount;
32-
PhysicalEntryNum s_currentDir = 0;
30+
std::vector<FstIndex> s_entryNumToFstIndex;
31+
s32 s_baseEntryCount = 0;
32+
FstIndex s_currentDir = 0;
3333
std::string s_currentPath = "/";
3434
BOOL s_autoInvalidation = FALSE;
3535
BOOL s_autoFatalMessaging = FALSE;
@@ -96,17 +96,20 @@ void clearState() {
9696
s_disc = nullptr;
9797
}
9898
s_fstEntries.clear();
99+
s_entryNumToFstIndex.clear();
100+
s_baseEntryCount = 0;
99101
s_currentDir = 0;
100102
s_currentPath = "/";
101103
s_diskID = {};
102104
s_initialized = false;
103105
}
104106

105-
bool isValidVirtualEntry(VirtualEntryNum entry) {
106-
return entry >= 0 && static_cast<size_t>(entry) < s_fstEntryMap.size() && s_fstEntryMap[entry] != k_invalidFstEntry;
107+
bool isValidEntryNum(s32 entry) {
108+
return entry >= 0 && static_cast<size_t>(entry) < s_entryNumToFstIndex.size() &&
109+
s_entryNumToFstIndex[entry] != k_invalidFstEntry;
107110
}
108111

109-
bool isValidPhysicalEntry(PhysicalEntryNum entry) {
112+
bool isValidFstIndex(FstIndex entry) {
110113
return entry >= 0 && static_cast<size_t>(entry) < s_fstEntries.size();
111114
}
112115

@@ -159,16 +162,16 @@ bool nameEqualsIgnoreCase(const std::string& lhs, const char* rhs, size_t rhsLen
159162
return aurora::dvd::impl::nameEqualsIgnoreCase(lhs, std::string_view(rhs, rhsLen));
160163
}
161164

162-
PhysicalEntryNum findInDir(PhysicalEntryNum dirEntry, const char* name, size_t nameLen) {
163-
if (!isValidPhysicalEntry(dirEntry) || !s_fstEntries[dirEntry].isDir) {
165+
FstIndex findInDir(FstIndex dirEntry, const char* name, size_t nameLen) {
166+
if (!isValidFstIndex(dirEntry) || !s_fstEntries[dirEntry].isDir) {
164167
return -1;
165168
}
166169

167170
u32 childEnd = s_fstEntries[dirEntry].nextOrLength;
168171
u32 i = static_cast<u32>(dirEntry) + 1;
169172
while (i < childEnd && i < s_fstEntries.size()) {
170173
if (nameEqualsIgnoreCase(s_fstEntries[i].name, name, nameLen)) {
171-
return static_cast<PhysicalEntryNum>(i);
174+
return static_cast<FstIndex>(i);
172175
}
173176

174177
if (s_fstEntries[i].isDir) {
@@ -181,14 +184,14 @@ PhysicalEntryNum findInDir(PhysicalEntryNum dirEntry, const char* name, size_t n
181184
return -1;
182185
}
183186

184-
std::string buildDirPath(PhysicalEntryNum entryNum) {
185-
if (entryNum <= 0 || !isValidPhysicalEntry(entryNum)) {
187+
std::string buildDirPath(FstIndex entryNum) {
188+
if (entryNum <= 0 || !isValidFstIndex(entryNum)) {
186189
return "/";
187190
}
188191

189192
std::vector<std::string> parts;
190-
PhysicalEntryNum cur = entryNum;
191-
while (cur > 0 && isValidPhysicalEntry(cur)) {
193+
FstIndex cur = entryNum;
194+
while (cur > 0 && isValidFstIndex(cur)) {
192195
parts.push_back(s_fstEntries[cur].name);
193196
auto parent = s_fstEntries[cur].parent;
194197
if (parent == cur) {
@@ -672,14 +675,14 @@ int DVDSetAutoFatalMessaging(BOOL enable) {
672675
return prev;
673676
}
674677

675-
VirtualEntryNum DVDConvertPathToEntrynum(const char* pathPtr) {
678+
s32 DVDConvertPathToEntrynum(const char* pathPtr) {
676679
std::lock_guard lock(s_fstLock);
677680

678681
if (!s_initialized || pathPtr == nullptr || s_fstEntries.empty()) {
679682
return -1;
680683
}
681684

682-
PhysicalEntryNum current = 0;
685+
FstIndex current = 0;
683686
const char* p = pathPtr;
684687
if (*p == '/') {
685688
++p;
@@ -695,7 +698,7 @@ VirtualEntryNum DVDConvertPathToEntrynum(const char* pathPtr) {
695698
break;
696699
}
697700

698-
if (!isValidPhysicalEntry(current) || !s_fstEntries[current].isDir) {
701+
if (!isValidFstIndex(current) || !s_fstEntries[current].isDir) {
699702
return -1;
700703
}
701704

@@ -710,7 +713,7 @@ VirtualEntryNum DVDConvertPathToEntrynum(const char* pathPtr) {
710713
} else if (compLen == 2 && p[0] == '.' && p[1] == '.') {
711714
current = static_cast<s32>(s_fstEntries[current].parent);
712715
} else {
713-
const PhysicalEntryNum found = findInDir(current, p, compLen);
716+
const FstIndex found = findInDir(current, p, compLen);
714717
if (found < 0) {
715718
return -1;
716719
}
@@ -719,21 +722,21 @@ VirtualEntryNum DVDConvertPathToEntrynum(const char* pathPtr) {
719722
p = compEnd;
720723
}
721724

722-
assert(isValidPhysicalEntry(current));
725+
assert(isValidFstIndex(current));
723726
return s_fstEntries[current].origEntryNum;
724727
}
725728

726-
BOOL DVDFastOpen(VirtualEntryNum entrynum, DVDFileInfo* fileInfo) {
729+
BOOL DVDFastOpen(s32 entrynum, DVDFileInfo* fileInfo) {
727730
std::lock_guard lock(s_fstLock);
728731

729-
if (!s_initialized || fileInfo == nullptr || !isValidVirtualEntry(entrynum) || s_partition == nullptr) {
732+
if (!s_initialized || fileInfo == nullptr || !isValidEntryNum(entrynum) || s_partition == nullptr) {
730733
return FALSE;
731734
}
732735

733-
const auto physical = s_fstEntryMap[entrynum];
734-
assert(physical >= 0);
736+
const auto fstIndex = s_entryNumToFstIndex[entrynum];
737+
assert(fstIndex >= 0);
735738

736-
const auto& entry = s_fstEntries[physical];
739+
const auto& entry = s_fstEntries[fstIndex];
737740
if (entry.isDir) {
738741
return FALSE;
739742
}
@@ -764,7 +767,7 @@ BOOL DVDFastOpen(VirtualEntryNum entrynum, DVDFileInfo* fileInfo) {
764767
}
765768

766769
BOOL DVDOpen(const char* fileName, DVDFileInfo* fileInfo) {
767-
VirtualEntryNum entrynum = DVDConvertPathToEntrynum(fileName);
770+
s32 entrynum = DVDConvertPathToEntrynum(fileName);
768771
if (entrynum < 0) {
769772
return FALSE;
770773
}
@@ -795,21 +798,21 @@ BOOL DVDGetCurrentDir(char* path, u32 maxlen) {
795798
}
796799

797800
BOOL DVDChangeDir(const char* dirName) {
798-
VirtualEntryNum entry = DVDConvertPathToEntrynum(dirName);
801+
s32 entry = DVDConvertPathToEntrynum(dirName);
799802

800803
std::lock_guard lock(s_fstLock);
801804

802-
if (!isValidVirtualEntry(entry)) {
805+
if (!isValidEntryNum(entry)) {
803806
return FALSE;
804807
}
805808

806-
const auto physical = s_fstEntryMap[entry];
807-
if (!s_fstEntries[physical].isDir) {
809+
const auto fstIndex = s_entryNumToFstIndex[entry];
810+
if (!s_fstEntries[fstIndex].isDir) {
808811
return FALSE;
809812
}
810813

811-
s_currentDir = physical;
812-
s_currentPath = buildDirPath(physical);
814+
s_currentDir = fstIndex;
815+
s_currentPath = buildDirPath(fstIndex);
813816
return TRUE;
814817
}
815818

@@ -872,26 +875,26 @@ s32 DVDGetFileInfoStatus(const DVDFileInfo* fileInfo) {
872875
return fileInfo->cb.state;
873876
}
874877

875-
BOOL DVDFastOpenDir(VirtualEntryNum entrynum, DVDDir* dir) {
878+
BOOL DVDFastOpenDir(s32 entrynum, DVDDir* dir) {
876879
std::lock_guard lock(s_fstLock);
877880

878-
if (!isValidVirtualEntry(entrynum) || dir == nullptr) {
881+
if (!isValidEntryNum(entrynum) || dir == nullptr) {
879882
return FALSE;
880883
}
881884

882-
const auto physical = s_fstEntryMap[entrynum];
883-
if (!s_fstEntries[physical].isDir) {
885+
const auto fstIndex = s_entryNumToFstIndex[entrynum];
886+
if (!s_fstEntries[fstIndex].isDir) {
884887
return FALSE;
885888
}
886889

887-
dir->entryNum = static_cast<u32>(physical);
888-
dir->location = static_cast<u32>(physical) + 1;
889-
dir->next = s_fstEntries[physical].nextOrLength;
890+
dir->entryNum = static_cast<u32>(entrynum);
891+
dir->location = static_cast<u32>(fstIndex) + 1;
892+
dir->next = s_fstEntries[fstIndex].nextOrLength;
890893
return TRUE;
891894
}
892895

893896
int DVDOpenDir(const char* dirName, DVDDir* dir) {
894-
VirtualEntryNum entrynum = DVDConvertPathToEntrynum(dirName);
897+
s32 entrynum = DVDConvertPathToEntrynum(dirName);
895898
if (entrynum < 0) {
896899
return FALSE;
897900
}
@@ -911,7 +914,7 @@ int DVDReadDir(DVDDir* dir, DVDDirEntry* dirent) {
911914

912915
const u32 index = dir->location;
913916
FSTEntry& entry = s_fstEntries[index];
914-
dirent->entryNum = index;
917+
dirent->entryNum = static_cast<u32>(entry.origEntryNum);
915918
dirent->isDir = entry.isDir ? TRUE : FALSE;
916919
dirent->name = entry.name.empty() ? nullptr : entry.name.data();
917920

@@ -933,7 +936,15 @@ void DVDRewindDir(DVDDir* dir) {
933936
if (dir == nullptr) {
934937
return;
935938
}
936-
dir->location = dir->entryNum + 1;
939+
940+
std::lock_guard lock(s_fstLock);
941+
const s32 entryNum = static_cast<s32>(dir->entryNum);
942+
if (!isValidEntryNum(entryNum)) {
943+
return;
944+
}
945+
946+
const auto fstIndex = s_entryNumToFstIndex[entryNum];
947+
dir->location = static_cast<u32>(fstIndex) + 1;
937948
}
938949

939950
void* DVDGetFSTLocation(void) {

lib/dolphin/dvd/dvd.hpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,32 @@ namespace aurora::dvd::impl {
1616

1717
inline Module Log("aurora::dvd");
1818

19-
using PhysicalEntryNum = s32;
20-
using VirtualEntryNum = s32;
19+
using FstIndex = s32;
2120
constexpr s32 k_invalidFstEntry = -1;
2221

2322
struct FSTEntry {
2423
std::string name;
2524
bool isDir = false;
26-
PhysicalEntryNum parent = 0;
25+
FstIndex parent = 0;
2726
u32 nextOrLength = 0;
2827
void* overlayData = nullptr;
2928
bool isOverlay = false;
30-
VirtualEntryNum origEntryNum = 0;
29+
s32 origEntryNum = 0;
3130
};
3231

3332
struct IterateNode {
3433
std::string name;
3534
bool isDir;
36-
u32 originalEntryNum;
35+
s32 originalEntryNum;
3736
u32 size;
3837
void* overlayData;
3938
bool isOverlay;
4039
std::vector<std::shared_ptr<IterateNode>> children;
4140

42-
IterateNode(std::string name, bool isDir, u32 size, u32 originalEntryNum, void* overlayData)
41+
IterateNode(std::string name, bool isDir, u32 size, s32 originalEntryNum, void* overlayData)
4342
: name(std::move(name)), isDir(isDir), size(size), originalEntryNum(originalEntryNum), overlayData(overlayData), isOverlay(true) {}
4443

45-
IterateNode(std::string name, bool isDir, u32 size, u32 originalEntryNum)
44+
IterateNode(std::string name, bool isDir, u32 size, s32 originalEntryNum)
4645
: name(std::move(name)), isDir(isDir), size(size), originalEntryNum(originalEntryNum), overlayData(nullptr), isOverlay(false) {}
4746
};
4847

@@ -53,12 +52,12 @@ struct IterateContext {
5352

5453
extern NodHandle* s_partition;
5554
extern std::vector<FSTEntry> s_fstEntries;
56-
// Map from "virtual" FST entryNums (matching base disc, game-assigned for new overlay files)
57-
// To the "physical" FST entryNums (that we use for navigating the tree).
55+
// Map from public FST entryNums (matching base disc, Aurora-assigned for new overlay files)
56+
// To the current FST indexes (that we use for navigating the tree).
5857
// Unfilled spots are given the k_invalidFstEntry value.
59-
extern std::vector<PhysicalEntryNum> s_fstEntryMap;
58+
extern std::vector<FstIndex> s_entryNumToFstIndex;
6059
extern s32 s_baseEntryCount;
61-
extern PhysicalEntryNum s_currentDir;
60+
extern FstIndex s_currentDir;
6261
extern std::string s_currentPath;
6362
extern BOOL s_autoInvalidation;
6463
extern BOOL s_autoFatalMessaging;
@@ -72,4 +71,4 @@ extern std::mutex s_fstLock;
7271
bool rebuildFST();
7372
bool nameEqualsIgnoreCase(std::string_view lhs, std::string_view rhs);
7473

75-
}
74+
}

0 commit comments

Comments
 (0)