Compare commits
2 Commits
ff00119e5b
...
ffad8f8460
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffad8f8460 | ||
|
|
c7377c3452 |
1
.gitattributes
vendored
1
.gitattributes
vendored
@@ -4,3 +4,4 @@
|
|||||||
*.png filter=lfs diff=lfs merge=lfs -text
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
*.jpg filter=lfs diff=lfs merge=lfs -text
|
*.jpg filter=lfs diff=lfs merge=lfs -text
|
||||||
*.blend filter=lfs diff=lfs merge=lfs -text
|
*.blend filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.pzl filter=lfs diff=lfs merge=lfs -text
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#include "CppGen.h"
|
#include "CppGen.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
#include "TypeDef.h"
|
#include "TypeDef.h"
|
||||||
|
#include "bx/string.h"
|
||||||
|
|
||||||
#include <bx/file.h>
|
#include <bx/file.h>
|
||||||
|
#include <cstdarg>
|
||||||
#include <memoryapi.h>
|
#include <memoryapi.h>
|
||||||
#include <winnt.h>
|
#include <winnt.h>
|
||||||
|
|
||||||
@@ -11,10 +13,15 @@
|
|||||||
|
|
||||||
namespace WriteTemplates
|
namespace WriteTemplates
|
||||||
{
|
{
|
||||||
constexpr char FileHeader[] =
|
constexpr char FileHeaderStart[] =
|
||||||
R"END(#pragma once
|
R"END(#pragma once
|
||||||
#include "Def.h"
|
#include "Def.h"
|
||||||
|
|
||||||
|
namespace Generated
|
||||||
|
{
|
||||||
|
)END";
|
||||||
|
constexpr char FileCppStart[] = R"END(#include "Generated.h"
|
||||||
|
|
||||||
namespace Generated
|
namespace Generated
|
||||||
{
|
{
|
||||||
)END";
|
)END";
|
||||||
@@ -36,7 +43,7 @@ namespace Generated
|
|||||||
R"END( struct %s
|
R"END( struct %s
|
||||||
{
|
{
|
||||||
static constexpr int32_t EntryCount = %u;
|
static constexpr int32_t EntryCount = %u;
|
||||||
enum class Enum : %s
|
enum Enum : %s
|
||||||
{
|
{
|
||||||
)END";
|
)END";
|
||||||
|
|
||||||
@@ -62,8 +69,96 @@ namespace Generated
|
|||||||
constexpr char FileEnd[] =
|
constexpr char FileEnd[] =
|
||||||
R"END(}
|
R"END(}
|
||||||
)END";
|
)END";
|
||||||
|
|
||||||
|
constexpr char SaveFuncHeader1[] =
|
||||||
|
R"END( bool Save(const %s* obj, uint32_t count, Serializer& serializer);
|
||||||
|
)END";
|
||||||
|
constexpr char SaveFuncBodyStart1[] = R"END( bool Save(const %s* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
)END";
|
||||||
|
constexpr char SaveFuncBodyType3[] = R"END( isOk = Save(%sobj[i].%s, %u, serializer) && isOk;
|
||||||
|
)END";
|
||||||
|
constexpr char SaveFuncBodyEnum1[] = R"END( auto val = (%s)obj[i];
|
||||||
|
isOk = Save(&val, 1, serializer) && isOk;
|
||||||
|
)END";
|
||||||
|
constexpr char SaveFuncBodyEnd[] = R"END( }
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
)END";
|
||||||
|
|
||||||
|
constexpr char LoadFuncHeader1[] =
|
||||||
|
R"END( bool Load(%s* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
)END";
|
||||||
|
constexpr char LoadFuncBodyStart1[] = R"END( bool Load(%s* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
)END";
|
||||||
|
constexpr char LoadFuncBodyType3[] = R"END( isOk = Load(%sobj[i].%s, %u, serializer) && isOk;
|
||||||
|
)END";
|
||||||
|
constexpr char LoadFuncBodyEnum1[] = R"END( auto val = (%s)obj[i];
|
||||||
|
isOk = Load(&val, 1, serializer) && isOk;
|
||||||
|
)END";
|
||||||
|
constexpr char LoadFuncBodyEnd[] = R"END( }
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
)END";
|
||||||
} // namespace WriteTemplates
|
} // namespace WriteTemplates
|
||||||
|
|
||||||
|
void CppFileWriter::InitBuffer(WriteBuffer& buf)
|
||||||
|
{
|
||||||
|
if (buf.Data != nullptr)
|
||||||
|
{
|
||||||
|
LOG_ERROR(0, "Multiple writes not supported yet!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buf.Data =
|
||||||
|
reinterpret_cast<char*>(VirtualAlloc(nullptr, BufferRequestSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
|
||||||
|
if (buf.Data == nullptr)
|
||||||
|
{
|
||||||
|
LOG_ERROR(0, "Failed to allocate write memory!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buf.WrittenBytes = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CppFileWriter::WriteBufferToDisk(const bx::FilePath& path, const WriteBuffer& buf)
|
||||||
|
{
|
||||||
|
bx::Error error;
|
||||||
|
bx::FileWriter writer;
|
||||||
|
|
||||||
|
LOG(0, "Writing to %s", path.getCPtr());
|
||||||
|
if (!writer.open(path, false, &error))
|
||||||
|
{
|
||||||
|
LOG_ERROR(0, "Failed to open output file: %s", error.getMessage().getCPtr());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.write(buf.Data, buf.WrittenBytes, &error);
|
||||||
|
if (!error.isOk())
|
||||||
|
{
|
||||||
|
LOG_ERROR(0, "Failed to write to output file: %s", error.getMessage().getCPtr());
|
||||||
|
}
|
||||||
|
writer.close();
|
||||||
|
LOG(0, "Finished writing!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CppFileWriter::WriteInternal(WriteBuffer& buf, const char* templateStr, va_list args)
|
||||||
|
{
|
||||||
|
if (buf.Data == nullptr)
|
||||||
|
{
|
||||||
|
LOG_ERROR(0, "Wrote too early!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf.WrittenBytes += bx::vsnprintf(&buf.Data[buf.WrittenBytes], BufferRequestSize, templateStr, args);
|
||||||
|
}
|
||||||
|
|
||||||
void CppFileWriter::PrintTypeName(char* buf,
|
void CppFileWriter::PrintTypeName(char* buf,
|
||||||
int32_t bufSize,
|
int32_t bufSize,
|
||||||
const Def::FieldType& type,
|
const Def::FieldType& type,
|
||||||
@@ -87,6 +182,7 @@ void CppFileWriter::PrintTypeName(char* buf,
|
|||||||
else if (type.FieldKind == Def::EFieldType::DefinedEnum)
|
else if (type.FieldKind == Def::EFieldType::DefinedEnum)
|
||||||
{
|
{
|
||||||
bx::strCopy(buf, bufSize, definitions.Enums[type.TypeIdx].Name);
|
bx::strCopy(buf, bufSize, definitions.Enums[type.TypeIdx].Name);
|
||||||
|
bx::strCat(buf, bufSize, "::Enum");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -143,64 +239,90 @@ void CppFileWriter::WriteTypes(const Def::DefinitionFile& definitions)
|
|||||||
Write(WriteTemplates::StructEnd);
|
Write(WriteTemplates::StructEnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void CppFileWriter::WriteSaveLoadMethods(const Def::DefinitionFile& definitions)
|
||||||
|
{
|
||||||
|
char nameBuf[64]{0};
|
||||||
|
char fieldBuf[64]{0};
|
||||||
|
for (int32_t enumIdx = 0; enumIdx < definitions.EnumCount; ++enumIdx)
|
||||||
|
{
|
||||||
|
const Def::Enum& e = definitions.Enums[enumIdx];
|
||||||
|
bx::snprintf(nameBuf, sizeof(nameBuf), "%s::Enum", e.Name);
|
||||||
|
PrintTypeName(fieldBuf, sizeof(fieldBuf), e.EnumType, definitions);
|
||||||
|
|
||||||
|
Write(WriteTemplates::SaveFuncHeader1, nameBuf);
|
||||||
|
Write(WriteTemplates::LoadFuncHeader1, nameBuf);
|
||||||
|
|
||||||
|
WriteCpp(WriteTemplates::SaveFuncBodyStart1, nameBuf);
|
||||||
|
WriteCpp(WriteTemplates::SaveFuncBodyEnum1, fieldBuf);
|
||||||
|
WriteCpp(WriteTemplates::SaveFuncBodyEnd);
|
||||||
|
|
||||||
|
WriteCpp(WriteTemplates::LoadFuncBodyStart1, nameBuf);
|
||||||
|
WriteCpp(WriteTemplates::LoadFuncBodyEnum1, fieldBuf);
|
||||||
|
WriteCpp(WriteTemplates::LoadFuncBodyEnd);
|
||||||
|
}
|
||||||
|
for (int32_t typeIdx = 0; typeIdx < definitions.TypeCount; ++typeIdx)
|
||||||
|
{
|
||||||
|
const Def::Type& t = definitions.Types[typeIdx];
|
||||||
|
Write(WriteTemplates::SaveFuncHeader1, t.Name);
|
||||||
|
Write(WriteTemplates::LoadFuncHeader1, t.Name);
|
||||||
|
|
||||||
|
WriteCpp(WriteTemplates::SaveFuncBodyStart1, t.Name);
|
||||||
|
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
|
||||||
|
{
|
||||||
|
WriteCpp(WriteTemplates::SaveFuncBodyType3,
|
||||||
|
t.FieldArraySizes[fieldIdx] > 0 ? "" : "&",
|
||||||
|
t.FieldNames[fieldIdx],
|
||||||
|
bx::max(1, t.FieldArraySizes[fieldIdx]));
|
||||||
|
}
|
||||||
|
WriteCpp(WriteTemplates::SaveFuncBodyEnd);
|
||||||
|
|
||||||
|
WriteCpp(WriteTemplates::LoadFuncBodyStart1, t.Name);
|
||||||
|
for (int32_t fieldIdx = 0; fieldIdx < t.FieldCount; ++fieldIdx)
|
||||||
|
{
|
||||||
|
WriteCpp(WriteTemplates::LoadFuncBodyType3,
|
||||||
|
t.FieldArraySizes[fieldIdx] > 0 ? "" : "&",
|
||||||
|
t.FieldNames[fieldIdx],
|
||||||
|
bx::max(1, t.FieldArraySizes[fieldIdx]));
|
||||||
|
}
|
||||||
|
WriteCpp(WriteTemplates::LoadFuncBodyEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
void CppFileWriter::GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions)
|
void CppFileWriter::GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions)
|
||||||
{
|
{
|
||||||
LOG(0, "Generating...");
|
LOG(0, "Generating output files...");
|
||||||
|
|
||||||
// Allocate write buffer
|
InitBuffer(HeaderWrite);
|
||||||
if (FileWriteBuffer != nullptr)
|
InitBuffer(CppWrite);
|
||||||
{
|
|
||||||
LOG_ERROR(0, "Multiple writes not supported yet!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FileWriteBuffer =
|
|
||||||
reinterpret_cast<char*>(VirtualAlloc(nullptr, BufferRequestSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
|
|
||||||
if (FileWriteBuffer == nullptr)
|
|
||||||
{
|
|
||||||
LOG_ERROR(0, "Failed to allocate write memory!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FileWriterWritten = 0;
|
|
||||||
|
|
||||||
// Write text to buffer
|
Write(WriteTemplates::FileHeaderStart);
|
||||||
Write(WriteTemplates::FileHeader);
|
WriteCpp(WriteTemplates::FileCppStart);
|
||||||
WriteEnums(definitions);
|
WriteEnums(definitions);
|
||||||
WriteTypes(definitions);
|
WriteTypes(definitions);
|
||||||
|
WriteSaveLoadMethods(definitions);
|
||||||
Write(WriteTemplates::FileEnd);
|
Write(WriteTemplates::FileEnd);
|
||||||
|
WriteCpp(WriteTemplates::FileEnd);
|
||||||
|
|
||||||
// Write buffer to disk
|
|
||||||
bx::Error error;
|
|
||||||
bx::FileWriter writer;
|
|
||||||
bx::FilePath writePath = outDir;
|
|
||||||
// std::filesystem::create_directory(outDir.getCPtr());
|
// std::filesystem::create_directory(outDir.getCPtr());
|
||||||
writePath.join("Generated.h");
|
bx::FilePath writePathHeader = outDir;
|
||||||
|
bx::FilePath writePathCpp = outDir;
|
||||||
LOG(0, "Writing to %s", writePath.getCPtr());
|
writePathHeader.join("Generated.h");
|
||||||
if (!writer.open(writePath, false, &error))
|
writePathCpp.join("Generated.cpp");
|
||||||
{
|
WriteBufferToDisk(writePathHeader, HeaderWrite);
|
||||||
LOG_ERROR(0, "Failed to open output file: %s", error.getMessage().getCPtr());
|
WriteBufferToDisk(writePathCpp, CppWrite);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.write(FileWriteBuffer, FileWriterWritten, &error);
|
void CppFileWriter::Write(const char* templateStr, ...)
|
||||||
if (!error.isOk())
|
|
||||||
{
|
{
|
||||||
LOG_ERROR(0, "Failed to write to output file: %s", error.getMessage().getCPtr());
|
va_list args;
|
||||||
}
|
va_start(args, templateStr);
|
||||||
writer.close();
|
WriteInternal(HeaderWrite, templateStr, args);
|
||||||
LOG(0, "Finished writing!");
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CppFileWriter::Write(const char* Template, ...)
|
void CppFileWriter::WriteCpp(const char* templateStr, ...)
|
||||||
{
|
{
|
||||||
if (FileWriteBuffer == nullptr)
|
va_list args;
|
||||||
{
|
va_start(args, templateStr);
|
||||||
LOG_ERROR(0, "Wrote too early!");
|
WriteInternal(CppWrite, templateStr, args);
|
||||||
return;
|
va_end(args);
|
||||||
}
|
|
||||||
|
|
||||||
va_list ArgList;
|
|
||||||
va_start(ArgList, Template);
|
|
||||||
FileWriterWritten += bx::vsnprintf(&FileWriteBuffer[FileWriterWritten], BufferRequestSize, Template, ArgList);
|
|
||||||
va_end(ArgList);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,29 @@
|
|||||||
|
|
||||||
#include "bx/filepath.h"
|
#include "bx/filepath.h"
|
||||||
|
|
||||||
|
struct WriteBuffer
|
||||||
|
{
|
||||||
|
char* Data = nullptr;
|
||||||
|
uint64_t WrittenBytes = 0;
|
||||||
|
};
|
||||||
|
|
||||||
struct CppFileWriter
|
struct CppFileWriter
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static constexpr size_t BufferRequestSize = 1024 * 1024 * 1024;
|
static constexpr size_t BufferRequestSize = 1024 * 1024 * 1024;
|
||||||
char* FileWriteBuffer = nullptr;
|
WriteBuffer HeaderWrite;
|
||||||
uint64_t FileWriterWritten = 0;
|
WriteBuffer CppWrite;
|
||||||
|
void InitBuffer(WriteBuffer& buf);
|
||||||
|
bool WriteBufferToDisk(const bx::FilePath& path, const WriteBuffer& buf);
|
||||||
|
void WriteInternal(WriteBuffer& buf, const char* templateStr, va_list args);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void PrintTypeName(char* buf, int32_t bufSize, const Def::FieldType& type, const Def::DefinitionFile& definitions);
|
void PrintTypeName(char* buf, int32_t bufSize, const Def::FieldType& type, const Def::DefinitionFile& definitions);
|
||||||
void WriteEnums(const Def::DefinitionFile& definitions);
|
void WriteEnums(const Def::DefinitionFile& definitions);
|
||||||
void WriteTypes(const Def::DefinitionFile& definitions);
|
void WriteTypes(const Def::DefinitionFile& definitions);
|
||||||
|
void WriteSaveLoadMethods(const Def::DefinitionFile& definitions);
|
||||||
|
|
||||||
void GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions);
|
void GenerateCpp(const bx::FilePath& outDir, const Def::DefinitionFile& definitions);
|
||||||
void Write(const char* Template, ...);
|
void Write(const char* templateStr, ...);
|
||||||
|
void WriteCpp(const char* templateStr, ...);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -6,6 +6,10 @@
|
|||||||
#include "Puzzle.h"
|
#include "Puzzle.h"
|
||||||
#include "SDL3/SDL_mouse.h"
|
#include "SDL3/SDL_mouse.h"
|
||||||
#include "bgfx/bgfx.h"
|
#include "bgfx/bgfx.h"
|
||||||
|
#include "bx/error.h"
|
||||||
|
#include "bx/file.h"
|
||||||
|
#include "bx/filepath.h"
|
||||||
|
#include "bx/string.h"
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "rendering/Rendering.h"
|
#include "rendering/Rendering.h"
|
||||||
#include <SDL3/SDL.h>
|
#include <SDL3/SDL.h>
|
||||||
@@ -70,7 +74,58 @@ namespace Game
|
|||||||
needReset |= PuzzleTiles.Setup(storagePtr, needReset);
|
needReset |= PuzzleTiles.Setup(storagePtr, needReset);
|
||||||
needReset |= UIQuads.Setup(storagePtr, needReset);
|
needReset |= UIQuads.Setup(storagePtr, needReset);
|
||||||
|
|
||||||
PuzzleData.Setup();
|
Generated::Setup(PuzzleData);
|
||||||
|
|
||||||
|
bx::Error err;
|
||||||
|
bx::DirectoryReader dirIter;
|
||||||
|
bx::FileInfo info;
|
||||||
|
bx::FilePath puzzleDirPath{"game/data/puzzles"};
|
||||||
|
uint32_t puzIdx = 0;
|
||||||
|
if (dirIter.open(puzzleDirPath, &err))
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
int32_t readCount = dirIter.read(&info, sizeof(info), &err);
|
||||||
|
if (readCount == 0) break;
|
||||||
|
if (err.isOk())
|
||||||
|
{
|
||||||
|
if (info.type != bx::FileType::File) continue;
|
||||||
|
bx::StringView pathEnd = info.filePath.getExt();
|
||||||
|
if (bx::strCmpI(pathEnd, ".pzl") != 0) continue;
|
||||||
|
if (puzIdx >= BX_COUNTOF(Puzzles))
|
||||||
|
{
|
||||||
|
LOG_WARN("Too many puzzles!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
bx::FilePath fullPath = puzzleDirPath;
|
||||||
|
fullPath.join(info.filePath);
|
||||||
|
LOG("Loading %s", fullPath.getCPtr());
|
||||||
|
|
||||||
|
Generated::Deserializer ser;
|
||||||
|
ser.Init(fullPath);
|
||||||
|
if (Generated::Load(&Puzzles[puzIdx].Data, 1, ser))
|
||||||
|
{
|
||||||
|
Puzzles[puzIdx].Setup();
|
||||||
|
++puzIdx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_WARN("Failed to load puzzle!");
|
||||||
|
}
|
||||||
|
ser.Finish();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR("Failed parsing file name at %s:\n%s", puzzleDirPath.getCPtr(), err.getMessage());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR("Failed to open puzzle dir at %s:\n%s", puzzleDirPath.getCPtr(), err.getMessage().getCPtr());
|
||||||
|
}
|
||||||
|
|
||||||
if (Cubes.Count == 0)
|
if (Cubes.Count == 0)
|
||||||
{
|
{
|
||||||
@@ -255,7 +310,7 @@ namespace Game
|
|||||||
|
|
||||||
for (uint32_t cardI = 0; cardI < Data.PlacedCardCount; ++cardI)
|
for (uint32_t cardI = 0; cardI < Data.PlacedCardCount; ++cardI)
|
||||||
{
|
{
|
||||||
const Puzzle::PlacedPuzzleCard& card = Data.PlacedCards[cardI];
|
const Generated::PlacedPuzzleCard& card = Data.PlacedCards[cardI];
|
||||||
Level& level = GetInstance().GameLevel;
|
Level& level = GetInstance().GameLevel;
|
||||||
TileHandles[cardI] = level.PuzzleTiles.New();
|
TileHandles[cardI] = level.PuzzleTiles.New();
|
||||||
UIPlacedCards[cardI] = level.UIQuads.New();
|
UIPlacedCards[cardI] = level.UIQuads.New();
|
||||||
@@ -283,9 +338,10 @@ namespace Game
|
|||||||
|
|
||||||
for (int32_t cardI = 0; cardI < Data.PlacedCardCount; ++cardI)
|
for (int32_t cardI = 0; cardI < Data.PlacedCardCount; ++cardI)
|
||||||
{
|
{
|
||||||
Puzzle::PlacedPuzzleCard& card = Data.PlacedCards[cardI];
|
Generated::PlacedPuzzleCard& card = Data.PlacedCards[cardI];
|
||||||
if (!card.RefCard.IsValid()) continue;
|
if (!Generated::IsValid(card.RefCard)) continue;
|
||||||
const Puzzle::StaticPuzzleCard& cData = Puzzle::StaticPuzzleData::Get().GetCard(card.RefCard);
|
const Generated::StaticPuzzleCard& cData =
|
||||||
|
Generated::GetCard(Generated::GetStaticPuzzleData(), card.RefCard);
|
||||||
level.PuzzleTiles.Get(TileHandles[cardI]).EData.ModelHandle = cData.ModelHandle;
|
level.PuzzleTiles.Get(TileHandles[cardI]).EData.ModelHandle = cData.ModelHandle;
|
||||||
|
|
||||||
auto& quad = level.UIQuads.Get(UIPlacedCards[cardI]);
|
auto& quad = level.UIQuads.Get(UIPlacedCards[cardI]);
|
||||||
|
|||||||
@@ -128,7 +128,7 @@ namespace Game
|
|||||||
struct WorldPuzzle
|
struct WorldPuzzle
|
||||||
{
|
{
|
||||||
static constexpr Vec2 WorldCardSize{10.0f, 10.0f};
|
static constexpr Vec2 WorldCardSize{10.0f, 10.0f};
|
||||||
Puzzle::PuzzleData Data;
|
Generated::PuzzleData Data;
|
||||||
Vec3 WorldPosition;
|
Vec3 WorldPosition;
|
||||||
PuzzleTileEntityHandle TileHandles[Puzzle::Config::MaxCardsInPuzzle];
|
PuzzleTileEntityHandle TileHandles[Puzzle::Config::MaxCardsInPuzzle];
|
||||||
UIQuadEntityHandle UIPlacedCards[Puzzle::Config::MaxCardsInPuzzle];
|
UIQuadEntityHandle UIPlacedCards[Puzzle::Config::MaxCardsInPuzzle];
|
||||||
@@ -146,7 +146,7 @@ namespace Game
|
|||||||
EntityManager<UIQuadEntity, UIQuadEntityHandle, 1024> UIQuads;
|
EntityManager<UIQuadEntity, UIQuadEntityHandle, 1024> UIQuads;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Puzzle::StaticPuzzleData PuzzleData;
|
Generated::StaticPuzzleData PuzzleData;
|
||||||
WorldPuzzle Puzzles[1];
|
WorldPuzzle Puzzles[1];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -9,73 +9,79 @@
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
static constexpr Puzzle::PuzPos Dirs[4]{
|
static constexpr Generated::PuzPos Dirs[4]{
|
||||||
{-1, 0},
|
{-1, 0},
|
||||||
{0, -1},
|
{0, -1},
|
||||||
{0, 1},
|
{0, 1},
|
||||||
{1, 0},
|
{1, 0},
|
||||||
};
|
};
|
||||||
|
|
||||||
Puzzle::StaticPuzzleData* StaticDataInstance = nullptr;
|
Generated::StaticPuzzleData* StaticDataInstance = nullptr;
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace Puzzle
|
namespace Generated
|
||||||
{
|
{
|
||||||
void StaticPuzzleData::Setup()
|
void Setup(StaticPuzzleData& data)
|
||||||
{
|
{
|
||||||
StaticDataInstance = this;
|
StaticDataInstance = &data;
|
||||||
LOG("Setting up static puzzle data");
|
LOG("Setting up static puzzle data");
|
||||||
for (int32_t i = 0; i < BX_COUNTOF(Cards); ++i)
|
for (int32_t i = 0; i < BX_COUNTOF(data.Cards); ++i)
|
||||||
{
|
{
|
||||||
Cards[i].ModelHandle = Game::GameRendering::Get().GetModelHandleFromPath("models/w straight.glb");
|
data.Cards[i].ModelHandle = Game::GameRendering::Get().GetModelHandleFromPath("models/w straight.glb");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StaticPuzzleData& StaticPuzzleData::Get()
|
StaticPuzzleData& GetStaticPuzzleData()
|
||||||
{
|
{
|
||||||
assert(StaticDataInstance != nullptr);
|
assert(StaticDataInstance != nullptr);
|
||||||
return *StaticDataInstance;
|
return *StaticDataInstance;
|
||||||
}
|
}
|
||||||
const StaticPuzzleCard& StaticPuzzleData::GetCard(StaticPuzzleCardHandle H) const
|
const StaticPuzzleCard& GetCard(const StaticPuzzleData& data, StaticPuzzleCardHandle H)
|
||||||
{
|
{
|
||||||
assert(H.IsValid());
|
assert(IsValid(H));
|
||||||
return Cards[H.Idx];
|
return data.Cards[H.Idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PuzzleNode::HasElement(PuzzleElementType search) const
|
bool HasElement(const PuzzleNode& node, PuzzleElementType::Enum search)
|
||||||
{
|
{
|
||||||
for (int32_t i = 0; i < Config::MaxElementsPerTile; ++i)
|
for (int32_t i = 0; i < Puzzle::Config::MaxElementsPerTile; ++i)
|
||||||
{
|
{
|
||||||
if (PlacedTypes[i] == search) return true;
|
if (node.PlacedTypes[i] == search) return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PuzzleNode::IsEmpty() const
|
bool IsEmpty(const PuzzleNode& node)
|
||||||
{
|
{
|
||||||
for (int32_t i = 0; i < Config::MaxElementsPerTile; ++i)
|
for (int32_t i = 0; i < Puzzle::Config::MaxElementsPerTile; ++i)
|
||||||
{
|
{
|
||||||
if (PlacedTypes[i] != PuzzleElementType::None) return false;
|
if (node.PlacedTypes[i] != PuzzleElementType::None) return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t PuzzleCardStack::GetRemainingCount()
|
bool IsValid(StaticPuzzleCardHandle h)
|
||||||
{
|
{
|
||||||
assert(MaxAvailableCount >= UsedCount);
|
return h.Idx != UINT16_MAX;
|
||||||
return MaxAvailableCount - UsedCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const PuzzleNode& PuzzleData::GetNodeAt(PuzPos pos) const
|
uint8_t GetRemainingCount(const PuzzleCardStack& stack)
|
||||||
{
|
{
|
||||||
assert(pos.X < Config::MaxPuzzleSizeCards && pos.Y < Config::MaxPuzzleSizeCards && pos.X >= 0 && pos.Y >= 0);
|
assert(stack.MaxAvailableCount >= stack.UsedCount);
|
||||||
return PlacedNodes[pos.Y * Config::MaxPuzzleSizeCards + pos.X];
|
return stack.MaxAvailableCount - stack.UsedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
PuzzleElementType PuzzleData::GetElementAt(ElemPos pos) const
|
const PuzzleNode& GetNodeAt(const PuzzleData& puz, PuzPos pos)
|
||||||
{
|
{
|
||||||
assert(pos.ElemIdx < Config::MaxElementsPerTile);
|
assert(pos.X < Puzzle::Config::MaxPuzzleSizeCards && pos.Y < Puzzle::Config::MaxPuzzleSizeCards && pos.X >= 0 &&
|
||||||
const PuzzleNode& node = GetNodeAt(pos.Position);
|
pos.Y >= 0);
|
||||||
|
return puz.PlacedNodes[pos.Y * Puzzle::Config::MaxPuzzleSizeCards + pos.X];
|
||||||
|
}
|
||||||
|
|
||||||
|
PuzzleElementType::Enum GetElementAt(const PuzzleData& puz, ElemPos pos)
|
||||||
|
{
|
||||||
|
assert(pos.ElemIdx < Puzzle::Config::MaxElementsPerTile);
|
||||||
|
const PuzzleNode& node = GetNodeAt(puz, pos.Position);
|
||||||
return node.PlacedTypes[pos.ElemIdx];
|
return node.PlacedTypes[pos.ElemIdx];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,26 +101,26 @@ namespace Puzzle
|
|||||||
|
|
||||||
bool PuzzleSolver::IsExitSatisfied(const PuzzleData& puzzle, ElemPos pos)
|
bool PuzzleSolver::IsExitSatisfied(const PuzzleData& puzzle, ElemPos pos)
|
||||||
{
|
{
|
||||||
const PuzzleNode& goalNode = puzzle.GetNodeAt(pos.Position);
|
const PuzzleNode& goalNode = GetNodeAt(puzzle, pos.Position);
|
||||||
PuzzleElementType goalType = puzzle.GetElementAt(pos);
|
PuzzleElementType::Enum goalType = GetElementAt(puzzle, pos);
|
||||||
|
|
||||||
uint32_t currentPositionQueueIdx = 0;
|
uint32_t currentPositionQueueIdx = 0;
|
||||||
uint32_t positionQueueCount = 0;
|
uint32_t positionQueueCount = 0;
|
||||||
PuzPos positionQueue[Config::MaxTilesInPuzzle];
|
PuzPos positionQueue[Puzzle::Config::MaxTilesInPuzzle];
|
||||||
|
|
||||||
positionQueue[0] = pos.Position;
|
positionQueue[0] = pos.Position;
|
||||||
positionQueueCount++;
|
positionQueueCount++;
|
||||||
while (positionQueueCount > 0)
|
while (positionQueueCount > 0)
|
||||||
{
|
{
|
||||||
assert(currentPositionQueueIdx < Config::MaxTilesInPuzzle);
|
assert(currentPositionQueueIdx < Puzzle::Config::MaxTilesInPuzzle);
|
||||||
PuzPos currentPos = positionQueue[currentPositionQueueIdx];
|
PuzPos currentPos = positionQueue[currentPositionQueueIdx];
|
||||||
for (PuzPos dir : Dirs)
|
for (PuzPos dir : Dirs)
|
||||||
{
|
{
|
||||||
PuzPos nextPos = currentPos + dir;
|
PuzPos nextPos = currentPos + dir;
|
||||||
if (IsValidGoalConnection(puzzle, nextPos, currentPos, goalType))
|
if (IsValidGoalConnection(puzzle, nextPos, currentPos, goalType))
|
||||||
{
|
{
|
||||||
const PuzzleNode& node = puzzle.GetNodeAt(nextPos);
|
const PuzzleNode& node = GetNodeAt(puzzle, nextPos);
|
||||||
for (PuzzleElementType e : node.PlacedTypes)
|
for (PuzzleElementType::Enum e : node.PlacedTypes)
|
||||||
{
|
{
|
||||||
if (IsValidSource(e, goalType))
|
if (IsValidSource(e, goalType))
|
||||||
{
|
{
|
||||||
@@ -133,46 +139,50 @@ namespace Puzzle
|
|||||||
bool PuzzleSolver::IsValidGoalConnection(const PuzzleData& puzzle,
|
bool PuzzleSolver::IsValidGoalConnection(const PuzzleData& puzzle,
|
||||||
PuzPos flowFrom,
|
PuzPos flowFrom,
|
||||||
PuzPos flowTo,
|
PuzPos flowTo,
|
||||||
PuzzleElementType goalType)
|
PuzzleElementType::Enum goalType)
|
||||||
{
|
{
|
||||||
const PuzzleNode& from = puzzle.GetNodeAt(flowFrom);
|
const PuzzleNode& from = GetNodeAt(puzzle, flowFrom);
|
||||||
const PuzzleNode& to = puzzle.GetNodeAt(flowTo);
|
const PuzzleNode& to = GetNodeAt(puzzle, flowTo);
|
||||||
|
|
||||||
if (goalType == PuzzleElementType::WaterGoal)
|
if (goalType == PuzzleElementType::WaterGoal)
|
||||||
{
|
{
|
||||||
return from.HasElement(PuzzleElementType::WaterIn) || from.HasElement(PuzzleElementType::WaterChannel) ||
|
return HasElement(from, PuzzleElementType::WaterIn) || HasElement(from, PuzzleElementType::WaterChannel) ||
|
||||||
from.HasElement(PuzzleElementType::WaterGoal);
|
HasElement(from, PuzzleElementType::WaterGoal);
|
||||||
}
|
}
|
||||||
else if (goalType == PuzzleElementType::ElectricGoal)
|
else if (goalType == PuzzleElementType::ElectricGoal)
|
||||||
{
|
{
|
||||||
return from.HasElement(PuzzleElementType::ElectricIn) || from.HasElement(PuzzleElementType::ElectricGoal) ||
|
return HasElement(from, PuzzleElementType::ElectricIn) ||
|
||||||
from.IsEmpty();
|
HasElement(from, PuzzleElementType::ElectricGoal) || IsEmpty(from);
|
||||||
}
|
}
|
||||||
assert(false);
|
assert(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool PuzzleSolver::IsValidSource(PuzzleElementType sourceType, PuzzleElementType goalType)
|
bool PuzzleSolver::IsValidSource(PuzzleElementType::Enum sourceType, PuzzleElementType::Enum goalType)
|
||||||
{
|
{
|
||||||
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()
|
} // namespace Generated
|
||||||
|
|
||||||
|
namespace Generated
|
||||||
|
{
|
||||||
|
bool RenderDebugUI(PuzzleData& obj)
|
||||||
{
|
{
|
||||||
bool dataChanged = false;
|
bool dataChanged = false;
|
||||||
|
|
||||||
bool isVisible = true;
|
bool isVisible = true;
|
||||||
if (ImGui::Begin("Puzzle", &isVisible))
|
if (ImGui::Begin("Puzzle", &isVisible))
|
||||||
{
|
{
|
||||||
ImGui::Text("%s", PuzzleName);
|
ImGui::Text("%s", obj.PuzzleName);
|
||||||
|
|
||||||
int32_t W = S.WidthTiles;
|
int32_t W = obj.WidthTiles;
|
||||||
int32_t H = S.HeightTiles;
|
int32_t H = obj.HeightTiles;
|
||||||
ImGui::PushID("width");
|
ImGui::PushID("width");
|
||||||
ImGui::SetNextItemWidth(40);
|
ImGui::SetNextItemWidth(40);
|
||||||
if (ImGui::DragInt("", &W, 0.3f, 0, Config::MaxPuzzleSizeTiles))
|
if (ImGui::DragInt("", &W, 0.3f, 0, Puzzle::Config::MaxPuzzleSizeTiles))
|
||||||
{
|
{
|
||||||
S.WidthTiles = uint8_t(W);
|
obj.WidthTiles = uint8_t(W);
|
||||||
dataChanged = true;
|
dataChanged = true;
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
@@ -181,9 +191,9 @@ namespace Puzzle
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(40);
|
ImGui::SetNextItemWidth(40);
|
||||||
ImGui::PushID("height");
|
ImGui::PushID("height");
|
||||||
if (ImGui::DragInt("", &H, 0.3f, 0, Config::MaxPuzzleSizeTiles))
|
if (ImGui::DragInt("", &H, 0.3f, 0, Puzzle::Config::MaxPuzzleSizeTiles))
|
||||||
{
|
{
|
||||||
S.HeightTiles = uint8_t(H);
|
obj.HeightTiles = uint8_t(H);
|
||||||
dataChanged = true;
|
dataChanged = true;
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
@@ -193,10 +203,43 @@ namespace Puzzle
|
|||||||
if (dataChanged)
|
if (dataChanged)
|
||||||
{
|
{
|
||||||
char path[128]{0};
|
char path[128]{0};
|
||||||
bx::snprintf(path, sizeof(path), "game/data/%s.pzl", PuzzleName);
|
bx::snprintf(path, sizeof(path), "game/data/puzzles/%s.pzl", obj.PuzzleName);
|
||||||
SerializeStruct(&S, sizeof(S), path);
|
Serializer ser;
|
||||||
|
ser.Init(path);
|
||||||
|
if (Save(&obj, 1, ser))
|
||||||
|
{
|
||||||
|
LOG("Saved to %s", path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG_ERROR("Failed to save to %s", path);
|
||||||
|
}
|
||||||
|
ser.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
return isVisible;
|
return isVisible;
|
||||||
}
|
}
|
||||||
} // namespace Puzzle
|
|
||||||
|
PuzPos operator+=(PuzPos lhs, const PuzPos& rhs)
|
||||||
|
{
|
||||||
|
lhs.X += rhs.X;
|
||||||
|
lhs.Y += rhs.Y;
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
PuzPos operator+(PuzPos lhs, const PuzPos& rhs)
|
||||||
|
{
|
||||||
|
lhs += rhs;
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
PuzPos operator-=(PuzPos lhs, const PuzPos& rhs)
|
||||||
|
{
|
||||||
|
lhs.X -= rhs.X;
|
||||||
|
lhs.Y -= rhs.Y;
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
PuzPos operator-(PuzPos lhs, const PuzPos& rhs)
|
||||||
|
{
|
||||||
|
lhs -= rhs;
|
||||||
|
return lhs;
|
||||||
|
}
|
||||||
|
} // namespace Generated
|
||||||
|
|||||||
@@ -19,125 +19,139 @@ namespace Puzzle
|
|||||||
static constexpr uint32_t MaxGoalPositions = 16;
|
static constexpr uint32_t MaxGoalPositions = 16;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PuzPos
|
// struct PuzPos
|
||||||
|
// {
|
||||||
|
// int8_t X = 0;
|
||||||
|
// int8_t Y = 0;
|
||||||
|
|
||||||
|
// PuzPos& operator+=(const PuzPos& rhs)
|
||||||
|
// {
|
||||||
|
// X += rhs.X;
|
||||||
|
// Y += rhs.Y;
|
||||||
|
// return *this;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// friend PuzPos operator+(PuzPos lhs, const PuzPos& rhs)
|
||||||
|
// {
|
||||||
|
// lhs += rhs;
|
||||||
|
// return lhs;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// struct ElemPos
|
||||||
|
// {
|
||||||
|
// PuzPos Position;
|
||||||
|
// uint8_t ElemIdx = 0;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// enum class PuzzleElementType : uint8_t
|
||||||
|
// {
|
||||||
|
// None,
|
||||||
|
// WaterIn,
|
||||||
|
// WaterGoal,
|
||||||
|
// WaterChannel,
|
||||||
|
// ElectricIn,
|
||||||
|
// ElectricGoal,
|
||||||
|
// Blocked,
|
||||||
|
// Bridge,
|
||||||
|
// };
|
||||||
|
|
||||||
|
// struct PuzzleNode
|
||||||
|
// {
|
||||||
|
// PuzzleElementType PlacedTypes[Config::MaxElementsPerTile]{PuzzleElementType::None};
|
||||||
|
|
||||||
|
// bool HasElement(PuzzleElementType search) const;
|
||||||
|
// bool IsEmpty() const;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// struct StaticPuzzleCard
|
||||||
|
// {
|
||||||
|
// PuzzleNode Nodes[Config::NodesPerCard];
|
||||||
|
// uint16_t ModelHandle = 0;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// struct StaticPuzzleCardHandle
|
||||||
|
// {
|
||||||
|
// uint16_t Idx = UINT16_MAX;
|
||||||
|
// bool IsValid()
|
||||||
|
// {
|
||||||
|
// return Idx != UINT16_MAX;
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
|
||||||
|
// struct StaticPuzzleData
|
||||||
|
// {
|
||||||
|
// StaticPuzzleCard Cards[64];
|
||||||
|
|
||||||
|
// void Setup();
|
||||||
|
// static StaticPuzzleData& Get();
|
||||||
|
// const StaticPuzzleCard& GetCard(StaticPuzzleCardHandle H) const;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// struct PlacedPuzzleCard
|
||||||
|
// {
|
||||||
|
// StaticPuzzleCardHandle RefCard;
|
||||||
|
// PuzPos Position;
|
||||||
|
// uint8_t Rotation = 0;
|
||||||
|
// bool IsLocked = false;
|
||||||
|
// };
|
||||||
|
|
||||||
|
// struct PuzzleCardStack
|
||||||
|
// {
|
||||||
|
// StaticPuzzleCardHandle RefCard;
|
||||||
|
// uint8_t MaxAvailableCount = 0;
|
||||||
|
// uint8_t UsedCount = 0;
|
||||||
|
|
||||||
|
// uint8_t GetRemainingCount();
|
||||||
|
// };
|
||||||
|
|
||||||
|
// struct PuzzleData
|
||||||
|
// {
|
||||||
|
// uint32_t AvailableCardCount = 0;
|
||||||
|
// PuzzleCardStack AvailableCards[Config::MaxAvailableStacks];
|
||||||
|
// uint32_t PlacedCardCount = 0;
|
||||||
|
// PlacedPuzzleCard PlacedCards[Config::MaxCardsInPuzzle];
|
||||||
|
|
||||||
|
// // Indexed by board position
|
||||||
|
// PuzzleNode PlacedNodes[Config::MaxTilesInPuzzle];
|
||||||
|
|
||||||
|
// uint32_t GoalPositionCount = 0;
|
||||||
|
// ElemPos GoalPositions[Config::MaxGoalPositions];
|
||||||
|
|
||||||
|
// const PuzzleNode& GetNodeAt(PuzPos pos) const;
|
||||||
|
// PuzzleElementType GetElementAt(ElemPos pos) const;
|
||||||
|
|
||||||
|
// char PuzzleName[32]{"Unnamed"};
|
||||||
|
// bool RenderDebugUI();
|
||||||
|
// };
|
||||||
|
} // namespace Puzzle
|
||||||
|
|
||||||
|
namespace Generated
|
||||||
{
|
{
|
||||||
int8_t X = 0;
|
PuzPos operator+=(PuzPos lhs, const PuzPos& rhs);
|
||||||
int8_t Y = 0;
|
PuzPos operator+(PuzPos lhs, const PuzPos& rhs);
|
||||||
|
|
||||||
PuzPos& operator+=(const PuzPos& rhs)
|
void Setup(StaticPuzzleData& data);
|
||||||
{
|
StaticPuzzleData& GetStaticPuzzleData();
|
||||||
X += rhs.X;
|
const StaticPuzzleCard& GetCard(const StaticPuzzleData& data, StaticPuzzleCardHandle H);
|
||||||
Y += rhs.Y;
|
bool HasElement(const PuzzleNode& node, PuzzleElementType::Enum search);
|
||||||
return *this;
|
bool IsEmpty(const PuzzleNode& node);
|
||||||
}
|
bool IsValid(StaticPuzzleCardHandle h);
|
||||||
|
uint8_t GetRemainingCount(const PuzzleCardStack& stack);
|
||||||
friend PuzPos operator+(PuzPos lhs, const PuzPos& rhs)
|
const PuzzleNode& GetNodeAt(const PuzzleData& puz, PuzPos pos);
|
||||||
{
|
PuzzleElementType::Enum GetElementAt(const PuzzleData& puz, ElemPos pos);
|
||||||
lhs += rhs;
|
|
||||||
return lhs;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ElemPos
|
|
||||||
{
|
|
||||||
PuzPos Position;
|
|
||||||
uint8_t ElemIdx = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class PuzzleElementType : uint8_t
|
|
||||||
{
|
|
||||||
None,
|
|
||||||
WaterIn,
|
|
||||||
WaterGoal,
|
|
||||||
WaterChannel,
|
|
||||||
ElectricIn,
|
|
||||||
ElectricGoal,
|
|
||||||
Blocked,
|
|
||||||
Bridge,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PuzzleNode
|
|
||||||
{
|
|
||||||
PuzzleElementType PlacedTypes[Config::MaxElementsPerTile]{PuzzleElementType::None};
|
|
||||||
|
|
||||||
bool HasElement(PuzzleElementType search) const;
|
|
||||||
bool IsEmpty() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StaticPuzzleCard
|
|
||||||
{
|
|
||||||
PuzzleNode Nodes[Config::NodesPerCard];
|
|
||||||
uint16_t ModelHandle = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StaticPuzzleCardHandle
|
|
||||||
{
|
|
||||||
uint16_t Idx = UINT16_MAX;
|
|
||||||
bool IsValid()
|
|
||||||
{
|
|
||||||
return Idx != UINT16_MAX;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct StaticPuzzleData
|
|
||||||
{
|
|
||||||
StaticPuzzleCard Cards[64];
|
|
||||||
|
|
||||||
void Setup();
|
|
||||||
static StaticPuzzleData& Get();
|
|
||||||
const StaticPuzzleCard& GetCard(StaticPuzzleCardHandle H) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PlacedPuzzleCard
|
|
||||||
{
|
|
||||||
StaticPuzzleCardHandle RefCard;
|
|
||||||
PuzPos Position;
|
|
||||||
uint8_t Rotation = 0;
|
|
||||||
bool IsLocked = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PuzzleCardStack
|
|
||||||
{
|
|
||||||
StaticPuzzleCardHandle RefCard;
|
|
||||||
uint8_t MaxAvailableCount = 0;
|
|
||||||
uint8_t UsedCount = 0;
|
|
||||||
|
|
||||||
uint8_t GetRemainingCount();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PuzzleData
|
|
||||||
{
|
|
||||||
SER_HEADER(1, "PZZL");
|
|
||||||
Generated::PuzzleData S;
|
|
||||||
|
|
||||||
uint32_t AvailableCardCount = 0;
|
|
||||||
PuzzleCardStack AvailableCards[Config::MaxAvailableStacks];
|
|
||||||
uint32_t PlacedCardCount = 0;
|
|
||||||
PlacedPuzzleCard PlacedCards[Config::MaxCardsInPuzzle];
|
|
||||||
|
|
||||||
// Indexed by board position
|
|
||||||
PuzzleNode PlacedNodes[Config::MaxTilesInPuzzle];
|
|
||||||
|
|
||||||
uint32_t GoalPositionCount = 0;
|
|
||||||
ElemPos GoalPositions[Config::MaxGoalPositions];
|
|
||||||
|
|
||||||
const PuzzleNode& GetNodeAt(PuzPos pos) const;
|
|
||||||
PuzzleElementType GetElementAt(ElemPos pos) const;
|
|
||||||
|
|
||||||
char PuzzleName[32]{"Unnamed"};
|
|
||||||
bool RenderDebugUI();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PuzzleSolver
|
struct PuzzleSolver
|
||||||
{
|
{
|
||||||
bool IsPuzzleSolved(const PuzzleData& puzzle);
|
bool IsPuzzleSolved(const Generated::PuzzleData& puzzle);
|
||||||
bool IsExitSatisfied(const PuzzleData& puzzle, ElemPos pos);
|
bool IsExitSatisfied(const Generated::PuzzleData& puzzle, ElemPos pos);
|
||||||
|
|
||||||
// This assumes flowFrom is already verified to be connected.
|
// This assumes flowFrom is already verified to be connected.
|
||||||
bool IsValidGoalConnection(const PuzzleData& puzzle,
|
bool IsValidGoalConnection(const Generated::PuzzleData& puzzle,
|
||||||
PuzPos flowFrom,
|
PuzPos flowFrom,
|
||||||
PuzPos flowTo,
|
PuzPos flowTo,
|
||||||
PuzzleElementType goalType);
|
PuzzleElementType::Enum goalType);
|
||||||
bool IsValidSource(PuzzleElementType sourceType, PuzzleElementType goalType);
|
bool IsValidSource(PuzzleElementType::Enum sourceType, PuzzleElementType::Enum goalType);
|
||||||
};
|
};
|
||||||
} // namespace Puzzle
|
bool RenderDebugUI(PuzzleData& obj);
|
||||||
|
} // namespace Generated
|
||||||
|
|||||||
BIN
src/game/data/puzzles/hell yea.pzl
LFS
Normal file
BIN
src/game/data/puzzles/hell yea.pzl
LFS
Normal file
Binary file not shown.
BIN
src/game/data/puzzles/test.pzl
LFS
Normal file
BIN
src/game/data/puzzles/test.pzl
LFS
Normal file
Binary file not shown.
@@ -69,4 +69,5 @@ type PuzzleData
|
|||||||
PuzzleNode PlacedNodes Arr(1024)
|
PuzzleNode PlacedNodes Arr(1024)
|
||||||
u32 GoalPositionCount
|
u32 GoalPositionCount
|
||||||
ElemPos GoalPositions Arr(16)
|
ElemPos GoalPositions Arr(16)
|
||||||
|
str PuzzleName Arr(64)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -511,6 +511,7 @@ namespace Game
|
|||||||
if (ImGui::Begin("Puzzles"))
|
if (ImGui::Begin("Puzzles"))
|
||||||
{
|
{
|
||||||
ImGui::Text("List");
|
ImGui::Text("List");
|
||||||
|
ImGui::Separator();
|
||||||
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
|
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
|
||||||
{
|
{
|
||||||
auto& puzzleData = level.Puzzles[i].Data;
|
auto& puzzleData = level.Puzzles[i].Data;
|
||||||
@@ -524,10 +525,10 @@ namespace Game
|
|||||||
if (isSelected)
|
if (isSelected)
|
||||||
{
|
{
|
||||||
ImGui::PushID("edit field");
|
ImGui::PushID("edit field");
|
||||||
ImGui::InputText("", puzzleData.PuzzleName, sizeof(Puzzle::PuzzleData::PuzzleName));
|
ImGui::InputText("", puzzleData.PuzzleName, sizeof(Generated::PuzzleData::PuzzleName));
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
|
||||||
if (!puzzleData.RenderDebugUI())
|
if (!Generated::RenderDebugUI(puzzleData))
|
||||||
{
|
{
|
||||||
debug.SelectedDebugLevel = UINT16_MAX;
|
debug.SelectedDebugLevel = UINT16_MAX;
|
||||||
}
|
}
|
||||||
@@ -540,13 +541,6 @@ namespace Game
|
|||||||
GetInstance().GameLevel.Update();
|
GetInstance().GameLevel.Update();
|
||||||
GetInstance().GameLevel.Render(MainViewID, Models, Materials);
|
GetInstance().GameLevel.Render(MainViewID, Models, Materials);
|
||||||
|
|
||||||
// bgfx::dbgTextPrintf(1, 1, 0x0F, "Time: %.1fs", GetInstance().Time.Now);
|
|
||||||
// for (int32_t i = 0; i < (int32_t)PerfCounterType::COUNT; ++i)
|
|
||||||
// {
|
|
||||||
// bgfx::dbgTextPrintf(
|
|
||||||
// 1, 2 + i, 0x0F, "%s Max: %.3fs", PerfCounterNames[i], shared.Window.PerfCounters[i].GetMax());
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Finish Frame
|
// Finish Frame
|
||||||
imguiEndFrame();
|
imguiEndFrame();
|
||||||
|
|
||||||
|
|||||||
41
src/gen/Def.cpp
Normal file
41
src/gen/Def.cpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
#include "Def.h"
|
||||||
|
|
||||||
|
#define INST(T) \
|
||||||
|
template bool Save<T>(const T* obj, uint32_t count, Serializer& serializer); \
|
||||||
|
template bool Load<T>(T * obj, uint32_t count, Deserializer & serializer);
|
||||||
|
|
||||||
|
namespace Generated
|
||||||
|
{
|
||||||
|
template <typename T> bool Save(const T* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = serializer.Write(&obj[i], sizeof(obj[i])) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> bool Load(T* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = serializer.Read(&obj[i], sizeof(obj[i])) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
|
||||||
|
INST(uint8_t)
|
||||||
|
INST(uint16_t)
|
||||||
|
INST(uint32_t)
|
||||||
|
INST(uint64_t)
|
||||||
|
INST(int8_t)
|
||||||
|
INST(int16_t)
|
||||||
|
INST(int32_t)
|
||||||
|
INST(int64_t)
|
||||||
|
INST(float)
|
||||||
|
INST(double)
|
||||||
|
INST(bool)
|
||||||
|
INST(char)
|
||||||
|
} // namespace Generated
|
||||||
@@ -1,2 +1,59 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include <bx/file.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Generated
|
||||||
|
{
|
||||||
|
struct Serializer
|
||||||
|
{
|
||||||
|
bx::Error Err;
|
||||||
|
bx::FilePath Path;
|
||||||
|
bx::FileWriter Writer;
|
||||||
|
|
||||||
|
bool Init(const bx::FilePath& path)
|
||||||
|
{
|
||||||
|
Path = path;
|
||||||
|
Writer.open(path, false, &Err);
|
||||||
|
return Err.isOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Write(const void* data, uint32_t size)
|
||||||
|
{
|
||||||
|
Writer.write(data, size, &Err);
|
||||||
|
return Err.isOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Finish()
|
||||||
|
{
|
||||||
|
Writer.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Deserializer
|
||||||
|
{
|
||||||
|
bx::Error Err;
|
||||||
|
bx::FilePath Path;
|
||||||
|
bx::FileReader Reader;
|
||||||
|
|
||||||
|
bool Init(const bx::FilePath& path)
|
||||||
|
{
|
||||||
|
Path = path;
|
||||||
|
Reader.open(path, &Err);
|
||||||
|
return Err.isOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Read(void* data, uint32_t size)
|
||||||
|
{
|
||||||
|
Reader.read(data, size, &Err);
|
||||||
|
return Err.isOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Finish()
|
||||||
|
{
|
||||||
|
Reader.close();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T> bool Save(const T* obj, uint32_t count, Serializer& serializer);
|
||||||
|
template <typename T> bool Load(T* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
} // namespace Generated
|
||||||
|
|||||||
221
src/gen/Generated.cpp
Normal file
221
src/gen/Generated.cpp
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
#include "Generated.h"
|
||||||
|
|
||||||
|
namespace Generated
|
||||||
|
{
|
||||||
|
bool Save(const PuzzleElementType::Enum* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
auto val = (int32_t)obj[i];
|
||||||
|
isOk = Save(&val, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(PuzzleElementType::Enum* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
auto val = (int32_t)obj[i];
|
||||||
|
isOk = Load(&val, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const PuzPos* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Save(&obj[i].X, 1, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].Y, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(PuzPos* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Load(&obj[i].X, 1, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].Y, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const ElemPos* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Save(&obj[i].Position, 1, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].ElemIdx, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(ElemPos* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Load(&obj[i].Position, 1, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].ElemIdx, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const PuzzleNode* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Save(obj[i].PlacedTypes, 4, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(PuzzleNode* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Load(obj[i].PlacedTypes, 4, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const StaticPuzzleCard* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Save(obj[i].Nodes, 4, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].ModelHandle, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(StaticPuzzleCard* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Load(obj[i].Nodes, 4, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].ModelHandle, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const StaticPuzzleCardHandle* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Save(&obj[i].Idx, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(StaticPuzzleCardHandle* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Load(&obj[i].Idx, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const StaticPuzzleData* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Save(obj[i].Cards, 64, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(StaticPuzzleData* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Load(obj[i].Cards, 64, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const PuzzleCardStack* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Save(&obj[i].RefCard, 1, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].MaxAvailableCount, 1, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].UsedCount, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(PuzzleCardStack* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Load(&obj[i].RefCard, 1, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].MaxAvailableCount, 1, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].UsedCount, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const PlacedPuzzleCard* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Save(&obj[i].RefCard, 1, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].Position, 1, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].Rotation, 1, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].IsLocked, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(PlacedPuzzleCard* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Load(&obj[i].RefCard, 1, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].Position, 1, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].Rotation, 1, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].IsLocked, 1, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Save(const PuzzleData* obj, uint32_t count, Serializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Save(&obj[i].WidthTiles, 1, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].HeightTiles, 1, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].AvailableCardCount, 1, serializer) && isOk;
|
||||||
|
isOk = Save(obj[i].AvailableCards, 16, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].PlacedCardCount, 1, serializer) && isOk;
|
||||||
|
isOk = Save(obj[i].PlacedCards, 256, serializer) && isOk;
|
||||||
|
isOk = Save(obj[i].PlacedNodes, 1024, serializer) && isOk;
|
||||||
|
isOk = Save(&obj[i].GoalPositionCount, 1, serializer) && isOk;
|
||||||
|
isOk = Save(obj[i].GoalPositions, 16, serializer) && isOk;
|
||||||
|
isOk = Save(obj[i].PuzzleName, 64, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
bool Load(PuzzleData* obj, uint32_t count, Deserializer& serializer)
|
||||||
|
{
|
||||||
|
bool isOk = true;
|
||||||
|
for (uint32_t i = 0; i < count; ++i)
|
||||||
|
{
|
||||||
|
isOk = Load(&obj[i].WidthTiles, 1, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].HeightTiles, 1, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].AvailableCardCount, 1, serializer) && isOk;
|
||||||
|
isOk = Load(obj[i].AvailableCards, 16, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].PlacedCardCount, 1, serializer) && isOk;
|
||||||
|
isOk = Load(obj[i].PlacedCards, 256, serializer) && isOk;
|
||||||
|
isOk = Load(obj[i].PlacedNodes, 1024, serializer) && isOk;
|
||||||
|
isOk = Load(&obj[i].GoalPositionCount, 1, serializer) && isOk;
|
||||||
|
isOk = Load(obj[i].GoalPositions, 16, serializer) && isOk;
|
||||||
|
isOk = Load(obj[i].PuzzleName, 64, serializer) && isOk;
|
||||||
|
}
|
||||||
|
return isOk;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ namespace Generated
|
|||||||
struct PuzzleElementType
|
struct PuzzleElementType
|
||||||
{
|
{
|
||||||
static constexpr int32_t EntryCount = 8;
|
static constexpr int32_t EntryCount = 8;
|
||||||
enum class Enum : int32_t
|
enum Enum : int32_t
|
||||||
{
|
{
|
||||||
None,
|
None,
|
||||||
WaterIn,
|
WaterIn,
|
||||||
@@ -52,7 +52,7 @@ namespace Generated
|
|||||||
};
|
};
|
||||||
struct PuzzleNode
|
struct PuzzleNode
|
||||||
{
|
{
|
||||||
PuzzleElementType PlacedTypes[4] = {};
|
PuzzleElementType::Enum PlacedTypes[4] = {};
|
||||||
};
|
};
|
||||||
struct StaticPuzzleCard
|
struct StaticPuzzleCard
|
||||||
{
|
{
|
||||||
@@ -91,5 +91,26 @@ namespace Generated
|
|||||||
PuzzleNode PlacedNodes[1024] = {};
|
PuzzleNode PlacedNodes[1024] = {};
|
||||||
uint32_t GoalPositionCount = {};
|
uint32_t GoalPositionCount = {};
|
||||||
ElemPos GoalPositions[16] = {};
|
ElemPos GoalPositions[16] = {};
|
||||||
|
char PuzzleName[64] = {};
|
||||||
};
|
};
|
||||||
|
bool Save(const PuzzleElementType::Enum* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(PuzzleElementType::Enum* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const PuzPos* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(PuzPos* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const ElemPos* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(ElemPos* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const PuzzleNode* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(PuzzleNode* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const StaticPuzzleCard* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(StaticPuzzleCard* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const StaticPuzzleCardHandle* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(StaticPuzzleCardHandle* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const StaticPuzzleData* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(StaticPuzzleData* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const PuzzleCardStack* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(PuzzleCardStack* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const PlacedPuzzleCard* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(PlacedPuzzleCard* obj, uint32_t count, Deserializer& serializer);
|
||||||
|
bool Save(const PuzzleData* obj, uint32_t count, Serializer& serializer);
|
||||||
|
bool Load(PuzzleData* obj, uint32_t count, Deserializer& serializer);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user