OXYGENHUB
◆ main openmsx / src / imgui / ImGuiMedia.hh
6.8 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
e8555c89 Andy McCall 1
#ifndef IMGUI_MEDIA_HH
2
#define IMGUI_MEDIA_HH
3
4
#include "ImGuiPart.hh"
5
6
#include "CartridgeSlotManager.hh"
7
#include "HD.hh"
8
#include "IDECDROM.hh"
9
#include "RealDrive.hh"
10
#include "RomTypes.hh"
11
#include "TclObject.hh"
12
13
#include "circular_buffer.hh"
14
#include "function_ref.hh"
15
#include "stl.hh"
16
#include "zstring_view.hh"
17
18
#include <array>
19
#include <functional>
20
#include <string>
21
#include <vector>
22
23
namespace openmsx {
24
25
class CassettePlayer;
26
class HardwareConfig;
27
class RomInfo;
28
29
class ImGuiMedia final : public ImGuiPart
30
{
31
public:
32
	struct ExtensionInfo {
33
		std::string configName;
34
		std::string displayName;
35
		std::vector<std::pair<std::string, std::string>> configInfo;
36
		std::optional<std::string> testResult; // lazily initialized
37
	};
38
39
public:
40
	using ImGuiPart::ImGuiPart;
41
42
	[[nodiscard]] zstring_view iniName() const override { return "media"; }
43
	void save(ImGuiTextBuffer& buf) override;
44
	void loadLine(std::string_view name, zstring_view value) override;
45
	void showMenu(MSXMotherBoard* motherBoard) override;
46
	void paint(MSXMotherBoard* motherBoard) override;
47
48
	[[nodiscard]] std::string displayNameForExtension(std::string_view config);
49
	[[nodiscard]] std::string displayNameForRom(const std::string& filename, bool compact = false);
50
	[[nodiscard]] std::string displayNameForHardwareConfig(const HardwareConfig& config, bool compact = false);
51
	[[nodiscard]] std::string displayNameForSlotContent(const CartridgeSlotManager& slotManager, unsigned slotNr, bool compact = false);
52
	[[nodiscard]] std::string slotAndNameForHardwareConfig(const CartridgeSlotManager& slotManager, const HardwareConfig& config);
53
	[[nodiscard]] std::string displayNameForDriveContent(unsigned drive, bool compact = false);
54
55
	std::vector<ExtensionInfo>& getAllExtensions();
56
	void resetExtensionInfo();
57
	ExtensionInfo* findExtensionInfo(std::string_view config);
58
	void extensionTooltip(ExtensionInfo& info);
59
	[[nodiscard]] const std::string& getTestResult(ExtensionInfo& info);
60
61
	void addRecent(const TclObject& cmd);
62
63
	static void printRomInfo(ImGuiManager& manager, const TclObject& mediaTopic, std::string_view filename, RomType romType);
64
65
	void paintLaserDiscMenuContent(std::string_view mediaSlotName, std::string_view slotDisplayName, const TclObject& currentImage);
66
	void paintCDROMMenuContent(std::string_view mediaSlotName, std::string_view slotDisplayName, const TclObject& currentImage);
67
	void paintHardDiskMenuContent(std::string_view mediaSlotName, std::string_view slotDisplayName, const TclObject& currentImage, const MSXMotherBoard& motherBoard);
68
69
public:
70
	enum class SelectDiskType : int {
71
		IMAGE, DIR_AS_DISK, RAMDISK, EMPTY,
72
		NUM
73
	};
74
	enum class SelectCartridgeType : int {
75
		IMAGE, EXTENSION, EMPTY,
76
		NUM
77
	};
78
79
	struct MediaItem {
80
		std::string name;
81
		std::vector<std::string> ipsPatches; // only used for disk and rom images
82
		RomType romType = RomType::UNKNOWN; // only used for rom images
83
84
		[[nodiscard]] bool isEject() const { return romType == RomType::NUM; } // hack
85
		[[nodiscard]] bool operator==(const MediaItem&) const = default;
86
	};
87
88
	struct ItemGroup { // MediaItem + history
89
		static constexpr size_t HISTORY_SIZE = 8;
90
91
		MediaItem edit;
92
		int patchIndex = -1; // only used for IPSItem
93
		circular_buffer<MediaItem> recent{HISTORY_SIZE};
94
	};
95
96
	struct CartridgeMediaInfo {
97
		CartridgeMediaInfo() {
98
			groups[SelectCartridgeType::EMPTY].edit.romType = RomType::NUM; // hack: indicates "eject"
99
		}
100
		array_with_enum_index<SelectCartridgeType, ItemGroup> groups;
101
		SelectCartridgeType select = SelectCartridgeType::IMAGE;
102
		bool show = false;
103
		bool filterOpen = false;
104
		std::string filterType;
105
		std::string filterString;
106
	};
107
	struct DiskMediaInfo {
108
		DiskMediaInfo() {
109
			groups[SelectDiskType::RAMDISK].edit.name = "ramdsk";
110
			groups[SelectDiskType::EMPTY].edit.romType = RomType::NUM; // hack: indicates "eject"
111
		}
112
		array_with_enum_index<SelectDiskType, ItemGroup> groups;
113
		SelectDiskType select = SelectDiskType::IMAGE;
114
		bool show = false;
115
	};
116
	struct CassetteMediaInfo {
117
		ItemGroup group;
118
		bool show = false;
119
	};
120
121
public:
122
	bool resetOnCartChanges = true;
123
124
	bool showExtensionSelector(int cartNum, std::optional<std::string> itemToShowAsSelected = std::nullopt);
125
126
	static void printDatabase(const RomInfo& romInfo, const char* buf);
127
	static bool selectMapperType(const char* label, RomType& romType);
128
129
	static std::string diskFilter();
130
131
	void showMediaWindow(std::string_view mediaName);
132
133
private:
134
	bool selectRecent(ItemGroup& group, function_ref<std::string(const std::string&)> displayFunc, float width) const;
135
	bool selectImage(ItemGroup& group, const std::string& title,
136
	                 function_ref<std::string()> createFilter, zstring_view current,
137
	                 function_ref<std::string(const std::string&)> displayFunc = std::identity{},
138
	                 const std::function<void()>& createNewCallback = {});
139
	bool selectDirectory(ItemGroup& group, const std::string& title, zstring_view current,
140
	                     const std::function<void()>& createNewCallback);
141
	bool selectPatches(MediaItem& item, int& patchIndex);
142
	bool insertMediaButton(std::string_view mediaName, const ItemGroup& group, bool* showWindow);
143
	TclObject showDiskInfo(std::string_view mediaName, DiskMediaInfo& info);
144
	TclObject showCartridgeInfo(std::string_view mediaName, CartridgeMediaInfo& info, int slot);
145
	void diskMenu(int i);
146
	void cartridgeMenu(int cartNum);
147
	void cassetteMenu(CassettePlayer& cassettePlayer);
148
	void insertMedia(std::string_view mediaName, const MediaItem& item, bool delayed = true);
149
	void paintCurrent(const TclObject& current, std::string_view type);
150
	void paintRecent(std::string_view mediaName, ItemGroup& group,
151
		function_ref<std::string(const std::string&)> displayFunc = std::identity{},
152
		const std::function<void(const std::string&)>& toolTip = {},
153
		std::function<void()>* actionToSet = nullptr);
154
155
	void printExtensionInfo(ExtensionInfo& info);
156
	bool drawExtensionFilter(std::string& filterType, std::string& filterString, bool& theFilterOpen, int id = 0);
157
158
private:
159
	std::array<DiskMediaInfo, RealDrive::MAX_DRIVES> diskMediaInfo;
160
	std::array<CartridgeMediaInfo, CartridgeSlotManager::MAX_SLOTS> cartridgeMediaInfo;
161
	ItemGroup extensionMediaInfo;
162
	CassetteMediaInfo cassetteMediaInfo;
163
	std::array<ItemGroup, HD::MAX_HD> hdMediaInfo;
164
	std::array<ItemGroup, IDECDROM::MAX_CD> cdMediaInfo;
165
	ItemGroup laserdiscMediaInfo;
166
167
	// for the generic extension selector (slot independent)
168
	std::string genericFilterType;
169
	std::string genericFilterString;
170
	bool genericFilterOpen = false;
171
	bool hideNonWorking = false;
172
	std::function<void(void)> switchHdAction;
173
174
	std::vector<ExtensionInfo> extensionInfo;
175
176
	static constexpr auto persistentElements = std::tuple{
177
		PersistentElement{"resetOnCartChanges", &ImGuiMedia::resetOnCartChanges},
178
		PersistentElement{"hideNonWorkingExtensions", &ImGuiMedia::hideNonWorking},
179
		// most media stuff is handled elsewhere
180
	};
181
};
182
183
} // namespace openmsx
184
185
#endif