Compare commits
2 Commits
aaf397fef6
...
29bb1d0208
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
29bb1d0208 | ||
|
|
b307165a6f |
@@ -1,6 +1,6 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
cmake_minimum_required(VERSION 3.10)
|
||||||
project(MiniDefProj)
|
project(MiniDefProj)
|
||||||
add_executable(minidef "${CMAKE_CURRENT_SOURCE_DIR}/src/MiniDef.cpp")
|
add_executable(minidef "${CMAKE_CURRENT_SOURCE_DIR}/src/MiniDef.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/Logging.cpp")
|
||||||
target_include_directories(minidef PRIVATE
|
target_include_directories(minidef PRIVATE
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../bgfx.cmake/bx/include/"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../bgfx.cmake/bx/include/"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/../bgfx.cmake/bx/include/compat/msvc/"
|
"${CMAKE_CURRENT_SOURCE_DIR}/../bgfx.cmake/bx/include/compat/msvc/"
|
||||||
|
|||||||
18
src/dependency/minidef/Logging.h
Normal file
18
src/dependency/minidef/Logging.h
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define LOG(line, fmt, ...) Logging::Log(Logging::ELogType::Log, line, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_WARN(line, fmt, ...) Logging::Log(Logging::ELogType::Warn, line, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_ERROR(line, fmt, ...) Logging::Log(Logging::ELogType::Error, line, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
struct Logging
|
||||||
|
{
|
||||||
|
enum class ELogType
|
||||||
|
{
|
||||||
|
Log,
|
||||||
|
Warn,
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
static void Log(ELogType logType, uint32_t line, const char* format, ...);
|
||||||
|
};
|
||||||
@@ -1,11 +1,17 @@
|
|||||||
|
type Test
|
||||||
|
{
|
||||||
|
u32 Number
|
||||||
|
}
|
||||||
|
|
||||||
type Texture
|
type Texture
|
||||||
{
|
{
|
||||||
u32 Width
|
u32 Width
|
||||||
u32 Height
|
u32 Height
|
||||||
str Test Arr(3)
|
str StrTest Arr(3)
|
||||||
|
Test T
|
||||||
}
|
}
|
||||||
|
|
||||||
enum KnownType
|
enum KnownType(u8)
|
||||||
{
|
{
|
||||||
i8 CName("int8_t")
|
i8 CName("int8_t")
|
||||||
i16 CName("int16_t")
|
i16 CName("int16_t")
|
||||||
@@ -15,6 +21,7 @@ enum KnownType
|
|||||||
u16 CName("uint16_t")
|
u16 CName("uint16_t")
|
||||||
u32 CName("uint32_t")
|
u32 CName("uint32_t")
|
||||||
u64 CName("uint64_t")
|
u64 CName("uint64_t")
|
||||||
|
b CName("bool")
|
||||||
f32 CName("float")
|
f32 CName("float")
|
||||||
f64 CName("double")
|
f64 CName("double")
|
||||||
str CName("char")
|
str CName("char")
|
||||||
|
|||||||
@@ -3,16 +3,21 @@
|
|||||||
|
|
||||||
namespace Generated
|
namespace Generated
|
||||||
{
|
{
|
||||||
|
struct Test
|
||||||
|
{
|
||||||
|
uint32_t Number = {};
|
||||||
|
};
|
||||||
struct Texture
|
struct Texture
|
||||||
{
|
{
|
||||||
uint32_t Width = {};
|
uint32_t Width = {};
|
||||||
uint32_t Height = {};
|
uint32_t Height = {};
|
||||||
char Test[3] = {};
|
char StrTest[3] = {};
|
||||||
|
Test T = {};
|
||||||
};
|
};
|
||||||
struct KnownType
|
struct KnownType
|
||||||
{
|
{
|
||||||
static constexpr int32_t EntryCount = 11;
|
static constexpr int32_t EntryCount = 12;
|
||||||
enum class Enum
|
enum class Enum : int32_t
|
||||||
{
|
{
|
||||||
i8,
|
i8,
|
||||||
i16,
|
i16,
|
||||||
@@ -22,6 +27,7 @@ namespace Generated
|
|||||||
u16,
|
u16,
|
||||||
u32,
|
u32,
|
||||||
u64,
|
u64,
|
||||||
|
b,
|
||||||
f32,
|
f32,
|
||||||
f64,
|
f64,
|
||||||
str,
|
str,
|
||||||
@@ -36,6 +42,7 @@ namespace Generated
|
|||||||
"u16",
|
"u16",
|
||||||
"u32",
|
"u32",
|
||||||
"u64",
|
"u64",
|
||||||
|
"b",
|
||||||
"f32",
|
"f32",
|
||||||
"f64",
|
"f64",
|
||||||
"str",
|
"str",
|
||||||
@@ -50,6 +57,7 @@ namespace Generated
|
|||||||
"uint16_t",
|
"uint16_t",
|
||||||
"uint32_t",
|
"uint32_t",
|
||||||
"uint64_t",
|
"uint64_t",
|
||||||
|
"bool",
|
||||||
"float",
|
"float",
|
||||||
"double",
|
"double",
|
||||||
"char",
|
"char",
|
||||||
|
|||||||
34
src/dependency/minidef/src/Logging.cpp
Normal file
34
src/dependency/minidef/src/Logging.cpp
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
#include "Logging.h"
|
||||||
|
#include "bx/string.h"
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include "Windows.h"
|
||||||
|
|
||||||
|
#define ESC "\x1B["
|
||||||
|
#define YELLOW ESC "33m"
|
||||||
|
#define RED ESC "31m"
|
||||||
|
#define END ESC "39m"
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
char LineBuffer[1024]{0};
|
||||||
|
char OutBuffer[1024]{0};
|
||||||
|
constexpr char LogFormat[]{"Line %u: %s\n"};
|
||||||
|
constexpr char WarnFormat[]{YELLOW "Line %u: %s" END "\n"};
|
||||||
|
constexpr char ErrorFormat[]{RED "Line %u: %s" END "\n"};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
void Logging::Log(ELogType logType, uint32_t line, const char* format, ...)
|
||||||
|
{
|
||||||
|
const char* LineFormat = LogFormat;
|
||||||
|
if (logType == ELogType::Warn) LineFormat = WarnFormat;
|
||||||
|
if (logType == ELogType::Error) LineFormat = ErrorFormat;
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, format);
|
||||||
|
bx::snprintf(LineBuffer, sizeof(LineBuffer), LineFormat, line, format);
|
||||||
|
bx::vprintf(LineBuffer, args);
|
||||||
|
bx::vsnprintf(OutBuffer, sizeof(OutBuffer), LineBuffer, args);
|
||||||
|
va_end(args);
|
||||||
|
OutputDebugStringA(OutBuffer);
|
||||||
|
}
|
||||||
19
src/dependency/minidef/src/Logging.h
Normal file
19
src/dependency/minidef/src/Logging.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
#define LOG(line, fmt, ...) Logging::Log(Logging::ELogType::Log, line, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_WARN(line, fmt, ...) Logging::Log(Logging::ELogType::Warn, line, fmt, ##__VA_ARGS__)
|
||||||
|
#define LOG_ERROR(line, fmt, ...) Logging::Log(Logging::ELogType::Error, line, fmt, ##__VA_ARGS__)
|
||||||
|
|
||||||
|
struct Logging
|
||||||
|
{
|
||||||
|
enum class ELogType
|
||||||
|
{
|
||||||
|
Log,
|
||||||
|
Warn,
|
||||||
|
Error,
|
||||||
|
};
|
||||||
|
static bool Assert(bool Condition, const char* Text);
|
||||||
|
static void Log(ELogType logType, uint32_t line, const char* format, ...);
|
||||||
|
};
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
|
#include "Gen/Generated.h"
|
||||||
|
#include "Logging.h"
|
||||||
#include "MiniDef.h"
|
#include "MiniDef.h"
|
||||||
|
|
||||||
#include "bx/string.h"
|
#include "bx/string.h"
|
||||||
#include <bx/filepath.h>
|
#include <bx/filepath.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@@ -27,11 +30,11 @@ namespace Generated
|
|||||||
R"END( };
|
R"END( };
|
||||||
)END";
|
)END";
|
||||||
|
|
||||||
constexpr char EnumHeader2[] =
|
constexpr char EnumHeader3[] =
|
||||||
R"END( struct %s
|
R"END( struct %s
|
||||||
{
|
{
|
||||||
static constexpr int32_t EntryCount = %u;
|
static constexpr int32_t EntryCount = %u;
|
||||||
enum class Enum
|
enum class Enum : %s
|
||||||
{
|
{
|
||||||
)END";
|
)END";
|
||||||
|
|
||||||
@@ -59,51 +62,37 @@ namespace Generated
|
|||||||
)END";
|
)END";
|
||||||
} // namespace WriteTemplates
|
} // namespace WriteTemplates
|
||||||
|
|
||||||
void DefinitionFile::PrintTypeName(char* buf, int32_t bufSize, Def::TypeUnion type)
|
void DefinitionFile::PrintTypeName(char* buf, int32_t bufSize, const Def::FieldType& type)
|
||||||
{
|
{
|
||||||
if (int32_t(type.Known) < Generated::KnownType::EntryCount)
|
if (type.FieldKind == Def::EFieldType::Native)
|
||||||
{
|
{
|
||||||
bx::strCopy(buf, bufSize, Generated::KnownType::CName[size_t(type.Known)]);
|
if (int32_t(type.Native) < Generated::KnownType::EntryCount)
|
||||||
|
{
|
||||||
|
bx::strCopy(buf, bufSize, Generated::KnownType::CName[size_t(type.Native)]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR(0, "Unknown native type index: %u", type.Native);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type.FieldKind == Def::EFieldType::DefinedClass)
|
||||||
|
{
|
||||||
|
bx::strCopy(buf, bufSize, Types[type.TypeIdx].Name);
|
||||||
|
}
|
||||||
|
else if (type.FieldKind == Def::EFieldType::DefinedEnum)
|
||||||
|
{
|
||||||
|
bx::strCopy(buf, bufSize, Enums[type.TypeIdx].Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefinitionFile::GenerateCpp(const bx::FilePath& outDir)
|
void DefinitionFile::WriteEnums(TemplateWriter& Template)
|
||||||
{
|
{
|
||||||
bx::Error error;
|
|
||||||
bx::FileWriter writer;
|
|
||||||
bx::FilePath writePath = outDir;
|
|
||||||
std::filesystem::create_directory(outDir.getCPtr());
|
|
||||||
writePath.join("Generated.h");
|
|
||||||
writer.open(writePath, false, &error);
|
|
||||||
|
|
||||||
TemplateWriter Template{writer, error};
|
|
||||||
Template.Write(WriteTemplates::FileHeader);
|
|
||||||
|
|
||||||
for (int32_t typeIdx = 0; typeIdx < TypeCount; ++typeIdx)
|
|
||||||
{
|
|
||||||
Def::Type& t = Types[typeIdx];
|
|
||||||
|
|
||||||
Template.Write(WriteTemplates::StructHeader1, t.Name);
|
|
||||||
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
|
|
||||||
{
|
|
||||||
char Type[64]{0};
|
|
||||||
PrintTypeName(Type, sizeof(Type), t.FieldTypes[fieldIdx]);
|
|
||||||
char Array[32]{0};
|
|
||||||
uint32_t ArraySize = t.FieldArraySizes[fieldIdx];
|
|
||||||
if (ArraySize > 0)
|
|
||||||
{
|
|
||||||
bx::snprintf(Array, sizeof(Array), "[%u]", ArraySize);
|
|
||||||
}
|
|
||||||
Template.Write(WriteTemplates::StructField4, Type, t.FieldNames[fieldIdx], Array, "{}");
|
|
||||||
}
|
|
||||||
Template.Write(WriteTemplates::StructEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int32_t enumIdx = 0; enumIdx < EnumCount; ++enumIdx)
|
for (int32_t enumIdx = 0; enumIdx < EnumCount; ++enumIdx)
|
||||||
{
|
{
|
||||||
Def::Enum& e = Enums[enumIdx];
|
Def::Enum& e = Enums[enumIdx];
|
||||||
|
|
||||||
Template.Write(WriteTemplates::EnumHeader2, e.Name, e.EntryCount);
|
Template.Write(
|
||||||
|
WriteTemplates::EnumHeader3, e.Name, e.EntryCount, Generated::KnownType::CName[(int32_t)e.EnumType.Native]);
|
||||||
for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx)
|
for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx)
|
||||||
{
|
{
|
||||||
Template.Write(WriteTemplates::EnumField1, e.EntryNames[entryIdx]);
|
Template.Write(WriteTemplates::EnumField1, e.EntryNames[entryIdx]);
|
||||||
@@ -126,29 +115,85 @@ void DefinitionFile::GenerateCpp(const bx::FilePath& outDir)
|
|||||||
|
|
||||||
Template.Write(WriteTemplates::EnumNamesEnd);
|
Template.Write(WriteTemplates::EnumNamesEnd);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
void DefinitionFile::WriteTypes(TemplateWriter& Template)
|
||||||
|
{
|
||||||
|
for (int32_t typeIdx = 0; typeIdx < TypeCount; ++typeIdx)
|
||||||
|
{
|
||||||
|
Def::Type& t = Types[typeIdx];
|
||||||
|
|
||||||
|
Template.Write(WriteTemplates::StructHeader1, t.Name);
|
||||||
|
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
|
||||||
|
{
|
||||||
|
char Type[64]{0};
|
||||||
|
PrintTypeName(Type, sizeof(Type), t.FieldTypes[fieldIdx]);
|
||||||
|
char Array[32]{0};
|
||||||
|
uint32_t ArraySize = t.FieldArraySizes[fieldIdx];
|
||||||
|
if (ArraySize > 0)
|
||||||
|
{
|
||||||
|
bx::snprintf(Array, sizeof(Array), "[%u]", ArraySize);
|
||||||
|
}
|
||||||
|
Template.Write(WriteTemplates::StructField4, Type, t.FieldNames[fieldIdx], Array, "{}");
|
||||||
|
}
|
||||||
|
Template.Write(WriteTemplates::StructEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void DefinitionFile::GenerateCpp(const bx::FilePath& outDir)
|
||||||
|
{
|
||||||
|
LOG(0, "Generating...");
|
||||||
|
|
||||||
|
bx::Error error;
|
||||||
|
bx::FileWriter writer;
|
||||||
|
bx::FilePath writePath = outDir;
|
||||||
|
std::filesystem::create_directory(outDir.getCPtr());
|
||||||
|
writePath.join("Generated.h");
|
||||||
|
writer.open(writePath, false, &error);
|
||||||
|
|
||||||
|
TemplateWriter Template{writer, error};
|
||||||
|
Template.Write(WriteTemplates::FileHeader);
|
||||||
|
|
||||||
|
WriteEnums(Template);
|
||||||
|
WriteTypes(Template);
|
||||||
|
|
||||||
Template.Write(WriteTemplates::FileEnd);
|
Template.Write(WriteTemplates::FileEnd);
|
||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::CmpAdvance(bx::StringView expect, Result& Res)
|
bool Parser::CmpAdvance(bx::StringView expect, Result& Res, bool RequireGap)
|
||||||
{
|
{
|
||||||
uint32_t size = expect.getLength();
|
uint32_t size = expect.getLength();
|
||||||
|
const char* ptr = expect.getPtr();
|
||||||
|
|
||||||
|
// abort if expect longer than remaining text
|
||||||
if (size > GetRemaining())
|
if (size > GetRemaining())
|
||||||
{
|
{
|
||||||
std::cout << "Failed to match " << expect.getPtr() << ", " << size << "<" << GetRemaining() << std::endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// start matching
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
for (; i < size; ++i)
|
for (; i < size; ++i)
|
||||||
{
|
{
|
||||||
|
// if expect has 0 byte, go back one idx, we succeded
|
||||||
if (expect.getPtr()[i] == 0)
|
if (expect.getPtr()[i] == 0)
|
||||||
{
|
{
|
||||||
i--;
|
i--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check match
|
||||||
if (expect.getPtr()[i] != ReadPtr[i]) return false;
|
if (expect.getPtr()[i] != ReadPtr[i]) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for following whitespace or symbols
|
||||||
|
if (RequireGap && GetRemaining() > size)
|
||||||
|
{
|
||||||
|
char next = ReadPtr[i];
|
||||||
|
if (isgraph(next) && next != '{' && next != '}' && next != '(' && next != ')')
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
Res = Advance(i);
|
Res = Advance(i);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -158,7 +203,8 @@ Parser::Result Parser::ExpectChar(bx::StringView expect)
|
|||||||
Result Res = OK;
|
Result Res = OK;
|
||||||
if (!CmpAdvance(expect, Res))
|
if (!CmpAdvance(expect, Res))
|
||||||
{
|
{
|
||||||
std::cout << "Expected " << expect.getPtr() << std::endl;
|
LOG_ERROR(Line, "Expected: %s", expect.getPtr());
|
||||||
|
ErrorLine();
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
return Res;
|
return Res;
|
||||||
@@ -170,7 +216,11 @@ Parser::Result Parser::SkipWhitespace(bool* SkippedNewLine)
|
|||||||
for (int32_t i = 0; i < Remaining; ++i)
|
for (int32_t i = 0; i < Remaining; ++i)
|
||||||
{
|
{
|
||||||
if (*ReadPtr == 0) return EndOfFile;
|
if (*ReadPtr == 0) return EndOfFile;
|
||||||
if (SkippedNewLine != nullptr && (*ReadPtr == '\r' || *ReadPtr == '\n')) *SkippedNewLine = true;
|
if (SkippedNewLine != nullptr && (*ReadPtr == '\r' || *ReadPtr == '\n'))
|
||||||
|
{
|
||||||
|
if (*ReadPtr == '\n') ++Line;
|
||||||
|
*SkippedNewLine = true;
|
||||||
|
}
|
||||||
if (isgraph(*ReadPtr)) return OK;
|
if (isgraph(*ReadPtr)) return OK;
|
||||||
ReadPtr++;
|
ReadPtr++;
|
||||||
}
|
}
|
||||||
@@ -236,19 +286,19 @@ Parser::Result Parser::Parse()
|
|||||||
Parser::Result Parser::HandleFileStart()
|
Parser::Result Parser::HandleFileStart()
|
||||||
{
|
{
|
||||||
Result Res = OK;
|
Result Res = OK;
|
||||||
if (CmpAdvance("type", Res) && Res == OK)
|
if (CmpAdvance("type", Res, true) && Res == OK)
|
||||||
{
|
{
|
||||||
return HandleType();
|
return HandleType();
|
||||||
}
|
}
|
||||||
if (Res != OK) return Res;
|
if (Res != OK) return Res;
|
||||||
|
|
||||||
if (CmpAdvance("enum", Res) && Res == OK)
|
if (CmpAdvance("enum", Res, true) && Res == OK)
|
||||||
{
|
{
|
||||||
return HandleEnum();
|
return HandleEnum();
|
||||||
}
|
}
|
||||||
if (Res != OK) return Res;
|
if (Res != OK) return Res;
|
||||||
|
|
||||||
std::cout << "Only valid here: type or enum!";
|
LOG(Line, "Only valid here: type or enum!");
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +310,8 @@ Parser::Result Parser::HandleType()
|
|||||||
|
|
||||||
if (Definitions.TypeCount >= DefinitionFile::MaxTypes)
|
if (Definitions.TypeCount >= DefinitionFile::MaxTypes)
|
||||||
{
|
{
|
||||||
std::cout << "Too many types!" << std::endl;
|
LOG_ERROR(Line, "Too many types!");
|
||||||
|
ErrorLine();
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
Def::Type& t = Definitions.Types[Definitions.TypeCount];
|
Def::Type& t = Definitions.Types[Definitions.TypeCount];
|
||||||
@@ -274,7 +325,8 @@ Parser::Result Parser::HandleType()
|
|||||||
{
|
{
|
||||||
if (t.FieldCount >= Def::MaxFields)
|
if (t.FieldCount >= Def::MaxFields)
|
||||||
{
|
{
|
||||||
std::cout << "Too many fields in type!" << std::endl;
|
LOG_ERROR(Line, "Too many fields in type!");
|
||||||
|
ErrorLine();
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
CHECK(ReadTypeToken());
|
CHECK(ReadTypeToken());
|
||||||
@@ -287,7 +339,7 @@ Parser::Result Parser::HandleType()
|
|||||||
if (!NewLine)
|
if (!NewLine)
|
||||||
{
|
{
|
||||||
Result Res;
|
Result Res;
|
||||||
if (CmpAdvance("Arr", Res) && Res == Result::OK)
|
if (CmpAdvance("Arr", Res, true) && Res == Result::OK)
|
||||||
{
|
{
|
||||||
CHECK(ExpectChar("("));
|
CHECK(ExpectChar("("));
|
||||||
CHECK(ReadUint(t.FieldArraySizes[t.FieldCount]));
|
CHECK(ReadUint(t.FieldArraySizes[t.FieldCount]));
|
||||||
@@ -310,21 +362,31 @@ Parser::Result Parser::HandleEnum()
|
|||||||
|
|
||||||
if (Definitions.EnumCount >= DefinitionFile::MaxTypes)
|
if (Definitions.EnumCount >= DefinitionFile::MaxTypes)
|
||||||
{
|
{
|
||||||
std::cout << "Too many enums!" << std::endl;
|
LOG_ERROR(Line, "Too many enums!");
|
||||||
|
ErrorLine();
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
Def::Enum& e = Definitions.Enums[Definitions.EnumCount];
|
Def::Enum& e = Definitions.Enums[Definitions.EnumCount];
|
||||||
CHECK(ReadName(e.Name));
|
CHECK(ReadName(e.Name));
|
||||||
|
|
||||||
CHECK(SkipWhitespace());
|
CHECK(SkipWhitespace());
|
||||||
|
|
||||||
|
if (CmpAdvance("(", Res) && Res == OK)
|
||||||
|
{
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
Def::FieldType field;
|
||||||
|
CHECK(ReadNativeFieldType(field));
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
CHECK(ExpectChar(")"));
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
}
|
||||||
|
|
||||||
CHECK(ExpectChar("{"));
|
CHECK(ExpectChar("{"));
|
||||||
CHECK(SkipWhitespace());
|
CHECK(SkipWhitespace());
|
||||||
|
|
||||||
while (!CmpAdvance("}", Res))
|
while (!CmpAdvance("}", Res))
|
||||||
{
|
{
|
||||||
if (e.EntryCount >= Def::MaxFields)
|
if (e.EntryCount >= Def::MaxFields)
|
||||||
{
|
{
|
||||||
std::cout << "Too many fields in enum!" << std::endl;
|
LOG_ERROR(Line, "Too many fields in enum!");
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
CHECK(ReadName(e.EntryNames[e.EntryCount]));
|
CHECK(ReadName(e.EntryNames[e.EntryCount]));
|
||||||
@@ -345,7 +407,8 @@ Parser::Result Parser::ReadName(char* Target)
|
|||||||
{
|
{
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
{
|
{
|
||||||
std::cout << "Empty names are not allowed!" << std::endl;
|
LOG_ERROR(Line, "Empty names are not allowed!");
|
||||||
|
ErrorLine();
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
return OK;
|
return OK;
|
||||||
@@ -356,7 +419,8 @@ Parser::Result Parser::ReadName(char* Target)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Name too long!" << std::endl;
|
LOG_ERROR(Line, "Name too long!");
|
||||||
|
ErrorLine();
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
ReadPtr++;
|
ReadPtr++;
|
||||||
@@ -381,30 +445,68 @@ Parser::Result Parser::ReadUint(uint32_t& Out)
|
|||||||
}
|
}
|
||||||
if (Written == 0)
|
if (Written == 0)
|
||||||
{
|
{
|
||||||
std::cout << "No digits for uint: " << PrintLine() << std::endl;
|
LOG_ERROR(Line, "No digits for uint!");
|
||||||
|
ErrorLine();
|
||||||
return Result::Error;
|
return Result::Error;
|
||||||
}
|
}
|
||||||
if (!bx::fromString(&Out, DigitBuf))
|
if (!bx::fromString(&Out, DigitBuf))
|
||||||
{
|
{
|
||||||
std::cout << "Failed to parse uint: " << PrintLine() << std::endl;
|
LOG_ERROR(Line, "Failed to parse uint!");
|
||||||
|
ErrorLine();
|
||||||
return Result::Error;
|
return Result::Error;
|
||||||
}
|
}
|
||||||
return Result::OK;
|
return Result::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::Result Parser::ReadTypeToken()
|
Parser::Result Parser::ReadTypeToken()
|
||||||
|
{
|
||||||
|
Result Res = OK;
|
||||||
|
Def::Type& t = Definitions.Types[Definitions.TypeCount];
|
||||||
|
if (ReadNativeFieldType(t.FieldTypes[t.FieldCount]) == OK) return OK;
|
||||||
|
if (ReadDefinedFieldType(t.FieldTypes[t.FieldCount]) == OK) return OK;
|
||||||
|
LOG_ERROR(Line, "Unknown type token!");
|
||||||
|
ErrorLine();
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::ReadNativeFieldType(Def::FieldType& FieldT)
|
||||||
{
|
{
|
||||||
Result Res = OK;
|
Result Res = OK;
|
||||||
for (int32_t i = 0; i < Generated::KnownType::EntryCount; ++i)
|
for (int32_t i = 0; i < Generated::KnownType::EntryCount; ++i)
|
||||||
{
|
{
|
||||||
if (CmpAdvance(Generated::KnownType::EntryNames[i], Res) && Res == OK)
|
if (CmpAdvance(Generated::KnownType::EntryNames[i], Res, true) && Res == OK)
|
||||||
{
|
{
|
||||||
Def::Type& t = Definitions.Types[Definitions.TypeCount];
|
FieldT.FieldKind = Def::EFieldType::Native;
|
||||||
t.FieldTypes[t.FieldCount].Known = Generated::KnownType::Enum(i);
|
FieldT.Native = Generated::KnownType::Enum(i);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::ReadDefinedFieldType(Def::FieldType& FieldT)
|
||||||
|
{
|
||||||
|
Result Res = OK;
|
||||||
|
for (uint16_t i = 0; i < Definitions.TypeCount; ++i)
|
||||||
|
{
|
||||||
|
if (CmpAdvance(Definitions.Types[i].Name, Res, true) && Res == OK)
|
||||||
|
{
|
||||||
|
Def::Type& t = Definitions.Types[Definitions.TypeCount];
|
||||||
|
FieldT.FieldKind = Def::EFieldType::DefinedClass;
|
||||||
|
FieldT.TypeIdx = i;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (uint16_t i = 0; i < Definitions.EnumCount; ++i)
|
||||||
|
{
|
||||||
|
if (CmpAdvance(Definitions.Enums[i].Name, Res, true) && Res == OK)
|
||||||
|
{
|
||||||
|
Def::Type& t = Definitions.Types[Definitions.TypeCount];
|
||||||
|
FieldT.FieldKind = Def::EFieldType::DefinedEnum;
|
||||||
|
FieldT.TypeIdx = i;
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << "Unknown type token:" << std::endl << PrintLine() << std::endl;
|
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,7 +543,8 @@ Parser::Result Parser::ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx)
|
|||||||
|
|
||||||
if (SkippedNewLine) return Res;
|
if (SkippedNewLine) return Res;
|
||||||
}
|
}
|
||||||
std::cout << "Too many extra enum fields!" << std::endl;
|
LOG_ERROR(Line, "Too many extra enum fields!");
|
||||||
|
ErrorLine();
|
||||||
return Error;
|
return Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -450,16 +553,6 @@ int32_t Parser::GetRemaining()
|
|||||||
return &Buffer[BufferSize] - ReadPtr;
|
return &Buffer[BufferSize] - ReadPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Log::Assert(bool Condition, const char* Text)
|
|
||||||
{
|
|
||||||
if (!Condition)
|
|
||||||
{
|
|
||||||
std::cout << "Assertion failed: " << Text << std::endl;
|
|
||||||
bx::debugBreak();
|
|
||||||
}
|
|
||||||
return !Condition;
|
|
||||||
}
|
|
||||||
|
|
||||||
char WriteBuffer[1024 * 1024]{0};
|
char WriteBuffer[1024 * 1024]{0};
|
||||||
void TemplateWriter::Write(const char* Template, ...)
|
void TemplateWriter::Write(const char* Template, ...)
|
||||||
{
|
{
|
||||||
@@ -473,9 +566,11 @@ void TemplateWriter::Write(const char* Template, ...)
|
|||||||
Parser TestParser;
|
Parser TestParser;
|
||||||
int main(int argc, const char** argv)
|
int main(int argc, const char** argv)
|
||||||
{
|
{
|
||||||
|
LOG(0, "Hello");
|
||||||
|
|
||||||
if (argc != 3)
|
if (argc != 3)
|
||||||
{
|
{
|
||||||
std::cout << "invalid number of arguments!" << std::endl;
|
LOG(0, "invalid number of arguments!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
bx::FilePath defPath(argv[1]);
|
bx::FilePath defPath(argv[1]);
|
||||||
@@ -485,18 +580,24 @@ int main(int argc, const char** argv)
|
|||||||
bx::Error error;
|
bx::Error error;
|
||||||
if (!reader.open(defPath, &error))
|
if (!reader.open(defPath, &error))
|
||||||
{
|
{
|
||||||
std::cout << "failed to find def file at " << error.getMessage().getCPtr() << std::endl;
|
LOG(0, "failed to find def file at %s", error.getMessage().getCPtr());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TestParser.BufferSize = bx::read(&reader, TestParser.Buffer, Parser::MaxBufferSize, &error);
|
TestParser.BufferSize = bx::read(&reader, TestParser.Buffer, Parser::MaxBufferSize, &error);
|
||||||
Parser::Result Res = TestParser.Parse();
|
Parser::Result Res = TestParser.Parse();
|
||||||
|
|
||||||
if (Res == Parser::EndOfFile)
|
if (Res == Parser::OK)
|
||||||
{
|
{
|
||||||
std::cout << "Success!" << std::endl;
|
LOG_WARN(0, "Ending not at end of file, this is strange...");
|
||||||
TestParser.Definitions.GenerateCpp(outPath);
|
|
||||||
}
|
}
|
||||||
|
else if (Res == Parser::Error)
|
||||||
|
{
|
||||||
|
LOG_ERROR(0, "Aborting with error, not generating file.");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
LOG(0, "Finished parsing!");
|
||||||
|
TestParser.Definitions.GenerateCpp(outPath);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <bx/file.h>
|
#include <bx/file.h>
|
||||||
|
#include <cctype>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <iostream>
|
#include <string>
|
||||||
|
|
||||||
#include "Gen/Generated.h"
|
#include "Gen/Generated.h"
|
||||||
|
#include "Logging.h"
|
||||||
#include "bx/string.h"
|
#include "bx/string.h"
|
||||||
|
|
||||||
struct Log
|
|
||||||
{
|
|
||||||
static bool Assert(bool Condition, const char* Text);
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class TokenType : uint8_t
|
enum class TokenType : uint8_t
|
||||||
{
|
{
|
||||||
StartOfFile,
|
StartOfFile,
|
||||||
@@ -33,35 +30,62 @@ struct ParseStack
|
|||||||
}
|
}
|
||||||
bool Push(TokenType T)
|
bool Push(TokenType T)
|
||||||
{
|
{
|
||||||
if (Log::Assert(StackIdx < MaxSize - 1, "Inbalanced Push/Pop!")) return false;
|
if (StackIdx >= MaxSize - 1)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
StackIdx++;
|
StackIdx++;
|
||||||
Stack[StackIdx] = T;
|
Stack[StackIdx] = T;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
TokenType Pop()
|
TokenType Pop()
|
||||||
{
|
{
|
||||||
if (Log::Assert(StackIdx == 0, "Inbalanced Push/Pop!")) return TokenType::StartOfFile;
|
if (StackIdx != 0)
|
||||||
|
{
|
||||||
|
return TokenType::StartOfFile;
|
||||||
|
}
|
||||||
TokenType T = Stack[StackIdx];
|
TokenType T = Stack[StackIdx];
|
||||||
StackIdx--;
|
StackIdx--;
|
||||||
return T;
|
return T;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TemplateWriter
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bx::WriterI& Writer;
|
||||||
|
bx::Error& Error;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TemplateWriter(bx::WriterI& W, bx::Error& E) : Writer(W), Error(E)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Write(const char* Template, ...);
|
||||||
|
};
|
||||||
|
|
||||||
namespace Def
|
namespace Def
|
||||||
{
|
{
|
||||||
constexpr int32_t MaxNameLength = 64;
|
constexpr int32_t MaxNameLength = 64;
|
||||||
constexpr int32_t MaxFields = 64;
|
constexpr int32_t MaxFields = 64;
|
||||||
constexpr int32_t MaxExtraEnumFields = 1;
|
constexpr int32_t MaxExtraEnumFields = 1;
|
||||||
union TypeUnion
|
enum class EFieldType
|
||||||
{
|
{
|
||||||
Generated::KnownType::Enum Known;
|
Native,
|
||||||
uint32_t TypeIdx;
|
DefinedClass,
|
||||||
|
DefinedEnum
|
||||||
|
};
|
||||||
|
struct FieldType
|
||||||
|
{
|
||||||
|
EFieldType FieldKind = EFieldType::Native;
|
||||||
|
Generated::KnownType::Enum Native = Generated::KnownType::Enum::i32;
|
||||||
|
uint16_t TypeIdx = UINT16_MAX;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Type
|
struct Type
|
||||||
{
|
{
|
||||||
int32_t FieldCount = 0;
|
int32_t FieldCount = 0;
|
||||||
TypeUnion FieldTypes[MaxFields];
|
FieldType FieldTypes[MaxFields];
|
||||||
char FieldNames[MaxFields][MaxNameLength];
|
char FieldNames[MaxFields][MaxNameLength];
|
||||||
uint32_t FieldArraySizes[MaxFields]{0};
|
uint32_t FieldArraySizes[MaxFields]{0};
|
||||||
char Name[MaxNameLength]{0};
|
char Name[MaxNameLength]{0};
|
||||||
@@ -69,6 +93,7 @@ namespace Def
|
|||||||
|
|
||||||
struct Enum
|
struct Enum
|
||||||
{
|
{
|
||||||
|
FieldType EnumType;
|
||||||
int32_t EntryCount = 0;
|
int32_t EntryCount = 0;
|
||||||
char EntryNames[MaxFields][MaxNameLength];
|
char EntryNames[MaxFields][MaxNameLength];
|
||||||
int32_t ExtraStringFieldCount = 0;
|
int32_t ExtraStringFieldCount = 0;
|
||||||
@@ -81,11 +106,13 @@ namespace Def
|
|||||||
struct DefinitionFile
|
struct DefinitionFile
|
||||||
{
|
{
|
||||||
static constexpr int32_t MaxTypes = 256;
|
static constexpr int32_t MaxTypes = 256;
|
||||||
void PrintTypeName(char* buf, int32_t bufSize, Def::TypeUnion type);
|
void PrintTypeName(char* buf, int32_t bufSize, const Def::FieldType& type);
|
||||||
|
void WriteEnums(TemplateWriter& Template);
|
||||||
|
void WriteTypes(TemplateWriter& Template);
|
||||||
void GenerateCpp(const bx::FilePath& outDir);
|
void GenerateCpp(const bx::FilePath& outDir);
|
||||||
|
|
||||||
Def::Type Types[MaxTypes];
|
Def::Type Types[MaxTypes];
|
||||||
int32_t TypeCount = 0;
|
uint16_t TypeCount = 0;
|
||||||
Def::Enum Enums[MaxTypes];
|
Def::Enum Enums[MaxTypes];
|
||||||
int32_t EnumCount = 0;
|
int32_t EnumCount = 0;
|
||||||
};
|
};
|
||||||
@@ -110,6 +137,7 @@ class Parser
|
|||||||
int32_t BufferSize = 0;
|
int32_t BufferSize = 0;
|
||||||
char Buffer[MaxBufferSize]{0};
|
char Buffer[MaxBufferSize]{0};
|
||||||
char* ReadPtr = &Buffer[0];
|
char* ReadPtr = &Buffer[0];
|
||||||
|
uint32_t Line = 0;
|
||||||
|
|
||||||
DefinitionFile Definitions;
|
DefinitionFile Definitions;
|
||||||
ParseStack Stack;
|
ParseStack Stack;
|
||||||
@@ -121,7 +149,7 @@ class Parser
|
|||||||
int32_t GetRemaining();
|
int32_t GetRemaining();
|
||||||
Result SkipWhitespace(bool* SkippedNewLine = nullptr);
|
Result SkipWhitespace(bool* SkippedNewLine = nullptr);
|
||||||
Result SkipLine();
|
Result SkipLine();
|
||||||
bool CmpAdvance(bx::StringView expect, Result& Res);
|
bool CmpAdvance(bx::StringView expect, Result& Res, bool RequireGap = false);
|
||||||
Result ExpectChar(bx::StringView expect);
|
Result ExpectChar(bx::StringView expect);
|
||||||
Result Advance(int32_t Amount);
|
Result Advance(int32_t Amount);
|
||||||
Result HandleFileStart();
|
Result HandleFileStart();
|
||||||
@@ -129,10 +157,12 @@ class Parser
|
|||||||
Result HandleEnum();
|
Result HandleEnum();
|
||||||
Result ReadName(char* Target);
|
Result ReadName(char* Target);
|
||||||
Result ReadUint(uint32_t& Out);
|
Result ReadUint(uint32_t& Out);
|
||||||
|
Result ReadNativeFieldType(Def::FieldType& FieldT);
|
||||||
|
Result ReadDefinedFieldType(Def::FieldType& FieldT);
|
||||||
Result ReadTypeToken();
|
Result ReadTypeToken();
|
||||||
Result ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx);
|
Result ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx);
|
||||||
|
|
||||||
std::string PrintLine()
|
void ErrorLine()
|
||||||
{
|
{
|
||||||
char line[64]{0};
|
char line[64]{0};
|
||||||
for (int32_t i = 0; i < sizeof(line) - 1; ++i)
|
for (int32_t i = 0; i < sizeof(line) - 1; ++i)
|
||||||
@@ -141,20 +171,6 @@ class Parser
|
|||||||
if (Advance(1) != Result::OK) break;
|
if (Advance(1) != Result::OK) break;
|
||||||
if (*ReadPtr == '\n' || *ReadPtr == '\r') break;
|
if (*ReadPtr == '\n' || *ReadPtr == '\r') break;
|
||||||
}
|
}
|
||||||
return std::string{line};
|
LOG_ERROR(Line, "%s", line);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class TemplateWriter
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
bx::WriterI& Writer;
|
|
||||||
bx::Error& Error;
|
|
||||||
|
|
||||||
public:
|
|
||||||
TemplateWriter(bx::WriterI& W, bx::Error& E) : Writer(W), Error(E)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Write(const char* Template, ...);
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -10,16 +10,16 @@ type ElemPos
|
|||||||
u8 ElemIdx
|
u8 ElemIdx
|
||||||
}
|
}
|
||||||
|
|
||||||
enum PuzzleElementType Type(u8)
|
enum PuzzleElementType(u8)
|
||||||
{
|
{
|
||||||
None,
|
None GameName("Empty")
|
||||||
WaterIn,
|
WaterIn GameName("Water Source")
|
||||||
WaterGoal,
|
WaterGoal GameName("Water Goal")
|
||||||
WaterChannel,
|
WaterChannel GameName("Water Channel")
|
||||||
ElectricIn,
|
ElectricIn GameName("Electricity Source")
|
||||||
ElectricGoal,
|
ElectricGoal GameName("Electricity Goal")
|
||||||
Blocked,
|
Blocked GameName("Blocked")
|
||||||
Bridge,
|
Bridge GameName("Bridge")
|
||||||
}
|
}
|
||||||
|
|
||||||
type PuzzleNode
|
type PuzzleNode
|
||||||
@@ -45,6 +45,14 @@ type PuzzleCardStack
|
|||||||
u8 UsedCount
|
u8 UsedCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type PlacedPuzzleCard
|
||||||
|
{
|
||||||
|
StaticPuzzleCardHandle RefCard
|
||||||
|
PuzPos Position
|
||||||
|
u8 Rotation
|
||||||
|
b IsLocked
|
||||||
|
}
|
||||||
|
|
||||||
type PuzzleData
|
type PuzzleData
|
||||||
{
|
{
|
||||||
u8 WidthTiles
|
u8 WidthTiles
|
||||||
|
|||||||
@@ -3,12 +3,89 @@
|
|||||||
|
|
||||||
namespace Generated
|
namespace Generated
|
||||||
{
|
{
|
||||||
|
struct PuzzleElementType
|
||||||
|
{
|
||||||
|
static constexpr int32_t EntryCount = 8;
|
||||||
|
enum class Enum : int32_t
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
WaterIn,
|
||||||
|
WaterGoal,
|
||||||
|
WaterChannel,
|
||||||
|
ElectricIn,
|
||||||
|
ElectricGoal,
|
||||||
|
Blocked,
|
||||||
|
Bridge,
|
||||||
|
};
|
||||||
|
static constexpr char EntryNames[EntryCount][64]
|
||||||
|
{
|
||||||
|
"None",
|
||||||
|
"WaterIn",
|
||||||
|
"WaterGoal",
|
||||||
|
"WaterChannel",
|
||||||
|
"ElectricIn",
|
||||||
|
"ElectricGoal",
|
||||||
|
"Blocked",
|
||||||
|
"Bridge",
|
||||||
|
};
|
||||||
|
static constexpr char GameName[EntryCount][64]
|
||||||
|
{
|
||||||
|
"Empty",
|
||||||
|
"Water Source",
|
||||||
|
"Water Goal",
|
||||||
|
"Water Channel",
|
||||||
|
"Electricity Source",
|
||||||
|
"Electricity Goal",
|
||||||
|
"Blocked",
|
||||||
|
"Bridge",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
struct PuzPos
|
||||||
|
{
|
||||||
|
int8_t X = {};
|
||||||
|
int8_t Y = {};
|
||||||
|
};
|
||||||
|
struct ElemPos
|
||||||
|
{
|
||||||
|
PuzPos Position = {};
|
||||||
|
uint8_t ElemIdx = {};
|
||||||
|
};
|
||||||
|
struct PuzzleNode
|
||||||
|
{
|
||||||
|
PuzzleElementType PlacedTypes = {};
|
||||||
|
};
|
||||||
|
struct StaticPuzzleCard
|
||||||
|
{
|
||||||
|
PuzzleNode Nodes[8] = {};
|
||||||
|
uint16_t ModelHandle = {};
|
||||||
|
};
|
||||||
|
struct StaticPuzzleCardHandle
|
||||||
|
{
|
||||||
|
uint16_t Idx = {};
|
||||||
|
};
|
||||||
|
struct PuzzleCardStack
|
||||||
|
{
|
||||||
|
StaticPuzzleCardHandle RefCard = {};
|
||||||
|
uint8_t MaxAvailableCount = {};
|
||||||
|
uint8_t UsedCount = {};
|
||||||
|
};
|
||||||
|
struct PlacedPuzzleCard
|
||||||
|
{
|
||||||
|
StaticPuzzleCardHandle RefCard = {};
|
||||||
|
PuzPos Position = {};
|
||||||
|
uint8_t Rotation = {};
|
||||||
|
bool IsLocked = {};
|
||||||
|
};
|
||||||
struct PuzzleData
|
struct PuzzleData
|
||||||
{
|
{
|
||||||
uint8_t WidthTiles = {};
|
uint8_t WidthTiles = {};
|
||||||
uint8_t HeightTiles = {};
|
uint8_t HeightTiles = {};
|
||||||
uint32_t AvailableCardCount = {};
|
uint32_t AvailableCardCount = {};
|
||||||
|
PuzzleCardStack AvailableCards[8] = {};
|
||||||
uint32_t PlacedCardCount = {};
|
uint32_t PlacedCardCount = {};
|
||||||
|
PlacedPuzzleCard PlacedCards[8] = {};
|
||||||
|
PuzzleNode PlacedNodes[8] = {};
|
||||||
uint32_t GoalPositionCount = {};
|
uint32_t GoalPositionCount = {};
|
||||||
|
ElemPos GoalPositions = {};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
tools/minidef.rdbg
Normal file
BIN
tools/minidef.rdbg
Normal file
Binary file not shown.
Reference in New Issue
Block a user