From 2dae5c788f8211f995c1a4e1f6b59ff8b58d4a9e Mon Sep 17 00:00:00 2001 From: djdiskmachine <110535302+djdiskmachine@users.noreply.github.com> Date: Wed, 12 Nov 2025 19:25:41 +0000 Subject: [PATCH 1/3] Interpolate selection Select rectangle of value columns then R+B will fill in values from the lowest to the highest. Gets very busy when notifications collide with help legend. --- sources/Application/Model/Project.h | 4 +- sources/Application/Views/PhraseView.cpp | 68 ++++++++++++++++++++++++ sources/Application/Views/PhraseView.h | 1 + 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/sources/Application/Model/Project.h b/sources/Application/Model/Project.h index f4bb4410..2079df12 100644 --- a/sources/Application/Model/Project.h +++ b/sources/Application/Model/Project.h @@ -19,8 +19,8 @@ #define VAR_SCALE MAKE_FOURCC('S', 'C', 'A', 'L') #define PROJECT_NUMBER "1" -#define PROJECT_RELEASE "5" -#define BUILD_COUNT "0-bacon3" +#define PROJECT_RELEASE "6" +#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..823bf49d 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(); } 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(); From 3318b6414bc54ce156d256ddc18cd6876fed5c2d Mon Sep 17 00:00:00 2001 From: djdiskmachine <110535302+djdiskmachine@users.noreply.github.com> Date: Thu, 13 Nov 2025 21:00:00 +0200 Subject: [PATCH 2/3] Interpolate in tables Removes help legend in value columns, keep only in command cols --- sources/Application/Views/PhraseView.cpp | 4 +- sources/Application/Views/TableView.cpp | 59 ++++++++++++++++++++++-- sources/Application/Views/TableView.h | 1 + 3 files changed, 59 insertions(+), 5 deletions(-) diff --git a/sources/Application/Views/PhraseView.cpp b/sources/Application/Views/PhraseView.cpp index 823bf49d..f370306a 100644 --- a/sources/Application/Views/PhraseView.cpp +++ b/sources/Application/Views/PhraseView.cpp @@ -1278,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); } } @@ -1325,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/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(); From a6dd0ba6d72b7869ddfb34ed0050abeae9fdb6b5 Mon Sep 17 00:00:00 2001 From: djdiskmachine <110535302+djdiskmachine@users.noreply.github.com> Date: Thu, 13 Nov 2025 18:28:58 +0000 Subject: [PATCH 3/3] Update CHANGELOG and documentation --- CHANGELOG | 5 +++++ docs/wiki/What-is-LittlePiggyTracker.md | 9 +++++++++ 2 files changed, 14 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 2be5d1f0..c5b33a37 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +1.6.0-bacon2 + Interpolate values in tables and phrases + R + B on single-column selection will fill values from lowest to highest + Good for plotting out fx rises or note scales + 1.5.0-bacon3 Contributions: purelygrey diff --git a/docs/wiki/What-is-LittlePiggyTracker.md b/docs/wiki/What-is-LittlePiggyTracker.md index 13641f55..22dbdd36 100644 --- a/docs/wiki/What-is-LittlePiggyTracker.md +++ b/docs/wiki/What-is-LittlePiggyTracker.md @@ -117,6 +117,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 @@ -136,6 +137,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.