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 */
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_getTexturesName( void );
RDI_EXTERN std::vector<std::string> RDI_getMusicsName( void );
/**

View File

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

View File

@ -44,13 +44,20 @@ public:
virtual ~DatFileEntry() = 0;
virtual bool isDirectory() = 0;
virtual bool isRootDirectory() = 0;
//virtual std::string toString() = 0;
virtual unsigned int getSize() = 0;
std::string getName() { return name; };
std::string getName() { return name; }
std::string getPath() { return virtualAbsPath; }
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 virtualAbsPath;
DAT_FILE_FLAGS fFlags;
};
@ -58,34 +65,32 @@ inline DatFileEntry::~DatFileEntry() {}
class DatFileEntryFile : public DatFileEntry {
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();
MEMFILE getDatas() { return fileMemPtr; }
//std::string toString();
bool isDirectory() { return false; }
bool isRootDirectory() { return false; }
unsigned int getSize() { return size; } // In bytes
private:
MEMFILE fileMemPtr;
unsigned int size;
MEMFILE fileMemPtr;
};
class DatFileEntryDirectory : public DatFileEntry {
public:
DatFileEntryDirectory( std::string name );
DatFileEntryDirectory( std::string name, DAT_FILE_FLAGS fFlags );
DatFileEntryDirectory( std::string name, DAT_FILE_FLAGS fFlags, DatFileEntry* hFileEntry );
DatFileEntryDirectory( std::string name, std::string path );
DatFileEntryDirectory( std::string name, std::string path, DAT_FILE_FLAGS fFlags );
DatFileEntryDirectory( std::string name, std::string path, DAT_FILE_FLAGS fFlags, DatFileEntry* hFileEntry );
~DatFileEntryDirectory();
void ClearLinkedFiles();
void AddEntry( DatFileEntry* hFileEntry );
std::vector<DatFileEntry*> getFiles() { return *vSubFiles; }
//std::string toString();
bool isDirectory() { return true; }
bool isRootDirectory() { return rootDir; }
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->clear();
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);
// Recalculate files descriptor offset for current section.
@ -207,12 +207,12 @@ RDI_RESULT Erso::ProcessTreeDirectoryContents( DatFileEntryDirectory* pCurDir, M
// Test for file or directory
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,
pSectionStart + ((T_FILE_HEADER*)(pDesc + i * sizeof(T_FILE_HEADER)))->datas_offset);
pCurDir->AddEntry(newFile);
} else {
newDir = new DatFileEntryDirectory(tmpStr, curEntryFlags);
newDir = new DatFileEntryDirectory(tmpStr, pCurDir->getPath() + "/" + tmpStr, curEntryFlags);
pCurDir->AddEntry(newDir);
// 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
*/
DatFileEntry *Erso::getElement( boost::filesystem::path virtualDirPath ) {
DatFileEntry *Erso::getElement( path virtualDirPath ) {
bool skip = false;
boost::filesystem::path newPath;
path newPath;
for ( DatFileEntry* de : *pFTRoot ) {
if (virtualDirPath.size() == 1 || virtualDirPath.begin() == --virtualDirPath.end()) {
@ -260,7 +260,7 @@ DatFileEntry *Erso::getElement( boost::filesystem::path virtualDirPath ) {
newPath.append(sp);
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;
}
/**
* 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.
*
@ -276,9 +302,9 @@ DatFileEntry *Erso::getElement( boost::filesystem::path virtualDirPath ) {
*
* @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;
boost::filesystem::path newPath;
path newPath;
for ( DatFileEntry* e : curDir->getFiles() ) {
if (virtualDirPath.size() == 1 || virtualDirPath.begin() == --virtualDirPath.end()) {
@ -292,7 +318,7 @@ DatFileEntry *Erso::SearchSectionForEntry( DatFileEntryDirectory *curDir, boost:
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;
}
/**
* 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;
/* 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:
std::string workingDir = ".";
@ -94,7 +95,8 @@ private:
void DisposeFile();
/* 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 "Krennic.hpp"
using std::string;
using std::vector;
using namespace RDI::DatFile;
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 ) {
BuildLevelList(pErso);
BuildModelList(pErso);
@ -34,61 +51,73 @@ Krennic::~Krennic() {}
void Krennic::BuildLevelList( Erso* pErso ) {
const static std::string legacyLvlPath = "data/level";
DatFileEntryDirectory* levelDir = nullptr;
const static vector<PathDescriptor> legacyLvlPath = {
PathDescriptor("data/level", true)
};
listLevel.clear();
levelDir = dynamic_cast<DatFileEntryDirectory*>(pErso->getElement(boost::filesystem::path(legacyLvlPath)));
if (levelDir != nullptr) {
for ( DatFileEntry* fl : levelDir->getFiles() ) {
if (fl->isDirectory()) {
if (pErso->getElement(boost::filesystem::path(legacyLvlPath).append(fl->getName()).append("dat")) != nullptr) {
listLevel.push_back(legacyLvlPath + "/" + fl->getName());
}
}
for (PathDescriptor legacyLvlSubpath : legacyLvlPath) {
for (DatFileEntry* file : pErso->getElements(boost::filesystem::path(legacyLvlSubpath.path), "dat", legacyLvlSubpath.isRecursive)) {
//TODO: level-class builder
listLevel.push_back(file->getPath());
}
}
//TODO: LvlClass builder
}
void Krennic::BuildModelList( Erso* pErso ) {
const static std::vector<std::string> legacyModelPath = {
"data/pl_crafts", "data/reb_stuff", "data/imp_stuff",
"data/gnrc_stuff", "data2"
};
DatFileEntryDirectory* curModelDir = nullptr;
const static vector<PathDescriptor> legacyModelPath = {
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)
};
listModel.clear();
for ( std::string path_it : legacyModelPath ) {
curModelDir = dynamic_cast<DatFileEntryDirectory*>(pErso->getElement(boost::filesystem::path(path_it)));
if (curModelDir != nullptr) {
for ( DatFileEntry* fl : curModelDir->getFiles() ) {
if (fl->getName().find("_HOB") != std::string::npos) {
listModel.push_back(path_it + "/" + fl->getName());
}
}
for (PathDescriptor legacyModelSubpath : legacyModelPath) {
for (DatFileEntry* file : pErso->getElements(boost::filesystem::path(legacyModelSubpath.path), "_HOB", legacyModelSubpath.isRecursive)) {
//TODO: model-class builder
listModel.push_back(file->getPath());
}
}
}
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 ) {
const static std::string legacyMusicPath = "data/sound";
DatFileEntryDirectory* musicDir = nullptr;
const static vector<PathDescriptor> legacyLvlPath = {
PathDescriptor("data/sound", false)
};
listMusic.clear();
musicDir = dynamic_cast<DatFileEntryDirectory*>(pErso->getElement(boost::filesystem::path(legacyMusicPath)));
if (musicDir != nullptr) {
for ( DatFileEntry* fl : musicDir->getFiles() ) {
for (PathDescriptor legacyMusicSubpath : legacyLvlPath) {
for (DatFileEntry* file : pErso->getElements(boost::filesystem::path(legacyMusicSubpath.path), "_SNG", legacyMusicSubpath.isRecursive)) {
//TODO: MusyX-Class builder
if (fl->getName().find("_SNG") != std::string::npos) {
listMusic.push_back(legacyMusicPath + "/" + fl->getName());
}
listMusic.push_back(file->getPath());
}
}
}

View File

@ -46,11 +46,11 @@ public:
* @return File type class handler.
*/
///@{
void* getLevel( std::string name );
void* getModel( std::string name );
HMT *getTexture( std::string name );
void* getMusic( std::string name );
void* getSample( std::string name );
void* getLevel( std::string name );
void* getModel( std::string name );
HMT* getTexture( std::string name );
void* getMusic( 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();
}
std::vector<std::string> RDI::RDI_getTexturesName( void ) {
return KrennicModule->getTexturesList();
}
std::vector<std::string> RDI::RDI_getMusicsName( void ) {
return KrennicModule->getMusicsList();
}

View File

@ -49,7 +49,7 @@ int main( int argc, char *argv[] ) {
cout << "> Section found: " << RDI::RDI_getSectionCount() << endl;
for ( i = 0; i < RDI::RDI_getSectionCount(); i++ ) {
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"
@ -65,15 +65,19 @@ int main( int argc, char *argv[] ) {
// Print game elements Krennic module found
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() ) {
cout << " " << lname << endl;
}
cout << endl << "> Models found:" << endl;
cout << endl << "> Models found: " << RDI::RDI_getModelsName().size() << endl;
for ( std::string mdname : RDI::RDI_getModelsName() ) {
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() ) {
cout << " " << mname << endl;
}