OXYGENHUB
◆ main openmsx / src / imgui / ImGuiTraceViewer.hh
5.0 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef IMGUI_TRACE_VIEWER_HH
2
#define IMGUI_TRACE_VIEWER_HH
3
4
#include "ImGuiPart.hh"
5
6
#include "EmuDuration.hh"
7
#include "EmuTime.hh"
8
#include "Tracer.hh"
9
10
#include "gl_vec.hh"
11
12
namespace openmsx {
13
14
struct Convertor;
15
16
class TimelineFormatter
17
{
18
public:
19
	// A timeline label with its position and formatted text
20
	struct Label {
21
		double value;     // Numeric position (e.g., timestamp)
22
		std::string text; // Formatted label text (e.g., "1.23e+06" or "12.345")
23
	};
24
25
	std::pair<const std::vector<Label>&, double> calc(double from, double to, double numLabels, double unitFactor);
26
27
private:
28
	struct Params {
29
		double from = 0.0;
30
		double to = 0.0;
31
		double numLabels = 0.0;
32
		double unitFactor = 1.0;
33
		bool operator==(const Params&) const = default;
34
	} prevParams;
35
36
	std::vector<Label> labels;
37
	double step;
38
};
39
40
class ImGuiTraceViewer final : public ImGuiPart
41
{
42
public:
43
	explicit ImGuiTraceViewer(ImGuiManager& manager);
44
45
	[[nodiscard]] zstring_view iniName() const override { return "Probe/Trace Viewer"; }
46
	void save(ImGuiTextBuffer& buf) override;
47
	void loadLine(std::string_view name, zstring_view value) override;
48
	void paint(MSXMotherBoard* motherBoard) override;
49
50
	[[nodiscard]] const std::vector<Tracer::Trace*>& getTraces(MSXMotherBoard& motherBoard);
51
	[[nodiscard]] EmuTime getMarker(int i) const { return i ? selectedTime2 : selectedTime1; }
52
	void setMarker(int i, EmuTime t) { (i ? selectedTime2 : selectedTime1) = t; }
53
	[[nodiscard]] static std::string_view formatTraceValue(const TraceValue& value, std::span<char, 64> tmpBuf,
54
	                                                       Tracer::Trace::Format format);
55
56
public:
57
	bool show = false;
58
	bool showSelect = false;
59
60
private:
61
	void calcTraces(Tracer& tracer);
62
	[[nodiscard]] double getUnitConversionFactor() const;
63
64
	void zoomToFit(EmuTime minT, EmuDuration totalT);
65
	void doZoom(double factor, double xFract);
66
	void scrollTo(EmuTime time);
67
	void gotoPrevPosEdge(EmuTime& selectedTime);
68
	void gotoPrevNegEdge(EmuTime& selectedTime);
69
	void gotoPrevEdge   (EmuTime& selectedTime);
70
	void gotoNextEdge   (EmuTime& selectedTime);
71
	void gotoNextPosEdge(EmuTime& selectedTime);
72
	void gotoNextNegEdge(EmuTime& selectedTime);
73
74
	void drawMenuBar(EmuTime minT, EmuDuration totalT, Tracer& tracer);
75
	void drawToolBar(EmuTime minT, EmuDuration totalT, float graphWidth);
76
	void drawNames(float rulerHeight, float rowHeight, int mouseRow);
77
	void drawSplitter(float width);
78
	void drawRuler(gl::vec2 size, const Convertor& convertor, EmuTime from, EmuTime to, EmuTime now);
79
	void drawGraphs(float rulerHeight, float rowHeight, int mouseRow, const Convertor& convertor,
80
	                EmuTime minT, EmuTime maxT, EmuTime now, MSXMotherBoard& motherBoard);
81
82
	void paintMain(MSXMotherBoard& motherBoard);
83
	void paintSelect(MSXMotherBoard& motherBoard);
84
	void paintHelp();
85
86
private:
87
	std::vector<Tracer::Trace*> traces; // recalculated each frame, but can be queried by ImGuiRasterViewer
88
	TimelineFormatter timelineFormatter;
89
	EmuTime viewStartTime = EmuTime::zero();
90
	EmuDuration viewDuration = EmuDuration::sec(4.0);
91
	EmuTime selectedTime1 = EmuTime::zero();
92
	EmuTime selectedTime2 = EmuTime::zero();
93
	float col0_width = 100.0f; // TODO
94
	float scrollY = 0.0f;
95
	int selectedRow = 1;
96
97
	float prevNowX = -1.0f; // X-position of 'now' on timeline in previous frame (negative: was not visible)
98
	bool scrollChanged = false; // was scroll position or zoom changed previous frame
99
	bool followNow = true; // should we follow the current time in the timeline
100
101
	std::string ctxInputPos = "0";
102
	float ctxMouseX = 0.0f;
103
	int ctxMouseRow = 0;
104
105
	enum Units : int {
106
		SECONDS,
107
		MILLI_SECONDS,
108
		MICRO_SECONDS,
109
		CYCLES,
110
		PAL,
111
		NTSC,
112
		NUM_UNITS // must be last
113
	};
114
	int units = Units::SECONDS;
115
116
	struct SelectedTrace {
117
		std::string name;
118
		bool selected = false; // always true for probes
119
	};
120
	std::vector<SelectedTrace> selectedTraces;
121
	bool allUserTraces = true;
122
123
	enum Origin : int {
124
		ZERO,
125
		PRIMARY,
126
		SECONDARY,
127
		NOW,
128
		NUM_ORIGIN // must be last
129
	};
130
	int timelineOrigin = Origin::ZERO;
131
	bool timelineStart = false;
132
	bool timelineStop = false;
133
134
	bool showMenuBar = true;
135
136
	enum class HelpSection : uint8_t{
137
		OVERVIEW,
138
		PROBES_AND_TRACES,
139
		GRAPHS,
140
		NAVIGATION,
141
		EXAMPLE,
142
	};
143
	std::optional<HelpSection> helpSection;
144
	bool showHelp = false;
145
146
	static constexpr auto persistentElements = std::tuple{
147
		PersistentElement   {"show",             &ImGuiTraceViewer::show},
148
		PersistentElement   {"showSelect",       &ImGuiTraceViewer::showSelect},
149
		PersistentElement   {"showMenuBar",      &ImGuiTraceViewer::showMenuBar},
150
		PersistentElementMax{"units",            &ImGuiTraceViewer::units, Units::NUM_UNITS},
151
		PersistentElement   {"allUserTraces",    &ImGuiTraceViewer::allUserTraces},
152
		PersistentElementMax{"timelineOrigin",   &ImGuiTraceViewer::timelineOrigin, Origin::NUM_ORIGIN},
153
		PersistentElement   {"timelineStart",    &ImGuiTraceViewer::timelineStart},
154
		PersistentElement   {"timelineStop",     &ImGuiTraceViewer::timelineStop},
155
		PersistentElement   {"followNow",        &ImGuiTraceViewer::followNow},
156
	};
157
};
158
159
} // namespace openmsx
160
161
#endif