mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-22 20:45:11 +00:00
GUI_ACTION_PAT_ABSORB_INSTRUMENT search through prior orders (also set instrument to none if no instrument found
This commit is contained in:
parent
c5310d1855
commit
d0f3e0fa58
3 changed files with 48 additions and 24 deletions
|
@ -681,30 +681,7 @@ void FurnaceGUI::doAction(int what) {
|
||||||
latchNibble=false;
|
latchNibble=false;
|
||||||
break;
|
break;
|
||||||
case GUI_ACTION_PAT_ABSORB_INSTRUMENT: {
|
case GUI_ACTION_PAT_ABSORB_INSTRUMENT: {
|
||||||
DivPattern* pat=e->curPat[cursor.xCoarse].getPattern(e->curOrders->ord[cursor.xCoarse][curOrder],false);
|
doAbsorbInstrument();
|
||||||
if (!pat) break;
|
|
||||||
bool foundIns=false;
|
|
||||||
bool foundOctave=false;
|
|
||||||
for (int i=cursor.y; i>=0 && !(foundIns && foundOctave); i--) {
|
|
||||||
// absorb most recent instrument
|
|
||||||
if (!foundIns && pat->data[i][2] >= 0) {
|
|
||||||
curIns=pat->data[i][2];
|
|
||||||
foundIns=true;
|
|
||||||
}
|
|
||||||
// absorb most recent octave (i.e. set curOctave such that the "main row" (QWERTY) of notes
|
|
||||||
// will result in an octave number equal to the previous note).
|
|
||||||
if (!foundOctave && pat->data[i][0] != 0) {
|
|
||||||
// decode octave data (was signed cast to unsigned char)
|
|
||||||
int octave=pat->data[i][1];
|
|
||||||
if (octave>128) octave-=256;
|
|
||||||
// @NOTE the special handling when note==12, which is really an octave above what's
|
|
||||||
// stored in the octave data. without this handling, if you press Q, then
|
|
||||||
// "ABSORB_INSTRUMENT", then Q again, you'd get a different octave!
|
|
||||||
if (pat->data[i][0]==12) octave++;
|
|
||||||
curOctave=CLAMP(octave-1, GUI_EDIT_OCTAVE_MIN, GUI_EDIT_OCTAVE_MAX);
|
|
||||||
foundOctave=true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1823,6 +1823,52 @@ void FurnaceGUI::doExpandSong(int multiplier) {
|
||||||
if (e->isPlaying()) e->play();
|
if (e->isPlaying()) e->play();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void FurnaceGUI::doAbsorbInstrument() {
|
||||||
|
bool foundIns=false;
|
||||||
|
bool foundOctave=false;
|
||||||
|
auto foundAll = [&]() { return foundIns && foundOctave; };
|
||||||
|
|
||||||
|
// search this order and all prior until we find all the data we need
|
||||||
|
int orderIdx=curOrder;
|
||||||
|
for (; orderIdx>=0 && !foundAll(); orderIdx--) {
|
||||||
|
DivPattern* pat=e->curPat[cursor.xCoarse].getPattern(e->curOrders->ord[cursor.xCoarse][orderIdx],false);
|
||||||
|
if (!pat) continue;
|
||||||
|
|
||||||
|
// start on current row when searching current order, but start from end when searching
|
||||||
|
// prior orders.
|
||||||
|
int searchStartRow=orderIdx==curOrder ? cursor.y : e->curSubSong->patLen-1;
|
||||||
|
for (int i=searchStartRow; i>=0 && !foundAll(); i--) {
|
||||||
|
|
||||||
|
// absorb most recent instrument
|
||||||
|
if (!foundIns && pat->data[i][2] >= 0) {
|
||||||
|
foundIns=true;
|
||||||
|
curIns=pat->data[i][2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// absorb most recent octave (i.e. set curOctave such that the "main row" (QWERTY) of
|
||||||
|
// notes will result in an octave number equal to the previous note).
|
||||||
|
if (!foundOctave && pat->data[i][0] != 0) {
|
||||||
|
foundOctave=true;
|
||||||
|
|
||||||
|
// decode octave data (was signed cast to unsigned char)
|
||||||
|
int octave=pat->data[i][1];
|
||||||
|
if (octave>128) octave-=256;
|
||||||
|
|
||||||
|
// @NOTE the special handling when note==12, which is really an octave above what's
|
||||||
|
// stored in the octave data. without this handling, if you press Q, then
|
||||||
|
// "ABSORB_INSTRUMENT", then Q again, you'd get a different octave!
|
||||||
|
if (pat->data[i][0]==12) octave++;
|
||||||
|
curOctave=CLAMP(octave-1, GUI_EDIT_OCTAVE_MIN, GUI_EDIT_OCTAVE_MAX);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if no instrument has been set at this point, the only way to match it is to use "none"
|
||||||
|
if (!foundIns) curIns=-1;
|
||||||
|
|
||||||
|
logD("doAbsorbInstrument -- searched %d orders", curOrder-orderIdx);
|
||||||
|
}
|
||||||
|
|
||||||
void FurnaceGUI::doDrag() {
|
void FurnaceGUI::doDrag() {
|
||||||
int len=dragEnd.xCoarse-dragStart.xCoarse+1;
|
int len=dragEnd.xCoarse-dragStart.xCoarse+1;
|
||||||
|
|
||||||
|
|
|
@ -2922,6 +2922,7 @@ class FurnaceGUI {
|
||||||
void doExpand(int multiplier, const SelectionPoint& sStart, const SelectionPoint& sEnd);
|
void doExpand(int multiplier, const SelectionPoint& sStart, const SelectionPoint& sEnd);
|
||||||
void doCollapseSong(int divider);
|
void doCollapseSong(int divider);
|
||||||
void doExpandSong(int multiplier);
|
void doExpandSong(int multiplier);
|
||||||
|
void doAbsorbInstrument();
|
||||||
void doUndo();
|
void doUndo();
|
||||||
void doRedo();
|
void doRedo();
|
||||||
void doFind();
|
void doFind();
|
||||||
|
|
Loading…
Reference in a new issue