yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
asm_importer.h
Go to the documentation of this file.
1#ifndef YAZE_ZELDA3_MUSIC_ASM_IMPORTER_H
2#define YAZE_ZELDA3_MUSIC_ASM_IMPORTER_H
3
4#include <string>
5#include <unordered_map>
6#include <vector>
7
8#include "absl/status/status.h"
9#include "absl/status/statusor.h"
12
13namespace yaze {
14namespace zelda3 {
15namespace music {
16
21 bool strict_mode = false; // Fail on unknown macros/syntax
22 bool resolve_subroutines = true; // Inline subroutine calls
23 bool verbose_errors = true; // Include line numbers in errors
24};
25
31 std::vector<std::string> warnings;
32 std::vector<std::string> errors;
33 int lines_parsed = 0;
35};
36
48 public:
49 AsmImporter() = default;
50 ~AsmImporter() = default;
51
58 absl::StatusOr<AsmParseResult> ImportSong(const std::string& asm_source,
59 const AsmImportOptions& options);
60
67 absl::StatusOr<AsmParseResult> ImportFromFile(
68 const std::string& path, const AsmImportOptions& options);
69
70 private:
71 // Parsing state
72 struct ParseState {
73 int line_number = 0;
75 uint8_t current_duration = 0;
76 std::string song_label;
77 uint16_t aram_address = 0xD800;
78 std::unordered_map<std::string, int> label_to_channel;
79 std::unordered_map<std::string, std::vector<TrackEvent>> subroutines;
80 std::vector<std::string> warnings;
81 std::vector<std::string> errors;
83 };
84
85 // Line parsing
86 absl::Status ParseLine(const std::string& line, MusicSong& song,
87 ParseState& state, const AsmImportOptions& options);
88
89 // Label parsing
90 bool ParseLabel(const std::string& line, ParseState& state);
91
92 // Directive parsing (!ARAMAddr, etc.)
93 bool ParseDirective(const std::string& line, ParseState& state);
94
95 // Data byte parsing (db statements)
96 absl::Status ParseDataBytes(const std::string& line, MusicSong& song,
97 ParseState& state,
98 const AsmImportOptions& options);
99
100 // Macro parsing (%SetTempo, %Piano, etc.)
101 absl::StatusOr<std::vector<TrackEvent>> ParseMacro(
102 const std::string& macro_call, ParseState& state,
103 const AsmImportOptions& options);
104
105 // Note name parsing (C4, G4s, Rest, Tie -> byte values)
106 absl::StatusOr<uint8_t> ParseNoteName(const std::string& note_name);
107
108 // Duration constant parsing (!4th -> 0x48)
109 absl::StatusOr<uint8_t> ParseDurationConstant(const std::string& duration);
110
111 // Instrument macro resolution (%Piano() -> SetInstrument($18))
112 absl::StatusOr<MusicCommand> ResolveInstrumentMacro(
113 const std::string& macro_name);
114
115 // Command macro resolution (%SetTempo($80) -> command bytes)
116 absl::StatusOr<MusicCommand> ResolveCommandMacro(
117 const std::string& macro_name, const std::vector<uint8_t>& params);
118
119 // Helper to extract macro name and parameters
120 bool ParseMacroCall(const std::string& call, std::string& macro_name,
121 std::vector<std::string>& params);
122
123 // Helper to parse hex value ($XX or 0xXX)
124 absl::StatusOr<uint8_t> ParseHexValue(const std::string& value);
125
126 // Trim whitespace
127 static std::string Trim(const std::string& s);
128};
129
130// =============================================================================
131// Note Name Mappings (for import)
132// =============================================================================
133
134// Maps note names to pitch values
136 const char* name;
137 uint8_t pitch;
138};
139
140// Standard notes (C1-B6)
142 // Octave 1
143 {"C1", 0x80},
144 {"Cs1", 0x81},
145 {"D1", 0x82},
146 {"Ds1", 0x83},
147 {"E1", 0x84},
148 {"F1", 0x85},
149 {"Fs1", 0x86},
150 {"G1", 0x87},
151 {"Gs1", 0x88},
152 {"A1", 0x89},
153 {"As1", 0x8A},
154 {"B1", 0x8B},
155 // Octave 2
156 {"C2", 0x8C},
157 {"Cs2", 0x8D},
158 {"D2", 0x8E},
159 {"Ds2", 0x8F},
160 {"E2", 0x90},
161 {"F2", 0x91},
162 {"Fs2", 0x92},
163 {"G2", 0x93},
164 {"Gs2", 0x94},
165 {"A2", 0x95},
166 {"As2", 0x96},
167 {"B2", 0x97},
168 // Octave 3
169 {"C3", 0x98},
170 {"Cs3", 0x99},
171 {"D3", 0x9A},
172 {"Ds3", 0x9B},
173 {"E3", 0x9C},
174 {"F3", 0x9D},
175 {"Fs3", 0x9E},
176 {"G3", 0x9F},
177 {"Gs3", 0xA0},
178 {"A3", 0xA1},
179 {"As3", 0xA2},
180 {"B3", 0xA3},
181 // Octave 4
182 {"C4", 0xA4},
183 {"Cs4", 0xA5},
184 {"D4", 0xA6},
185 {"Ds4", 0xA7},
186 {"E4", 0xA8},
187 {"F4", 0xA9},
188 {"Fs4", 0xAA},
189 {"G4", 0xAB},
190 {"Gs4", 0xAC},
191 {"A4", 0xAD},
192 {"As4", 0xAE},
193 {"B4", 0xAF},
194 // Octave 5
195 {"C5", 0xB0},
196 {"Cs5", 0xB1},
197 {"D5", 0xB2},
198 {"Ds5", 0xB3},
199 {"E5", 0xB4},
200 {"F5", 0xB5},
201 {"Fs5", 0xB6},
202 {"G5", 0xB7},
203 {"Gs5", 0xB8},
204 {"A5", 0xB9},
205 {"As5", 0xBA},
206 {"B5", 0xBB},
207 // Octave 6
208 {"C6", 0xBC},
209 {"Cs6", 0xBD},
210 {"D6", 0xBE},
211 {"Ds6", 0xBF},
212 {"E6", 0xC0},
213 {"F6", 0xC1},
214 {"Fs6", 0xC2},
215 {"G6", 0xC3},
216 {"Gs6", 0xC4},
217 {"A6", 0xC5},
218 {"As6", 0xC6},
219 {"B6", 0xC7},
220 // Special
221 {"Tie", 0xC8},
222 {"Rest", 0xC9},
223 {"End", 0x00},
224};
225
226// Maps command macro names to opcodes
228 const char* name;
229 uint8_t opcode;
231};
232
234 {"SetInstrument", 0xE0, 1},
235 {"SetPan", 0xE1, 1},
236 {"PanFade", 0xE2, 2},
237 {"VibratoOn", 0xE3, 3},
238 {"VibratoOff", 0xE4, 0},
239 {"SetMasterVolume", 0xE5, 1},
240 {"MasterVolumeFade", 0xE6, 2},
241 {"SetTempo", 0xE7, 1},
242 {"TempoFade", 0xE8, 2},
243 {"GlobalTranspose", 0xE9, 1},
244 {"ChannelTranspose", 0xEA, 1},
245 {"TremoloOn", 0xEB, 3},
246 {"TremoloOff", 0xEC, 0},
247 {"SetChannelVolume", 0xED, 1},
248 {"ChannelVolumeFade", 0xEE, 2},
249 {"CallSubroutine", 0xEF, 3},
250 {"VibratoFade", 0xF0, 1},
251 {"PitchEnvelopeTo", 0xF1, 3},
252 {"PitchEnvelopeFrom", 0xF2, 3},
253 {"PitchEnvelopeOff", 0xF3, 0},
254 {"Tuning", 0xF4, 1},
255 {"EchoVBits", 0xF5, 1},
256 {"EchoOff", 0xF6, 0},
257 {"EchoParams", 0xF7, 3},
258 {"EchoVolumeFade", 0xF8, 3},
259 {"PitchSlide", 0xF9, 3},
260 {"PercussionPatch", 0xFA, 1},
261};
262
263// Maps instrument macro names to instrument IDs
265 const char* macro;
266 uint8_t id;
267};
268
270 {"Tympani", 0x02}, {"Sawtooth", 0x04}, {"Sine", 0x05},
271 {"Strings", 0x09}, {"Trombone", 0x0B}, {"Cymbal", 0x0C},
272 {"Ocarina", 0x0D}, {"Harp", 0x0F}, {"Splash", 0x10},
273 {"Trumpet", 0x11}, {"Horn", 0x12}, {"Snare", 0x13},
274 {"Choir", 0x15}, {"Flute", 0x16}, {"Piano", 0x18},
275};
276
277} // namespace music
278} // namespace zelda3
279} // namespace yaze
280
281#endif // YAZE_ZELDA3_MUSIC_ASM_IMPORTER_H
Imports music_macros.asm format files into MusicSong.
absl::StatusOr< AsmParseResult > ImportSong(const std::string &asm_source, const AsmImportOptions &options)
Import a song from ASM string.
bool ParseLabel(const std::string &line, ParseState &state)
absl::StatusOr< uint8_t > ParseDurationConstant(const std::string &duration)
bool ParseDirective(const std::string &line, ParseState &state)
absl::StatusOr< MusicCommand > ResolveCommandMacro(const std::string &macro_name, const std::vector< uint8_t > &params)
absl::Status ParseLine(const std::string &line, MusicSong &song, ParseState &state, const AsmImportOptions &options)
absl::StatusOr< uint8_t > ParseNoteName(const std::string &note_name)
static std::string Trim(const std::string &s)
absl::Status ParseDataBytes(const std::string &line, MusicSong &song, ParseState &state, const AsmImportOptions &options)
bool ParseMacroCall(const std::string &call, std::string &macro_name, std::vector< std::string > &params)
absl::StatusOr< uint8_t > ParseHexValue(const std::string &value)
absl::StatusOr< AsmParseResult > ImportFromFile(const std::string &path, const AsmImportOptions &options)
Import a song from a file.
absl::StatusOr< MusicCommand > ResolveInstrumentMacro(const std::string &macro_name)
absl::StatusOr< std::vector< TrackEvent > > ParseMacro(const std::string &macro_call, ParseState &state, const AsmImportOptions &options)
constexpr CommandMacroMapping kCommandMacros[]
constexpr NoteNameMapping kAsmNoteNames[]
constexpr InstrumentMacroMapping kInstrumentMacroImport[]
Options for ASM import from music_macros.asm format.
std::unordered_map< std::string, std::vector< TrackEvent > > subroutines
std::unordered_map< std::string, int > label_to_channel
Parse result with diagnostics.
std::vector< std::string > errors
std::vector< std::string > warnings
A complete song composed of segments.
Definition song_data.h:334