Add imgui layer editor

This commit is contained in:
Henrique Gemignani Passos Lima 2021-05-27 23:55:30 +03:00 committed by Luke Street
parent 634f33c27f
commit 6fb20ab703
4 changed files with 66 additions and 14 deletions

View File

@ -575,6 +575,7 @@ void ImGuiConsole::ShowAppMainMenuBar(bool canInspect) {
if (ImGui::BeginMenu("Tools")) { if (ImGui::BeginMenu("Tools")) {
ImGui::MenuItem("Inspect", nullptr, &m_showInspectWindow, canInspect); ImGui::MenuItem("Inspect", nullptr, &m_showInspectWindow, canInspect);
ImGui::MenuItem("Items", nullptr, &m_showItemsWindow, canInspect); ImGui::MenuItem("Items", nullptr, &m_showItemsWindow, canInspect);
ImGui::MenuItem("Layers", nullptr, &m_showLayersWindow, canInspect);
ImGui::Separator(); ImGui::Separator();
ImGui::MenuItem("Demo", nullptr, &m_showDemoWindow); ImGui::MenuItem("Demo", nullptr, &m_showDemoWindow);
ImGui::EndMenu(); ImGui::EndMenu();
@ -642,6 +643,9 @@ void ImGuiConsole::PreUpdate() {
if (canInspect && m_showItemsWindow) { if (canInspect && m_showItemsWindow) {
ShowItemsWindow(); ShowItemsWindow();
} }
if (canInspect && m_showLayersWindow) {
ShowLayersWindow();
}
if (m_showAboutWindow) { if (m_showAboutWindow) {
ShowAboutWindow(); ShowAboutWindow();
} }
@ -778,4 +782,43 @@ void ImGuiConsole::ShowItemsWindow() {
} }
ImGui::End(); ImGui::End();
} }
void ImGuiConsole::ShowLayersWindow() {
if (ImGui::Begin("Layers", &m_showLayersWindow)) {
for (const auto& world : ListWorlds()) {
const auto& layers = dummyWorlds[world.second]->GetWorldLayers();
if (!layers) {
continue;
}
if (ImGui::TreeNode(world.first.c_str())) {
auto worldLayerState = g_GameState->StateForWorld(world.second).GetLayerState();
u32 startNameIdx = 0;
for (const auto& area : ListAreas(world.second)) {
u32 layerCount = worldLayerState->GetAreaLayerCount(area.second);
if (layerCount == 0) {
continue;
}
if (ImGui::TreeNode(area.first.c_str())) {
// TODO: m_startNameIdx have incorrect values in the data due to a Metaforce bug
// u32 startNameIdx = layers->m_areas[area.second].m_startNameIdx;
for (u32 layer = 0; layer < layerCount; ++layer) {
bool active = worldLayerState->IsLayerActive(area.second, layer);
if (ImGui::Checkbox(layers->m_names[startNameIdx + layer].c_str(), &active)) {
worldLayerState->SetLayerActive(area.second, layer, active);
}
}
ImGui::TreePop();
}
startNameIdx += layerCount;
}
ImGui::TreePop();
}
}
}
ImGui::End();
}
} // namespace metaforce } // namespace metaforce

View File

@ -51,6 +51,7 @@ private:
bool m_showDemoWindow = false; bool m_showDemoWindow = false;
bool m_showAboutWindow = false; bool m_showAboutWindow = false;
bool m_showItemsWindow = false; bool m_showItemsWindow = false;
bool m_showLayersWindow = false;
bool m_paused = false; bool m_paused = false;
bool m_stepFrame = false; bool m_stepFrame = false;
@ -83,5 +84,6 @@ private:
void ShowAboutWindow(); void ShowAboutWindow();
void ShowDebugOverlay(); void ShowDebugOverlay();
void ShowItemsWindow(); void ShowItemsWindow();
void ShowLayersWindow();
}; };
} // namespace metaforce } // namespace metaforce

View File

