diff --git a/src/dependency/minidef/CMakeLists.txt b/src/dependency/minidef/CMakeLists.txt index c136c5b..661277a 100644 --- a/src/dependency/minidef/CMakeLists.txt +++ b/src/dependency/minidef/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) 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 "${CMAKE_CURRENT_SOURCE_DIR}/../bgfx.cmake/bx/include/" "${CMAKE_CURRENT_SOURCE_DIR}/../bgfx.cmake/bx/include/compat/msvc/" diff --git a/src/dependency/minidef/Logging.h b/src/dependency/minidef/Logging.h new file mode 100644 index 0000000..2029ef4 --- /dev/null +++ b/src/dependency/minidef/Logging.h @@ -0,0 +1,18 @@ +#pragma once + +#include + +#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, ...); +}; diff --git a/src/dependency/minidef/mini.def b/src/dependency/minidef/mini.def index 0df4fe5..7f1a528 100644 --- a/src/dependency/minidef/mini.def +++ b/src/dependency/minidef/mini.def @@ -1,11 +1,17 @@ +type Test +{ + u32 Number +} + type Texture { u32 Width u32 Height - str Test Arr(3) + str StrTest Arr(3) + Test T } -enum KnownType +enum KnownType(u8) { i8 CName("int8_t") i16 CName("int16_t") @@ -15,6 +21,7 @@ enum KnownType u16 CName("uint16_t") u32 CName("uint32_t") u64 CName("uint64_t") + b CName("bool") f32 CName("float") f64 CName("double") str CName("char") diff --git a/src/dependency/minidef/src/Gen/Generated.h b/src/dependency/minidef/src/Gen/Generated.h index 8883568..5535533 100644 --- a/src/dependency/minidef/src/Gen/Generated.h +++ b/src/dependency/minidef/src/Gen/Generated.h @@ -3,16 +3,21 @@ namespace Generated { + struct Test + { + uint32_t Number = {}; + }; struct Texture { uint32_t Width = {}; uint32_t Height = {}; - char Test[3] = {}; + char StrTest[3] = {}; + Test T = {}; }; struct KnownType { - static constexpr int32_t EntryCount = 11; - enum class Enum + static constexpr int32_t EntryCount = 12; + enum class Enum : int32_t { i8, i16, @@ -22,6 +27,7 @@ namespace Generated u16, u32, u64, + b, f32, f64, str, @@ -36,6 +42,7 @@ namespace Generated "u16", "u32", "u64", + "b", "f32", "f64", "str", @@ -50,6 +57,7 @@ namespace Generated "uint16_t", "uint32_t", "uint64_t", + "bool", "float", "double", "char", diff --git a/src/dependency/minidef/src/Logging.cpp b/src/dependency/minidef/src/Logging.cpp new file mode 100644 index 0000000..affaae3 --- /dev/null +++ b/src/dependency/minidef/src/Logging.cpp @@ -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); +} diff --git a/src/dependency/minidef/src/Logging.h b/src/dependency/minidef/src/Logging.h new file mode 100644 index 0000000..434aa87 --- /dev/null +++ b/src/dependency/minidef/src/Logging.h @@ -0,0 +1,19 @@ +#pragma once + +#include + +#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, ...); +}; diff --git a/src/dependency/minidef/src/MiniDef.cpp b/src/dependency/minidef/src/MiniDef.cpp index 94c6a98..1f9befa 100644 --- a/src/dependency/minidef/src/MiniDef.cpp +++ b/src/dependency/minidef/src/MiniDef.cpp @@ -1,4 +1,7 @@ +#include "Gen/Generated.h" +#include "Logging.h" #include "MiniDef.h" + #include "bx/string.h" #include #include @@ -27,11 +30,11 @@ namespace Generated R"END( }; )END"; - constexpr char EnumHeader2[] = + constexpr char EnumHeader3[] = R"END( struct %s { static constexpr int32_t EntryCount = %u; - enum class Enum + enum class Enum : %s { )END"; @@ -59,51 +62,37 @@ namespace Generated )END"; } // 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) { 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) { Template.Write(WriteTemplates::EnumField1, e.EntryNames[entryIdx]); @@ -126,29 +115,85 @@ void DefinitionFile::GenerateCpp(const bx::FilePath& outDir) 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); 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(); + const char* ptr = expect.getPtr(); + + // abort if expect longer than remaining text if (size > GetRemaining()) { - std::cout << "Failed to match " << expect.getPtr() << ", " << size << "<" << GetRemaining() << std::endl; return false; } + + // start matching int32_t i = 0; for (; i < size; ++i) { + // if expect has 0 byte, go back one idx, we succeded if (expect.getPtr()[i] == 0) { i--; break; } + + // check match 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); return true; } @@ -158,7 +203,8 @@ Parser::Result Parser::ExpectChar(bx::StringView expect) Result Res = OK; if (!CmpAdvance(expect, Res)) { - std::cout << "Expected " << expect.getPtr() << std::endl; + LOG_ERROR(Line, "Expected: %s", expect.getPtr()); + ErrorLine(); return Error; } return Res; @@ -170,7 +216,11 @@ Parser::Result Parser::SkipWhitespace(bool* SkippedNewLine) for (int32_t i = 0; i < Remaining; ++i) { 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; ReadPtr++; } @@ -236,19 +286,19 @@ Parser::Result Parser::Parse() Parser::Result Parser::HandleFileStart() { Result Res = OK; - if (CmpAdvance("type", Res) && Res == OK) + if (CmpAdvance("type", Res, true) && Res == OK) { return HandleType(); } if (Res != OK) return Res; - if (CmpAdvance("enum", Res) && Res == OK) + if (CmpAdvance("enum", Res, true) && Res == OK) { return HandleEnum(); } if (Res != OK) return Res; - std::cout << "Only valid here: type or enum!"; + LOG(Line, "Only valid here: type or enum!"); return Error; } @@ -260,7 +310,8 @@ Parser::Result Parser::HandleType() if (Definitions.TypeCount >= DefinitionFile::MaxTypes) { - std::cout << "Too many types!" << std::endl; + LOG_ERROR(Line, "Too many types!"); + ErrorLine(); return Error; } Def::Type& t = Definitions.Types[Definitions.TypeCount]; @@ -274,7 +325,8 @@ Parser::Result Parser::HandleType() { 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; } CHECK(ReadTypeToken()); @@ -287,7 +339,7 @@ Parser::Result Parser::HandleType() if (!NewLine) { Result Res; - if (CmpAdvance("Arr", Res) && Res == Result::OK) + if (CmpAdvance("Arr", Res, true) && Res == Result::OK) { CHECK(ExpectChar("(")); CHECK(ReadUint(t.FieldArraySizes[t.FieldCount])); @@ -310,21 +362,31 @@ Parser::Result Parser::HandleEnum() if (Definitions.EnumCount >= DefinitionFile::MaxTypes) { - std::cout << "Too many enums!" << std::endl; + LOG_ERROR(Line, "Too many enums!"); + ErrorLine(); return Error; } Def::Enum& e = Definitions.Enums[Definitions.EnumCount]; CHECK(ReadName(e.Name)); - CHECK(SkipWhitespace()); + + if (CmpAdvance("(", Res) && Res == OK) + { + CHECK(SkipWhitespace()); + Def::FieldType field; + CHECK(ReadNativeFieldType(field)); + CHECK(SkipWhitespace()); + CHECK(ExpectChar(")")); + CHECK(SkipWhitespace()); + } + CHECK(ExpectChar("{")); CHECK(SkipWhitespace()); - while (!CmpAdvance("}", Res)) { if (e.EntryCount >= Def::MaxFields) { - std::cout << "Too many fields in enum!" << std::endl; + LOG_ERROR(Line, "Too many fields in enum!"); return Error; } CHECK(ReadName(e.EntryNames[e.EntryCount])); @@ -345,7 +407,8 @@ Parser::Result Parser::ReadName(char* Target) { if (i == 0) { - std::cout << "Empty names are not allowed!" << std::endl; + LOG_ERROR(Line, "Empty names are not allowed!"); + ErrorLine(); return Error; } return OK; @@ -356,7 +419,8 @@ Parser::Result Parser::ReadName(char* Target) } else { - std::cout << "Name too long!" << std::endl; + LOG_ERROR(Line, "Name too long!"); + ErrorLine(); return Error; } ReadPtr++; @@ -381,30 +445,68 @@ Parser::Result Parser::ReadUint(uint32_t& Out) } if (Written == 0) { - std::cout << "No digits for uint: " << PrintLine() << std::endl; + LOG_ERROR(Line, "No digits for uint!"); + ErrorLine(); return Result::Error; } 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::OK; } 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; 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]; - t.FieldTypes[t.FieldCount].Known = Generated::KnownType::Enum(i); + FieldT.FieldKind = Def::EFieldType::Native; + 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; } } - std::cout << "Unknown type token:" << std::endl << PrintLine() << std::endl; return Error; } @@ -441,7 +543,8 @@ Parser::Result Parser::ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx) if (SkippedNewLine) return Res; } - std::cout << "Too many extra enum fields!" << std::endl; + LOG_ERROR(Line, "Too many extra enum fields!"); + ErrorLine(); return Error; } @@ -450,16 +553,6 @@ int32_t Parser::GetRemaining() 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}; void TemplateWriter::Write(const char* Template, ...) { @@ -473,9 +566,11 @@ void TemplateWriter::Write(const char* Template, ...) Parser TestParser; int main(int argc, const char** argv) { + LOG(0, "Hello"); + if (argc != 3) { - std::cout << "invalid number of arguments!" << std::endl; + LOG(0, "invalid number of arguments!"); return 1; } bx::FilePath defPath(argv[1]); @@ -485,18 +580,24 @@ int main(int argc, const char** argv) bx::Error 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; } TestParser.BufferSize = bx::read(&reader, TestParser.Buffer, Parser::MaxBufferSize, &error); Parser::Result Res = TestParser.Parse(); - if (Res == Parser::EndOfFile) + if (Res == Parser::OK) { - std::cout << "Success!" << std::endl; - TestParser.Definitions.GenerateCpp(outPath); + LOG_WARN(0, "Ending not at end of file, this is strange..."); } + 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; } diff --git a/src/dependency/minidef/src/MiniDef.h b/src/dependency/minidef/src/MiniDef.h index 828ba57..cde56f3 100644 --- a/src/dependency/minidef/src/MiniDef.h +++ b/src/dependency/minidef/src/MiniDef.h @@ -1,16 +1,13 @@ #pragma once #include +#include #include -#include +#include #include "Gen/Generated.h" +#include "Logging.h" #include "bx/string.h" -struct Log -{ - static bool Assert(bool Condition, const char* Text); -}; - enum class TokenType : uint8_t { StartOfFile, @@ -33,35 +30,62 @@ struct ParseStack } bool Push(TokenType T) { - if (Log::Assert(StackIdx < MaxSize - 1, "Inbalanced Push/Pop!")) return false; + if (StackIdx >= MaxSize - 1) + { + return false; + } StackIdx++; Stack[StackIdx] = T; return true; } TokenType Pop() { - if (Log::Assert(StackIdx == 0, "Inbalanced Push/Pop!")) return TokenType::StartOfFile; + if (StackIdx != 0) + { + return TokenType::StartOfFile; + } TokenType T = Stack[StackIdx]; StackIdx--; 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 { constexpr int32_t MaxNameLength = 64; constexpr int32_t MaxFields = 64; constexpr int32_t MaxExtraEnumFields = 1; - union TypeUnion + enum class EFieldType { - Generated::KnownType::Enum Known; - uint32_t TypeIdx; + Native, + DefinedClass, + DefinedEnum + }; + struct FieldType + { + EFieldType FieldKind = EFieldType::Native; + Generated::KnownType::Enum Native = Generated::KnownType::Enum::i32; + uint16_t TypeIdx = UINT16_MAX; }; struct Type { int32_t FieldCount = 0; - TypeUnion FieldTypes[MaxFields]; + FieldType FieldTypes[MaxFields]; char FieldNames[MaxFields][MaxNameLength]; uint32_t FieldArraySizes[MaxFields]{0}; char Name[MaxNameLength]{0}; @@ -69,6 +93,7 @@ namespace Def struct Enum { + FieldType EnumType; int32_t EntryCount = 0; char EntryNames[MaxFields][MaxNameLength]; int32_t ExtraStringFieldCount = 0; @@ -81,11 +106,13 @@ namespace Def struct DefinitionFile { 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); Def::Type Types[MaxTypes]; - int32_t TypeCount = 0; + uint16_t TypeCount = 0; Def::Enum Enums[MaxTypes]; int32_t EnumCount = 0; }; @@ -110,6 +137,7 @@ class Parser int32_t BufferSize = 0; char Buffer[MaxBufferSize]{0}; char* ReadPtr = &Buffer[0]; + uint32_t Line = 0; DefinitionFile Definitions; ParseStack Stack; @@ -121,7 +149,7 @@ class Parser int32_t GetRemaining(); Result SkipWhitespace(bool* SkippedNewLine = nullptr); 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 Advance(int32_t Amount); Result HandleFileStart(); @@ -129,10 +157,12 @@ class Parser Result HandleEnum(); Result ReadName(char* Target); Result ReadUint(uint32_t& Out); + Result ReadNativeFieldType(Def::FieldType& FieldT); + Result ReadDefinedFieldType(Def::FieldType& FieldT); Result ReadTypeToken(); Result ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx); - std::string PrintLine() + void ErrorLine() { char line[64]{0}; for (int32_t i = 0; i < sizeof(line) - 1; ++i) @@ -141,20 +171,6 @@ class Parser if (Advance(1) != Result::OK) 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, ...); -}; diff --git a/src/game/mini.def b/src/game/mini.def index e96478c..1ce0039 100644 --- a/src/game/mini.def +++ b/src/game/mini.def @@ -10,16 +10,16 @@ type ElemPos u8 ElemIdx } -enum PuzzleElementType Type(u8) +enum PuzzleElementType(u8) { - None, - WaterIn, - WaterGoal, - WaterChannel, - ElectricIn, - ElectricGoal, - Blocked, - Bridge, + None GameName("Empty") + WaterIn GameName("Water Source") + WaterGoal GameName("Water Goal") + WaterChannel GameName("Water Channel") + ElectricIn GameName("Electricity Source") + ElectricGoal GameName("Electricity Goal") + Blocked GameName("Blocked") + Bridge GameName("Bridge") } type PuzzleNode @@ -45,6 +45,14 @@ type PuzzleCardStack u8 UsedCount } +type PlacedPuzzleCard +{ + StaticPuzzleCardHandle RefCard + PuzPos Position + u8 Rotation + b IsLocked +} + type PuzzleData { u8 WidthTiles diff --git a/src/gen/Generated.h b/src/gen/Generated.h index 99f0ef5..df759a2 100644 --- a/src/gen/Generated.h +++ b/src/gen/Generated.h @@ -3,12 +3,89 @@ 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 { uint8_t WidthTiles = {}; uint8_t HeightTiles = {}; uint32_t AvailableCardCount = {}; + PuzzleCardStack AvailableCards[8] = {}; uint32_t PlacedCardCount = {}; + PlacedPuzzleCard PlacedCards[8] = {}; + PuzzleNode PlacedNodes[8] = {}; uint32_t GoalPositionCount = {}; + ElemPos GoalPositions = {}; }; } diff --git a/tools/minidef.rdbg b/tools/minidef.rdbg index f8e24b2..a12eaf4 100644 Binary files a/tools/minidef.rdbg and b/tools/minidef.rdbg differ