diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 0d43dda2..df7c4cf7 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -3901,42 +3901,92 @@ void FurnaceGUI::finishSelection() { selEnd.xFine^=selStart.xFine; } selecting=false; + + // boundary check + int chanCount=e->getTotalChannelCount(); + + if (selStart.xCoarse<0) selStart.xCoarse=0; + if (selStart.xCoarse>=chanCount) selStart.xCoarse=chanCount-1; + if (selStart.y<0) selStart.y=0; + if (selStart.y>=e->song.patLen) selStart.y=e->song.patLen-1; + if (selEnd.xCoarse<0) selEnd.xCoarse=0; + if (selEnd.xCoarse>=chanCount) selEnd.xCoarse=chanCount-1; + if (selEnd.y<0) selEnd.y=0; + if (selEnd.y>=e->song.patLen) selEnd.y=e->song.patLen-1; + if (cursor.xCoarse<0) cursor.xCoarse=0; + if (cursor.xCoarse>=chanCount) cursor.xCoarse=chanCount-1; + if (cursor.y<0) cursor.y=0; + if (cursor.y>=e->song.patLen) cursor.y=e->song.patLen-1; } +#define DETERMINE_FIRST \ + int firstChannel=0; \ + for (int i=0; igetTotalChannelCount(); i++) { \ + if (e->song.chanShow[i]) { \ + firstChannel=i; \ + break; \ + } \ + } \ + +#define DETERMINE_LAST \ + int lastChannel=0; \ + for (int i=e->getTotalChannelCount()-1; i>=0; i--) { \ + if (e->song.chanShow[i]) { \ + lastChannel=i+1; \ + break; \ + } \ + } + +#define DETERMINE_FIRST_LAST \ + DETERMINE_FIRST \ + DETERMINE_LAST + void FurnaceGUI::moveCursor(int x, int y, bool select) { if (!select) { finishSelection(); } + + DETERMINE_FIRST_LAST; + curNibble=false; if (x!=0) { if (x>0) { for (int i=0; i=3+e->song.pat[cursor.xCoarse].effectRows*2) { cursor.xFine=0; - if (++cursor.xCoarse>=e->getTotalChannelCount()) { + if (++cursor.xCoarse>=lastChannel) { if (settings.wrapHorizontal!=0 && !select) { - cursor.xCoarse=0; + cursor.xCoarse=firstChannel; if (settings.wrapHorizontal==2) y++; } else { - cursor.xCoarse=e->getTotalChannelCount()-1; + cursor.xCoarse=lastChannel-1; cursor.xFine=2+e->song.pat[cursor.xCoarse].effectRows*2; } + } else { + while (!e->song.chanShow[cursor.xCoarse]) { + cursor.xCoarse++; + if (cursor.xCoarse>=e->getTotalChannelCount()) break; + } } } } } else { for (int i=0; i<-x; i++) { if (--cursor.xFine<0) { - if (--cursor.xCoarse<0) { + if (--cursor.xCoarsegetTotalChannelCount()-1; + cursor.xCoarse=lastChannel-1; cursor.xFine=2+e->song.pat[cursor.xCoarse].effectRows*2; if (settings.wrapHorizontal==2) y--; } else { - cursor.xCoarse=0; + cursor.xCoarse=firstChannel; cursor.xFine=0; } } else { + while (!e->song.chanShow[cursor.xCoarse]) { + cursor.xCoarse--; + if (cursor.xCoarse<0) break; + } cursor.xFine=2+e->song.pat[cursor.xCoarse].effectRows*2; } } @@ -4155,6 +4205,7 @@ void FurnaceGUI::doDelete() { int iFine=selStart.xFine; int ord=e->getOrder(); for (; iCoarse<=selEnd.xCoarse; iCoarse++) { + if (!e->song.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true); for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsegetOrder(); for (; iCoarse<=selEnd.xCoarse; iCoarse++) { + if (!e->song.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true); for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.patLen; j++) { @@ -4218,6 +4270,7 @@ void FurnaceGUI::doInsert() { int iFine=selStart.xFine; int ord=e->getOrder(); for (; iCoarse<=selEnd.xCoarse; iCoarse++) { + if (!e->song.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true); for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.patLen-1; j>=selStart.y; j--) { @@ -4249,6 +4302,7 @@ void FurnaceGUI::doTranspose(int amount) { int iFine=selStart.xFine; int ord=e->getOrder(); for (; iCoarse<=selEnd.xCoarse; iCoarse++) { + if (!e->song.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true); for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsegetOrder(); clipboard+='\n'; for (; iCoarse<=selEnd.xCoarse; iCoarse++) { + if (!e->song.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true); for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsegetOrder(); @@ -4372,10 +4429,14 @@ void FurnaceGUI::doPaste() { String& line=data[i]; - while (charPosgetTotalChannelCount()) { + while (charPossong.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][ord],true); if (line[charPos]=='|') { iCoarse++; + if (iCoarsesong.chanShow[iCoarse]) { + iCoarse++; + if (iCoarse>=lastChannel) break; + } iFine=0; charPos++; continue;