@ -76,9 +76,9 @@ std::vector<CWorld::CRelay> CWorld::CRelay::ReadMemoryRelays(athena::io::MemoryR
return ret; return ret;
} }
void CWorldLayers::ReadWorldLayers(athena::io::MemoryReader& r, int version, CAssetId mlvlId) { std::optional<CWorldLayers> CWorldLayers::ReadWorldLayers(athena::io::MemoryReader& r, int version, CAssetId mlvlId) {
if (version <= 14) { if (version <= 14) {
return; return std::nullopt;
} }
CWorldLayers ret; CWorldLayers ret;
@ -104,6 +104,8 @@ void CWorldLayers::ReadWorldLayers(athena::io::MemoryReader& r, int version, CAs
CWorldState& wldState = g_GameState->StateForWorld(mlvlId); CWorldState& wldState = g_GameState->StateForWorld(mlvlId);
wldState.GetLayerState()->InitializeWorldLayers(ret.m_areas); wldState.GetLayerState()->InitializeWorldLayers(ret.m_areas);
return ret;
} }
bool CDummyWorld::ICheckWorldComplete() { bool CDummyWorld::ICheckWorldComplete() {
@ -148,7 +150,7 @@ bool CDummyWorld::ICheckWorldComplete() {
if (version > 12) if (version > 12)
r.readString(); r.readString();
CWorldLayers::ReadWorldLayers(r, version, xc_mlvlId); worldLayers = CWorldLayers::ReadWorldLayers(r, version, xc_mlvlId);
x30_loadToken.reset(); x30_loadToken.reset();
x34_loadBuf.reset(); x34_loadBuf.reset();
@ -188,6 +190,8 @@ std::string CDummyWorld::IGetDefaultAudioTrack() const { return {}; }
int CDummyWorld::IGetAreaCount() const { return x18_areas.size(); } int CDummyWorld::IGetAreaCount() const { return x18_areas.size(); }
const std::optional<CWorldLayers>& CDummyWorld::GetWorldLayers() const { return worldLayers; }
CWorld::CWorld(IObjectStore& objStore, IFactory& resFactory, CAssetId mlvlId) CWorld::CWorld(IObjectStore& objStore, IFactory& resFactory, CAssetId mlvlId)
: x8_mlvlId(mlvlId) : x8_mlvlId(mlvlId)
, x60_objectStore(objStore) , x60_objectStore(objStore)

View File

@ -37,6 +37,17 @@ public:
virtual int IGetAreaCount() const = 0; virtual int IGetAreaCount() const = 0;
}; };
struct CWorldLayers {
struct Area {
u32 m_startNameIdx;
u32 m_layerCount;
u64 m_layerBits;
};
std::vector<Area> m_areas;
std::vector<std::string> m_names;
static std::optional<CWorldLayers> ReadWorldLayers(athena::io::MemoryReader& r, int version, CAssetId mlvlId);
};
class CDummyWorld : public IWorld { class CDummyWorld : public IWorld {
enum class Phase { enum class Phase {
Loading, Loading,
@ -58,6 +69,8 @@ class CDummyWorld : public IWorld {
u32 x38_bufSz; u32 x38_bufSz;
TAreaId x3c_curAreaId = kInvalidAreaId; TAreaId x3c_curAreaId = kInvalidAreaId;
std::optional<CWorldLayers> worldLayers;
public: public:
CDummyWorld(CAssetId mlvlId, bool loadMap); CDummyWorld(CAssetId mlvlId, bool loadMap);
~CDummyWorld() override; ~CDummyWorld() override;
@ -72,6 +85,7 @@ public:
bool ICheckWorldComplete() override; bool ICheckWorldComplete() override;
std::string IGetDefaultAudioTrack() const override; std::string IGetDefaultAudioTrack() const override;
int IGetAreaCount() const override; int IGetAreaCount() const override;
const std::optional<CWorldLayers>& GetWorldLayers() const;
}; };
class CWorld : public IWorld { class CWorld : public IWorld {
@ -214,15 +228,4 @@ public:
TAreaId GetAreaIdForSaveId(s32 saveId) const; TAreaId GetAreaIdForSaveId(s32 saveId) const;
}; };
struct CWorldLayers {
struct Area {
u32 m_startNameIdx;
u32 m_layerCount;
u64 m_layerBits;
};
std::vector<Area> m_areas;
std::vector<std::string> m_names;
static void ReadWorldLayers(athena::io::MemoryReader& r, int version, CAssetId mlvlId);
};
} // namespace metaforce } // namespace metaforce