diff --git a/CHANGELOG b/CHANGELOG index 4e6ba592..9a7b7e80 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,7 @@ -1.6.0-bacon1 +1.6.0-bacon2 + Interpolate values in tables and phrases + R + B on single-column selection will fill values from lowest to highest + Contributions: drbscl Add 64 bit soundfont support (#211) diff --git a/docs/wiki/What-is-LittlePiggyTracker.md b/docs/wiki/What-is-LittlePiggyTracker.md index a3adff3b..52c6fd3c 100644 --- a/docs/wiki/What-is-LittlePiggyTracker.md +++ b/docs/wiki/What-is-LittlePiggyTracker.md @@ -118,6 +118,7 @@ Note: CTRL Key mappings of RT and LT are inverted. Since the keyboard's Arrow Ke - B+LEFT/RIGHT: Next/Previous Channel in Chain/Phrase Screen. Navigation +/- 1 in Instrument/Table Screen. Switch between Song and Live Modes in Song Screen. - RT+ARROWS: Navigate between the Screens. - LT+UP/DOWN: Jump up/down to next populated row after a blank row (great for live mode entire row queuing!) +- RT+B: in chains or tables, a single-column selection will fill values from lowest to highest ## Selections @@ -137,6 +138,14 @@ And then: - LT+A: paste the clipboard content at current location +- RT+B: in chains or tables, a single-column selection will fill values from lowest to highest + +00 01 00 01 +01 -- => 01 02 +02 -- 02 03 +03 04 03 04 + + ## Playback Modes and Controls There are two modes for playback, Song and Live. The controls in each mode differ slightly. diff --git a/sources/Application/Model/Project.h b/sources/Application/Model/Project.h index 3a3c6d68..5b8f5c1a 100644 --- a/sources/Application/Model/Project.h +++ b/sources/Application/Model/Project.h @@ -20,7 +20,7 @@ #define PROJECT_NUMBER "1" #define PROJECT_RELEASE "6" -#define BUILD_COUNT "0-bacon1" +#define BUILD_COUNT "0-bacon2" #define MAX_TAP 3 diff --git a/sources/Application/Views/PhraseView.cpp b/sources/Application/Views/PhraseView.cpp index c95bfb46..f370306a 100644 --- a/sources/Application/Views/PhraseView.cpp +++ b/sources/Application/Views/PhraseView.cpp @@ -505,6 +505,72 @@ void PhraseView::extendSelection() { isDirty_ = true; } } + +/****************************************************** + interpolateSelection: + expands the lowest value of selection to the highest + ******************************************************/ +void PhraseView::interpolateSelection() { + if (!clipboard_.active_) { + return; + } + + GUIRect rect = getSelectionRect(); + // Only interpolate if we're in note (0) or param (3, 5) columns + int col = rect.Left(); + if (col != rect.Right() || (col != 0 && col != 3 && col != 5)) { + return; + } + + int startRow = rect.Top(); + int endRow = rect.Bottom(); + // Need at least 2 rows to interpolate + if (endRow - startRow < 1) { + return; + } + + // Select the appropriate data array based on column + if (col == 0) { + // Note column + uchar *noteData = phrase_->note_ + (16 * viewData_->currentPhrase_); + + uchar startNote = noteData[startRow]; + uchar endNote = noteData[endRow]; + + if (startNote == 0xFF || endNote == 0xFF) { + View::SetNotification("No note info"); + return; + } + + int numSteps = endRow - startRow; + int noteDiff = (int)endNote - (int)startNote; + + for (int step = 0; step <= numSteps; step++) { + int row = startRow + step; + int value = startNote + (2 * noteDiff * step + numSteps) / (2 * numSteps); + noteData[row] = (uchar)value; + } + } else { + // Parameter columns (3 or 5) + ushort *paramData = (col == 3) ? + phrase_->param1_ + (16 * viewData_->currentPhrase_) : + phrase_->param2_ + (16 * viewData_->currentPhrase_); + + ushort startParam = paramData[startRow]; + ushort endParam = paramData[endRow]; + + int numSteps = endRow - startRow; + int paramDiff = (int)endParam - (int)startParam; + + for (int step = 0; step <= numSteps; step++) { + int row = startRow + step; + int value = startParam + (2 * paramDiff * step + numSteps) / (2 * numSteps); + paramData[row] = (ushort)value; + } + } + isDirty_ = true; +} + /****************************************************** copySelection: copies data in the current selection to the @@ -992,6 +1058,8 @@ void PhraseView::processSelectionButtonMask(unsigned short mask) { if (mask & EPBM_B) { if (mask & EPBM_L) { extendSelection(); + } else if (mask & EPBM_R) { + interpolateSelection(); } else { copySelection(); } @@ -1210,7 +1278,7 @@ void PhraseView::DrawView() { DrawString(pos._x, pos._y, buffer, props); setTextProps(props, 2, j, true); pos._y++; - if (j == row_ && (col_ == 2 || col_ == 3)) { + if (j == row_ && col_ == 2) { printHelpLegend(command, props); } } @@ -1257,7 +1325,7 @@ void PhraseView::DrawView() { DrawString(pos._x, pos._y, buffer, props); setTextProps(props, 4, j, true); pos._y++; - if (j == row_ && (col_ == 4 || col_ == 5)) { + if (j == row_ && col_ == 4) { printHelpLegend(command, props); } } diff --git a/sources/Application/Views/PhraseView.h b/sources/Application/Views/PhraseView.h index 7693164d..1e266254 100644 --- a/sources/Application/Views/PhraseView.h +++ b/sources/Application/Views/PhraseView.h @@ -33,6 +33,7 @@ class PhraseView : public View { GUIRect getSelectionRect(); void fillClipboardData(); + void interpolateSelection(); void copySelection(); void cutSelection(); void pasteClipboard(); diff --git a/sources/Application/Views/TableView.cpp b/sources/Application/Views/TableView.cpp index f16355d8..1fe50cad 100644 --- a/sources/Application/Views/TableView.cpp +++ b/sources/Application/Views/TableView.cpp @@ -119,6 +119,57 @@ void TableView::extendSelection() { } } +/****************************************************** + interpolateSelection: + expands the lowest value of selection to the highest + ******************************************************/ +void TableView::interpolateSelection() { + if (!clipboard_.active_) { + return; + } + + GUIRect rect = getSelectionRect(); + + // Only interpolate if we're in param columns (1, 3, 5) + int col = rect.Left(); + if (col != rect.Right() || (col != 1 && col != 3 && col != 5)) { + return; + } + + int startRow = rect.Top(); + int endRow = rect.Bottom(); + + // Need at least 2 rows to interpolate + if (endRow - startRow < 1) { + return; + } + + Table &table = TableHolder::GetInstance()->GetTable(viewData_->currentTable_); + + ushort *paramData; + if (col == 1) { + paramData = table.param1_; + } else if (col == 3) { + paramData = table.param2_; + } else { + paramData = table.param3_; + } + + ushort startParam = paramData[startRow]; + ushort endParam = paramData[endRow]; + + int numSteps = endRow - startRow; + int paramDiff = (int)endParam - (int)startParam; + + for (int step = 0; step <= numSteps; step++) { + int row = startRow + step; + int value = startParam + (2 * paramDiff * step + numSteps) / (2 * numSteps); + paramData[row] = (ushort)value; + } + + isDirty_ = true; +} + void TableView::copySelection() { // Keep up with row,col of selection coz @@ -619,6 +670,8 @@ void TableView::processSelectionButtonMask(unsigned short mask) { if (mask & EPBM_B) { if (mask & EPBM_L) { extendSelection(); + } else if (mask & EPBM_R) { + interpolateSelection(); } else { copySelection(); } @@ -750,7 +803,7 @@ void TableView::DrawView() { DrawString(pos._x, pos._y, buffer, props); setTextProps(props, 0, j, true); pos._y++; - if (j == row_ && (col_ == 0 || col_ == 1)) { + if (j == row_ && col_ == 0) { printHelpLegend(command, props); } } @@ -788,7 +841,7 @@ void TableView::DrawView() { DrawString(pos._x, pos._y, buffer, props); setTextProps(props, 2, j, true); pos._y++; - if (j == row_ && (col_ == 2 || col_ == 3)) { + if (j == row_ && col_ == 2) { printHelpLegend(command, props); } } @@ -826,7 +879,7 @@ void TableView::DrawView() { DrawString(pos._x, pos._y, buffer, props); setTextProps(props, 4, j, true); pos._y++; - if (j == row_ && (col_ == 4 || col_ == 5)) { + if (j == row_ && col_ == 5) { printHelpLegend(command, props); } } diff --git a/sources/Application/Views/TableView.h b/sources/Application/Views/TableView.h index 38a68a53..db11ca99 100644 --- a/sources/Application/Views/TableView.h +++ b/sources/Application/Views/TableView.h @@ -21,6 +21,7 @@ class TableView : public View { void cutPosition(); void pasteLast(); + void interpolateSelection(); void copySelection(); void cutSelection(); void pasteClipboard();