Implement writer for raw materials

This commit is contained in:
Jan 2023-07-29 02:08:10 +02:00
parent 5db7bc2d4c
commit d48e0519ac
7 changed files with 329 additions and 0 deletions

View File

@ -0,0 +1,35 @@
#include "MaterialCommon.h"
using namespace material;
CommonConstant::CommonConstant()
: m_literal{}
{
}
CommonMaterial::CommonMaterial()
: m_game_flags(0u),
m_sort_key(0u),
m_texture_atlas_row_count(0u),
m_texture_atlas_column_count(0u),
m_surface_flags(0u),
m_contents(0u),
m_ref_state_bits{}
{
}
CommonTexture::CommonTexture()
: m_sampler_state(0u),
m_semantic(0u)
{
}
CommonWaterDef::CommonWaterDef()
: m_texture_width(0u),
m_horizontal_world_length(0u),
m_vertical_world_length(0u),
m_amplitude(0u),
m_wind_speed(0u),
m_wind_direction{}
{
}

View File

@ -0,0 +1,61 @@
#pragma once
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
namespace material
{
class CommonWaterDef
{
public:
int m_texture_width;
float m_horizontal_world_length;
float m_vertical_world_length;
float m_amplitude;
float m_wind_speed;
float m_wind_direction[2];
CommonWaterDef();
};
class CommonTexture
{
public:
std::string m_name;
uint8_t m_sampler_state;
uint8_t m_semantic;
std::string m_image_name;
std::unique_ptr<CommonWaterDef> m_water_def;
CommonTexture();
};
class CommonConstant
{
public:
std::string m_name;
float m_literal[4];
CommonConstant();
};
class CommonMaterial
{
public:
std::string m_name;
uint8_t m_game_flags;
uint8_t m_sort_key;
uint8_t m_texture_atlas_row_count;
uint8_t m_texture_atlas_column_count;
uint32_t m_surface_flags;
uint32_t m_contents;
uint32_t m_ref_state_bits[2];
std::vector<CommonTexture> m_textures;
std::vector<CommonConstant> m_constants;
std::string m_techset_name;
CommonMaterial();
};
}

View File

@ -0,0 +1,59 @@
#pragma once
#include <cstdint>
namespace material
{
struct MaterialRawOatHeader
{
uint8_t magic[3];
uint8_t version;
};
struct MaterialInfoRaw
{
uint32_t nameOffset;
uint8_t gameFlags;
uint8_t sortKey;
uint8_t textureAtlasRowCount;
uint8_t textureAtlasColumnCount;
uint32_t surfaceFlags;
uint32_t contents;
};
struct MaterialRaw
{
MaterialInfoRaw info;
uint32_t refStateBits[2];
uint16_t textureCount;
uint16_t constantCount;
uint32_t techSetNameOffset;
uint32_t textureTableOffset;
uint32_t constantTableOffset;
};
struct MaterialTextureDefRaw
{
uint32_t nameOffset;
uint8_t samplerState;
uint8_t semantic;
uint32_t imageNameOffset;
uint32_t waterDefOffset;
};
struct MaterialWaterDefRaw
{
uint32_t textureWidth;
float horizontalWorldLength;
float verticalWorldLength;
float amplitude;
float windSpeed;
float windDirection[2];
};
struct MaterialConstantDefRaw
{
uint32_t nameOffset;
float literal[4];
};
}

View File

@ -0,0 +1,30 @@
#include "AbstractRawDumper.h"
AbstractRawDumper::AbstractRawDumper(std::ostream& stream)
: m_stream(stream),
m_current_offset(0u)
{
}
size_t AbstractRawDumper::OffsetAdd(const size_t len)
{
const auto lastOffset = m_current_offset;
m_current_offset += len;
return lastOffset;
}
size_t AbstractRawDumper::OffsetAdd(const std::string& str)
{
return OffsetAdd(str.size() + 1);
}
void AbstractRawDumper::Write(const void* ptr, const size_t size) const
{
m_stream.write(static_cast<const char*>(ptr), size);
}
void AbstractRawDumper::Write(const std::string& str) const
{
m_stream.write(str.c_str(), str.size() + 1);
}

View File

@ -0,0 +1,25 @@
#pragma once
#include <ostream>
class AbstractRawDumper
{
protected:
explicit AbstractRawDumper(std::ostream& stream);
public:
virtual ~AbstractRawDumper() = default;
AbstractRawDumper(const AbstractRawDumper& other) = default;
AbstractRawDumper(AbstractRawDumper&& other) noexcept = default;
AbstractRawDumper& operator=(const AbstractRawDumper& other) = delete;
AbstractRawDumper& operator=(AbstractRawDumper&& other) noexcept = delete;
protected:
size_t OffsetAdd(size_t len);
size_t OffsetAdd(const std::string& str);
void Write(const void* ptr, size_t size) const;
void Write(const std::string& str) const;
std::ostream& m_stream;
size_t m_current_offset;
};

