yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
music_editor.h
Go to the documentation of this file.
1#ifndef YAZE_APP_EDITOR_MUSIC_EDITOR_H
2#define YAZE_APP_EDITOR_MUSIC_EDITOR_H
3
4#include <chrono>
5#include <memory>
6#include <optional>
7#include <string>
8#include <unordered_map>
9
10#include "absl/status/statusor.h"
12#include "app/editor/editor.h"
14#include "rom/rom.h"
16#include "imgui/imgui.h"
27
28namespace yaze {
29
30// Forward declaration
31namespace emu {
32class Emulator;
33namespace audio {
34class IAudioBackend;
35struct AudioConfig;
36}
37}
38
39namespace project {
40struct YazeProject;
41}
42
43namespace editor {
44
45// TODO(user): Remove this when MusicBank provides song names
46static const char* kGameSongs[] = {"Title",
47 "Light World",
48 "Beginning",
49 "Rabbit",
50 "Forest",
51 "Intro",
52 "Town",
53 "Warp",
54 "Dark world",
55 "Master sword",
56 "File select",
57 "Soldier",
58 "Mountain",
59 "Shop",
60 "Fanfare",
61 "Castle",
62 "Palace (Pendant)",
63 "Cave (Same as Secret Way)",
64 "Clear (Dungeon end)",
65 "Church",
66 "Boss",
67 "Dungeon (Crystal)",
68 "Psychic",
69 "Secret Way (Same as Cave)",
70 "Rescue",
71 "Crystal",
72 "Fountain",
73 "Pyramid",
74 "Kill Agahnim",
75 "Ganon Room",
76 "Last Boss"};
77
78static constexpr absl::string_view kSongNotes[] = {
79 "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C",
80 "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C"};
81
82const ImGuiTableFlags toolset_table_flags_ = ImGuiTableFlags_SizingFixedFit;
83const ImGuiTableFlags music_editor_flags_ = ImGuiTableFlags_SizingFixedFit |
84 ImGuiTableFlags_Resizable |
85 ImGuiTableFlags_Reorderable;
90class MusicEditor : public Editor {
91 public:
92 explicit MusicEditor(Rom* rom = nullptr) : rom_(rom) {
94 }
95
96 void SetDependencies(const EditorDependencies& deps) override;
97
98 void Initialize() override;
99 absl::Status Load() override;
100 absl::Status Save() override;
101 absl::Status Update() override;
102 absl::Status Cut() override;
103 absl::Status Copy() override;
104 absl::Status Paste() override;
105 absl::Status Undo() override;
106 absl::Status Redo() override;
107 absl::Status Find() override { return absl::UnimplementedError("Find"); }
108
109 // Set the ROM pointer
110 void set_rom(Rom* rom) { rom_ = rom; }
111
112 // Get the ROM pointer
113 Rom* rom() const { return rom_; }
114
115 // Emulator integration for live audio playback
117 emu::Emulator* emulator() const { return emulator_; }
118
119 void SetProject(project::YazeProject* project);
120
121 // Scoped editor actions (for ShortcutManager)
122 void TogglePlayPause();
123 void StopPlayback();
124 void SpeedUp(float delta = 0.1f);
125 void SlowDown(float delta = 0.1f);
126
127 // API for sub-views
128
129
130 // Song window management (like dungeon rooms)
131 void OpenSong(int song_index);
132 void FocusSong(int song_index);
133
134 private:
135 // UI Drawing Methods
136 void DrawSongTrackerWindow(int song_index);
137 void DrawPlaybackControl(); // Playback control panel
138 void DrawTrackerView(); // Legacy tracker view
139 void DrawPianoRollView();
141 void DrawSampleEditor();
142 void DrawSongBrowser();
143 void DrawToolset();
144 void DrawChannelOverview();
145 absl::StatusOr<bool> RestoreMusicState();
146 absl::Status PersistMusicState(const char* reason = nullptr);
147 void MarkMusicDirty();
148
149 // Playback Control
150 // Delegated to music_player_
151
153
154 // New Data Model
161
162 // Undo/Redo (delegates to undo_manager_ from Editor base class)
163 void PushUndoState();
164 void PushUndoState(int song_index);
165 void FinalizePendingUndo();
166 std::optional<zelda3::music::MusicSong> pending_undo_before_;
168
169 // Note: APU requires ROM memory, will be initialized when needed
170
171 // UI State
172 int current_song_index_ = 0; // Selected song in browser (UI selection)
176 std::vector<bool> channel_muted_ = std::vector<bool>(8, false);
177 std::vector<bool> channel_soloed_ = std::vector<bool>(8, false);
178 std::vector<std::string> song_names_;
179
180 // Accessors for UI Views
182 void set_current_channel(int channel) {
183 if (channel >= 0 && channel < 8) current_channel_index_ = channel;
184 }
185
186 ImGuiTableFlags music_editor_flags_ =
187 ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter |
188 ImGuiTableFlags_BordersV | ImGuiTableFlags_SizingFixedFit;
189
190 ImGuiTableFlags toolset_table_flags_ =
191 ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_BordersOuter |
192 ImGuiTableFlags_BordersV | ImGuiTableFlags_PadOuterX;
193
195 emu::Emulator* emulator_ = nullptr; // For live audio playback
197
198 // Single shared audio backend - owned here and shared with emulators
199 // This avoids the dual-backend bug where two SDL audio devices conflict
200 std::unique_ptr<emu::audio::IAudioBackend> audio_backend_;
204 bool music_dirty_ = false;
207 std::chrono::steady_clock::time_point last_music_persist_;
208
209 // Per-song tracker windows (like dungeon room cards)
210 ImVector<int> active_songs_; // Song indices that are currently open
211 std::unordered_map<int, std::shared_ptr<gui::PanelWindow>> song_cards_;
212 std::unordered_map<int, std::unique_ptr<editor::music::TrackerView>>
215 std::shared_ptr<gui::PanelWindow> card;
216 std::unique_ptr<editor::music::PianoRollView> view;
217 bool* visible_flag = nullptr;
218 };
219 std::unordered_map<int, SongPianoRollWindow> song_piano_rolls_;
220
221 // Docking class for song windows to dock together
222 ImGuiWindowClass song_window_class_;
223
224 void OpenSongPianoRoll(int song_index);
225
226 // ASM export/import
227 void ExportSongToAsm(int song_index);
228 void ImportSongFromAsm(int song_index);
229 bool ImportAsmBufferToSong(int song_index);
230 void DrawAsmPopups();
231
232 std::string asm_buffer_; // Buffer for ASM text
233 bool show_asm_export_popup_ = false; // Show export dialog
234 bool show_asm_import_popup_ = false; // Show import dialog
235 int asm_import_target_index_ = -1; // Song index for import target
236 std::string asm_import_error_; // Last ASM import error (UI)
237 // Segment seeking
238 void SeekToSegment(int segment_index);
239
240 std::unique_ptr<editor::music::MusicPlayer> music_player_;
241
242 // Note: EditorPanel instances are owned by PanelManager after registration
243};
244
245} // namespace editor
246} // namespace yaze
247
248#endif
The Rom class is used to load, save, and modify Rom data. This is a generic SNES ROM container and do...
Definition rom.h:28
Text editor for modifying assembly code.
Interface for editor classes.
Definition editor.h:236
EditorType type_
Definition editor.h:305
A class for editing music data in a Rom.
absl::Status Find() override
std::unordered_map< int, std::unique_ptr< editor::music::TrackerView > > song_trackers_
void FocusSong(int song_index)
std::unique_ptr< emu::audio::IAudioBackend > audio_backend_
ImVector< int > active_songs_
std::vector< bool > channel_soloed_
void SlowDown(float delta=0.1f)
void DrawSongTrackerWindow(int song_index)
emu::Emulator * emulator_
std::unordered_map< int, std::shared_ptr< gui::PanelWindow > > song_cards_
std::optional< zelda3::music::MusicSong > pending_undo_before_
absl::Status Paste() override
std::vector< bool > channel_muted_
zelda3::music::MusicBank music_bank_
std::unordered_map< int, SongPianoRollWindow > song_piano_rolls_
void SetProject(project::YazeProject *project)
void Initialize() override
void OpenSong(int song_index)
emu::Emulator * emulator() const
void ExportSongToAsm(int song_index)
editor::music::SampleEditorView sample_editor_view_
absl::Status Save() override
absl::Status Cut() override
void OpenSongPianoRoll(int song_index)
absl::Status Load() override
void SetDependencies(const EditorDependencies &deps) override
void ImportSongFromAsm(int song_index)
absl::StatusOr< bool > RestoreMusicState()
absl::Status Copy() override
void SpeedUp(float delta=0.1f)
absl::Status PersistMusicState(const char *reason=nullptr)
absl::Status Update() override
editor::music::InstrumentEditorView instrument_editor_view_
std::unique_ptr< editor::music::MusicPlayer > music_player_
void set_emulator(emu::Emulator *emulator)
ImGuiTableFlags music_editor_flags_
absl::Status Undo() override
absl::Status Redo() override
ImGuiTableFlags toolset_table_flags_
std::vector< std::string > song_names_
std::chrono::steady_clock::time_point last_music_persist_
void set_current_channel(int channel)
AssemblyEditor assembly_editor_
bool ImportAsmBufferToSong(int song_index)
project::YazeProject * project_
MusicEditor(Rom *rom=nullptr)
void SeekToSegment(int segment_index)
editor::music::TrackerView tracker_view_
editor::music::SongBrowserView song_browser_view_
editor::music::PianoRollView piano_roll_view_
ImGuiWindowClass song_window_class_
Editor for SNES instruments (ADSR, Gain, Samples).
UI component for displaying and editing music tracks as a piano roll.
UI component for browsing and managing songs.
UI component for displaying and editing music tracks.
A class for emulating and debugging SNES games.
Definition emulator.h:40
Abstract audio backend interface.
Manages the collection of songs, instruments, and samples from a ROM.
Definition music_bank.h:27
const ImGuiTableFlags music_editor_flags_
const ImGuiTableFlags toolset_table_flags_
Unified dependency container for all editor types.
Definition editor.h:163
std::unique_ptr< editor::music::PianoRollView > view
std::shared_ptr< gui::PanelWindow > card
Modern project structure with comprehensive settings consolidation.
Definition project.h:120