Update Dungeon Usage Stats

This commit is contained in:
scawful
2024-01-14 13:33:38 -05:00
parent ea6d8f9636
commit be7276d976
4 changed files with 280 additions and 123 deletions

View File

@@ -61,7 +61,7 @@ absl::Status DungeonEditor::Update() {
}
TAB_BAR("##DungeonEditorTabBar")
TAB_ITEM("Dungeon Room Editor")
TAB_ITEM("Room Editor")
UpdateDungeonRoomView();
END_TAB_ITEM()
TAB_ITEM("Usage Statistics")
@@ -432,19 +432,24 @@ void DungeonEditor::CalculateUsageStats() {
}
}
namespace {
template <typename T>
void RenderSetUsage(const absl::flat_hash_map<T, int>& usage_map) {
void DungeonEditor::RenderSetUsage(
const absl::flat_hash_map<uint16_t, int>& usage_map,
uint16_t& selected_set) {
// Sort the usage map by set number
std::vector<std::pair<T, int>> sorted_usage(usage_map.begin(),
usage_map.end());
std::vector<std::pair<uint16_t, int>> sorted_usage(usage_map.begin(),
usage_map.end());
std::sort(sorted_usage.begin(), sorted_usage.end(),
[](const auto& a, const auto& b) { return a.first < b.first; });
for (const auto& [set, count] : sorted_usage) {
ImGui::Text("%#02x: %d uses", set, count);
auto display_str = absl::StrFormat("%#02x: %d", set, count);
if (ImGui::Selectable(display_str.c_str(), selected_set == set)) {
selected_set = set; // Update the selected set when clicked
}
}
}
namespace {
// Calculate the unused sets in a usage map
// Range for blocksets 0-0x24
// Range for spritesets 0-0x8F
@@ -465,37 +470,146 @@ void RenderUnusedSets(const absl::flat_hash_map<T, int>& usage_map,
} // namespace
void DungeonEditor::DrawUsageStats() {
if (ImGui::BeginTable("DungeonUsageStatsTable", 6, kDungeonTableFlags,
ImVec2(0, 0))) {
if (ImGui::Button("Refresh")) {
CalculateUsageStats();
selected_blockset_ = 0xFFFF;
selected_spriteset_ = 0xFFFF;
selected_palette_ = 0xFFFF;
}
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
if (ImGui::BeginTable("DungeonUsageStatsTable", 8,
kDungeonTableFlags | ImGuiTableFlags_SizingFixedFit,
ImGui::GetContentRegionAvail())) {
TableSetupColumn("Blockset Usage");
TableSetupColumn("Unused Blockset");
TableSetupColumn("Palette Usage");
TableSetupColumn("Unused Palette");
TableSetupColumn("Spriteset Usage");
TableSetupColumn("Unused Spriteset");
TableSetupColumn("Usage Grid");
TableSetupColumn("Group Preview");
TableHeadersRow();
ImGui::PopStyleVar(2);
TableNextColumn();
RenderSetUsage(blockset_usage_);
ImGui::BeginChild("BlocksetUsageScroll", ImVec2(0, 0), true,
ImGuiWindowFlags_HorizontalScrollbar);
RenderSetUsage(blockset_usage_, selected_blockset_);
ImGui::EndChild();
TableNextColumn();
ImGui::BeginChild("UnusedBlocksetScroll", ImVec2(0, 0), true,
ImGuiWindowFlags_HorizontalScrollbar);
RenderUnusedSets(blockset_usage_, 0x25);
ImGui::EndChild();
TableNextColumn();
RenderSetUsage(palette_usage_);
ImGui::BeginChild("PaletteUsageScroll", ImVec2(0, 0), true,
ImGuiWindowFlags_HorizontalScrollbar);
RenderSetUsage(palette_usage_, selected_palette_);
ImGui::EndChild();
TableNextColumn();
ImGui::BeginChild("UnusedPaletteScroll", ImVec2(0, 0), true,
ImGuiWindowFlags_HorizontalScrollbar);
RenderUnusedSets(palette_usage_, 0x48);
ImGui::EndChild();
TableNextColumn();
RenderSetUsage(spriteset_usage_);
ImGui::BeginChild("SpritesetUsageScroll", ImVec2(0, 0), true,
ImGuiWindowFlags_HorizontalScrollbar);
RenderSetUsage(spriteset_usage_, selected_spriteset_);
ImGui::EndChild();
TableNextColumn();
ImGui::BeginChild("UnusedSpritesetScroll", ImVec2(0, 0), true,
ImGuiWindowFlags_HorizontalScrollbar);
RenderUnusedSets(spriteset_usage_, 0x90);
ImGui::EndChild();
TableNextColumn();
DrawUsageGrid();
TableNextColumn();
if (selected_blockset_ < 0x25) {
gfx_group_editor_.SetSelectedBlockset(selected_blockset_);
gfx_group_editor_.DrawBlocksetViewer(true);
} else if (selected_spriteset_ < 0x90) {
gfx_group_editor_.SetSelectedSpriteset(selected_spriteset_ + 0x40);
gfx_group_editor_.DrawSpritesetViewer(true);
}
}
ImGui::EndTable();
}
void DungeonEditor::DrawUsageGrid() {
// Create a grid of 295 small squares which is 16 squares wide
// Each square represents a room in the game
// When you hover a square it should show a hover tooltip with the properties
// of the room such as the blockset, spriteset, palette, etc. Calculate the
// number of rows
int totalSquares = 295;
int squaresWide = 16;
int squaresTall = (totalSquares + squaresWide - 1) /
squaresWide; // Ceiling of totalSquares/squaresWide
// Loop through each row
for (int row = 0; row < squaresTall; ++row) {
// Start a new line for each row
ImGui::NewLine();
// Loop through each column in the row
for (int col = 0; col < squaresWide; ++col) {
// Check if we have reached 295 squares
if (row * squaresWide + col >= totalSquares) {
break;
}
// Determine if this square should be highlighted
const auto& room = rooms_[row * squaresWide + col];
bool highlight = room.blockset == selected_blockset_ ||
room.spriteset == selected_spriteset_ ||
room.palette == selected_palette_;
// Set highlight color if needed
if (highlight) {
ImGui::PushStyleColor(
ImGuiCol_Button,
ImVec4(1.0f, 0.5f, 0.0f, 1.0f)); // Or any highlight color
}
// Create a button or selectable for each square
if (ImGui::Button("##square", ImVec2(20, 20))) {
// Handle button click event here
}
// Reset style if it was highlighted
if (highlight) {
ImGui::PopStyleColor();
}
// Check if the square is hovered
if (ImGui::IsItemHovered()) {
// Display a tooltip with all the room properties
ImGui::BeginTooltip();
ImGui::Text("Room ID: %d", row * squaresWide + col);
ImGui::Text("Blockset: %#02x", room.blockset);
ImGui::Text("Spriteset: %#02x", room.spriteset);
ImGui::Text("Palette: %#02x", room.palette);
ImGui::Text("Floor1: %#02x", room.floor1);
ImGui::Text("Floor2: %#02x", room.floor2);
ImGui::Text("Message ID: %#04x", room.message_id_);
ImGui::EndTooltip();
}
// Keep squares in the same line
ImGui::SameLine();
}
}
}
} // namespace editor
} // namespace app
} // namespace yaze

View File

@@ -5,6 +5,7 @@
#include "app/core/common.h"
#include "app/core/editor.h"
#include "app/editor/modules/gfx_group_editor.h"
#include "app/editor/modules/palette_editor.h"
#include "app/gui/canvas.h"
#include "app/gui/icons.h"
@@ -41,7 +42,6 @@ class DungeonEditor : public Editor,
absl::Status Redo() override { return absl::OkStatus(); }
private:
void UpdateDungeonRoomView();
void DrawToolset();
@@ -56,6 +56,9 @@ class DungeonEditor : public Editor,
void CalculateUsageStats();
void DrawUsageStats();
void DrawUsageGrid();
void RenderSetUsage(const absl::flat_hash_map<uint16_t, int>& usage_map,
uint16_t& selected_set);
enum BackgroundType {
kNoBackground,
@@ -82,6 +85,7 @@ class DungeonEditor : public Editor,
ImVector<int> active_rooms_;
GfxGroupEditor gfx_group_editor_;
PaletteEditor palette_editor_;
gfx::SNESPalette current_palette_;
gfx::SNESPalette full_palette_;
@@ -102,6 +106,11 @@ class DungeonEditor : public Editor,
absl::flat_hash_map<uint16_t, int> spriteset_usage_;
absl::flat_hash_map<uint16_t, int> blockset_usage_;
absl::flat_hash_map<uint16_t, int> palette_usage_;
// Add member variables to track the selected set
uint16_t selected_blockset_ = 0xFFFF; // 0xFFFF indicates no selection
uint16_t selected_spriteset_ = 0xFFFF;
uint16_t selected_palette_ = 0xFFFF;
};
} // namespace editor

