static puzzle data!

This commit is contained in:
Asuro
2025-03-13 00:41:32 +01:00
parent f3f994fd8b
commit 155339917d
18 changed files with 264 additions and 143 deletions

View File

@@ -102,7 +102,7 @@ namespace Generated
)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];
constexpr char LoadFuncBodyEnum2[] = R"END( %s& val = (%s&)obj[i];
isOk = Load(&val, 1, serializer) && isOk;
)END";
constexpr char LoadFuncBodyEnd[] = R"END( }
@@ -262,7 +262,7 @@ void CppFileWriter::WriteSaveLoadMethods(const Def::DefinitionFile& definitions)
WriteCpp(WriteTemplates::SaveFuncBodyEnd);
WriteCpp(WriteTemplates::LoadFuncBodyStart1, nameBuf);
WriteCpp(WriteTemplates::LoadFuncBodyEnum1, fieldBuf);
WriteCpp(WriteTemplates::LoadFuncBodyEnum2, fieldBuf, fieldBuf);
WriteCpp(WriteTemplates::LoadFuncBodyEnd);
}
for (int32_t typeIdx = 0; typeIdx < definitions.TypeCount; ++typeIdx)

View File

@@ -43,6 +43,10 @@ namespace Game
uint16_t SelectedDebugLevel = UINT16_MAX;
uint64_t ImguiIniSize = 0;
char ImguiIni[4096]{0};
static constexpr uint32_t MaxAssets = 128;
uint32_t AssetCount = 0;
uint32_t AssetHandles[MaxAssets]{0};
char AssetHandlePaths[MaxAssets][128];
};
struct GameInstance

View File

@@ -74,7 +74,7 @@ namespace Game
needReset |= PuzzleTiles.Setup(storagePtr, needReset);
needReset |= UIQuads.Setup(storagePtr, needReset);
Generated::Setup(PuzzleData);
Generated::Setup();
bx::Error err;
bx::DirectoryReader dirIter;

View File

@@ -1,3 +1,4 @@
#include "Global.h"
#include "Log.h"
#include "Mesh.h"
#include "bx/bx.h"
@@ -8,6 +9,8 @@
#include "bx/string.h"
#include "rendering/Rendering.h"
#include "Instance.h"
#define TINYGLTF_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_WRITE_IMPLEMENTATION
@@ -139,6 +142,15 @@ namespace Game
if (LoadMesh(mod, fullPath.getCPtr(), modelFileIsBinary[i]))
{
mod.AssetHandle = CrcPath(fullPath.getCPtr());
auto& inst = GetInstance();
if (inst.DebugData.AssetCount < inst.DebugData.MaxAssets)
{
inst.DebugData.AssetHandles[inst.DebugData.AssetCount] = mod.AssetHandle;
bx::strCopy(inst.DebugData.AssetHandlePaths[inst.DebugData.AssetCount],
sizeof(inst.DebugData.AssetHandlePaths[inst.DebugData.AssetCount]),
fullPath.getCPtr());
++inst.DebugData.AssetCount;
}
++writeI;
}
else

View File

@@ -1,10 +1,9 @@
#include "Log.h"
#include "Puzzle.h"
#include "bx/string.h"
#include "imgui.h"
#include "rendering/Rendering.h"
#include "bx/bx.h"
#include "imgui.h"
#include <cassert>
namespace
@@ -16,25 +15,43 @@ namespace
{1, 0},
};
Generated::StaticPuzzleData* StaticDataInstance = nullptr;
Generated::StaticPuzzleData StaticData;
} // namespace
namespace Generated
{
void Setup(StaticPuzzleData& data)
void Setup()
{
StaticDataInstance = &data;
LOG("Setting up static puzzle data");
for (int32_t i = 0; i < BX_COUNTOF(data.Cards); ++i)
{
data.Cards[i].ModelHandle = Game::GameRendering::Get().GetModelHandleFromPath("models/w straight.glb");
}
LoadStaticPuzzleData();
}
StaticPuzzleData& GetStaticPuzzleData()
{
assert(StaticDataInstance != nullptr);
return *StaticDataInstance;
return StaticData;
}
void LoadStaticPuzzleData()
{
Deserializer ser;
ser.Init("game/data/static/puzzle.dat");
if (ser.ReadT("SPUZ", StaticData))
{
LOG("Successfully loaded static puzzle data!");
}
ser.Finish();
}
void SaveStaticPuzzleData()
{
auto& data = GetStaticPuzzleData();
Serializer ser;
ser.Init("game/data/static/puzzle.dat");
if (ser.WriteT("SPUZ", GetStaticPuzzleData()))
{
LOG("Successfully saved static puzzle data!");
}
ser.Finish();
}
const StaticPuzzleCard& GetCard(const StaticPuzzleData& data, StaticPuzzleCardHandle H)
{
@@ -167,6 +184,18 @@ namespace Generated
namespace Generated
{
constexpr float UIPuzBoxSize = 26;
const char* GetShortNodeName(const PuzzleNode& node)
{
PuzzleElementType::Enum elemMax = PuzzleElementType::None;
for (int32_t i = 0; i < BX_COUNTOF(node.PlacedTypes); ++i)
{
if (node.PlacedTypes[i] > elemMax) elemMax = node.PlacedTypes[i];
}
return PuzzleElementType::ShortName[elemMax];
}
bool RenderDebugUI(PuzzleData& obj)
{
bool dataChanged = false;
@@ -197,6 +226,47 @@ namespace Generated
dataChanged = true;
}
ImGui::PopID();
ImVec2 puzCursorStart = ImGui::GetCursorScreenPos();
auto& drawList = *ImGui::GetWindowDrawList();
for (int32_t y = 0; y < obj.HeightTiles; ++y)
{
for (int32_t x = 0; x < obj.WidthTiles; ++x)
{
PuzzleNode& node = obj.PlacedNodes[Puzzle::Config::MaxPuzzleSizeTiles * y + x];
ImVec2 pos = ImVec2{puzCursorStart.x + x * UIPuzBoxSize + 5, puzCursorStart.y + y * UIPuzBoxSize};
ImGui::SetCursorScreenPos(pos);
ImGui::Text("%s", GetShortNodeName(node));
}
}
for (int32_t y = 0; y <= obj.HeightTiles; ++y)
{
ImVec2 linePos = {puzCursorStart.x, puzCursorStart.y + y * UIPuzBoxSize};
drawList.AddLine(linePos,
{linePos.x + obj.WidthTiles * UIPuzBoxSize, linePos.y},
y % Puzzle::Config::CardSize == 0 ? 0xFFFFFFFF : 0x11FFFFFF);
}
for (int32_t x = 0; x <= obj.WidthTiles; ++x)
{
ImVec2 linePos = {puzCursorStart.x + x * UIPuzBoxSize, puzCursorStart.y};
drawList.AddLine(linePos,
{linePos.x, linePos.y + obj.HeightTiles * UIPuzBoxSize},
x % Puzzle::Config::CardSize == 0 ? 0xFFFFFFFF : 0x11FFFFFF);
}
ImGui::Spacing();
ImGui::Spacing();
if (ImGui::TreeNodeEx("Available Cards", ImGuiTreeNodeFlags_DefaultOpen | ImGuiTreeNodeFlags_Framed))
{
for (int32_t i = 0; i < obj.AvailableCardCount; ++i)
{
ImGui::Text("Card");
}
ImGui::TreePop();
}
}
ImGui::End();

View File

@@ -18,112 +18,6 @@ namespace Puzzle
static constexpr uint32_t MaxAvailableStacks = 16;
static constexpr uint32_t MaxGoalPositions = 16;
};
// 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
@@ -131,8 +25,10 @@ namespace Generated
PuzPos operator+=(PuzPos lhs, const PuzPos& rhs);
PuzPos operator+(PuzPos lhs, const PuzPos& rhs);
void Setup(StaticPuzzleData& data);
void Setup();
StaticPuzzleData& GetStaticPuzzleData();
void LoadStaticPuzzleData();
void SaveStaticPuzzleData();
const StaticPuzzleCard& GetCard(const StaticPuzzleData& data, StaticPuzzleCardHandle H);
bool HasElement(const PuzzleNode& node, PuzzleElementType::Enum search);
bool IsEmpty(const PuzzleNode& node);

View File

@@ -48,6 +48,7 @@ namespace Game
instance.UsedScratchAmount = 0;
SetShared(shared);
SetInstance(instance);
Generated::LoadStaticPuzzleData();
SetupInstance.Rendering.Setup();
instance.GameLevel.Setup(shared.Game);
instance.IsInitialized = true;

39
src/game/Tools.cpp Normal file
View File

@@ -0,0 +1,39 @@
#include "Global.h"
#include "Instance.h"
#include "Tools.h"
#include "rendering/Rendering.h"
#include <imgui.h>
namespace Tools
{
const char* GetAssetPath(uint32_t assetHandle)
{
const auto& inst = Game::GetInstance();
for (int32_t j = 0; j < inst.DebugData.AssetCount; ++j)
{
if (inst.DebugData.AssetHandles[j] == assetHandle)
{
return inst.DebugData.AssetHandlePaths[j];
}
}
return "---";
}
void ModelDropdown(uint16_t& modelHandle)
{
auto& R = Game::GameRendering::Get();
const char* name = GetAssetPath(R.Models[modelHandle].AssetHandle);
if (ImGui::BeginCombo("Models", name))
{
for (int32_t i = 0; i < R.ModelCount; ++i)
{
if (ImGui::Selectable(GetAssetPath(R.Models[i].AssetHandle), i == modelHandle))
{
modelHandle = i;
}
}
ImGui::EndCombo();
}
}
} // namespace Tools

7
src/game/Tools.h Normal file
View File

@@ -0,0 +1,7 @@
#pragma once
#include <cstdint>
namespace Tools
{
void ModelDropdown(uint16_t& modelHandle);
} // namespace Tools

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -12,14 +12,14 @@ type ElemPos
enum PuzzleElementType(u8)
{
None GameName("Empty")
WaterIn GameName("Water Source")
WaterGoal GameName("Water Goal")
WaterChannel GameName("Water Channel")
ElectricIn GameName("Electricity Source")
ElectricGoal GameName("Electricity Goal")
Blocked GameName("Blocked")
Bridge GameName("Bridge")
None GameName("Empty") ShortName(" ")
WaterIn GameName("Water Source") ShortName("~+")
WaterGoal GameName("Water Goal") ShortName("~-")
WaterChannel GameName("Water Channel") ShortName("~")
ElectricIn GameName("Electricity Source") ShortName("e+")
ElectricGoal GameName("Electricity Goal") ShortName("e-")
Blocked GameName("Blocked") ShortName("B")
Bridge GameName("Bridge") ShortName("#")
}
type PuzzleNode

View File

@@ -3,6 +3,7 @@
#include "../Instance.h"
#include "../Log.h"
#include "../Mesh.h"
#include "../Tools.h"
#include "Rendering.h"
#include "SDL3/SDL_events.h"
@@ -515,6 +516,8 @@ namespace Game
for (int32_t i = 0; i < BX_COUNTOF(level.Puzzles); ++i)
{
auto& puzzleData = level.Puzzles[i].Data;
if (puzzleData.PuzzleName[0] == 0) continue;
bool isSelected = debug.SelectedDebugLevel == i;
ImGui::PushID("selectable");
if (ImGui::Selectable(puzzleData.PuzzleName, isSelected))
@@ -525,6 +528,7 @@ namespace Game
if (isSelected)
{
ImGui::PushID("edit field");
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
ImGui::InputText("", puzzleData.PuzzleName, sizeof(Generated::PuzzleData::PuzzleName));
ImGui::PopID();
@@ -536,6 +540,53 @@ namespace Game
}
}
ImGui::End();
if (ImGui::Begin("Cards"))
{
Generated::StaticPuzzleData& staticData = Generated::GetStaticPuzzleData();
if (ImGui::Button("Save"))
{
Generated::SaveStaticPuzzleData();
}
ImGui::SameLine();
if (ImGui::Button("Reload"))
{
Generated::LoadStaticPuzzleData();
}
for (int32_t i = 0; i < BX_COUNTOF(staticData.Cards); ++i)
{
ImGui::Separator();
Generated::StaticPuzzleCard& card = staticData.Cards[i];
ImGui::PushID(i);
ImGui::Text("%i", i);
Tools::ModelDropdown(card.ModelHandle);
for (int32_t y = 0; y < Puzzle::Config::CardSize; ++y)
{
ImGui::PushID(y);
for (int32_t x = 0; x < Puzzle::Config::CardSize; ++x)
{
if (x > 0) ImGui::SameLine();
ImGui::PushID(x);
auto& node = card.Nodes[y * Puzzle::Config::CardSize + x];
if (ImGui::Button(Generated::PuzzleElementType::ShortName[node.PlacedTypes[0]], {26, 24}))
{
int32_t newVal = int32_t(node.PlacedTypes[0]) + 1;
if (newVal >= Generated::PuzzleElementType::EntryCount)
{
newVal = 0;
}
node.PlacedTypes[0] = Generated::PuzzleElementType::Enum(newVal);
}
ImGui::PopID();
}
ImGui::PopID();
}
ImGui::PopID();
}
}
ImGui::End();
}
GetInstance().GameLevel.Update();

