diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce61a52..1d63755 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -28,7 +28,14 @@ set_property(TARGET PuzGameEngine PROPERTY CXX_STANDARD 17) target_include_directories(PuzGameEngine PUBLIC) # Game -file(GLOB_RECURSE sources_game game/*.cpp game/*.h gen/*.cpp gen/*.h) +add_custom_command( + COMMAND "${CMAKE_BINARY_DIR}/minidef.exe" "${CMAKE_SOURCE_DIR}/game/mini.def" "${CMAKE_SOURCE_DIR}/gen/" + DEPENDS "${CMAKE_SOURCE_DIR}/game/mini.def" + OUTPUT "${CMAKE_SOURCE_DIR}/gen/Generated.h" "${CMAKE_SOURCE_DIR}/gen/Generated.cpp" + COMMENT "Genrating from minidef" +) + +file(GLOB_RECURSE sources_game game/*.cpp game/*.h gen/Generated.cpp gen/Generated.h gen/Def.h gen/Def.cpp) 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}) set_property(TARGET PuzGame PROPERTY CXX_STANDARD 17) diff --git a/src/game/Puzzle.cpp b/src/game/Puzzle.cpp index 06e3e7d..b6b3164 100644 --- a/src/game/Puzzle.cpp +++ b/src/game/Puzzle.cpp @@ -60,24 +60,6 @@ namespace Generated return data.Cards[H.Idx]; } - bool HasElement(const PuzzleNode& node, PuzzleElementType::Enum search) - { - for (int32_t i = 0; i < Puzzle::Config::MaxElementsPerTile; ++i) - { - if (node.PlacedTypes[i] == search) return true; - } - return false; - } - - bool IsEmpty(const PuzzleNode& node) - { - for (int32_t i = 0; i < Puzzle::Config::MaxElementsPerTile; ++i) - { - if (node.PlacedTypes[i] != PuzzleElementType::None) return false; - } - return true; - } - bool IsValid(StaticPuzzleCardHandle h) { return h.Idx != UINT16_MAX; @@ -89,18 +71,43 @@ namespace Generated return stack.MaxAvailableCount - stack.UsedCount; } - const PuzzleNode& GetNodeAt(const PuzzleData& puz, PuzPos pos) + PuzzleElementType::Enum GetNodeAt(const PuzzleData& puz, PuzPos pos) { assert(pos.X < Puzzle::Config::MaxPuzzleSizeCards && pos.Y < Puzzle::Config::MaxPuzzleSizeCards && pos.X >= 0 && pos.Y >= 0); - return puz.PlacedNodes[pos.Y * Puzzle::Config::MaxPuzzleSizeCards + pos.X]; + // TODO: this is horrible + for (int32_t i = 0; i < puz.PlacedCardCount; ++i) + { + auto& card = puz.PlacedCards[i]; + int8_t offsetX = pos.X - card.Position.X; + int8_t offsetY = pos.Y - card.Position.Y; + if (offsetX >= 0 && offsetX < Puzzle::Config::CardSize && offsetY >= 0 && + offsetY < Puzzle::Config::CardSize) + { + PuzzleElementType::Enum cardVal = + GetCardNodeAt(GetCard(GetStaticPuzzleData(), card.RefCard), offsetX, offsetY); + if (cardVal != PuzzleElementType::None) return cardVal; + } + } + return puz.BackgroundTiles[pos.Y * Puzzle::Config::MaxPuzzleSizeCards + pos.X]; } - PuzzleElementType::Enum GetElementAt(const PuzzleData& puz, ElemPos pos) + PuzzleElementType::Enum GetCardNodeAt(const StaticPuzzleCard& card, int8_t x, int8_t y) { - assert(pos.ElemIdx < Puzzle::Config::MaxElementsPerTile); - const PuzzleNode& node = GetNodeAt(puz, pos.Position); - return node.PlacedTypes[pos.ElemIdx]; + assert(x >= 0 && x < Puzzle::Config::CardSize); + assert(y >= 0 && y < Puzzle::Config::CardSize); + + // TODO: account for card rotation + return card.Elements[y * Puzzle::Config::CardSize + x]; + } + + PuzzleElementType::Enum& EditCardNodeAt(StaticPuzzleCard& card, int8_t x, int8_t y) + { + assert(x >= 0 && x < Puzzle::Config::CardSize); + assert(y >= 0 && y < Puzzle::Config::CardSize); + + // TODO: account for card rotation + return card.Elements[y * Puzzle::Config::CardSize + x]; } bool PuzzleSolver::IsPuzzleSolved(const PuzzleData& puzzle) @@ -117,16 +124,15 @@ namespace Generated return IsSolved; } - bool PuzzleSolver::IsExitSatisfied(const PuzzleData& puzzle, ElemPos pos) + bool PuzzleSolver::IsExitSatisfied(const PuzzleData& puzzle, PuzPos pos) { - const PuzzleNode& goalNode = GetNodeAt(puzzle, pos.Position); - PuzzleElementType::Enum goalType = GetElementAt(puzzle, pos); + PuzzleElementType::Enum goalType = GetNodeAt(puzzle, pos); uint32_t currentPositionQueueIdx = 0; uint32_t positionQueueCount = 0; PuzPos positionQueue[Puzzle::Config::MaxTilesInPuzzle]; - positionQueue[0] = pos.Position; + positionQueue[0] = pos; positionQueueCount++; while (positionQueueCount > 0) { @@ -137,13 +143,9 @@ namespace Generated PuzPos nextPos = currentPos + dir; if (IsValidGoalConnection(puzzle, nextPos, currentPos, goalType)) { - const PuzzleNode& node = GetNodeAt(puzzle, nextPos); - for (PuzzleElementType::Enum e : node.PlacedTypes) + if (IsValidSource(GetNodeAt(puzzle, nextPos), goalType)) { - if (IsValidSource(e, goalType)) - { - return true; - } + return true; } positionQueue[positionQueueCount] = nextPos; positionQueueCount++; @@ -159,18 +161,18 @@ namespace Generated PuzPos flowTo, PuzzleElementType::Enum goalType) { - const PuzzleNode& from = GetNodeAt(puzzle, flowFrom); - const PuzzleNode& to = GetNodeAt(puzzle, flowTo); + auto from = GetNodeAt(puzzle, flowFrom); + auto to = GetNodeAt(puzzle, flowTo); if (goalType == PuzzleElementType::WaterGoal) { - return HasElement(from, PuzzleElementType::WaterIn) || HasElement(from, PuzzleElementType::WaterChannel) || - HasElement(from, PuzzleElementType::WaterGoal); + return from == PuzzleElementType::WaterIn || from == PuzzleElementType::WaterChannel || + from == PuzzleElementType::WaterGoal; } else if (goalType == PuzzleElementType::ElectricGoal) { - return HasElement(from, PuzzleElementType::ElectricIn) || - HasElement(from, PuzzleElementType::ElectricGoal) || IsEmpty(from); + return from == PuzzleElementType::ElectricIn || from == PuzzleElementType::ElectricGoal || + from == PuzzleElementType::None; } assert(false); return false; @@ -192,14 +194,9 @@ namespace Generated bx::snprintf(buf, bufSize, "%s/%u.pzl", Puzzle::PuzzleFileDir, puzID); } - const char* GetShortNodeName(const PuzzleNode& node) + const char* GetShortNodeName(const PuzzleElementType::Enum 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]; + return PuzzleElementType::ShortName[node]; } bool RenderDebugUI(PuzzleData& obj) @@ -257,7 +254,7 @@ namespace Generated for (int32_t x = 0; x < obj.WidthTiles; ++x) { ImGui::PushID(x); - PuzzleNode& node = obj.PlacedNodes[Puzzle::Config::MaxPuzzleSizeTiles * y + x]; + auto node = GetNodeAt(obj, {int8_t(x), int8_t(y)}); ImVec2 pos = ImVec2{puzCursorStart.x + x * UIPuzBoxSize + 5, puzCursorStart.y + y * UIPuzBoxSize}; ImGui::SetCursorScreenPos(pos); ImGui::Text("%s", GetShortNodeName(node)); diff --git a/src/game/Puzzle.h b/src/game/Puzzle.h index cc18dcf..cb9fac7 100644 --- a/src/game/Puzzle.h +++ b/src/game/Puzzle.h @@ -31,17 +31,16 @@ namespace Generated 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); bool IsValid(StaticPuzzleCardHandle h); uint8_t GetRemainingCount(const PuzzleCardStack& stack); - const PuzzleNode& GetNodeAt(const PuzzleData& puz, PuzPos pos); - PuzzleElementType::Enum GetElementAt(const PuzzleData& puz, ElemPos pos); + PuzzleElementType::Enum GetNodeAt(const PuzzleData& puz, PuzPos pos); + PuzzleElementType::Enum GetCardNodeAt(const StaticPuzzleCard& card, int8_t x, int8_t y); + PuzzleElementType::Enum& EditCardNodeAt(StaticPuzzleCard& card, int8_t x, int8_t y); struct PuzzleSolver { bool IsPuzzleSolved(const Generated::PuzzleData& puzzle); - bool IsExitSatisfied(const Generated::PuzzleData& puzzle, ElemPos pos); + bool IsExitSatisfied(const Generated::PuzzleData& puzzle, PuzPos pos); // This assumes flowFrom is already verified to be connected. bool IsValidGoalConnection(const Generated::PuzzleData& puzzle, diff --git a/src/game/data/puzzles/0.pzl b/src/game/data/puzzles/0.pzl index 03dc239..289083a 100644 --- a/src/game/data/puzzles/0.pzl +++ b/src/game/data/puzzles/0.pzl @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:46b544848f139d2a7f3dd20643596e338f0aaab45394c96ba67e8f058915c8d9 -size 18124 +oid sha256:017e1fab623e2bce8a32933f1945242335279d895b43204802630fa47e653386 +size 5820 diff --git a/src/game/data/static/puzzle.dat b/src/game/data/static/puzzle.dat index 3a28f6b..d555fea 100644 Binary files a/src/game/data/static/puzzle.dat and b/src/game/data/static/puzzle.dat differ diff --git a/src/game/mini.def b/src/game/mini.def index f0a9e52..90c7032 100644 --- a/src/game/mini.def +++ b/src/game/mini.def @@ -44,12 +44,6 @@ type PuzPos i8 Y } -type ElemPos -{ - PuzPos Position - u8 ElemIdx -} - enum PuzzleElementType(u8) { None GameName("Empty") ShortName(" ") @@ -62,15 +56,10 @@ enum PuzzleElementType(u8) Bridge GameName("Bridge") ShortName("#") } -type PuzzleNode -{ - PuzzleElementType PlacedTypes Arr(4) -} - type StaticPuzzleCard { - PuzzleNode Nodes Arr(4) - u16 ModelHandle + PuzzleElementType Elements Arr(4) + u16 ModelHandle } type StaticPuzzleCardHandle @@ -108,7 +97,7 @@ type PuzzleData PuzzleCardStack AvailableCards Arr(16) u32 PlacedCardCount PlacedPuzzleCard PlacedCards Arr(256) - PuzzleNode PlacedNodes Arr(1024) + PuzzleElementType BackgroundTiles Arr(1024) u32 GoalPositionCount - ElemPos GoalPositions Arr(16) + PuzPos GoalPositions Arr(16) } diff --git a/src/game/rendering/Rendering.cpp b/src/game/rendering/Rendering.cpp index 0bd6b8d..5c1c140 100644 --- a/src/game/rendering/Rendering.cpp +++ b/src/game/rendering/Rendering.cpp @@ -603,22 +603,22 @@ namespace Game } Tools::ModelDropdown(card.ModelHandle); - for (int32_t y = 0; y < Puzzle::Config::CardSize; ++y) + for (int8_t y = 0; y < Puzzle::Config::CardSize; ++y) { ImGui::PushID(y); - for (int32_t x = 0; x < Puzzle::Config::CardSize; ++x) + for (int8_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})) + auto& node = Generated::EditCardNodeAt(card, x, y); + if (ImGui::Button(Generated::PuzzleElementType::ShortName[node], {26, 24})) { - int32_t newVal = int32_t(node.PlacedTypes[0]) + 1; + int32_t newVal = int32_t(node) + 1; if (newVal >= Generated::PuzzleElementType::EntryCount) { newVal = 0; } - node.PlacedTypes[0] = Generated::PuzzleElementType::Enum(newVal); + node = Generated::PuzzleElementType::Enum(newVal); } ImGui::PopID(); } diff --git a/src/gen/Generated.cpp b/src/gen/Generated.cpp index 2feba1b..085952a 100644 --- a/src/gen/Generated.cpp +++ b/src/gen/Generated.cpp @@ -144,50 +144,12 @@ namespace Generated } 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].Elements, 4, serializer) && isOk; isOk = Save(&obj[i].ModelHandle, 1, serializer) && isOk; } return isOk; @@ -197,7 +159,7 @@ namespace Generated bool isOk = true; for (uint32_t i = 0; i < count; ++i) { - isOk = Load(obj[i].Nodes, 4, serializer) && isOk; + isOk = Load(obj[i].Elements, 4, serializer) && isOk; isOk = Load(&obj[i].ModelHandle, 1, serializer) && isOk; } return isOk; @@ -290,16 +252,16 @@ namespace Generated for (uint32_t i = 0; i < count; ++i) { isOk = Save(&obj[i].ID, 1, serializer) && isOk; + isOk = Save(obj[i].PuzzleName, 64, serializer) && isOk; 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].BackgroundTiles, 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; } @@ -309,16 +271,16 @@ namespace Generated for (uint32_t i = 0; i < count; ++i) { isOk = Load(&obj[i].ID, 1, serializer) && isOk; + isOk = Load(obj[i].PuzzleName, 64, serializer) && isOk; 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].BackgroundTiles, 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; } diff --git a/src/gen/Generated.h b/src/gen/Generated.h index 2994819..099dcc8 100644 --- a/src/gen/Generated.h +++ b/src/gen/Generated.h @@ -98,21 +98,10 @@ namespace Generated int8_t X = {}; int8_t Y = {}; }; - struct ElemPos - { - static constexpr uint32_t Hash = 3966109730; - PuzPos Position = {}; - uint8_t ElemIdx = {}; - }; - struct PuzzleNode - { - static constexpr uint32_t Hash = 1417779061; - PuzzleElementType::Enum PlacedTypes[4] = {}; - }; struct StaticPuzzleCard { - static constexpr uint32_t Hash = 110653106; - PuzzleNode Nodes[4] = {}; + static constexpr uint32_t Hash = 2507139249; + PuzzleElementType::Enum Elements[4] = {}; uint16_t ModelHandle = {}; }; struct StaticPuzzleCardHandle @@ -122,7 +111,7 @@ namespace Generated }; struct StaticPuzzleData { - static constexpr uint32_t Hash = 1881743597; + static constexpr uint32_t Hash = 3210954810; StaticPuzzleCard Cards[64] = {}; }; struct PuzzleCardStack @@ -142,18 +131,18 @@ namespace Generated }; struct PuzzleData { - static constexpr uint32_t Hash = 255994202; + static constexpr uint32_t Hash = 2775382112; uint16_t ID = {}; + char PuzzleName[64] = {}; uint8_t WidthTiles = {}; uint8_t HeightTiles = {}; uint32_t AvailableCardCount = {}; PuzzleCardStack AvailableCards[16] = {}; uint32_t PlacedCardCount = {}; PlacedPuzzleCard PlacedCards[256] = {}; - PuzzleNode PlacedNodes[1024] = {}; + PuzzleElementType::Enum BackgroundTiles[1024] = {}; uint32_t GoalPositionCount = {}; - ElemPos GoalPositions[16] = {}; - char PuzzleName[64] = {}; + PuzPos GoalPositions[16] = {}; }; bool Save(const PuzzleElementType::Enum* obj, uint32_t count, Serializer& serializer); bool Load(PuzzleElementType::Enum* obj, uint32_t count, Deserializer& serializer); @@ -169,10 +158,6 @@ namespace Generated bool Load(Mat4* 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);