#pragma once
/*
GameEngine and Editor
by John Ryland
Copyright (c) 2023
*/
#include <cstddef>
#include <cstdint>
namespace GameRuntime {
enum class VariableTypeEnum
{
E_Void,
E_Bool,
E_Enum,
E_String,
E_Number,
E_EncodedNumber,
E_Color,
E_Entity,
E_Asset,
E_Struct,
E_Component,
E_Max
};
enum UnifiedTypeEnum
{
// Extended/unified variable+number types
//E_Void, // label
//E_Bool8,
//E_Entity64,
//E_UInt8,
//E_UInt16,
//E_UInt32,
//E_UInt64,
//E_Int8,
//E_Int16,
//E_Int32,
//E_Int64,
//E_Enum8,
//E_Enum16,
//E_Enum32,
//E_Enum64,
//E_String64, // 8 characters
//E_String128, // 16 characters
//E_String256, // 32 characters
//E_String512, // 64 characters
//E_String1024, // 128 characters
//E_String2048, // 256 characters
//E_Color16_R5G6B5,
//E_Color16_R5G5B5A1,
//E_Color24_R8G8B8,
//E_Color32_R8G8B8,
//E_Color32_R8G8B8A8,
//E_ColorFloat128_R32G32B32A32,
//E_ColorFloat256_R64G64B64A64,
//E_Float16,
//E_Float32,
//E_Float64, // Scalar
//E_Float128_X32Y32Z32W32, // Vector
//E_Float256_X64Y64Z64W64, // Vector
//E_Scientific32,
//E_Scientific64,
//E_Coordinate128_X32Y32Z32W32
//E_Direction128_X32Y32Z32W32
//E_Normal128_X32Y32Z32W32
//E_EulerRadianAngles128_X32Y32Z32W32
//E_EulerDegreeAngles128_X32Y32Z32W32
//E_Quaternion128_X32Y32Z32W32
//E_Angle8,
//E_Angle16,
//E_Angle32,
//E_Angle64,
//E_Ratio8,
//E_Ratio16,
//E_Ratio32,
//E_Ratio64,
//E_GeometryShaderAssetId32,
//E_VertexShaderAssetId32,
//E_FragmentShaderAssetId32,
//E_TessellationShaderAssetId32,
//E_ComputeShaderAssetId32,
//E_SPIRVShaderAssetId32,
//E_AudioAssetId32,
//E_MeshAssetId32,
//E_TextureAssetId32,
//E_Struct8, // 1 byte alignment
//E_Struct16, // 2 byte alignment
//E_Struct32,
//E_Struct64,
//E_Struct128, // 16 byte alignment
//E_Struct256, // 32 byte alignment
//E_Struct512 // 64 byte alignment (cache line)
//E_UnixTimeNano64 // Nanosceonds since UNIX epoch as 64bit value 1 January 1970
// DateTime ideas:
// Age of the universe: 13.7 billion years old
// Epoch of 15 billion years ago -> 15,000,000,000 yrs (36-bits)
// 2^32 is 4,294,967,296
// 2^64 is 18,446,744,073,709,551,616
// 60*60*24 = 86400 second / day
// 31,536,000 seconds / year (25-bits)
// 31,536,000,000,000,000 nanoseconds / year (55-bits)
// 18,446,744,073,709,551,616 / 31,536,000,000,000,000 = 584
// 584 years without rollover of nanoseconds in a 64bit value
// Idea:
// 1-bit as flag for nanosecond datetime or seconds
// if 1 -> 38-bits for the year, 25-bits for the second of the year (epoch of -15 billion years)
// if 0 -> 8-bits for the year, 55-bits for the nanosecond of the year (epoch of 1 Jan 1970) (only contemporary times need nanoseconds)
// might be easier to deal with leap seconds etc if the year is split out
};
enum NumberTypeEnum
{
E_UInt8,
E_UInt16,
E_UInt32,
E_UInt64,
E_Int8,
E_Int16,
E_Int32,
E_Int64,
E_Float32,
E_Float64,
E_Angle,
E_Ratio
};
/*
enum NumberPurposeEnum
{
E_Numeric, // Scalar
E_Count,
E_Scientific,
E_Normal,
E_Ratio,
E_Color,
E_Boolean,
E_Void,
};
enum NumberRangeEnum
{
E_Zero, // void
E_BinaryZeroOrOne, // bool
E_ZeroToOne, // 0.0 to 1.0 ratio
E_Ratio = E_ZeroToOne,
E_MinusOneToPlusOne, // -1.0 to 1.0 normalized range
E_NormalComponent = E_MinusOneToPlusOne,
E_MinusPiToPlusPi, // radian angle
E_Byte,
E_Character = E_Byte,
E_Octet = E_Byte,
};
*/
enum ColorTypeEnum
{
E_RGB32,
E_RGBA32,
// This might be more file format related
E_R8G8B8,
E_R16G15B16,
E_R32G32B32,
E_R8G8B8A8,
E_B8G8R8A8,
E_R16G15B16A16,
E_R32G32B32A32,
E_R32G32B32A32_FLOAT,
E_R32G32B32A32_DOUBLE,
};
enum ShaderTypeEnum
{
E_GeometryShader,
E_VertexShader,
E_FragmentShader,
E_TessellationShader,
E_ComputeShader,
E_SPIRVShader
};
enum AssetTypeEnum
{
E_Audio,
E_Mesh,
E_Shader,
E_Texture
};
struct StringTable
{
uint64_t count;
char text[];
};
struct String
{
uint32_t stringTableOffset;
uint32_t stringLength;
};
struct NameValue
{
String name;
uint64_t value;
};
struct NameValueTable
{
uint64_t count;
NameValue values[];
};
struct NumberDescription
{
NumberTypeEnum numberType;
};
struct EntityDescription
{
};
struct StringDescription
{
uint32_t maximumCharacterCount;
};
struct EnumDescription
{
uint32_t numberOfEnumValues;
uint32_t nameValueTableOffset;
};
struct StructDescription
{
uint32_t numberOfFields;
uint32_t variableDescriptionTableOffset;
};
struct ColorDescription
{
ColorTypeEnum colorType;
};
struct AssetDescription
{
AssetTypeEnum assetType;
};
// This might be better for file formats than for component types
struct EncodedNumberDescription
{
bool hasNullValue; // Can it encode a special 'NoValue' value
bool hasSignBit;
uint8_t exponentBits;
uint8_t mantissaBits; // significant
int32_t exponentBias; // For 128bit wide floats, the exponent can be more than 16 bits so we need a 32bit value for this
double scale; // Can this handle the exponentBias for us? I am thinking it can't.
double bias;
};
struct VariableDescription
{
uint64_t uid;
String name;
VariableTypeEnum variableType;
union
{
NumberDescription numberDescription;
// EncodedNumberDescription encodedNumberDescription;
StringDescription stringDescription;
EnumDescription enumDescription;
EntityDescription entityDescription;
StructDescription structDescription;
StructDescription componentDescription;
ColorDescription colorDescription;
AssetDescription assetDescription;
};
};
struct VariableDescriptionTable
{
uint64_t count;
VariableDescription variables[];
};
struct Schema
{
StringTable* strings;
NameValueTable* enums;
VariableDescriptionTable* variables;
};
struct SchemaFileFormatHeader
{
uint32_t fileFormatCode;
uint32_t formatVersion;
uint32_t fileSize;
uint32_t headerSize;
uint32_t stringTableSize;
uint32_t stringTableFileOffset;
uint32_t nameValueTableSize;
uint32_t nameValueTableFileOffset;
uint32_t variableDescriptionTableSize;
uint32_t variableDescriptionTableFileOffset;
};
Schema* LoadSchemaFromFile(const char* schemaFileName);
void DestroySchema(Schema* schema);
size_t CalculateEnumSize(const Schema& schema, const EnumDescription& enumDesc);
size_t CalculateNumberSize(const Schema& schema, const NumberTypeEnum& numberDesc);
size_t CalculateFieldSize(const Schema& schema, size_t structOffset, const VariableDescription& fieldDesc);
size_t CalculateComponentSize(const Schema& schema, const StructDescription& fields);
} // GameRuntime namespace