From a3e3b77a08a69dbd2eb1d4f703269f39928a9fd2 Mon Sep 17 00:00:00 2001 From: PhoenixBound Date: Sun, 11 Feb 2024 17:43:42 -0600 Subject: [PATCH] Support transposing notes in F9 commands Also makes the code around here use more structured control flow --- src/tracker.c | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/tracker.c b/src/tracker.c index 673e70c..1b94ddd 100644 --- a/src/tracker.c +++ b/src/tracker.c @@ -1190,18 +1190,29 @@ void editor_command(int id) { case ID_TRANSPOSE: { int delta = DialogBox(hinstance, MAKEINTRESOURCE(IDD_TRANSPOSE), hwndMain, TransposeDlgProc); - if (delta == 0) break; - for (BYTE *p = sel_start; p < sel_end; p = next_code(p)) { - int note = *p - 0x80; - if (note < 0 || note >= 0x48) continue; - note += delta; - note %= 0x48; - if (note < 0) note += 0x48; - *p = 0x80 + note; + if (delta != 0) { + for (BYTE *p = sel_start; p < sel_end; p = next_code(p)) { + if (*p == 0xF9) { + // F9 is a pitch bend to a specific note. + // To make transpose a reversible operation and prevent unwanted consequences, + // don't wrap around from B6 to C1 for these commands. (The composer might've + // used a note outside of that range.) + p[3] += delta; + } else if (*p >= 0x80 && *p < 0xC8) { + // This is a command to play a given note + int note = *p - 0x80; + note += delta; + // Wrap around note commands, so that transposing C1 one semitone down yields + // a B6 + note %= 0x48; + if (note < 0) note += 0x48; + *p = 0x80 + note; + } + } + cur_song.changed = TRUE; + show_track_text(); + InvalidateRect(hwndTracker, NULL, FALSE); } - cur_song.changed = TRUE; - show_track_text(); - InvalidateRect(hwndTracker, NULL, FALSE); break; } case ID_ZOOM_IN: