yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
music_bank.h
Go to the documentation of this file.
1#ifndef YAZE_ZELDA3_MUSIC_MUSIC_BANK_H
2#define YAZE_ZELDA3_MUSIC_MUSIC_BANK_H
3
4#include <cstdint>
5#include <string>
6#include <vector>
7
8#include "absl/status/status.h"
9#include "absl/status/statusor.h"
10#include "rom/rom.h"
11#include "nlohmann/json.hpp"
13
14namespace yaze {
15namespace zelda3 {
16namespace music {
17
27class MusicBank {
28 public:
29 // Bank identifiers
30 enum class Bank : uint8_t {
31 Overworld = 0,
32 Dungeon = 1,
33 Credits = 2,
34 OverworldExpanded = 3, // Oracle of Secrets expanded dark world bank
35 Auxiliary = 4 // SONG_POINTERS_AUX bank at $2B00
36 };
37
38 // Space usage information
39 struct SpaceInfo {
44 bool is_warning = false; // >75% usage
45 bool is_critical = false; // >90% usage
46 std::string recommendation;
47 };
48
49 // Expanded bank detection info (Oracle of Secrets format)
51 uint32_t main_rom_offset = 0; // SongBank_OverworldExpanded_Main
52 uint32_t aux_rom_offset = 0; // SongBank_Overworld_Auxiliary
53 uint16_t aux_aram_address = 0; // SONG_POINTERS_AUX ($2B00)
54 uint32_t hook_address = 0; // LoadOverworldSongsExpanded location
55 bool detected = false;
56 };
57
58 MusicBank() = default;
59 ~MusicBank() = default;
60
61 // Non-copyable, moveable
62 MusicBank(const MusicBank&) = delete;
63 MusicBank& operator=(const MusicBank&) = delete;
64 MusicBank(MusicBank&&) = default;
66
67 // =========================================================================
68 // ROM Loading/Saving
69 // =========================================================================
70
76 absl::Status LoadFromRom(Rom& rom);
77
83 absl::Status SaveToRom(Rom& rom);
84
88 bool IsLoaded() const { return loaded_; }
89
90 // =========================================================================
91 // Song Access
92 // =========================================================================
93
97 size_t GetSongCount() const { return songs_.size(); }
98
104 MusicSong* GetSong(int index);
105 const MusicSong* GetSong(int index) const;
106
112 MusicSong* GetSongById(int song_id);
113
120 int CreateNewSong(const std::string& name, Bank bank);
121
127 absl::Status DeleteSong(int index);
128
134 int DuplicateSong(int index);
135
141 bool IsVanilla(int index) const;
142
148
154 bool IsExpandedSong(int index) const;
155
161 return expanded_bank_info_;
162 }
163
167 std::vector<MusicSong*> GetSongsInBank(Bank bank);
168
169 // =========================================================================
170 // Instrument Access
171 // =========================================================================
172
176 size_t GetInstrumentCount() const { return instruments_.size(); }
177
181 MusicInstrument* GetInstrument(int index);
182 const MusicInstrument* GetInstrument(int index) const;
183
189 int CreateNewInstrument(const std::string& name);
190
191 // =========================================================================
192 // Sample Access
193 // =========================================================================
194
198 size_t GetSampleCount() const { return samples_.size(); }
199
203 MusicSample* GetSample(int index);
204 const MusicSample* GetSample(int index) const;
205
212 absl::StatusOr<int> ImportSampleFromWav(const std::string& filepath,
213 const std::string& name);
214
215 // =========================================================================
216 // Space Management
217 // =========================================================================
218
224 SpaceInfo CalculateSpaceUsage(Bank bank) const;
225
230 bool AllSongsFit() const;
231
235 static int GetBankMaxSize(Bank bank);
236
240 static uint32_t GetBankRomAddress(Bank bank);
241
242 // =========================================================================
243 // Modification Tracking
244 // =========================================================================
245
249 bool HasModifications() const;
250
254 void ClearModifications();
255
256 // Serialization helpers for persistence (e.g., WASM storage)
257 nlohmann::json ToJson() const;
258 absl::Status LoadFromJson(const nlohmann::json& j);
259
260 private:
261 // Internal loading methods
262 absl::Status LoadSongTable(Rom& rom, Bank bank,
263 std::vector<MusicSong>* custom_songs);
264 absl::Status LoadInstruments(Rom& rom);
265 absl::Status LoadSamples(Rom& rom);
266
267 // Expanded bank detection and loading
268 absl::Status DetectExpandedMusicPatch(Rom& rom);
269 absl::Status LoadExpandedSongTable(Rom& rom,
270 std::vector<MusicSong>* custom_songs);
271
272 // Internal saving methods
273 absl::Status SaveSongTable(Rom& rom, Bank bank);
274 absl::Status SaveInstruments(Rom& rom);
275 absl::Status SaveSamples(Rom& rom);
276
277 // Calculate size of serialized song
278 int CalculateSongSize(const MusicSong& song) const;
279
280 // Data storage
281 std::vector<MusicSong> songs_;
282 std::vector<MusicInstrument> instruments_;
283 std::vector<MusicSample> samples_;
284
285 // State
286 bool loaded_ = false;
288 bool samples_modified_ = false;
289
290 // Song counts per bank (from original ROM)
296
297 // Expanded bank info (Oracle of Secrets format)
299
300 // Helper metadata for ROM banks
302 int start_id = 0;
303 int end_id = -1;
304
305 int Count() const {
306 return (end_id >= start_id) ? (end_id - start_id + 1) : 0;
307 }
308 };
309
310 static BankSongRange GetBankSongRange(Bank bank);
311 static uint8_t GetSpcBankId(Bank bank);
312 static constexpr uint16_t GetSongTableAddress() { return kSongTableAram; }
313};
314
315// =============================================================================
316// Vanilla Song Names
317// =============================================================================
318
324const char* GetVanillaSongName(int song_id);
325
332
333} // namespace music
334} // namespace zelda3
335} // namespace yaze
336
337#endif // YAZE_ZELDA3_MUSIC_MUSIC_BANK_H
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
Represents the full Overworld data, light and dark world.
Definition overworld.h:217
Manages the collection of songs, instruments, and samples from a ROM.
Definition music_bank.h:27
static uint8_t GetSpcBankId(Bank bank)
static uint32_t GetBankRomAddress(Bank bank)
Get the ROM address for a bank.
bool HasModifications() const
Check if any music data has been modified.
MusicInstrument * GetInstrument(int index)
Get an instrument by index.
int CreateNewInstrument(const std::string &name)
Create a new instrument.
static constexpr uint16_t GetSongTableAddress()
Definition music_bank.h:312
nlohmann::json ToJson() const
bool IsVanilla(int index) const
Check if a song is a vanilla (original) song.
absl::Status LoadFromJson(const nlohmann::json &j)
absl::Status LoadSamples(Rom &rom)
size_t GetSampleCount() const
Get the number of samples.
Definition music_bank.h:198
MusicSong * GetSongById(int song_id)
Get a song by vanilla ID (1-based).
MusicSong * GetSong(int index)
Get a song by index.
absl::Status DetectExpandedMusicPatch(Rom &rom)
absl::Status LoadInstruments(Rom &rom)
static int GetBankMaxSize(Bank bank)
Get the maximum size for a bank.
ExpandedBankInfo expanded_bank_info_
Definition music_bank.h:298
size_t GetInstrumentCount() const
Get the number of instruments.
Definition music_bank.h:176
size_t GetSongCount() const
Get the number of songs loaded.
Definition music_bank.h:97
std::vector< MusicSample > samples_
Definition music_bank.h:283
const ExpandedBankInfo & GetExpandedBankInfo() const
Get information about the expanded bank configuration.
Definition music_bank.h:160
absl::Status LoadSongTable(Rom &rom, Bank bank, std::vector< MusicSong > *custom_songs)
bool AllSongsFit() const
Check if all songs fit in their banks.
static BankSongRange GetBankSongRange(Bank bank)
absl::Status SaveInstruments(Rom &rom)
MusicSample * GetSample(int index)
Get a sample by index.
absl::Status DeleteSong(int index)
Delete a song by index.
MusicBank & operator=(const MusicBank &)=delete
MusicBank & operator=(MusicBank &&)=default
MusicBank(MusicBank &&)=default
std::vector< MusicSong > songs_
Definition music_bank.h:281
SpaceInfo CalculateSpaceUsage(Bank bank) const
Calculate space usage for a bank.
absl::StatusOr< int > ImportSampleFromWav(const std::string &filepath, const std::string &name)
Import a WAV file as a new sample.
absl::Status SaveSamples(Rom &rom)
absl::Status SaveToRom(Rom &rom)
Save all modified music data back to ROM.
absl::Status SaveSongTable(Rom &rom, Bank bank)
int CalculateSongSize(const MusicSong &song) const
bool IsExpandedSong(int index) const
Check if a song is from an expanded bank.
void ClearModifications()
Mark all data as unmodified (after save).
absl::Status LoadExpandedSongTable(Rom &rom, std::vector< MusicSong > *custom_songs)
std::vector< MusicInstrument > instruments_
Definition music_bank.h:282
MusicBank(const MusicBank &)=delete
int CreateNewSong(const std::string &name, Bank bank)
Create a new empty song.
bool IsLoaded() const
Check if music data has been loaded.
Definition music_bank.h:88
absl::Status LoadFromRom(Rom &rom)
Load all music data from a ROM.
std::vector< MusicSong * > GetSongsInBank(Bank bank)
Get all songs in a specific bank.
bool HasExpandedMusicPatch() const
Check if the ROM has the Oracle of Secrets expanded music patch.
Definition music_bank.h:147
int DuplicateSong(int index)
Duplicate a song.
MusicBank::Bank GetVanillaSongBank(int song_id)
Get the bank for a vanilla song ID.
constexpr uint16_t kSongTableAram
Definition song_data.h:82
const char * GetVanillaSongName(int song_id)
Get the vanilla name for a song ID.
An instrument definition with ADSR envelope.
Definition song_data.h:358
A BRR-encoded audio sample.
Definition song_data.h:388
A complete song composed of segments.
Definition song_data.h:334