View File

@ -0,0 +1,101 @@
#include "MaterialRawOatWriter.h"
#include "Material/Raw/MaterialRawOat.h"
using namespace material;
MaterialRawOatWriter::MaterialRawOatWriter(std::ostream& stream)
: AbstractRawDumper(stream)
{
}
void MaterialRawOatWriter::WriteMaterial(const CommonMaterial& material)
{
constexpr MaterialRawOatHeader header{
{'M', 'T', 'L'},
1u
};
OffsetAdd(sizeof(header));
MaterialRaw materialRaw{};
OffsetAdd(sizeof(materialRaw));
materialRaw.info.nameOffset = OffsetAdd(material.m_name);
materialRaw.info.gameFlags = material.m_game_flags;
materialRaw.info.sortKey = material.m_sort_key;
materialRaw.info.textureAtlasRowCount = material.m_texture_atlas_row_count;
materialRaw.info.textureAtlasColumnCount = material.m_texture_atlas_column_count;
materialRaw.info.surfaceFlags = material.m_surface_flags;
materialRaw.info.contents = material.m_contents;
materialRaw.refStateBits[0] = material.m_ref_state_bits[0];
materialRaw.refStateBits[1] = material.m_ref_state_bits[1];
materialRaw.textureCount = static_cast<uint16_t>(material.m_textures.size());
materialRaw.constantCount = static_cast<uint16_t>(material.m_textures.size());
materialRaw.techSetNameOffset = OffsetAdd(material.m_techset_name);
materialRaw.textureTableOffset = OffsetAdd(sizeof(MaterialTextureDefRaw) * material.m_textures.size());
materialRaw.constantTableOffset = OffsetAdd(sizeof(MaterialConstantDefRaw) * material.m_textures.size());
const auto textureCount = material.m_textures.size();
std::vector<MaterialTextureDefRaw> textureDefs(textureCount);
for (auto i = 0u; i < textureCount; i++)
{
const auto& texture = material.m_textures[i];
auto& textureDef = textureDefs[i];
textureDef.nameOffset = OffsetAdd(texture.m_name);
textureDef.samplerState = texture.m_sampler_state;
textureDef.semantic = texture.m_semantic;
textureDef.imageNameOffset = OffsetAdd(texture.m_image_name);
textureDef.waterDefOffset = texture.m_water_def ? OffsetAdd(sizeof(MaterialWaterDefRaw)) : 0u;
}
const auto constantCount = material.m_constants.size();
std::vector<MaterialConstantDefRaw> constantDefs(constantCount);
for (auto i = 0u; i < constantCount; i++)
{
const auto& constant = material.m_constants[i];
auto& constantDef = constantDefs[i];
constantDef.nameOffset = OffsetAdd(constant.m_name);
constantDef.literal[0] = constant.m_literal[0];
constantDef.literal[1] = constant.m_literal[1];
constantDef.literal[2] = constant.m_literal[2];
constantDef.literal[3] = constant.m_literal[3];
}
Write(&header, sizeof(header));
Write(&materialRaw, sizeof(materialRaw));
Write(material.m_name);
Write(material.m_techset_name);
Write(textureDefs.data(), sizeof(MaterialTextureDefRaw) * textureCount);
Write(constantDefs.data(), sizeof(MaterialConstantDefRaw) * constantCount);
for (auto i = 0u; i < textureCount; i++)
{
const auto& texture = material.m_textures[i];
Write(texture.m_name);
Write(texture.m_image_name);
if (texture.m_water_def)
{
const auto& water = *texture.m_water_def;
MaterialWaterDefRaw waterDef{};
waterDef.textureWidth = water.m_texture_width;
waterDef.horizontalWorldLength = water.m_horizontal_world_length;
waterDef.verticalWorldLength = water.m_vertical_world_length;
waterDef.amplitude = water.m_amplitude;
waterDef.windSpeed = water.m_wind_speed;
waterDef.windDirection[0] = water.m_wind_direction[0];
waterDef.windDirection[1] = water.m_wind_direction[1];
Write(&waterDef, sizeof(MaterialWaterDefRaw));
}
}
for (auto i = 0u; i < constantCount; i++)
{
const auto& constant = material.m_constants[i];
Write(constant.m_name);
}
}

View File

@ -0,0 +1,18 @@
#pragma once
#include <ostream>
#include "Dumping/AbstractRawDumper.h"
#include "Material/MaterialCommon.h"
namespace material
{
class MaterialRawOatWriter final : AbstractRawDumper
{
public:
explicit MaterialRawOatWriter(std::ostream& stream);
void WriteMaterial(const CommonMaterial& material);
};
}