diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 185f03633..a62ae36e2 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -140,7 +140,7 @@ void DivEngine::walkSong(int& loopOrder, int& loopRow, int& loopEnd) { for (int j=nextRow; jdata[j][5+(l<<1)]; if (effectVal<0) effectVal=0; if (pat[k]->data[j][4+(l<<1)]==0x0d) { diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index 3996f2d0b..16678c49b 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -637,14 +637,14 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { for (int i=0; i4 || chan.effectRows<1) { - logE("invalid effect row count %d. are you sure everything is ok?",chan.effectRows); - lastError="file is corrupt or unreadable at effect rows"; + logD("%d fx rows: %d",i,chan.effectCols); + if (chan.effectCols>4 || chan.effectCols<1) { + logE("invalid effect column count %d. are you sure everything is ok?",chan.effectCols); + lastError="file is corrupt or unreadable at effect columns"; delete[] file; return false; } @@ -694,7 +694,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { pat->data[k][3]=(pat->data[k][3]&3)*5; } } - for (int l=0; ldata[k][4+(l<<1)]=reader.readS(); pat->data[k][5+(l<<1)]=reader.readS(); @@ -1291,10 +1291,10 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { } for (int i=0; i8) { - logE("channel %d has zero or too many effect columns! (%d)",i,ds.pat[i].effectRows); - lastError=fmt::sprintf("channel %d has too many effect columns! (%d)",i,ds.pat[i].effectRows); + ds.pat[i].effectCols=reader.readC(); + if (ds.pat[i].effectCols<1 || ds.pat[i].effectCols>8) { + logE("channel %d has zero or too many effect columns! (%d)",i,ds.pat[i].effectCols); + lastError=fmt::sprintf("channel %d has too many effect columns! (%d)",i,ds.pat[i].effectCols); delete[] file; return false; } @@ -1565,7 +1565,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { pat->data[j][1]=reader.readS(); pat->data[j][2]=reader.readS(); pat->data[j][3]=reader.readS(); - for (int k=0; kdata[j][4+(k<<1)]=reader.readS(); pat->data[j][5+(k<<1)]=reader.readS(); } @@ -1960,7 +1960,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) { } } } - ds.pat[ch].effectRows=fxCols; + ds.pat[ch].effectCols=fxCols; } ds.pal=false; @@ -1977,7 +1977,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) { ds.chanShortName[i]=fmt::sprintf("C%d",i+1); } for(int i=chCount; iwriteC(song.pat[i].effectRows); + w->writeC(song.pat[i].effectCols); } for (int i=0; iwriteS(pat->data[j][1]); // octave w->writeS(pat->data[j][2]); // instrument w->writeS(pat->data[j][3]); // volume - w->write(&pat->data[j][4],2*song.pat[i>>16].effectRows*2); // effects + w->write(&pat->data[j][4],2*song.pat[i>>16].effectCols*2); // effects } w->writeString(pat->name,false); @@ -2717,7 +2717,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) { } for (int i=0; iwriteC(song.pat[i].effectRows); + w->writeC(song.pat[i].effectCols); for (int j=0; jwriteS(pat->data[k][0]); // note w->writeS(pat->data[k][1]); // octave w->writeS(pat->data[k][3]); // volume - w->write(&pat->data[k][4],2*song.pat[i].effectRows*2); // effects + w->write(&pat->data[k][4],2*song.pat[i].effectCols*2); // effects w->writeS(pat->data[k][2]); // instrument } } diff --git a/src/engine/pattern.cpp b/src/engine/pattern.cpp index 8241255b3..4f4663cae 100644 --- a/src/engine/pattern.cpp +++ b/src/engine/pattern.cpp @@ -130,6 +130,6 @@ SafeReader* DivPattern::compile(int len, int fxRows) { } DivChannelData::DivChannelData(): - effectRows(1) { + effectCols(1) { memset(data,0,256*sizeof(void*)); } diff --git a/src/engine/pattern.h b/src/engine/pattern.h index fd0b0d076..4d1070f3b 100644 --- a/src/engine/pattern.h +++ b/src/engine/pattern.h @@ -40,7 +40,7 @@ struct DivPattern { }; struct DivChannelData { - unsigned char effectRows; + unsigned char effectCols; // data goes as follows: data[ROW][TYPE] // TYPE is: // 0: note diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index c2c20d3d0..13cc495b9 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -910,7 +910,7 @@ void DivEngine::processRow(int i, bool afterDelay) { int whatRow=afterDelay?chan[i].delayRow:curRow; DivPattern* pat=song.pat[i].getPattern(song.orders.ord[i][whatOrder],false); // pre effects - if (!afterDelay) for (int j=0; jdata[whatRow][4+(j<<1)]; short effectVal=pat->data[whatRow][5+(j<<1)]; @@ -1019,7 +1019,7 @@ void DivEngine::processRow(int i, bool afterDelay) { bool calledPorta=false; // effects - for (int j=0; jdata[whatRow][4+(j<<1)]; short effectVal=pat->data[whatRow][5+(j<<1)]; @@ -1338,7 +1338,7 @@ void DivEngine::processRow(int i, bool afterDelay) { chan[i].noteOnInhibit=false; // post effects - for (int j=0; jdata[whatRow][4+(j<<1)]; short effectVal=pat->data[whatRow][5+(j<<1)]; @@ -1375,7 +1375,7 @@ void DivEngine::nextRow() { snprintf(pb2,4095,"\x1b[0;36m%.2x",pat->data[curRow][2]); strcat(pb3,pb2); } - for (int j=0; jdata[curRow][4+(j<<1)]==-1) { strcat(pb3,"\x1b[m--"); } else { @@ -1449,7 +1449,7 @@ void DivEngine::nextRow() { if (song.oneTickCut) { bool doPrepareCut=true; - for (int j=0; jdata[curRow][4+(j<<1)]==0x03) { doPrepareCut=false; break; diff --git a/src/gui/cursor.cpp b/src/gui/cursor.cpp index 53652ec70..1fdf64d77 100644 --- a/src/gui/cursor.cpp +++ b/src/gui/cursor.cpp @@ -87,7 +87,7 @@ void FurnaceGUI::finishSelection() { selStart.xFine=0; } if (e->song.chanCollapse[selEnd.xCoarse]) { - selEnd.xFine=2+e->song.pat[cursor.xCoarse].effectRows*2; + selEnd.xFine=2+e->song.pat[cursor.xCoarse].effectCols*2; } e->setMidiBaseChan(cursor.xCoarse); @@ -105,7 +105,7 @@ void FurnaceGUI::moveCursor(int x, int y, bool select) { demandScrollX=true; if (x>0) { for (int i=0; i=(e->song.chanCollapse[cursor.xCoarse]?1:(3+e->song.pat[cursor.xCoarse].effectRows*2))) { + if (++cursor.xFine>=(e->song.chanCollapse[cursor.xCoarse]?1:(3+e->song.pat[cursor.xCoarse].effectCols*2))) { cursor.xFine=0; if (++cursor.xCoarse>=lastChannel) { if (settings.wrapHorizontal!=0 && !select) { @@ -113,7 +113,7 @@ void FurnaceGUI::moveCursor(int x, int y, bool select) { if (settings.wrapHorizontal==2) y++; } else { cursor.xCoarse=lastChannel-1; - cursor.xFine=e->song.chanCollapse[cursor.xCoarse]?0:(2+e->song.pat[cursor.xCoarse].effectRows*2); + cursor.xFine=e->song.chanCollapse[cursor.xCoarse]?0:(2+e->song.pat[cursor.xCoarse].effectCols*2); } } else { while (!e->song.chanShow[cursor.xCoarse]) { @@ -129,7 +129,7 @@ void FurnaceGUI::moveCursor(int x, int y, bool select) { if (--cursor.xCoarsesong.pat[cursor.xCoarse].effectRows*2; + cursor.xFine=2+e->song.pat[cursor.xCoarse].effectCols*2; if (settings.wrapHorizontal==2) y--; } else { cursor.xCoarse=firstChannel; @@ -143,7 +143,7 @@ void FurnaceGUI::moveCursor(int x, int y, bool select) { if (e->song.chanCollapse[cursor.xCoarse]) { cursor.xFine=0; } else { - cursor.xFine=2+e->song.pat[cursor.xCoarse].effectRows*2; + cursor.xFine=2+e->song.pat[cursor.xCoarse].effectCols*2; } } } @@ -271,7 +271,7 @@ void FurnaceGUI::moveCursorBottom(bool select) { DETERMINE_LAST; cursor.xCoarse=lastChannel-1; if (cursor.xCoarse<0) cursor.xCoarse=0; - cursor.xFine=2+e->song.pat[cursor.xCoarse].effectRows*2; + cursor.xFine=2+e->song.pat[cursor.xCoarse].effectCols*2; demandScrollX=true; } else { cursor.y=e->song.patLen-1; diff --git a/src/gui/doAction.cpp b/src/gui/doAction.cpp index c12df2fe4..28f6cf882 100644 --- a/src/gui/doAction.cpp +++ b/src/gui/doAction.cpp @@ -462,13 +462,13 @@ void FurnaceGUI::doAction(int what) { break; case GUI_ACTION_PAT_INCREASE_COLUMNS: if (cursor.xCoarse<0 || cursor.xCoarse>=e->getTotalChannelCount()) break; - e->song.pat[cursor.xCoarse].effectRows++; - if (e->song.pat[cursor.xCoarse].effectRows>8) e->song.pat[cursor.xCoarse].effectRows=8; + e->song.pat[cursor.xCoarse].effectCols++; + if (e->song.pat[cursor.xCoarse].effectCols>8) e->song.pat[cursor.xCoarse].effectCols=8; break; case GUI_ACTION_PAT_DECREASE_COLUMNS: if (cursor.xCoarse<0 || cursor.xCoarse>=e->getTotalChannelCount()) break; - e->song.pat[cursor.xCoarse].effectRows--; - if (e->song.pat[cursor.xCoarse].effectRows<1) e->song.pat[cursor.xCoarse].effectRows=1; + e->song.pat[cursor.xCoarse].effectCols--; + if (e->song.pat[cursor.xCoarse].effectCols<1) e->song.pat[cursor.xCoarse].effectCols=1; break; case GUI_ACTION_PAT_INTERPOLATE: doInterpolate(); diff --git a/src/gui/editing.cpp b/src/gui/editing.cpp index e5874f91a..8832b7fbb 100644 --- a/src/gui/editing.cpp +++ b/src/gui/editing.cpp @@ -137,12 +137,12 @@ void FurnaceGUI::makeUndo(ActionType action) { void FurnaceGUI::doSelectAll() { finishSelection(); curNibble=false; - if (selStart.xFine==0 && selEnd.xFine==2+e->song.pat[selEnd.xCoarse].effectRows*2) { + if (selStart.xFine==0 && selEnd.xFine==2+e->song.pat[selEnd.xCoarse].effectCols*2) { if (selStart.y==0 && selEnd.y==e->song.patLen-1) { // select entire pattern selStart.xCoarse=0; selStart.xFine=0; selEnd.xCoarse=e->getTotalChannelCount()-1; - selEnd.xFine=2+e->song.pat[selEnd.xCoarse].effectRows*2; + selEnd.xFine=2+e->song.pat[selEnd.xCoarse].effectCols*2; } else { // select entire column selStart.y=0; selEnd.y=e->song.patLen-1; @@ -153,14 +153,14 @@ void FurnaceGUI::doSelectAll() { // find row position for (SelectionPoint i; i.xCoarse!=selStart.xCoarse || i.xFine!=selStart.xFine; selStartX++) { i.xFine++; - if (i.xFine>=3+e->song.pat[i.xCoarse].effectRows*2) { + if (i.xFine>=3+e->song.pat[i.xCoarse].effectCols*2) { i.xFine=0; i.xCoarse++; } } for (SelectionPoint i; i.xCoarse!=selEnd.xCoarse || i.xFine!=selEnd.xFine; selEndX++) { i.xFine++; - if (i.xFine>=3+e->song.pat[i.xCoarse].effectRows*2) { + if (i.xFine>=3+e->song.pat[i.xCoarse].effectCols*2) { i.xFine=0; i.xCoarse++; } @@ -172,7 +172,7 @@ void FurnaceGUI::doSelectAll() { selEnd.y=e->song.patLen-1; } else { // left-right selStart.xFine=0; - selEnd.xFine=2+e->song.pat[selEnd.xCoarse].effectRows*2; + selEnd.xFine=2+e->song.pat[selEnd.xCoarse].effectCols*2; } } } @@ -200,7 +200,7 @@ void FurnaceGUI::doDelete() { for (; iCoarse<=selEnd.xCoarse; iCoarse++) { if (!e->song.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.patLen; j++) { if (jsong.patLen-1) { @@ -269,7 +269,7 @@ void FurnaceGUI::doInsert() { for (; iCoarse<=selEnd.xCoarse; iCoarse++) { if (!e->song.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.patLen-1; j>=selStart.y; j--) { if (j==selStart.y) { @@ -301,7 +301,7 @@ void FurnaceGUI::doTranspose(int amount, OperationMask& mask) { for (; iCoarse<=selEnd.xCoarse; iCoarse++) { if (!e->song.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsedata[j][0],pat->data[j][1]); if (cut) { @@ -530,7 +530,7 @@ void FurnaceGUI::doPaste(PasteMode mode) { break; } if (mode!=GUI_PASTE_MODE_MIX_BG || pat->data[j][iFine+1]==-1) { - if (iFine<(3+e->song.pat[iCoarse].effectRows*2)) pat->data[j][iFine+1]=val; + if (iFine<(3+e->song.pat[iCoarse].effectCols*2)) pat->data[j][iFine+1]=val; } } } @@ -589,7 +589,7 @@ void FurnaceGUI::doInterpolate() { for (; iCoarse<=selEnd.xCoarse; iCoarse++) { if (!e->song.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarsesong.chanShow[iCoarse]) continue; DivPattern* pat=e->song.pat[iCoarse].getPattern(e->song.orders.ord[iCoarse][curOrder],true); - for (; iFine<3+e->song.pat[iCoarse].effectRows*2 && (iCoarsesong.pat[iCoarse].effectCols*2 && (iCoarse=(3+(e->song.pat[cursor.xCoarse].effectRows*2))) { + if (++cursor.xFine>=(3+(e->song.pat[cursor.xCoarse].effectCols*2))) { cursor.xFine=3; } } else { diff --git a/src/gui/pattern.cpp b/src/gui/pattern.cpp index 3b45cd27b..9ba22ef51 100644 --- a/src/gui/pattern.cpp +++ b/src/gui/pattern.cpp @@ -217,7 +217,7 @@ inline void FurnaceGUI::patternRow(int i, bool isPlaying, float lineHeight, int ImGui::PopStyleColor(); // effects - for (int k=0; ksong.pat[j].effectRows; k++) { + for (int k=0; ksong.pat[j].effectCols; k++) { int index=4+(k<<1); bool selectedEffect=selectedRow && (j32+index-1>=sel1XSum && j32+index-1<=sel2XSum); bool selectedEffectVal=selectedRow && (j32+index>=sel1XSum && j32+index<=sel2XSum); @@ -427,7 +427,7 @@ void FurnaceGUI::drawPattern() { displayTooltip=true; } else { const char* chName=e->getChannelName(i); - size_t chNameLimit=6+4*e->song.pat[i].effectRows; + size_t chNameLimit=6+4*e->song.pat[i].effectCols; if (strlen(chName)>chNameLimit) { String shortChName=chName; shortChName.resize(chNameLimit-3); @@ -524,18 +524,18 @@ void FurnaceGUI::drawPattern() { if (!e->song.chanCollapse[i]) { ImGui::SameLine(); snprintf(chanID,2048,"<##_LCH%d",i); - ImGui::BeginDisabled(e->song.pat[i].effectRows<=1); + ImGui::BeginDisabled(e->song.pat[i].effectCols<=1); if (ImGui::SmallButton(chanID)) { - e->song.pat[i].effectRows--; - if (e->song.pat[i].effectRows<1) e->song.pat[i].effectRows=1; + e->song.pat[i].effectCols--; + if (e->song.pat[i].effectCols<1) e->song.pat[i].effectCols=1; } ImGui::EndDisabled(); ImGui::SameLine(); - ImGui::BeginDisabled(e->song.pat[i].effectRows>=8); + ImGui::BeginDisabled(e->song.pat[i].effectCols>=8); snprintf(chanID,2048,">##_RCH%d",i); if (ImGui::SmallButton(chanID)) { - e->song.pat[i].effectRows++; - if (e->song.pat[i].effectRows>8) e->song.pat[i].effectRows=8; + e->song.pat[i].effectCols++; + if (e->song.pat[i].effectCols>8) e->song.pat[i].effectCols=8; } ImGui::EndDisabled(); }