openMSX
ImGuiCheatFinder.cc
Go to the documentation of this file.
1#include "ImGuiCheatFinder.hh"
2
3#include "ImGuiCpp.hh"
4#include "ImGuiManager.hh"
5#include "ImGuiUtils.hh"
6
7#include "narrow.hh"
8#include "stl.hh"
9#include "view.hh"
10
11namespace openmsx {
12
13using namespace std::literals;
14
16{
17 if (!show) return;
18
19 bool start = false;
20 std::string searchExpr;
21
22 ImGui::SetNextWindowSize(gl::vec2{35, 0} * ImGui::GetFontSize(), ImGuiCond_FirstUseEver);
23 im::Window("Cheat Finder", &show, [&]{
24 const auto& style = ImGui::GetStyle();
25 auto tSize = ImGui::CalcTextSize("=="sv).x + 2.0f * style.FramePadding.x;
26 auto bSpacing = 2.0f;
27 auto height = 12.5f * ImGui::GetTextLineHeightWithSpacing();
28 auto sWidth = 2.0f * (style.WindowBorderSize + style.WindowPadding.x)
29 + style.IndentSpacing + 6 * tSize + 5 * bSpacing;
30 im::Child("search", {sWidth, height}, ImGuiChildFlags_Border, [&]{
31 ImGui::TextUnformatted("Search"sv);
32 HelpMarker("OpenMSX cheat finder. See here for a quick tutorial:\n"
33 " openMSX tutorial: Working with the Cheat Finder\n"
34 " http://www.youtube.com/watch?v=F11ltfkCtKo\n"
35 "The UI has changed, but the ideas remain the same.");
36 im::Disabled(searchResults.empty(), [&]{
37 ImGui::TextUnformatted("Compare"sv);
38 im::Indent([&]{
39 auto bSize = ImVec2{tSize, 0.0f};
40 if (ImGui::Button("<", bSize)) searchExpr = "$new < $old";
41 simpleToolTip("Search for memory locations with strictly decreased value");
42 ImGui::SameLine(0.0f, bSpacing);
43 if (ImGui::Button("<=", bSize)) searchExpr = "$new <= $old";
44 simpleToolTip("Search for memory locations with decreased value");
45 ImGui::SameLine(0.0f, bSpacing);
46 if (ImGui::Button("!=", bSize)) searchExpr = "$new != $old";
47 simpleToolTip("Search for memory locations with changed value");
48 ImGui::SameLine(0.0f, bSpacing);
49 if (ImGui::Button("==", bSize)) searchExpr = "$new == $old";
50 simpleToolTip("Search for memory locations with unchanged value");
51 ImGui::SameLine(0.0f, bSpacing);
52 if (ImGui::Button(">=", bSize)) searchExpr = "$new >= $old";
53 simpleToolTip("Search for memory locations with increased value");
54 ImGui::SameLine(0.0f, bSpacing);
55 if (ImGui::Button(">", bSize)) searchExpr = "$new > $old";
56 simpleToolTip("Search for memory locations with strictly increased value");
57 });
58 ImGui::TextUnformatted("Specific value"sv);
59 im::Indent([&]{
60 ImGui::SetNextItemWidth(3 * ImGui::GetFontSize());
61 ImGui::InputScalar("##value", ImGuiDataType_U8, &searchValue);
62 ImGui::SameLine();
63 if (ImGui::Button("Go")) {
64 searchExpr = strCat("$new == ", searchValue);
65 }
66 simpleToolTip("Search for memory locations with a specific value");
67 });
68 });
69 start |= ImGui::Button("Restart search");
70 });
71
72 ImGui::SameLine();
73 im::Child("result", {0.0f, height}, ImGuiChildFlags_Border, [&]{
74 auto num = searchResults.size();
75 if (num == 0) {
76 ImGui::TextUnformatted("Results: no remaining locations"sv);
77 start |= ImGui::Button("Start a new search");
78 } else {
79 if (num == 1) {
80 ImGui::TextUnformatted("Results: 1 remaining location"sv);
81 } else {
82 ImGui::Text("Results: %d remaining locations", narrow<int>(num));
83 }
84 int flags = ImGuiTableFlags_RowBg |
85 ImGuiTableFlags_BordersV |
86 ImGuiTableFlags_BordersOuter |
87 ImGuiTableFlags_ScrollY;
88 im::Table("##table", 3, flags, [&]{
89 ImGui::TableSetupScrollFreeze(0, 1); // Make top row always visible
90 ImGui::TableSetupColumn("Address");
91 ImGui::TableSetupColumn("Previous");
92 ImGui::TableSetupColumn("New value");
93 ImGui::TableHeadersRow();
94
95 for (const auto& row : searchResults) {
96 if (ImGui::TableNextColumn()) { // addr
97 ImGui::Text("0x%04x", row.address);
98 }
99 if (ImGui::TableNextColumn()) { // old
100 ImGui::Text("%d", row.oldValue);
101 }
102 if (ImGui::TableNextColumn()) { // new
103 ImGui::Text("%d", row.newValue);
104 }
105 }
106 });
107 }
108 });
109 });
110
111 if (start) {
112 manager.execute(TclObject("cheat_finder::start"));
113 searchExpr = "1"; // could be optimized, but good enough
114 }
115 if (!searchExpr.empty()) {
116 auto result = manager.execute(makeTclList("cheat_finder::search", searchExpr)).value_or(TclObject{});
117 searchResults = to_vector(view::transform(xrange(result.size()), [&](size_t i) {
118 auto line = result.getListIndexUnchecked(narrow<unsigned>(i));
119 auto addr = line.getListIndexUnchecked(0).getOptionalInt().value_or(0);
120 auto oldValue = line.getListIndexUnchecked(1).getOptionalInt().value_or(0);
121 auto newValue = line.getListIndexUnchecked(2).getOptionalInt().value_or(0);
122 return SearchResult{narrow_cast<uint16_t>(addr),
123 narrow_cast<uint8_t>(oldValue),
124 narrow_cast<uint8_t>(newValue)};
125 }));
126 }
127}
128
129} // namespace openmsx
void paint(MSXMotherBoard *motherBoard) override
auto CalcTextSize(std::string_view str)
Definition ImGuiUtils.hh:37
void TextUnformatted(const std::string &str)
Definition ImGuiUtils.hh:24
void Table(const char *str_id, int column, ImGuiTableFlags flags, const ImVec2 &outer_size, float inner_width, std::invocable<> auto next)
Definition ImGuiCpp.hh:459
void Window(const char *name, bool *p_open, ImGuiWindowFlags flags, std::invocable<> auto next)
Definition ImGuiCpp.hh:63
void Child(const char *str_id, const ImVec2 &size, ImGuiChildFlags child_flags, ImGuiWindowFlags window_flags, std::invocable<> auto next)
Definition ImGuiCpp.hh:110
void Disabled(bool b, std::invocable<> auto next)
Definition ImGuiCpp.hh:510
void Indent(float indent_w, std::invocable<> auto next)
Definition ImGuiCpp.hh:224
This file implemented 3 utility functions:
Definition Autofire.cc:11
void simpleToolTip(std::string_view desc)
Definition ImGuiUtils.hh:66
void HelpMarker(std::string_view desc)
Definition ImGuiUtils.cc:23
TclObject makeTclList(Args &&... args)
Definition TclObject.hh:293
constexpr auto transform(Range &&range, UnaryOp op)
Definition view.hh:520
auto to_vector(Range &&range) -> std::vector< detail::ToVectorType< T, decltype(std::begin(range))> >
Definition stl.hh:275
std::string strCat()
Definition strCat.hh:703
constexpr auto xrange(T e)
Definition xrange.hh:132