HOB file management
HOB file handler prototype Mesh building should be moved to RSPModel lib Tree rendering unicode chars fix Updated version detection HOB file handler Debug HOB handler Pointer probably deallocated, need to check it Fix HOB loader and disposer Using HOB instance instead of static methods Review DLL support for MSVC build Vertices values calculation fix Added export obj method to debug tool Missed levels name separation Cleaned model processing Multithreading branch reported to later
This commit is contained in:
parent
4a0b0df410
commit
05b3c1e88a
@ -7,8 +7,8 @@
|
||||
|
||||
|
||||
# CMake requirement and general configuration
|
||||
cmake_minimum_required(VERSION 3.12)
|
||||
cmake_policy(VERSION 3.12)
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
cmake_policy(VERSION 3.15)
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_BINARY_DIR})
|
||||
if(DEFINED ENV{MS_COMPATIBLE})
|
||||
set(CMAKE_GNUtoMS ON) # Enable compatibility level to exported libraries
|
||||
@ -27,10 +27,10 @@ endif()
|
||||
set(RDI_LIB_NAME RDI)
|
||||
if(NOT MSVC)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++17 -static-libgcc -static-libstdc++")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||
else()
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Wall")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wall /std:c++17")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Wall")
|
||||
endif()
|
||||
|
||||
set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables")
|
||||
@ -43,13 +43,13 @@ option(RDI_STATIC "Build static lib" ON)
|
||||
option(BUILD_TOOLS "Build lib tools" ON)
|
||||
|
||||
# Import needed packages and references their include path
|
||||
find_package(RSPModel 2.2 REQUIRED)
|
||||
find_package(RSPModel 2.3 REQUIRED)
|
||||
include_directories(${RSPModel_INCLUDE_DIR})
|
||||
find_package(RSPTerrain 2.0 REQUIRED)
|
||||
include_directories(${RSPTerrain_INCLUDE_DIR})
|
||||
find_package(RSPTexture 2.1 REQUIRED)
|
||||
include_directories(${RSPTexture_INCLUDE_DIR})
|
||||
find_package(Boost 1.80.0 EXACT REQUIRED)
|
||||
find_package(Boost 1.81.0 REQUIRED)
|
||||
include_directories(${Boost_INCLUDE_DIR})
|
||||
add_definitions(-DBOOST_ALL_NO_LIB)
|
||||
|
||||
@ -80,14 +80,22 @@ endif()
|
||||
# Declare the shared library instance
|
||||
if(RDI_SHARED)
|
||||
add_library(rdi-lib SHARED ${RDI_LIB_SOURCES})
|
||||
set_property(TARGET rdi-lib PROPERTY C_STANDARD 90)
|
||||
set_property(TARGET rdi-lib PROPERTY C_STANDARD 17)
|
||||
set_property(TARGET rdi-lib PROPERTY CXX_STANDARD 17)
|
||||
set_property(TARGET rdi-lib PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
set_target_properties(rdi-lib PROPERTIES VERSION 1.0.0)
|
||||
|
||||
target_include_directories(rdi-lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
set_target_properties(rdi-lib PROPERTIES OUTPUT_NAME "${RDI_LIB_NAME}")
|
||||
|
||||
# As GNU-GCC have different runtime lib, we statically link them for this type of build
|
||||
if (NOT MSVC)
|
||||
target_link_libraries(rdi-lib PRIVATE
|
||||
-static-libgcc
|
||||
-static-libstdc++
|
||||
)
|
||||
endif()
|
||||
target_link_libraries(rdi-lib PRIVATE
|
||||
${RSPModel_LIBRARIES}
|
||||
${RSPTerrain_LIBRARIES}
|
||||
@ -113,11 +121,20 @@ endif()
|
||||
# Declare the static library instance
|
||||
if(RDI_STATIC)
|
||||
add_library(rdi-libstatic STATIC ${RDI_LIB_SOURCES})
|
||||
set_property(TARGET rdi-libstatic PROPERTY C_STANDARD 90)
|
||||
set_property(TARGET rdi-libstatic PROPERTY C_STANDARD 17)
|
||||
set_property(TARGET rdi-libstatic PROPERTY CXX_STANDARD 17)
|
||||
set_property(TARGET rdi-libstatic PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
|
||||
set_target_properties(rdi-libstatic PROPERTIES VERSION 1.0.0)
|
||||
|
||||
target_include_directories(rdi-libstatic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
# As GNU-GCC have different runtime lib, we statically link them for this type of build
|
||||
if (NOT MSVC)
|
||||
target_link_libraries(rdi-libstatic PRIVATE
|
||||
-static-libgcc
|
||||
-static-libstdc++
|
||||
)
|
||||
endif()
|
||||
target_link_libraries(rdi-libstatic PRIVATE
|
||||
${RSPModel_LIBRARIES}
|
||||
${RSPTerrain_LIBRARIES}
|
||||
@ -158,17 +175,20 @@ if(BUILD_TOOLS)
|
||||
|
||||
#add_executable(rdi-debug-tools ${RDI_TOOLS_SOURCES})
|
||||
add_executable(rdi-debug-tools ./tools/RDIDebug.cpp)
|
||||
set_property(TARGET rdi-debug-tools PROPERTY C_STANDARD 90)
|
||||
set_property(TARGET rdi-debug-tools PROPERTY C_STANDARD 17)
|
||||
set_property(TARGET rdi-debug-tools PROPERTY CXX_STANDARD 17)
|
||||
set_target_properties(rdi-debug-tools PROPERTIES OUTPUT_NAME "RDI-debug")
|
||||
list(APPEND RDI_TARGETS_LIST rdi-debug-tools)
|
||||
|
||||
add_executable(erso-debug-tools ./tools/ErsoDebug.cpp)
|
||||
set_property(TARGET erso-debug-tools PROPERTY C_STANDARD 90)
|
||||
set_property(TARGET erso-debug-tools PROPERTY C_STANDARD 17)
|
||||
set_property(TARGET erso-debug-tools PROPERTY CXX_STANDARD 17)
|
||||
set_target_properties(erso-debug-tools PROPERTIES OUTPUT_NAME "Erso-debug")
|
||||
list(APPEND RDI_TARGETS_LIST erso-debug-tools)
|
||||
|
||||
add_executable(krennic-debug-tools ./tools/KrennicDebug.cpp)
|
||||
set_property(TARGET krennic-debug-tools PROPERTY C_STANDARD 90)
|
||||
set_property(TARGET krennic-debug-tools PROPERTY C_STANDARD 17)
|
||||
set_property(TARGET krennic-debug-tools PROPERTY CXX_STANDARD 17)
|
||||
set_target_properties(krennic-debug-tools PROPERTIES OUTPUT_NAME "Krennic-debug")
|
||||
list(APPEND RDI_TARGETS_LIST krennic-debug-tools)
|
||||
|
||||
@ -180,6 +200,7 @@ if(BUILD_TOOLS)
|
||||
set_target_properties(krennic-debug-tools PROPERTIES IMPORT_PREFIX "lib")
|
||||
endif()
|
||||
|
||||
# Static libgcc and libstdc++ already linked in library
|
||||
if(RDI_SHARED)
|
||||
target_link_libraries(rdi-debug-tools PRIVATE rdi-lib ${Boost_LIBRARIES})
|
||||
target_link_libraries(erso-debug-tools PRIVATE rdi-lib)
|
||||
|
@ -1,8 +1,8 @@
|
||||
[requires]
|
||||
rspmodellib/2.2.0
|
||||
rspmodellib/2.3.0
|
||||
rspterrainlib/2.0.4
|
||||
rsptexturelib/2.1.0
|
||||
boost/1.80.0
|
||||
boost/1.81.0
|
||||
|
||||
[generators]
|
||||
cmake
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file GenericFile.h
|
||||
* @date 23/09/2022
|
||||
* @date 01/02/2023
|
||||
* @author JackCarterSmith
|
||||
* @copyright GPL-v3.0
|
||||
* @brief Generic file object class.
|
||||
@ -22,15 +22,38 @@ namespace DatFile {
|
||||
|
||||
class GenericFile {
|
||||
public:
|
||||
GenericFile( DatFile::DatFileEntryFile &hDat );
|
||||
// Default constructor
|
||||
// Set the default class members and link against correct MEMFILE
|
||||
GenericFile( DatFile::DatFileEntryFile* hDat );
|
||||
virtual ~GenericFile();
|
||||
|
||||
GenericFile(const GenericFile&) = default;
|
||||
GenericFile& operator=(const GenericFile&) = default;
|
||||
|
||||
GenericFile(GenericFile&&) = default;
|
||||
GenericFile& operator=(GenericFile&&) = default;
|
||||
|
||||
// Primary datas parsing/loading function
|
||||
// This function must be called to load datas in memory and access to others function
|
||||
void Load();
|
||||
bool isLoaded() const { return loaded; }
|
||||
|
||||
// Free memory of object datas
|
||||
// Should be called after using it
|
||||
void Dispose();
|
||||
|
||||
std::string getFileName() const { return fileName; }
|
||||
std::string getFullPath() const { return fullFilePath; }
|
||||
std::string getFileExtension() const { return fileExtension; }
|
||||
MEMFILE get() { return pMemLoc; }
|
||||
|
||||
protected:
|
||||
unsigned long size;
|
||||
std::string fileName, fileExtension;
|
||||
std::string fileName, fullFilePath, fileExtension;
|
||||
MEMFILE pMemLoc = nullptr;
|
||||
|
||||
private:
|
||||
bool loaded = false;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace RDI {
|
||||
|
||||
class HMT : public GenericFile {
|
||||
public:
|
||||
HMT( DatFile::DatFileEntryFile &hDat );
|
||||
HMT( DatFile::DatFileEntryFile* hDat );
|
||||
virtual ~HMT();
|
||||
};
|
||||
|
||||
|
120
include/FileHandler/HOB.h
Normal file
120
include/FileHandler/HOB.h
Normal file
@ -0,0 +1,120 @@
|
||||
/**
|
||||
* @file HOB.h
|
||||
* @date 31/01/2023
|
||||
* @author JackCarterSmith
|
||||
* @copyright GPL-v3.0
|
||||
* @brief HOB file object class.
|
||||
*
|
||||
* Rogue data files use a specific (and size optimized) storage method of model.
|
||||
* HOB handler parse these datas and store them in a more GPU-frienly BOOST-Lib
|
||||
* type.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <boost/qvm_lite.hpp>
|
||||
#include <FileHandler/Generic.h>
|
||||
|
||||
|
||||
#ifndef HOB_H_
|
||||
#define HOB_H_
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# define RDI_ABI_EXPORT __declspec(dllexport)
|
||||
# define RDI_ABI_IMPORT __declspec(dllimport)
|
||||
#elif __GNUC__ >= 4
|
||||
# define RDI_ABI_EXPORT __attribute__ ((visibility("default")))
|
||||
# define RDI_ABI_IMPORT __attribute__ ((visibility("default")))
|
||||
#else
|
||||
# define RDI_ABI_EXPORT
|
||||
# define RDI_ABI_IMPORT
|
||||
#endif
|
||||
|
||||
#if defined(RDI_DLL)
|
||||
# if defined(WIN32)
|
||||
# if defined(RDI_DLLBUILD)
|
||||
# define RDI_EXTERN RDI_ABI_EXPORT
|
||||
# else
|
||||
# define RDI_EXTERN RDI_ABI_IMPORT
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef RDI_EXTERN
|
||||
# define RDI_EXTERN
|
||||
#endif
|
||||
|
||||
namespace RDI {
|
||||
|
||||
class HOB final : public GenericFile {
|
||||
public:
|
||||
/*
|
||||
struct Vertex {
|
||||
Vertex() noexcept = default;
|
||||
Vertex(float x, float y, float z) noexcept
|
||||
: x(x),y(y),z(z) {}
|
||||
Vertex(std::array<float, 3> vArray) noexcept
|
||||
: x(vArray[0]),y(vArray[1]),z(vArray[2]) {}
|
||||
|
||||
Vertex(const Vertex&) = default;
|
||||
Vertex& operator=(const Vertex&) = default;
|
||||
|
||||
Vertex(Vertex&&) = default;
|
||||
Vertex& operator=(Vertex&&) = default;
|
||||
|
||||
float x = 0.0f, y = 0.0f, z = 0.0f;
|
||||
};
|
||||
*/
|
||||
|
||||
struct Mesh {
|
||||
// Empty vertices mesh should be considered as root/main mesh struct.
|
||||
std::vector<boost::qvm::vec<float, 3>*> vertices;
|
||||
std::vector<uint16_t> indices;
|
||||
|
||||
// Transform matrix not used for now, equal to identity matrix.
|
||||
boost::qvm::mat<float,4,4> transform;
|
||||
//Material material;
|
||||
|
||||
// Submesh are divided by material/texture
|
||||
std::vector<HOB::Mesh*> subMeshs;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
HOB( DatFile::DatFileEntryFile* hDat );
|
||||
~HOB();
|
||||
|
||||
HOB(const HOB&) = default;
|
||||
HOB& operator=(const HOB&) = default;
|
||||
|
||||
HOB(HOB&&) = default;
|
||||
HOB& operator=(HOB&&) = default;
|
||||
|
||||
// Mandatory function from base class
|
||||
RDI_EXTERN void Load();
|
||||
RDI_EXTERN void Dispose();
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
RDI_EXTERN unsigned int getObjectCount() const;
|
||||
RDI_EXTERN std::string* getObjectName( unsigned short index ) const;
|
||||
|
||||
RDI_EXTERN HOB::Mesh* getMeshFromObject( unsigned short index ) const;
|
||||
RDI_EXTERN HOB::Mesh* getMeshFromObject( std::string name ) const;
|
||||
|
||||
//ObjectMaterials getMaterialFromObject( unsigned short index, unsigned short materialIndex );
|
||||
//ObjectMaterials getMaterialFromObject( std::string name, unsigned short materialIndex );
|
||||
//std::vector<ObjectMaterials> getMaterialsFromObject( unsigned short index );
|
||||
//std::vector<ObjectMaterials> getMaterialsFromObject( std::string name );
|
||||
|
||||
|
||||
private:
|
||||
void* hobInstance = nullptr;
|
||||
unsigned int objCnt = 0;
|
||||
std::unordered_map<std::string, HOB::Mesh*> objectMeshList; // Each object mesh ordered by index
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif /* HOB_H_ */
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file RDI.hpp
|
||||
* @date 24/09/2022
|
||||
* @date 22/01/2023
|
||||
* @author JackCarterSmith
|
||||
* @copyright GPL-v3.0
|
||||
* @brief Rogue Data Interface library main entry file.
|
||||
@ -10,6 +10,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "RDI_Datatypes.h"
|
||||
#include "FileHandler/HOB.h"
|
||||
|
||||
|
||||
#ifndef RDI_HPP_
|
||||
@ -48,7 +49,7 @@ namespace RDI {
|
||||
* @brief Get the current library version.
|
||||
* @return String of the version.
|
||||
*/
|
||||
RDI_EXTERN std::string RDI_getLibVersion( void );
|
||||
RDI_EXTERN const std::string RDI_getLibVersion( void ) noexcept;
|
||||
|
||||
/**
|
||||
* @brief Allocate memory and create default structure to access datas.
|
||||
@ -58,20 +59,26 @@ namespace RDI {
|
||||
*/
|
||||
RDI_EXTERN void RDI_Init( std::string roguePath );
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* Erso specific methods */
|
||||
RDI_EXTERN unsigned char RDI_getSectionCount( void );
|
||||
RDI_EXTERN std::string RDI_getSectionName( unsigned char id );
|
||||
RDI_EXTERN unsigned int RDI_getSectionOffset( unsigned char id );
|
||||
RDI_EXTERN const unsigned char RDI_getSectionCount( void );
|
||||
RDI_EXTERN const std::string RDI_getSectionName( unsigned char id );
|
||||
RDI_EXTERN const unsigned int RDI_getSectionOffset( unsigned char id );
|
||||
|
||||
RDI_EXTERN unsigned int RDI_getDirectoryElementCount( std::string path );
|
||||
RDI_EXTERN std::vector<std::string> RDI_getDirectoryElements( std::string path );
|
||||
RDI_EXTERN bool RDI_isElementDirectory( std::string path );
|
||||
RDI_EXTERN const unsigned int RDI_getDirectoryElementCount( std::string path );
|
||||
RDI_EXTERN const std::vector<std::string> RDI_getDirectoryElements( std::string path );
|
||||
RDI_EXTERN const bool RDI_isElementDirectory( std::string path );
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
/* 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 );
|
||||
RDI_EXTERN const std::vector<std::string> RDI_getLevelsName( void );
|
||||
RDI_EXTERN const std::vector<std::string> RDI_getModelsName( void );
|
||||
RDI_EXTERN const std::vector<std::string> RDI_getTexturesName( void );
|
||||
RDI_EXTERN const std::vector<std::string> RDI_getMusicsName( void );
|
||||
|
||||
RDI_EXTERN HOB* RDI_getModel( std::string modelName );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Clean up global resources.
|
||||
|
@ -59,13 +59,14 @@ public:
|
||||
MEMFILE getRDat() const { return rDatPtr; }
|
||||
|
||||
/* Workspace management */
|
||||
std::string getWorkingDirectory() { return workingDir; }
|
||||
std::string getWorkingDirectory() const { return workingDir; }
|
||||
RDI_RESULT setWorkingDirectory( std::string newPath );
|
||||
|
||||
/* Generals informations getters */
|
||||
unsigned char getDataSectionCount() const { return cDatSection; }
|
||||
std::string getDataSectionName( unsigned char id ) const;
|
||||
unsigned int getDataSectionOffset( unsigned char id ) const;
|
||||
bool isUpdatedVersion() const { return (cDatSection > 2); }
|
||||
|
||||
/* Tree manipulation/parse methods */
|
||||
DatFile::DatFileEntry* getElement( boost::filesystem::path virtualDirPath );
|
||||
|
122
src/Krennic.cpp
122
src/Krennic.cpp
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file Krennic.cpp
|
||||
* @date 24/09/2022
|
||||
* @date 18/09/2023
|
||||
* @author JackCarterSmith
|
||||
* @copyright GPL-v3.0
|
||||
* @brief Main game assets parser and interface.
|
||||
@ -10,15 +10,22 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <RSPModel.h>
|
||||
#include <RSPTerrain.h>
|
||||
#include <RSPTexture.h>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <FileHandler/Generic.h>
|
||||
#include <FileHandler/HMT.h>
|
||||
#include <FileHandler/HOB.h>
|
||||
#include "Erso.hpp"
|
||||
#include "Krennic.hpp"
|
||||
|
||||
using std::string;
|
||||
using std::vector;
|
||||
using std::array;
|
||||
|
||||
using namespace RDI::DatFile;
|
||||
|
||||
@ -40,32 +47,32 @@ struct PathDescriptor {
|
||||
};
|
||||
|
||||
Krennic::Krennic( Erso* pErso ) {
|
||||
BuildLevelList(pErso);
|
||||
BuildModelList(pErso);
|
||||
BuildTextureList(pErso);
|
||||
BuildMusicList(pErso);
|
||||
BuildSampleList(pErso);
|
||||
BuildLevelFileList(pErso);
|
||||
BuildModelFileList(pErso);
|
||||
BuildTextureFileList(pErso);
|
||||
BuildMusicFileList(pErso);
|
||||
BuildSampleFileList(pErso);
|
||||
}
|
||||
|
||||
Krennic::~Krennic() {}
|
||||
|
||||
|
||||
void Krennic::BuildLevelList( Erso* pErso ) {
|
||||
const static vector<PathDescriptor> legacyLvlPath = {
|
||||
void Krennic::BuildLevelFileList( Erso* pErso ) {
|
||||
const static array<PathDescriptor, 1> legacyLvlPath = {
|
||||
PathDescriptor("data/level", true)
|
||||
};
|
||||
|
||||
listLevel.clear();
|
||||
listLevelsName.clear();
|
||||
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());
|
||||
listLevelsName.push_back(file->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Krennic::BuildModelList( Erso* pErso ) {
|
||||
const static vector<PathDescriptor> legacyModelPath = {
|
||||
void Krennic::BuildModelFileList( Erso* pErso ) {
|
||||
const static array<PathDescriptor, 9> legacyModelPath = {
|
||||
PathDescriptor("data", false),
|
||||
PathDescriptor("data/pl_crafts", false),
|
||||
PathDescriptor("data/reb_stuff", false),
|
||||
@ -74,20 +81,36 @@ void Krennic::BuildModelList( Erso* pErso ) {
|
||||
PathDescriptor("data/level", true),
|
||||
PathDescriptor("data/frontend", true),
|
||||
PathDescriptor("data/dbg", false),
|
||||
PathDescriptor("dbg_data", false)
|
||||
};
|
||||
// Update version game legacy assets paths
|
||||
const static array<PathDescriptor, 1> legacyModelPath2= {
|
||||
PathDescriptor("data2", false)
|
||||
};
|
||||
|
||||
listModel.clear();
|
||||
listModels.clear();
|
||||
listModelsName.clear();
|
||||
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());
|
||||
auto hobObj = new HOB(dynamic_cast<DatFileEntryFile*>(file));
|
||||
listModels.push_back(hobObj);
|
||||
listModelsName.push_back(file->getPath());
|
||||
}
|
||||
}
|
||||
if (pErso->isUpdatedVersion()) {
|
||||
for (PathDescriptor legacyModelSubpath2 : legacyModelPath2) {
|
||||
for (DatFileEntry* file : pErso->getElements(boost::filesystem::path(legacyModelSubpath2.path), "_HOB", legacyModelSubpath2.isRecursive)) {
|
||||
auto hobObj = new HOB(dynamic_cast<DatFileEntryFile*>(file));
|
||||
listModels.push_back(hobObj);
|
||||
listModelsName.push_back(file->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Krennic::BuildTextureList( Erso* pErso ) {
|
||||
const static vector<PathDescriptor> legacyTexturePath = {
|
||||
void Krennic::BuildTextureFileList( Erso* pErso ) {
|
||||
// Base game legacy assets paths
|
||||
const static array<PathDescriptor, 9> legacyTexturePath = {
|
||||
PathDescriptor("data", false),
|
||||
PathDescriptor("data/pl_crafts", false),
|
||||
PathDescriptor("data/reb_stuff", false),
|
||||
@ -96,34 +119,85 @@ void Krennic::BuildTextureList( Erso* pErso ) {
|
||||
PathDescriptor("data/level", true),
|
||||
PathDescriptor("data/frontend", true),
|
||||
PathDescriptor("data/dbg", false),
|
||||
PathDescriptor("dbg_data", false)
|
||||
};
|
||||
// Update version game legacy assets paths
|
||||
const static array<PathDescriptor, 1> legacyTexturePath2= {
|
||||
PathDescriptor("data2", false)
|
||||
};
|
||||
|
||||
listTexture.clear();
|
||||
listTexturesName.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());
|
||||
listTexturesName.push_back(file->getPath());
|
||||
}
|
||||
}
|
||||
if (pErso->isUpdatedVersion()) {
|
||||
for (PathDescriptor legacyTextureSubpath2 : legacyTexturePath2) {
|
||||
for (DatFileEntry* file : pErso->getElements(boost::filesystem::path(legacyTextureSubpath2.path), "_HMT", legacyTextureSubpath2.isRecursive)) {
|
||||
//TODO: texture-class builder
|
||||
listTexturesName.push_back(file->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Krennic::BuildMusicList( Erso* pErso ) {
|
||||
const static vector<PathDescriptor> legacyLvlPath = {
|
||||
void Krennic::BuildMusicFileList( Erso* pErso ) {
|
||||
const static array<PathDescriptor, 1> legacyLvlPath = {
|
||||
PathDescriptor("data/sound", false)
|
||||
};
|
||||
|
||||
listMusic.clear();
|
||||
listMusicsName.clear();
|
||||
for (PathDescriptor legacyMusicSubpath : legacyLvlPath) {
|
||||
for (DatFileEntry* file : pErso->getElements(boost::filesystem::path(legacyMusicSubpath.path), "_SNG", legacyMusicSubpath.isRecursive)) {
|
||||
//TODO: MusyX-Class builder
|
||||
listMusic.push_back(file->getPath());
|
||||
listMusicsName.push_back(file->getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Krennic::BuildSampleList( Erso* pErso ) {
|
||||
void Krennic::BuildSampleFileList( Erso* pErso ) {
|
||||
|
||||
}
|
||||
|
||||
//void* Krennic::getLevel( std::string name ) {}
|
||||
|
||||
HOB* Krennic::getModel( string name ) {
|
||||
unsigned int i = 0;
|
||||
|
||||
for (string fileName : listModelsName) {
|
||||
if (fileName.find(name) != string::npos) {
|
||||
return listModels.at(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
throw std::invalid_argument("Krennic can't found the requested model.");
|
||||
}
|
||||
|
||||
//HMT* Krennic::getTexture( std::string name ) {}
|
||||
|
||||
//void* Krennic::getMusic( std::string name ) {}
|
||||
|
||||
//void* Krennic::getSample( std::string name ) {}
|
||||
|
||||
|
||||
void Krennic::DisposeLevels() {}
|
||||
|
||||
void Krennic::DisposeModels() {
|
||||
for (HOB* hobObj : listModels) {
|
||||
if (hobObj->isLoaded())
|
||||
hobObj->Dispose();
|
||||
|
||||
delete hobObj;
|
||||
}
|
||||
}
|
||||
|
||||
void Krennic::DisposeTextures() {}
|
||||
|
||||
void Krennic::DisposeMusics() {}
|
||||
|
||||
void Krennic::DisposeSamples() {}
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file Krennic.hpp
|
||||
* @date 24/09/2022
|
||||
* @date 18/01/2023
|
||||
* @author JackCarterSmith
|
||||
* @copyright GPL-v3.0
|
||||
* @brief Main game assets parser and interface.
|
||||
@ -15,6 +15,7 @@
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <FileHandler/Generic.h>
|
||||
#include <FileHandler/HMT.h>
|
||||
#include <FileHandler/HOB.h>
|
||||
#include "Erso.hpp"
|
||||
|
||||
|
||||
@ -33,11 +34,11 @@ public:
|
||||
* @return Array of filtered elements.
|
||||
*/
|
||||
///@{
|
||||
std::vector<std::string> getLevelsList() { return listLevel; }
|
||||
std::vector<std::string> getModelsList() { return listModel; }
|
||||
std::vector<std::string> getTexturesList() { return listTexture; }
|
||||
std::vector<std::string> getMusicsList() { return listMusic; }
|
||||
std::vector<std::string> getSamplesList() { return listSample; }
|
||||
std::vector<std::string> getLevelsList() { return listLevelsName; }
|
||||
std::vector<std::string> getModelsList() { return listModelsName; }
|
||||
std::vector<std::string> getTexturesList() { return listTexturesName; }
|
||||
std::vector<std::string> getMusicsList() { return listMusicsName; }
|
||||
std::vector<std::string> getSamplesList() { return listSamplesName; }
|
||||
///@}
|
||||
|
||||
/**
|
||||
@ -47,7 +48,7 @@ public:
|
||||
*/
|
||||
///@{
|
||||
void* getLevel( std::string name );
|
||||
void* getModel( std::string name );
|
||||
HOB* getModel( std::string name );
|
||||
HMT* getTexture( std::string name );
|
||||
void* getMusic( std::string name );
|
||||
void* getSample( std::string name );
|
||||
@ -64,17 +65,25 @@ public:
|
||||
GenericFile *getFile( boost::filesystem::path vPath );
|
||||
|
||||
private:
|
||||
std::vector<std::string> listLevel;
|
||||
std::vector<std::string> listModel;
|
||||
std::vector<std::string> listTexture;
|
||||
std::vector<std::string> listMusic;
|
||||
std::vector<std::string> listSample;
|
||||
std::vector<HOB*> listModels;
|
||||
|
||||
void BuildLevelList( Erso* pErso );
|
||||
void BuildModelList( Erso* pErso );
|
||||
void BuildTextureList( Erso* pErso );
|
||||
void BuildMusicList( Erso* pErso );
|
||||
void BuildSampleList( Erso* pErso );
|
||||
std::vector<std::string> listLevelsName;
|
||||
std::vector<std::string> listModelsName;
|
||||
std::vector<std::string> listTexturesName;
|
||||
std::vector<std::string> listMusicsName;
|
||||
std::vector<std::string> listSamplesName;
|
||||
|
||||
void BuildLevelFileList( Erso* pErso );
|
||||
void BuildModelFileList( Erso* pErso );
|
||||
void BuildTextureFileList( Erso* pErso );
|
||||
void BuildMusicFileList( Erso* pErso );
|
||||
void BuildSampleFileList( Erso* pErso );
|
||||
|
||||
void DisposeLevels();
|
||||
void DisposeModels();
|
||||
void DisposeTextures();
|
||||
void DisposeMusics();
|
||||
void DisposeSamples();
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file GenericFile.cpp
|
||||
* @date 23/09/2022
|
||||
* @date 01/02/2023
|
||||
* @author JackCarterSmith
|
||||
* @copyright GPL-v3.0
|
||||
* @brief Generic file object class.
|
||||
@ -16,13 +16,12 @@ using namespace RDI::DatFile;
|
||||
|
||||
namespace RDI {
|
||||
|
||||
GenericFile::GenericFile( DatFile::DatFileEntryFile &hDat ) {
|
||||
this->size = hDat.getSize();
|
||||
this->fileName = hDat.getName();
|
||||
this->fileExtension = "";
|
||||
this->pMemLoc = hDat.getDatas();
|
||||
}
|
||||
GenericFile::GenericFile( DatFile::DatFileEntryFile* hDat )
|
||||
: size(hDat->getSize()), fileName(hDat->getName()), fullFilePath(hDat->getPath()), pMemLoc(hDat->getDatas()) {}
|
||||
|
||||
GenericFile::~GenericFile() {}
|
||||
|
||||
void GenericFile::Load() { this->loaded = true; }
|
||||
void GenericFile::Dispose() { this->loaded = false; }
|
||||
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ using namespace RDI::DatFile;
|
||||
|
||||
namespace RDI {
|
||||
|
||||
HMT::HMT( DatFile::DatFileEntryFile &hDat ): GenericFile( hDat ) {
|
||||
HMT::HMT( DatFile::DatFileEntryFile* hDat ): GenericFile( hDat ) {
|
||||
this->fileExtension = "hmt";
|
||||
}
|
||||
|
||||
|
189
src/KrennicHandlerHOB.cpp
Normal file
189
src/KrennicHandlerHOB.cpp
Normal file
@ -0,0 +1,189 @@
|
||||
/**
|
||||
* @file KrennicHandlerHOB.cpp
|
||||
* @date 19/01/2023
|
||||
* @author JackCarterSmith
|
||||
* @copyright GPL-v3.0
|
||||
* @brief HOB file object class.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
#include <stdexcept>
|
||||
#include <boost/qvm_lite.hpp>
|
||||
#include <RSPModel.h>
|
||||
#include <RSPModel_errordefs.h>
|
||||
#include "DatFileEntry.hpp"
|
||||
#include <FileHandler/Generic.h>
|
||||
#include <FileHandler/HOB.h>
|
||||
|
||||
using std::runtime_error;
|
||||
using std::out_of_range;
|
||||
using std::invalid_argument;
|
||||
using std::string;
|
||||
using namespace RDI::DatFile;
|
||||
using namespace boost::qvm;
|
||||
|
||||
|
||||
namespace RDI {
|
||||
|
||||
HOB::Mesh* BuildObjectMesh( const T_RSPMODEL_OBJECT* hobPtr );
|
||||
HOB::Mesh* FillMesh( const T_RSPMODEL_OBJ_PARTS* objPtr );
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
HOB::HOB( DatFileEntryFile* hDat )
|
||||
: GenericFile(hDat) {
|
||||
this->fileExtension = "hob";
|
||||
}
|
||||
|
||||
HOB::~HOB() {
|
||||
Dispose();
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void HOB::Load() {
|
||||
unsigned int i;
|
||||
RSPMODEL_PARAMETERS rspParams;
|
||||
unsigned short result = RSPLIB_SUCCESS;
|
||||
|
||||
if (this->isLoaded()) return;
|
||||
|
||||
this->hobInstance = new T_RSPMODEL_HOB{};
|
||||
auto hobInstancePtr = static_cast<T_RSPMODEL_HOB*>(this->hobInstance);
|
||||
rspParams.raw = 0;
|
||||
result = RSPModel_processHOBFileMemory(hobInstancePtr, this->pMemLoc, this->size, rspParams);
|
||||
if (result != RSPLIB_SUCCESS) {
|
||||
RSPModel_freeHOB(static_cast<T_RSPMODEL_HOB*>(this->hobInstance));
|
||||
delete static_cast<T_RSPMODEL_HOB*>(this->hobInstance);
|
||||
|
||||
if (result == RSPLIB_ERROR_GENERIC)
|
||||
throw out_of_range("HOB handler tried to process empty file.");
|
||||
else
|
||||
throw runtime_error("HOB handler processing failed with error: " + std::to_string(result));
|
||||
}
|
||||
|
||||
this->objCnt = hobInstancePtr->obj_count;
|
||||
this->objectMeshList.clear();
|
||||
for ( i = 0; i < this->objCnt; i++ )
|
||||
this->objectMeshList[string(hobInstancePtr->objects[i].name)] = BuildObjectMesh(hobInstancePtr->objects + i);
|
||||
|
||||
RSPModel_freeHOB(static_cast<T_RSPMODEL_HOB*>(this->hobInstance));
|
||||
|
||||
// Must be called last to set loaded state
|
||||
GenericFile::Load();
|
||||
}
|
||||
|
||||
void HOB::Dispose() {
|
||||
if (!this->isLoaded()) return;
|
||||
|
||||
for ( const auto& [objName, objMesh] : this->objectMeshList ) {
|
||||
for ( auto v : objMesh->vertices)
|
||||
delete v;
|
||||
|
||||
for ( auto sm : objMesh->subMeshs)
|
||||
delete sm;
|
||||
|
||||
delete objMesh;
|
||||
}
|
||||
|
||||
this->objectMeshList.clear();
|
||||
delete static_cast<T_RSPMODEL_HOB*>(this->hobInstance);
|
||||
|
||||
// Must be called last to unset loaded state
|
||||
GenericFile::Dispose();
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
unsigned int HOB::getObjectCount() const {
|
||||
if (this->isLoaded())
|
||||
return this->objCnt;
|
||||
|
||||
return RSPModel_getHOBFileMemObjCount(this->pMemLoc);
|
||||
}
|
||||
|
||||
std::string* HOB::getObjectName( unsigned short index ) const {
|
||||
if (!this->isLoaded())
|
||||
throw runtime_error("HOB handler has not been loaded prior to function calling.");
|
||||
|
||||
if (index >= this->objCnt)
|
||||
throw out_of_range("HOB handler object index out of range!");
|
||||
|
||||
auto entry = objectMeshList.begin();
|
||||
std::advance(entry, index);
|
||||
return new string(entry->first);
|
||||
}
|
||||
|
||||
HOB::Mesh* HOB::getMeshFromObject( unsigned short index ) const {
|
||||
if (!this->isLoaded())
|
||||
throw runtime_error("HOB handler has not been loaded prior to function calling.");
|
||||
|
||||
if (index >= this->objCnt)
|
||||
throw out_of_range("HOB handler object index out of range!");
|
||||
|
||||
auto entry = objectMeshList.begin();
|
||||
std::advance(entry, index);
|
||||
return entry->second;
|
||||
}
|
||||
|
||||
HOB::Mesh* HOB::getMeshFromObject( string name ) const {
|
||||
if (!this->isLoaded())
|
||||
throw runtime_error("HOB handler has not been loaded prior to function calling.");
|
||||
|
||||
for ( const auto& [objName, objMesh] : this->objectMeshList )
|
||||
if (objName == name) return objMesh;
|
||||
|
||||
throw invalid_argument("HOB handler can't find requested object name.");
|
||||
}
|
||||
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
HOB::Mesh* BuildObjectMesh( const T_RSPMODEL_OBJECT* hobPtr ) {
|
||||
unsigned int i;
|
||||
auto meshObj = new HOB::Mesh();
|
||||
|
||||
meshObj->indices.clear();
|
||||
meshObj->vertices.clear();
|
||||
meshObj->subMeshs.clear();
|
||||
|
||||
meshObj->transform = identity_mat<float, 4>();
|
||||
for (i = 0; i < hobPtr->object_part_count; i++)
|
||||
meshObj->subMeshs.push_back(FillMesh(hobPtr->object_parts + i));
|
||||
|
||||
return meshObj;
|
||||
}
|
||||
|
||||
HOB::Mesh* FillMesh( const T_RSPMODEL_OBJ_PARTS* objPtr ) {
|
||||
unsigned int i;
|
||||
auto meshObj = new HOB::Mesh();
|
||||
|
||||
meshObj->indices.clear();
|
||||
meshObj->vertices.clear();
|
||||
meshObj->subMeshs.clear();
|
||||
|
||||
//meshObj->transform = mat<float,4,4>();
|
||||
meshObj->transform = identity_mat<float, 4>();
|
||||
for (i = 0; i < objPtr->vertex_count; i++) {
|
||||
auto v = new vec<float, 3>();
|
||||
v->a[0] = static_cast<float>(-(objPtr->vertices[i].x)) / 1024.0;
|
||||
v->a[1] = static_cast<float>(-(objPtr->vertices[i].y)) / 1024.0;
|
||||
v->a[2] = static_cast<float>((objPtr->vertices[i].z)) / 1024.0;
|
||||
meshObj->vertices.push_back(v);
|
||||
}
|
||||
for (i = 0; i < objPtr->face_count; i++) {
|
||||
meshObj->indices.push_back(static_cast<uint16_t>(objPtr->faces[i].indices[0]));
|
||||
meshObj->indices.push_back(static_cast<uint16_t>(objPtr->faces[i].indices[1]));
|
||||
meshObj->indices.push_back(static_cast<uint16_t>(objPtr->faces[i].indices[2]));
|
||||
|
||||
if (objPtr->faces[i].flags_bits.fIsQuad) {
|
||||
meshObj->indices.push_back(static_cast<uint16_t>(objPtr->faces[i].indices[2]));
|
||||
meshObj->indices.push_back(static_cast<uint16_t>(objPtr->faces[i].indices[3]));
|
||||
meshObj->indices.push_back(static_cast<uint16_t>(objPtr->faces[i].indices[0]));
|
||||
}
|
||||
}
|
||||
|
||||
return meshObj;
|
||||
}
|
||||
|
||||
}
|
48
src/RDI.cpp
48
src/RDI.cpp
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file RDI.cpp
|
||||
* @date 24/09/2022
|
||||
* @date 22/01/2023
|
||||
* @author JackCarterSmith
|
||||
* @copyright GPL-v3.0
|
||||
* @brief Rogue Data Interface library main entry abstraction file.
|
||||
@ -15,10 +15,13 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
#include <RSPModel.h> // Only for version getting, no processing.
|
||||
#include "config.h"
|
||||
#include "Erso.hpp"
|
||||
#include "DatFileEntry.hpp"
|
||||
#include "Krennic.hpp"
|
||||
#include <FileHandler/HOB.h>
|
||||
#include "RDI.hpp"
|
||||
|
||||
using namespace RDI::DatFile;
|
||||
@ -34,12 +37,12 @@ static RDI::Krennic *KrennicModule = nullptr;
|
||||
/*
|
||||
* Libs interface
|
||||
*/
|
||||
std::string RDI::RDI_getLibVersion() { return PRG_VERSION; }
|
||||
const std::string RDI::RDI_getLibVersion() noexcept { return PRG_VERSION; }
|
||||
|
||||
void RDI::RDI_Init( std::string roguePath ) {
|
||||
#ifdef DEBUG
|
||||
std::cout << std::endl << "Running RDI v" << RDI_getLibVersion() << std::endl;
|
||||
std::cout << "> RSPModelLib v" << "N/A" << std::endl;
|
||||
#ifndef NDEBUG
|
||||
std::cout << std::endl << "Running RDI v" << std::string(RDI::RDI_getLibVersion()) << std::endl;
|
||||
std::cout << "> RSPModelLib v" << std::string(RSPModel_getVersion()) << std::endl;
|
||||
std::cout << "> RSPTerrainLib v" << "N/A" << std::endl;
|
||||
std::cout << "> RSPTextureLib v" << "N/A" << std::endl;
|
||||
#endif
|
||||
@ -47,7 +50,7 @@ void RDI::RDI_Init( std::string roguePath ) {
|
||||
// Create new instance of Erso module
|
||||
// Load and extract datas files from DATA.DAT
|
||||
if (ErsoModule == nullptr) {
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
std::cout << "[RDI][DBG] Loading Erso module..." << std::endl;
|
||||
#endif
|
||||
ErsoModule = new RDI::Erso(roguePath);
|
||||
@ -56,7 +59,7 @@ void RDI::RDI_Init( std::string roguePath ) {
|
||||
// Create new instance of Krennic module
|
||||
// Process datas from Erso and build new dataset to be used outside this library
|
||||
if (ErsoModule != nullptr && KrennicModule == nullptr) {
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
std::cout << "[RDI][DBG] Loading Krennic module..." << std::endl;
|
||||
#endif
|
||||
KrennicModule = new RDI::Krennic(ErsoModule);
|
||||
@ -68,23 +71,23 @@ void RDI::RDI_Init( std::string roguePath ) {
|
||||
|
||||
|
||||
|
||||
unsigned char RDI::RDI_getSectionCount() {
|
||||
const unsigned char RDI::RDI_getSectionCount() {
|
||||
if (ErsoModule == nullptr) return 0;
|
||||
else return ErsoModule->getDataSectionCount();
|
||||
}
|
||||
|
||||
std::string RDI::RDI_getSectionName( unsigned char id ) {
|
||||
const std::string RDI::RDI_getSectionName( unsigned char id ) {
|
||||
if (ErsoModule == nullptr) return "";
|
||||
else return ErsoModule->getDataSectionName(id);
|
||||
}
|
||||
|
||||
unsigned int RDI::RDI_getSectionOffset( unsigned char id ) {
|
||||
const unsigned int RDI::RDI_getSectionOffset( unsigned char id ) {
|
||||
if (ErsoModule == nullptr) return 0;
|
||||
else return ErsoModule->getDataSectionOffset(id);
|
||||
}
|
||||
|
||||
|
||||
unsigned int RDI::RDI_getDirectoryElementCount( std::string path ) {
|
||||
const unsigned int RDI::RDI_getDirectoryElementCount( std::string path ) {
|
||||
DatFileEntryDirectory* result = nullptr;
|
||||
|
||||
if (path.empty()) return 0;
|
||||
@ -95,7 +98,7 @@ unsigned int RDI::RDI_getDirectoryElementCount( std::string path ) {
|
||||
else return result->getSize();
|
||||
}
|
||||
|
||||
std::vector<std::string> RDI::RDI_getDirectoryElements( std::string path ) {
|
||||
const std::vector<std::string> RDI::RDI_getDirectoryElements( std::string path ) {
|
||||
DatFileEntryDirectory* de = nullptr;
|
||||
std::vector<std::string> elementsNameArray;
|
||||
elementsNameArray.clear();
|
||||
@ -112,7 +115,7 @@ std::vector<std::string> RDI::RDI_getDirectoryElements( std::string path ) {
|
||||
return elementsNameArray;
|
||||
}
|
||||
|
||||
bool RDI::RDI_isElementDirectory( std::string path ) {
|
||||
const bool RDI::RDI_isElementDirectory( std::string path ) {
|
||||
DatFileEntry* result = nullptr;
|
||||
|
||||
if (path.empty()) return false;
|
||||
@ -124,22 +127,33 @@ bool RDI::RDI_isElementDirectory( std::string path ) {
|
||||
}
|
||||
|
||||
|
||||
std::vector<std::string> RDI::RDI_getLevelsName( void ) {
|
||||
/* -------------------------------------------------------------------------- */
|
||||
const std::vector<std::string> RDI::RDI_getLevelsName( void ) {
|
||||
return KrennicModule->getLevelsList();
|
||||
}
|
||||
|
||||
std::vector<std::string> RDI::RDI_getModelsName( void ) {
|
||||
const std::vector<std::string> RDI::RDI_getModelsName( void ) {
|
||||
return KrennicModule->getModelsList();
|
||||
}
|
||||
|
||||
std::vector<std::string> RDI::RDI_getTexturesName( void ) {
|
||||
const std::vector<std::string> RDI::RDI_getTexturesName( void ) {
|
||||
return KrennicModule->getTexturesList();
|
||||
}
|
||||
|
||||
std::vector<std::string> RDI::RDI_getMusicsName( void ) {
|
||||
const std::vector<std::string> RDI::RDI_getMusicsName( void ) {
|
||||
return KrennicModule->getMusicsList();
|
||||
}
|
||||
|
||||
RDI::HOB* RDI::RDI_getModel( std::string modelName ) {
|
||||
try {
|
||||
return KrennicModule->getModel(modelName);
|
||||
}
|
||||
catch (std::invalid_argument const &ex) { // Can't find model, incorrect name?
|
||||
throw std::invalid_argument(ex);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
void RDI::RDI_CleanUp(){
|
||||
if (KrennicModule) delete KrennicModule;
|
||||
if (ErsoModule) delete ErsoModule;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**
|
||||
* @file RDIDebug.cpp
|
||||
* @date 12/01/2023
|
||||
* @date 01/02/2023
|
||||
* @author JackCarterSmith
|
||||
* @copyright GPL-v3.0
|
||||
* @brief Debug app to test functions of RDI library.
|
||||
@ -8,31 +8,249 @@
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#ifdef USE_MULTITHREADING
|
||||
#include <deque>
|
||||
#include <thread>
|
||||
#endif
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <RDI.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
using namespace boost::filesystem;
|
||||
using namespace std;
|
||||
|
||||
|
||||
void PrintVirtualDirectoryContents( path, string, bool );
|
||||
static vector<RDI::HOB*> modelCollection;
|
||||
|
||||
static void PrintVirtualDirectoryContents( path p, bool unicode, string outPrefix = "" ) {
|
||||
auto curDirElementsName = RDI::RDI_getDirectoryElements(p.string());
|
||||
auto newPath = path(p);
|
||||
auto newOutPrefix = string(outPrefix);
|
||||
|
||||
for ( string eName : curDirElementsName ) {
|
||||
newPath.clear();
|
||||
newPath.concat(p);
|
||||
newOutPrefix.clear();
|
||||
newOutPrefix.append(outPrefix);
|
||||
|
||||
newPath.append(eName);
|
||||
if (RDI::RDI_isElementDirectory(newPath.string())) {
|
||||
if (unicode) {
|
||||
if (*--curDirElementsName.end() == eName) {
|
||||
cout << outPrefix << "\u2514 " << eName << endl;
|
||||
newOutPrefix.append(" ");
|
||||
} else {
|
||||
cout << outPrefix << "\u251C " << eName << endl;
|
||||
newOutPrefix.append("\u2502 ");
|
||||
}
|
||||
} else {
|
||||
if (*--curDirElementsName.end() == eName) {
|
||||
cout << outPrefix << "\\ " << eName << endl;
|
||||
newOutPrefix.append(" ");
|
||||
} else {
|
||||
cout << outPrefix << "\\ " << eName << endl;
|
||||
newOutPrefix.append("| ");
|
||||
}
|
||||
}
|
||||
PrintVirtualDirectoryContents(newPath, unicode, newOutPrefix);
|
||||
} else {
|
||||
if (unicode) {
|
||||
if (*--curDirElementsName.end() == eName)
|
||||
cout << newOutPrefix << "\u2514 " << eName << endl;
|
||||
else
|
||||
cout << newOutPrefix << "\u251C " << eName << endl;
|
||||
} else {
|
||||
cout << newOutPrefix << "+ " << eName << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintModel( const RDI::HOB::Mesh* mesh, string prefix = "" ) {
|
||||
if (mesh == nullptr)
|
||||
return;
|
||||
|
||||
string newPrefix = string(prefix);
|
||||
|
||||
for ( auto submesh : mesh->subMeshs ) {
|
||||
for ( auto v : submesh->vertices )
|
||||
cout << "[ " << v->a[0] << "; " << v->a[1] << "; " << v->a[2] << " ]" << endl;
|
||||
|
||||
newPrefix.append(" ");
|
||||
PrintModel(submesh, newPrefix);
|
||||
}
|
||||
}
|
||||
|
||||
static void GenerateModelOBJ( const RDI::HOB::Mesh* mesh, const string outFolder, const string* name ) {
|
||||
if (mesh == nullptr || name == nullptr || outFolder.empty())
|
||||
return;
|
||||
|
||||
unsigned long i, i_offset = 0;
|
||||
|
||||
ofstream objFile(".\\objOut\\" + outFolder + "\\" + (*name) + ".obj");
|
||||
|
||||
for ( auto submesh : mesh->subMeshs ) {
|
||||
for ( auto v : submesh->vertices ) {
|
||||
objFile << "v " << v->a[0] << " " << v->a[1] << " " << v->a[2] << endl;
|
||||
}
|
||||
objFile << endl;
|
||||
for ( i = 0; i < submesh->indices.size(); i += 3 ) {
|
||||
objFile << "f " << submesh->indices[i]+i_offset+1;
|
||||
objFile << " " << submesh->indices[i+1]+i_offset+1;
|
||||
objFile << " " << submesh->indices[i+2]+i_offset+1 << endl;
|
||||
}
|
||||
objFile << endl;
|
||||
|
||||
i_offset += submesh->vertices.size();
|
||||
}
|
||||
|
||||
objFile.close();
|
||||
}
|
||||
|
||||
#ifdef USE_MULTITHREADING
|
||||
static void GenerateModelOBJThreaded() {
|
||||
unsigned int i, successCnt;
|
||||
deque<thread*> process;
|
||||
const unsigned int maxThreads = thread::hardware_concurrency();
|
||||
|
||||
if (modelCollection.empty())
|
||||
return;
|
||||
|
||||
#ifdef _WIN32
|
||||
CreateDirectory(".\\objOut", NULL);
|
||||
#else
|
||||
mkdir("./objOut");
|
||||
#endif
|
||||
|
||||
for ( RDI::HOB* hobFile : modelCollection ) {
|
||||
successCnt = 0;
|
||||
cout << " Processing " << hobFile->getFullPath() << "..." << endl;
|
||||
if (hobFile->isLoaded() && (hobFile->getObjectCount() > 0)) {
|
||||
|
||||
string parentPath = path(hobFile->getFullPath()).parent_path().filename().string();
|
||||
replace(parentPath.begin(), parentPath.end(), '/', '\\');
|
||||
|
||||
#ifdef _WIN32
|
||||
CreateDirectory((".\\objOut\\" + parentPath).c_str(), NULL);
|
||||
#else
|
||||
mkdir(("./objOut/" + parentPath).c_str());
|
||||
#endif
|
||||
|
||||
// Create initial threads for files processing
|
||||
for ( i = 0; i < maxThreads; i++ ) {
|
||||
if (i >= hobFile->getObjectCount())
|
||||
break;
|
||||
|
||||
process.push_back(new thread(
|
||||
GenerateModelOBJ,
|
||||
hobFile->getMeshFromObject(i),
|
||||
parentPath,
|
||||
hobFile->getObjectName(i)
|
||||
));
|
||||
}
|
||||
|
||||
// Loop until all threads finished and no more file should be processed
|
||||
while (true) {
|
||||
process.front()->join();
|
||||
//delete process.front();
|
||||
process.pop_front();
|
||||
++successCnt;
|
||||
|
||||
if (successCnt >= hobFile->getObjectCount())
|
||||
break;
|
||||
|
||||
process.push_back(new thread(
|
||||
GenerateModelOBJ,
|
||||
hobFile->getMeshFromObject(successCnt),
|
||||
parentPath,
|
||||
hobFile->getObjectName(successCnt)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void ProcessModels() {
|
||||
unsigned int i,invalid = 0;
|
||||
|
||||
// Build models collection
|
||||
modelCollection.clear();
|
||||
for ( string mdname : RDI::RDI_getModelsName() ) {
|
||||
auto filePath = path(mdname);
|
||||
modelCollection.push_back(RDI::RDI_getModel(filePath.string()));
|
||||
}
|
||||
|
||||
// Try to load models using low-level library
|
||||
for ( RDI::HOB* hobFile : modelCollection ) {
|
||||
try {
|
||||
hobFile->Load();
|
||||
for ( i = 0; i < hobFile->getObjectCount(); i++ ) {
|
||||
if (hobFile->getMeshFromObject(i)->subMeshs.empty()) {
|
||||
cout << "Memory allocation failure!" << endl;
|
||||
invalid++;
|
||||
}
|
||||
}
|
||||
} catch (out_of_range const &ex) {
|
||||
//cout << "Empty object" << endl;
|
||||
}
|
||||
}
|
||||
cout << "Number of invalid memory allocation: " << invalid << endl;
|
||||
|
||||
// Launch threaded OBJ file building
|
||||
//GenerateModelOBJThreaded();
|
||||
//PrintModel(meshCollection.back());
|
||||
#ifdef _WIN32
|
||||
CreateDirectory(".\\objOut", NULL);
|
||||
#else
|
||||
mkdir("./objOut");
|
||||
#endif
|
||||
|
||||
for ( RDI::HOB* hobFile : modelCollection ) {
|
||||
if (hobFile->getObjectCount()) {
|
||||
string parentPath = path(hobFile->getFullPath()).parent_path().filename().string();
|
||||
replace(parentPath.begin(), parentPath.end(), '/', '\\');
|
||||
|
||||
#ifdef _WIN32
|
||||
CreateDirectory((".\\objOut\\" + parentPath).c_str(), NULL);
|
||||
#else
|
||||
mkdir(("./objOut/" + parentPath).c_str());
|
||||
#endif
|
||||
|
||||
for ( i = 0; i < hobFile->getObjectCount(); i++ ) {
|
||||
cout << " Processing " << hobFile->getFullPath() << "..." << endl;
|
||||
GenerateModelOBJ(hobFile->getMeshFromObject(i), parentPath, hobFile->getObjectName(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unload models
|
||||
for ( RDI::HOB* hobFile : modelCollection ) {
|
||||
hobFile->Dispose();
|
||||
modelCollection.clear();
|
||||
}
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] ) {
|
||||
unsigned int i;
|
||||
path pathBuilder;
|
||||
string prefix;
|
||||
bool use_unicode = true;
|
||||
|
||||
#ifdef _WIN32
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
#endif
|
||||
|
||||
cout << "Using RDI lib v" << RDI::RDI_getLibVersion() << endl << endl;
|
||||
cout << "RDIDebug tool - using RDI lib v" << RDI::RDI_getLibVersion() << endl << endl;
|
||||
|
||||
// Initialize RDI (Erso and Krennic module) with folder provided in program
|
||||
// argument, or the current directory by default
|
||||
@ -46,7 +264,8 @@ int main( int argc, char *argv[] ) {
|
||||
}
|
||||
|
||||
// Print details about legacy DATA.DAT file
|
||||
cout << "> Section found: " << RDI::RDI_getSectionCount() << endl;
|
||||
//cout << "> Section found: " << RDI::RDI_getSectionCount() << endl;
|
||||
printf("> Section found: %d\n", RDI::RDI_getSectionCount());
|
||||
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) << dec << endl;
|
||||
@ -60,7 +279,7 @@ int main( int argc, char *argv[] ) {
|
||||
pathBuilder.clear();
|
||||
pathBuilder.concat(RDI::RDI_getSectionName(i));
|
||||
|
||||
PrintVirtualDirectoryContents(pathBuilder, prefix, use_unicode);
|
||||
PrintVirtualDirectoryContents(pathBuilder, use_unicode);
|
||||
}
|
||||
|
||||
// Print game elements Krennic module found
|
||||
@ -70,9 +289,7 @@ int main( int argc, char *argv[] ) {
|
||||
cout << " " << lname << endl;
|
||||
}
|
||||
cout << endl << "> Models found: " << RDI::RDI_getModelsName().size() << endl;
|
||||
for ( std::string mdname : RDI::RDI_getModelsName() ) {
|
||||
cout << " " << mdname << endl;
|
||||
}
|
||||
ProcessModels();
|
||||
cout << endl << "> Textures found: " << RDI::RDI_getTexturesName().size() << endl;
|
||||
for ( std::string txname : RDI::RDI_getTexturesName() ) {
|
||||
cout << " " << txname << endl;
|
||||
@ -87,37 +304,3 @@ int main( int argc, char *argv[] ) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PrintVirtualDirectoryContents( path p, string outPrefix, bool unicode ) {
|
||||
auto curDirElementsName = RDI::RDI_getDirectoryElements(p.string());
|
||||
auto newPath = path(p);
|
||||
auto newOutPrefix = string(outPrefix);
|
||||
|
||||
for ( string eName : curDirElementsName ) {
|
||||
newPath.clear();
|
||||
newPath.concat(p);
|
||||
newOutPrefix.clear();
|
||||
newOutPrefix.append(outPrefix);
|
||||
|
||||
newPath.append(eName);
|
||||
if (RDI::RDI_isElementDirectory(newPath.string())) {
|
||||
if (unicode) {
|
||||
cout << outPrefix << "\u251C " << eName << endl;
|
||||
newOutPrefix.append("\u2502 ");
|
||||
} else {
|
||||
cout << outPrefix << "\\ " << eName << endl;
|
||||
newOutPrefix.append("| ");
|
||||
}
|
||||
PrintVirtualDirectoryContents(newPath, newOutPrefix, unicode);
|
||||
} else {
|
||||
if (unicode) {
|
||||
if (*--curDirElementsName.end() == eName)
|
||||
cout << newOutPrefix << "\u2514 " << eName << endl;
|
||||
else
|
||||
cout << newOutPrefix << "\u251C " << eName << endl;
|
||||
} else {
|
||||
cout << newOutPrefix << "+ " << eName << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user