View File

@@ -33,89 +33,15 @@ absl::Status GfxGroupEditor::Update() {
if (ImGui::BeginTabBar("GfxGroupEditor")) {
if (ImGui::BeginTabItem("Main")) {
gui::InputHexByte("Selected Blockset", &selected_blockset_);
ImGui::Text("Values");
if (ImGui::BeginTable("##BlocksetTable", 2, ImGuiTableFlags_Borders,
ImVec2(0, 0))) {
TableSetupColumn("Inputs", ImGuiTableColumnFlags_WidthStretch,
ImGui::GetContentRegionAvail().x);
TableSetupColumn("Sheets", ImGuiTableColumnFlags_WidthFixed, 256);
TableHeadersRow();
TableNextRow();
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 8; i++) {
ImGui::SetNextItemWidth(100.f);
gui::InputHexByte(("##blockset0" + std::to_string(i)).c_str(),
&rom()->main_blockset_ids[selected_blockset_][i]);
if (i != 3 && i != 7) {
SameLine();
}
}
ImGui::EndGroup();
}
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 8; i++) {
int sheet_id = rom()->main_blockset_ids[selected_blockset_][i];
auto &sheet = *rom()->bitmap_manager()[sheet_id];
if (sheet_id != last_sheet_id_) {
last_sheet_id_ = sheet_id;
auto palette_group = rom()->palette_group("ow_main");
auto palette = palette_group[preview_palette_id_];
sheet.ApplyPalette(palette);
rom()->UpdateBitmap(&sheet);
}
gui::BitmapCanvasPipeline(blockset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 22);
}
ImGui::EndGroup();
}
ImGui::EndTable();
}
DrawBlocksetViewer();
ImGui::EndTabItem();
}
if (ImGui::BeginTabItem("Rooms")) {
gui::InputHexByte("Selected Blockset", &selected_roomset_);
ImGui::Text("Values - Overwrites 4 of main blockset");
if (ImGui::BeginTable("##Roomstable", 2, ImGuiTableFlags_Borders,
ImVec2(0, 0))) {
TableSetupColumn("Inputs", ImGuiTableColumnFlags_WidthStretch,
ImGui::GetContentRegionAvail().x);
TableSetupColumn("Sheets", ImGuiTableColumnFlags_WidthFixed, 256);
TableHeadersRow();
TableNextRow();
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 4; i++) {
ImGui::SetNextItemWidth(100.f);
gui::InputHexByte(("##roomset0" + std::to_string(i)).c_str(),
&rom()->room_blockset_ids[selected_roomset_][i]);
if (i != 3 && i != 7) {
SameLine();
}
}
ImGui::EndGroup();
}
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 4; i++) {
int sheet_id = rom()->room_blockset_ids[selected_roomset_][i];
auto &sheet = *rom()->bitmap_manager()[sheet_id];
gui::BitmapCanvasPipeline(roomset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 23);
}
ImGui::EndGroup();
}
ImGui::EndTable();
}
DrawRoomsetViewer();
ImGui::EndTabItem();
}
@@ -123,39 +49,7 @@ absl::Status GfxGroupEditor::Update() {
gui::InputHexByte("Selected Spriteset", &selected_spriteset_);
ImGui::Text("Values");
if (ImGui::BeginTable("##SpritesTable", 2, ImGuiTableFlags_Borders,
ImVec2(0, 0))) {
TableSetupColumn("Inputs", ImGuiTableColumnFlags_WidthStretch,
ImGui::GetContentRegionAvail().x);
TableSetupColumn("Sheets", ImGuiTableColumnFlags_WidthFixed, 256);
TableHeadersRow();
TableNextRow();
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 4; i++) {
ImGui::SetNextItemWidth(100.f);
gui::InputHexByte(("##spriteset0" + std::to_string(i)).c_str(),
&rom()->spriteset_ids[selected_spriteset_][i]);
if (i != 3 && i != 7) {
SameLine();
}
}
ImGui::EndGroup();
}
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 4; i++) {
int sheet_id = rom()->spriteset_ids[selected_spriteset_][i];
auto sheet = *rom()->bitmap_manager()[sheet_id];
gui::BitmapCanvasPipeline(spriteset_canvas_, sheet, 256,
0x10 * 0x04, 0x20, true, false, 24);
}
ImGui::EndGroup();
}
ImGui::EndTable();
}
DrawSpritesetViewer();
ImGui::EndTabItem();
}
@@ -173,6 +67,135 @@ absl::Status GfxGroupEditor::Update() {
return absl::OkStatus();
}
void GfxGroupEditor::DrawBlocksetViewer(bool sheet_only) {
if (ImGui::BeginTable("##BlocksetTable", sheet_only ? 1 : 2,
ImGuiTableFlags_Borders, ImVec2(0, 0))) {
if (!sheet_only) {
TableSetupColumn("Inputs", ImGuiTableColumnFlags_WidthStretch,
ImGui::GetContentRegionAvail().x);
}
TableSetupColumn("Sheets", ImGuiTableColumnFlags_WidthFixed, 256);
TableHeadersRow();
TableNextRow();
if (!sheet_only) {
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 8; i++) {
ImGui::SetNextItemWidth(100.f);
gui::InputHexByte(("##blockset0" + std::to_string(i)).c_str(),
&rom()->main_blockset_ids[selected_blockset_][i]);
if (i != 3 && i != 7) {
SameLine();
}
}
ImGui::EndGroup();
}
}
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 8; i++) {
int sheet_id = rom()->main_blockset_ids[selected_blockset_][i];
auto &sheet = *rom()->bitmap_manager()[sheet_id];
if (sheet_id != last_sheet_id_) {
last_sheet_id_ = sheet_id;
auto palette_group = rom()->palette_group("ow_main");
auto palette = palette_group[preview_palette_id_];
sheet.ApplyPalette(palette);
rom()->UpdateBitmap(&sheet);
}
gui::BitmapCanvasPipeline(blockset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 22);
}
ImGui::EndGroup();
}
ImGui::EndTable();
}
}
void GfxGroupEditor::DrawRoomsetViewer() {
ImGui::Text("Values - Overwrites 4 of main blockset");
if (ImGui::BeginTable("##Roomstable", 2, ImGuiTableFlags_Borders,
ImVec2(0, 0))) {
TableSetupColumn("Inputs", ImGuiTableColumnFlags_WidthStretch,
ImGui::GetContentRegionAvail().x);
TableSetupColumn("Sheets", ImGuiTableColumnFlags_WidthFixed, 256);
TableHeadersRow();
TableNextRow();
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 4; i++) {
ImGui::SetNextItemWidth(100.f);
gui::InputHexByte(("##roomset0" + std::to_string(i)).c_str(),
&rom()->room_blockset_ids[selected_roomset_][i]);
if (i != 3 && i != 7) {
SameLine();
}
}
ImGui::EndGroup();
}
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 4; i++) {
int sheet_id = rom()->room_blockset_ids[selected_roomset_][i];
auto &sheet = *rom()->bitmap_manager()[sheet_id];
gui::BitmapCanvasPipeline(roomset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 23);
}
ImGui::EndGroup();
}
ImGui::EndTable();
}
}
void GfxGroupEditor::DrawSpritesetViewer(bool sheet_only) {
if (ImGui::BeginTable("##SpritesTable", sheet_only ? 1 : 2,
ImGuiTableFlags_Borders, ImVec2(0, 0))) {
if (!sheet_only) {
TableSetupColumn("Inputs", ImGuiTableColumnFlags_WidthStretch,
ImGui::GetContentRegionAvail().x);
}
TableSetupColumn("Sheets", ImGuiTableColumnFlags_WidthFixed, 256);
TableHeadersRow();
TableNextRow();
if (!sheet_only) {
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 4; i++) {
ImGui::SetNextItemWidth(100.f);
gui::InputHexByte(("##spriteset0" + std::to_string(i)).c_str(),
&rom()->spriteset_ids[selected_spriteset_][i]);
if (i != 3 && i != 7) {
SameLine();
}
}
ImGui::EndGroup();
}
}
TableNextColumn();
{
ImGui::BeginGroup();
for (int i = 0; i < 4; i++) {
int sheet_id = rom()->spriteset_ids[selected_spriteset_][i];
auto sheet = *rom()->bitmap_manager()[115 + sheet_id];
gui::BitmapCanvasPipeline(spriteset_canvas_, sheet, 256, 0x10 * 0x04,
0x20, true, false, 24);
}
ImGui::EndGroup();
}
ImGui::EndTable();
}
}
void GfxGroupEditor::DrawPaletteViewer() {
// TODO: Implement palette viewer
}
void GfxGroupEditor::InitBlockset(gfx::Bitmap tile16_blockset) {
tile16_blockset_bmp_ = tile16_blockset;
}

View File

@@ -8,13 +8,13 @@
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "app/core/editor.h"
#include "app/gui/pipeline.h"
#include "app/editor/modules/palette_editor.h"
#include "app/gfx/bitmap.h"
#include "app/gfx/snes_palette.h"
#include "app/gfx/snes_tile.h"
#include "app/gui/canvas.h"
#include "app/gui/icons.h"
#include "app/gui/pipeline.h"
#include "app/gui/widgets.h"
#include "app/rom.h"
#include "app/zelda3/overworld.h"
@@ -27,6 +27,17 @@ class GfxGroupEditor : public SharedROM {
public:
absl::Status Update();
void DrawBlocksetViewer(bool sheet_only = false);
void DrawRoomsetViewer();
void DrawSpritesetViewer(bool sheet_only = false);
void DrawPaletteViewer();
void SetSelectedBlockset(uint8_t blockset) { selected_blockset_ = blockset; }
void SetSelectedRoomset(uint8_t roomset) { selected_roomset_ = roomset; }
void SetSelectedSpriteset(uint8_t spriteset) {
selected_spriteset_ = spriteset;
}
void InitBlockset(gfx::Bitmap tile16_blockset);
private: