Assets system refactor, Save Asset
This commit is contained in:
parent
49affdcc38
commit
9d5a41b02d
@ -11,7 +11,7 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
project (EtrediaEmpires)
|
||||
|
||||
add_subdirectory(sdk/map)
|
||||
add_subdirectory(sdk/materials)
|
||||
add_subdirectory(sdk/assets)
|
||||
add_subdirectory(utils)
|
||||
add_subdirectory(p7lib)
|
||||
add_subdirectory(server)
|
||||
|
||||
BIN
assets/map/_states.map
Normal file
BIN
assets/map/_states.map
Normal file
Binary file not shown.
BIN
assets/scenarios/empires.save
Normal file
BIN
assets/scenarios/empires.save
Normal file
Binary file not shown.
@ -1,32 +1,57 @@
|
||||
#pragma once
|
||||
#include "GameData.hpp"
|
||||
#include "Map.hpp"
|
||||
#include <concepts>
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace ee_assets
|
||||
{
|
||||
struct AssetData {};
|
||||
template<typename T> concept Asset = std::derived_from<T, AssetData>;
|
||||
|
||||
enum AssetType
|
||||
{
|
||||
BINARY,
|
||||
|
||||
MAP_MESH,
|
||||
SAVE,
|
||||
|
||||
SHADER,
|
||||
MATERIAL,
|
||||
IMAGE
|
||||
};
|
||||
|
||||
struct AssetBinary : AssetData
|
||||
struct AssetBinary : public AssetData
|
||||
{
|
||||
uint8_t* content = nullptr;
|
||||
size_t size = 0;
|
||||
|
||||
AssetBinary(uint8_t* &source, const size_t &sourceSize);
|
||||
AssetBinary(uint8_t* &source, const size_t sourceSize);
|
||||
~AssetBinary();
|
||||
};
|
||||
|
||||
struct AssetMapMesh : AssetData
|
||||
struct AssetMapMesh : public AssetData
|
||||
{
|
||||
ee_engine::MapMesh content;
|
||||
|
||||
AssetMapMesh(uint8_t* &source, const size_t &sourceSize);
|
||||
uint8_t* Serialize(size_t &size);
|
||||
AssetMapMesh() {};
|
||||
AssetMapMesh(uint8_t* &source, const size_t sourceSize);
|
||||
};
|
||||
|
||||
struct AssetSave : public AssetData
|
||||
{
|
||||
std::vector<ee_data::Subject> subjects;
|
||||
|
||||
uint8_t* Serialize(size_t &size);
|
||||
AssetSave() {};
|
||||
AssetSave(uint8_t* &source, const size_t sourceSize);
|
||||
};
|
||||
|
||||
#define AssetShader AssetBinary
|
||||
|
||||
struct AssetMaterial : AssetData
|
||||
struct AssetMaterial : public AssetData
|
||||
{
|
||||
uint32_t vertexShaderAssetID;
|
||||
uint32_t fragmentShaderAssetID;
|
||||
|
||||
13
engine-api/include/ee_engine_api/GameData.hpp
Normal file
13
engine-api/include/ee_engine_api/GameData.hpp
Normal file
@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
namespace ee_data
|
||||
{
|
||||
struct Subject
|
||||
{
|
||||
uint32_t tag;
|
||||
uint32_t color;
|
||||
std::vector<uint32_t> regions;
|
||||
};
|
||||
}
|
||||
@ -9,9 +9,12 @@ YOU CAN PREVENT SOURCE BUFFER FROM CLOSING.
|
||||
IT CAN BE USED FOR STORING ASSET DATA WITHOUT COPY.
|
||||
IN THIS CASE, YOU MUST SET SOURCE TO NULLPTR AND FREE BUFFER YOURSELF.
|
||||
|
||||
TODO: make binary format describing for common functions instead of individual serialize/deserialize functions
|
||||
TODO: parallelize convertion loops
|
||||
|
||||
*/
|
||||
|
||||
ee_assets::AssetBinary::AssetBinary(uint8_t* &source, const size_t &sourceSize)
|
||||
ee_assets::AssetBinary::AssetBinary(uint8_t* &source, const size_t sourceSize)
|
||||
{
|
||||
content = source;
|
||||
size = sourceSize;
|
||||
@ -26,7 +29,7 @@ ee_assets::AssetBinary::~AssetBinary()
|
||||
|
||||
|
||||
|
||||
ee_assets::AssetMapMesh::AssetMapMesh(uint8_t* &source, const size_t &sourceSize)
|
||||
ee_assets::AssetMapMesh::AssetMapMesh(uint8_t* &source, const size_t sourceSize)
|
||||
{
|
||||
uint8_t* buffer = source;
|
||||
uint8_t* pointer = source;
|
||||
@ -86,4 +89,79 @@ ee_assets::AssetMapMesh::AssetMapMesh(uint8_t* &source, const size_t &sourceSize
|
||||
}
|
||||
|
||||
DeallocateArray(buffer);
|
||||
}
|
||||
|
||||
|
||||
ee_assets::AssetSave::AssetSave(uint8_t* &source, const size_t sourceSize)
|
||||
{
|
||||
uint8_t* buffer = source;
|
||||
uint8_t* pointer = source;
|
||||
size_t leftoverSize = sourceSize;
|
||||
source = nullptr;
|
||||
|
||||
uint16_t subjectsCount = static_cast<uint16_t>(subjects.size());
|
||||
ee_utils::readNext(&subjectsCount, pointer, leftoverSize, sizeof(uint16_t));
|
||||
|
||||
for (uint16_t i = 0; i < subjectsCount; i++)
|
||||
{
|
||||
ee_data::Subject subject;
|
||||
|
||||
ee_utils::readNext(&subject.tag, pointer, leftoverSize, sizeof(subject.tag));
|
||||
ee_utils::readNext(&subject.color, pointer, leftoverSize, sizeof(subject.color));
|
||||
|
||||
uint16_t regionsCount = 0;
|
||||
ee_utils::readNext(®ionsCount, pointer, leftoverSize, sizeof(uint16_t));
|
||||
subject.regions.resize(regionsCount);
|
||||
ee_utils::readNext(
|
||||
subject.regions.data(),
|
||||
pointer,
|
||||
leftoverSize,
|
||||
subject.regions.size() * sizeof(uint32_t)
|
||||
);
|
||||
|
||||
subjects.push_back(subject);
|
||||
}
|
||||
|
||||
DeallocateArray(buffer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// SERIALIZERS
|
||||
|
||||
uint8_t* ee_assets::AssetSave::Serialize(size_t &size)
|
||||
{
|
||||
size = sizeof(uint16_t);
|
||||
for (ee_data::Subject &subject : subjects)
|
||||
{
|
||||
size += sizeof(subject.tag);
|
||||
size += sizeof(subject.color);
|
||||
size += sizeof(uint16_t) + subject.regions.size() * sizeof(uint32_t);
|
||||
}
|
||||
|
||||
size_t leftover = size;
|
||||
uint8_t *result = AllocateArray<uint8_t>(size);
|
||||
uint8_t *pointer = result;
|
||||
|
||||
uint16_t subjectsCount = static_cast<uint16_t>(subjects.size());
|
||||
ee_utils::writeNext(pointer, &subjectsCount, leftover, sizeof(uint16_t));
|
||||
|
||||
for (ee_data::Subject &subject : subjects)
|
||||
{
|
||||
ee_utils::writeNext(pointer, &subject.tag, leftover, sizeof(subject.tag));
|
||||
ee_utils::writeNext(pointer, &subject.color, leftover, sizeof(subject.color));
|
||||
|
||||
uint16_t regionsCount = static_cast<uint16_t>(subject.regions.size());
|
||||
ee_utils::writeNext(pointer, ®ionsCount, leftover, sizeof(uint16_t));
|
||||
ee_utils::writeNext(
|
||||
pointer,
|
||||
subject.regions.data(),
|
||||
leftover,
|
||||
subject.regions.size() * sizeof(uint32_t)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -2,6 +2,7 @@
|
||||
#include "FileSystem.hpp"
|
||||
#include <ee_engine_api/AssetData.hpp>
|
||||
|
||||
#include "Logger.h"
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
#include <filesystem>
|
||||
@ -26,16 +27,7 @@ struct AssetHandle
|
||||
class AssetInfo
|
||||
{
|
||||
public:
|
||||
enum Type
|
||||
{
|
||||
BINARY,
|
||||
|
||||
MAP_MESH,
|
||||
|
||||
SHADER,
|
||||
MATERIAL,
|
||||
IMAGE
|
||||
} type = BINARY;
|
||||
ee_assets::AssetType type = ee_assets::BINARY;
|
||||
|
||||
std::atomic<bool> isReady;
|
||||
AssetAddress* resourceAddress;
|
||||
@ -72,7 +64,7 @@ struct AssetStreamCommand
|
||||
AssetHandle target;
|
||||
uint32_t targetId = INVALID_ASSET_ID;
|
||||
std::filesystem::path targetPath;
|
||||
AssetInfo::Type targetType = AssetInfo::BINARY;
|
||||
ee_assets::AssetType targetType = ee_assets::BINARY;
|
||||
std::atomic<void*>* out;
|
||||
};
|
||||
|
||||
@ -87,9 +79,9 @@ public:
|
||||
void Start();
|
||||
void Shutdown();
|
||||
|
||||
void LoadDir(AssetInfo::Type type, const std::filesystem::path &path);
|
||||
void LoadDir(ee_assets::AssetType type, const std::filesystem::path &path);
|
||||
|
||||
void LoadAsync(AssetInfo::Type type, const std::filesystem::path &path);
|
||||
void LoadAsync(ee_assets::AssetType type, const std::filesystem::path &path);
|
||||
AssetHandle& Find(const std::filesystem::path &path);
|
||||
AssetHandle& Find(const uint32_t &id);
|
||||
template <ee_assets::Asset T> T& FindOnce(const std::filesystem::path &path);
|
||||
@ -112,6 +104,7 @@ private:
|
||||
std::vector<AssetLoadingEntry> loadingEntries;
|
||||
|
||||
std::vector<ee_assets::AssetBinary*> binaryStorage;
|
||||
std::vector<ee_assets::AssetSave*> savesStorage;
|
||||
std::vector<ee_assets::AssetMapMesh*> mapMeshesStorage;
|
||||
std::vector<ee_assets::AssetShader*> shadersStorage;
|
||||
std::vector<ee_assets::AssetMaterial*> materialsStorage;
|
||||
@ -123,6 +116,8 @@ private:
|
||||
void ProcessCommand(AssetStreamCommand &command);
|
||||
void Release();
|
||||
|
||||
template<ee_assets::Asset T> void FinishLoadConstruct(AssetLoadingEntry &loaded, std::vector<T*> &storage);
|
||||
template<ee_assets::Asset T> void FinishLoadPlain(AssetLoadingEntry &loaded, std::vector<T*> &storage);
|
||||
template<ee_assets::Asset T> void ClearStorage(std::vector<T*> &storage);
|
||||
};
|
||||
|
||||
@ -149,6 +144,23 @@ template <ee_assets::Asset T> T& AssetManager::FindOnce(const uint32_t &id)
|
||||
return Get<T>(Find(id));
|
||||
}
|
||||
|
||||
template<ee_assets::Asset T> void AssetManager::FinishLoadConstruct(AssetLoadingEntry &loaded, std::vector<T*> &storage)
|
||||
{
|
||||
T* resource = Allocate<T>(loaded.file->data, loaded.file->size);
|
||||
storage.push_back(resource);
|
||||
Redirect(loaded.handle, storage.back());
|
||||
}
|
||||
|
||||
template<ee_assets::Asset T> void AssetManager::FinishLoadPlain(AssetLoadingEntry &loaded, std::vector<T*> &storage)
|
||||
{
|
||||
T* resource = Allocate<T>();
|
||||
if (loaded.file->size < sizeof(T))
|
||||
LOG(CRITICAL, "File size is less than needed for asset of type: %d", typeid(T).name());
|
||||
std::memcpy(resource, loaded.file->data, sizeof(T));
|
||||
storage.push_back(resource);
|
||||
Redirect(loaded.handle, storage.back());
|
||||
}
|
||||
|
||||
template<ee_assets::Asset T> void AssetManager::ClearStorage(std::vector<T*> &storage)
|
||||
{
|
||||
for (T* &resource : storage)
|
||||
|
||||
@ -87,7 +87,7 @@ void AssetManager::Request(const AssetStreamCommand::Type &type)
|
||||
commands.push(AssetStreamCommand {.type = type});
|
||||
}
|
||||
|
||||
void AssetManager::LoadAsync(AssetInfo::Type type, const std::filesystem::path &path)
|
||||
void AssetManager::LoadAsync(ee_assets::AssetType type, const std::filesystem::path &path)
|
||||
{
|
||||
AssetStreamCommand command {
|
||||
.type = AssetStreamCommand::LOAD,
|
||||
@ -166,6 +166,7 @@ void AssetManager::Loop()
|
||||
}
|
||||
incompleteCommands.clear();
|
||||
|
||||
// TODO: FinishLoadTasks()
|
||||
for (AssetLoadingEntry &entry : loadingEntries)
|
||||
{
|
||||
bool isReady = entry.fileOwner->PollReady(*entry.file);
|
||||
@ -175,47 +176,26 @@ void AssetManager::Loop()
|
||||
|
||||
switch (asset.type)
|
||||
{
|
||||
case AssetInfo::MAP_MESH:
|
||||
{
|
||||
ee_assets::AssetMapMesh* mesh = Allocate<ee_assets::AssetMapMesh>(entry.file->data, entry.file->size);
|
||||
mapMeshesStorage.push_back(mesh);
|
||||
Redirect(entry.handle, mapMeshesStorage.back());
|
||||
case ee_assets::MAP_MESH:
|
||||
FinishLoadConstruct(entry, mapMeshesStorage);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case AssetInfo::SHADER:
|
||||
{
|
||||
ee_assets::AssetShader* shader = Allocate<ee_assets::AssetShader>(entry.file->data, entry.file->size);
|
||||
shadersStorage.push_back(shader);
|
||||
Redirect(entry.handle, shadersStorage.back());
|
||||
case ee_assets::SAVE:
|
||||
FinishLoadConstruct(entry, savesStorage);
|
||||
break;
|
||||
}
|
||||
|
||||
case AssetInfo::MATERIAL:
|
||||
{
|
||||
ee_assets::AssetMaterial* material = Allocate<ee_assets::AssetMaterial>();
|
||||
if (entry.file->size < sizeof(ee_assets::AssetMaterial))
|
||||
LOG(CRITICAL, "File size is less than needed for material");
|
||||
std::memcpy(material, entry.file->data, sizeof(ee_assets::AssetMaterial));
|
||||
materialsStorage.push_back(material);
|
||||
Redirect(entry.handle, materialsStorage.back());
|
||||
case ee_assets::SHADER:
|
||||
FinishLoadConstruct(entry, shadersStorage);
|
||||
break;
|
||||
}
|
||||
|
||||
case AssetInfo::IMAGE:
|
||||
{
|
||||
case ee_assets::MATERIAL:
|
||||
FinishLoadPlain(entry, materialsStorage);
|
||||
break;
|
||||
case ee_assets::IMAGE:
|
||||
break;
|
||||
}
|
||||
|
||||
case AssetInfo::BINARY:
|
||||
case ee_assets::BINARY:
|
||||
default:
|
||||
{
|
||||
ee_assets::AssetBinary* data = Allocate<ee_assets::AssetBinary>(entry.file->data, entry.file->size);
|
||||
binaryStorage.push_back(data);
|
||||
Redirect(entry.handle, binaryStorage.back());
|
||||
FinishLoadConstruct(entry, binaryStorage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
entry.fileOwner->Close(*entry.file);
|
||||
@ -234,6 +214,7 @@ void AssetManager::Loop()
|
||||
}
|
||||
void AssetManager::ProcessCommand(AssetStreamCommand &command)
|
||||
{
|
||||
// TODO: method for each command
|
||||
switch(command.type)
|
||||
{
|
||||
case AssetStreamCommand::LOAD:
|
||||
@ -353,7 +334,7 @@ void AssetManager::Release()
|
||||
isRunning.store(false);
|
||||
}
|
||||
|
||||
void AssetManager::LoadDir(AssetInfo::Type type, const std::filesystem::path &path)
|
||||
void AssetManager::LoadDir(ee_assets::AssetType type, const std::filesystem::path &path)
|
||||
{
|
||||
for (const std::filesystem::directory_entry &entry : std::filesystem::directory_iterator(path))
|
||||
{
|
||||
|
||||
@ -40,11 +40,12 @@ int main(int argc, char **argv)
|
||||
// Setup Asset Manager
|
||||
Engine::assetManager = Allocate<AssetManager>();
|
||||
Engine::assetManager->Start();
|
||||
Engine::assetManager->LoadDir(AssetInfo::SHADER, "assets/shaders");
|
||||
Engine::assetManager->LoadDir(AssetInfo::MATERIAL, "assets/materials");
|
||||
Engine::assetManager->LoadDir(ee_assets::SHADER, "assets/shaders");
|
||||
Engine::assetManager->LoadDir(ee_assets::MATERIAL, "assets/materials");
|
||||
|
||||
// Load assets
|
||||
Engine::assetManager->LoadAsync(AssetInfo::MAP_MESH, "assets/map/states.map");
|
||||
Engine::assetManager->LoadAsync(ee_assets::MAP_MESH, "assets/map/states.map");
|
||||
Engine::assetManager->LoadAsync(ee_assets::SAVE, "assets/scenarios/empires.save");
|
||||
|
||||
// Setup input manager TODO: builder
|
||||
Engine::input = Allocate<GLFWInput>(Actions::mappings);
|
||||
|
||||
23
sdk/assets/CMakeLists.txt
Normal file
23
sdk/assets/CMakeLists.txt
Normal file
@ -0,0 +1,23 @@
|
||||
cmake_minimum_required (VERSION 3.8)
|
||||
|
||||
if (POLICY CMP0141)
|
||||
cmake_policy(SET CMP0141 NEW)
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
|
||||
endif()
|
||||
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
project (compile_assets)
|
||||
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
find_package(xxHash CONFIG REQUIRED)
|
||||
|
||||
add_executable(${PROJECT_NAME} compile_assets.cpp)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash)
|
||||
target_link_libraries(${PROJECT_NAME} PUBLIC engine-api)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
|
||||
endif()
|
||||
23
sdk/assets/_save.schema.json
Normal file
23
sdk/assets/_save.schema.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"type": "object",
|
||||
"title": "Etredia Empires savegame data",
|
||||
"description": "Contains initial state of a game (e.g. scenarios, saves)",
|
||||
|
||||
"properties": {
|
||||
"subjects": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"tag": {"type": "string"},
|
||||
"color": {"type": "string"},
|
||||
|
||||
"regions": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
177
sdk/assets/compile_assets.cpp
Normal file
177
sdk/assets/compile_assets.cpp
Normal file
@ -0,0 +1,177 @@
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <xxhash.h>
|
||||
#include <string>
|
||||
#include <charconv>
|
||||
#include <functional>
|
||||
#include <ee_engine_api/AssetData.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
#define bytes(value) reinterpret_cast<const char*>(value)
|
||||
|
||||
namespace ee_data
|
||||
{
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(
|
||||
Subject,
|
||||
tag,
|
||||
color,
|
||||
regions
|
||||
)
|
||||
}
|
||||
|
||||
namespace ee_assets
|
||||
{
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(
|
||||
AssetSave,
|
||||
subjects
|
||||
)
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(
|
||||
AssetMaterial,
|
||||
vertexShaderAssetID,
|
||||
fragmentShaderAssetID
|
||||
)
|
||||
}
|
||||
|
||||
struct MappingEntry
|
||||
{
|
||||
std::string_view name;
|
||||
uint32_t value;
|
||||
};
|
||||
static constexpr MappingEntry mappings[] = {
|
||||
#define MAP(name, value) {#name, ((value & 0x0000FF) << 16) | ( value & 0x00FF00) | ((value & 0xFF0000) >> 16)},
|
||||
#include "define/regions.def"
|
||||
#undef MAP
|
||||
};
|
||||
|
||||
void CompileRecursive(json &obj, std::function<void(const std::basic_string<char> &key, json &value)> callback)
|
||||
{
|
||||
if (obj.is_array()) {for (auto &element : obj) CompileRecursive(element, callback); return;}
|
||||
if (!obj.is_object()) {callback("", obj); return;}
|
||||
|
||||
for (auto &[key, value] : obj.items())
|
||||
{
|
||||
if (value.is_object())
|
||||
CompileRecursive(value, callback);
|
||||
else if (value.is_array())
|
||||
for (auto &element : value)
|
||||
CompileRecursive(element, callback);
|
||||
else callback(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::path in = argv[1];
|
||||
std::filesystem::path out = argv[2];
|
||||
char* assetTypeStr = argv[3];
|
||||
|
||||
std::ifstream fin(in);
|
||||
std::ofstream fout(out);
|
||||
ee_assets::AssetType assetType = static_cast<ee_assets::AssetType>(atoi(assetTypeStr));
|
||||
|
||||
if (!fin.is_open()) {
|
||||
std::cout << "Error: Could not open input file: " << in << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if (!fout.is_open()) {
|
||||
std::cout << "Error: Could not open output file: " << out << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
json data = json::parse(fin);
|
||||
|
||||
// Compile hashes
|
||||
CompileRecursive(data, [](const std::basic_string<char> &key, json &value) {
|
||||
if (!value.is_string()) return;
|
||||
|
||||
if (
|
||||
!(key == "tag") &&
|
||||
!key.ends_with("AssetID") &&
|
||||
!key.ends_with("Type")
|
||||
) return;
|
||||
|
||||
std::filesystem::path linkPath = value;
|
||||
auto linkPath8 = linkPath.generic_u8string();
|
||||
uint32_t assetId = XXH32(linkPath8.data(), linkPath8.size(), 0);
|
||||
|
||||
std::cout << "Replace string [" << value << "] with [" << assetId << "]" << std::endl;
|
||||
value = assetId;
|
||||
});
|
||||
|
||||
// Compile mappings
|
||||
CompileRecursive(data, [](const std::basic_string<char> &key, json &value) {
|
||||
if (!value.is_string()) return;
|
||||
const std::string& value_string = value.get_ref<const std::string&>();
|
||||
|
||||
for (const MappingEntry &map : mappings)
|
||||
{
|
||||
if (value_string == map.name)
|
||||
{
|
||||
std::cout << "Replace string [" << value << "] with [" << map.value << "]" << std::endl;
|
||||
value = map.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Compile colors
|
||||
CompileRecursive(data, [](const std::basic_string<char> &key, json &value) {
|
||||
if (!value.is_string()) return;
|
||||
|
||||
const char* color_str = value.get_ref<const std::string&>().c_str() + 1;
|
||||
uint8_t b = 0, g = 0, r = 0;
|
||||
uint32_t hex = 0;
|
||||
|
||||
std::from_chars(color_str, color_str + 2, r, 16); color_str += 2;
|
||||
std::from_chars(color_str, color_str + 2, g, 16); color_str += 2;
|
||||
std::from_chars(color_str, color_str + 2, b, 16); color_str += 2;
|
||||
|
||||
hex = static_cast<uint32_t>(r) << 16 |
|
||||
static_cast<uint32_t>(g) << 8 |
|
||||
static_cast<uint32_t>(b);
|
||||
|
||||
std::cout << "Replace string [" << value << "] with [" << (int)r << "," << (int)g << "," << (int)b << "]" << std::endl;
|
||||
value = hex;
|
||||
});
|
||||
|
||||
switch (assetType)
|
||||
{
|
||||
case ee_assets::MATERIAL:
|
||||
{
|
||||
ee_assets::AssetMaterial material = data.get<ee_assets::AssetMaterial>();
|
||||
fout.write(bytes(&material), sizeof(material));
|
||||
break;
|
||||
}
|
||||
|
||||
case ee_assets::SAVE:
|
||||
{
|
||||
ee_assets::AssetSave save = data.get<ee_assets::AssetSave>();
|
||||
size_t size = 0;
|
||||
const char* data = bytes(save.Serialize(size));
|
||||
fout.write(data, size);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
fin.close();
|
||||
fout.close();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
19
sdk/assets/define/regions.def
Normal file
19
sdk/assets/define/regions.def
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef MAP
|
||||
#define MAP(name, color)
|
||||
#endif
|
||||
|
||||
MAP(elnia, 0xFF0000)
|
||||
MAP(south_hleria, 0xFFD800)
|
||||
MAP(siburia_central, 0xFF00DC)
|
||||
MAP(siburia, 0xFF0000)
|
||||
MAP(savatia, 0xFF0000)
|
||||
MAP(east_monfua, 0xFF0000)
|
||||
|
||||
MAP(dineria, 0x0400FF)
|
||||
MAP(perdania, 0xFF6A00)
|
||||
MAP(arstinia, 0xFF0000)
|
||||
MAP(ortostan, 0xFF0000)
|
||||
MAP(zerandia, 0xFF0000)
|
||||
MAP(mgahvatia, 0xFF0000)
|
||||
|
||||
#undef MAP
|
||||
10
sdk/assets/run.cmd
Normal file
10
sdk/assets/run.cmd
Normal file
@ -0,0 +1,10 @@
|
||||
@echo off
|
||||
|
||||
set ASSETS=../../assets
|
||||
set COMPILE=%CD%/../../out/build/DEBUG/sdk/assets/compile_assets.exe
|
||||
|
||||
set MATERIAL=4
|
||||
set SAVE=2
|
||||
|
||||
for %%F in (materials/*) do %COMPILE% "materials/%%~nF.json" "%ASSETS%/materials/%%~nF" %MATERIAL% && echo "Compiled: %%~nF"
|
||||
for %%F in (saves/*) do %COMPILE% "saves/%%~nF.json" "%ASSETS%/scenarios/%%~nF" %SAVE% && echo "Compiled: %%~nF"
|
||||
33
sdk/assets/saves/empires.save.json
Normal file
33
sdk/assets/saves/empires.save.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"subjects": [
|
||||
|
||||
{
|
||||
"tag": "ESH",
|
||||
"color": "#FF0000",
|
||||
|
||||
"regions": [
|
||||
"elnia",
|
||||
"south_hleria",
|
||||
"siburia_central",
|
||||
"siburia",
|
||||
"savatia",
|
||||
"east_monfua"
|
||||
]
|
||||
},
|
||||
|
||||
{
|
||||
"tag": "UCB",
|
||||
"color": "#00FF00",
|
||||
|
||||
"regions": [
|
||||
"dineria",
|
||||
"perdania",
|
||||
"arstinia",
|
||||
"ortostan",
|
||||
"zerandia",
|
||||
"mgahvatia"
|
||||
]
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
@ -1,4 +1,3 @@
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <cstdint>
|
||||
@ -40,7 +39,9 @@ struct vertex { float x,y; };
|
||||
|
||||
struct BGRHash {
|
||||
size_t operator()(const BGR& c) const noexcept {
|
||||
return (c.r<<16)|(c.g<<8)|c.b;
|
||||
return static_cast<uint32_t>(c.r) << 16 |
|
||||
static_cast<uint32_t>(c.g) << 8 |
|
||||
static_cast<uint32_t>(c.b);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1,46 +0,0 @@
|
||||
cmake_minimum_required (VERSION 3.8)
|
||||
|
||||
if (POLICY CMP0141)
|
||||
cmake_policy(SET CMP0141 NEW)
|
||||
set(CMAKE_MSVC_DEBUG_INFORMATION_FORMAT "$<IF:$<AND:$<C_COMPILER_ID:MSVC>,$<CXX_COMPILER_ID:MSVC>>,$<$<CONFIG:Debug,RelWithDebInfo>:EditAndContinue>,$<$<CONFIG:Debug,RelWithDebInfo>:ProgramDatabase>>")
|
||||
endif()
|
||||
|
||||
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
|
||||
project (compile_materials)
|
||||
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
find_package(xxHash CONFIG REQUIRED)
|
||||
|
||||
add_executable(${PROJECT_NAME} compile_materials.cpp)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE nlohmann_json::nlohmann_json)
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE xxHash::xxhash)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_SOURCE_DIR}/engine-api/include/)
|
||||
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.12)
|
||||
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
|
||||
endif()
|
||||
|
||||
file(GLOB MATERIAL_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.mat.json")
|
||||
|
||||
set(COMPILED_DIR "${CMAKE_SOURCE_DIR}/assets/materials")
|
||||
|
||||
foreach(MAT ${MATERIAL_FILES})
|
||||
get_filename_component(MAT_NAME ${MAT} NAME_WE)
|
||||
set(OUT_FILE "${COMPILED_DIR}/${MAT_NAME}.mat")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${OUT_FILE}
|
||||
COMMAND ${PROJECT_NAME} ${MAT} ${OUT_FILE}
|
||||
DEPENDS ${MAT}
|
||||
COMMENT "Compiling material ${MAT_NAME}"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
list(APPEND COMPILED_BINARIES ${OUT_FILE})
|
||||
endforeach()
|
||||
|
||||
add_custom_target(compile_material_assets ALL
|
||||
DEPENDS ${COMPILED_BINARIES}
|
||||
)
|
||||
@ -1,66 +0,0 @@
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <xxhash.h>
|
||||
#include <string>
|
||||
#include <ee_engine_api/AssetData.hpp>
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(
|
||||
AssetMaterial,
|
||||
vertexShaderAssetID,
|
||||
fragmentShaderAssetID
|
||||
)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
try
|
||||
{
|
||||
std::filesystem::path in = argv[1];
|
||||
std::filesystem::path out = argv[2];
|
||||
|
||||
|
||||
std::ifstream fin(in);
|
||||
std::ofstream fout(out);
|
||||
|
||||
if (!fin.is_open()) {
|
||||
std::cout << "Error: Could not open input file." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
if (!fout.is_open()) {
|
||||
std::cout << "Error: Could not open output file." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
json data = json::parse(fin);
|
||||
|
||||
for (auto &[key, value] : data.items())
|
||||
{
|
||||
if (
|
||||
!key.ends_with("AssetID") &&
|
||||
!key.ends_with("Type")
|
||||
) continue;
|
||||
|
||||
std::filesystem::path linkPath = data[key];
|
||||
auto linkPath8 = linkPath.generic_u8string();
|
||||
uint32_t assetId = XXH32(linkPath8.data(), linkPath8.size(), 0);
|
||||
data[key] = assetId;
|
||||
}
|
||||
|
||||
AssetMaterial material = data.get<AssetMaterial>();
|
||||
fout.write(reinterpret_cast<const char*>(&material), sizeof(material));
|
||||
|
||||
fin.close();
|
||||
fout.close();
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
std::cerr << e.what() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1,7 +1,10 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
|
||||
#define as_bytes(value) reinterpret_cast<const char*>(value)
|
||||
|
||||
namespace ee_utils
|
||||
{
|
||||
bool readNext(void* dist, uint8_t* &srcPointer, size_t &srcLeftoverSize, const size_t &readSize);
|
||||
bool readNext(void* dst, uint8_t* &srcPointer, size_t &srcLeftoverSize, const size_t &readSize);
|
||||
bool writeNext(uint8_t* &dstPointer, void* src, size_t &dstLeftoverSize, const size_t &writeSize);
|
||||
}
|
||||
@ -1,16 +1,30 @@
|
||||
#include <ee_utils/buffers.hpp>
|
||||
#include <cstring>
|
||||
|
||||
bool ee_utils::readNext(void* dist, uint8_t* &srcPointer, size_t &srcLeftoverSize, const size_t &readSize)
|
||||
bool ee_utils::readNext(void* dst, uint8_t* &srcPointer, size_t &srcLeftoverSize, const size_t &readSize)
|
||||
{
|
||||
if (srcLeftoverSize >= readSize)
|
||||
{
|
||||
srcLeftoverSize -= readSize;
|
||||
std::memcpy(dist, srcPointer, readSize);
|
||||
std::memcpy(dst, srcPointer, readSize);
|
||||
srcPointer += readSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ee_utils::writeNext(uint8_t* &dstPointer, void* src, size_t &dstLeftoverSize, const size_t &writeSize)
|
||||
{
|
||||
if (dstLeftoverSize >= writeSize)
|
||||
{
|
||||
dstLeftoverSize -= writeSize;
|
||||
std::memcpy(dstPointer, src, writeSize);
|
||||
dstPointer += writeSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user