Skip to content

Commit 16546d5

Browse files
committed
[debugger] Improve symbols window
1 parent c239688 commit 16546d5

File tree

1 file changed

+214
-26
lines changed

1 file changed

+214
-26
lines changed

platforms/shared/desktop/gui_debug_disassembler.cpp

Lines changed: 214 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,19 @@ struct DisassemblerBookmark
4747
char name[32];
4848
};
4949

50+
struct SymbolEntry
51+
{
52+
DebugSymbol* symbol;
53+
bool is_manual;
54+
int bank;
55+
};
56+
57+
static bool symbols_dirty = true;
58+
static bool show_auto_symbols = false;
5059
static DebugSymbol*** fixed_symbols = NULL;
5160
static DebugSymbol*** dynamic_symbols = NULL;
61+
static std::vector<SymbolEntry> fixed_symbol_list;
62+
static std::vector<SymbolEntry> dynamic_symbol_list;
5263
static std::vector<DisassemblerLine> disassembler_lines(0x10000);
5364
static std::vector<DisassemblerBookmark> bookmarks;
5465
static int selected_address = -1;
@@ -88,6 +99,12 @@ static void add_bookmark_popup(void);
8899
static void add_symbol_popup(void);
89100
static void save_full_disassembler(FILE* file);
90101
static void save_current_disassembler(FILE* file);
102+
static bool symbol_sort_address_asc(const SymbolEntry& a, const SymbolEntry& b);
103+
static bool symbol_sort_address_desc(const SymbolEntry& a, const SymbolEntry& b);
104+
static bool symbol_sort_addr_only_asc(const SymbolEntry& a, const SymbolEntry& b);
105+
static bool symbol_sort_addr_only_desc(const SymbolEntry& a, const SymbolEntry& b);
106+
static bool symbol_sort_name_asc(const SymbolEntry& a, const SymbolEntry& b);
107+
static bool symbol_sort_name_desc(const SymbolEntry& a, const SymbolEntry& b);
91108

92109
void gui_debug_disassembler_init(void)
93110
{
@@ -145,6 +162,10 @@ void gui_debug_reset_symbols(void)
145162
}
146163
}
147164

165+
fixed_symbol_list.clear();
166+
dynamic_symbol_list.clear();
167+
symbols_dirty = true;
168+
148169
if (emu_get_core()->GetMedia()->IsCDROM())
149170
{
150171
add_cdrom_symbols();
@@ -932,6 +953,13 @@ static void add_symbol(const char* line)
932953
snprintf(new_symbol->text, 64, "%s", s.text);
933954

934955
fixed_symbols[s.bank][s.address] = new_symbol;
956+
957+
SymbolEntry entry;
958+
entry.symbol = new_symbol;
959+
entry.is_manual = true;
960+
entry.bank = s.bank;
961+
fixed_symbol_list.push_back(entry);
962+
symbols_dirty = true;
935963
}
936964
}
937965
}
@@ -977,6 +1005,8 @@ static void add_auto_symbol(GG_Disassembler_Record* record, u16 address)
9771005
{
9781006
if (record->subroutine)
9791007
snprintf(dynamic_symbols[s.bank][s.address]->text, 64, "SUB_%02X_%04X", record->jump_bank, record->jump_address);
1008+
if (show_auto_symbols)
1009+
symbols_dirty = true;
9801010
}
9811011
else
9821012
{
@@ -986,6 +1016,15 @@ static void add_auto_symbol(GG_Disassembler_Record* record, u16 address)
9861016
snprintf(new_symbol->text, 64, "%s", s.text);
9871017

9881018
dynamic_symbols[s.bank][s.address] = new_symbol;
1019+
1020+
SymbolEntry entry;
1021+
entry.symbol = new_symbol;
1022+
entry.is_manual = false;
1023+
entry.bank = s.bank;
1024+
dynamic_symbol_list.push_back(entry);
1025+
1026+
if (show_auto_symbols)
1027+
symbols_dirty = true;
9891028
}
9901029
}
9911030
}
@@ -1621,61 +1660,163 @@ void gui_debug_window_symbols(void)
16211660
{
16221661
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 8.0f);
16231662
ImGui::SetNextWindowPos(ImVec2(340, 400), ImGuiCond_FirstUseEver);
1624-
ImGui::SetNextWindowSize(ImVec2(356, 300), ImGuiCond_FirstUseEver);
1663+
ImGui::SetNextWindowSize(ImVec2(356, 370), ImGuiCond_FirstUseEver);
16251664

