solved status ui

This commit is contained in:
Asuro
2025-05-19 18:20:05 +02:00
parent 1a8be39c19
commit 70db6ca2aa
11 changed files with 166 additions and 21 deletions

View File

@@ -32,12 +32,6 @@ namespace Game
int64_t StartTime = 0;
};
// TODO: move to generated data and save
struct SavedPlayerConfig
{
Gen::SavedEntityRenderData TabletRenderData;
};
struct PlayerData
{
Gen::Transform PlayerCamTransform;
@@ -53,7 +47,7 @@ namespace Game
InteractionMode InteractionM = InteractionMode::Walk;
float MouseSensitivity = 1.0f;
float MovementSpeed = 10.0f;
SavedPlayerConfig Config;
Gen::SavedPlayerConfig Config;
};
struct InstanceDebugData

View File

@@ -195,7 +195,7 @@ namespace Game
{
Deserializer d;
d.Init("game/data/static/uiconfig.dat", "UICO");
d.ReadT(GetInstance().Player.Config.TabletRenderData);
d.ReadT(GetInstance().Player.Config);
d.Finish();
}
}
@@ -271,7 +271,7 @@ namespace Game
if (IsValid(TabletHandle))
{
auto& tablet = UIQuads.Get(TabletHandle);
tablet.EData.LoadFromSaved(player.Config.TabletRenderData);
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});
@@ -382,6 +382,7 @@ namespace Game
quad.EData.MaterialHandle = EMaterial::UI;
quad.EData.ModelH = GameRendering::Get().GetModelHandleFromPath("models/plane.glb");
}
SolvedQuad = level.UIQuads.New();
IsSetup = true;
LOG("finished setup!");
}
@@ -450,6 +451,21 @@ namespace Game
Vec3 mousePosWorld = GetMousePosWorld();
Puzzle::PuzzleSolver solver;
EntityRenderData solvedData;
solvedData.LoadFromSaved(GetInstance().Player.Config.TabletStatusRenderData);
auto& solvedQuad = level.UIQuads.Get(SolvedQuad);
solvedQuad.EData = solvedData;
solvedQuad.EData.Visible = IsActive;
solvedQuad.EData.TextureHandle = solver.IsPuzzleSolved(Data)
? GetInstance().Player.Config.TabletStatusSolvedTexture
: solvedData.TextureHandle;
solvedQuad.EData.Transform.Position = tileOriginTransform.Position;
solvedQuad.EData.Transform.Rotation = camTransform.Rotation;
solvedQuad.EData.Transform.Scale = solvedData.Transform.Scale;
TranslateLocal(solvedQuad.EData.Transform, solvedData.Transform.Position);
Rotate(solvedQuad.EData.Transform, Vec3{bx::kPi * 0.5f, 0.0f, (1.0f - 0 * 0.5f) * bx::kPi});
// Available Cards
for (int32_t i = 0; i < Puzzle::Config::MaxAvailableStacks; ++i)
{

View File

@@ -157,6 +157,7 @@ namespace Game
PuzzleTileCoverHandle CoverHandles[Puzzle::Config::MaxCardsInPuzzle * Puzzle::Config::MaxCoversInTile];
UIQuadEntityHandle UIPlacedCards[Puzzle::Config::MaxCardsInPuzzle];
UIQuadEntityHandle UIAvailableCards[Puzzle::Config::MaxAvailableStacks * UIAvailableCardMaxStackPreview];
UIQuadEntityHandle SolvedQuad;
Gen::PuzPos DraggedCard{-1, -1};
uint16_t DraggedAvailableCardIdx = UINT16_MAX;
bool IsSetup = false;

View File

@@ -240,7 +240,7 @@ namespace Puzzle
return from == PuzzleElementType::ElectricIn || from == PuzzleElementType::ElectricGoal ||
from == PuzzleElementType::None;
}
assert(false);
// assert(false);
return false;
}
bool PuzzleSolver::IsValidSource(PuzzleElementType::Enum sourceType, PuzzleElementType::Enum goalType)

View File

