IT import: improvements
- scan patterns for effect usage - sort of implement note fade
This commit is contained in:
parent
72edfa463f
commit
6ad49e88c3
|
@ -101,7 +101,11 @@ void readEnvelope(SafeReader& reader, DivInstrument* ins, int env) {
|
||||||
pointJustBegan=false;
|
pointJustBegan=false;
|
||||||
if (flags&2) { // loop
|
if (flags&2) { // loop
|
||||||
if (point==loopStart && (!(flags&4) || susStart==susEnd || loopStart>=susEnd)) {
|
if (point==loopStart && (!(flags&4) || susStart==susEnd || loopStart>=susEnd)) {
|
||||||
target->loop=i;
|
if (loopStart==loopEnd) {
|
||||||
|
target->rel=i;
|
||||||
|
} else {
|
||||||
|
target->loop=i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (flags&4) { // sustain
|
if (flags&4) { // sustain
|
||||||
|
@ -386,6 +390,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
||||||
unsigned char initCut=255;
|
unsigned char initCut=255;
|
||||||
unsigned char initRes=255;
|
unsigned char initRes=255;
|
||||||
unsigned char insVol=128;
|
unsigned char insVol=128;
|
||||||
|
unsigned short fadeOut=256;
|
||||||
|
|
||||||
if (compatTracker<0x200) { // old format
|
if (compatTracker<0x200) { // old format
|
||||||
unsigned char flags=reader.readC();
|
unsigned char flags=reader.readC();
|
||||||
|
@ -402,7 +407,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
reader.readS(); // x
|
reader.readS(); // x
|
||||||
|
|
||||||
unsigned short fadeOut=reader.readS();
|
fadeOut=reader.readS();
|
||||||
|
|
||||||
logV("fadeOut: %d",fadeOut);
|
logV("fadeOut: %d",fadeOut);
|
||||||
|
|
||||||
|
@ -418,7 +423,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
||||||
reader.readC();
|
reader.readC();
|
||||||
reader.readC();
|
reader.readC();
|
||||||
|
|
||||||
unsigned short fadeOut=reader.readS();
|
fadeOut=reader.readS();
|
||||||
|
|
||||||
logV("fadeOut: %d",fadeOut);
|
logV("fadeOut: %d",fadeOut);
|
||||||
|
|
||||||
|
@ -487,6 +492,17 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add note fade if there isn't a release point in the volume envelope
|
||||||
|
if (ins->std.volMacro.len>0) {
|
||||||
|
ins->std.volMacro.len--;
|
||||||
|
int initial=ins->std.volMacro.val[ins->std.volMacro.len];
|
||||||
|
ins->std.volMacro.rel=ins->std.volMacro.len;
|
||||||
|
for (int i=1024; ins->std.volMacro.len<255; i-=fadeOut) {
|
||||||
|
ins->std.volMacro.val[ins->std.volMacro.len++]=(initial*i)>>10;
|
||||||
|
if (i<0) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ds.ins.push_back(ins);
|
ds.ins.push_back(ins);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,8 +709,151 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
||||||
ds.sample.push_back(s);
|
ds.sample.push_back(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
// read patterns
|
// scan pattern data for effect use
|
||||||
int maxChan=0;
|
int maxChan=0;
|
||||||
|
for (int i=0; i<patCount; i++) {
|
||||||
|
if (patPtr[i]==0) continue;
|
||||||
|
|
||||||
|
unsigned char mask[64];
|
||||||
|
unsigned char note[64];
|
||||||
|
unsigned char ins[64];
|
||||||
|
unsigned char vol[64];
|
||||||
|
unsigned char effect[64];
|
||||||
|
unsigned char effectVal[64];
|
||||||
|
int curRow=0;
|
||||||
|
|
||||||
|
memset(mask,0,64);
|
||||||
|
memset(note,0,64);
|
||||||
|
memset(ins,0,64);
|
||||||
|
memset(vol,0,64);
|
||||||
|
memset(effect,0,64);
|
||||||
|
memset(effectVal,0,64);
|
||||||
|
|
||||||
|
logV("scanning pattern %d...",i);
|
||||||
|
if (!reader.seek(patPtr[i],SEEK_SET)) {
|
||||||
|
logE("premature end of file!");
|
||||||
|
lastError="incomplete file";
|
||||||
|
delete[] file;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int dataLen=(unsigned short)reader.readS();
|
||||||
|
unsigned short patRows=reader.readS();
|
||||||
|
|
||||||
|
patLen[i]=patRows;
|
||||||
|
|
||||||
|
if (patRows>DIV_MAX_ROWS) {
|
||||||
|
logE("too many rows! %d",patRows);
|
||||||
|
lastError="too many rows";
|
||||||
|
delete[] file;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.readI(); // x
|
||||||
|
|
||||||
|
dataLen+=reader.tell();
|
||||||
|
|
||||||
|
// read pattern data
|
||||||
|
while (reader.tell()<dataLen) {
|
||||||
|
unsigned char chan=reader.readC();
|
||||||
|
bool hasVol=false;
|
||||||
|
bool hasEffect=false;
|
||||||
|
|
||||||
|
if (chan==0) {
|
||||||
|
curRow++;
|
||||||
|
if (curRow>=patRows) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chan&128) {
|
||||||
|
mask[chan&63]=reader.readC();
|
||||||
|
}
|
||||||
|
chan&=63;
|
||||||
|
|
||||||
|
if (chan>maxChan) maxChan=chan;
|
||||||
|
|
||||||
|
if (mask[chan]&1) {
|
||||||
|
note[chan]=reader.readC();
|
||||||
|
}
|
||||||
|
if (mask[chan]&2) {
|
||||||
|
ins[chan]=reader.readC();
|
||||||
|
}
|
||||||
|
if (mask[chan]&4) {
|
||||||
|
vol[chan]=reader.readC();
|
||||||
|
hasVol=true;
|
||||||
|
}
|
||||||
|
if (mask[chan]&8) {
|
||||||
|
effect[chan]=reader.readC();
|
||||||
|
effectVal[chan]=reader.readC();
|
||||||
|
hasEffect=true;
|
||||||
|
}
|
||||||
|
if (mask[chan]&64) {
|
||||||
|
hasVol=true;
|
||||||
|
}
|
||||||
|
if (mask[chan]&128) {
|
||||||
|
hasEffect=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasVol) {
|
||||||
|
if (vol[chan]>64) {
|
||||||
|
if (vol[chan]>=65 && vol[chan]<=74) { // fine vol up
|
||||||
|
doesVolSlide[chan]=true;
|
||||||
|
} else if (vol[chan]>=75 && vol[chan]<=84) { // fine vol down
|
||||||
|
doesVolSlide[chan]=true;
|
||||||
|
} else if (vol[chan]>=85 && vol[chan]<=94) { // vol slide up
|
||||||
|
doesVolSlide[chan]=true;
|
||||||
|
} else if (vol[chan]>=95 && vol[chan]<=104) { // vol slide down
|
||||||
|
doesVolSlide[chan]=true;
|
||||||
|
} else if (vol[chan]>=105 && vol[chan]<=114) { // pitch down
|
||||||
|
doesPitchSlide[chan]=true;
|
||||||
|
} else if (vol[chan]>=115 && vol[chan]<=124) { // pitch up
|
||||||
|
doesPitchSlide[chan]=true;
|
||||||
|
} else if (vol[chan]>=193 && vol[chan]<=202) { // porta
|
||||||
|
doesPitchSlide[chan]=true;
|
||||||
|
} else if (vol[chan]>=203 && vol[chan]<=212) { // vibrato
|
||||||
|
doesVibrato[chan]=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (hasEffect) {
|
||||||
|
switch (effect[chan]+'A'-1) {
|
||||||
|
case 'D': // vol slide
|
||||||
|
doesVolSlide[chan]=true;
|
||||||
|
break;
|
||||||
|
case 'E': // pitch down
|
||||||
|
doesPitchSlide[chan]=true;
|
||||||
|
break;
|
||||||
|
case 'F': // pitch up
|
||||||
|
doesPitchSlide[chan]=true;
|
||||||
|
break;
|
||||||
|
case 'G': // porta
|
||||||
|
doesPitchSlide[chan]=true;
|
||||||
|
break;
|
||||||
|
case 'H': // vibrato
|
||||||
|
doesVibrato[chan]=true;
|
||||||
|
break;
|
||||||
|
case 'J': // arp
|
||||||
|
doesArp[chan]=true;
|
||||||
|
break;
|
||||||
|
case 'K': // vol slide + vibrato
|
||||||
|
doesVolSlide[chan]=true;
|
||||||
|
doesVibrato[chan]=true;
|
||||||
|
break;
|
||||||
|
case 'L': // vol slide + porta
|
||||||
|
doesVolSlide[chan]=true;
|
||||||
|
doesPitchSlide[chan]=true;
|
||||||
|
break;
|
||||||
|
case 'U': // fine vibrato
|
||||||
|
doesVibrato[chan]=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// read patterns
|
||||||
for (int i=0; i<patCount; i++) {
|
for (int i=0; i<patCount; i++) {
|
||||||
unsigned char effectCol[64];
|
unsigned char effectCol[64];
|
||||||
unsigned char vibStatus[64];
|
unsigned char vibStatus[64];
|
||||||
|
|
Loading…
Reference in a new issue