From 03fb71562288733c4d603ee38b3cc9680ca3d11b Mon Sep 17 00:00:00 2001 From: Joeyrp Date: Tue, 26 Oct 2021 16:33:25 -0400 Subject: [PATCH] Asset Index loader implemented (can not test yet) Beginnings of asset pipeline designed --- CMakeLists.txt | 2 + docs/Tasks.todo | 6 +- docs/binary_file_formats.txt | 38 +++++++ docs/project_structure.txt | 1 + scripts/build.bat | 4 +- scripts/build.sh | 2 +- src/assets/assetManager.h | 55 +++++++++ src/assets/loaders/assetIndex.cpp | 106 ++++++++++++++++++ src/assets/loaders/assetIndex.h | 54 +++++++++ src/assets/loaders/gameFile.h | 0 src/assets/types/asset.cpp | 29 +++++ src/assets/types/asset.h | 34 ++++++ src/assets/types/image.cpp | 2 +- src/assets/types/image.h | 3 +- src/core/core.cpp | 6 +- src/utils/opRes.cpp | 13 ++- src/utils/opRes.h | 6 +- .../{lunarium_state.xml => engine_state.xml} | 0 18 files changed, 347 insertions(+), 14 deletions(-) create mode 100644 docs/binary_file_formats.txt create mode 100644 src/assets/assetManager.h create mode 100644 src/assets/loaders/assetIndex.cpp create mode 100644 src/assets/loaders/assetIndex.h create mode 100644 src/assets/loaders/gameFile.h create mode 100644 src/assets/types/asset.cpp create mode 100644 src/assets/types/asset.h rename test_data/{lunarium_state.xml => engine_state.xml} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f7a491..e3ee2ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,8 @@ set(LUNARIUM_SRC "src/scripting/scriptManager.cpp" "src/scripting/coreAPI.cpp" "src/assets/types/image.cpp" +"src/assets/types/asset.cpp" +"src/assets/loaders/binary/assetIndex.cpp" ) # add the executable diff --git a/docs/Tasks.todo b/docs/Tasks.todo index 284e991..aefad8a 100644 --- a/docs/Tasks.todo +++ b/docs/Tasks.todo @@ -78,12 +78,12 @@ Game: Editor: ✔ Come up with project directory structure @done (9/17/2021, 6:46:44 PM) - ☐ Implement Run Mode interface class + ✔ Implement Run Mode interface class @done (10/25/2021, 6:54:36 PM) ☐ Reference raw asset files in a "content" folder ☐ Platform independant file browsing ☐ Scan script files to make sure they don't overwrite globals - Raw Asset Loaders: + Raw Asset Importers: - Need classes to load raw resource files for the editor ☐ Raw Resource loader interface class ☐ Raw Image loader class @@ -131,7 +131,7 @@ Assets: Tester: - A special class that is used to unit-test features of the engine - ☐ Implement Run Mode interface class + ✔ Implement Run Mode interface class @done (10/25/2021, 7:37:00 PM) ☐ Needs a timer to keep track of how long a test has run ☐ Main Tick method should use the timer to determine when to switch to the next test ☐ Add function for testing render to Texture diff --git a/docs/binary_file_formats.txt b/docs/binary_file_formats.txt new file mode 100644 index 0000000..13dc4e0 --- /dev/null +++ b/docs/binary_file_formats.txt @@ -0,0 +1,38 @@ + +.bin + This is the first file that will be loaded. will be set by with the + editor and the engine_state.xml file will direct the engine to this file. + + FORMAT: + Engine ID, 8 bytes (should say "lunarium") + Engine version, 3 bytes (major, minor, patch) + + + +index.dat + This is an index of all of the assets in the game project. Each asset will be + listed by name (and/or ID) followed by the file name and offset position within + the file where the asset can be found (ex. the asset with ID 6 might be found in file assets0.dat at byte offset 93846). + + FORMAT: + Number of assets, 4 bytes + + [REPEAT] + Asset ID, 4 bytes + Name Size, 2 bytes + Asset Name, bytes (Must be null-terminated) + Asset Type, 2 bytes + File Name Size, 2 bytes + Asset File, bytes (Must be null-terminated) + Asset Offset, 4 bytes + [REPEAT - for all assets] + +asset0.dat + This is an asset pack file. There could be many of these files and when there are + more than one the 0 in the file name will increase on each file (assets0.dat, assets1.dat, assets2.dat etc..) + + FORMAT: + Asset ID, 4 bytes + Asset Data Size, 4 bytes + Asset Data, bytes + [REPEAT FOR EACH ASSET] diff --git a/docs/project_structure.txt b/docs/project_structure.txt index aac0225..61dee2c 100644 --- a/docs/project_structure.txt +++ b/docs/project_structure.txt @@ -16,6 +16,7 @@ Project directory structure (this should be auto-generated by the editor when cr └─ release/ ├── (This directory is generated by the editor when building the project) ├── game_name.exe - (The non-editor version of the engine renamed to the game name) + ├── engine_state.xml - (configured to load the game from the data/ directory) └── data/ - (The data folder generated by the asset compiler, contains all the assets for the game in binary formats) diff --git a/scripts/build.bat b/scripts/build.bat index 169a182..d243510 100644 --- a/scripts/build.bat +++ b/scripts/build.bat @@ -10,10 +10,10 @@ IF not exist build/ ( IF "%~1" == "r" ( cmake --build build/ --target ALL_BUILD --config Release -xcopy /y test_data\lunarium_state.xml build\Release\ +xcopy /y test_data\engine_state.xml build\Release\ ) ELSE ( cmake --build build/ --target ALL_BUILD --config Debug -xcopy /y test_data\lunarium_state.xml build\Debug\ +xcopy /y test_data\engine_state.xml build\Debug\ ) :END \ No newline at end of file diff --git a/scripts/build.sh b/scripts/build.sh index f4aa409..0891e81 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -3,4 +3,4 @@ # ex. scripts/build.sh make -C build/ -cp test_data/lunarium_state.xml build/lunarium_state.xml \ No newline at end of file +cp test_data/engine_state.xml build/engine_state.xml \ No newline at end of file diff --git a/src/assets/assetManager.h b/src/assets/assetManager.h new file mode 100644 index 0000000..6455828 --- /dev/null +++ b/src/assets/assetManager.h @@ -0,0 +1,55 @@ +/****************************************************************************** +* File - assetManager.h +* Author - Joey Pollack +* Date - 2021/10/25 (y/m/d) +* Mod Date - 2021/10/25 (y/m/d) +* Description - Manages loading/unloading of all data/assets +******************************************************************************/ + +#ifndef ASSET_MANAGER_H_ +#define ASSET_MANAGER_H_ + +#include +#include +#include + +namespace lunarium +{ + class Asset; + + class AssetManager + { + public: + static AssetManager& GetInstance(); + + OpRes Initialize(); + void Shutdown(); + + // Used for preloading a list of assets + OpRes LoadAssets(std::vector names); + Asset* GetAsset(std::string name); + void ReturnAsset(Asset* pAsset) + void UnloadAsset(std::string name); + + private: + + static AssetManager* mpInstance; + + struct AssetBox + { + Asset* asset; + int references; + }; + + // Assets stored by name + std::map mAssets; + + private: + AssetManager(); + AssetManager(const AssetManager&) = delete; + AssetManager& operator=(const AssetManager&) = delete; + }; + +} + +#endif // ASSET_MANAGER_H_ \ No newline at end of file diff --git a/src/assets/loaders/assetIndex.cpp b/src/assets/loaders/assetIndex.cpp new file mode 100644 index 0000000..5c3ae70 --- /dev/null +++ b/src/assets/loaders/assetIndex.cpp @@ -0,0 +1,106 @@ +/****************************************************************************** +* File - assetIndex.h +* Author - Joey Pollack +* Date - 2021/10/25 (y/m/d) +* Mod Date - 2021/10/25 (y/m/d) +* Description - Loads and stores the index.dat file. Allows querying +* the asset index by asset ID or name. +******************************************************************************/ + +#include "assetIndex.h" +#include + +namespace lunarium +{ + AssetIndex* AssetIndex::mpInstance = nullptr; + + AssetIndex::AssetIndex() + { + } + + AssetIndex& AssetIndex::GetInstance() + { + if (!mpInstance) + { + mpInstance = new AssetIndex; + } + + return *mpInstance; + } + + void AssetIndex::FreeInstance() + { + for (auto iter = mpInstance->mAssets.begin(); iter != mpInstance->mAssets.end(); iter++) + { + delete iter->second; + } + + mpInstance->mAssets.clear(); + mpInstance->mAssetsByName.clear(); + + delete mpInstance; + mpInstance = nullptr; + } + + + OpRes AssetIndex::LoadIndex(const char* filename) + { + BinaryFileBuffer buffer; + if (!buffer.LoadFile(filename)) + { + return OpRes::Fail("AssetIndex::LoadIndex - unable to load file: %s", filename); + } + + int32_t num_assets = 0; + buffer.Read((char*) &num_assets, 4); + + char str_buf[512]; + + for (int i = 0; i < num_assets; i++) + { + AssetInfo* pAI = new AssetInfo; + buffer.Read((char*) &pAI->ID, 4); + + int16_t name_size = 0; + buffer.Read((char*) &name_size, 2); + buffer.Read(str_buf, name_size); + pAI->Name = str_buf; + + buffer.Read((char*) &pAI->Type, 2); + buffer.Read((char*) &name_size, 2); + buffer.Read(str_buf, name_size); + pAI->File = str_buf; + + buffer.Read((char*) &pAI->Offset, 4); + + mAssets[pAI->ID] = pAI; + mAssetsByName[pAI->Name] = pAI; + } + + buffer.Unload(); + + return OpRes::OK(); + } + + const AssetIndex::AssetInfo* AssetIndex::GetAssetInfo(int id) const + { + auto res = mAssets.find(id); + if (res != mAssets.end()) + { + return res->second; + } + + return nullptr; + } + + const AssetIndex::AssetInfo* AssetIndex::GetAssetInfo(const char* name) const + { + auto res = mAssetsByName.find(name); + if (res != mAssetsByName.end()) + { + return res->second; + } + + return nullptr; + } +} \ No newline at end of file diff --git a/src/assets/loaders/assetIndex.h b/src/assets/loaders/assetIndex.h new file mode 100644 index 0000000..af22cb0 --- /dev/null +++ b/src/assets/loaders/assetIndex.h @@ -0,0 +1,54 @@ +/****************************************************************************** +* File - assetIndex.h +* Author - Joey Pollack +* Date - 2021/10/25 (y/m/d) +* Mod Date - 2021/10/25 (y/m/d) +* Description - Loads and stores the index.dat file. Allows querying +* the asset index by asset ID or name. +******************************************************************************/ + +#ifndef ASSET_INDEX_H_ +#define ASSET_INDEX_H_ + +#include +#include +#include +#include +#include + +namespace lunarium +{ + class AssetIndex + { + public: + struct AssetInfo + { + int32_t ID; + std::string Name; + AssetType Type; + std::string File; + int32_t Offset; + }; + + public: + + static AssetIndex& GetInstance(); + static void FreeInstance(); + + OpRes LoadIndex(const char* filename); + const AssetInfo* GetAssetInfo(int id) const; + const AssetInfo* GetAssetInfo(const char* name) const; + + + private: + static AssetIndex* mpInstance; + std::map mAssets; + std::map mAssetsByName; + + AssetIndex(); + AssetIndex(const AssetIndex&) = delete; + AssetIndex& operator=(const AssetIndex&) = delete; + }; +} + +#endif // ASSET_INDEX_H_ diff --git a/src/assets/loaders/gameFile.h b/src/assets/loaders/gameFile.h new file mode 100644 index 0000000..e69de29 diff --git a/src/assets/types/asset.cpp b/src/assets/types/asset.cpp new file mode 100644 index 0000000..b16a705 --- /dev/null +++ b/src/assets/types/asset.cpp @@ -0,0 +1,29 @@ +/****************************************************************************** +* File - asset.cpp +* Author - Joey Pollack +* Date - 2021/10/25 (y/m/d) +* Mod Date - 2021/10/25 (y/m/d) +* Description - The base class for all asset type files +******************************************************************************/ + +#include "asset.h" + +namespace lunarium +{ + Asset::Asset(AssetType type) + : mType(type) + { + + } + + Asset::~Asset() + { + + } + + AssetType Asset::GetType() const + { + return mType; + } + +} \ No newline at end of file diff --git a/src/assets/types/asset.h b/src/assets/types/asset.h new file mode 100644 index 0000000..ba98fea --- /dev/null +++ b/src/assets/types/asset.h @@ -0,0 +1,34 @@ +/****************************************************************************** +* File - asset.h +* Author - Joey Pollack +* Date - 2021/10/25 (y/m/d) +* Mod Date - 2021/10/25 (y/m/d) +* Description - The base class for all asset type files +******************************************************************************/ + +#ifndef ASSET_H_ +#define ASSET_H_ + +namespace lunarium +{ + enum AssetType + { + ASSET_TYPE_IMAGE, + ASSET_TYPE_SCRIPT, + ASSET_TYPE_AUDIO, + ASSET_TYPE_UNKNOWN, + }; + + class Asset + { + public: + Asset(AssetType type = AssetType::ASSET_TYPE_UNKNOWN); + virtual ~Asset() = 0; + + AssetType GetType() const; + private: + AssetType mType; + }; +} + +#endif // ASSET_H_ \ No newline at end of file diff --git a/src/assets/types/image.cpp b/src/assets/types/image.cpp index 3ca9175..5186063 100644 --- a/src/assets/types/image.cpp +++ b/src/assets/types/image.cpp @@ -14,7 +14,7 @@ namespace lunarium { Image::Image() - : mRawData(nullptr), mRawDataSize(0), mWidth(0), mHeight(0) + : Asset(AssetType::ASSET_TYPE_IMAGE), mRawData(nullptr), mRawDataSize(0), mWidth(0), mHeight(0) { } diff --git a/src/assets/types/image.h b/src/assets/types/image.h index e081bd3..96127ce 100644 --- a/src/assets/types/image.h +++ b/src/assets/types/image.h @@ -11,11 +11,12 @@ #define IMAGE_H_ #include +#include "asset.h" namespace lunarium { class OglGraphics; - class Image + class Image : public Asset { friend OglGraphics; diff --git a/src/core/core.cpp b/src/core/core.cpp index 5f70cf4..b63e62f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -128,14 +128,14 @@ namespace lunarium Logger::Log(LogCategory::CORE, LogLevel::INFO, "Running Lunarium version %s", Version::GetVersion().ToString().c_str()); // Attempt to load the engine state file. This file should be placed in the same directory as the lunarium program. - if (Failed(State::CreateFromFile("lunarium_state.xml", mState))) + if (Failed(State::CreateFromFile("engine_state.xml", mState))) { - Logger::Log(LogCategory::CORE, LogLevel::WARNING, "Unable to load state file: lunarium_state.xml. Loading default state."); + Logger::Log(LogCategory::CORE, LogLevel::WARNING, "Unable to load state file: engine_state.xml. Loading default state."); mState = State::CreateDefault(); } else { - Logger::Log(LogCategory::CORE, LogLevel::INFO, "Loaded state file: lunarium_state.xml"); + Logger::Log(LogCategory::CORE, LogLevel::INFO, "Loaded state file: engine_state.xml"); } // RUN MODE diff --git a/src/utils/opRes.cpp b/src/utils/opRes.cpp index 8833731..312c025 100644 --- a/src/utils/opRes.cpp +++ b/src/utils/opRes.cpp @@ -9,8 +9,12 @@ #include "opRes.h" +#include + namespace lunarium { + char OpRes::Buffer[OpRes::BUFFER_SIZE]; + bool OpRes::operator==(const OpRes& rhs) { return this->Type == rhs.Type; @@ -26,9 +30,14 @@ namespace lunarium return { ResultType::OK, "The operation succeeded" }; } - OpRes OpRes::Fail(const char* why) + OpRes OpRes::Fail(const char* why, ...) { - return { ResultType::FAIL, why }; + va_list args; + va_start(args, why); + vsprintf(OpRes::Buffer, why, args); + va_end(args); + + return { ResultType::FAIL, OpRes::Buffer }; } bool IsOK(OpRes&& res) diff --git a/src/utils/opRes.h b/src/utils/opRes.h index 4be48c0..e4dbaa0 100644 --- a/src/utils/opRes.h +++ b/src/utils/opRes.h @@ -32,7 +32,11 @@ namespace lunarium static OpRes OK(); - static OpRes Fail(const char* why); + static OpRes Fail(const char* why, ...); + + private: + static const int BUFFER_SIZE = 512; + static char Buffer[OpRes::BUFFER_SIZE]; }; bool IsOK(OpRes&& res); diff --git a/test_data/lunarium_state.xml b/test_data/engine_state.xml similarity index 100% rename from test_data/lunarium_state.xml rename to test_data/engine_state.xml