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