diff --git a/src/game/Entity.h b/src/game/Entity.h index 7df44b3..f3b770d 100644 --- a/src/game/Entity.h +++ b/src/game/Entity.h @@ -6,7 +6,7 @@ #include "bgfx/bgfx.h" #include "rendering/Rendering.h" #include -#include +#include #define ENTITY_HANDLE(X) \ struct X \ diff --git a/src/game/Instance.h b/src/game/Instance.h index 6e775c9..955999b 100644 --- a/src/game/Instance.h +++ b/src/game/Instance.h @@ -63,7 +63,6 @@ namespace Game uint8_t DebugCardRotation = 0; bool ShortenLogFileNames = true; bool ShowStats = true; - bool ShowArenaUsage = false; }; struct GameInstance diff --git a/src/game/Level.cpp b/src/game/Level.cpp index 59bfb6e..23dd6ef 100644 --- a/src/game/Level.cpp +++ b/src/game/Level.cpp @@ -29,7 +29,12 @@ namespace Game { void EntityRenderData::Render(const Model* models, const Material* materials, const Texture* textures) { - if (DebugBreakOnRender) bx::debugBreak(); + if (DebugBreakOnRender) + { + bx::debugBreak(); + DebugBreakOnRender = false; + } + if (models == nullptr || materials == nullptr || textures == nullptr) return; if (!Gen::IsValid(ModelH) || MaterialHandle >= EMaterial::EntryCount) return; if (!Visible) return; @@ -201,7 +206,9 @@ namespace Game } PuzzleUI.Setup(); - TabletHandle = UIQuads.New(); + + ReloadLevelEntities(); + UpdatePlayerInputMode(); } @@ -272,18 +279,6 @@ namespace Game UpdatePlayerInputMode(); } - // UI Tablet - if (IsValid(TabletHandle)) - { - auto& tablet = UIQuads.Get(TabletHandle); - tablet.EData.LoadFromSaved(player.Config.TabletBackgroundRenderData); - UpdateMatrix(player.PlayerCamTransform); - tablet.EData.Transform.Rotation = player.PlayerCamTransform.Rotation; - Rotate(tablet.EData.Transform, {0.5f * bx::kPi, 0.0f, 0.0f}); - tablet.EData.Transform.Position = - player.PlayerCamTransform.Position + AxisForward(player.PlayerCamTransform.M) * 1.0f; - } - // Cubes for (uint16_t i = 0; i < Cubes.Count; ++i) { @@ -342,6 +337,7 @@ namespace Game { UIQuads.Render(models, materials, textures); } + LevelEntities.Render(models, materials, textures); } void Cube::Setup() @@ -440,4 +436,16 @@ namespace Game } } } + + void Level::ReloadLevelEntities() + { + LevelEntities.Count = 0; + for (int32_t i = 0; i < BX_COUNTOF(BackgroundEntityHandles); ++i) + { + BackgroundEntityHandles[i] = LevelEntities.New(); + auto& levelBgEntity = LevelEntities.Get(BackgroundEntityHandles[i]); + levelBgEntity.EData.LoadFromSaved(GetInstance().Player.Config.BackgroundLevelRenderData[i]); + } + } + } // namespace Game diff --git a/src/game/Level.h b/src/game/Level.h index 4399769..3bf6803 100644 --- a/src/game/Level.h +++ b/src/game/Level.h @@ -1,9 +1,11 @@ #pragma once #include "../engine/Shared.h" +#include "Entity.h" #include "Puzzle.h" #include "UI.h" #include "rendering/Rendering.h" + #include #include namespace Game @@ -35,7 +37,7 @@ namespace Game EntityManager LevelEntities; CubeHandle PlayerOutsideViewCube; - UIQuadEntityHandle TabletHandle; + LevelEntityHandle BackgroundEntityHandles[16]; public: Gen::StaticPuzzleData PuzzleData; @@ -46,5 +48,6 @@ namespace Game void Setup(GameData& data); void Update(); void Render(uint16_t ViewID, const Model* models, const Material* materials, const Texture* textures); + void ReloadLevelEntities(); }; } // namespace Game diff --git a/src/game/Tools.cpp b/src/game/Tools.cpp index 2711990..3f725f7 100644 --- a/src/game/Tools.cpp +++ b/src/game/Tools.cpp @@ -182,329 +182,355 @@ namespace Tools return changed; } - void RenderDebugUI(Game::GameRendering& rendering) + void RenderLogUI() { - if (!rendering.SetupData.UseImgui) return; + auto& time = Game::GetInstance().Time; + auto& debug = Game::GetInstance().DebugData; + if (ImGui::Begin("Log")) + { + ImGui::Checkbox("Shorten File Names", &debug.ShortenLogFileNames); + ImGui::BeginTable("tbl", + 4, + ImGuiTableFlags_Resizable | ImGuiTableFlags_Hideable | ImGuiTableFlags_SizingFixedFit | + ImGuiTableFlags_RowBg); + ImGui::TableSetupColumn("Time", ImGuiTableColumnFlags_NoResize); + ImGui::TableSetupColumn("Log"); + ImGui::TableSetupColumn("Line", ImGuiTableColumnFlags_NoResize); + ImGui::TableSetupColumn("File", ImGuiTableColumnFlags_NoResize); + ImGui::TableHeadersRow(); + + auto& logs = GetLogHistory(); + + int32_t lineCount = bx::min(100, LogInternal::LogHistorySize); + for (int32_t i = 0; i < lineCount; ++i) + { + int32_t idx = logs.WriteIdx - i - 1; + if (idx < 0) idx += LogInternal::LogHistorySize; + const char* line = &logs.LogBuffer[idx * LogInternal::MaxLineSize]; + if (line[0] != 0) + { + int64_t timeOffset = logs.WriteTime[idx] - time.StartTime; + double writeTime = (double)timeOffset / bx::getHPFrequency(); + uint32_t fileLine = logs.LineBuffer[idx]; + const char* filePath = &logs.FileBuffer[idx * LogInternal::MaxLineSize]; + const char* filePathRes = + debug.ShortenLogFileNames ? bx::FilePath{filePath}.getFileName().getPtr() : filePath; + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::Text("%.01f", writeTime); + + ImGui::TableNextColumn(); + ImGui::Text("%s", line); + ImGui::SetItemTooltip("%f\n%s%s:%u", writeTime, line, filePath, fileLine); + + ImGui::TableNextColumn(); + ImGui::Text("%u", fileLine); + + ImGui::TableNextColumn(); + ImGui::Text("%s", filePathRes); + + if (i > 0) ImGui::PopStyleColor(2); + ImVec4 bgCol = {0.0f, 0.0f, 0.0f, 1.0f}; + if (logs.WriteType[idx] == ELogType::Warn) + bgCol = {0.2f, 0.2f, 0.0f, 1.0f}; + else if (logs.WriteType[idx] == ELogType::Error) + bgCol = {0.2f, 0.0f, 0.0f, 1.0f}; + ImGui::PushStyleColor(ImGuiCol_TableRowBg, bgCol); + ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, bgCol); + } + } + + ImGui::EndTable(); + + if (lineCount > 0) ImGui::PopStyleColor(2); + } + ImGui::End(); + } + + void RenderRenderSettingsUI(Game::GameRendering& rendering) + { auto& time = Game::GetInstance().Time; auto& shared = Game::GetShared(); auto& debug = Game::GetInstance().DebugData; auto& level = Game::GetInstance().GameLevel; auto& player = Game::GetInstance().Player; - if (rendering.UIVisible == Game::UIVisibilityState::Debug) + if (ImGui::Begin("Rendering")) { - ZoneScopedN("DebugUI"); - if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)) + if (rendering.LastShaderLoadTime >= 0.0f) { - debug.DebugCardRotation++; - if (debug.DebugCardRotation >= 4) debug.DebugCardRotation = 0; + ImGui::TextColored({0.2f, 0.9f, 0.2f, 1.0f}, + "Shader loaded %.0f seconds ago", + time.Now - rendering.LastShaderLoadTime); } - if (ImGui::Begin("Log")) + else { - ImGui::Checkbox("Shorten File Names", &debug.ShortenLogFileNames); - ImGui::BeginTable("tbl", - 4, - ImGuiTableFlags_Resizable | ImGuiTableFlags_Hideable | - ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg); - ImGui::TableSetupColumn("Time", ImGuiTableColumnFlags_NoResize); - ImGui::TableSetupColumn("Log"); - ImGui::TableSetupColumn("Line", ImGuiTableColumnFlags_NoResize); - ImGui::TableSetupColumn("File", ImGuiTableColumnFlags_NoResize); - ImGui::TableHeadersRow(); - - auto& logs = GetLogHistory(); - - int32_t lineCount = bx::min(100, LogInternal::LogHistorySize); - for (int32_t i = 0; i < lineCount; ++i) - { - int32_t idx = logs.WriteIdx - i - 1; - if (idx < 0) idx += LogInternal::LogHistorySize; - const char* line = &logs.LogBuffer[idx * LogInternal::MaxLineSize]; - if (line[0] != 0) - { - int64_t timeOffset = logs.WriteTime[idx] - time.StartTime; - double writeTime = (double)timeOffset / bx::getHPFrequency(); - uint32_t fileLine = logs.LineBuffer[idx]; - const char* filePath = &logs.FileBuffer[idx * LogInternal::MaxLineSize]; - const char* filePathRes = - debug.ShortenLogFileNames ? bx::FilePath{filePath}.getFileName().getPtr() : filePath; - - ImGui::TableNextRow(); - ImGui::TableNextColumn(); - ImGui::Text("%.01f", writeTime); - - ImGui::TableNextColumn(); - ImGui::Text("%s", line); - ImGui::SetItemTooltip("%f\n%s%s:%u", writeTime, line, filePath, fileLine); - - ImGui::TableNextColumn(); - ImGui::Text("%u", fileLine); - - ImGui::TableNextColumn(); - ImGui::Text("%s", filePathRes); - - if (i > 0) ImGui::PopStyleColor(2); - ImVec4 bgCol = {0.0f, 0.0f, 0.0f, 1.0f}; - if (logs.WriteType[idx] == ELogType::Warn) - bgCol = {0.2f, 0.2f, 0.0f, 1.0f}; - else if (logs.WriteType[idx] == ELogType::Error) - bgCol = {0.2f, 0.0f, 0.0f, 1.0f}; - ImGui::PushStyleColor(ImGuiCol_TableRowBg, bgCol); - ImGui::PushStyleColor(ImGuiCol_TableRowBgAlt, bgCol); - } - } - - ImGui::EndTable(); - - if (lineCount > 0) ImGui::PopStyleColor(2); + ImGui::TextColored({0.9f, 0.2f, 0.2f, 1.0f}, "Shader load Failiure!"); } - ImGui::End(); - if (ImGui::Begin("Rendering")) + if (ImGui::Button("Reload Meshes")) { - if (rendering.LastShaderLoadTime >= 0.0f) - { - ImGui::TextColored({0.2f, 0.9f, 0.2f, 1.0f}, - "Shader loaded %.0f seconds ago", - time.Now - rendering.LastShaderLoadTime); - } - else - { - ImGui::TextColored({0.9f, 0.2f, 0.2f, 1.0f}, "Shader load Failiure!"); - } - if (ImGui::Button("Reload Meshes")) - { - LoadModels(rendering.Models, rendering.ModelCount); - } - ImGui::SameLine(); - if (ImGui::Button("Reload Level")) - { - level = {}; - level.Setup(shared.Game); - } + LoadModels(rendering.Models, rendering.ModelCount); + } + ImGui::SameLine(); + if (ImGui::Button("Reload Level")) + { + level = {}; + level.Setup(shared.Game); + } - ImGui::SliderFloat("Mouse Sensitivity", &player.MouseSensitivity, 0.1f, 5.0f); - ImGui::SliderFloat("Player Speed", &player.MovementSpeed, 1.0f, 30.0f); + ImGui::SliderFloat("Mouse Sensitivity", &player.MouseSensitivity, 0.1f, 5.0f); + ImGui::SliderFloat("Player Speed", &player.MovementSpeed, 1.0f, 30.0f); - ImGui::Checkbox("Show ImGui Demo", &debug.ShowImguiDemo); - ImGui::Checkbox("Show Stats", &debug.ShowStats); - if (debug.ShowImguiDemo) ImGui::ShowDemoWindow(&debug.ShowImguiDemo); + ImGui::Checkbox("Show ImGui Demo", &debug.ShowImguiDemo); + ImGui::Checkbox("Show Stats", &debug.ShowStats); + if (debug.ShowImguiDemo) ImGui::ShowDemoWindow(&debug.ShowImguiDemo); + ImGui::Separator(); + + ImGui::Text("Entity Groups"); + ImGui::Checkbox("Cubes", &level.Cubes.IsEnabled); + ImGui::Checkbox("Tests", &level.Tests.IsEnabled); + ImGui::Checkbox("PuzzleTiles", &level.PuzzleTiles.IsEnabled); + ImGui::Checkbox("UIQuads", &level.UIQuads.IsEnabled); + ImGui::Checkbox("Level", &level.LevelEntities.IsEnabled); + + ImGui::Separator(); + + bool uiconfigChanged = false; + if (ImGui::TreeNodeEx("Game Tablet")) + { + uiconfigChanged |= Tools::EntityDataSettings(player.Config.TabletBackgroundRenderData); ImGui::Separator(); - - ImGui::Text("Entity Groups"); - ImGui::Checkbox("Cubes", &level.Cubes.IsEnabled); - ImGui::Checkbox("Tests", &level.Tests.IsEnabled); - ImGui::Checkbox("PuzzleTiles", &level.PuzzleTiles.IsEnabled); - ImGui::Checkbox("UIQuads", &level.UIQuads.IsEnabled); - - ImGui::Separator(); - - ImGui::Text("Game Tablet"); - bool bTabletChanged = false; - bTabletChanged |= Tools::EntityDataSettings(player.Config.TabletBackgroundRenderData); ImGui::Text("Status"); - bTabletChanged |= Tools::EntityDataSettings(player.Config.TabletStatusRenderData); - bTabletChanged |= Tools::TextureDropdown(player.Config.TabletStatusSolvedTexture, "Solved Texture"); - bTabletChanged |= + uiconfigChanged |= Tools::EntityDataSettings(player.Config.TabletStatusRenderData); + uiconfigChanged |= Tools::TextureDropdown(player.Config.TabletStatusSolvedTexture, "Solved Texture"); + uiconfigChanged |= Tools::TextureDropdown(player.Config.TabletStatusNotSolvedTexture, "Not Solved Texture"); + ImGui::Separator(); ImGui::Text("Reset"); - bTabletChanged |= Tools::EntityDataSettings(player.Config.TabletResetRenderData); - if (bTabletChanged) - { - Serializer s; - s.Init("game/data/static/uiconfig.dat", "UICO"); - s.WriteT(player.Config); - s.Finish(); - level.PuzzleUI.Reset(); - } + uiconfigChanged |= Tools::EntityDataSettings(player.Config.TabletResetRenderData); + ImGui::TreePop(); + } + if (ImGui::TreeNodeEx("Background Level")) + { + for (int32_t i = 0; i < BX_COUNTOF(player.Config.BackgroundLevelRenderData); ++i) + { + if (i > 0) ImGui::Separator(); + uiconfigChanged |= Tools::EntityDataSettings(player.Config.BackgroundLevelRenderData[i]); + } + ImGui::TreePop(); + } + + if (uiconfigChanged) + { + Serializer s; + s.Init("game/data/static/uiconfig.dat", "UICO"); + s.WriteT(player.Config); + s.Finish(); + level.PuzzleUI.Reset(); + level.ReloadLevelEntities(); + } + + ImGui::Separator(); + + if (ImGui::Button("Dithergen")) + { + DitherGen(rendering.DitherTextures, rendering.DitherRecursion); + } + ImGui::SameLine(); + ImGui::SliderInt("Recursion", &rendering.DitherRecursion, 1, 4); + ImGui::Text("%ux%ux%u", + rendering.DitherTextures.DitherTexWH, + rendering.DitherTextures.DitherTexWH, + rendering.DitherTextures.DitherTexDepth); + if (!isValid(rendering.DitherTextures.PreviewTex)) + { + ImGui::Text("Invalid Texture"); + } + else + { + ImGui::Image(rendering.DitherTextures.PreviewTex.idx, + {(float)rendering.DitherTextures.DitherTexWH, + (float)rendering.DitherTextures.DitherTexWH * rendering.DitherTextures.DitherTexDepth}); + } + if (isValid(rendering.DitherTextures.RampTex)) + { + ImGui::Image(rendering.DitherTextures.RampTex.idx, + {BX_COUNTOF(rendering.DitherTextures.BrightnessRamp), 8}); + } + Vec3 quadPos = level.UIQuads.Get({0}).EData.Transform.Position; + ImGui::Text("%f %f %f", quadPos.x, quadPos.y, quadPos.z); + + ImGui::Text("Shader log:"); + ImGui::TextWrapped("%s", Game::GetShared().Dev.ShaderLog); + } + ImGui::End(); + } + + void RenderTexturesUI(Game::GameRendering& rendering) + { + if (ImGui::Begin("Textures")) + { + if (ImGui::Button("Reload")) + { + rendering.LoadTextures(); + } + for (int32_t i = 0; i < rendering.MaxTextures; ++i) + { + if (!isValid(rendering.Textures[i].RenderHandle)) continue; + ImGui::Text("%i", i); + float width = bx::min(ImGui::GetContentRegionAvail().x, rendering.Textures[i].Info.width); + float height = bx::min(ImGui::GetContentRegionAvail().x, rendering.Textures[i].Info.height); + ImGui::Image(rendering.Textures[i].RenderHandle.idx, {width, height}); + } + } + ImGui::End(); + } + + void RenderPuzzlesUI() + { + auto& debug = Game::GetInstance().DebugData; + auto& level = Game::GetInstance().GameLevel; + + if (ImGui::Begin("Puzzles")) + { + char nameBuf[64]{0}; + 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"); + bx::snprintf(nameBuf, sizeof(nameBuf), "%u: %s", i, puzzleData.PuzzleName); + if (ImGui::Selectable(nameBuf, isSelected)) + { + debug.SelectedDebugLevel = isSelected ? UINT16_MAX : i; + } + ImGui::PopID(); + } + } + ImGui::End(); + + if (debug.SelectedDebugLevel < BX_COUNTOF(level.Puzzles)) + { + if (!Puzzle::RenderDebugUI(level.Puzzles[debug.SelectedDebugLevel].Data)) + { + debug.SelectedDebugLevel = UINT16_MAX; + } + } + } + + void RenderCardsUI(Game::GameRendering& rendering) + { + auto& debug = Game::GetInstance().DebugData; + + if (ImGui::Begin("Cards")) + { + Gen::StaticPuzzleData& staticData = Puzzle::GetStaticPuzzleData(); + + if (ImGui::Button("Save")) + { + Puzzle::SaveStaticPuzzleData(); + } + ImGui::SameLine(); + if (ImGui::Button("Reload")) + { + Puzzle::LoadStaticPuzzleData(); + } + + ImGui::Separator(); + + ImGui::ColorEdit3("Disabled Tint", &staticData.Visuals.DisabledCardTint.x); + ImGui::ColorEdit3("Tile Base Color", &staticData.Visuals.TileBaseColor.x); + ImGui::ColorEdit3("Tile Dot Color", &staticData.Visuals.TileDotColor.x); + + for (int32_t i = 0; i < BX_COUNTOF(staticData.Cards); ++i) + { ImGui::Separator(); - if (ImGui::Button("Dithergen")) + Gen::StaticPuzzleCard& card = staticData.Cards[i]; + ImGui::PushID(i); + char cardName[64]{0}; + bx::snprintf(cardName, sizeof(cardName), "%i", i); + ImGui::Selectable(cardName); + if (ImGui::BeginDragDropSource()) { - DitherGen(rendering.DitherTextures, rendering.DitherRecursion); + Puzzle::DrawCard(card, debug.DebugCardRotation, ImGui::GetCursorScreenPos()); + ImGui::SetDragDropPayload("cardtype", &i, sizeof(i)); + ImGui::EndDragDropSource(); } - ImGui::SameLine(); - ImGui::SliderInt("Recursion", &rendering.DitherRecursion, 1, 4); - ImGui::Text("%ux%ux%u", - rendering.DitherTextures.DitherTexWH, - rendering.DitherTextures.DitherTexWH, - rendering.DitherTextures.DitherTexDepth); - if (!isValid(rendering.DitherTextures.PreviewTex)) - { - ImGui::Text("Invalid Texture"); - } - else - { - ImGui::Image( - rendering.DitherTextures.PreviewTex.idx, - {(float)rendering.DitherTextures.DitherTexWH, - (float)rendering.DitherTextures.DitherTexWH * rendering.DitherTextures.DitherTexDepth}); - } - if (isValid(rendering.DitherTextures.RampTex)) - { - ImGui::Image(rendering.DitherTextures.RampTex.idx, - {BX_COUNTOF(rendering.DitherTextures.BrightnessRamp), 8}); - } - Vec3 quadPos = level.UIQuads.Get({0}).EData.Transform.Position; - ImGui::Text("%f %f %f", quadPos.x, quadPos.y, quadPos.z); - ImGui::Text("Shader log:"); - ImGui::TextWrapped("%s", Game::GetShared().Dev.ShaderLog); - } - ImGui::End(); - if (ImGui::Begin("Textures")) - { - if (ImGui::Button("Reload")) + Tools::ModelDropdown(card.BaseModelHandle); + Tools::TextureDropdown(card.BoardTextureHandle); + if (IsValid(card.BaseModelHandle)) { - rendering.LoadTextures(); - } - for (int32_t i = 0; i < rendering.MaxTextures; ++i) - { - if (!isValid(rendering.Textures[i].RenderHandle)) continue; - ImGui::Text("%i", i); - float width = bx::min(ImGui::GetContentRegionAvail().x, rendering.Textures[i].Info.width); - float height = bx::min(ImGui::GetContentRegionAvail().x, rendering.Textures[i].Info.height); - ImGui::Image(rendering.Textures[i].RenderHandle.idx, {width, height}); - } - } - ImGui::End(); - if (ImGui::Begin("Puzzles")) - { - char nameBuf[64]{0}; - 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"); - bx::snprintf(nameBuf, sizeof(nameBuf), "%u: %s", i, puzzleData.PuzzleName); - if (ImGui::Selectable(nameBuf, isSelected)) + auto& mdl = rendering.Models[card.BaseModelHandle.ModelIdx]; + if (mdl.SocketCount > 0 && ImGui::TreeNodeEx("Slots")) { - debug.SelectedDebugLevel = isSelected ? UINT16_MAX : i; - } - ImGui::PopID(); - } - } - ImGui::End(); - if (debug.SelectedDebugLevel < BX_COUNTOF(level.Puzzles)) - { - if (!Puzzle::RenderDebugUI(level.Puzzles[debug.SelectedDebugLevel].Data)) - { - debug.SelectedDebugLevel = UINT16_MAX; - } - } - if (ImGui::Begin("Cards")) - { - Gen::StaticPuzzleData& staticData = Puzzle::GetStaticPuzzleData(); - - if (ImGui::Button("Save")) - { - Puzzle::SaveStaticPuzzleData(); - } - ImGui::SameLine(); - if (ImGui::Button("Reload")) - { - Puzzle::LoadStaticPuzzleData(); - } - - ImGui::Separator(); - - ImGui::ColorEdit3("Disabled Tint", &staticData.Visuals.DisabledCardTint.x); - ImGui::ColorEdit3("Tile Base Color", &staticData.Visuals.TileBaseColor.x); - ImGui::ColorEdit3("Tile Dot Color", &staticData.Visuals.TileDotColor.x); - - for (int32_t i = 0; i < BX_COUNTOF(staticData.Cards); ++i) - { - ImGui::Separator(); - - Gen::StaticPuzzleCard& card = staticData.Cards[i]; - ImGui::PushID(i); - char cardName[64]{0}; - bx::snprintf(cardName, sizeof(cardName), "%i", i); - ImGui::Selectable(cardName); - if (ImGui::BeginDragDropSource()) - { - Puzzle::DrawCard(card, debug.DebugCardRotation, ImGui::GetCursorScreenPos()); - ImGui::SetDragDropPayload("cardtype", &i, sizeof(i)); - ImGui::EndDragDropSource(); - } - - Tools::ModelDropdown(card.BaseModelHandle); - Tools::TextureDropdown(card.BoardTextureHandle); - if (IsValid(card.BaseModelHandle)) - { - auto& mdl = rendering.Models[card.BaseModelHandle.ModelIdx]; - if (mdl.SocketCount > 0 && ImGui::TreeNodeEx("Slots")) + for (int32_t sIdx = 0; sIdx < mdl.SocketCount; ++sIdx) { - for (int32_t sIdx = 0; sIdx < mdl.SocketCount; ++sIdx) + Tools::ModelDropdown(card.Sockets[sIdx].Model, mdl.Sockets[sIdx].Name); + int val = card.Sockets[sIdx].ConnectionDirection; + ImGui::PushID(sIdx); + if (ImGui::Combo("Connection Direction", &val, "North\0East\0South\0West\0")) { - Tools::ModelDropdown(card.Sockets[sIdx].Model, mdl.Sockets[sIdx].Name); - int val = card.Sockets[sIdx].ConnectionDirection; - ImGui::PushID(sIdx); - if (ImGui::Combo("Connection Direction", &val, "North\0East\0South\0West\0")) - { - card.Sockets[sIdx].ConnectionDirection = val; - } - ImGui::PopID(); - } - ImGui::TreePop(); - } - } - - ImGui::Text("Card"); - for (int8_t y = 0; y < Puzzle::Config::CardSize; ++y) - { - ImGui::PushID(y); - for (int8_t x = 0; x < Puzzle::Config::CardSize; ++x) - { - if (x > 0) ImGui::SameLine(); - ImGui::PushID(x); - auto& node = Puzzle::EditCardNodeAt(card, 0, x, y); - if (ImGui::Button(Gen::PuzzleElementType::ShortName[node], {26, 24})) - { - int32_t newVal = int32_t(node) + 1; - if (newVal >= Gen::PuzzleElementType::EntryCount) - { - newVal = 0; - } - node = Gen::PuzzleElementType::Enum(newVal); + card.Sockets[sIdx].ConnectionDirection = val; } ImGui::PopID(); } + ImGui::TreePop(); + } + } + + ImGui::Text("Card"); + for (int8_t y = 0; y < Puzzle::Config::CardSize; ++y) + { + ImGui::PushID(y); + for (int8_t x = 0; x < Puzzle::Config::CardSize; ++x) + { + if (x > 0) ImGui::SameLine(); + ImGui::PushID(x); + auto& node = Puzzle::EditCardNodeAt(card, 0, x, y); + if (ImGui::Button(Gen::PuzzleElementType::ShortName[node], {26, 24})) + { + int32_t newVal = int32_t(node) + 1; + if (newVal >= Gen::PuzzleElementType::EntryCount) + { + newVal = 0; + } + node = Gen::PuzzleElementType::Enum(newVal); + } ImGui::PopID(); } ImGui::PopID(); } + ImGui::PopID(); } - ImGui::End(); - if (ImGui::Begin("Debug")) - { - ImGui::Checkbox("Arenas", &debug.ShowArenaUsage); - ImGui::Checkbox("ImGui Demo", &debug.ShowImguiDemo); - ImGui::SliderFloat("Font Scale", &ImGui::GetIO().FontGlobalScale, 0.5f, 4.0f); - } - ImGui::End(); + } + ImGui::End(); + } - if (debug.ShowArenaUsage) - { - if (ImGui::Begin("Arenas", &debug.ShowArenaUsage)) - { - ProgressBar("Permanent", shared.Game.PermanentArena.Used, shared.Game.PermanentArena.MaxSize); - ProgressBar("Entity", shared.Game.EntityArena.Used, shared.Game.EntityArena.MaxSize); - ProgressBar("Transient", shared.Game.TransientArena.Used, shared.Game.TransientArena.MaxSize); - } - ImGui::End(); - } + void RenderEntitiesUI() + { + auto& level = Game::GetInstance().GameLevel; - if (ImGui::Begin("Entities")) + if (ImGui::Begin("Entities")) + { + if (ImGui::TreeNodeEx("UIQuads")) { - ImGui::Text("UIQuads"); + ImGui::Text("Count: %u", level.UIQuads.Count); for (uint16_t i = 0; i < level.UIQuads.Count; ++i) { + ImGui::Separator(); ImGui::PushID(i); + ImGui::Text("%u", i); + ImGui::SameLine(); auto& quad = level.UIQuads.Get({i}); + ImGui::Checkbox("Debug Break on Render", &quad.EData.DebugBreakOnRender); + ImGui::SameLine(); ImGui::Checkbox("Visible", &quad.EData.Visible); TextureDropdown(quad.EData.TextureHandle); MaterialDropdown(quad.EData.MaterialHandle); @@ -512,9 +538,37 @@ namespace Tools ImGui::DragFloat3("UI Pos", &quad.UIPos.x); ImGui::PopID(); } + ImGui::TreePop(); + } + if (ImGui::TreeNodeEx("Level")) + { + ImGui::Text("Count: %u", level.LevelEntities.Count); + for (uint16_t i = 0; i < level.LevelEntities.Count; ++i) + { + ImGui::Separator(); + ImGui::PushID(i); + ImGui::Text("%u", i); + ImGui::SameLine(); + auto& levelEnt = level.LevelEntities.Get({i}); + ImGui::Checkbox("Debug Break on Render", &levelEnt.EData.DebugBreakOnRender); + ImGui::SameLine(); + ImGui::Checkbox("Visible", &levelEnt.EData.Visible); + TextureDropdown(levelEnt.EData.TextureHandle); + MaterialDropdown(levelEnt.EData.MaterialHandle); + ImGui::DragFloat3("Pos", &levelEnt.EData.Transform.Position.x); + ImGui::PopID(); + } + ImGui::TreePop(); } - ImGui::End(); } + ImGui::End(); + } + + void RenderStatsUI() + { + auto& time = Game::GetInstance().Time; + auto& debug = Game::GetInstance().DebugData; + if (debug.ShowStats) { ImGui::SetNextWindowPos({0, 0}); @@ -563,6 +617,48 @@ namespace Tools ImGui::End(); } } + + void RenderDebugUI(Game::GameRendering& rendering) + { + if (!rendering.SetupData.UseImgui) return; + ZoneScopedN("DebugUI"); + + auto& time = Game::GetInstance().Time; + auto& shared = Game::GetShared(); + auto& debug = Game::GetInstance().DebugData; + auto& level = Game::GetInstance().GameLevel; + auto& player = Game::GetInstance().Player; + + if (rendering.UIVisible == Game::UIVisibilityState::Debug) + { + if (ImGui::IsMouseClicked(ImGuiMouseButton_Right)) + { + debug.DebugCardRotation++; + if (debug.DebugCardRotation >= 4) debug.DebugCardRotation = 0; + } + + if (ImGui::Begin("Debug")) + { + ImGui::Checkbox("ImGui Demo", &debug.ShowImguiDemo); + ImGui::SliderFloat("Font Scale", &ImGui::GetIO().FontGlobalScale, 0.5f, 4.0f); + + ImGui::Separator(); + ImGui::Text("Arenas"); + ProgressBar("Permanent", shared.Game.PermanentArena.Used, shared.Game.PermanentArena.MaxSize); + ProgressBar("Entity", shared.Game.EntityArena.Used, shared.Game.EntityArena.MaxSize); + ProgressBar("Transient", shared.Game.TransientArena.Used, shared.Game.TransientArena.MaxSize); + } + ImGui::End(); + + RenderLogUI(); + RenderRenderSettingsUI(rendering); + RenderTexturesUI(rendering); + RenderPuzzlesUI(); + RenderCardsUI(rendering); + RenderEntitiesUI(); + } + RenderStatsUI(); + } void MeasureFrameEnd() { FrameTimes[FrameTimeIdx] = bx::getHPCounter(); diff --git a/src/game/UI.cpp b/src/game/UI.cpp index ba23257..ad88add 100644 --- a/src/game/UI.cpp +++ b/src/game/UI.cpp @@ -1,5 +1,6 @@ #include "UI.h" +#include "Entity.h" #include "Gen.h" #include "Global.h" #include "Input.h" @@ -18,10 +19,16 @@ namespace namespace Game { - UIQuadEntityHandle NewQuad(UIQuadEntityManager& manager, const Gen::SavedEntityRenderData& loadData) + UIQuadEntityHandle NewQuad(UIQuadEntityManager& manager, + const Gen::SavedEntityRenderData& loadData, + UIQuadEntityHandle oldHandle) { - UIQuadEntityHandle h = manager.New(); - if (!IsValid(h)) return h; + UIQuadEntityHandle h = oldHandle; + if (!IsValid(h)) + { + h = manager.New(); + if (!IsValid(h)) return h; + } UIQuadEntity& entity = manager.Get(h); entity.EData.LoadFromSaved(loadData); @@ -85,8 +92,11 @@ namespace Game void WorldPuzzleUI::Setup() { auto& level = GetInstance().GameLevel; - SolvedQuad = NewQuad(level.UIQuads, GetInstance().Player.Config.TabletStatusRenderData); - ResetQuad = NewQuad(level.UIQuads, GetInstance().Player.Config.TabletResetRenderData); + auto& player = GetInstance().Player; + + TabletHandle = NewQuad(level.UIQuads, player.Config.TabletBackgroundRenderData); + SolvedQuad = NewQuad(level.UIQuads, player.Config.TabletStatusRenderData); + ResetQuad = NewQuad(level.UIQuads, player.Config.TabletResetRenderData); for (int32_t i = 0; i < Puzzle::Config::MaxCardsInPuzzle; ++i) { @@ -247,15 +257,6 @@ namespace Game Vec3 boardTilePos = boardPos / UICardOffset; int32_t xPos = (int32_t)bx::round(boardTilePos.x); int32_t yPos = (int32_t)bx::round(boardTilePos.y); - LOG("boardPos: %f %f %f, offset: %f %f %f, xy: %i %i", - boardPos.x, - boardPos.y, - boardPos.z, - boardOffset.x, - boardOffset.y, - boardOffset.z, - xPos, - yPos); Gen::PuzPos srcCardPos = {(int8_t)DraggedCard.X, (int8_t)DraggedCard.Y}; Gen::PlacedPuzzleCard& srcCard = Data.PlacedCards[srcCardPos.Y * Puzzle::Config::MaxPuzzleSizeCards + srcCardPos.X]; @@ -311,19 +312,31 @@ namespace Game void WorldPuzzleUI::Update(Gen::PuzzleData& Data, bool IsPuzzleSolved) { auto& level = GetInstance().GameLevel; + auto& player = GetInstance().Player; - Transform& camTransform = GetInstance().Player.PlayerCamTransform; + Transform& camTransform = player.PlayerCamTransform; UpdateMatrix(camTransform); - StaticData.UITransform = level.UIQuads.Get(level.TabletHandle).EData.Transform; + // UI Tablet + if (IsValid(TabletHandle)) + { + auto& tablet = level.UIQuads.Get(TabletHandle); + tablet.EData.Transform.Rotation = camTransform.Rotation; + Rotate(tablet.EData.Transform, {0.5f * bx::kPi, 0.0f, 0.0f}); + tablet.EData.Transform.Position = camTransform.Position + AxisForward(camTransform.M) * 1.0f; + StaticData.UITransform = tablet.EData.Transform; + tablet.EData.Transform.Position += {0.0f, 0.0f, 0.01f}; + } + StaticData.UITransform.Rotation = camTransform.Rotation; StaticData.ZAxis = AxisForward(StaticData.UITransform.M); StaticData.UITransform.Position += StaticData.ZAxis * -0.01f; StaticData.MousePosWorld = GetMousePosWorld(); - // TODO: disable warning & check if parentheses make sense like this - Vec2 uiOffset = Vec2{static_cast(Data.WidthTiles / Puzzle::Config::CardSize) - 1, - static_cast(Data.HeightTiles / Puzzle::Config::CardSize) - 1}; + // NOLINTBEGIN + Vec2 uiOffset = Vec2{static_cast(Data.WidthTiles / Puzzle::Config::CardSize - 1), + static_cast(Data.HeightTiles / Puzzle::Config::CardSize - 1)}; + // NOLINTEND uiOffset *= -UICardOffset * 0.5f; Transform tileOriginTransform = StaticData.UITransform; @@ -354,5 +367,9 @@ namespace Game void WorldPuzzleUI::Reset() { auto& level = GetInstance().GameLevel; + auto& config = GetInstance().Player.Config; + TabletHandle = NewQuad(level.UIQuads, config.TabletBackgroundRenderData, TabletHandle); + SolvedQuad = NewQuad(level.UIQuads, config.TabletStatusRenderData, SolvedQuad); + ResetQuad = NewQuad(level.UIQuads, config.TabletResetRenderData, ResetQuad); } } // namespace Game diff --git a/src/game/UI.h b/src/game/UI.h index 69058da..99aa6a1 100644 --- a/src/game/UI.h +++ b/src/game/UI.h @@ -19,6 +19,7 @@ namespace Game static constexpr float UICardOffset = 2.1f * UICardScale; static constexpr int32_t UIAvailableCardMaxStackPreview = 3; + UIQuadEntityHandle TabletHandle; UIQuadEntityHandle SolvedQuad; UIQuadEntityHandle ResetQuad; @@ -34,7 +35,9 @@ namespace Game void Reset(); }; - UIQuadEntityHandle NewQuad(UIQuadEntityManager& manager, const Gen::SavedEntityRenderData& loadData); + UIQuadEntityHandle NewQuad(UIQuadEntityManager& manager, + const Gen::SavedEntityRenderData& loadData, + UIQuadEntityHandle oldHandle = {}); void UpdateQuad(UIQuadEntityManager& manager, UIQuadEntityHandle handle); Gen::Vec3 GetMousePosWorld(); bool IsQuadHovered(Gen::Transform& quadTransform, Gen::Vec3 mousePosWorld, Gen::Vec3& outQuadPlaneIntersectPos); diff --git a/src/game/data/puzzles/0.pzl b/src/game/data/puzzles/0.pzl index 72a394c..9dbeb72 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:2144b5b8885d119aa1432060595728b0628a828a2115fb3d41099fccbb765363 -size 11416 +oid sha256:05b2511e2d9f8b91944b2f805dfd38db5943f633ff9a9332f834bd0cd97eb2f2 +size 11441 diff --git a/src/game/data/static/puzzle.dat b/src/game/data/static/puzzle.dat index f7c6fc3..16a58bb 100644 Binary files a/src/game/data/static/puzzle.dat and b/src/game/data/static/puzzle.dat differ diff --git a/src/game/data/static/uiconfig.dat b/src/game/data/static/uiconfig.dat index 257ceea..50b15c9 100644 Binary files a/src/game/data/static/uiconfig.dat and b/src/game/data/static/uiconfig.dat differ diff --git a/src/game/mini.def b/src/game/mini.def index 1e41d91..b93337c 100644 --- a/src/game/mini.def +++ b/src/game/mini.def @@ -180,4 +180,5 @@ type SavedPlayerConfig TextureHandle TabletStatusNotSolvedTexture TextureHandle TabletStatusSolvedTexture SavedEntityRenderData TabletResetRenderData + SavedEntityRenderData BackgroundLevelRenderData Arr(16) } diff --git a/src/gen/Generated.cpp b/src/gen/Generated.cpp index b7053ba..d083b00 100644 --- a/src/gen/Generated.cpp +++ b/src/gen/Generated.cpp @@ -363,13 +363,19 @@ namespace Gen if (bx::strCmp(memberName, "x") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "y") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -468,19 +474,28 @@ namespace Gen if (bx::strCmp(memberName, "x") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "y") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "z") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -585,25 +600,37 @@ namespace Gen if (bx::strCmp(memberName, "x") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "y") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "z") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "w") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -690,7 +717,10 @@ namespace Gen if (bx::strCmp(memberName, "M") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 9, serializer) && isOk; + uint16_t wantedCount = 9; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -777,7 +807,10 @@ namespace Gen if (bx::strCmp(memberName, "M") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 16, serializer) && isOk; + uint16_t wantedCount = 16; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -888,31 +921,46 @@ namespace Gen if (bx::strCmp(memberName, "M") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "MI") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Position") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Rotation") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Scale") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -999,7 +1047,10 @@ namespace Gen if (bx::strCmp(memberName, "Idx") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -1092,13 +1143,19 @@ namespace Gen if (bx::strCmp(memberName, "ModelIdx") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Asset") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -1191,13 +1248,19 @@ namespace Gen if (bx::strCmp(memberName, "TextureIdx") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Asset") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -1290,13 +1353,19 @@ namespace Gen if (bx::strCmp(memberName, "X") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Y") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -1389,13 +1458,19 @@ namespace Gen if (bx::strCmp(memberName, "Model") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "ConnectionDirection") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -1530,55 +1605,82 @@ namespace Gen if (bx::strCmp(memberName, "Elements") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 4, serializer) && isOk; + uint16_t wantedCount = 4; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "BaseModelHandle") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "NorthCoverHandle") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "EastCoverHandle") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "SouthCoverHandle") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "WestCoverHandle") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Sockets") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 16, serializer) && isOk; + uint16_t wantedCount = 16; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "ModelTextureHandle") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "BoardTextureHandle") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -1665,7 +1767,10 @@ namespace Gen if (bx::strCmp(memberName, "Idx") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -1770,25 +1875,37 @@ namespace Gen if (bx::strCmp(memberName, "TileBaseColor") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "TileDotColor") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Test") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "DisabledCardTint") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -1881,13 +1998,19 @@ namespace Gen if (bx::strCmp(memberName, "Cards") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 64, serializer) && isOk; + uint16_t wantedCount = 64; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Visuals") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -1986,19 +2109,28 @@ namespace Gen if (bx::strCmp(memberName, "RefCard") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "MaxAvailableCount") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "UsedCount") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -2103,25 +2235,37 @@ namespace Gen if (bx::strCmp(memberName, "RefCard") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Position") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Rotation") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Flags") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -2268,67 +2412,100 @@ namespace Gen if (bx::strCmp(memberName, "ID") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "PuzzleName") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 64, serializer) && isOk; + uint16_t wantedCount = 64; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "WidthTiles") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "HeightTiles") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "AvailableCardCount") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "AvailableCards") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 16, serializer) && isOk; + uint16_t wantedCount = 16; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "PlacedCards") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 256, serializer) && isOk; + uint16_t wantedCount = 256; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "InitialPlacedCards") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 256, serializer) && isOk; + uint16_t wantedCount = 256; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "BackgroundTiles") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1024, serializer) && isOk; + uint16_t wantedCount = 1024; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "GoalPositionCount") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "GoalPositions") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 16, serializer) && isOk; + uint16_t wantedCount = 16; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -2451,43 +2628,64 @@ namespace Gen if (bx::strCmp(memberName, "BaseColor") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "HighlightColor") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "TF") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Material") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Texture") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Model") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "Visible") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); @@ -2506,6 +2704,7 @@ namespace Gen isOk = Save(&obj[i].TabletStatusNotSolvedTexture, 1, serializer) && isOk; isOk = Save(&obj[i].TabletStatusSolvedTexture, 1, serializer) && isOk; isOk = Save(&obj[i].TabletResetRenderData, 1, serializer) && isOk; + isOk = Save(obj[i].BackgroundLevelRenderData, 16, serializer) && isOk; } return isOk; } @@ -2527,6 +2726,7 @@ namespace Gen isOk = Load(&obj[i].TabletStatusNotSolvedTexture, 1, serializer) && isOk; isOk = Load(&obj[i].TabletStatusSolvedTexture, 1, serializer) && isOk; isOk = Load(&obj[i].TabletResetRenderData, 1, serializer) && isOk; + isOk = Load(obj[i].BackgroundLevelRenderData, 16, serializer) && isOk; } // if we're not ok here, something went really wrong assert(isOk); @@ -2575,6 +2775,10 @@ namespace Gen { WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletResetRenderData); } + if (bx::strCmp(memberName, "BackgroundLevelRenderData") == 0 && bx::strCmp(memberTypeName, "SavedEntityRenderData") == 0) + { + WriteDestinations[i] = offsetof(SavedPlayerConfig, BackgroundLevelRenderData); + } } // Start reading in file order, skipping things that we don't know by name and type @@ -2598,31 +2802,55 @@ namespace Gen if (bx::strCmp(memberName, "TabletBackgroundRenderData") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "TabletStatusRenderData") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "TabletStatusNotSolvedTexture") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "TabletStatusSolvedTexture") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } if (bx::strCmp(memberName, "TabletResetRenderData") == 0) { auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); - isOk = Load(fieldPtr, 1, serializer) && isOk; + uint16_t wantedCount = 1; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); + continue; + } + if (bx::strCmp(memberName, "BackgroundLevelRenderData") == 0) + { + auto* fieldPtr = reinterpret_cast(objBasePtr + WriteDestinations[j]); + uint16_t wantedCount = 16; + uint16_t existingCount = matchedDef.ChildArraySizes[j]; + isOk = Load(fieldPtr, bx::min(wantedCount, existingCount), serializer) && isOk; + if (existingCount > wantedCount) serializer.Skip((existingCount - wantedCount) * childDef.Size); continue; } assert(false); diff --git a/src/gen/Generated.h b/src/gen/Generated.h index f2e9d3d..5e0e3bc 100644 --- a/src/gen/Generated.h +++ b/src/gen/Generated.h @@ -259,6 +259,7 @@ namespace Gen TextureHandle TabletStatusNotSolvedTexture = {}; TextureHandle TabletStatusSolvedTexture = {}; SavedEntityRenderData TabletResetRenderData = {}; + SavedEntityRenderData BackgroundLevelRenderData[16] = {}; }; bool Save(const PuzzleElementType::Enum* obj, uint32_t count, Serializer& serializer); bool Load(PuzzleElementType::Enum* obj, uint32_t count, Deserializer& serializer); @@ -386,12 +387,12 @@ namespace Gen TypeDef{sizeof(PlacedPuzzleCard), 838818025, "PlacedPuzzleCard", 4, {24, 21, 4, 33}, {0, 0, 0, 0}, {{313, 7}, {320, 8}, {328, 8}, {336, 5}}}, TypeDef{sizeof(PuzzleData), 1562434765, "PuzzleData", 11, {5, 11, 4, 4, 6, 27, 28, 28, 32, 6, 21}, {0, 64, 0, 0, 0, 16, 256, 256, 1024, 0, 16}, {{341, 2}, {343, 10}, {353, 10}, {363, 11}, {374, 18}, {392, 14}, {406, 11}, {417, 18}, {435, 15}, {450, 17}, {467, 13}}}, TypeDef{sizeof(SavedEntityRenderData), 3172756855, "SavedEntityRenderData", 7, {14, 14, 17, 34, 20, 19, 8}, {0, 0, 0, 0, 0, 0, 0}, {{480, 9}, {489, 14}, {503, 2}, {505, 8}, {513, 7}, {520, 5}, {525, 7}}}, - TypeDef{sizeof(SavedPlayerConfig), 3685229621, "SavedPlayerConfig", 5, {30, 30, 20, 20, 30}, {0, 0, 0, 0, 0}, {{532, 26}, {558, 22}, {580, 28}, {608, 25}, {633, 21}}}, + TypeDef{sizeof(SavedPlayerConfig), 1710757245, "SavedPlayerConfig", 6, {30, 30, 20, 20, 30, 30}, {0, 0, 0, 0, 0, 16}, {{532, 26}, {558, 22}, {580, 28}, {608, 25}, {633, 21}, {654, 25}}}, TypeDef{sizeof(PuzzleElementType::Enum), 2983807453, "PuzzleElementType", 0, {}, {}, {}}, TypeDef{sizeof(PlacedPuzzleCardFlags::Enum), 2983807453, "PlacedPuzzleCardFlags", 0, {}, {}, {}}, TypeDef{sizeof(EMaterial::Enum), 2024002654, "EMaterial", 0, {}, {}, {}}, }; - char MemberNameBuffer[64*64*64]{"xyxyzxyzwMMMMIPositionRotationScaleIdxModelIdxAssetTextureIdxAssetXYModelConnectionDirectionElementsBaseModelHandleNorthCoverHandleEastCoverHandleSouthCoverHandleWestCoverHandleSocketsModelTextureHandleBoardTextureHandleIdxTileBaseColorTileDotColorTestDisabledCardTintCardsVisualsRefCardMaxAvailableCountUsedCountRefCardPositionRotationFlagsIDPuzzleNameWidthTilesHeightTilesAvailableCardCountAvailableCardsPlacedCardsInitialPlacedCardsBackgroundTilesGoalPositionCountGoalPositionsBaseColorHighlightColorTFMaterialTextureModelVisibleTabletBackgroundRenderDataTabletStatusRenderDataTabletStatusNotSolvedTextureTabletStatusSolvedTextureTabletResetRenderData"}; + char MemberNameBuffer[64*64*64]{"xyxyzxyzwMMMMIPositionRotationScaleIdxModelIdxAssetTextureIdxAssetXYModelConnectionDirectionElementsBaseModelHandleNorthCoverHandleEastCoverHandleSouthCoverHandleWestCoverHandleSocketsModelTextureHandleBoardTextureHandleIdxTileBaseColorTileDotColorTestDisabledCardTintCardsVisualsRefCardMaxAvailableCountUsedCountRefCardPositionRotationFlagsIDPuzzleNameWidthTilesHeightTilesAvailableCardCountAvailableCardsPlacedCardsInitialPlacedCardsBackgroundTilesGoalPositionCountGoalPositionsBaseColorHighlightColorTFMaterialTextureModelVisibleTabletBackgroundRenderDataTabletStatusRenderDataTabletStatusNotSolvedTextureTabletStatusSolvedTextureTabletResetRenderDataBackgroundLevelRenderData"}; }; constexpr MetadataTable Metadata; diff --git a/src/models/landscape.glb b/src/models/landscape.glb index eeee03b..0c5f45f 100644 --- a/src/models/landscape.glb +++ b/src/models/landscape.glb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8ac3a438b7b478616c945abfd35b49dcfc8798fcddaad11544a699a809c4ea02 -size 2428 +oid sha256:e11b6cb08ae73158c54b04d9d6c7b14a37cd6243b85f200b19e17dfc8f35a773 +size 65216 diff --git a/src/models/river.glb b/src/models/river.glb new file mode 100644 index 0000000..7ef4131 --- /dev/null +++ b/src/models/river.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3bd5d0cad38a53e206def0147ced05ebdf901b4e2dd8fe9240bc2f94657f996f +size 340652 diff --git a/tools/radsession.rad b/tools/radsession.rad new file mode 100644 index 0000000..fccb158 --- /dev/null +++ b/tools/radsession.rad @@ -0,0 +1,22 @@ +// raddbg 0.9.19 project file + +recent_file: path: "../src/game/entity.h" +recent_file: path: "../src/game/level.cpp" +recent_file: path: "../src/game/ui.cpp" +recent_file: path: "../src/gen/generated.cpp" +recent_file: path: "../src/engine/main.cpp" +recent_file: path: "../src/game/setup.cpp" +recent_file: path: "../src/game/rendering/rendering.cpp" +recent_file: path: "../src/dependency/imgui/imgui_widgets.cpp" +recent_file: path: "../src/game/tools.cpp" +recent_file: path: "../src/dependency/bgfx.cmake/bx/src/debug.cpp" +recent_file: path: "../src/gen/def.h" +recent_file: path: "../src/game/global.cpp" +recent_file: path: "../src/game/Log.cpp" +target: +{ + executable: "../src/cmake-build/PuzGameEngine.exe" + working_directory: "../src" + enabled: 1 + debug_subprocesses: 0 +}