16261665
ImGui::Begin("Symbols", &config_debug.show_symbols);
16271666

1628-
static bool show_auto_symbols = false;
1629-
ImGui::Checkbox("Show Automatic Symbols", &show_auto_symbols);
1667+
static char symbol_filter[64] = "";
1668+
static std::vector<SymbolEntry> sorted_symbols;
1669+
static int last_sort_column = -1;
1670+
static int last_sort_direction = -1;
1671+
1672+
bool prev_auto = show_auto_symbols;
1673+
ImGui::Checkbox("Automatic Symbols", &show_auto_symbols);
1674+
if (show_auto_symbols != prev_auto)
1675+
symbols_dirty = true;
1676+
ImGui::SameLine();
1677+
ImGui::PushItemWidth(-1);
1678+
if (ImGui::InputTextWithHint("##symbol_filter", "Filter...", symbol_filter, IM_ARRAYSIZE(symbol_filter)))
1679+
symbols_dirty = true;
1680+
ImGui::PopItemWidth();
16301681

16311682
ImGui::Separator();
16321683

1633-
ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable;
1684+
ImGuiTableFlags flags = ImGuiTableFlags_ScrollY | ImGuiTableFlags_RowBg | ImGuiTableFlags_BordersOuter | ImGuiTableFlags_BordersV | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable;
16341685

16351686
if (ImGui::BeginTable("symbols_table", 4, flags))
16361687
{
16371688
ImGui::TableSetupScrollFreeze(0, 1);
1638-
ImGui::TableSetupColumn("Bank", ImGuiTableColumnFlags_WidthFixed, 36.0f);
1689+
ImGui::TableSetupColumn("Bank", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_DefaultSort, 36.0f);
16391690
ImGui::TableSetupColumn("Address", ImGuiTableColumnFlags_WidthFixed, 58.0f);
16401691
ImGui::TableSetupColumn("Symbol", ImGuiTableColumnFlags_WidthStretch, 2.0f);
1641-
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed, 44.0f);
1692+
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_NoSort, 44.0f);
16421693
ImGui::TableHeadersRow();
16431694

1644-
ImGui::PushFont(gui_default_font);
1695+
if (ImGuiTableSortSpecs* sort_specs = ImGui::TableGetSortSpecs())
1696+
{
1697+
if (sort_specs->SpecsDirty || symbols_dirty)
1698+
{
1699+
sort_specs->SpecsDirty = false;
1700+
symbols_dirty = true;
1701+
}
1702+
1703+
if (sort_specs->SpecsCount > 0)
1704+
{
1705+
last_sort_column = sort_specs->Specs[0].ColumnIndex;
1706+
last_sort_direction = sort_specs->Specs[0].SortDirection;
1707+
}
1708+
}
16451709