@@ -39,6 +39,7 @@ namespace Tools
bool EntityDataSettings(Gen::SavedEntityRenderData& data)
{
ImGui::PushID(&data);
bool changed = false;
changed |= ModelDropdown(data.Model);
changed |= MaterialDropdown(data.Material);
@@ -47,6 +48,7 @@ namespace Tools
changed |= ImGui::Checkbox("Visible", &data.Visible);
changed |= ImGui::ColorEdit4("Color 1", &data.BaseColor.x);
changed |= ImGui::ColorEdit4("Color 2", &data.HighlightColor.x);
ImGui::PopID();
return changed;
}
@@ -299,11 +301,16 @@ namespace Tools
ImGui::Separator();
ImGui::Text("Game Tablet");
if (Tools::EntityDataSettings(player.Config.TabletRenderData))
bool bTabletChanged = false;
bTabletChanged |= Tools::EntityDataSettings(player.Config.TabletBackgroundRenderData);
ImGui::Text("Status");
bTabletChanged |= Tools::EntityDataSettings(player.Config.TabletStatusRenderData);
bTabletChanged |= Tools::TextureDropdown(player.Config.TabletStatusSolvedTexture);
if (bTabletChanged)
{
Serializer s;
s.Init("game/data/static/uiconfig.dat", "UICO");
s.WriteT(player.Config.TabletRenderData);
s.WriteT(player.Config);
s.Finish();
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -165,3 +165,10 @@ type SavedEntityRenderData
ModelHandle Model
b Visible
}
type SavedPlayerConfig
{
SavedEntityRenderData TabletBackgroundRenderData
SavedEntityRenderData TabletStatusRenderData
TextureHandle TabletStatusSolvedTexture
}

View File

@@ -2445,4 +2445,114 @@ namespace Gen
assert(isOk);
return isOk;
}
bool Save(const SavedPlayerConfig* obj, uint32_t count, Serializer& serializer)
{
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Save(&obj[i].TabletBackgroundRenderData, 1, serializer) && isOk;
isOk = Save(&obj[i].TabletStatusRenderData, 1, serializer) && isOk;
isOk = Save(&obj[i].TabletStatusSolvedTexture, 1, serializer) && isOk;
}
return isOk;
}
bool Load(SavedPlayerConfig* obj, uint32_t count, Deserializer& serializer)
{
const char* typeName = Meta::Metadata.TypeDefinitions[SavedPlayerConfig::TypeIdx].Name;
// Quick match
int32_t matchedHashIdx =
serializer.TypeBuf.FindHash(Meta::Metadata.TypeDefinitions[SavedPlayerConfig::TypeIdx].Hash);
if (matchedHashIdx >= 0)
{
assert(bx::strCmp(serializer.TypeBuf.Defs[matchedHashIdx].Name, typeName) == 0);
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
isOk = Load(&obj[i].TabletBackgroundRenderData, 1, serializer) && isOk;
isOk = Load(&obj[i].TabletStatusRenderData, 1, serializer) && isOk;
isOk = Load(&obj[i].TabletStatusSolvedTexture, 1, serializer) && isOk;
}
// if we're not ok here, something went really wrong
assert(isOk);
return isOk;
}
// Failed to resolve hash, the type definition chaned since the file was saved! try to match by name.
int32_t nameMatchIdx = serializer.TypeBuf.FindDefByName(typeName);
if (nameMatchIdx < 0)
{
// Name match failed, caller has to handle this and potentially skip some bytes
return false;
}
// Successfully matched name, but we need to follow the definition of the file now!
const Meta::TypeDef& matchedDef = serializer.TypeBuf.Defs[nameMatchIdx];
// Figure out new member mapping
uint64_t WriteDestinations[64];
for (int32_t i = 0; i < BX_COUNTOF(WriteDestinations); ++i)
{
WriteDestinations[i] = UINT64_MAX;
}
for (uint32_t i = 0; i < matchedDef.ChildCount; ++i)
{
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[i].Offset], matchedDef.MemberNameIndices[i].Size};
const char* memberTypeName = serializer.TypeBuf.Defs[matchedDef.ChildIndices[i]].Name;
if (bx::strCmp(memberName, "TabletBackgroundRenderData") == 0 && bx::strCmp(memberTypeName, "SavedEntityRenderData") == 0)
{
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletBackgroundRenderData);
}
if (bx::strCmp(memberName, "TabletStatusRenderData") == 0 && bx::strCmp(memberTypeName, "SavedEntityRenderData") == 0)
{
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletStatusRenderData);
}
if (bx::strCmp(memberName, "TabletStatusSolvedTexture") == 0 && bx::strCmp(memberTypeName, "TextureHandle") == 0)
{
WriteDestinations[i] = offsetof(SavedPlayerConfig, TabletStatusSolvedTexture);
}
}
// Start reading in file order, skipping things that we don't know by name and type
bool isOk = true;
for (uint32_t i = 0; i < count; ++i)
{
uint8_t* objBasePtr = reinterpret_cast<uint8_t*>(&obj[i]);
for (uint32_t j = 0; j < matchedDef.ChildCount; ++j)
{
const Meta::TypeDef& childDef = serializer.TypeBuf.Defs[matchedDef.ChildIndices[j]];
const bx::StringView memberName = {&serializer.MemberNameBuf[matchedDef.MemberNameIndices[j].Offset], matchedDef.MemberNameIndices[j].Size};
if (WriteDestinations[j] == UINT64_MAX)
{
// Unknown member name or type changed
uint16_t count = bx::max(1, matchedDef.ChildArraySizes[matchedDef.ChildIndices[j]]);
serializer.Skip(childDef.Size * count);
continue;
}
if (bx::strCmp(memberName, "TabletBackgroundRenderData") == 0)
{
auto* fieldPtr = reinterpret_cast<SavedEntityRenderData*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "TabletStatusRenderData") == 0)
{
auto* fieldPtr = reinterpret_cast<SavedEntityRenderData*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
if (bx::strCmp(memberName, "TabletStatusSolvedTexture") == 0)
{
auto* fieldPtr = reinterpret_cast<TextureHandle*>(objBasePtr + WriteDestinations[j]);
isOk = Load(fieldPtr, 1, serializer) && isOk;
continue;
}
assert(false);
}
}
assert(isOk);
return isOk;
}
}

