diff --git a/src/app/core/common.cc b/src/app/core/common.cc index a8d0ee85..13217f01 100644 --- a/src/app/core/common.cc +++ b/src/app/core/common.cc @@ -58,6 +58,73 @@ bool StringReplace(std::string &str, const std::string &from, return true; } +void stle(uint8_t *const p_arr, size_t const p_index, unsigned const p_val) { + uint8_t v = (p_val >> (8 * p_index)) & 0xff; + + p_arr[p_index] = v; +} + +void stle0(uint8_t *const p_arr, unsigned const p_val) { + stle(p_arr, 0, p_val); +} + +void stle1(uint8_t *const p_arr, unsigned const p_val) { + stle(p_arr, 1, p_val); +} + +void stle2(uint8_t *const p_arr, unsigned const p_val) { + stle(p_arr, 2, p_val); +} + +void stle3(uint8_t *const p_arr, unsigned const p_val) { + stle(p_arr, 3, p_val); +} +void stle16b(uint8_t *const p_arr, uint16_t const p_val) { + stle0(p_arr, p_val); + stle1(p_arr, p_val); +} +// "Store little endian 16-bit value using a byte pointer, offset by an +// index before dereferencing" +void stle16b_i(uint8_t *const p_arr, size_t const p_index, + uint16_t const p_val) { + stle16b(p_arr + (p_index * 2), p_val); +} +// "load little endian value at the given byte offset and shift to get its +// value relative to the base offset (powers of 256, essentially)" +unsigned ldle(uint8_t const *const p_arr, unsigned const p_index) { + uint32_t v = p_arr[p_index]; + + v <<= (8 * p_index); + + return v; +} + +// Helper function to get the first byte in a little endian number +uint32_t ldle0(uint8_t const *const p_arr) { return ldle(p_arr, 0); } + +// Helper function to get the second byte in a little endian number +uint32_t ldle1(uint8_t const *const p_arr) { return ldle(p_arr, 1); } + +// Helper function to get the third byte in a little endian number +uint32_t ldle2(uint8_t const *const p_arr) { return ldle(p_arr, 2); } + +// Helper function to get the third byte in a little endian number +uint32_t ldle3(uint8_t const *const p_arr) { return ldle(p_arr, 3); } +// Load little endian halfword (16-bit) dereferenced from +uint16_t ldle16b(uint8_t const *const p_arr) { + uint16_t v = 0; + + v |= (ldle0(p_arr) | ldle1(p_arr)); + + return v; +} +// Load little endian halfword (16-bit) dereferenced from an arrays of bytes. +// This version provides an index that will be multiplied by 2 and added to the +// base address. +uint16_t ldle16b_i(uint8_t const *const p_arr, size_t const p_index) { + return ldle16b(p_arr + (2 * p_index)); +} + } // namespace core } // namespace app } // namespace yaze diff --git a/src/app/core/common.h b/src/app/core/common.h index 4a6969a5..9db4a37e 100644 --- a/src/app/core/common.h +++ b/src/app/core/common.h @@ -14,6 +14,16 @@ int HexToDec(char *input, int length); bool StringReplace(std::string &str, const std::string &from, const std::string &to); +void stle16b_i(uint8_t *const p_arr, size_t const p_index, + uint16_t const p_val); +uint16_t ldle16b_i(uint8_t const *const p_arr, size_t const p_index); + +void stle16b(uint8_t *const p_arr, uint16_t const p_val); +void stle32b(uint8_t *const p_arr, uint32_t const p_val); + +void stle32b_i(uint8_t *const p_arr, size_t const p_index, + uint32_t const p_val); + } // namespace core } // namespace app } // namespace yaze diff --git a/src/app/editor/master_editor.cc b/src/app/editor/master_editor.cc index 16ae7243..2f5f0995 100644 --- a/src/app/editor/master_editor.cc +++ b/src/app/editor/master_editor.cc @@ -106,6 +106,7 @@ void MasterEditor::DrawFileDialog() { overworld_editor_.SetupROM(rom_); screen_editor_.SetupROM(rom_); palette_editor_.SetupROM(rom_); + music_editor_.SetupROM(rom_); } ImGuiFileDialog::Instance()->Close(); } diff --git a/src/app/editor/music_editor.cc b/src/app/editor/music_editor.cc index a635f081..05d26678 100644 --- a/src/app/editor/music_editor.cc +++ b/src/app/editor/music_editor.cc @@ -252,11 +252,13 @@ void MusicEditor::DrawToolset() { ImGui::Combo("#songs_in_game", &selected_option, kGameSongs, 30); gui::ItemLabel("Controls: ", gui::ItemLabelFlags::Left); - if (ImGui::BeginTable("SongToolset", 5, toolset_table_flags_, ImVec2(0, 0))) { + if (ImGui::BeginTable("SongToolset", 6, toolset_table_flags_, ImVec2(0, 0))) { ImGui::TableSetupColumn("#play"); ImGui::TableSetupColumn("#rewind"); ImGui::TableSetupColumn("#fastforward"); ImGui::TableSetupColumn("#volume"); + ImGui::TableSetupColumn("#debug"); + ImGui::TableSetupColumn("#slider"); ImGui::TableNextColumn(); @@ -271,6 +273,9 @@ void MusicEditor::DrawToolset() { BUTTON_COLUMN(ICON_MD_FAST_REWIND) BUTTON_COLUMN(ICON_MD_FAST_FORWARD) BUTTON_COLUMN(ICON_MD_VOLUME_UP) + if (ImGui::Button(ICON_MD_ACCESS_TIME)) { + music_tracker_.LoadSongs(rom_); + } ImGui::TableNextColumn(); ImGui::SliderInt("Volume", ¤t_volume, 0, 100); ImGui::EndTable(); diff --git a/src/app/editor/music_editor.h b/src/app/editor/music_editor.h index 929d36ae..a903fae3 100644 --- a/src/app/editor/music_editor.h +++ b/src/app/editor/music_editor.h @@ -6,6 +6,8 @@ #include "absl/strings/str_format.h" #include "app/editor/assembly_editor.h" +#include "app/rom.h" +#include "app/zelda3/tracker.h" #include "gui/canvas.h" #include "gui/icons.h" #include "gui/input.h" @@ -55,6 +57,7 @@ static constexpr absl::string_view kSongNotes[] = { class MusicEditor { public: void Update(); + void SetupROM(ROM& rom) { rom_ = rom; } private: void DrawChannels(); @@ -63,6 +66,9 @@ class MusicEditor { void DrawSongToolset(); void DrawToolset(); + zelda3::Tracker music_tracker_; + ROM rom_; + Mix_Music* current_song_ = NULL; AssemblyEditor assembly_editor_; diff --git a/src/app/zelda3/tracker.cc b/src/app/zelda3/tracker.cc index f6faf61f..45b5eb53 100644 --- a/src/app/zelda3/tracker.cc +++ b/src/app/zelda3/tracker.cc @@ -828,22 +828,32 @@ void Tracker::SaveSongs(ROM &rom) { int g; unsigned short bank_next[4]; unsigned short bank_lwr[4]; - short *c, *d; - unsigned char *rom_data, *b; + short *c; + short *d; + unsigned char *rom_data; + unsigned char *b; Song *s; + SPCCommand *spc_command; + SongPart *sp; + SongSPCBlock *stbl; SongSPCBlock *sptbl; SongSPCBlock *trtbl; SongSPCBlock *pstbl; + ZeldaWave *zelda_wave; ZeldaWave *zelda_wave2; + ZeldaInstrument *zi; + SampleEdit *sed; - short wtbl[128], x[16], y[18]; + short wtbl[128]; + short x[16]; + short y[18]; unsigned char z[64]; ss_num = 0; @@ -924,9 +934,9 @@ void Tracker::SaveSongs(ROM &rom) { q = 1; for (n = 0; n < 8; n++) { - stle16b_i(trtbl->buf, n, SaveSPCCommand(rom, sp->tbl[n], p, q)); + core::stle16b_i(trtbl->buf, n, SaveSPCCommand(rom, sp->tbl[n], p, q)); - if (ldle16b_i(trtbl->buf, n)) AddSPCReloc(trtbl, n << 1), q = 0; + if (core::ldle16b_i(trtbl->buf, n)) AddSPCReloc(trtbl, n << 1), q = 0; } sp->addr = trtbl->start; @@ -1029,12 +1039,14 @@ void Tracker::SaveSongs(ROM &rom) { // Modifywaves(rom, i); } } + k = (-zelda_wave->end) & 15; d = zelda_wave->buf; n = 0; wtbl[(i << 1) + 1] = ((zelda_wave->lopst + k) >> 4) * 9 + wtbl[i << 1]; y[0] = y[1] = 0; u = 4; + for (;;) { for (o = 0; o < 16; o++) { if (k) @@ -1044,6 +1056,7 @@ void Tracker::SaveSongs(ROM &rom) { } p = 0x7fffffff; a = 0; + for (t = 0; t < 4; t++) { r = 0; for (o = 0; o < 16; o++) { @@ -1159,15 +1172,8 @@ void Tracker::SaveSongs(ROM &rom) { pstbl = 0; } if (j + stbl->len > 0x3c00 && j < 0xd000) { - text_buf_ty buf; - - // SetCursor(normal_cursor); - printf("Not enough space for music bank %d", k); - printf("Error"); - m_modf = 1; - return; } if (pstbl && (pstbl->flag & 1) && (stbl->flag & 2)) j--, pstbl->len--; @@ -1193,16 +1199,8 @@ void Tracker::SaveSongs(ROM &rom) { *(unsigned short *)(stbl->buf + stbl->relocs[j]) = sptbl->addr + k - sptbl->start; } else { - text_buf_ty buf; - - // wsprintf(buf, "An address outside the bank was referenced", - // sptbl->bank, - // stbl->bank); - - printf("Error"); - + printf("An address outside the bank was referenced.\n"); m_modf = 1; - return; } } @@ -1255,7 +1253,6 @@ void Tracker::SaveSongs(ROM &rom) { if (k == 1) m = l + 4; } free(ssblt); - // SetCursor(normal_cursor); } // ============================================================================= @@ -1321,7 +1318,7 @@ void Tracker::NewSR(ROM &rom, int bank) { sr = song_range_ + srnum; srnum++; - sr->first = AllocSPCCommand(rom); + sr->first = AllocSPCCommand(); sr->bank = bank; sr->editor = 0; spc_command = current_spc_command_ + sr->first; diff --git a/src/app/zelda3/tracker.h b/src/app/zelda3/tracker.h index 9baac431..acb4e9a8 100644 --- a/src/app/zelda3/tracker.h +++ b/src/app/zelda3/tracker.h @@ -7,6 +7,7 @@ #include #include "absl/status/status.h" +#include "app/core/common.h" #include "app/core/constants.h" #include "app/gfx/bitmap.h" #include "app/gfx/snes_tile.h" @@ -20,95 +21,20 @@ namespace zelda3 { // bank 19, 1A, 1B // iirc 1A is OW, 1B is dungeon // 19 is general spc stuff like samples, ects -char op_len[32] = {1, 1, 2, 3, 0, 1, 2, 1, 2, 1, 1, 3, 0, 1, 2, 3, - 1, 3, 3, 0, 1, 3, 0, 3, 3, 3, 1, 2, 0, 0, 0, 0}; +static char op_len[32] = {1, 1, 2, 3, 0, 1, 2, 1, 2, 1, 1, 3, 0, 1, 2, 3, + 1, 3, 3, 0, 1, 3, 0, 3, 3, 3, 1, 2, 0, 0, 0, 0}; // ============================================================================= static int sbank_ofs[] = {0xc8000, 0, 0xd8000, 0}; -char fil1[4] = {0, 15, 61, 115}; -char fil2[4] = {0, 4, 5, 6}; -char fil3[4] = {0, 0, 15, 13}; +static char fil1[4] = {0, 15, 61, 115}; +static char fil2[4] = {0, 4, 5, 6}; +static char fil3[4] = {0, 0, 15, 13}; constexpr int kOverworldMusicBank = 0x0D0000; constexpr int kDungeonMusicBank = 0x0D8000; -void stle16b_i(uint8_t *const p_arr, size_t const p_index, - uint16_t const p_val); -uint16_t ldle16b_i(uint8_t const *const p_arr, size_t const p_index); - -void stle16b(uint8_t *const p_arr, uint16_t const p_val); - -// "Store little endian 16-bit value using a byte pointer, offset by an -// index before dereferencing" -void stle16b_i(uint8_t *const p_arr, size_t const p_index, - uint16_t const p_val) { - stle16b(p_arr + (p_index * 2), p_val); -} - -void stle(uint8_t *const p_arr, size_t const p_index, unsigned const p_val) { - uint8_t v = (p_val >> (8 * p_index)) & 0xff; - - p_arr[p_index] = v; -} - -void stle0(uint8_t *const p_arr, unsigned const p_val) { - stle(p_arr, 0, p_val); -} - -void stle1(uint8_t *const p_arr, unsigned const p_val) { - stle(p_arr, 1, p_val); -} - -void stle2(uint8_t *const p_arr, unsigned const p_val) { - stle(p_arr, 2, p_val); -} - -void stle3(uint8_t *const p_arr, unsigned const p_val) { - stle(p_arr, 3, p_val); -} -void stle16b(uint8_t *const p_arr, uint16_t const p_val) { - stle0(p_arr, p_val); - stle1(p_arr, p_val); -} - -// "load little endian value at the given byte offset and shift to get its -// value relative to the base offset (powers of 256, essentially)" -unsigned ldle(uint8_t const *const p_arr, unsigned const p_index) { - uint32_t v = p_arr[p_index]; - - v <<= (8 * p_index); - - return v; -} - -// Helper function to get the first byte in a little endian number -uint32_t ldle0(uint8_t const *const p_arr) { return ldle(p_arr, 0); } - -// Helper function to get the second byte in a little endian number -uint32_t ldle1(uint8_t const *const p_arr) { return ldle(p_arr, 1); } - -// Helper function to get the third byte in a little endian number -uint32_t ldle2(uint8_t const *const p_arr) { return ldle(p_arr, 2); } - -// Helper function to get the third byte in a little endian number -uint32_t ldle3(uint8_t const *const p_arr) { return ldle(p_arr, 3); } -// Load little endian halfword (16-bit) dereferenced from -uint16_t ldle16b(uint8_t const *const p_arr) { - uint16_t v = 0; - - v |= (ldle0(p_arr) | ldle1(p_arr)); - - return v; -} -// Load little endian halfword (16-bit) dereferenced from an arrays of bytes. -// This version provides an index that will be multiplied by 2 and added to the -// base address. -uint16_t ldle16b_i(uint8_t const *const p_arr, size_t const p_index) { - return ldle16b(p_arr + (2 * p_index)); -} - using text_buf_ty = char[512]; // ============================================================================