1646-
for (int b = 0; b < 0x100; b++)
1710+
if (symbols_dirty)
16471711
{
1648-
for (int i = 0; i < 0x10000; i++)
1712+
symbols_dirty = false;
1713+
sorted_symbols.clear();
1714+
1715+
for (size_t i = 0; i < fixed_symbol_list.size(); i++)
16491716
{
1650-
DebugSymbol* fixed = fixed_symbols[b][i];
1651-
DebugSymbol* dynamic_sym = (!IsValidPointer(fixed) && show_auto_symbols) ? dynamic_symbols[b][i] : NULL;
1717+
SymbolEntry& e = fixed_symbol_list[i];
16521718

1653-
DebugSymbol* symbol = IsValidPointer(fixed) ? fixed : dynamic_sym;
1719+
if (symbol_filter[0] != 0)
1720+
{
1721+
char addr_str[8];
1722+
snprintf(addr_str, sizeof(addr_str), "%04X", e.symbol->address);
16541723

1655-
if (IsValidPointer(symbol))
1724+
char filter_upper[64];
1725+
char text_upper[64];
1726+
for (int j = 0; j < 63 && symbol_filter[j]; j++) { filter_upper[j] = toupper(symbol_filter[j]); filter_upper[j + 1] = 0; }
1727+
for (int j = 0; j < 63 && e.symbol->text[j]; j++) { text_upper[j] = toupper(e.symbol->text[j]); text_upper[j + 1] = 0; }
1728+
1729+
if (strstr(text_upper, filter_upper) == NULL && strstr(addr_str, filter_upper) == NULL)
1730+
continue;
1731+
}
1732+
1733+
sorted_symbols.push_back(e);
1734+
}
1735+
1736+
if (show_auto_symbols)
1737+
{
1738+
for (size_t i = 0; i < dynamic_symbol_list.size(); i++)
16561739
{
1657-
bool is_manual = IsValidPointer(fixed);
1740+
SymbolEntry& e = dynamic_symbol_list[i];
16581741

1659-
ImGui::TableNextRow();
1742+
if (IsValidPointer(fixed_symbols[e.bank][e.symbol->address]))
1743+
continue;
16601744

1661-
ImGui::TableNextColumn();
1662-
ImGui::TextColored(cyan, "$%02X", b);
1745+
if (symbol_filter[0] != 0)
1746+
{
1747+
char addr_str[8];
1748+
snprintf(addr_str, sizeof(addr_str), "%04X", e.symbol->address);
16631749

1664-
ImGui::TableNextColumn();
1665-
ImGui::TextColored(cyan, "$%04X", symbol->address);
1750+
char filter_upper[64];
1751+
char text_upper[64];
1752+
for (int j = 0; j < 63 && symbol_filter[j]; j++) { filter_upper[j] = toupper(symbol_filter[j]); filter_upper[j + 1] = 0; }
1753+
for (int j = 0; j < 63 && e.symbol->text[j]; j++) { text_upper[j] = toupper(e.symbol->text[j]); text_upper[j + 1] = 0; }
16661754

1667-
ImGui::TableNextColumn();
1668-
ImGui::TextColored(is_manual ? green : yellow, "%s", symbol->text);
1755+
if (strstr(text_upper, filter_upper) == NULL && strstr(addr_str, filter_upper) == NULL)
1756+
continue;
1757+
}
16691758

1670-
ImGui::TableNextColumn();
1671-
if (is_manual)
1672-
ImGui::TextColored(orange, "Manual");
1673-
else
1674-
ImGui::TextColored(brown, "Auto");
1759+
sorted_symbols.push_back(e);
1760+
}
1761+
}
1762+
1763+
if (last_sort_column >= 0)
1764+
{
1765+
bool ascending = (last_sort_direction == ImGuiSortDirection_Ascending);
1766+
1767+
if (last_sort_column == 0)
1768+
{
1769+
std::sort(sorted_symbols.begin(), sorted_symbols.end(), ascending ? symbol_sort_address_asc : symbol_sort_address_desc);
1770+
}
1771+
else if (last_sort_column == 1)
1772+
{
1773+
std::sort(sorted_symbols.begin(), sorted_symbols.end(), ascending ? symbol_sort_addr_only_asc : symbol_sort_addr_only_desc);
1774+
}
1775+
else if (last_sort_column == 2)
1776+
{
1777+
std::sort(sorted_symbols.begin(), sorted_symbols.end(), ascending ? symbol_sort_name_asc : symbol_sort_name_desc);
16751778
}
16761779
}
16771780
}
16781781

