Skip to content

Commit

Permalink
Added duration setting options/shortcuts
Browse files Browse the repository at this point in the history
Set Duration was added as a dropdown option under the Edit menu with options to increment, decrement, and set a fixed duration and associated shortcut keys.
  • Loading branch information
ChrisBlueStone committed Dec 30, 2019
1 parent 7c91e34 commit 2c534f5
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 19 deletions.
26 changes: 17 additions & 9 deletions src/id.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,23 @@
#define ID_TRANSPOSE 117
#define ID_MAKE_SUBROUTINE 118
#define ID_UNMAKE_SUBROUTINE 119
#define ID_OPTIONS 120
#define ID_PLAY 121
#define ID_STOP 122
#define ID_CLEAR_SONG 123
#define ID_ZOOM_IN 130
#define ID_ZOOM_OUT 131
#define ID_OCTAVE_1 140
#define ID_HELP 150
#define ID_ABOUT 151
#define ID_INCREMENT_DURATION 120
#define ID_DECREMENT_DURATION 121
#define ID_SET_DURATION_1 123
#define ID_SET_DURATION_2 124
#define ID_SET_DURATION_3 125
#define ID_SET_DURATION_4 126
#define ID_SET_DURATION_5 127
#define ID_SET_DURATION_6 128
#define ID_OPTIONS 130
#define ID_PLAY 131
#define ID_STOP 132
#define ID_CLEAR_SONG 133
#define ID_ZOOM_IN 140
#define ID_ZOOM_OUT 141
#define ID_OCTAVE_1 150
#define ID_HELP 160
#define ID_ABOUT 161

#define IDA_ACCEL 1

