minidef
This commit is contained in:
@@ -19,18 +19,16 @@ file(GLOB imgui_backend_sdl
|
|||||||
dependency/imgui/backends/imgui_impl_sdl3.h
|
dependency/imgui/backends/imgui_impl_sdl3.h
|
||||||
dependency/imgui/backends/imgui_impl_sdl3.cpp)
|
dependency/imgui/backends/imgui_impl_sdl3.cpp)
|
||||||
|
|
||||||
|
add_subdirectory("${CMAKE_SOURCE_DIR}/dependency/minidef")
|
||||||
|
|
||||||
# Engine
|
# Engine
|
||||||
file(GLOB_RECURSE sources_engine engine/*.cpp engine/*.h)
|
file(GLOB_RECURSE sources_engine engine/*.cpp engine/*.h)
|
||||||
add_executable(PuzGameEngine ${sources_engine})
|
add_executable(PuzGameEngine ${sources_engine})
|
||||||
set_property(TARGET PuzGameEngine PROPERTY CXX_STANDARD 17)
|
set_property(TARGET PuzGameEngine PROPERTY CXX_STANDARD 17)
|
||||||
target_include_directories(PuzGameEngine PUBLIC)
|
target_include_directories(PuzGameEngine PUBLIC)
|
||||||
#file(COPY ${data} DESTINATION resources)
|
|
||||||
|
|
||||||
#target_compile_options(PuzGameEngine PUBLIC xyz)
|
|
||||||
#file(GLOB_RECURSE data resources/xyz)
|
|
||||||
|
|
||||||
# Game
|
# Game
|
||||||
file(GLOB_RECURSE sources_game game/*.cpp game/*.h)
|
file(GLOB_RECURSE sources_game game/*.cpp game/*.h gen/*.cpp gen/*.h)
|
||||||
file(GLOB source_singleheader dependency/tinygltf/stb_image.h dependency/tinygltf/stb_image_write.h dependency/tinygltf/json.hpp dependency/tinygltf/tiny_gltf.h)
|
file(GLOB source_singleheader dependency/tinygltf/stb_image.h dependency/tinygltf/stb_image_write.h dependency/tinygltf/json.hpp dependency/tinygltf/tiny_gltf.h)
|
||||||
add_library(PuzGame SHARED ${sources_game} ${source_singleheader} ${imgui_sources} ${imgui_backend_sdl})
|
add_library(PuzGame SHARED ${sources_game} ${source_singleheader} ${imgui_sources} ${imgui_backend_sdl})
|
||||||
set_property(TARGET PuzGame PROPERTY CXX_STANDARD 17)
|
set_property(TARGET PuzGame PROPERTY CXX_STANDARD 17)
|
||||||
|
|||||||
9
src/dependency/minidef/CMakeLists.txt
Normal file
9
src/dependency/minidef/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.10)
|
||||||
|
project(MiniDefProj)
|
||||||
|
add_executable(minidef "${CMAKE_CURRENT_SOURCE_DIR}/src/MiniDef.cpp")
|
||||||
|
target_include_directories(minidef PRIVATE
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../bgfx.cmake/bx/include/"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../bgfx.cmake/bx/include/compat/msvc/"
|
||||||
|
)
|
||||||
|
target_link_libraries(minidef bx)
|
||||||
|
target_compile_definitions(minidef PRIVATE "$<$<CONFIG:DEBUG>:BX_CONFIG_DEBUG=1>$<$<CONFIG:RELEASE>:BX_CONFIG_DEBUG=0>")
|
||||||
21
src/dependency/minidef/mini.def
Normal file
21
src/dependency/minidef/mini.def
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
type Texture
|
||||||
|
{
|
||||||
|
u32 Width
|
||||||
|
u32 Height
|
||||||
|
str Test Arr(3)
|
||||||
|
}
|
||||||
|
|
||||||
|
enum KnownType
|
||||||
|
{
|
||||||
|
i8 CName("int8_t")
|
||||||
|
i16 CName("int16_t")
|
||||||
|
i32 CName("int32_t")
|
||||||
|
i64 CName("int64_t")
|
||||||
|
u8 CName("uint8_t")
|
||||||
|
u16 CName("uint16_t")
|
||||||
|
u32 CName("uint32_t")
|
||||||
|
u64 CName("uint64_t")
|
||||||
|
f32 CName("float")
|
||||||
|
f64 CName("double")
|
||||||
|
str CName("char")
|
||||||
|
}
|
||||||
2
src/dependency/minidef/src/Gen/Def.h
Normal file
2
src/dependency/minidef/src/Gen/Def.h
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
58
src/dependency/minidef/src/Gen/Generated.h
Normal file
58
src/dependency/minidef/src/Gen/Generated.h
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Def.h"
|
||||||
|
|
||||||
|
namespace Generated
|
||||||
|
{
|
||||||
|
struct Texture
|
||||||
|
{
|
||||||
|
uint32_t Width = {};
|
||||||
|
uint32_t Height = {};
|
||||||
|
char Test[3] = {};
|
||||||
|
};
|
||||||
|
struct KnownType
|
||||||
|
{
|
||||||
|
static constexpr int32_t EntryCount = 11;
|
||||||
|
enum class Enum
|
||||||
|
{
|
||||||
|
i8,
|
||||||
|
i16,
|
||||||
|
i32,
|
||||||
|
i64,
|
||||||
|
u8,
|
||||||
|
u16,
|
||||||
|
u32,
|
||||||
|
u64,
|
||||||
|
f32,
|
||||||
|
f64,
|
||||||
|
str,
|
||||||
|
};
|
||||||
|
static constexpr char EntryNames[EntryCount][64]
|
||||||
|
{
|
||||||
|
"i8",
|
||||||
|
"i16",
|
||||||
|
"i32",
|
||||||
|
"i64",
|
||||||
|
"u8",
|
||||||
|
"u16",
|
||||||
|
"u32",
|
||||||
|
"u64",
|
||||||
|
"f32",
|
||||||
|
"f64",
|
||||||
|
"str",
|
||||||
|
};
|
||||||
|
static constexpr char CName[EntryCount][64]
|
||||||
|
{
|
||||||
|
"int8_t",
|
||||||
|
"int16_t",
|
||||||
|
"int32_t",
|
||||||
|
"int64_t",
|
||||||
|
"uint8_t",
|
||||||
|
"uint16_t",
|
||||||
|
"uint32_t",
|
||||||
|
"uint64_t",
|
||||||
|
"float",
|
||||||
|
"double",
|
||||||
|
"char",
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
503
src/dependency/minidef/src/MiniDef.cpp
Normal file
503
src/dependency/minidef/src/MiniDef.cpp
Normal file
@@ -0,0 +1,503 @@
|
|||||||
|
#include "MiniDef.h"
|
||||||
|
#include "bx/string.h"
|
||||||
|
#include <bx/filepath.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace WriteTemplates
|
||||||
|
{
|
||||||
|
constexpr char FileHeader[] =
|
||||||
|
R"END(#pragma once
|
||||||
|
#include "Def.h"
|
||||||
|
|
||||||
|
namespace Generated
|
||||||
|
{
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char StructHeader1[] =
|
||||||
|
R"END( struct %s
|
||||||
|
{
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char StructField4[] =
|
||||||
|
R"END( %s %s%s = %s;
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char StructEnd[] =
|
||||||
|
R"END( };
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char EnumHeader2[] =
|
||||||
|
R"END( struct %s
|
||||||
|
{
|
||||||
|
static constexpr int32_t EntryCount = %u;
|
||||||
|
enum class Enum
|
||||||
|
{
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char EnumField1[] =
|
||||||
|
R"END( %s,
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char EnumNamesStart2[] =
|
||||||
|
R"END( };
|
||||||
|
static constexpr char %s[EntryCount][%u]
|
||||||
|
{
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char EnumNamesEntry1[] =
|
||||||
|
R"END( "%s",
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char EnumNamesEnd[] =
|
||||||
|
R"END( };
|
||||||
|
};
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char FileEnd[] =
|
||||||
|
R"END(}
|
||||||
|
)END";
|
||||||
|
} // namespace WriteTemplates
|
||||||
|
|
||||||
|
void DefinitionFile::PrintTypeName(char* buf, int32_t bufSize, Def::TypeUnion type)
|
||||||
|
{
|
||||||
|
if (int32_t(type.Known) < Generated::KnownType::EntryCount)
|
||||||
|
{
|
||||||
|
bx::strCopy(buf, bufSize, Generated::KnownType::CName[size_t(type.Known)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DefinitionFile::GenerateCpp(const bx::FilePath& outDir)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx)
|
||||||
|
{
|
||||||
|
Template.Write(WriteTemplates::EnumField1, e.EntryNames[entryIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Template.Write(WriteTemplates::EnumNamesStart2, "EntryNames", Def::MaxNameLength);
|
||||||
|
for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx)
|
||||||
|
{
|
||||||
|
Template.Write(WriteTemplates::EnumNamesEntry1, e.EntryNames[entryIdx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int32_t extraIdx = 0; extraIdx < e.ExtraStringFieldCount; ++extraIdx)
|
||||||
|
{
|
||||||
|
Template.Write(WriteTemplates::EnumNamesStart2, e.ExtraStringFieldNames[extraIdx], Def::MaxNameLength);
|
||||||
|
for (int32_t entryIdx = 0; entryIdx < e.EntryCount; ++entryIdx)
|
||||||
|
{
|
||||||
|
Template.Write(WriteTemplates::EnumNamesEntry1, e.ExtraStringFields[entryIdx][extraIdx]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Template.Write(WriteTemplates::EnumNamesEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
Template.Write(WriteTemplates::FileEnd);
|
||||||
|
writer.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Parser::CmpAdvance(bx::StringView expect, Result& Res)
|
||||||
|
{
|
||||||
|
uint32_t size = expect.getLength();
|
||||||
|
if (size > GetRemaining())
|
||||||
|
{
|
||||||
|
std::cout << "Failed to match " << expect.getPtr() << ", " << size << "<" << GetRemaining() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
int32_t i = 0;
|
||||||
|
for (; i < size; ++i)
|
||||||
|
{
|
||||||
|
if (expect.getPtr()[i] == 0)
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (expect.getPtr()[i] != ReadPtr[i]) return false;
|
||||||
|
}
|
||||||
|
Res = Advance(i);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::ExpectChar(bx::StringView expect)
|
||||||
|
{
|
||||||
|
Result Res = OK;
|
||||||
|
if (!CmpAdvance(expect, Res))
|
||||||
|
{
|
||||||
|
std::cout << "Expected " << expect.getPtr() << std::endl;
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::SkipWhitespace(bool* SkippedNewLine)
|
||||||
|
{
|
||||||
|
int32_t Remaining = GetRemaining();
|
||||||
|
for (int32_t i = 0; i < Remaining; ++i)
|
||||||
|
{
|
||||||
|
if (*ReadPtr == 0) return EndOfFile;
|
||||||
|
if (SkippedNewLine != nullptr && (*ReadPtr == '\r' || *ReadPtr == '\n')) *SkippedNewLine = true;
|
||||||
|
if (isgraph(*ReadPtr)) return OK;
|
||||||
|
ReadPtr++;
|
||||||
|
}
|
||||||
|
return EndOfFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::SkipLine()
|
||||||
|
{
|
||||||
|
int32_t Remaining = GetRemaining();
|
||||||
|
for (int32_t i = 0; i < Remaining; ++i)
|
||||||
|
{
|
||||||
|
if (*ReadPtr == 0) return EndOfFile;
|
||||||
|
if (*ReadPtr == '\n' && i < Remaining - 1)
|
||||||
|
{
|
||||||
|
ReadPtr++;
|
||||||
|
if (*ReadPtr == 0) return EndOfFile;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
ReadPtr++;
|
||||||
|
}
|
||||||
|
return EndOfFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::Advance(int32_t Amount)
|
||||||
|
{
|
||||||
|
int32_t Remaining = GetRemaining();
|
||||||
|
if (Amount > Remaining)
|
||||||
|
{
|
||||||
|
ReadPtr += Remaining;
|
||||||
|
return EndOfFile;
|
||||||
|
}
|
||||||
|
ReadPtr += Amount;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define CHECK(x) \
|
||||||
|
Res = x; \
|
||||||
|
if (Res != OK) return Res;
|
||||||
|
|
||||||
|
Parser::Result Parser::Parse()
|
||||||
|
{
|
||||||
|
ReadPtr = &Buffer[0];
|
||||||
|
Parser::Result Res = Parser::OK;
|
||||||
|
while (Res == Parser::OK)
|
||||||
|
{
|
||||||
|
Res = SkipWhitespace();
|
||||||
|
if (Res == Parser::OK)
|
||||||
|
{
|
||||||
|
// Start of Line
|
||||||
|
if (*ReadPtr == '#')
|
||||||
|
{
|
||||||
|
Res = SkipLine();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Res = HandleFileStart();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::HandleFileStart()
|
||||||
|
{
|
||||||
|
Result Res = OK;
|
||||||
|
if (CmpAdvance("type", Res) && Res == OK)
|
||||||
|
{
|
||||||
|
return HandleType();
|
||||||
|
}
|
||||||
|
if (Res != OK) return Res;
|
||||||
|
|
||||||
|
if (CmpAdvance("enum", Res) && Res == OK)
|
||||||
|
{
|
||||||
|
return HandleEnum();
|
||||||
|
}
|
||||||
|
if (Res != OK) return Res;
|
||||||
|
|
||||||
|
std::cout << "Only valid here: type or enum!";
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::HandleType()
|
||||||
|
{
|
||||||
|
Result Res = OK;
|
||||||
|
if (!Stack.Push(TokenType::TypeKeyword)) return Error;
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
|
||||||
|
if (Definitions.TypeCount >= DefinitionFile::MaxTypes)
|
||||||
|
{
|
||||||
|
std::cout << "Too many types!" << std::endl;
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
Def::Type& t = Definitions.Types[Definitions.TypeCount];
|
||||||
|
CHECK(ReadName(t.Name));
|
||||||
|
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
CHECK(ExpectChar("{"));
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
|
||||||
|
while (!CmpAdvance("}", Res))
|
||||||
|
{
|
||||||
|
if (t.FieldCount >= Def::MaxFields)
|
||||||
|
{
|
||||||
|
std::cout << "Too many fields in type!" << std::endl;
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
CHECK(ReadTypeToken());
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
CHECK(ReadName(t.FieldNames[t.FieldCount]));
|
||||||
|
|
||||||
|
bool NewLine = false;
|
||||||
|
CHECK(SkipWhitespace(&NewLine));
|
||||||
|
|
||||||
|
if (!NewLine)
|
||||||
|
{
|
||||||
|
Result Res;
|
||||||
|
if (CmpAdvance("Arr", Res) && Res == Result::OK)
|
||||||
|
{
|
||||||
|
CHECK(ExpectChar("("));
|
||||||
|
CHECK(ReadUint(t.FieldArraySizes[t.FieldCount]));
|
||||||
|
CHECK(ExpectChar(")"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
t.FieldCount++;
|
||||||
|
}
|
||||||
|
Definitions.TypeCount++;
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::HandleEnum()
|
||||||
|
{
|
||||||
|
Result Res = OK;
|
||||||
|
if (!Stack.Push(TokenType::EnumKeyword)) return Error;
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
|
||||||
|
if (Definitions.EnumCount >= DefinitionFile::MaxTypes)
|
||||||
|
{
|
||||||
|
std::cout << "Too many enums!" << std::endl;
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
Def::Enum& e = Definitions.Enums[Definitions.EnumCount];
|
||||||
|
CHECK(ReadName(e.Name));
|
||||||
|
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
CHECK(ExpectChar("{"));
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
|
||||||
|
while (!CmpAdvance("}", Res))
|
||||||
|
{
|
||||||
|
if (e.EntryCount >= Def::MaxFields)
|
||||||
|
{
|
||||||
|
std::cout << "Too many fields in enum!" << std::endl;
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
CHECK(ReadName(e.EntryNames[e.EntryCount]));
|
||||||
|
CHECK(ReadOptionalEnumValues(e, e.EntryCount));
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
e.EntryCount++;
|
||||||
|
}
|
||||||
|
Definitions.EnumCount++;
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::ReadName(char* Target)
|
||||||
|
{
|
||||||
|
int32_t Remaining = GetRemaining();
|
||||||
|
for (int32_t i = 0; i < Remaining; ++i)
|
||||||
|
{
|
||||||
|
if (!IsValidNameCharacter(*ReadPtr))
|
||||||
|
{
|
||||||
|
if (i == 0)
|
||||||
|
{
|
||||||
|
std::cout << "Empty names are not allowed!" << std::endl;
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
if (i < Def::MaxNameLength)
|
||||||
|
{
|
||||||
|
Target[i] = *ReadPtr;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "Name too long!" << std::endl;
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
ReadPtr++;
|
||||||
|
}
|
||||||
|
return EndOfFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::ReadUint(uint32_t& Out)
|
||||||
|
{
|
||||||
|
char DigitBuf[32]{0};
|
||||||
|
int32_t Remaining = GetRemaining();
|
||||||
|
if (Remaining == 0) return Result::EndOfFile;
|
||||||
|
int32_t Written = 0;
|
||||||
|
|
||||||
|
for (int32_t i = 0; i < Remaining; ++i)
|
||||||
|
{
|
||||||
|
if (*ReadPtr < '0' || *ReadPtr > '9') break;
|
||||||
|
|
||||||
|
DigitBuf[i] = *ReadPtr;
|
||||||
|
++ReadPtr;
|
||||||
|
++Written;
|
||||||
|
}
|
||||||
|
if (Written == 0)
|
||||||
|
{
|
||||||
|
std::cout << "No digits for uint: " << PrintLine() << std::endl;
|
||||||
|
return Result::Error;
|
||||||
|
}
|
||||||
|
if (!bx::fromString(&Out, DigitBuf))
|
||||||
|
{
|
||||||
|
std::cout << "Failed to parse uint: " << PrintLine() << std::endl;
|
||||||
|
return Result::Error;
|
||||||
|
}
|
||||||
|
return Result::OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::ReadTypeToken()
|
||||||
|
{
|
||||||
|
Result Res = OK;
|
||||||
|
for (int32_t i = 0; i < Generated::KnownType::EntryCount; ++i)
|
||||||
|
{
|
||||||
|
if (CmpAdvance(Generated::KnownType::EntryNames[i], Res) && Res == OK)
|
||||||
|
{
|
||||||
|
Def::Type& t = Definitions.Types[Definitions.TypeCount];
|
||||||
|
t.FieldTypes[t.FieldCount].Known = Generated::KnownType::Enum(i);
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::cout << "Unknown type token:" << std::endl << PrintLine() << std::endl;
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser::Result Parser::ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx)
|
||||||
|
{
|
||||||
|
Result Res = OK;
|
||||||
|
|
||||||
|
bool SkippedNewLine = false;
|
||||||
|
CHECK(SkipWhitespace(&SkippedNewLine));
|
||||||
|
if (SkippedNewLine) return Res;
|
||||||
|
|
||||||
|
for (int32_t extraIdx = 0; extraIdx < Def::MaxExtraEnumFields; ++extraIdx)
|
||||||
|
{
|
||||||
|
CHECK(ReadName(Enum.ExtraStringFieldNames[extraIdx]));
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
CHECK(ExpectChar("("));
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
CHECK(ExpectChar("\""));
|
||||||
|
|
||||||
|
int32_t Remaining = GetRemaining();
|
||||||
|
for (int32_t i = 0; i < Remaining; ++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (CmpAdvance("\"", Res)) break;
|
||||||
|
Enum.ExtraStringFields[extraIdx][EntryIdx][i] = *ReadPtr;
|
||||||
|
ReadPtr++;
|
||||||
|
}
|
||||||
|
if (Res != OK) return Res;
|
||||||
|
|
||||||
|
CHECK(SkipWhitespace());
|
||||||
|
CHECK(ExpectChar(")"));
|
||||||
|
CHECK(SkipWhitespace(&SkippedNewLine));
|
||||||
|
Enum.ExtraStringFieldCount = bx::max(Enum.ExtraStringFieldCount, extraIdx + 1);
|
||||||
|
|
||||||
|
if (SkippedNewLine) return Res;
|
||||||
|
}
|
||||||
|
std::cout << "Too many extra enum fields!" << std::endl;
|
||||||
|
return Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
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, ...)
|
||||||
|
{
|
||||||
|
va_list ArgList;
|
||||||
|
va_start(ArgList, Template);
|
||||||
|
int32_t Count = bx::vsnprintf(WriteBuffer, sizeof(WriteBuffer), Template, ArgList);
|
||||||
|
va_end(ArgList);
|
||||||
|
bx::write(&Writer, WriteBuffer, Count, &Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
Parser TestParser;
|
||||||
|
int main(int argc, const char** argv)
|
||||||
|
{
|
||||||
|
if (argc != 3)
|
||||||
|
{
|
||||||
|
std::cout << "invalid number of arguments!" << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
bx::FilePath defPath(argv[1]);
|
||||||
|
bx::FilePath outPath(argv[2]);
|
||||||
|
|
||||||
|
bx::FileReader reader;
|
||||||
|
bx::Error error;
|
||||||
|
if (!reader.open(defPath, &error))
|
||||||
|
{
|
||||||
|
std::cout << "failed to find def file at " << error.getMessage().getCPtr() << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
TestParser.BufferSize = bx::read(&reader, TestParser.Buffer, Parser::MaxBufferSize, &error);
|
||||||
|
Parser::Result Res = TestParser.Parse();
|
||||||
|
|
||||||
|
if (Res == Parser::EndOfFile)
|
||||||
|
{
|
||||||
|
std::cout << "Success!" << std::endl;
|
||||||
|
TestParser.Definitions.GenerateCpp(outPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
160
src/dependency/minidef/src/MiniDef.h
Normal file
160
src/dependency/minidef/src/MiniDef.h
Normal file
@@ -0,0 +1,160 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <bx/file.h>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "Gen/Generated.h"
|
||||||
|
#include "bx/string.h"
|
||||||
|
|
||||||
|
struct Log
|
||||||
|
{
|
||||||
|
static bool Assert(bool Condition, const char* Text);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class TokenType : uint8_t
|
||||||
|
{
|
||||||
|
StartOfFile,
|
||||||
|
TypeKeyword,
|
||||||
|
EnumKeyword,
|
||||||
|
Name,
|
||||||
|
ScopeStart,
|
||||||
|
ScopeEnd,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ParseStack
|
||||||
|
{
|
||||||
|
static constexpr size_t MaxSize = 32;
|
||||||
|
TokenType Stack[MaxSize] = {TokenType::StartOfFile};
|
||||||
|
int32_t StackIdx = 0;
|
||||||
|
|
||||||
|
TokenType GetCurrent()
|
||||||
|
{
|
||||||
|
return Stack[StackIdx];
|
||||||
|
}
|
||||||
|
bool Push(TokenType T)
|
||||||
|
{
|
||||||
|
if (Log::Assert(StackIdx < MaxSize - 1, "Inbalanced Push/Pop!")) return false;
|
||||||
|
StackIdx++;
|
||||||
|
Stack[StackIdx] = T;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
TokenType Pop()
|
||||||
|
{
|
||||||
|
if (Log::Assert(StackIdx == 0, "Inbalanced Push/Pop!")) return TokenType::StartOfFile;
|
||||||
|
TokenType T = Stack[StackIdx];
|
||||||
|
StackIdx--;
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace Def
|
||||||
|
{
|
||||||
|
constexpr int32_t MaxNameLength = 64;
|
||||||
|
constexpr int32_t MaxFields = 64;
|
||||||
|
constexpr int32_t MaxExtraEnumFields = 1;
|
||||||
|
union TypeUnion
|
||||||
|
{
|
||||||
|
Generated::KnownType::Enum Known;
|
||||||
|
uint32_t TypeIdx;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Type
|
||||||
|
{
|
||||||
|
int32_t FieldCount = 0;
|
||||||
|
TypeUnion FieldTypes[MaxFields];
|
||||||
|
char FieldNames[MaxFields][MaxNameLength];
|
||||||
|
uint32_t FieldArraySizes[MaxFields]{0};
|
||||||
|
char Name[MaxNameLength]{0};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Enum
|
||||||
|
{
|
||||||
|
int32_t EntryCount = 0;
|
||||||
|
char EntryNames[MaxFields][MaxNameLength];
|
||||||
|
int32_t ExtraStringFieldCount = 0;
|
||||||
|
char ExtraStringFieldNames[MaxExtraEnumFields][MaxNameLength];
|
||||||
|
char ExtraStringFields[MaxFields][MaxExtraEnumFields][MaxNameLength];
|
||||||
|
char Name[MaxNameLength]{0};
|
||||||
|
};
|
||||||
|
} // namespace Def
|
||||||
|
|
||||||
|
struct DefinitionFile
|
||||||
|
{
|
||||||
|
static constexpr int32_t MaxTypes = 256;
|
||||||
|
void PrintTypeName(char* buf, int32_t bufSize, Def::TypeUnion type);
|
||||||
|
void GenerateCpp(const bx::FilePath& outDir);
|
||||||
|
|
||||||
|
Def::Type Types[MaxTypes];
|
||||||
|
int32_t TypeCount = 0;
|
||||||
|
Def::Enum Enums[MaxTypes];
|
||||||
|
int32_t EnumCount = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Parser
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Result : uint8_t
|
||||||
|
{
|
||||||
|
OK,
|
||||||
|
Error,
|
||||||
|
EndOfFile,
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr int32_t MaxBufferSize = 1024 * 1024;
|
||||||
|
static constexpr int32_t MaxTokens = UINT16_MAX;
|
||||||
|
static bool IsValidNameCharacter(char c)
|
||||||
|
{
|
||||||
|
return isgraph(c) && c != '"' && c != '(' && c != ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t BufferSize = 0;
|
||||||
|
char Buffer[MaxBufferSize]{0};
|
||||||
|
char* ReadPtr = &Buffer[0];
|
||||||
|
|
||||||
|
DefinitionFile Definitions;
|
||||||
|
ParseStack Stack;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Result Parse();
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32_t GetRemaining();
|
||||||
|
Result SkipWhitespace(bool* SkippedNewLine = nullptr);
|
||||||
|
Result SkipLine();
|
||||||
|
bool CmpAdvance(bx::StringView expect, Result& Res);
|
||||||
|
Result ExpectChar(bx::StringView expect);
|
||||||
|
Result Advance(int32_t Amount);
|
||||||
|
Result HandleFileStart();
|
||||||
|
Result HandleType();
|
||||||
|
Result HandleEnum();
|
||||||
|
Result ReadName(char* Target);
|
||||||
|
Result ReadUint(uint32_t& Out);
|
||||||
|
Result ReadTypeToken();
|
||||||
|
Result ReadOptionalEnumValues(Def::Enum& Enum, int32_t EntryIdx);
|
||||||
|
|
||||||
|
std::string PrintLine()
|
||||||
|
{
|
||||||
|
char line[64]{0};
|
||||||
|
for (int32_t i = 0; i < sizeof(line) - 1; ++i)
|
||||||
|
{
|
||||||
|
line[i] = ReadPtr[0];
|
||||||
|
if (Advance(1) != Result::OK) break;
|
||||||
|
if (*ReadPtr == '\n' || *ReadPtr == '\r') break;
|
||||||
|
}
|
||||||
|
return std::string{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, ...);
|
||||||
|
};
|
||||||
@@ -38,6 +38,13 @@ namespace Game
|
|||||||
InputMode InputM = InputMode::Game;
|
InputMode InputM = InputMode::Game;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct InstanceDebugData
|
||||||
|
{
|
||||||
|
uint16_t SelectedDebugLevel = UINT16_MAX;
|
||||||
|
uint64_t ImguiIniSize = 0;
|
||||||
|
char ImguiIni[4096]{0};
|
||||||
|
};
|
||||||
|
|
||||||
struct GameInstance
|
struct GameInstance
|
||||||
{
|
{
|
||||||
bool IsInitialized = false;
|
bool IsInitialized = false;
|
||||||
@@ -46,7 +53,6 @@ namespace Game
|
|||||||
Time Time;
|
Time Time;
|
||||||
PlayerData Player;
|
PlayerData Player;
|
||||||
Level GameLevel;
|
Level GameLevel;
|
||||||
uint64_t ImguiIniSize = 0;
|
InstanceDebugData DebugData;
|
||||||
char ImguiIni[4096]{0};
|
|
||||||
};
|
};
|
||||||
} // namespace Game
|
} // namespace Game
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ namespace Game
|
|||||||
|
|
||||||
// Cubes.Render(models, materials);
|
// Cubes.Render(models, materials);
|
||||||
Tests.Render(models, materials);
|
Tests.Render(models, materials);
|
||||||
// PuzzleTiles.Render(models, materials);
|
PuzzleTiles.Render(models, materials);
|
||||||
UIQuads.Render(models, materials);
|
UIQuads.Render(models, materials);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@ namespace Game
|
|||||||
|
|
||||||
UIQuadEntity& quad = level.UIQuads.Get(UIPlacedCards[cardI]);
|
UIQuadEntity& quad = level.UIQuads.Get(UIPlacedCards[cardI]);
|
||||||
quad.EData.MaterialHandle = 0;
|
quad.EData.MaterialHandle = 0;
|
||||||
quad.EData.ModelHandle = GameRendering::Get().GetModelHandleFromPath("models/cube.glb");
|
quad.EData.ModelHandle = GameRendering::Get().GetModelHandleFromPath("models/plane.glb");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include "Puzzle.h"
|
#include "Puzzle.h"
|
||||||
|
#include "bx/string.h"
|
||||||
|
#include "imgui.h"
|
||||||
#include "rendering/Rendering.h"
|
#include "rendering/Rendering.h"
|
||||||
|
|
||||||
#include "bx/bx.h"
|
#include "bx/bx.h"
|
||||||
@@ -154,4 +156,47 @@ namespace Puzzle
|
|||||||
return (sourceType == PuzzleElementType::WaterIn && goalType == PuzzleElementType::WaterGoal) ||
|
return (sourceType == PuzzleElementType::WaterIn && goalType == PuzzleElementType::WaterGoal) ||
|
||||||
(sourceType == PuzzleElementType::ElectricIn && goalType == PuzzleElementType::ElectricGoal);
|
(sourceType == PuzzleElementType::ElectricIn && goalType == PuzzleElementType::ElectricGoal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PuzzleData::RenderDebugUI()
|
||||||
|
{
|
||||||
|
bool dataChanged = false;
|
||||||
|
|
||||||
|
bool isVisible = true;
|
||||||
|
if (ImGui::Begin("Puzzle", &isVisible))
|
||||||
|
{
|
||||||
|
ImGui::Text("%s", PuzzleName);
|
||||||
|
|
||||||
|
int32_t W = S.WidthTiles;
|
||||||
|
int32_t H = S.HeightTiles;
|
||||||
|
ImGui::PushID("width");
|
||||||
|
ImGui::SetNextItemWidth(40);
|
||||||
|
if (ImGui::DragInt("", &W, 0.3f, 0, Config::MaxPuzzleSizeTiles))
|
||||||
|
{
|
||||||
|
S.WidthTiles = uint8_t(W);
|
||||||
|
dataChanged = true;
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Text("x");
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(40);
|
||||||
|
ImGui::PushID("height");
|
||||||
|
if (ImGui::DragInt("", &H, 0.3f, 0, Config::MaxPuzzleSizeTiles))
|
||||||
|
{
|
||||||
|
S.HeightTiles = uint8_t(H);
|
||||||
|
dataChanged = true;
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
if (dataChanged)
|
||||||
|
{
|
||||||
|
char path[128]{0};
|
||||||
|
bx::snprintf(path, sizeof(path), "game/data/%s.pzl", PuzzleName);
|
||||||
|
SerializeStruct(&S, sizeof(S), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return isVisible;
|
||||||
|
}
|
||||||
} // namespace Puzzle
|
} // namespace Puzzle
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "Serial.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
#include "../../gen/Generated.h"
|
||||||
|
|
||||||
namespace Puzzle
|
namespace Puzzle
|
||||||
{
|
{
|
||||||
struct Config
|
struct Config
|
||||||
@@ -104,6 +107,9 @@ namespace Puzzle
|
|||||||
|
|
||||||
struct PuzzleData
|
struct PuzzleData
|
||||||
{
|
{
|
||||||
|
SER_HEADER(1, "PZZL");
|
||||||
|
Generated::PuzzleData S;
|
||||||
|
|
||||||
uint32_t AvailableCardCount = 0;
|
uint32_t AvailableCardCount = 0;
|
||||||
PuzzleCardStack AvailableCards[Config::MaxAvailableStacks];
|
PuzzleCardStack AvailableCards[Config::MaxAvailableStacks];
|
||||||
uint32_t PlacedCardCount = 0;
|
uint32_t PlacedCardCount = 0;
|
||||||
@@ -117,6 +123,9 @@ namespace Puzzle
|
|||||||
|
|
||||||
const PuzzleNode& GetNodeAt(PuzPos pos) const;
|
const PuzzleNode& GetNodeAt(PuzPos pos) const;
|
||||||
PuzzleElementType GetElementAt(ElemPos pos) const;
|
PuzzleElementType GetElementAt(ElemPos pos) const;
|
||||||
|
|
||||||
|
char PuzzleName[32]{"Unnamed"};
|
||||||
|
bool RenderDebugUI();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PuzzleSolver
|
struct PuzzleSolver
|
||||||
|
|||||||
32
src/game/Serial.cpp
Normal file
32
src/game/Serial.cpp
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include "Global.h"
|
||||||
|
#include "Log.h"
|
||||||
|
#include "Serial.h"
|
||||||
|
#include "bx/bx.h"
|
||||||
|
#include "bx/file.h"
|
||||||
|
#include "bx/filepath.h"
|
||||||
|
|
||||||
|
void SerializeStruct(void* data, uint64_t size, const char* path)
|
||||||
|
{
|
||||||
|
bx::Error err;
|
||||||
|
bx::FilePath filePath{path};
|
||||||
|
bx::FileWriter writer;
|
||||||
|
if (writer.open(filePath, false, &err))
|
||||||
|
{
|
||||||
|
if (!writer.write(data, size, &err))
|
||||||
|
{
|
||||||
|
LOG_ERROR("Failed to write to file %s: %s", path, err.getMessage().getCPtr());
|
||||||
|
writer.close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR("Failed to open file %s: %s", path, err.getMessage().getCPtr());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
LOG("Successful serialization");
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeserializeStruct(void* data, SerializationHeader& expectedHeader, const char* path)
|
||||||
|
{
|
||||||
|
}
|
||||||
32
src/game/Serial.h
Normal file
32
src/game/Serial.h
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
struct SerializationHeader
|
||||||
|
{
|
||||||
|
uint8_t _ID0 = 0;
|
||||||
|
uint8_t _ID1 = 0;
|
||||||
|
uint8_t _ID2 = 0;
|
||||||
|
uint8_t _ID3 = 0;
|
||||||
|
uint8_t HeaderVersion = 0;
|
||||||
|
uint8_t VersionNum = 0;
|
||||||
|
uint8_t Reserved0 = 0;
|
||||||
|
uint8_t Reserved1 = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SER_HEADER(Version, FCC) \
|
||||||
|
SerializationHeader __Header{ \
|
||||||
|
FCC[0], \
|
||||||
|
FCC[1], \
|
||||||
|
FCC[2], \
|
||||||
|
FCC[3], \
|
||||||
|
1, \
|
||||||
|
Version, \
|
||||||
|
0, \
|
||||||
|
0, \
|
||||||
|
}; \
|
||||||
|
bool VersionMatches(uint8_t headerVersion, uint8_t versionNum) \
|
||||||
|
{ \
|
||||||
|
return headerVersion == 1 && versionNum == Version; \
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerializeStruct(void* data, uint64_t size, const char* path);
|
||||||
|
void DeserializeStruct(void* data, SerializationHeader& expectedHeader, const char* path);
|
||||||
8
src/game/mini.def
Normal file
8
src/game/mini.def
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
type PuzzleData
|
||||||
|
{
|
||||||
|
u8 WidthTiles
|
||||||
|
u8 HeightTiles
|
||||||
|
u32 AvailableCardCount
|
||||||
|
u32 PlacedCardCount
|
||||||
|
u32 GoalPositionCount
|
||||||
|
}
|
||||||
@@ -390,9 +390,9 @@ namespace Game
|
|||||||
inst.Time.StartTime = bx::getHPCounter();
|
inst.Time.StartTime = bx::getHPCounter();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst.ImguiIniSize > 0)
|
if (inst.DebugData.ImguiIniSize > 0)
|
||||||
{
|
{
|
||||||
ImGui::LoadIniSettingsFromMemory(inst.ImguiIni, inst.ImguiIniSize);
|
ImGui::LoadIniSettingsFromMemory(inst.DebugData.ImguiIni, inst.DebugData.ImguiIniSize);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -453,6 +453,8 @@ namespace Game
|
|||||||
ImGui_ImplSDL3_NewFrame();
|
ImGui_ImplSDL3_NewFrame();
|
||||||
ImGui::DockSpaceOverViewport(0, 0, ImGuiDockNodeFlags_PassthruCentralNode);
|
ImGui::DockSpaceOverViewport(0, 0, ImGuiDockNodeFlags_PassthruCentralNode);
|
||||||
|
|
||||||
|
auto& level = GetInstance().GameLevel;
|
||||||
|
auto& debug = GetInstance().DebugData;
|
||||||
if (UIVisible == UIVisibilityState::Debug)
|
if (UIVisible == UIVisibilityState::Debug)
|
||||||
{
|
{
|
||||||
if (ImGui::Begin("Rendering"))
|
if (ImGui::Begin("Rendering"))
|
||||||
@@ -500,12 +502,39 @@ namespace Game
|
|||||||
{
|
{
|
||||||
ImGui::Image(DitherTextures.RampTex.idx, {BX_COUNTOF(DitherTextures.BrightnessRamp), 8});
|
ImGui::Image(DitherTextures.RampTex.idx, {BX_COUNTOF(DitherTextures.BrightnessRamp), 8});
|
||||||
}
|
}
|
||||||
Vec3 quadPos = GetInstance().GameLevel.UIQuads.Get({0}).EData.Transform.GetPosition();
|
Vec3 quadPos = level.UIQuads.Get({0}).EData.Transform.GetPosition();
|
||||||
ImGui::Text("%f %f %f", quadPos.x, quadPos.y, quadPos.z);
|
ImGui::Text("%f %f %f", quadPos.x, quadPos.y, quadPos.z);
|
||||||
ImGui::Text("Shader log:");
|
ImGui::Text("Shader log:");
|
||||||
ImGui::TextWrapped("%s", GetShared().Dev.ShaderLog);
|
ImGui::TextWrapped("%s", GetShared().Dev.ShaderLog);
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
if (ImGui::Begin("Puzzles"))
|
||||||
|
{
|
||||||
|
ImGui::Text("List");
|
||||||
|
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
|
||||||
|
{
|
||||||
|
auto& puzzleData = level.Puzzles[i].Data;
|
||||||
|
bool isSelected = debug.SelectedDebugLevel == i;
|
||||||
|
ImGui::PushID("selectable");
|
||||||
|
if (ImGui::Selectable(puzzleData.PuzzleName, isSelected))
|
||||||
|
{
|
||||||
|
debug.SelectedDebugLevel = isSelected ? UINT16_MAX : i;
|
||||||
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
if (isSelected)
|
||||||
|
{
|
||||||
|
ImGui::PushID("edit field");
|
||||||
|
ImGui::InputText("", puzzleData.PuzzleName, sizeof(Puzzle::PuzzleData::PuzzleName));
|
||||||
|
ImGui::PopID();
|
||||||
|
|
||||||
|
if (!puzzleData.RenderDebugUI())
|
||||||
|
{
|
||||||
|
debug.SelectedDebugLevel = UINT16_MAX;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
GetInstance().GameLevel.Update();
|
GetInstance().GameLevel.Update();
|
||||||
@@ -536,10 +565,10 @@ namespace Game
|
|||||||
{
|
{
|
||||||
LOG("--- RENDERING_SHUTDOWN ---");
|
LOG("--- RENDERING_SHUTDOWN ---");
|
||||||
ImGui::SaveIniSettingsToDisk("imgui.ini");
|
ImGui::SaveIniSettingsToDisk("imgui.ini");
|
||||||
const char* iniData = ImGui::SaveIniSettingsToMemory(reinterpret_cast<uint64_t*>(&GetInstance().ImguiIniSize));
|
auto& debug = GetInstance().DebugData;
|
||||||
assert(GetInstance().ImguiIniSize <= BX_COUNTOF(GameInstance::ImguiIni));
|
const char* iniData = ImGui::SaveIniSettingsToMemory(reinterpret_cast<uint64_t*>(&debug.ImguiIniSize));
|
||||||
bx::memCopy(
|
assert(debug.ImguiIniSize <= BX_COUNTOF(InstanceDebugData::ImguiIni));
|
||||||
GetInstance().ImguiIni, iniData, bx::min(GetInstance().ImguiIniSize, BX_COUNTOF(GameInstance::ImguiIni)));
|
bx::memCopy(debug.ImguiIni, iniData, bx::min(debug.ImguiIniSize, BX_COUNTOF(InstanceDebugData::ImguiIni)));
|
||||||
ImGui_ImplSDL3_Shutdown();
|
ImGui_ImplSDL3_Shutdown();
|
||||||
imguiDestroy();
|
imguiDestroy();
|
||||||
bgfx::shutdown();
|
bgfx::shutdown();
|
||||||
|
|||||||
2
src/gen/Def.h
Normal file
2
src/gen/Def.h
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <cstdint>
|
||||||
14
src/gen/Generated.h
Normal file
14
src/gen/Generated.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Def.h"
|
||||||
|
|
||||||
|
namespace Generated
|
||||||
|
{
|
||||||
|
struct PuzzleData
|
||||||
|
{
|
||||||
|
uint8_t WidthTiles = {};
|
||||||
|
uint8_t HeightTiles = {};
|
||||||
|
uint32_t AvailableCardCount = {};
|
||||||
|
uint32_t PlacedCardCount = {};
|
||||||
|
uint32_t GoalPositionCount = {};
|
||||||
|
};
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user