View File

@@ -96,7 +96,7 @@ namespace Game
UIVisibilityState UIVisible = UIVisibilityState::Game;
DitherData DitherTextures;
private:
public:
bgfx::UniformHandle DefaultSampler;
Texture Textures[8];
Material Materials[8];

View File

@@ -1,4 +1,7 @@
#pragma once
#include "../game/Log.h"
#include "bx/string.h"
#include <bx/file.h>
#include <cstdint>
@@ -19,18 +22,21 @@ namespace Generated
template <typename T> bool WriteT(const char* _4cc, const T& data)
{
Writer.write(_4cc, 4, &Err);
if (!Err.isOk()) return false;
if (!Write(_4cc, 4)) return false;
uint32_t hash = data.Hash;
Writer.write(&hash, sizeof(hash), &Err);
if (!Write(&hash, sizeof(hash))) return false;
uint32_t size = sizeof(T);
Writer.write(&size, sizeof(size), &Err);
return Err.isOk() && Save(&data, 1, *this);
if (!Write(&size, sizeof(size))) return false;
return Save(&data, 1, *this);
}
bool Write(const void* data, uint32_t size)
{
Writer.write(data, size, &Err);
if (!Err.isOk()) LOG_ERROR("Write error: %s", Err.getMessage().getCPtr());
return Err.isOk();
}
@@ -56,9 +62,47 @@ namespace Generated
bool Read(void* data, uint32_t size)
{
Reader.read(data, size, &Err);
if (!Err.isOk()) LOG_ERROR("Read error: %s", Err.getMessage().getCPtr());
return Err.isOk();
}
template <typename T> bool ReadT(const char* _4cc, T& data)
{
char magic[5]{0};
if (!Read(magic, 4)) return false;
bx::StringView given{_4cc, 4};
bx::StringView loaded{magic, 4};
if (bx::strCmp(given, loaded) != 0)
{
LOG_ERROR("Magic mismatch! %s != %s", _4cc, magic);
return false;
}
uint32_t hash = 0;
if (!Read(&hash, sizeof(hash))) return false;
if (data.Hash != hash)
{
LOG_ERROR("Hash mismatch! %u != %u", data.Hash, hash);
return false;
}
uint32_t size = 0;
if (!Read(&size, sizeof(size))) return false;
if (sizeof(T) != size)
{
LOG_ERROR("Size mismatch! %u != %u", sizeof(T), size);
return false;
}
if (!Load(&data, 1, *this))
{
LOG_ERROR("Failed to load: %s", Err.getMessage().getCPtr());
return false;
}
return true;
}
void Finish()
{
Reader.close();

View File

@@ -17,7 +17,7 @@ namespace Generated
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
auto val = (int32_t)obj[i];
int32_t& val = (int32_t&)obj[i];
isOk = Load(&val, 1, serializer) && isOk;
}
return isOk;
@@ -123,7 +123,6 @@ namespace Generated
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].CardCount, 1, serializer) && isOk;
isOk = Save(obj[i].Cards, 64, serializer) && isOk;
}
return isOk;
@@ -133,7 +132,6 @@ namespace Generated
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].CardCount, 1, serializer) && isOk;
isOk = Load(obj[i].Cards, 64, serializer) && isOk;
}
return isOk;

View File

@@ -48,7 +48,7 @@ namespace Generated
"~",
"e+",
"e-",
"",
"B",
"#",
};
};
@@ -82,8 +82,7 @@ namespace Generated
};
struct StaticPuzzleData
{
static constexpr uint32_t Hash = 2220151575;
uint16_t CardCount = {};
static constexpr uint32_t Hash = 1881743597;
StaticPuzzleCard Cards[64] = {};
};
struct PuzzleCardStack