Reforge library structure - final pass

Rework files lister

DatEntries class got new path member


Play with vectors concatenation


Harmonize configuration
This commit is contained in:
JackCarterSmith 2023-01-15 17:04:34 +01:00
parent 2da49b53ae
commit 4a0b0df410
Signed by: JackCarterSmith
GPG Key ID: 832E52F4E23F8F24
9 changed files with 167 additions and 84 deletions

View File

@ -70,6 +70,7 @@ namespace RDI {
/* Krennic specific methods */ /* Krennic specific methods */
RDI_EXTERN std::vector<std::string> RDI_getLevelsName( void ); RDI_EXTERN std::vector<std::string> RDI_getLevelsName( void );
RDI_EXTERN std::vector<std::string> RDI_getModelsName( void ); RDI_EXTERN std::vector<std::string> RDI_getModelsName( void );
RDI_EXTERN std::vector<std::string> RDI_getTexturesName( void );
RDI_EXTERN std::vector<std::string> RDI_getMusicsName( void ); RDI_EXTERN std::vector<std::string> RDI_getMusicsName( void );
/** /**

View File

@ -19,33 +19,24 @@ using std::vector;
namespace RDI { namespace RDI {
namespace DatFile { namespace DatFile {
DatFileEntryFile::DatFileEntryFile( string name, DAT_FILE_FLAGS fFlags, unsigned int size, MEMFILE fPtr ) { DatFileEntryFile::DatFileEntryFile( string name, string path, DAT_FILE_FLAGS fFlags, unsigned int size, MEMFILE fPtr )
this->name = name; : DatFileEntry::DatFileEntry(name, path, fFlags), size(size), fileMemPtr(fPtr) {}
this->size = size;
this->fFlags.raw = fFlags.raw;
this->fileMemPtr = fPtr;
}
DatFileEntryFile::~DatFileEntryFile() {} DatFileEntryFile::~DatFileEntryFile() {}
DatFileEntryDirectory::DatFileEntryDirectory( string name ) { DatFileEntryDirectory::DatFileEntryDirectory( string name, string path )
this->name = name; : DatFileEntry::DatFileEntry(name, path), rootDir(true) {
this->fFlags.raw = 0;
this->rootDir = true;
vSubFiles = new vector<DatFileEntry*>; vSubFiles = new vector<DatFileEntry*>;
} }
DatFileEntryDirectory::DatFileEntryDirectory( string name, DAT_FILE_FLAGS fFlags ) { DatFileEntryDirectory::DatFileEntryDirectory( string name, string path, DAT_FILE_FLAGS fFlags )
this->name = name; : DatFileEntry::DatFileEntry(name, path, fFlags), rootDir(false) {
this->fFlags.raw = fFlags.raw;
this->rootDir = false;
vSubFiles = new vector<DatFileEntry*>; vSubFiles = new vector<DatFileEntry*>;
} }
DatFileEntryDirectory::DatFileEntryDirectory( string name, DAT_FILE_FLAGS fFlags, DatFileEntry* hFileEntry ) { DatFileEntryDirectory::DatFileEntryDirectory( string name, string path, DAT_FILE_FLAGS fFlags, DatFileEntry* hFileEntry )
this->name = name; : DatFileEntry::DatFileEntry(name, path, fFlags), rootDir(false) {
this->fFlags.raw = fFlags.raw;
vSubFiles = new vector<DatFileEntry*>; vSubFiles = new vector<DatFileEntry*>;
AddEntry(hFileEntry); AddEntry(hFileEntry);
} }
@ -56,10 +47,6 @@ DatFileEntryDirectory::~DatFileEntryDirectory() {
delete vSubFiles; delete vSubFiles;
} }
/*std::string DirectoryEntry::toString() {
}*/
void DatFileEntryDirectory::ClearLinkedFiles() { void DatFileEntryDirectory::ClearLinkedFiles() {
vSubFiles->clear(); vSubFiles->clear();
} }

View File

@ -44,13 +44,20 @@ public:
virtual ~DatFileEntry() = 0; virtual ~DatFileEntry() = 0;
virtual bool isDirectory() = 0; virtual bool isDirectory() = 0;
virtual bool isRootDirectory() = 0; virtual bool isRootDirectory() = 0;
//virtual std::string toString() = 0;
virtual unsigned int getSize() = 0; virtual unsigned int getSize() = 0;
std::string getName() { return name; }; std::string getName() { return name; }
std::string getPath() { return virtualAbsPath; }
protected: protected:
DatFileEntry( std::string name, std::string path ) : name(name), virtualAbsPath(path) {
this->fFlags.raw = 0;
}
DatFileEntry( std::string name, std::string path, DAT_FILE_FLAGS fFlags )
: name(name), virtualAbsPath(path), fFlags(fFlags) {}
std::string name; std::string name;
std::string virtualAbsPath;
DAT_FILE_FLAGS fFlags; DAT_FILE_FLAGS fFlags;
}; };
@ -58,34 +65,32 @@ inline DatFileEntry::~DatFileEntry() {}
class DatFileEntryFile : public DatFileEntry { class DatFileEntryFile : public DatFileEntry {
public: public:
DatFileEntryFile( std::string name, DAT_FILE_FLAGS fFlags, unsigned int size, MEMFILE fPtr ); DatFileEntryFile( std::string name, std::string path, DAT_FILE_FLAGS fFlags, unsigned int size, MEMFILE fPtr );
~DatFileEntryFile(); ~DatFileEntryFile();
MEMFILE getDatas() { return fileMemPtr; } MEMFILE getDatas() { return fileMemPtr; }
//std::string toString();
bool isDirectory() { return false; } bool isDirectory() { return false; }
bool isRootDirectory() { return false; } bool isRootDirectory() { return false; }
unsigned int getSize() { return size; } // In bytes unsigned int getSize() { return size; } // In bytes
private: private:
MEMFILE fileMemPtr;
unsigned int size; unsigned int size;
MEMFILE fileMemPtr;
}; };
class DatFileEntryDirectory : public DatFileEntry { class DatFileEntryDirectory : public DatFileEntry {
public: public:
DatFileEntryDirectory( std::string name ); DatFileEntryDirectory( std::string name, std::string path );
DatFileEntryDirectory( std::string name, DAT_FILE_FLAGS fFlags ); DatFileEntryDirectory( std::string name, std::string path, DAT_FILE_FLAGS fFlags );
DatFileEntryDirectory( std::string name, DAT_FILE_FLAGS fFlags, DatFileEntry* hFileEntry ); DatFileEntryDirectory( std::string name, std::string path, DAT_FILE_FLAGS fFlags, DatFileEntry* hFileEntry );
~DatFileEntryDirectory(); ~DatFileEntryDirectory();
void ClearLinkedFiles(); void ClearLinkedFiles();
void AddEntry( DatFileEntry* hFileEntry ); void AddEntry( DatFileEntry* hFileEntry );
std::vector<DatFileEntry*> getFiles() { return *vSubFiles; } std::vector<DatFileEntry*> getFiles() { return *vSubFiles; }
//std::string toString();
bool isDirectory() { return true; } bool isDirectory() { return true; }
bool isRootDirectory() { return rootDir; } bool isRootDirectory() { return rootDir; }
unsigned int getSize() { return vSubFiles->size(); } // In number of elements unsigned int getSize() { return vSubFiles->size(); } // In number of elements

View File

@ -164,7 +164,7 @@ RDI_RESULT Erso::CreateDataFilesTree() {
pFTRoot = new std::vector<DatFileEntryDirectory*>; pFTRoot = new std::vector<DatFileEntryDirectory*>;
pFTRoot->clear(); pFTRoot->clear();
for ( i = 0; i < cDatSection; i++ ) { for ( i = 0; i < cDatSection; i++ ) {
curDir = new DatFileEntryDirectory(pDatSection->at(i).name); curDir = new DatFileEntryDirectory(pDatSection->at(i).name, pDatSection->at(i).name);
pFTRoot->push_back(curDir); pFTRoot->push_back(curDir);
// Recalculate files descriptor offset for current section. // Recalculate files descriptor offset for current section.
@ -207,12 +207,12 @@ RDI_RESULT Erso::ProcessTreeDirectoryContents( DatFileEntryDirectory* pCurDir, M
// Test for file or directory // Test for file or directory
if (!curEntryFlags.isDirectory) { if (!curEntryFlags.isDirectory) {
newFile = new DatFileEntryFile(tmpStr, curEntryFlags, newFile = new DatFileEntryFile(tmpStr, pCurDir->getPath() + "/" + tmpStr, curEntryFlags,
((T_FILE_HEADER*)(pDesc + i * sizeof(T_FILE_HEADER)))->datas_size, ((T_FILE_HEADER*)(pDesc + i * sizeof(T_FILE_HEADER)))->datas_size,
pSectionStart + ((T_FILE_HEADER*)(pDesc + i * sizeof(T_FILE_HEADER)))->datas_offset); pSectionStart + ((T_FILE_HEADER*)(pDesc + i * sizeof(T_FILE_HEADER)))->datas_offset);
pCurDir->AddEntry(newFile); pCurDir->AddEntry(newFile);
} else { } else {
newDir = new DatFileEntryDirectory(tmpStr, curEntryFlags); newDir = new DatFileEntryDirectory(tmpStr, pCurDir->getPath() + "/" + tmpStr, curEntryFlags);
pCurDir->AddEntry(newDir); pCurDir->AddEntry(newDir);
// Keep entries count in new directory to jump over after processing it. // Keep entries count in new directory to jump over after processing it.
@ -245,9 +245,9 @@ void Erso::DisposeFile() {
* *
* @return Reference to the resource from specified input path * @return Reference to the resource from specified input path
*/ */
DatFileEntry *Erso::getElement( boost::filesystem::path virtualDirPath ) { DatFileEntry *Erso::getElement( path virtualDirPath ) {
bool skip = false; bool skip = false;
boost::filesystem::path newPath; path newPath;
for ( DatFileEntry* de : *pFTRoot ) { for ( DatFileEntry* de : *pFTRoot ) {
if (virtualDirPath.size() == 1 || virtualDirPath.begin() == --virtualDirPath.end()) { if (virtualDirPath.size() == 1 || virtualDirPath.begin() == --virtualDirPath.end()) {
@ -260,7 +260,7 @@ DatFileEntry *Erso::getElement( boost::filesystem::path virtualDirPath ) {
newPath.append(sp); newPath.append(sp);
skip = true; skip = true;
} }
return SearchSectionForEntry(dynamic_cast<DatFileEntryDirectory *>(de), newPath); return SearchEntryPath(dynamic_cast<DatFileEntryDirectory*>(de), newPath);
} }
} }
} }
@ -268,6 +268,32 @@ DatFileEntry *Erso::getElement( boost::filesystem::path virtualDirPath ) {
return nullptr; return nullptr;
} }
/**
* Get a list of files corresponding to the specified pattern.
*
* @param virtualDirPath Origin of browsing
* @param pattern Search filename pattern
* @param recursive Do the search inside subfolders
*
* @return List of references to the files corresponding to pattern
*/
vector<DatFileEntry*> Erso::getElements( path virtualDirPath, string pattern, bool recursive ) {
vector<DatFileEntry*> result;
DatFileEntryDirectory* curDir = dynamic_cast<DatFileEntryDirectory*>(getElement(virtualDirPath));
if (recursive) {
auto recursFileList = SearchEntriesPattern(curDir, pattern);
result.insert(result.end(), recursFileList.begin(), recursFileList.end());
} else {
for ( DatFileEntry* e : curDir->getFiles() ) {
if (e->getName().find(pattern) != string::npos) //TODO: Replace using RegEx search
result.push_back(e);
}
}
return result;
}
/** /**
* Browse inside virtual path to the final object from specific root DatFileEntryDirectory. * Browse inside virtual path to the final object from specific root DatFileEntryDirectory.
* *
@ -276,9 +302,9 @@ DatFileEntry *Erso::getElement( boost::filesystem::path virtualDirPath ) {
* *
* @return Reference to the file resource * @return Reference to the file resource
*/ */
DatFileEntry *Erso::SearchSectionForEntry( DatFileEntryDirectory *curDir, boost::filesystem::path virtualDirPath ) { DatFileEntry* Erso::SearchEntryPath( DatFileEntryDirectory* curDir, path virtualDirPath ) {
bool skip = false; bool skip = false;
boost::filesystem::path newPath; path newPath;
for ( DatFileEntry* e : curDir->getFiles() ) { for ( DatFileEntry* e : curDir->getFiles() ) {
if (virtualDirPath.size() == 1 || virtualDirPath.begin() == --virtualDirPath.end()) { if (virtualDirPath.size() == 1 || virtualDirPath.begin() == --virtualDirPath.end()) {
@ -292,7 +318,7 @@ DatFileEntry *Erso::SearchSectionForEntry( DatFileEntryDirectory *curDir, boost:
skip = true; skip = true;
} }
return SearchSectionForEntry(dynamic_cast<DatFileEntryDirectory *>(e), newPath); return SearchEntryPath(dynamic_cast<DatFileEntryDirectory*>(e), newPath);
} }
} }
} }
@ -300,4 +326,29 @@ DatFileEntry *Erso::SearchSectionForEntry( DatFileEntryDirectory *curDir, boost:
return nullptr; return nullptr;
} }
/**
* Browse inside virtual path to find specific pattern and add it reference to the list in input.
*
* @param upDir Origin of browsing
* @param pattern Search filename pattern
*
* @return Vector list of DatFileEntry
*/
vector<DatFileEntry*> Erso::SearchEntriesPattern( DatFileEntryDirectory* upDir, string pattern ) {
vector<DatFileEntry*> subDatEntries;
for ( DatFileEntry* e : upDir->getFiles() )
if (e->getName().find(pattern) != string::npos) //TODO: Replace using RegEx search
subDatEntries.push_back(e);
for ( DatFileEntry* e : upDir->getFiles() ) {
if (e->isDirectory()) {
auto recursFileList = SearchEntriesPattern(dynamic_cast<DatFileEntryDirectory*>(e), pattern);
subDatEntries.insert(subDatEntries.end(), recursFileList.begin(), recursFileList.end());
}
}
return subDatEntries;
}
} }

View File

@ -68,7 +68,8 @@ public:
unsigned int getDataSectionOffset( unsigned char id ) const; unsigned int getDataSectionOffset( unsigned char id ) const;
/* Tree manipulation/parse methods */ /* Tree manipulation/parse methods */
DatFile::DatFileEntry *getElement( boost::filesystem::path virtualDirPath ); DatFile::DatFileEntry* getElement( boost::filesystem::path virtualDirPath );
std::vector<DatFile::DatFileEntry*> getElements( boost::filesystem::path virtualDirPath, std::string pattern, bool recursive );
private: private:
std::string workingDir = "."; std::string workingDir = ".";
@ -94,7 +95,8 @@ private:
void DisposeFile(); void DisposeFile();
/* Tree manipulation/parse methods */ /* Tree manipulation/parse methods */
DatFile::DatFileEntry *SearchSectionForEntry( DatFile::DatFileEntryDirectory *curDir, boost::filesystem::path virtualDirPath); DatFile::DatFileEntry* SearchEntryPath( DatFile::DatFileEntryDirectory *curDir, boost::filesystem::path virtualDirPath);
std::vector<DatFile::DatFileEntry*> SearchEntriesPattern(DatFile::DatFileEntryDirectory *upDir, std::string pattern);
}; };

View File

@ -17,11 +17,28 @@
#include "Erso.hpp" #include "Erso.hpp"
#include "Krennic.hpp" #include "Krennic.hpp"
using std::string;
using std::vector;
using namespace RDI::DatFile; using namespace RDI::DatFile;
namespace RDI { namespace RDI {
struct PathDescriptor {
PathDescriptor(string p, bool r) noexcept
: path(p), isRecursive(r) {}
PathDescriptor(const PathDescriptor&) = default;
PathDescriptor& operator=(const PathDescriptor&) = default;
PathDescriptor(PathDescriptor&&) = default;
PathDescriptor& operator=(PathDescriptor&&) = default;
string path;
bool isRecursive;
};
Krennic::Krennic( Erso* pErso ) { Krennic::Krennic( Erso* pErso ) {
BuildLevelList(pErso); BuildLevelList(pErso);
BuildModelList(pErso); BuildModelList(pErso);
@ -34,61 +51,73 @@ Krennic::~Krennic() {}
void Krennic::BuildLevelList( Erso* pErso ) { void Krennic::BuildLevelList( Erso* pErso ) {
const static std::string legacyLvlPath = "data/level"; const static vector<PathDescriptor> legacyLvlPath = {
DatFileEntryDirectory* levelDir = nullptr; PathDescriptor("data/level", true)
};
listLevel.clear(); listLevel.clear();
levelDir = dynamic_cast<DatFileEntryDirectory*>(pErso->getElement(boost::filesystem::path(legacyLvlPath))); for (PathDescriptor legacyLvlSubpath : legacyLvlPath) {
if (levelDir != nullptr) { for (DatFileEntry* file : pErso->getElements(boost::filesystem::path(legacyLvlSubpath.path), "dat", legacyLvlSubpath.isRecursive)) {
for ( DatFileEntry* fl : levelDir->getFiles() ) { //TODO: level-class builder
if (fl->isDirectory()) { listLevel.push_back(file->getPath());
if (pErso->getElement(boost::filesystem::path(legacyLvlPath).append(fl->getName()).append("dat")) != nullptr) {
listLevel.push_back(legacyLvlPath + "/" + fl->getName());
}
}
} }
} }
//TODO: LvlClass builder
} }
void Krennic::BuildModelList( Erso* pErso ) { void Krennic::BuildModelList( Erso* pErso ) {
const static std::vector<std::string> legacyModelPath = { const static vector<PathDescriptor> legacyModelPath = {
"data/pl_crafts", "data/reb_stuff", "data/imp_stuff", PathDescriptor("data", false),
"data/gnrc_stuff", "data2" PathDescriptor("data/pl_crafts", false),
}; PathDescriptor("data/reb_stuff", false),
DatFileEntryDirectory* curModelDir = nullptr; PathDescriptor("data/imp_stuff", false),
PathDescriptor("data/gnrc_stuff", false),
PathDescriptor("data/level", true),
PathDescriptor("data/frontend", true),
PathDescriptor("data/dbg", false),
PathDescriptor("data2", false)
};
listModel.clear(); listModel.clear();
for ( std::string path_it : legacyModelPath ) { for (PathDescriptor legacyModelSubpath : legacyModelPath) {
curModelDir = dynamic_cast<DatFileEntryDirectory*>(pErso->getElement(boost::filesystem::path(path_it))); for (DatFileEntry* file : pErso->getElements(boost::filesystem::path(legacyModelSubpath.path), "_HOB", legacyModelSubpath.isRecursive)) {
if (curModelDir != nullptr) { //TODO: model-class builder
for ( DatFileEntry* fl : curModelDir->getFiles() ) { listModel.push_back(file->getPath());
if (fl->getName().find("_HOB") != std::string::npos) {
listModel.push_back(path_it + "/" + fl->getName());
}
}
} }
} }
} }
void Krennic::BuildTextureList( Erso* pErso ) { void Krennic::BuildTextureList( Erso* pErso ) {
const static vector<PathDescriptor> legacyTexturePath = {
PathDescriptor("data", false),
PathDescriptor("data/pl_crafts", false),
PathDescriptor("data/reb_stuff", false),
PathDescriptor("data/imp_stuff", false),
PathDescriptor("data/gnrc_stuff", false),
PathDescriptor("data/level", true),
PathDescriptor("data/frontend", true),
PathDescriptor("data/dbg", false),
PathDescriptor("data2", false)
};
listTexture.clear();
for (PathDescriptor legacyTextureSubpath : legacyTexturePath) {
for (DatFileEntry* file : pErso->getElements(boost::filesystem::path(legacyTextureSubpath.path), "_HMT", legacyTextureSubpath.isRecursive)) {
//TODO: texture-class builder
listTexture.push_back(file->getPath());
}
}
} }
void Krennic::BuildMusicList( Erso* pErso ) { void Krennic::BuildMusicList( Erso* pErso ) {
const static std::string legacyMusicPath = "data/sound"; const static vector<PathDescriptor> legacyLvlPath = {
DatFileEntryDirectory* musicDir = nullptr; PathDescriptor("data/sound", false)
};
listMusic.clear(); listMusic.clear();
musicDir = dynamic_cast<DatFileEntryDirectory*>(pErso->getElement(boost::filesystem::path(legacyMusicPath))); for (PathDescriptor legacyMusicSubpath : legacyLvlPath) {
if (musicDir != nullptr) { for (DatFileEntry* file : pErso->getElements(boost::filesystem::path(legacyMusicSubpath.path), "_SNG", legacyMusicSubpath.isRecursive)) {
for ( DatFileEntry* fl : musicDir->getFiles() ) {
//TODO: MusyX-Class builder //TODO: MusyX-Class builder
listMusic.push_back(file->getPath());
if (fl->getName().find("_SNG") != std::string::npos) {
listMusic.push_back(legacyMusicPath + "/" + fl->getName());
}
} }
} }
} }

View File

@ -46,11 +46,11 @@ public:
* @return File type class handler. * @return File type class handler.
*/ */
///@{ ///@{
void* getLevel( std::string name ); void* getLevel( std::string name );
void* getModel( std::string name ); void* getModel( std::string name );
HMT *getTexture( std::string name ); HMT* getTexture( std::string name );
void* getMusic( std::string name ); void* getMusic( std::string name );
void* getSample( std::string name ); void* getSample( std::string name );
///@} ///@}
/** /**

View File

@ -132,6 +132,10 @@ std::vector<std::string> RDI::RDI_getModelsName( void ) {
return KrennicModule->getModelsList(); return KrennicModule->getModelsList();
} }
std::vector<std::string> RDI::RDI_getTexturesName( void ) {
return KrennicModule->getTexturesList();
}
std::vector<std::string> RDI::RDI_getMusicsName( void ) { std::vector<std::string> RDI::RDI_getMusicsName( void ) {
return KrennicModule->getMusicsList(); return KrennicModule->getMusicsList();
} }

View File

@ -49,7 +49,7 @@ int main( int argc, char *argv[] ) {
cout << "> Section found: " << RDI::RDI_getSectionCount() << endl; cout << "> Section found: " << RDI::RDI_getSectionCount() << endl;
for ( i = 0; i < RDI::RDI_getSectionCount(); i++ ) { for ( i = 0; i < RDI::RDI_getSectionCount(); i++ ) {
cout << " -Section " << i << " name: " << RDI::RDI_getSectionName(i) << endl; cout << " -Section " << i << " name: " << RDI::RDI_getSectionName(i) << endl;
cout << " -Section " << i << " offset: 0x" << hex << uppercase << RDI::RDI_getSectionOffset(i) << endl; cout << " -Section " << i << " offset: 0x" << hex << uppercase << RDI::RDI_getSectionOffset(i) << dec << endl;
} }
// Print DATA.DAT tree view with unicode "style" // Print DATA.DAT tree view with unicode "style"
@ -65,15 +65,19 @@ int main( int argc, char *argv[] ) {
// Print game elements Krennic module found // Print game elements Krennic module found
cout << endl << "Legacy files processing result:"; cout << endl << "Legacy files processing result:";
cout << endl << "> Levels found:" << endl; cout << endl << "> Levels found: " << RDI::RDI_getLevelsName().size() << endl;
for ( std::string lname : RDI::RDI_getLevelsName() ) { for ( std::string lname : RDI::RDI_getLevelsName() ) {
cout << " " << lname << endl; cout << " " << lname << endl;
} }
cout << endl << "> Models found:" << endl; cout << endl << "> Models found: " << RDI::RDI_getModelsName().size() << endl;
for ( std::string mdname : RDI::RDI_getModelsName() ) { for ( std::string mdname : RDI::RDI_getModelsName() ) {
cout << " " << mdname << endl; cout << " " << mdname << endl;
} }
cout << endl << "> Musics found:" << endl; cout << endl << "> Textures found: " << RDI::RDI_getTexturesName().size() << endl;
for ( std::string txname : RDI::RDI_getTexturesName() ) {
cout << " " << txname << endl;
}
cout << endl << "> Musics found: " << RDI::RDI_getMusicsName().size() << endl;
for ( std::string mname : RDI::RDI_getMusicsName() ) { for ( std::string mname : RDI::RDI_getMusicsName() ) {
cout << " " << mname << endl; cout << " " << mname << endl;
} }