1782+
ImGui::PushFont(gui_default_font);
1783+
1784+
ImGuiListClipper clipper;
1785+
clipper.Begin((int)sorted_symbols.size());
1786+
while (clipper.Step())
1787+
{
1788+
for (int idx = clipper.DisplayStart; idx < clipper.DisplayEnd; idx++)
1789+
{
1790+
DebugSymbol* symbol = sorted_symbols[idx].symbol;
1791+
bool is_manual = sorted_symbols[idx].is_manual;
1792+
int b = sorted_symbols[idx].bank;
1793+
1794+
ImGui::TableNextRow();
1795+
1796+
ImGui::TableNextColumn();
1797+
char selectable_id[16];
1798+
snprintf(selectable_id, sizeof(selectable_id), "##sym%d", (int)idx);
1799+
if (ImGui::Selectable(selectable_id, false, ImGuiSelectableFlags_SpanAllColumns))
1800+
{
1801+
request_goto_address(symbol->address);
1802+
}
1803+
ImGui::SameLine();
1804+
ImGui::TextColored(cyan, "$%02X", b);
1805+
1806+
ImGui::TableNextColumn();
1807+
ImGui::TextColored(cyan, "$%04X", symbol->address);
1808+
1809+
ImGui::TableNextColumn();
1810+
ImGui::TextColored(is_manual ? green : yellow, "%s", symbol->text);
1811+
1812+
ImGui::TableNextColumn();
1813+
if (is_manual)
1814+
ImGui::TextColored(orange, "Manual");
1815+
else
1816+
ImGui::TextColored(brown, "Auto");
1817+
}
1818+
}
1819+
16791820
ImGui::PopFont();
16801821

16811822
ImGui::EndTable();
@@ -1700,8 +1841,17 @@ void gui_debug_remove_symbol(u8 bank, u16 address)
17001841
DebugSymbol* symbol = fixed_symbols[bank][address];
17011842
if (IsValidPointer(symbol))
17021843
{
1844+
for (size_t i = 0; i < fixed_symbol_list.size(); i++)
1845+
{
1846+
if (fixed_symbol_list[i].symbol == symbol)
1847+
{
1848+
fixed_symbol_list.erase(fixed_symbol_list.begin() + i);
1849+
break;
1850+
}
1851+
}
17031852
delete symbol;
17041853
fixed_symbols[bank][address] = NULL;
1854+
symbols_dirty = true;
17051855
}
17061856
}
17071857
}
@@ -1859,3 +2009,41 @@ static void save_current_disassembler(FILE* file)
18592009
}
18602010
}
18612011
}
2012+
2013+
static bool symbol_sort_address_asc(const SymbolEntry& a, const SymbolEntry& b)
2014+
{
2015+
if (a.bank != b.bank)
2016+
return a.bank < b.bank;
2017+
return a.symbol->address < b.symbol->address;
2018+
}
2019+
2020+
static bool symbol_sort_address_desc(const SymbolEntry& a, const SymbolEntry& b)
2021+
{
2022+
if (a.bank != b.bank)
2023+
return a.bank > b.bank;
2024+
return a.symbol->address > b.symbol->address;
2025+
}
2026+
2027+
static bool symbol_sort_addr_only_asc(const SymbolEntry& a, const SymbolEntry& b)
2028+
{
2029+
if (a.symbol->address != b.symbol->address)
2030+
return a.symbol->address < b.symbol->address;
2031+
return a.bank < b.bank;
2032+
}
2033+
2034+
static bool symbol_sort_addr_only_desc(const SymbolEntry& a, const SymbolEntry& b)
2035+
{
2036+
if (a.symbol->address != b.symbol->address)
2037+
return a.symbol->address > b.symbol->address;
2038+
return a.bank > b.bank;
2039+
}
2040+
2041+
static bool symbol_sort_name_asc(const SymbolEntry& a, const SymbolEntry& b)
2042+
{
2043+
return strcmp(a.symbol->text, b.symbol->text) < 0;
2044+
}
2045+
2046+
static bool symbol_sort_name_desc(const SymbolEntry& a, const SymbolEntry& b)
2047+
{
2048+
return strcmp(a.symbol->text, b.symbol->text) > 0;
2049+
}

0 commit comments

Comments
 (0)