yaze 0.2.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
music_editor.cc
Go to the documentation of this file.
1#include "music_editor.h"
2
3#include "imgui/imgui.h"
4
5#include "absl/strings/str_format.h"
7#include "app/gui/icons.h"
8#include "app/gui/input.h"
9
10namespace yaze {
11namespace editor {
12
13absl::Status MusicEditor::Update() {
14 if (ImGui::BeginTable("MusicEditorColumns", 2, music_editor_flags_,
15 ImVec2(0, 0))) {
16 ImGui::TableSetupColumn("Assembly");
17 ImGui::TableSetupColumn("Composition");
18 ImGui::TableHeadersRow();
19 ImGui::TableNextRow();
20
21 ImGui::TableNextColumn();
22 assembly_editor_.InlineUpdate();
23
24 ImGui::TableNextColumn();
28
29 ImGui::EndTable();
30 }
31
32 return absl::OkStatus();
33}
34
36 if (ImGui::BeginTabBar("MyTabBar", ImGuiTabBarFlags_None)) {
37 for (int i = 1; i <= 8; ++i) {
38 if (ImGui::BeginTabItem(absl::StrFormat("%d", i).data())) {
40 ImGui::EndTabItem();
41 }
42 }
43 ImGui::EndTabBar();
44 }
45}
46
47static const int NUM_KEYS = 25;
48static bool keys[NUM_KEYS];
49
51 if (ImGuiID child_id = ImGui::GetID((void*)(intptr_t)9);
52 ImGui::BeginChild(child_id, ImVec2(0, 170), false)) {
53 const int NUM_LINES = 5;
54 const int LINE_THICKNESS = 2;
55 const int LINE_SPACING = 40;
56
57 // Get the draw list for the current window
58 ImDrawList* draw_list = ImGui::GetWindowDrawList();
59
60 // Draw the staff lines
61 ImVec2 canvas_p0 =
62 ImVec2(ImGui::GetCursorScreenPos().x, ImGui::GetCursorScreenPos().y);
63 ImVec2 canvas_p1 = ImVec2(canvas_p0.x + ImGui::GetContentRegionAvail().x,
64 canvas_p0.y + ImGui::GetContentRegionAvail().y);
65 draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(32, 32, 32, 255));
66 for (int i = 0; i < NUM_LINES; i++) {
67 auto line_start = ImVec2(canvas_p0.x, canvas_p0.y + i * LINE_SPACING);
68 auto line_end = ImVec2(canvas_p1.x + ImGui::GetContentRegionAvail().x,
69 canvas_p0.y + i * LINE_SPACING);
70 draw_list->AddLine(line_start, line_end, IM_COL32(200, 200, 200, 255),
71 LINE_THICKNESS);
72 }
73
74 // Draw the ledger lines
75 const int NUM_LEDGER_LINES = 3;
76 for (int i = -NUM_LEDGER_LINES; i <= NUM_LINES + NUM_LEDGER_LINES; i++) {
77 if (i % 2 == 0) continue; // skip every other line
78 auto line_start = ImVec2(canvas_p0.x, canvas_p0.y + i * LINE_SPACING / 2);
79 auto line_end = ImVec2(canvas_p1.x + ImGui::GetContentRegionAvail().x,
80 canvas_p0.y + i * LINE_SPACING / 2);
81 draw_list->AddLine(line_start, line_end, IM_COL32(150, 150, 150, 255),
82 LINE_THICKNESS);
83 }
84 }
85 ImGui::EndChild();
86}
87
89 // Render the piano roll
90 float key_width = ImGui::GetContentRegionAvail().x / NUM_KEYS;
91 float white_key_height = ImGui::GetContentRegionAvail().y * 0.8f;
92 float black_key_height = ImGui::GetContentRegionAvail().y * 0.5f;
93 ImGui::Text("Piano Roll");
94 ImGui::Separator();
95 ImDrawList* draw_list = ImGui::GetWindowDrawList();
96
97 // Draw the staff lines
98 ImVec2 canvas_p0 =
99 ImVec2(ImGui::GetCursorScreenPos().x, ImGui::GetCursorScreenPos().y);
100 ImVec2 canvas_p1 = ImVec2(canvas_p0.x + ImGui::GetContentRegionAvail().x,
101 canvas_p0.y + ImGui::GetContentRegionAvail().y);
102 draw_list->AddRectFilled(canvas_p0, canvas_p1, IM_COL32(200, 200, 200, 255));
103
104 ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4.f, 0.f));
105 ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 0.f);
106 for (int i = 0; i < NUM_KEYS; i++) {
107 // Calculate the position and size of the key
108 ImVec2 key_pos = ImVec2(i * key_width, 0.0f);
109 ImVec2 key_size;
110 ImVec4 key_color;
111 ImVec4 text_color;
112 if (i % 12 == 1 || i % 12 == 3 || i % 12 == 6 || i % 12 == 8 ||
113 i % 12 == 10) {
114 // This is a black key
115 key_size = ImVec2(key_width * 0.6f, black_key_height);
116 key_color = ImVec4(0, 0, 0, 255);
117 text_color = ImVec4(255, 255, 255, 255);
118 } else {
119 // This is a white key
120 key_size = ImVec2(key_width, white_key_height);
121 key_color = ImVec4(255, 255, 255, 255);
122 text_color = ImVec4(0, 0, 0, 255);
123 }
124
125 ImGui::PushID(i);
126 ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0.f, 0.f));
127 ImGui::PushStyleColor(ImGuiCol_Button, key_color);
128 ImGui::PushStyleColor(ImGuiCol_Text, text_color);
129 if (ImGui::Button(kSongNotes[i].data(), key_size)) {
130 keys[i] ^= 1;
131 }
132 ImGui::PopStyleColor();
133 ImGui::PopStyleColor();
134 ImGui::PopStyleVar();
135
136 ImVec2 button_pos = ImGui::GetItemRectMin();
137 ImVec2 button_size = ImGui::GetItemRectSize();
138 if (keys[i]) {
139 ImVec2 dest;
140 dest.x = button_pos.x + button_size.x;
141 dest.y = button_pos.y + button_size.y;
142 ImGui::GetWindowDrawList()->AddRectFilled(button_pos, dest,
143 IM_COL32(200, 200, 255, 200));
144 }
145 ImGui::PopID();
146 ImGui::SameLine();
147 }
148 ImGui::PopStyleVar();
149 ImGui::PopStyleVar();
150}
151
153 if (ImGui::BeginTable("DWToolset", 8, toolset_table_flags_, ImVec2(0, 0))) {
154 ImGui::TableSetupColumn("#1");
155 ImGui::TableSetupColumn("#play");
156 ImGui::TableSetupColumn("#rewind");
157 ImGui::TableSetupColumn("#fastforward");
158 ImGui::TableSetupColumn("volumeController");
159
160 ImGui::EndTable();
161 }
162}
163
165 static bool is_playing = false;
166 static int selected_option = 0;
167 static int current_volume = 0;
168 static bool has_loaded_song = false;
169 const int MAX_VOLUME = 100;
170
171 if (is_playing && !has_loaded_song) {
172 has_loaded_song = true;
173 }
174
175 gui::ItemLabel("Select a song to edit: ", gui::ItemLabelFlags::Left);
176 ImGui::Combo("#songs_in_game", &selected_option, kGameSongs, 30);
177
178 gui::ItemLabel("Controls: ", gui::ItemLabelFlags::Left);
179 if (ImGui::BeginTable("SongToolset", 6, toolset_table_flags_, ImVec2(0, 0))) {
180 ImGui::TableSetupColumn("#play");
181 ImGui::TableSetupColumn("#rewind");
182 ImGui::TableSetupColumn("#fastforward");
183 ImGui::TableSetupColumn("#volume");
184 ImGui::TableSetupColumn("#debug");
185
186 ImGui::TableSetupColumn("#slider");
187
188 ImGui::TableNextColumn();
189 if (ImGui::Button(is_playing ? ICON_MD_STOP : ICON_MD_PLAY_ARROW)) {
190 if (is_playing) {
191 has_loaded_song = false;
192 }
193 is_playing = !is_playing;
194 }
195
199 if (ImGui::Button(ICON_MD_ACCESS_TIME)) {
200 music_tracker_.LoadSongs(*rom());
201 }
202 ImGui::TableNextColumn();
203 ImGui::SliderInt("Volume", &current_volume, 0, 100);
204 ImGui::EndTable();
205 }
206
207 const int SONG_DURATION = 120; // duration of the song in seconds
208 static int current_time = 0; // current time in the song in seconds
209
210 // Display the current time in the song
211 gui::ItemLabel("Current Time: ", gui::ItemLabelFlags::Left);
212 ImGui::Text("%d:%02d", current_time / 60, current_time % 60);
213 ImGui::SameLine();
214 // Display the song duration/progress using a progress bar
215 ImGui::ProgressBar((float)current_time / SONG_DURATION);
216}
217
218} // namespace editor
219} // namespace yaze
auto rom()
Definition rom.h:383
zelda3::music::Tracker music_tracker_
absl::Status Update() override
AssemblyEditor assembly_editor_
#define ICON_MD_VOLUME_UP
Definition icons.h:2106
#define ICON_MD_FAST_FORWARD
Definition icons.h:722
#define ICON_MD_PLAY_ARROW
Definition icons.h:1477
#define ICON_MD_STOP
Definition icons.h:1857
#define ICON_MD_FAST_REWIND
Definition icons.h:723
#define ICON_MD_ACCESS_TIME
Definition icons.h:71
#define BUTTON_COLUMN(w)
Definition macro.h:12
Editors are the view controllers for the application.
const ImGuiTableFlags music_editor_flags_
const ImGuiTableFlags toolset_table_flags_
void ItemLabel(absl::string_view title, ItemLabelFlags flags)
Definition input.cc:187
Main namespace for the application.
Definition controller.cc:18