Expand Down
24 changes: 20 additions & 4 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,26 @@ LRESULT CALLBACK MainWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
DialogBox(hinstance, MAKEINTRESOURCE(IDD_OPTIONS), hWnd, OptionsDlgProc);
break;
}
case ID_CUT: case ID_COPY: case ID_PASTE: case ID_DELETE:
case ID_SPLIT_PATTERN: case ID_JOIN_PATTERNS:
case ID_MAKE_SUBROUTINE: case ID_UNMAKE_SUBROUTINE: case ID_TRANSPOSE:
case ID_CLEAR_SONG: case ID_ZOOM_OUT: case ID_ZOOM_IN:
case ID_CUT:
case ID_COPY:
case ID_PASTE:
case ID_DELETE:
case ID_SPLIT_PATTERN:
case ID_JOIN_PATTERNS:
case ID_MAKE_SUBROUTINE:
case ID_UNMAKE_SUBROUTINE:
case ID_TRANSPOSE:
case ID_CLEAR_SONG:
case ID_ZOOM_OUT:
case ID_ZOOM_IN:
case ID_INCREMENT_DURATION:
case ID_DECREMENT_DURATION:
case ID_SET_DURATION_1:
case ID_SET_DURATION_2:
case ID_SET_DURATION_3:
case ID_SET_DURATION_4:
case ID_SET_DURATION_5:
case ID_SET_DURATION_6:
editor_command(id);
break;
case ID_PLAY:
Expand Down
13 changes: 12 additions & 1 deletion src/resource.rc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ BEGIN
MENUITEM "&Make Subroutine", ID_MAKE_SUBROUTINE, GRAYED
MENUITEM "U&nmake Subroutine", ID_UNMAKE_SUBROUTINE, GRAYED
MENUITEM "T&ranspose...", ID_TRANSPOSE, GRAYED
POPUP "Set D&uration"
{
MENUITEM "&Increment\tCtrl+.", ID_INCREMENT_DURATION, GRAYED
MENUITEM "&Decrement\tCtrl+,", ID_DECREMENT_DURATION, GRAYED
MENUITEM "&Whole Note\tCtrl+1", ID_SET_DURATION_1, GRAYED
MENUITEM "&Half Note\tCtrl+2", ID_SET_DURATION_2, GRAYED
MENUITEM "&Quarter Note\tCtrl+3", ID_SET_DURATION_3, GRAYED
MENUITEM "&Eighth Note\tCtrl+4", ID_SET_DURATION_4, GRAYED
MENUITEM "&Sixteenth Note\tCtrl+5", ID_SET_DURATION_5, GRAYED
MENUITEM "&Thirty-second Note\tCtrl+6", ID_SET_DURATION_6, GRAYED
}
END
POPUP "&Options"
BEGIN
Expand Down Expand Up @@ -115,7 +126,7 @@ STYLE 0
CAPTION "About EB Music Editor"
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "EarthBound Music Editor v2.204: released 2015-10-31\r\nProgrammed by Goplat\r\nAdditional programming by BlueStone\r\n\r\nDefault BGM titles based on 4F90A.txt by Michael1\r\n", 0,
LTEXT "EarthBound Music Editor v2.3.0: released 2015-10-31\r\nProgrammed by Goplat\r\nAdditional programming by BlueStone\r\n\r\nDefault BGM titles based on 4F90A.txt by Michael1\r\n", 0,
5, 5, 190, 55
DEFPUSHBUTTON "&OK", IDOK, 145, 51, 50, 14
END
Expand Down
171 changes: 166 additions & 5 deletions src/tracker.c
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,12 @@ LRESULT CALLBACK EditorWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPara
ID_SPLIT_PATTERN, ID_JOIN_PATTERNS,
ID_MAKE_SUBROUTINE, ID_UNMAKE_SUBROUTINE, ID_TRANSPOSE,
ID_CLEAR_SONG,
ID_ZOOM_IN, ID_ZOOM_OUT, 0
ID_ZOOM_IN, ID_ZOOM_OUT,
ID_INCREMENT_DURATION, ID_DECREMENT_DURATION,
ID_SET_DURATION_1, ID_SET_DURATION_2,
ID_SET_DURATION_3, ID_SET_DURATION_4,
ID_SET_DURATION_5, ID_SET_DURATION_6,
0
};
switch (uMsg) {
case WM_CREATE:
Expand Down Expand Up @@ -719,6 +724,9 @@ static BOOL cursor_home(BOOL select) {
return TRUE;
}

/// \brief Attempts to move the cursor back by one control code.
/// \return Returns false if the cursor cannot be moved backwards due
/// to already being at the top of the track, otherwise returns true.
static BOOL cursor_back(BOOL select) {
int prev_pos;
struct parser prev;
Expand Down Expand Up @@ -940,6 +948,102 @@ static void delete_sel(BOOL cut) {
restore_cursor(t, start - t->track);
}

static void updateOrInsertDuration(BYTE(*callback)(BYTE, int), int durationOrOffset)
{
// We cannot insert a duration code before an 0x00 code,
// so ensure that's not the case before proceeding.
if (cursor_track->track != NULL
&& *cursor.ptr != 0)
{
BYTE* original_pos = cursor.ptr;
struct track* t = cursor_track;
int off = cursor.ptr - t->track;
if (*cursor.ptr >= 0x01 && *cursor.ptr <= 0x7F)
{
BYTE duration = callback(*cursor.ptr, durationOrOffset);
if (duration != 0)
{
*cursor.ptr = duration;
cur_song.changed = TRUE;
InvalidateRect(hwndTracker, NULL, FALSE);
}
}
else
{
// A duration code isn't selected so
// find the last duration and last note, if any.
BYTE* last_duration_pos = NULL;
BYTE* last_note_pos = NULL;
cursor_home(FALSE);
while (cursor.ptr != original_pos)
{
if (*cursor.ptr >= 0x01 && *cursor.ptr <= 0x7F)
last_duration_pos = cursor.ptr;
else if (*cursor.ptr >= 0x80 && *cursor.ptr <= 0xDF)
last_note_pos = cursor.ptr;

// Advance the cursor if possible and continue, otherwise break.
if (!cursor_fwd(FALSE))
break;
}

// If we found a duration and a note doesn't follow it (meaning
// the selected note follows the duration code), set the duration.
if (last_duration_pos != NULL
&& last_duration_pos > last_note_pos)
{
BYTE duration = callback(*last_duration_pos, durationOrOffset);
if (duration != 0)
{
*last_duration_pos = duration;

// restore the cursor position.
//cursor.ptr = original_pos;
pattern_changed();
restore_cursor(t, off);
}
}
else if (last_note_pos != NULL)
{
// Else if we found a note position and it comes after the last
// duration code (or there is none), insert a duration.
BYTE duration = callback(last_duration_pos == NULL ? state.chan[cursor_chan].note_len : *last_duration_pos, durationOrOffset);
if (duration != 0)
{
track_insert(1, (BYTE *)&duration);
cursor_fwd(FALSE);
}
}
}
}
}

static BYTE setDurationOffsetCallback(BYTE originalDuration, int offset)
{
BYTE newDuration = min(max(0x00, originalDuration + offset), 0xFF);
return (newDuration >= 0x01 && newDuration <= 0x7F) ? newDuration : 0;
}

static BYTE setDurationCallback(BYTE originalDuration, int duration)
{
return (duration >= 0x01 && duration <= 0x7F) ? duration : 0;
}

static void incrementDuration()
{
updateOrInsertDuration(setDurationOffsetCallback, 1);
}

static void decrementDuration()
{
updateOrInsertDuration(setDurationOffsetCallback, -1);
}

static void setDuration(BYTE duration)
{
updateOrInsertDuration(setDurationCallback, duration);
}

void editor_command(int id) {
switch (id) {
case ID_CUT: delete_sel(TRUE); break;
Expand Down Expand Up @@ -1061,6 +1165,30 @@ void editor_command(int id) {
zoom = zoom_levels[++zoom_idx];
InvalidateRect(hwndTracker, NULL, FALSE);
break;
case ID_INCREMENT_DURATION:
incrementDuration();
break;
case ID_DECREMENT_DURATION:
decrementDuration();
break;
case ID_SET_DURATION_1:
setDuration(0x60);
break;
case ID_SET_DURATION_2:
setDuration(0x30);
break;
case ID_SET_DURATION_3:
setDuration(0x18);
break;
case ID_SET_DURATION_4:
setDuration(0x0C);
break;
case ID_SET_DURATION_5:
setDuration(0x06);
break;
case ID_SET_DURATION_6:
setDuration(0x03);
break;
}
}

Expand Down Expand Up @@ -1132,16 +1260,49 @@ static void tracker_keydown(WPARAM wParam) {
case VK_DELETE:
delete_sel(shift);
break;
case VK_ADD:
incrementDuration();
break;
case VK_SUBTRACT:
decrementDuration();
break;
case VK_NUMPAD1:
setDuration(0x60);
break;
case VK_NUMPAD2:
setDuration(0x30);
break;
case VK_NUMPAD3:
setDuration(0x18);
break;
case VK_NUMPAD4:
setDuration(0x0C);
break;
case VK_NUMPAD5:
setDuration(0x06);
break;
case VK_NUMPAD6:
setDuration(0x03);
break;
default:
if (control) {
if (wParam == 'C') copy_sel();
else if (wParam == 'V') paste_sel();
else if (wParam == 'X') delete_sel(TRUE);
break;
else if (wParam == VK_OEM_COMMA) decrementDuration();
else if (wParam == VK_OEM_PERIOD) incrementDuration();
else if (wParam == '1') setDuration(0x60);
else if (wParam == '2') setDuration(0x30);
else if (wParam == '3') setDuration(0x18);
else if (wParam == '4') setDuration(0x0C);
else if (wParam == '5') setDuration(0x06);
else if (wParam == '6') setDuration(0x03);
}
else
{
int note = note_from_key(wParam, shift);
addOrInsertNote(note);
}

int note = note_from_key(wParam, shift);
addOrInsertNote(note);
break;
}
}
Expand Down

0 comments on commit 2c534f5

Please sign in to comment.