View File

@@ -7,7 +7,7 @@ namespace Gen
struct Deserializer;
struct PuzzleElementType
{
static constexpr uint16_t TypeIdx = 31;
static constexpr uint16_t TypeIdx = 32;
static constexpr int32_t EntryCount = 8;
enum Enum : uint8_t
{
@@ -56,7 +56,7 @@ namespace Gen
};
struct EMaterial
{
static constexpr uint16_t TypeIdx = 32;
static constexpr uint16_t TypeIdx = 33;
static constexpr int32_t EntryCount = 2;
enum Enum : int32_t
{
@@ -219,6 +219,13 @@ namespace Gen
ModelHandle Model = {};
bool Visible = {};
};
struct SavedPlayerConfig
{
static constexpr uint16_t TypeIdx = 31;
SavedEntityRenderData TabletBackgroundRenderData = {};
SavedEntityRenderData TabletStatusRenderData = {};
TextureHandle TabletStatusSolvedTexture = {};
};
bool Save(const PuzzleElementType::Enum* obj, uint32_t count, Serializer& serializer);
bool Load(PuzzleElementType::Enum* obj, uint32_t count, Deserializer& serializer);
bool Save(const EMaterial::Enum* obj, uint32_t count, Serializer& serializer);
@@ -285,6 +292,8 @@ namespace Gen
bool Load(PuzzleData* obj, uint32_t count, Deserializer& serializer);
bool Save(const SavedEntityRenderData* obj, uint32_t count, Serializer& serializer);
bool Load(SavedEntityRenderData* obj, uint32_t count, Deserializer& serializer);
bool Save(const SavedPlayerConfig* obj, uint32_t count, Serializer& serializer);
bool Load(SavedPlayerConfig* obj, uint32_t count, Deserializer& serializer);
namespace Meta {
constexpr uint16_t CurrentMetaVersion = 1;
@@ -308,7 +317,7 @@ namespace Gen
struct MetadataTable
{
TypeDef TypeDefinitions[33]
TypeDef TypeDefinitions[34]
{
TypeDef{sizeof(int8_t), 0, "i8", 0, {}, {}, {}},
TypeDef{sizeof(int16_t), 1, "i16", 0, {}, {}, {}},
@@ -333,18 +342,19 @@ namespace Gen
TypeDef{sizeof(TextureHandle), 1633273761, "TextureHandle", 2, {5, 18}, {0, 0}, {{51, 10}, {61, 5}}},
TypeDef{sizeof(PuzPos), 1834398141, "PuzPos", 2, {0, 0}, {0, 0}, {{66, 1}, {67, 1}}},
TypeDef{sizeof(CardSocket), 2168907571, "CardSocket", 2, {19, 4}, {0, 0}, {{68, 5}, {73, 19}}},
TypeDef{sizeof(StaticPuzzleCard), 537913399, "StaticPuzzleCard", 9, {31, 19, 19, 19, 19, 19, 22, 20, 20}, {4, 0, 0, 0, 0, 0, 16, 0, 0}, {{92, 8}, {100, 15}, {115, 16}, {131, 15}, {146, 16}, {162, 15}, {177, 7}, {184, 18}, {202, 18}}},
TypeDef{sizeof(StaticPuzzleCard), 537913399, "StaticPuzzleCard", 9, {32, 19, 19, 19, 19, 19, 22, 20, 20}, {4, 0, 0, 0, 0, 0, 16, 0, 0}, {{92, 8}, {100, 15}, {115, 16}, {131, 15}, {146, 16}, {162, 15}, {177, 7}, {184, 18}, {202, 18}}},
TypeDef{sizeof(StaticPuzzleCardHandle), 1742502768, "StaticPuzzleCardHandle", 1, {5}, {0}, {{220, 3}}},
TypeDef{sizeof(PuzzleVisualSettings), 2302077481, "PuzzleVisualSettings", 4, {14, 14, 13, 14}, {0, 0, 0, 0}, {{223, 13}, {236, 12}, {248, 4}, {252, 16}}},
TypeDef{sizeof(StaticPuzzleData), 2637647137, "StaticPuzzleData", 2, {23, 25}, {64, 0}, {{268, 5}, {273, 7}}},
TypeDef{sizeof(PuzzleCardStack), 53538532, "PuzzleCardStack", 3, {24, 4, 4}, {0, 0, 0}, {{280, 7}, {287, 17}, {304, 9}}},
TypeDef{sizeof(PlacedPuzzleCard), 3555575973, "PlacedPuzzleCard", 4, {24, 21, 4, 8}, {0, 0, 0, 0}, {{313, 7}, {320, 8}, {328, 8}, {336, 8}}},
TypeDef{sizeof(PuzzleData), 3349686056, "PuzzleData", 10, {5, 11, 4, 4, 6, 27, 28, 31, 6, 21}, {0, 64, 0, 0, 0, 16, 256, 1024, 0, 16}, {{344, 2}, {346, 10}, {356, 10}, {366, 11}, {377, 18}, {395, 14}, {409, 11}, {420, 15}, {435, 17}, {452, 13}}},
TypeDef{sizeof(SavedEntityRenderData), 3172756855, "SavedEntityRenderData", 7, {14, 14, 17, 32, 20, 19, 8}, {0, 0, 0, 0, 0, 0, 0}, {{465, 9}, {474, 14}, {488, 2}, {490, 8}, {498, 7}, {505, 5}, {510, 7}}},
TypeDef{sizeof(PuzzleData), 3349686056, "PuzzleData", 10, {5, 11, 4, 4, 6, 27, 28, 32, 6, 21}, {0, 64, 0, 0, 0, 16, 256, 1024, 0, 16}, {{344, 2}, {346, 10}, {356, 10}, {366, 11}, {377, 18}, {395, 14}, {409, 11}, {420, 15}, {435, 17}, {452, 13}}},
TypeDef{sizeof(SavedEntityRenderData), 3172756855, "SavedEntityRenderData", 7, {14, 14, 17, 33, 20, 19, 8}, {0, 0, 0, 0, 0, 0, 0}, {{465, 9}, {474, 14}, {488, 2}, {490, 8}, {498, 7}, {505, 5}, {510, 7}}},
TypeDef{sizeof(SavedPlayerConfig), 692059165, "SavedPlayerConfig", 3, {30, 30, 20}, {0, 0, 0}, {{517, 26}, {543, 22}, {565, 25}}},
TypeDef{sizeof(PuzzleElementType::Enum), 2983807453, "PuzzleElementType", 0, {}, {}, {}},
TypeDef{sizeof(EMaterial::Enum), 2024002654, "EMaterial", 0, {}, {}, {}},
};
char MemberNameBuffer[64*64*64]{"xyxyzxyzwMMMMIPositionRotationScaleIdxModelIdxAssetTextureIdxAssetXYModelConnectionDirectionElementsBaseModelHandleNorthCoverHandleEastCoverHandleSouthCoverHandleWestCoverHandleSocketsModelTextureHandleBoardTextureHandleIdxTileBaseColorTileDotColorTestDisabledCardTintCardsVisualsRefCardMaxAvailableCountUsedCountRefCardPositionRotationIsLockedIDPuzzleNameWidthTilesHeightTilesAvailableCardCountAvailableCardsPlacedCardsBackgroundTilesGoalPositionCountGoalPositionsBaseColorHighlightColorTFMaterialTextureModelVisible"};
char MemberNameBuffer[64*64*64]{"xyxyzxyzwMMMMIPositionRotationScaleIdxModelIdxAssetTextureIdxAssetXYModelConnectionDirectionElementsBaseModelHandleNorthCoverHandleEastCoverHandleSouthCoverHandleWestCoverHandleSocketsModelTextureHandleBoardTextureHandleIdxTileBaseColorTileDotColorTestDisabledCardTintCardsVisualsRefCardMaxAvailableCountUsedCountRefCardPositionRotationIsLockedIDPuzzleNameWidthTilesHeightTilesAvailableCardCountAvailableCardsPlacedCardsBackgroundTilesGoalPositionCountGoalPositionsBaseColorHighlightColorTFMaterialTextureModelVisibleTabletBackgroundRenderDataTabletStatusRenderDataTabletStatusSolvedTexture"};
};
constexpr MetadataTable Metadata;