diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 34e7c6b04..361dd255a 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -3544,14 +3544,14 @@ void DivEngine::delSample(int index) { BUSY_END; } -void DivEngine::addOrder(bool duplicate, bool where) { +void DivEngine::addOrder(int pos, bool duplicate, bool where) { unsigned char order[DIV_MAX_CHANS]; if (curSubSong->ordersLen>=(DIV_MAX_PATTERNS-1)) return; memset(order,0,DIV_MAX_CHANS); BUSY_BEGIN_SOFT; if (duplicate) { for (int i=0; iord[i][curOrder]; + order[i]=curOrders->ord[i][pos]; } } else { bool used[DIV_MAX_PATTERNS]; @@ -3579,14 +3579,14 @@ void DivEngine::addOrder(bool duplicate, bool where) { } else { // after current order saveLock.lock(); for (int i=0; iordersLen; j>curOrder; j--) { + for (int j=curSubSong->ordersLen; j>pos; j--) { curOrders->ord[i][j]=curOrders->ord[i][j-1]; } - curOrders->ord[i][curOrder+1]=order[i]; + curOrders->ord[i][pos+1]=order[i]; } curSubSong->ordersLen++; saveLock.unlock(); - curOrder++; + if (pos<=curOrder) curOrder++; if (playing && !freelance) { playSub(false); } @@ -3594,7 +3594,7 @@ void DivEngine::addOrder(bool duplicate, bool where) { BUSY_END; } -void DivEngine::deepCloneOrder(bool where) { +void DivEngine::deepCloneOrder(int pos, bool where) { unsigned char order[DIV_MAX_CHANS]; if (curSubSong->ordersLen>=(DIV_MAX_PATTERNS-1)) return; warnings=""; @@ -3602,7 +3602,7 @@ void DivEngine::deepCloneOrder(bool where) { for (int i=0; iord[i][curOrder]; + order[i]=curOrders->ord[i][pos]; // find free slot for (int j=0; jordersLen; j>curOrder; j--) { + for (int j=curSubSong->ordersLen; j>pos; j--) { curOrders->ord[i][j]=curOrders->ord[i][j-1]; } - curOrders->ord[i][curOrder+1]=order[i]; + curOrders->ord[i][pos+1]=order[i]; } curSubSong->ordersLen++; saveLock.unlock(); - curOrder++; + if (pos<=curOrder) curOrder++; if (playing && !freelance) { playSub(false); } @@ -3646,17 +3646,18 @@ void DivEngine::deepCloneOrder(bool where) { BUSY_END; } -void DivEngine::deleteOrder() { +void DivEngine::deleteOrder(int pos) { if (curSubSong->ordersLen<=1) return; BUSY_BEGIN_SOFT; saveLock.lock(); for (int i=0; iordersLen; j++) { + for (int j=pos; jordersLen; j++) { curOrders->ord[i][j]=curOrders->ord[i][j+1]; } } curSubSong->ordersLen--; saveLock.unlock(); + if (curOrder>pos) curOrder--; if (curOrder>=curSubSong->ordersLen) curOrder=curSubSong->ordersLen-1; if (playing && !freelance) { playSub(false); @@ -3664,40 +3665,46 @@ void DivEngine::deleteOrder() { BUSY_END; } -void DivEngine::moveOrderUp() { +void DivEngine::moveOrderUp(int& pos) { BUSY_BEGIN_SOFT; - if (curOrder<1) { + if (pos<1) { BUSY_END; return; } saveLock.lock(); for (int i=0; iord[i][curOrder]^=curOrders->ord[i][curOrder-1]; - curOrders->ord[i][curOrder-1]^=curOrders->ord[i][curOrder]; - curOrders->ord[i][curOrder]^=curOrders->ord[i][curOrder-1]; + curOrders->ord[i][pos]^=curOrders->ord[i][pos-1]; + curOrders->ord[i][pos-1]^=curOrders->ord[i][pos]; + curOrders->ord[i][pos]^=curOrders->ord[i][pos-1]; } saveLock.unlock(); - curOrder--; + if (curOrder==pos) { + curOrder--; + } + pos--; if (playing && !freelance) { playSub(false); } BUSY_END; } -void DivEngine::moveOrderDown() { +void DivEngine::moveOrderDown(int& pos) { BUSY_BEGIN_SOFT; - if (curOrder>=curSubSong->ordersLen-1) { + if (pos>=curSubSong->ordersLen-1) { BUSY_END; return; } saveLock.lock(); for (int i=0; iord[i][curOrder]^=curOrders->ord[i][curOrder+1]; - curOrders->ord[i][curOrder+1]^=curOrders->ord[i][curOrder]; - curOrders->ord[i][curOrder]^=curOrders->ord[i][curOrder+1]; + curOrders->ord[i][pos]^=curOrders->ord[i][pos+1]; + curOrders->ord[i][pos+1]^=curOrders->ord[i][pos]; + curOrders->ord[i][pos]^=curOrders->ord[i][pos+1]; } saveLock.unlock(); - curOrder++; + if (curOrder==pos) { + curOrder++; + } + pos++; if (playing && !freelance) { playSub(false); } diff --git a/src/engine/engine.h b/src/engine/engine.h index 9b26c4737..e88227e01 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -810,19 +810,19 @@ class DivEngine { void delSample(int index); // add order - void addOrder(bool duplicate, bool where); + void addOrder(int pos, bool duplicate, bool where); // deep clone orders - void deepCloneOrder(bool where); + void deepCloneOrder(int pos, bool where); // delete order - void deleteOrder(); + void deleteOrder(int pos); // move order up - void moveOrderUp(); + void moveOrderUp(int& pos); // move order down - void moveOrderDown(); + void moveOrderDown(int& pos); // move thing up bool moveInsUp(int which); diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index 83ab4e37e..85da41c9b 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -1471,17 +1471,17 @@ void FurnaceGUI::doAction(int what) { break; case GUI_ACTION_ORDERS_ADD: prepareUndo(GUI_UNDO_CHANGE_ORDER); - e->addOrder(false,false); + e->addOrder(curOrder,false,false); makeUndo(GUI_UNDO_CHANGE_ORDER); break; case GUI_ACTION_ORDERS_DUPLICATE: prepareUndo(GUI_UNDO_CHANGE_ORDER); - e->addOrder(true,false); + e->addOrder(curOrder,true,false); makeUndo(GUI_UNDO_CHANGE_ORDER); break; case GUI_ACTION_ORDERS_DEEP_CLONE: prepareUndo(GUI_UNDO_CHANGE_ORDER); - e->deepCloneOrder(false); + e->deepCloneOrder(curOrder,false); makeUndo(GUI_UNDO_CHANGE_ORDER); if (!e->getWarnings().empty()) { showWarning(e->getWarnings(),GUI_WARN_GENERIC); @@ -1489,12 +1489,12 @@ void FurnaceGUI::doAction(int what) { break; case GUI_ACTION_ORDERS_DUPLICATE_END: prepareUndo(GUI_UNDO_CHANGE_ORDER); - e->addOrder(true,true); + e->addOrder(curOrder,true,true); makeUndo(GUI_UNDO_CHANGE_ORDER); break; case GUI_ACTION_ORDERS_DEEP_CLONE_END: prepareUndo(GUI_UNDO_CHANGE_ORDER); - e->deepCloneOrder(true); + e->deepCloneOrder(curOrder,true); makeUndo(GUI_UNDO_CHANGE_ORDER); if (!e->getWarnings().empty()) { showWarning(e->getWarnings(),GUI_WARN_GENERIC); @@ -1502,7 +1502,7 @@ void FurnaceGUI::doAction(int what) { break; case GUI_ACTION_ORDERS_REMOVE: prepareUndo(GUI_UNDO_CHANGE_ORDER); - e->deleteOrder(); + e->deleteOrder(curOrder); if (curOrder>=e->curSubSong->ordersLen) { curOrder=e->curSubSong->ordersLen-1; oldOrder=curOrder; @@ -1513,12 +1513,12 @@ void FurnaceGUI::doAction(int what) { break; case GUI_ACTION_ORDERS_MOVE_UP: prepareUndo(GUI_UNDO_CHANGE_ORDER); - e->moveOrderUp(); + e->moveOrderUp(curOrder); makeUndo(GUI_UNDO_CHANGE_ORDER); break; case GUI_ACTION_ORDERS_MOVE_DOWN: prepareUndo(GUI_UNDO_CHANGE_ORDER); - e->moveOrderDown(); + e->moveOrderDown(curOrder); makeUndo(GUI_UNDO_CHANGE_ORDER); break; case GUI_ACTION_ORDERS_REPLAY: