pattern data refactor, part 1
this first stage changes the way notes are encoded instead of note/octave, it is just note
This commit is contained in:
parent
7d7d95a97d
commit
d4ecf4045b
10 changed files with 447 additions and 465 deletions
|
|
@ -2293,6 +2293,63 @@ int DivEngine::getEffectiveSampleRate(int rate) {
|
|||
return rate;
|
||||
}
|
||||
|
||||
short DivEngine::splitNoteToNote(short note, short octave) {
|
||||
if (note==100) {
|
||||
return DIV_NOTE_OFF;
|
||||
} else if (note==101) {
|
||||
return DIV_NOTE_REL;
|
||||
} else if (note==102) {
|
||||
return DIV_MACRO_REL;
|
||||
} else if (note==0 && octave!=0) {
|
||||
// "BUG" note!
|
||||
return DIV_NOTE_NULL_PAT;
|
||||
} else if (note==0 && octave==0) {
|
||||
return -1;
|
||||
} else {
|
||||
int seek=(note+(signed char)octave*12)+60;
|
||||
if (seek<0 || seek>=180) {
|
||||
return DIV_NOTE_NULL_PAT;
|
||||
} else {
|
||||
return seek;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void DivEngine::noteToSplitNote(short note, short& outNote, short& outOctave) {
|
||||
switch (note) {
|
||||
case DIV_NOTE_OFF:
|
||||
outNote=100;
|
||||
outOctave=0;
|
||||
break;
|
||||
case DIV_NOTE_REL:
|
||||
outNote=101;
|
||||
outOctave=0;
|
||||
break;
|
||||
case DIV_MACRO_REL:
|
||||
outNote=102;
|
||||
outOctave=0;
|
||||
break;
|
||||
case DIV_NOTE_NULL_PAT:
|
||||
// "BUG" note!
|
||||
outNote=0;
|
||||
outOctave=1;
|
||||
break;
|
||||
case -1:
|
||||
outNote=0;
|
||||
outOctave=0;
|
||||
default:
|
||||
outNote=note%12;
|
||||
outOctave=(unsigned char)(note-60)/12;
|
||||
if (outNote==0) {
|
||||
outNote=12;
|
||||
outOctave--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void DivEngine::previewSample(int sample, int note, int pStart, int pEnd) {
|
||||
BUSY_BEGIN;
|
||||
previewSampleNoLock(sample,note,pStart,pEnd);
|
||||
|
|
|
|||
|
|
@ -721,7 +721,7 @@ class DivEngine {
|
|||
SafeWriter* saveDMF(unsigned char version);
|
||||
// save as .fur.
|
||||
// if notPrimary is true then the song will not be altered
|
||||
SafeWriter* saveFur(bool notPrimary=false, bool newPatternFormat=true);
|
||||
SafeWriter* saveFur(bool notPrimary=false);
|
||||
// return a ROM exporter.
|
||||
DivROMExport* buildROM(DivROMExportOptions sys);
|
||||
// dump to VGM.
|
||||
|
|
@ -927,6 +927,10 @@ class DivEngine {
|
|||
// get effective sample rate
|
||||
int getEffectiveSampleRate(int rate);
|
||||
|
||||
// convert between old and new note/octave format
|
||||
short splitNoteToNote(short note, short octave);
|
||||
void noteToSplitNote(short note, short& outNote, short& outOctave);
|
||||
|
||||
// is FM system
|
||||
bool isFMSystem(DivSystem sys);
|
||||
|
||||
|
|
|
|||
|
|
@ -811,25 +811,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
octave--;
|
||||
}
|
||||
|
||||
if (note==100) {
|
||||
pat->newData[k][DIV_PAT_NOTE]=DIV_NOTE_OFF;
|
||||
} else if (note==101) {
|
||||
pat->newData[k][DIV_PAT_NOTE]=DIV_NOTE_REL;
|
||||
} else if (note==102) {
|
||||
pat->newData[k][DIV_PAT_NOTE]=DIV_MACRO_REL;
|
||||
} else if (note==0 && octave!=0) {
|
||||
// "BUG" note!
|
||||
pat->newData[k][DIV_PAT_NOTE]=DIV_NOTE_NULL_PAT;
|
||||
} else if (note==0 && octave==0) {
|
||||
pat->newData[k][DIV_PAT_NOTE]=-1;
|
||||
} else {
|
||||
int seek=(note+(signed char)octave*12)+60;
|
||||
if (seek<0 || seek>=180) {
|
||||
pat->newData[k][DIV_PAT_NOTE]=DIV_NOTE_NULL_PAT;
|
||||
} else {
|
||||
pat->newData[k][DIV_PAT_NOTE]=seek;
|
||||
}
|
||||
}
|
||||
pat->newData[k][DIV_PAT_NOTE]=splitNoteToNote(note,octave);
|
||||
|
||||
// volume
|
||||
pat->newData[k][DIV_PAT_VOL]=reader.readS();
|
||||
|
|
@ -844,7 +826,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
if (ds.version<0x12) {
|
||||
if (ds.system[0]==DIV_SYSTEM_GB && i==2 && pat->newData[k][DIV_PAT_VOL]>0) {
|
||||
// volume range of GB wave channel was 0-3 rather than 0-F
|
||||
pat->newData[k][DIV_PAT_VOL]=(pat->data[k][DIV_PAT_VOL]&3)*5;
|
||||
pat->newData[k][DIV_PAT_VOL]=(pat->newData[k][DIV_PAT_VOL]&3)*5;
|
||||
}
|
||||
}
|
||||
for (int l=0; l<chan.effectCols; l++) {
|
||||
|
|
@ -879,33 +861,35 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
}
|
||||
} else { // historic pattern format
|
||||
if (i<16) pat->data[0][2]=historicColIns[i];
|
||||
if (i<16) pat->newData[0][DIV_PAT_INS]=historicColIns[i];
|
||||
for (int k=0; k<ds.subsong[0]->patLen; k++) {
|
||||
// note
|
||||
pat->data[k][0]=reader.readC();
|
||||
// octave
|
||||
pat->data[k][1]=reader.readC();
|
||||
if (pat->data[k][0]!=0) {
|
||||
short note=reader.readC();
|
||||
short octave=reader.readC();
|
||||
|
||||
if (note!=0) {
|
||||
// YMU759 is stored 2 octaves lower
|
||||
pat->data[k][1]+=2;
|
||||
octave+=2;
|
||||
}
|
||||
if (pat->data[k][0]==0 && pat->data[k][1]!=0) {
|
||||
logD("what? %d:%d:%d note %d octave %d",i,j,k,pat->data[k][0],pat->data[k][1]);
|
||||
pat->data[k][0]=12;
|
||||
pat->data[k][1]--;
|
||||
if (note==0 && octave!=0) {
|
||||
logD("what? %d:%d:%d note %d octave %d",i,j,k,note,octave);
|
||||
note=12;
|
||||
octave--;
|
||||
}
|
||||
|
||||
pat->newData[k][DIV_PAT_NOTE]=splitNoteToNote(note,octave);
|
||||
|
||||
// volume and effect
|
||||
unsigned char vol=reader.readC();
|
||||
unsigned char fx=reader.readC();
|
||||
unsigned char fxVal=reader.readC();
|
||||
pat->data[k][3]=(vol==0x80 || vol==0xff)?-1:vol;
|
||||
pat->newData[k][DIV_PAT_VOL]=(vol==0x80 || vol==0xff)?-1:vol;
|
||||
// effect
|
||||
pat->data[k][4]=(fx==0x80 || fx==0xff)?-1:fx;
|
||||
pat->data[k][5]=(fxVal==0x80 || fx==0xff)?-1:fxVal;
|
||||
pat->newData[k][DIV_PAT_FX(0)]=(fx==0x80 || fx==0xff)?-1:fx;
|
||||
pat->newData[k][DIV_PAT_FXVAL(0)]=(fxVal==0x80 || fx==0xff)?-1:fxVal;
|
||||
// instrument
|
||||
if (ds.version>0x05) {
|
||||
pat->data[k][2]=reader.readC();
|
||||
if (pat->data[k][2]==0x80 || pat->data[k][2]==0xff) pat->data[k][2]=-1;
|
||||
pat->newData[k][DIV_PAT_INS]=reader.readC();
|
||||
if (pat->newData[k][DIV_PAT_INS]==0x80 || pat->newData[k][DIV_PAT_INS]==0xff) pat->newData[k][DIV_PAT_INS]=-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1650,12 +1634,13 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
|||
bool relWarning=false;
|
||||
|
||||
for (int i=0; i<getChannelCount(sys); i++) {
|
||||
short note, octave;
|
||||
w->writeC(curPat[i].effectCols);
|
||||
|
||||
for (int j=0; j<curSubSong->ordersLen; j++) {
|
||||
DivPattern* pat=curPat[i].getPattern(curOrders->ord[i][j],false);
|
||||
for (int k=0; k<curSubSong->patLen; k++) {
|
||||
if ((pat->data[k][0]==101 || pat->data[k][0]==102) && pat->data[k][1]==0) {
|
||||
if (pat->newData[k][DIV_PAT_NOTE]==DIV_NOTE_REL || pat->newData[k][DIV_PAT_NOTE]==DIV_MACRO_REL) {
|
||||
w->writeS(100);
|
||||
w->writeS(0);
|
||||
if (!relWarning) {
|
||||
|
|
@ -1663,18 +1648,19 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) {
|
|||
addWarning("note/macro release will be converted to note off!");
|
||||
}
|
||||
} else {
|
||||
w->writeS(pat->data[k][0]); // note
|
||||
w->writeS(pat->data[k][1]); // octave
|
||||
noteToSplitNote(pat->newData[k][DIV_PAT_NOTE],note,octave);
|
||||
w->writeS(note); // note
|
||||
w->writeS(octave); // octave
|
||||
}
|
||||
w->writeS(pat->data[k][3]); // volume
|
||||
w->writeS(pat->newData[k][DIV_PAT_VOL]); // volume
|
||||
#ifdef TA_BIG_ENDIAN
|
||||
for (int l=0; l<curPat[i].effectCols*2; l++) {
|
||||
w->writeS(pat->data[k][4+l]);
|
||||
w->writeS(pat->newData[k][DIV_PAT_FX(0)+l]);
|
||||
}
|
||||
#else
|
||||
w->write(&pat->data[k][4],2*curPat[i].effectCols*2); // effects
|
||||
w->write(&pat->newData[k][DIV_PAT_FX(0)],2*curPat[i].effectCols*2); // effects
|
||||
#endif
|
||||
w->writeS(pat->data[k][2]); // instrument
|
||||
w->writeS(pat->newData[k][DIV_PAT_INS]); // instrument
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -418,8 +418,8 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
|
|||
ds.subsong[0]->orders.ord[j][i]=i;
|
||||
DivPattern* p=ds.subsong[0]->pat[j].getPattern(i,true);
|
||||
if (j==3 && seq[i].speed) {
|
||||
p->data[0][6]=0x0f;
|
||||
p->data[0][7]=seq[i].speed;
|
||||
p->newData[0][DIV_PAT_FX(1)]=0x0f;
|
||||
p->newData[0][DIV_PAT_FXVAL(1)]=seq[i].speed;
|
||||
}
|
||||
|
||||
bool ignoreNext=false;
|
||||
|
|
@ -428,80 +428,65 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
|
|||
FCPattern& fp=pat[seq[i].pat[j]];
|
||||
if (fp.note[k]>0 && fp.note[k]<0x49) {
|
||||
lastNote[j]=fp.note[k];
|
||||
short note=(fp.note[k]+seq[i].transpose[j])%12;
|
||||
short octave=2+((fp.note[k]+seq[i].transpose[j])/12);
|
||||
if (fp.note[k]>=0x3d) octave-=6;
|
||||
if (note==0) {
|
||||
note=12;
|
||||
octave--;
|
||||
}
|
||||
octave&=0xff;
|
||||
p->data[k][0]=note;
|
||||
p->data[k][1]=octave;
|
||||
p->newData[k][DIV_PAT_NOTE]=fp.note[k]+seq[i].transpose[j]+60;
|
||||
// wrap-around if the note is too high
|
||||
if (fp.note[k]>=0x3d) p->newData[k][DIV_PAT_NOTE]-=6*12;
|
||||
if (isSliding[j]) {
|
||||
isSliding[j]=false;
|
||||
p->data[k][4]=2;
|
||||
p->data[k][5]=0;
|
||||
p->newData[k][DIV_PAT_FX(0)]=2;
|
||||
p->newData[k][DIV_PAT_FXVAL(0)]=0;
|
||||
}
|
||||
} else if (fp.note[k]==0x49) {
|
||||
if (k>0) {
|
||||
p->data[k-1][4]=0x0d;
|
||||
p->data[k-1][5]=0;
|
||||
p->newData[k-1][DIV_PAT_FX(0)]=0x0d;
|
||||
p->newData[k-1][DIV_PAT_FXVAL(0)]=0;
|
||||
}
|
||||
} else if (k==0 && lastTranspose[j]!=seq[i].transpose[j]) {
|
||||
p->data[0][2]=lastIns[j];
|
||||
p->data[0][4]=0x03;
|
||||
p->data[0][5]=0xff;
|
||||
p->newData[0][DIV_PAT_INS]=lastIns[j];
|
||||
p->newData[0][DIV_PAT_FX(0)]=0x03;
|
||||
p->newData[0][DIV_PAT_FXVAL(0)]=0xff;
|
||||
lastTranspose[j]=seq[i].transpose[j];
|
||||
|
||||
short note=(lastNote[j]+seq[i].transpose[j])%12;
|
||||
short octave=2+((lastNote[j]+seq[i].transpose[j])/12);
|
||||
if (lastNote[j]>=0x3d) octave-=6;
|
||||
if (note==0) {
|
||||
note=12;
|
||||
octave--;
|
||||
}
|
||||
octave&=0xff;
|
||||
p->data[k][0]=note;
|
||||
p->data[k][1]=octave;
|
||||
p->newData[k][DIV_PAT_NOTE]=lastNote[j]+seq[i].transpose[j]+60;
|
||||
// wrap-around if the note is too high
|
||||
if (lastNote[j]>=0x3d) p->newData[k][DIV_PAT_NOTE]-=6*12;
|
||||
}
|
||||
if (fp.val[k]) {
|
||||
if (ignoreNext) {
|
||||
ignoreNext=false;
|
||||
} else {
|
||||
if (fp.val[k]==0xf0) {
|
||||
p->data[k][0]=100;
|
||||
p->data[k][1]=0;
|
||||
p->data[k][2]=-1;
|
||||
p->newData[k][DIV_PAT_NOTE]=DIV_NOTE_OFF;
|
||||
p->newData[k][DIV_PAT_INS]=-1;
|
||||
} else if (fp.val[k]&0xe0) {
|
||||
if (fp.val[k]&0x40) {
|
||||
p->data[k][4]=2;
|
||||
p->data[k][5]=0;
|
||||
p->newData[k][DIV_PAT_FX(0)]=2;
|
||||
p->newData[k][DIV_PAT_FXVAL(0)]=0;
|
||||
isSliding[j]=false;
|
||||
} else if (fp.val[k]&0x80) {
|
||||
isSliding[j]=true;
|
||||
if (k<31) {
|
||||
if (fp.val[k+1]&0x20) {
|
||||
p->data[k][4]=2;
|
||||
p->data[k][5]=fp.val[k+1]&0x1f;
|
||||
p->newData[k][DIV_PAT_FX(0)]=2;
|
||||
p->newData[k][DIV_PAT_FXVAL(0)]=fp.val[k+1]&0x1f;
|
||||
} else {
|
||||
p->data[k][4]=1;
|
||||
p->data[k][5]=fp.val[k+1]&0x1f;
|
||||
p->newData[k][DIV_PAT_FX(0)]=1;
|
||||
p->newData[k][DIV_PAT_FXVAL(0)]=fp.val[k+1]&0x1f;
|
||||
}
|
||||
ignoreNext=true;
|
||||
} else {
|
||||
p->data[k][4]=2;
|
||||
p->data[k][5]=0;
|
||||
p->newData[k][DIV_PAT_FX(0)]=2;
|
||||
p->newData[k][DIV_PAT_FXVAL(0)]=0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
p->data[k][2]=(fp.val[k]+seq[i].offsetIns[j])&0x3f;
|
||||
lastIns[j]=p->data[k][2];
|
||||
p->newData[k][DIV_PAT_INS]=(fp.val[k]+seq[i].offsetIns[j])&0x3f;
|
||||
lastIns[j]=p->newData[k][DIV_PAT_INS];
|
||||
}
|
||||
}
|
||||
} else if (fp.note[k]>0 && fp.note[k]<0x49) {
|
||||
p->data[k][2]=seq[i].offsetIns[j];
|
||||
lastIns[j]=p->data[k][2];
|
||||
p->newData[k][DIV_PAT_INS]=seq[i].offsetIns[j];
|
||||
lastIns[j]=p->newData[k][DIV_PAT_INS];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -270,7 +270,7 @@ int convert_vrc6_duties[4] = {1, 3, 7, 3};
|
|||
|
||||
int findEmptyFx(short* data) {
|
||||
for (int i=0; i<7; i++) {
|
||||
if (data[4+i*2]==-1) return i;
|
||||
if (data[DIV_PAT_FX(i)]==-1) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -1752,17 +1752,13 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
|
||||
if (map_channels[ch] != 0xff) {
|
||||
if (nextNote == 0x0d) {
|
||||
pat->data[row][0] = 101;
|
||||
pat->newData[row][DIV_PAT_NOTE] = DIV_NOTE_REL;
|
||||
} else if (nextNote == 0x0e) {
|
||||
pat->data[row][0] = 100;
|
||||
} else if (nextNote == 0x01) {
|
||||
pat->data[row][0] = 12;
|
||||
pat->data[row][1] = nextOctave - 1;
|
||||
pat->newData[row][DIV_PAT_NOTE] = DIV_NOTE_OFF;
|
||||
} else if (nextNote == 0) {
|
||||
pat->data[row][0] = 0;
|
||||
pat->newData[row][DIV_PAT_NOTE] = -1;
|
||||
} else if (nextNote < 0x0d) {
|
||||
pat->data[row][0] = nextNote - 1;
|
||||
pat->data[row][1] = nextOctave;
|
||||
pat->newData[row][DIV_PAT_NOTE] = nextOctave*12 + (nextNote - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1770,27 +1766,27 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
// TODO: you sure about 0xff?
|
||||
if (map_channels[ch] != 0xff) {
|
||||
if (nextIns < 0x40 && nextNote != 0x0d && nextNote != 0x0e) {
|
||||
pat->data[row][2] = nextIns;
|
||||
pat->newData[row][DIV_PAT_INS] = nextIns;
|
||||
} else {
|
||||
pat->data[row][2] = -1;
|
||||
pat->newData[row][DIV_PAT_INS] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char nextVol = reader.readC();
|
||||
if (map_channels[ch] != 0xff) {
|
||||
if (nextVol < 0x10) {
|
||||
pat->data[row][3] = nextVol;
|
||||
pat->newData[row][DIV_PAT_VOL] = nextVol;
|
||||
if (map_channels[ch] == vrc6_saw_chan) // scale volume
|
||||
{
|
||||
// TODO: shouldn't it be 32?
|
||||
pat->data[row][3] = (pat->data[row][3] * 42) / 15;
|
||||
pat->newData[row][DIV_PAT_VOL] = (pat->newData[row][DIV_PAT_VOL] * 42) / 15;
|
||||
}
|
||||
|
||||
if (map_channels[ch] == fds_chan) {
|
||||
pat->data[row][3] = (pat->data[row][3] * 31) / 15;
|
||||
pat->newData[row][DIV_PAT_VOL] = (pat->newData[row][DIV_PAT_VOL] * 31) / 15;
|
||||
}
|
||||
} else {
|
||||
pat->data[row][3] = -1;
|
||||
pat->newData[row][DIV_PAT_VOL] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1829,15 +1825,15 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
if (nextEffect == FT_EF_SPEED && nextEffectVal < 20)
|
||||
nextEffectVal++;
|
||||
|
||||
if (pat->data[row][3] == 0)
|
||||
pat->data[row][3] = 0xf;
|
||||
if (pat->newData[row][DIV_PAT_VOL] == 0)
|
||||
pat->newData[row][DIV_PAT_VOL] = 0xf;
|
||||
else {
|
||||
pat->data[row][3]--;
|
||||
pat->data[row][3] &= 0x0F;
|
||||
pat->newData[row][DIV_PAT_VOL]--;
|
||||
pat->newData[row][DIV_PAT_VOL] &= 0x0F;
|
||||
}
|
||||
|
||||
if (pat->data[row][0] == 0)
|
||||
pat->data[row][2] = -1;
|
||||
if (pat->newData[row][DIV_PAT_NOTE] == -1)
|
||||
pat->newData[row][DIV_PAT_INS] = -1;
|
||||
}
|
||||
|
||||
if (blockVersion == 3) {
|
||||
|
|
@ -1902,43 +1898,43 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
|
||||
if (map_channels[ch] != 0xff) {
|
||||
if (nextEffect == 0 && nextEffectVal == 0) {
|
||||
pat->data[row][4 + (j * 2)] = -1;
|
||||
pat->data[row][5 + (j * 2)] = -1;
|
||||
pat->newData[row][DIV_PAT_FX(j)] = -1;
|
||||
pat->newData[row][DIV_PAT_FXVAL(j)] = -1;
|
||||
} else {
|
||||
if ((eft && nextEffect<eftEffectMapSize) || (!eft && nextEffect<ftEffectMapSize)) {
|
||||
if (eft) {
|
||||
pat->data[row][4 + (j * 2)] = eftEffectMap[nextEffect];
|
||||
pat->data[row][5 + (j * 2)] = eftEffectMap[nextEffect] == -1 ? -1 : nextEffectVal;
|
||||
pat->newData[row][DIV_PAT_FX(j)] = eftEffectMap[nextEffect];
|
||||
pat->newData[row][DIV_PAT_FXVAL(j)] = eftEffectMap[nextEffect] == -1 ? -1 : nextEffectVal;
|
||||
|
||||
if (pat->data[row][4 + (j * 2)] == 0x100) {
|
||||
pat->data[row][3] += pat->data[row][5 + (j * 2)] ? 0x10 : 0; // extra volume bit for AY8930
|
||||
pat->data[row][4 + (j * 2)] = -1;
|
||||
pat->data[row][5 + (j * 2)] = -1;
|
||||
if (pat->newData[row][DIV_PAT_FX(j)] == 0x100) {
|
||||
pat->newData[row][DIV_PAT_VOL] += pat->newData[row][DIV_PAT_FXVAL(j)] ? 0x10 : 0; // extra volume bit for AY8930
|
||||
pat->newData[row][DIV_PAT_FX(j)] = -1;
|
||||
pat->newData[row][DIV_PAT_FXVAL(j)] = -1;
|
||||
}
|
||||
|
||||
if (eftEffectMap[nextEffect] == 0x0f && nextEffectVal > 0x1f) {
|
||||
pat->data[row][4 + (j * 2)] = 0xfd; // BPM speed change!
|
||||
pat->newData[row][DIV_PAT_FX(j)] = 0xfd; // BPM speed change!
|
||||
}
|
||||
|
||||
if ((eftEffectMap[nextEffect] == 0xe1 || eftEffectMap[nextEffect] == 0xe2) && (nextEffectVal & 0xf0) == 0) {
|
||||
pat->data[row][5 + (j * 2)] |= 0x10; // in FamiTracker if e1/e2 commands speed is 0 the portamento still has some speed!
|
||||
pat->newData[row][DIV_PAT_FXVAL(j)] |= 0x10; // in FamiTracker if e1/e2 commands speed is 0 the portamento still has some speed!
|
||||
}
|
||||
} else {
|
||||
pat->data[row][4 + (j * 2)] = ftEffectMap[nextEffect];
|
||||
pat->data[row][5 + (j * 2)] = ftEffectMap[nextEffect] == -1 ? -1 : nextEffectVal;
|
||||
pat->newData[row][DIV_PAT_FX(j)] = ftEffectMap[nextEffect];
|
||||
pat->newData[row][DIV_PAT_FXVAL(j)] = ftEffectMap[nextEffect] == -1 ? -1 : nextEffectVal;
|
||||
|
||||
if (ftEffectMap[nextEffect] == 0x0f && nextEffectVal > 0x1f) {
|
||||
pat->data[row][4 + (j * 2)] = 0xfd; // BPM speed change!
|
||||
pat->newData[row][DIV_PAT_FX(j)] = 0xfd; // BPM speed change!
|
||||
}
|
||||
|
||||
if ((ftEffectMap[nextEffect] == 0xe1 || ftEffectMap[nextEffect] == 0xe2) && (nextEffectVal & 0xf0) == 0) {
|
||||
pat->data[row][5 + (j * 2)] |= 0x10; // in FamiTracker if e1/e2 commands speed is 0 the portamento still has some speed!
|
||||
pat->newData[row][DIV_PAT_FXVAL(j)] |= 0x10; // in FamiTracker if e1/e2 commands speed is 0 the portamento still has some speed!
|
||||
}
|
||||
}
|
||||
for (int v = 0; v < 8; v++) {
|
||||
if (map_channels[ch] == n163_chans[v]) {
|
||||
if (pat->data[row][4 + (j * 2)] == 0x12) {
|
||||
pat->data[row][4 + (j * 2)] = 0x110; // N163 wave change (we'll map this later)
|
||||
if (pat->newData[row][DIV_PAT_FX(j)] == 0x12) {
|
||||
pat->newData[row][DIV_PAT_FX(j)] = 0x110; // N163 wave change (we'll map this later)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1947,23 +1943,24 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
{
|
||||
if (map_channels[ch] == vrc7_chans[vrr])
|
||||
{
|
||||
if (pat->data[row][4 + (j * 2)] == 0x12)
|
||||
if (pat->newData[row][DIV_PAT_FX(j)] == 0x12)
|
||||
{
|
||||
pat->data[row][4 + (j * 2)] = 0x10; // set VRC7 patch
|
||||
pat->newData[row][DIV_PAT_FX(j)] = 0x10; // set VRC7 patch
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int v = 0; v < 3; v++) {
|
||||
if (map_channels[ch] == s5b_chans[v] || map_channels[ch] == ay8930_chans[v]) {
|
||||
if (pat->data[row][4 + (j * 2)] == 0x22 && (pat->data[row][5 + (j * 2)] & 0xf0) != 0) {
|
||||
pat->data[row][4 + (7 * 2)] = -666; //marker
|
||||
if (pat->newData[row][DIV_PAT_FX(j)] == 0x22 && (pat->newData[row][DIV_PAT_FXVAL(j)] & 0xf0) != 0) {
|
||||
// TODO: in the second stage of pattern refactor this will have to change.
|
||||
pat->newData[row][DIV_PAT_FX(7)] = -666; //marker
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pat->data[row][4 + (j * 2)] = -1;
|
||||
pat->data[row][5 + (j * 2)] = -1;
|
||||
pat->newData[row][DIV_PAT_FX(j)] = -1;
|
||||
pat->newData[row][DIV_PAT_FXVAL(j)] = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2438,8 +2435,8 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
if (ds.subsong[j]->pat[ii].data[k] == NULL)
|
||||
continue;
|
||||
for (int l = 0; l < ds.subsong[j]->patLen; l++) {
|
||||
if (ds.subsong[j]->pat[ii].data[k]->data[l][2] > index) {
|
||||
ds.subsong[j]->pat[ii].data[k]->data[l][2]--;
|
||||
if (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS] > index) {
|
||||
ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS]--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2456,12 +2453,12 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
if (ds.subsong[j]->pat[ii].data[k] == NULL)
|
||||
continue;
|
||||
for (int l = 0; l < ds.subsong[j]->patLen; l++) {
|
||||
if (ds.subsong[j]->pat[ii].data[k]->data[l][4 + 7*2] == -666) {
|
||||
if (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_FX(7)] == -666) {
|
||||
bool converted = false;
|
||||
// for()? if()? THESE ARE NOT FUNCTIONS!
|
||||
for (int hh = 0; hh < 7; hh++) { // oh and now you 1TBS up. oh man...
|
||||
if (ds.subsong[j]->pat[ii].data[k]->data[l][4 + hh*2] == 0x22 && !converted) {
|
||||
int slot = findEmptyFx(ds.subsong[j]->pat[ii].data[k]->data[l]);
|
||||
if (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_FX(hh)] == 0x22 && !converted) {
|
||||
int slot = findEmptyFx(ds.subsong[j]->pat[ii].data[k]->newData[l]);
|
||||
if (slot != -1) {
|
||||
// space your comments damn it!
|
||||
// Hxy - Envelope automatic pitch
|
||||
|
|
@ -2469,7 +2466,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
// Sets envelope period to the note period shifted by x and envelope type y.
|
||||
// Approximate envelope frequency is note frequency * (2^|x - 8|) / 32.
|
||||
|
||||
int ftAutoEnv = (ds.subsong[j]->pat[ii].data[k]->data[l][5 + hh*2] >> 4) & 15;
|
||||
int ftAutoEnv = (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_FXVAL(hh)] >> 4) & 15;
|
||||
int autoEnvDen = 16; // ???? with 32 it's an octave lower...
|
||||
int autoEnvNum = (1 << (abs(ftAutoEnv - 8)));
|
||||
|
||||
|
|
@ -2479,18 +2476,18 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
}
|
||||
|
||||
if (autoEnvDen < 16 && autoEnvNum < 16) {
|
||||
ds.subsong[j]->pat[ii].data[k]->data[l][4 + slot*2] = 0x29;
|
||||
ds.subsong[j]->pat[ii].data[k]->data[l][5 + slot*2] = (autoEnvNum << 4) | autoEnvDen;
|
||||
ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_FX(slot)] = 0x29;
|
||||
ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_FXVAL(slot)] = (autoEnvNum << 4) | autoEnvDen;
|
||||
}
|
||||
|
||||
ds.subsong[j]->pat[ii].data[k]->data[l][5 + hh*2] = (ds.subsong[j]->pat[ii].data[k]->data[l][5 + hh*2] & 0xf) << 4;
|
||||
ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_FXVAL(hh)] = (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_FXVAL(hh)] & 0xf) << 4;
|
||||
|
||||
converted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ds.subsong[j]->pat[ii].data[k]->data[l][4 + (7 * 2)] = -1; //delete marker
|
||||
ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_FX(7)] = -1; //delete marker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2506,10 +2503,10 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
for (int p = 0; p < s->ordersLen; p++) {
|
||||
for (int r = 0; r < s->patLen; r++) {
|
||||
DivPattern* pat = s->pat[c].getPattern(s->orders.ord[c][p], true);
|
||||
short* s_row_data = pat->data[r];
|
||||
short* s_row_data = pat->newData[r];
|
||||
|
||||
for (int eff = 0; eff < DIV_MAX_EFFECTS - 1; eff++) {
|
||||
if (s_row_data[4 + 2 * eff] != -1 && eff + 1 > num_fx) {
|
||||
if (s_row_data[DIV_PAT_FX(eff)] != -1 && eff + 1 > num_fx) {
|
||||
num_fx = eff + 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -2556,7 +2553,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
continue;
|
||||
for (int l = 0; l < ds.subsong[j]->patLen; l++) {
|
||||
// 1TBS > GNU
|
||||
if (ds.subsong[j]->pat[ii].data[k]->data[l][2] == i) { // instrument
|
||||
if (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS] == i) { // instrument
|
||||
DivInstrument* ins = ds.ins[i];
|
||||
bool go_to_end = false;
|
||||
|
||||
|
|
@ -2606,7 +2603,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
if (ds.subsong[j]->pat[ii].data[k] == NULL)
|
||||
continue;
|
||||
for (int l = 0; l < ds.subsong[j]->patLen; l++) {
|
||||
if (ds.subsong[j]->pat[ii].data[k]->data[l][2] == i) // instrument
|
||||
if (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS] == i) // instrument
|
||||
{
|
||||
DivInstrument* ins = ds.ins[i];
|
||||
bool go_to_end = false;
|
||||
|
|
@ -2658,7 +2655,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
if (ds.subsong[j]->pat[ii].data[k] == NULL)
|
||||
continue;
|
||||
for (int l = 0; l < ds.subsong[j]->patLen; l++) {
|
||||
if (ds.subsong[j]->pat[ii].data[k]->data[l][2] == i) // instrument
|
||||
if (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS] == i) // instrument
|
||||
{
|
||||
DivInstrument* ins = ds.ins[i];
|
||||
bool go_to_end = false;
|
||||
|
|
@ -2729,17 +2726,17 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
if (ds.subsong[j]->pat[ii].data[k] == NULL)
|
||||
continue;
|
||||
for (int l = 0; l < ds.subsong[j]->patLen; l++) {
|
||||
if (ds.subsong[j]->pat[ii].data[k]->data[l][2] == ins_vrc6_conv[i][0] && (ii == vrc6_chans[0] || ii == vrc6_chans[1])) // change ins index
|
||||
if (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS] == ins_vrc6_conv[i][0] && (ii == vrc6_chans[0] || ii == vrc6_chans[1])) // change ins index
|
||||
{
|
||||
ds.subsong[j]->pat[ii].data[k]->data[l][2] = ins_vrc6_conv[i][1];
|
||||
ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS] = ins_vrc6_conv[i][1];
|
||||
}
|
||||
|
||||
if (ds.subsong[j]->pat[ii].data[k]->data[l][2] == ins_vrc6_saw_conv[i][0] && ii == vrc6_saw_chan) {
|
||||
ds.subsong[j]->pat[ii].data[k]->data[l][2] = ins_vrc6_saw_conv[i][1];
|
||||
if (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS] == ins_vrc6_saw_conv[i][0] && ii == vrc6_saw_chan) {
|
||||
ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS] = ins_vrc6_saw_conv[i][1];
|
||||
}
|
||||
|
||||
if (ds.subsong[j]->pat[ii].data[k]->data[l][2] == ins_nes_conv[i][0] && (ii == mmc5_chans[0] || ii == mmc5_chans[1] || ii < 5)) {
|
||||
ds.subsong[j]->pat[ii].data[k]->data[l][2] = ins_nes_conv[i][1];
|
||||
if (ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS] == ins_nes_conv[i][0] && (ii == mmc5_chans[0] || ii == mmc5_chans[1] || ii < 5)) {
|
||||
ds.subsong[j]->pat[ii].data[k]->newData[l][DIV_PAT_INS] = ins_nes_conv[i][1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2785,19 +2782,19 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
DivPattern* p=i->pat[j].getPattern(i->orders.ord[j][k],true);
|
||||
for (int l=0; l<i->patLen; l++) {
|
||||
// check for instrument change
|
||||
if (p->data[l][2]!=-1) {
|
||||
curWaveOff=n163WaveOff[p->data[l][2]&127];
|
||||
if (p->newData[l][DIV_PAT_INS]!=-1) {
|
||||
curWaveOff=n163WaveOff[p->newData[l][DIV_PAT_INS]&127];
|
||||
}
|
||||
|
||||
// check effect columns for 0x110 (dummy wave change)
|
||||
for (int m=0; m<i->pat[j].effectCols; m++) {
|
||||
if (p->data[l][4+(m<<1)]==0x110) {
|
||||
if (p->newData[l][DIV_PAT_FX(m)]==0x110) {
|
||||
// map wave
|
||||
p->data[l][4+(m<<1)]=0x10;
|
||||
if (p->data[l][5+(m<<1)]==-1) {
|
||||
p->data[l][5+(m<<1)]=curWaveOff&0xff;
|
||||
p->newData[l][DIV_PAT_FX(m)]=0x10;
|
||||
if (p->newData[l][DIV_PAT_FXVAL(m)]==-1) {
|
||||
p->newData[l][DIV_PAT_FXVAL(m)]=curWaveOff&0xff;
|
||||
} else {
|
||||
p->data[l][5+(m<<1)]=(p->data[l][5+(m<<1)]+curWaveOff)&0xff;
|
||||
p->newData[l][DIV_PAT_FXVAL(m)]=(p->newData[l][DIV_PAT_FXVAL(m)]+curWaveOff)&0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1778,32 +1778,28 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
|||
|
||||
if (mask&1) { // note
|
||||
unsigned char note=reader.readC();
|
||||
// TODO: PAT2 format with new off/===/rel values!
|
||||
if (note==180) {
|
||||
pat->data[j][0]=100;
|
||||
pat->data[j][1]=0;
|
||||
pat->newData[j][0]=DIV_NOTE_OFF;
|
||||
} else if (note==181) {
|
||||
pat->data[j][0]=101;
|
||||
pat->data[j][1]=0;
|
||||
pat->newData[j][0]=DIV_NOTE_REL;
|
||||
} else if (note==182) {
|
||||
pat->data[j][0]=102;
|
||||
pat->data[j][1]=0;
|
||||
pat->newData[j][0]=DIV_MACRO_REL;
|
||||
} else if (note<180) {
|
||||
pat->data[j][0]=newFormatNotes[note];
|
||||
pat->data[j][1]=newFormatOctaves[note];
|
||||
pat->newData[j][DIV_PAT_NOTE]=note;
|
||||
} else {
|
||||
pat->data[j][0]=0;
|
||||
pat->data[j][1]=0;
|
||||
pat->newData[j][0]=-1;
|
||||
}
|
||||
}
|
||||
if (mask&2) { // instrument
|
||||
pat->data[j][2]=(unsigned char)reader.readC();
|
||||
pat->newData[j][DIV_PAT_INS]=(unsigned char)reader.readC();
|
||||
}
|
||||
if (mask&4) { // volume
|
||||
pat->data[j][3]=(unsigned char)reader.readC();
|
||||
pat->newData[j][DIV_PAT_VOL]=(unsigned char)reader.readC();
|
||||
}
|
||||
for (unsigned char k=0; k<16; k++) {
|
||||
if (effectMask&(1<<k)) {
|
||||
pat->data[j][4+k]=(unsigned char)reader.readC();
|
||||
pat->newData[j][DIV_PAT_FX(0)+k]=(unsigned char)reader.readC();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1844,18 +1840,20 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
|||
|
||||
DivPattern* pat=ds.subsong[subs]->pat[chan].getPattern(index,true);
|
||||
for (int j=0; j<ds.subsong[subs]->patLen; j++) {
|
||||
pat->data[j][0]=reader.readS();
|
||||
pat->data[j][1]=reader.readS();
|
||||
pat->data[j][2]=reader.readS();
|
||||
pat->data[j][3]=reader.readS();
|
||||
for (int k=0; k<ds.subsong[subs]->pat[chan].effectCols; k++) {
|
||||
pat->data[j][4+(k<<1)]=reader.readS();
|
||||
pat->data[j][5+(k<<1)]=reader.readS();
|
||||
short note=reader.readS();
|
||||
short octave=reader.readS();
|
||||
if (note==0 && octave!=0) {
|
||||
logD("what? %d:%d:%d note %d octave %d",chan,i,j,note,octave);
|
||||
note=12;
|
||||
octave--;
|
||||
}
|
||||
if (pat->data[j][0]==0 && pat->data[j][1]!=0) {
|
||||
logD("what? %d:%d:%d note %d octave %d",chan,i,j,pat->data[j][0],pat->data[j][1]);
|
||||
pat->data[j][0]=12;
|
||||
pat->data[j][1]--;
|
||||
pat->newData[j][DIV_PAT_NOTE]=splitNoteToNote(note,octave);
|
||||
|
||||
pat->newData[j][DIV_PAT_INS]=reader.readS();
|
||||
pat->newData[j][DIV_PAT_VOL]=reader.readS();
|
||||
for (int k=0; k<ds.subsong[subs]->pat[chan].effectCols; k++) {
|
||||
pat->newData[j][DIV_PAT_FX(k)]=reader.readS();
|
||||
pat->newData[j][DIV_PAT_FXVAL(k)]=reader.readS();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2171,7 +2169,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
|||
return true;
|
||||
}
|
||||
|
||||
SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) {
|
||||
SafeWriter* DivEngine::saveFur(bool notPrimary) {
|
||||
saveLock.lock();
|
||||
std::vector<int> subSongPtr;
|
||||
std::vector<int> sysFlagsPtr;
|
||||
|
|
@ -2622,133 +2620,100 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) {
|
|||
DivPattern* pat=song.subsong[i.subsong]->pat[i.chan].getPattern(i.pat,false);
|
||||
patPtr.push_back(w->tell());
|
||||
|
||||
if (newPatternFormat) {
|
||||
w->write("PATN",4);
|
||||
blockStartSeek=w->tell();
|
||||
w->writeI(0);
|
||||
w->write("PATN",4);
|
||||
blockStartSeek=w->tell();
|
||||
w->writeI(0);
|
||||
|
||||
w->writeC(i.subsong);
|
||||
w->writeC(i.chan);
|
||||
w->writeS(i.pat);
|
||||
w->writeString(pat->name,false);
|
||||
w->writeC(i.subsong);
|
||||
w->writeC(i.chan);
|
||||
w->writeS(i.pat);
|
||||
w->writeString(pat->name,false);
|
||||
|
||||
unsigned char emptyRows=0;
|
||||
unsigned char emptyRows=0;
|
||||
|
||||
for (int j=0; j<song.subsong[i.subsong]->patLen; j++) {
|
||||
unsigned char mask=0;
|
||||
unsigned char finalNote=255;
|
||||
unsigned short effectMask=0;
|
||||
for (int j=0; j<song.subsong[i.subsong]->patLen; j++) {
|
||||
unsigned char mask=0;
|
||||
unsigned char finalNote=255;
|
||||
unsigned short effectMask=0;
|
||||
|
||||
if (pat->data[j][0]==100) {
|
||||
finalNote=180;
|
||||
} else if (pat->data[j][0]==101) { // note release
|
||||
finalNote=181;
|
||||
} else if (pat->data[j][0]==102) { // macro release
|
||||
finalNote=182;
|
||||
} else if (pat->data[j][1]==0 && pat->data[j][0]==0) {
|
||||
finalNote=255;
|
||||
} else {
|
||||
int seek=(pat->data[j][0]+(signed char)pat->data[j][1]*12)+60;
|
||||
if (seek<0 || seek>=180) {
|
||||
finalNote=255;
|
||||
} else {
|
||||
finalNote=seek;
|
||||
}
|
||||
}
|
||||
|
||||
if (finalNote!=255) mask|=1; // note
|
||||
if (pat->data[j][2]!=-1) mask|=2; // instrument
|
||||
if (pat->data[j][3]!=-1) mask|=4; // volume
|
||||
for (int k=0; k<song.subsong[i.subsong]->pat[i.chan].effectCols*2; k+=2) {
|
||||
if (k==0) {
|
||||
if (pat->data[j][4+k]!=-1) mask|=8;
|
||||
if (pat->data[j][5+k]!=-1) mask|=16;
|
||||
} else if (k<8) {
|
||||
if (pat->data[j][4+k]!=-1 || pat->data[j][5+k]!=-1) mask|=32;
|
||||
} else {
|
||||
if (pat->data[j][4+k]!=-1 || pat->data[j][5+k]!=-1) mask|=64;
|
||||
}
|
||||
|
||||
if (pat->data[j][4+k]!=-1) effectMask|=(1<<k);
|
||||
if (pat->data[j][5+k]!=-1) effectMask|=(2<<k);
|
||||
}
|
||||
|
||||
if (mask==0) {
|
||||
emptyRows++;
|
||||
if (emptyRows>127) {
|
||||
w->writeC(128|(emptyRows-2));
|
||||
emptyRows=0;
|
||||
}
|
||||
} else {
|
||||
if (emptyRows>1) {
|
||||
w->writeC(128|(emptyRows-2));
|
||||
emptyRows=0;
|
||||
} else if (emptyRows) {
|
||||
w->writeC(0);
|
||||
emptyRows=0;
|
||||
}
|
||||
|
||||
w->writeC(mask);
|
||||
|
||||
if (mask&32) w->writeC(effectMask&0xff);
|
||||
if (mask&64) w->writeC((effectMask>>8)&0xff);
|
||||
|
||||
if (mask&1) w->writeC(finalNote);
|
||||
if (mask&2) w->writeC(pat->data[j][2]);
|
||||
if (mask&4) w->writeC(pat->data[j][3]);
|
||||
if (mask&8) w->writeC(pat->data[j][4]);
|
||||
if (mask&16) w->writeC(pat->data[j][5]);
|
||||
if (mask&32) {
|
||||
if (effectMask&4) w->writeC(pat->data[j][6]);
|
||||
if (effectMask&8) w->writeC(pat->data[j][7]);
|
||||
if (effectMask&16) w->writeC(pat->data[j][8]);
|
||||
if (effectMask&32) w->writeC(pat->data[j][9]);
|
||||
if (effectMask&64) w->writeC(pat->data[j][10]);
|
||||
if (effectMask&128) w->writeC(pat->data[j][11]);
|
||||
}
|
||||
if (mask&64) {
|
||||
if (effectMask&256) w->writeC(pat->data[j][12]);
|
||||
if (effectMask&512) w->writeC(pat->data[j][13]);
|
||||
if (effectMask&1024) w->writeC(pat->data[j][14]);
|
||||
if (effectMask&2048) w->writeC(pat->data[j][15]);
|
||||
if (effectMask&4096) w->writeC(pat->data[j][16]);
|
||||
if (effectMask&8192) w->writeC(pat->data[j][17]);
|
||||
if (effectMask&16384) w->writeC(pat->data[j][18]);
|
||||
if (effectMask&32768) w->writeC(pat->data[j][19]);
|
||||
}
|
||||
}
|
||||
if (pat->newData[j][DIV_PAT_NOTE]==DIV_NOTE_OFF) { // note off
|
||||
finalNote=180;
|
||||
} else if (pat->newData[j][DIV_PAT_NOTE]==DIV_NOTE_REL) { // note release
|
||||
finalNote=181;
|
||||
} else if (pat->newData[j][DIV_PAT_NOTE]==DIV_MACRO_REL) { // macro release
|
||||
finalNote=182;
|
||||
} else if (pat->newData[j][DIV_PAT_NOTE]==-1) { // empty
|
||||
finalNote=255;
|
||||
} else {
|
||||
finalNote=pat->newData[j][DIV_PAT_NOTE];
|
||||
}
|
||||
|
||||
// stop
|
||||
w->writeC(0xff);
|
||||
} else {
|
||||
w->write("PATR",4);
|
||||
blockStartSeek=w->tell();
|
||||
w->writeI(0);
|
||||
|
||||
w->writeS(i.chan);
|
||||
w->writeS(i.pat);
|
||||
w->writeS(i.subsong);
|
||||
|
||||
w->writeS(0); // reserved
|
||||
|
||||
for (int j=0; j<song.subsong[i.subsong]->patLen; j++) {
|
||||
w->writeS(pat->data[j][0]); // note
|
||||
w->writeS(pat->data[j][1]); // octave
|
||||
w->writeS(pat->data[j][2]); // instrument
|
||||
w->writeS(pat->data[j][3]); // volume
|
||||
#ifdef TA_BIG_ENDIAN
|
||||
for (int k=0; k<song.subsong[i.subsong]->pat[i.chan].effectCols*2; k++) {
|
||||
w->writeS(pat->data[j][4+k]);
|
||||
if (finalNote!=255) mask|=1; // note
|
||||
if (pat->newData[j][DIV_PAT_INS]!=-1) mask|=2; // instrument
|
||||
if (pat->newData[j][DIV_PAT_VOL]!=-1) mask|=4; // volume
|
||||
for (int k=0; k<song.subsong[i.subsong]->pat[i.chan].effectCols*2; k+=2) {
|
||||
if (k==0) {
|
||||
if (pat->newData[j][DIV_PAT_FX(0)+k]!=-1) mask|=8;
|
||||
if (pat->newData[j][DIV_PAT_FXVAL(1)+k]!=-1) mask|=16;
|
||||
} else if (k<8) {
|
||||
if (pat->newData[j][DIV_PAT_FX(0)+k]!=-1 || pat->newData[j][DIV_PAT_FXVAL(1)+k]!=-1) mask|=32;
|
||||
} else {
|
||||
if (pat->newData[j][DIV_PAT_FX(0)+k]!=-1 || pat->newData[j][DIV_PAT_FXVAL(1)+k]!=-1) mask|=64;
|
||||
}
|
||||
#else
|
||||
w->write(&pat->data[j][4],2*song.subsong[i.subsong]->pat[i.chan].effectCols*2); // effects
|
||||
#endif
|
||||
|
||||
if (pat->newData[j][DIV_PAT_FX(0)+k]!=-1) effectMask|=(1<<k);
|
||||
if (pat->newData[j][DIV_PAT_FXVAL(1)+k]!=-1) effectMask|=(2<<k);
|
||||
}
|
||||
|
||||
w->writeString(pat->name,false);
|
||||
if (mask==0) {
|
||||
emptyRows++;
|
||||
if (emptyRows>127) {
|
||||
w->writeC(128|(emptyRows-2));
|
||||
emptyRows=0;
|
||||
}
|
||||
} else {
|
||||
if (emptyRows>1) {
|
||||
w->writeC(128|(emptyRows-2));
|
||||
emptyRows=0;
|
||||
} else if (emptyRows) {
|
||||
w->writeC(0);
|
||||
emptyRows=0;
|
||||
}
|
||||
|
||||
w->writeC(mask);
|
||||
|
||||
if (mask&32) w->writeC(effectMask&0xff);
|
||||
if (mask&64) w->writeC((effectMask>>8)&0xff);
|
||||
|
||||
if (mask&1) w->writeC(finalNote);
|
||||
if (mask&2) w->writeC(pat->newData[j][DIV_PAT_INS]);
|
||||
if (mask&4) w->writeC(pat->newData[j][DIV_PAT_VOL]);
|
||||
if (mask&8) w->writeC(pat->newData[j][DIV_PAT_FX(0)]);
|
||||
if (mask&16) w->writeC(pat->newData[j][DIV_PAT_FXVAL(0)]);
|
||||
if (mask&32) {
|
||||
if (effectMask&4) w->writeC(pat->newData[j][DIV_PAT_FX(1)]);
|
||||
if (effectMask&8) w->writeC(pat->newData[j][DIV_PAT_FXVAL(1)]);
|
||||
if (effectMask&16) w->writeC(pat->newData[j][DIV_PAT_FX(2)]);
|
||||
if (effectMask&32) w->writeC(pat->newData[j][DIV_PAT_FXVAL(2)]);
|
||||
if (effectMask&64) w->writeC(pat->newData[j][DIV_PAT_FX(3)]);
|
||||
if (effectMask&128) w->writeC(pat->newData[j][DIV_PAT_FXVAL(3)]);
|
||||
}
|
||||
if (mask&64) {
|
||||
if (effectMask&256) w->writeC(pat->newData[j][DIV_PAT_FX(4)]);
|
||||
if (effectMask&512) w->writeC(pat->newData[j][DIV_PAT_FXVAL(4)]);
|
||||
if (effectMask&1024) w->writeC(pat->newData[j][DIV_PAT_FX(5)]);
|
||||
if (effectMask&2048) w->writeC(pat->newData[j][DIV_PAT_FXVAL(5)]);
|
||||
if (effectMask&4096) w->writeC(pat->newData[j][DIV_PAT_FX(6)]);
|
||||
if (effectMask&8192) w->writeC(pat->newData[j][DIV_PAT_FXVAL(6)]);
|
||||
if (effectMask&16384) w->writeC(pat->newData[j][DIV_PAT_FX(7)]);
|
||||
if (effectMask&32768) w->writeC(pat->newData[j][DIV_PAT_FXVAL(7)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stop
|
||||
w->writeC(0xff);
|
||||
|
||||
blockEndSeek=w->tell();
|
||||
w->seek(blockStartSeek,SEEK_SET);
|
||||
w->writeI(blockEndSeek-blockStartSeek-4);
|
||||
|
|
|
|||
|
|
@ -1139,82 +1139,82 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
for (int j=0; j<64; j++) {
|
||||
DivPattern* p=ds.subsong[0]->pat[j].getPattern(i,true);
|
||||
if (vibing[j]!=vibingOld[j] || vibStatusChanged[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0x04;
|
||||
p->data[readRow][effectCol[j]++]=vibing[j]?vibStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x04;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=vibing[j]?vibStatus[j]:0;
|
||||
doesVibrato[j]=true;
|
||||
} else if (doesVibrato[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x04;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x04;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (volSliding[j]!=volSlidingOld[j] || volSlideStatusChanged[j]) {
|
||||
if (volSlideStatus[j]>=0xf1 && volSliding[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0xf9;
|
||||
p->data[readRow][effectCol[j]++]=volSlideStatus[j]&15;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0xf9;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=volSlideStatus[j]&15;
|
||||
volSliding[j]=false;
|
||||
} else if ((volSlideStatus[j]&15)==15 && volSlideStatus[j]>=0x10 && volSliding[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0xf8;
|
||||
p->data[readRow][effectCol[j]++]=volSlideStatus[j]>>4;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0xf8;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=volSlideStatus[j]>>4;
|
||||
volSliding[j]=false;
|
||||
} else {
|
||||
p->data[readRow][effectCol[j]++]=0xfa;
|
||||
p->data[readRow][effectCol[j]++]=volSliding[j]?volSlideStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0xfa;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=volSliding[j]?volSlideStatus[j]:0;
|
||||
}
|
||||
doesVolSlide[j]=true;
|
||||
} else if (doesVolSlide[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0xfa;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0xfa;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (porting[j]!=portingOld[j] || portaStatusChanged[j]) {
|
||||
if (portaStatus[j]>=0xe0 && portaType[j]!=3 && porting[j]) {
|
||||
p->data[readRow][effectCol[j]++]=portaType[j]|0xf0;
|
||||
p->data[readRow][effectCol[j]++]=(portaStatus[j]&15)*((portaStatus[j]>=0xf0)?1:1);
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=portaType[j]|0xf0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=(portaStatus[j]&15)*((portaStatus[j]>=0xf0)?1:1);
|
||||
porting[j]=false;
|
||||
} else {
|
||||
p->data[readRow][effectCol[j]++]=portaType[j];
|
||||
p->data[readRow][effectCol[j]++]=porting[j]?portaStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=portaType[j];
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=porting[j]?portaStatus[j]:0;
|
||||
}
|
||||
doesPitchSlide[j]=true;
|
||||
} else if (doesPitchSlide[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x01;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x01;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (arping[j]!=arpingOld[j] || arpStatusChanged[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0x00;
|
||||
p->data[readRow][effectCol[j]++]=arping[j]?arpStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x00;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=arping[j]?arpStatus[j]:0;
|
||||
doesArp[j]=true;
|
||||
} else if (doesArp[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x00;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x00;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (treming[j]!=tremingOld[j] || tremStatusChanged[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0x07;
|
||||
p->data[readRow][effectCol[j]++]=treming[j]?tremStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x07;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=treming[j]?tremStatus[j]:0;
|
||||
doesTremolo[j]=true;
|
||||
} else if (doesTremolo[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x07;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x07;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (panning[j]!=panningOld[j] || panStatusChanged[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0x84;
|
||||
p->data[readRow][effectCol[j]++]=panning[j]?panStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x84;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=panning[j]?panStatus[j]:0;
|
||||
doesPanbrello[j]=true;
|
||||
} else if (doesPanbrello[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x84;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x84;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (panSliding[j]!=panSlidingOld[j] || panSlideStatusChanged[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0x83;
|
||||
p->data[readRow][effectCol[j]++]=panSliding[j]?panSlideStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x83;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=panSliding[j]?panSlideStatus[j]:0;
|
||||
doesPanSlide[j]=true;
|
||||
} else if (doesPanSlide[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x83;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x83;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if ((effectCol[j]>>1)-2>ds.subsong[0]->pat[j].effectCols) {
|
||||
|
|
@ -1250,8 +1250,8 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
if (readRow>0) {
|
||||
// place end of pattern marker
|
||||
DivPattern* p=ds.subsong[0]->pat[0].getPattern(i,true);
|
||||
p->data[readRow-1][effectCol[0]++]=0x0d;
|
||||
p->data[readRow-1][effectCol[0]++]=0;
|
||||
p->newData[readRow-1][DIV_PAT_FX(0)+effectCol[0]++]=0x0d;
|
||||
p->newData[readRow-1][DIV_PAT_FX(0)+effectCol[0]++]=0;
|
||||
|
||||
if ((effectCol[0]>>1)-2>ds.subsong[0]->pat[0].effectCols) {
|
||||
ds.subsong[0]->pat[0].effectCols=(effectCol[0]>>1)-1;
|
||||
|
|
@ -1302,25 +1302,17 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
|
||||
if (hasNote) {
|
||||
if (note[chan]==255) { // note release
|
||||
p->data[readRow][0]=101;
|
||||
p->data[readRow][1]=0;
|
||||
p->newData[readRow][DIV_PAT_NOTE]=DIV_NOTE_REL;
|
||||
} else if (note[chan]==254) { // note off
|
||||
p->data[readRow][0]=100;
|
||||
p->data[readRow][1]=0;
|
||||
p->newData[readRow][DIV_PAT_NOTE]=DIV_NOTE_OFF;
|
||||
} else if (note[chan]<120) {
|
||||
p->data[readRow][0]=note[chan]%12;
|
||||
p->data[readRow][1]=note[chan]/12;
|
||||
if (p->data[readRow][0]==0) {
|
||||
p->data[readRow][0]=12;
|
||||
p->data[readRow][1]--;
|
||||
}
|
||||
p->newData[readRow][DIV_PAT_NOTE]=note[chan]+60;
|
||||
} else { // note fade, but Furnace does not support that
|
||||
p->data[readRow][0]=102;
|
||||
p->data[readRow][1]=0;
|
||||
p->newData[readRow][DIV_PAT_NOTE]=DIV_MACRO_REL;
|
||||
}
|
||||
}
|
||||
if (hasIns) {
|
||||
p->data[readRow][2]=ins[chan]-1;
|
||||
p->newData[readRow][DIV_PAT_INS]=ins[chan]-1;
|
||||
if ((note[chan]<120 || ds.insLen==0) && ins[chan]>0) {
|
||||
unsigned char targetPan=0;
|
||||
if (ds.insLen==0) {
|
||||
|
|
@ -1332,26 +1324,26 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
}
|
||||
}
|
||||
if (targetPan&128) {
|
||||
p->data[readRow][effectCol[chan]++]=0x80;
|
||||
p->data[readRow][effectCol[chan]++]=CLAMP((targetPan&127)<<2,0,255);
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x80;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=CLAMP((targetPan&127)<<2,0,255);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasNote && (note[chan]<120 || ds.insLen==0) && ins[chan]>0) {
|
||||
if (ds.insLen==0) {
|
||||
p->data[readRow][3]=defVol[(ins[chan]-1)&255];
|
||||
p->newData[readRow][DIV_PAT_VOL]=defVol[(ins[chan]-1)&255];
|
||||
} else {
|
||||
p->data[readRow][3]=defVol[noteMap[(ins[chan]-1)&255][note[chan]]];
|
||||
p->newData[readRow][DIV_PAT_VOL]=defVol[noteMap[(ins[chan]-1)&255][note[chan]]];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasVol) {
|
||||
if (vol[chan]<=64) {
|
||||
p->data[readRow][3]=vol[chan];
|
||||
p->newData[readRow][DIV_PAT_VOL]=vol[chan];
|
||||
} else { // effects in volume column
|
||||
if (vol[chan]>=128 && vol[chan]<=192) { // panning
|
||||
p->data[readRow][effectCol[chan]++]=0x80;
|
||||
p->data[readRow][effectCol[chan]++]=CLAMP((vol[chan]-128)<<2,0,255);
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x80;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=CLAMP((vol[chan]-128)<<2,0,255);
|
||||
} else if (vol[chan]>=65 && vol[chan]<=74) { // fine vol up
|
||||
} else if (vol[chan]>=75 && vol[chan]<=84) { // fine vol down
|
||||
} else if (vol[chan]>=85 && vol[chan]<=94) { // vol slide up
|
||||
|
|
@ -1398,16 +1390,16 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
if (hasEffect) {
|
||||
switch (effect[chan]+'A'-1) {
|
||||
case 'A': // speed
|
||||
p->data[readRow][effectCol[chan]++]=0x0f;
|
||||
p->data[readRow][effectCol[chan]++]=effectVal[chan];
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0f;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal[chan];
|
||||
break;
|
||||
case 'B': // go to order
|
||||
p->data[readRow][effectCol[chan]++]=0x0b;
|
||||
p->data[readRow][effectCol[chan]++]=orders[effectVal[chan]];
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0b;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=orders[effectVal[chan]];
|
||||
break;
|
||||
case 'C': // next order
|
||||
p->data[readRow][effectCol[chan]++]=0x0d;
|
||||
p->data[readRow][effectCol[chan]++]=effectVal[chan];
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0d;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal[chan];
|
||||
break;
|
||||
case 'D': // vol slide
|
||||
if (effectVal[chan]!=0) {
|
||||
|
|
@ -1490,8 +1482,8 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
case 'N': // channel vol slide
|
||||
break;
|
||||
case 'O': // offset
|
||||
p->data[readRow][effectCol[chan]++]=0x91;
|
||||
p->data[readRow][effectCol[chan]++]=effectVal[chan];
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x91;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal[chan];
|
||||
break;
|
||||
case 'P': // pan slide
|
||||
if (effectVal[chan]!=0) {
|
||||
|
|
@ -1504,8 +1496,8 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
if (effectVal[chan]!=0) {
|
||||
lastRetrig[chan]=effectVal[chan];
|
||||
}
|
||||
p->data[readRow][effectCol[chan]++]=0x0c;
|
||||
p->data[readRow][effectCol[chan]++]=lastRetrig[chan]&15;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0c;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=lastRetrig[chan]&15;
|
||||
break;
|
||||
case 'R': // tremolo
|
||||
if (effectVal[chan]!=0) {
|
||||
|
|
@ -1519,77 +1511,77 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
case 0x3: // vibrato waveform
|
||||
switch (effectVal[chan]&3) {
|
||||
case 0x0: // sine
|
||||
p->data[readRow][effectCol[chan]++]=0xe3;
|
||||
p->data[readRow][effectCol[chan]++]=0x00;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xe3;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x00;
|
||||
break;
|
||||
case 0x1: // ramp down
|
||||
p->data[readRow][effectCol[chan]++]=0xe3;
|
||||
p->data[readRow][effectCol[chan]++]=0x05;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xe3;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x05;
|
||||
break;
|
||||
case 0x2: // square
|
||||
p->data[readRow][effectCol[chan]++]=0xe3;
|
||||
p->data[readRow][effectCol[chan]++]=0x06;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xe3;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x06;
|
||||
break;
|
||||
case 0x3: // random
|
||||
p->data[readRow][effectCol[chan]++]=0xe3;
|
||||
p->data[readRow][effectCol[chan]++]=0x07;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xe3;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x07;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x7:
|
||||
switch (effectVal[chan]&15) {
|
||||
case 0x7: // volume envelope off
|
||||
p->data[readRow][effectCol[chan]++]=0xf5;
|
||||
p->data[readRow][effectCol[chan]++]=0x00;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xf5;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x00;
|
||||
break;
|
||||
case 0x8: // volume envelope on
|
||||
p->data[readRow][effectCol[chan]++]=0xf6;
|
||||
p->data[readRow][effectCol[chan]++]=0x00;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xf6;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x00;
|
||||
break;
|
||||
case 0x9: // panning envelope off
|
||||
p->data[readRow][effectCol[chan]++]=0xf5;
|
||||
p->data[readRow][effectCol[chan]++]=0x0c;
|
||||
p->data[readRow][effectCol[chan]++]=0xf5;
|
||||
p->data[readRow][effectCol[chan]++]=0x0d;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xf5;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0c;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xf5;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0d;
|
||||
break;
|
||||
case 0xa: // panning envelope on
|
||||
p->data[readRow][effectCol[chan]++]=0xf6;
|
||||
p->data[readRow][effectCol[chan]++]=0x0c;
|
||||
p->data[readRow][effectCol[chan]++]=0xf6;
|
||||
p->data[readRow][effectCol[chan]++]=0x0d;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xf6;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0c;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xf6;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x0d;
|
||||
break;
|
||||
case 0xb: // pitch envelope off
|
||||
p->data[readRow][effectCol[chan]++]=0xf5;
|
||||
p->data[readRow][effectCol[chan]++]=0x04;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xf5;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x04;
|
||||
break;
|
||||
case 0xc: //pitch envelope on
|
||||
p->data[readRow][effectCol[chan]++]=0xf6;
|
||||
p->data[readRow][effectCol[chan]++]=0x04;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xf6;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x04;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x8: // panning
|
||||
p->data[readRow][effectCol[chan]++]=0x80;
|
||||
p->data[readRow][effectCol[chan]++]=(effectVal[chan]&15)<<4;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x80;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=(effectVal[chan]&15)<<4;
|
||||
break;
|
||||
case 0xa: // offset (high nibble)
|
||||
p->data[readRow][effectCol[chan]++]=0x92;
|
||||
p->data[readRow][effectCol[chan]++]=effectVal[chan]&15;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x92;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal[chan]&15;
|
||||
break;
|
||||
case 0xc: // note cut
|
||||
p->data[readRow][effectCol[chan]++]=0xec;
|
||||
p->data[readRow][effectCol[chan]++]=effectVal[chan]&15;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xec;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal[chan]&15;
|
||||
break;
|
||||
case 0xd: // note delay
|
||||
p->data[readRow][effectCol[chan]++]=0xed;
|
||||
p->data[readRow][effectCol[chan]++]=effectVal[chan]&15;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xed;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal[chan]&15;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'T': // tempo
|
||||
if (effectVal[chan]>=0x20) {
|
||||
p->data[readRow][effectCol[chan]++]=0xf0;
|
||||
p->data[readRow][effectCol[chan]++]=effectVal[chan];
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0xf0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal[chan];
|
||||
}
|
||||
break;
|
||||
case 'U': // fine vibrato
|
||||
|
|
@ -1604,8 +1596,8 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
case 'W': // global volume slide (!)
|
||||
break;
|
||||
case 'X': // panning
|
||||
p->data[readRow][effectCol[chan]++]=0x80;
|
||||
p->data[readRow][effectCol[chan]++]=effectVal[chan];
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=0x80;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[chan]++]=effectVal[chan];
|
||||
break;
|
||||
case 'Y': // panbrello
|
||||
if (effectVal[chan]!=0) {
|
||||
|
|
@ -1690,18 +1682,18 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
for (int j=0; j<maxChan; j++) {
|
||||
DivPattern* p=ds.subsong[i]->pat[j].getPattern(ds.subsong[i]->orders.ord[j][0],true);
|
||||
for (int k=0; k<DIV_MAX_EFFECTS; k++) {
|
||||
if (p->data[0][4+(k<<1)]==0x80) {
|
||||
if (p->newData[0][DIV_PAT_FX(k)]==0x80) {
|
||||
// give up if there's a panning effect already
|
||||
break;
|
||||
}
|
||||
if (p->data[0][4+(k<<1)]==-1) {
|
||||
if (p->newData[0][DIV_PAT_FX(k)]==-1) {
|
||||
if ((chanPan[j]&127)==100) {
|
||||
// should be surround...
|
||||
p->data[0][4+(k<<1)]=0x80;
|
||||
p->data[0][5+(k<<1)]=0x80;
|
||||
p->newData[0][DIV_PAT_FX(k)]=0x80;
|
||||
p->newData[0][DIV_PAT_FXVAL(k)]=0x80;
|
||||
} else {
|
||||
p->data[0][4+(k<<1)]=0x80;
|
||||
p->data[0][5+(k<<1)]=CLAMP((chanPan[j]&127)<<2,0,255);
|
||||
p->newData[0][DIV_PAT_FX(k)]=0x80;
|
||||
p->newData[0][DIV_PAT_FXVAL(k)]=CLAMP((chanPan[j]&127)<<2,0,255);
|
||||
}
|
||||
if (ds.subsong[i]->pat[j].effectCols<=k) ds.subsong[i]->pat[j].effectCols=k+1;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -185,21 +185,21 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
}
|
||||
for (int row=0; row<64; row++) {
|
||||
for (int ch=0; ch<chCount; ch++) {
|
||||
short* dstrow=chpats[ch]->data[row];
|
||||
short* dstrowN=chpats[ch]->newData[row];
|
||||
unsigned char data[4];
|
||||
reader.read(&data,4);
|
||||
// instrument
|
||||
short ins=(data[0]&0xf0)|(data[2]>>4);
|
||||
if (ins>0) {
|
||||
dstrow[2]=ins-1;
|
||||
dstrow[3]=defaultVols[ins-1];
|
||||
dstrowN[DIV_PAT_INS]=ins-1;
|
||||
dstrowN[DIV_PAT_VOL]=defaultVols[ins-1];
|
||||
}
|
||||
// note
|
||||
int period=data[1]+((data[0]&0x0f)<<8);
|
||||
if (period>0 && period<0x0fff) {
|
||||
short note=(short)round(log2(3424.0/period)*12);
|
||||
dstrow[0]=((note+11)%12)+1;
|
||||
dstrow[1]=(note-1)/12+1;
|
||||
// TODO: refactor test
|
||||
dstrowN[DIV_PAT_NOTE]=note+60;
|
||||
if (period<114) {
|
||||
bypassLimits=true;
|
||||
}
|
||||
|
|
@ -207,8 +207,8 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
// effects are done later
|
||||
short fxtyp=data[2]&0x0f;
|
||||
short fxval=data[3];
|
||||
dstrow[4]=fxtyp;
|
||||
dstrow[5]=fxval;
|
||||
dstrowN[DIV_PAT_FX(0)]=fxtyp;
|
||||
dstrowN[DIV_PAT_FXVAL(0)]=fxval;
|
||||
switch (fxtyp) {
|
||||
case 0:
|
||||
if (fxval!=0) fxUsage[ch][0]=true;
|
||||
|
|
@ -256,7 +256,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
for (int ch=0; ch<=chCount; ch++) {
|
||||
unsigned char fxCols=1;
|
||||
for (int pat=0; pat<=patMax; pat++) {
|
||||
auto* data=ds.subsong[0]->pat[ch].getPattern(pat,true)->data;
|
||||
auto* newData=ds.subsong[0]->pat[ch].getPattern(pat,true)->newData;
|
||||
short lastPitchEffect=-1;
|
||||
short lastEffectState[5]={-1,-1,-1,-1,-1};
|
||||
short setEffectState[5]={-1,-1,-1,-1,-1};
|
||||
|
|
@ -264,11 +264,11 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
const short fxUsageTyp[5]={0x00,0x01,0x04,0x07,0xFA};
|
||||
short effectState[5]={0,0,0,0,0};
|
||||
unsigned char curFxCol=0;
|
||||
short fxTyp=data[row][4];
|
||||
short fxVal=data[row][5];
|
||||
auto writeFxCol=[data,row,&curFxCol](short typ, short val) {
|
||||
data[row][4+curFxCol*2]=typ;
|
||||
data[row][5+curFxCol*2]=val;
|
||||
short fxTyp=newData[row][DIV_PAT_FX(0)];
|
||||
short fxVal=newData[row][DIV_PAT_FXVAL(0)];
|
||||
auto writeFxCol=[newData,row,&curFxCol](short typ, short val) {
|
||||
newData[row][DIV_PAT_FX(curFxCol)]=typ;
|
||||
newData[row][DIV_PAT_FXVAL(curFxCol)]=val;
|
||||
curFxCol++;
|
||||
};
|
||||
writeFxCol(-1,-1);
|
||||
|
|
@ -293,7 +293,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
effectState[1]=fxVal;
|
||||
if ((effectState[1]!=lastEffectState[1]) ||
|
||||
(fxTyp!=lastPitchEffect) ||
|
||||
(effectState[1]!=0 && data[row][0]>0)) {
|
||||
(effectState[1]!=0 && newData[row][DIV_PAT_NOTE]>-1)) {
|
||||
writeFxCol(fxTyp,fxVal);
|
||||
}
|
||||
lastPitchEffect=fxTyp;
|
||||
|
|
@ -331,7 +331,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
writeFxCol(fxTyp,fxVal);
|
||||
break;
|
||||
case 12: // set vol
|
||||
data[row][3]=MIN(0x40,fxVal);
|
||||
newData[row][DIV_PAT_VOL]=MIN(0x40,fxVal);
|
||||
break;
|
||||
case 13: // break to row (BCD)
|
||||
writeFxCol(fxTyp,((fxVal>>4)*10)+(fxVal&15));
|
||||
|
|
@ -387,7 +387,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
for (int i=0; i<5; i++) {
|
||||
// pitch slide and volume slide needs to be kept active on new note
|
||||
// even after target/max is reached
|
||||
if (fxUsage[ch][i] && (effectState[i]!=lastEffectState[i] || (effectState[i]!=0 && i==4 && data[row][3]>=0))) {
|
||||
if (fxUsage[ch][i] && (effectState[i]!=lastEffectState[i] || (effectState[i]!=0 && i==4 && newData[row][DIV_PAT_VOL]>=0))) {
|
||||
writeFxCol(fxUsageTyp[i],effectState[i]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -811,82 +811,82 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
|||
for (int j=0; j<32; j++) {
|
||||
DivPattern* p=ds.subsong[0]->pat[chanMap[j]].getPattern(i,true);
|
||||
if (vibing[j]!=vibingOld[j] || vibStatusChanged[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0x04;
|
||||
p->data[readRow][effectCol[j]++]=vibing[j]?vibStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x04;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=vibing[j]?vibStatus[j]:0;
|
||||
doesVibrato[j]=true;
|
||||
} else if (doesVibrato[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x04;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x04;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (volSliding[j]!=volSlidingOld[j] || volSlideStatusChanged[j]) {
|
||||
if (volSlideStatus[j]>=0xf1 && volSliding[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0xf9;
|
||||
p->data[readRow][effectCol[j]++]=volSlideStatus[j]&15;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0xf9;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=volSlideStatus[j]&15;
|
||||
volSliding[j]=false;
|
||||
} else if ((volSlideStatus[j]&15)==15 && volSlideStatus[j]>=0x10 && volSliding[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0xf8;
|
||||
p->data[readRow][effectCol[j]++]=volSlideStatus[j]>>4;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0xf8;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=volSlideStatus[j]>>4;
|
||||
volSliding[j]=false;
|
||||
} else {
|
||||
p->data[readRow][effectCol[j]++]=0xfa;
|
||||
p->data[readRow][effectCol[j]++]=volSliding[j]?volSlideStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0xfa;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=volSliding[j]?volSlideStatus[j]:0;
|
||||
}
|
||||
doesVolSlide[j]=true;
|
||||
} else if (doesVolSlide[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0xfa;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0xfa;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (porting[j]!=portingOld[j] || portaStatusChanged[j]) {
|
||||
if (portaStatus[j]>=0xe0 && portaType[j]!=3 && porting[j]) {
|
||||
p->data[readRow][effectCol[j]++]=portaType[j]|0xf0;
|
||||
p->data[readRow][effectCol[j]++]=(portaStatus[j]&15)*((portaStatus[j]>=0xf0)?1:1);
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=portaType[j]|0xf0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=(portaStatus[j]&15)*((portaStatus[j]>=0xf0)?1:1);
|
||||
porting[j]=false;
|
||||
} else {
|
||||
p->data[readRow][effectCol[j]++]=portaType[j];
|
||||
p->data[readRow][effectCol[j]++]=porting[j]?portaStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=portaType[j];
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=porting[j]?portaStatus[j]:0;
|
||||
}
|
||||
doesPitchSlide[j]=true;
|
||||
} else if (doesPitchSlide[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x01;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x01;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (arping[j]!=arpingOld[j] || arpStatusChanged[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0x00;
|
||||
p->data[readRow][effectCol[j]++]=arping[j]?arpStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x00;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=arping[j]?arpStatus[j]:0;
|
||||
doesArp[j]=true;
|
||||
} else if (doesArp[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x00;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x00;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (treming[j]!=tremingOld[j] || tremStatusChanged[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0x07;
|
||||
p->data[readRow][effectCol[j]++]=treming[j]?tremStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x07;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=treming[j]?tremStatus[j]:0;
|
||||
doesTremolo[j]=true;
|
||||
} else if (doesTremolo[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x07;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x07;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (panning[j]!=panningOld[j] || panStatusChanged[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0x84;
|
||||
p->data[readRow][effectCol[j]++]=panning[j]?panStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x84;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=panning[j]?panStatus[j]:0;
|
||||
doesPanbrello[j]=true;
|
||||
} else if (doesPanbrello[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x84;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x84;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (panSliding[j]!=panSlidingOld[j] || panSlideStatusChanged[j]) {
|
||||
p->data[readRow][effectCol[j]++]=0x83;
|
||||
p->data[readRow][effectCol[j]++]=panSliding[j]?panSlideStatus[j]:0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x83;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=panSliding[j]?panSlideStatus[j]:0;
|
||||
doesPanSlide[j]=true;
|
||||
} else if (doesPanSlide[j] && mustCommitInitial) {
|
||||
p->data[readRow][effectCol[j]++]=0x83;
|
||||
p->data[readRow][effectCol[j]++]=0;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0x83;
|
||||
p->newData[readRow][DIV_PAT_FX(0)+effectCol[j]++]=0;
|
||||
}
|
||||
|
||||
if (effectCol[j]>=4+8*2) {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ std::vector<std::pair<int,int>> DivChannelData::optimize() {
|
|||
for (int j=0; j<DIV_MAX_PATTERNS; j++) {
|
||||
if (j==i) continue;
|
||||
if (data[j]==NULL) continue;
|
||||
if (memcmp(data[i]->data,data[j]->data,DIV_MAX_ROWS*DIV_MAX_COLS*sizeof(short))==0) {
|
||||
if (memcmp(data[i]->newData,data[j]->newData,DIV_MAX_ROWS*DIV_MAX_COLS*sizeof(short))==0) {
|
||||
delete data[j];
|
||||
data[j]=NULL;
|
||||
logV("%d == %d",i,j);
|
||||
|
|
@ -86,15 +86,11 @@ void DivChannelData::wipePatterns() {
|
|||
|
||||
void DivPattern::copyOn(DivPattern* dest) {
|
||||
dest->name=name;
|
||||
memcpy(dest->data,data,sizeof(data));
|
||||
memcpy(dest->newData,newData,sizeof(newData));
|
||||
}
|
||||
|
||||
void DivPattern::clear() {
|
||||
memset(data,-1,DIV_MAX_ROWS*DIV_MAX_COLS*sizeof(short));
|
||||
for (int i=0; i<DIV_MAX_ROWS; i++) {
|
||||
data[i][0]=0;
|
||||
data[i][1]=0;
|
||||
}
|
||||
memset(newData,-1,DIV_MAX_ROWS*DIV_MAX_COLS*sizeof(short));
|
||||
}
|
||||
|
||||
DivChannelData::DivChannelData():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue