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 <string>
7#include <unordered_map>
8
9#include "absl/status/statusor.h"
11#include "app/editor/editor.h"
13#include "rom/rom.h"
15#include "imgui/imgui.h"
26
27namespace yaze {
28
29// Forward declaration
30namespace emu {
31class Emulator;
32namespace audio {
33class IAudioBackend;
34struct AudioConfig;
35}
36}
37
38namespace project {
39struct YazeProject;
40}
41
42namespace editor {
43
44// TODO(user): Remove this when MusicBank provides song names
45static const char* kGameSongs[] = {"Title",
46 "Light World",
47 "Beginning",
48 "Rabbit",
49 "Forest",
50 "Intro",
51 "Town",
52 "Warp",
53 "Dark world",
54 "Master sword",
55 "File select",
56 "Soldier",
57 "Mountain",
58 "Shop",
59 "Fanfare",
60 "Castle",
61 "Palace (Pendant)",
62 "Cave (Same as Secret Way)",
63 "Clear (Dungeon end)",
64 "Church",
65 "Boss",
66 "Dungeon (Crystal)",
67 "Psychic",
68 "Secret Way (Same as Cave)",
69 "Rescue",
70 "Crystal",
71 "Fountain",
72 "Pyramid",
73 "Kill Agahnim",
74 "Ganon Room",
75 "Last Boss"};
76
77static constexpr absl::string_view kSongNotes[] = {
78 "C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C",
79 "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B", "C"};
80
81const ImGuiTableFlags toolset_table_flags_ = ImGuiTableFlags_SizingFixedFit;
82const ImGuiTableFlags music_editor_flags_ = ImGuiTableFlags_SizingFixedFit |
83 ImGuiTableFlags_Resizable |
84 ImGuiTableFlags_Reorderable;
89class MusicEditor : public Editor {
90 public:
91 explicit MusicEditor(Rom* rom = nullptr) : rom_(rom) {
93 }
94
95 void Initialize() override;
96 absl::Status Load() override;
97 absl::Status Save() override;
98 absl::Status Update() override;
99 absl::Status Cut() override;
100 absl::Status Copy() override;
101 absl::Status Paste() override;
102 absl::Status Undo() override;
103 absl::Status Redo() override;
104 absl::Status Find() override { return absl::UnimplementedError("Find"); }
105
106 // Set the ROM pointer
107 void set_rom(Rom* rom) { rom_ = rom; }
108
109 // Get the ROM pointer
110 Rom* rom() const { return rom_; }
111
112 // Emulator integration for live audio playback
114 emu::Emulator* emulator() const { return emulator_; }
115
116 void SetProject(project::YazeProject* project);
117
118 // Scoped editor actions (for ShortcutManager)
119 void TogglePlayPause();
120 void StopPlayback();
121 void SpeedUp(float delta = 0.1f);
122 void SlowDown(float delta = 0.1f);
123
124 // API for sub-views
125
126
127 // Song window management (like dungeon rooms)
128 void OpenSong(int song_index);
129 void FocusSong(int song_index);
130
131 private:
132 // UI Drawing Methods
133 void DrawSongTrackerWindow(int song_index);
134 void DrawPlaybackControl(); // Playback control panel
135 void DrawTrackerView(); // Legacy tracker view
136 void DrawPianoRollView();
138 void DrawSampleEditor();
139 void DrawSongBrowser();
140 void DrawToolset();
141 void DrawChannelOverview();
142 absl::StatusOr<bool> RestoreMusicState();
143 absl::Status PersistMusicState(const char* reason = nullptr);
144 void MarkMusicDirty();
145
146 // Playback Control
147 // Delegated to music_player_
148
150
151 // New Data Model
158
159 // Undo/Redo
164 std::vector<UndoState> undo_stack_;
165 std::vector<UndoState> redo_stack_;
166
167 void PushUndoState();
168 void RestoreState(const UndoState& state);
169
170 // Note: APU requires ROM memory, will be initialized when needed
171
172 // UI State
173 int current_song_index_ = 0; // Selected song in browser (UI selection)
177 std::vector<bool> channel_muted_ = std::vector<bool>(8, false);
178 std::vector<bool> channel_soloed_ = std::vector<bool>(8, false);
179 std::vector<std::string> song_names_;
180
181 // Accessors for UI Views
183 void set_current_channel(int channel) {
184 if (channel >= 0 && channel < 8) current_channel_index_ = channel;
185 }
186
187 ImGuiTableFlags music_editor_flags_ =
188 ImGuiTableFlags_Resizable | ImGuiTableFlags_BordersOuter |
189 ImGuiTableFlags_BordersV | ImGuiTableFlags_SizingFixedFit;
190
191 ImGuiTableFlags toolset_table_flags_ =
192 ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_BordersOuter |
193 ImGuiTableFlags_BordersV | ImGuiTableFlags_PadOuterX;
194
196 emu::Emulator* emulator_ = nullptr; // For live audio playback
198
199 // Single shared audio backend - owned here and shared with emulators
200 // This avoids the dual-backend bug where two SDL audio devices conflict
201 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:24
Text editor for modifying assembly code.
Interface for editor classes.
Definition editor.h:179
EditorType type_
Definition editor.h:236
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_
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
std::vector< UndoState > undo_stack_
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 RestoreState(const UndoState &state)
void ImportSongFromAsm(int song_index)
absl::StatusOr< bool > RestoreMusicState()
absl::Status Copy() override
std::vector< UndoState > redo_stack_
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:39
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_
std::unique_ptr< editor::music::PianoRollView > view
std::shared_ptr< gui::PanelWindow > card
zelda3::music::MusicSong song_snapshot
Modern project structure with comprehensive settings consolidation.
Definition project.h:84
A complete song composed of segments.
Definition song_data.h:334