giga-refactor, part 2
This commit is contained in:
parent
a654d33df2
commit
db419dc6c8
27 changed files with 282 additions and 237 deletions
|
|
@ -704,7 +704,7 @@ bool DivCSPlayer::init() {
|
|||
|
||||
// initialize state
|
||||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||
chan[i].volMax=(e->getDispatch(e->dispatchOfChan[i])->dispatch(DivCommand(DIV_CMD_GET_VOLMAX,e->dispatchChanOfChan[i]))<<8)|0xff;
|
||||
chan[i].volMax=(e->getDispatch(e->song.dispatchOfChan[i])->dispatch(DivCommand(DIV_CMD_GET_VOLMAX,e->song.dispatchChanOfChan[i]))<<8)|0xff;
|
||||
chan[i].volume=chan[i].volMax;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1303,7 +1303,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
|
||||
// write header
|
||||
w->write("FCS",4);
|
||||
w->writeS(chans);
|
||||
w->writeS(song.chans);
|
||||
// flags
|
||||
w->writeC((options.longPointers?1:0)|(options.bigEndian?2:0));
|
||||
// reserved
|
||||
|
|
@ -1313,7 +1313,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
w->writeC(0);
|
||||
}
|
||||
// offsets
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
chanStream[i]=new SafeWriter;
|
||||
chanStream[i]->init();
|
||||
if (options.longPointers) {
|
||||
|
|
@ -1323,7 +1323,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
}
|
||||
}
|
||||
// max stack sizes
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeC(0);
|
||||
}
|
||||
|
||||
|
|
@ -1338,7 +1338,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
|
||||
// PASS 0: play the song and log channel command streams
|
||||
// song beginning marker
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
chanStream[i]->writeC(0xd0);
|
||||
chanStream[i]->writeC(i);
|
||||
chanStream[i]->writeC(0x00);
|
||||
|
|
@ -1350,7 +1350,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
chanStream[i]->writeC(0x00);
|
||||
}
|
||||
while (!done) {
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
tickPos[i].push_back(chanStream[i]->tell());
|
||||
}
|
||||
if (loopTick==-1) {
|
||||
|
|
@ -1359,7 +1359,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
logI("loop is on tick %d",tick);
|
||||
loopTick=tick;
|
||||
// loop marker
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
chanStream[i]->writeC(0xd0);
|
||||
chanStream[i]->writeC(i);
|
||||
chanStream[i]->writeC(0x00);
|
||||
|
|
@ -1410,7 +1410,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
}
|
||||
}
|
||||
cmdStream.clear();
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
chanStream[i]->writeC(0xde);
|
||||
// padding
|
||||
chanStream[i]->writeC(0x00);
|
||||
|
|
@ -1424,7 +1424,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
tick++;
|
||||
}
|
||||
if (!playing || loopTick<0) {
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
chanStream[i]->writeC(0xdf);
|
||||
// padding
|
||||
chanStream[i]->writeC(0x00);
|
||||
|
|
@ -1436,7 +1436,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
chanStream[i]->writeC(0x00);
|
||||
}
|
||||
} else {
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if ((int)tickPos[i].size()>loopTick) {
|
||||
chanStream[i]->writeC(0xda);
|
||||
chanStream[i]->writeI(tickPos[i][loopTick]);
|
||||
|
|
@ -1494,7 +1494,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
}
|
||||
|
||||
// set preset instruments
|
||||
for (int h=0; h<chans; h++) {
|
||||
for (int h=0; h<song.chans; h++) {
|
||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||
for (size_t i=0; i<chanStream[h]->size(); i+=8) {
|
||||
if (buf[i]==0xb8) {
|
||||
|
|
@ -1536,7 +1536,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
}
|
||||
|
||||
// set preset volumes
|
||||
for (int h=0; h<chans; h++) {
|
||||
for (int h=0; h<song.chans; h++) {
|
||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||
for (size_t i=0; i<chanStream[h]->size(); i+=8) {
|
||||
if (buf[i]==0xc7) {
|
||||
|
|
@ -1578,7 +1578,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
}
|
||||
|
||||
// set speed dial commands
|
||||
for (int h=0; h<chans; h++) {
|
||||
for (int h=0; h<song.chans; h++) {
|
||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||
for (size_t i=0; i<chanStream[h]->size(); i+=8) {
|
||||
if (buf[i]==0xd7) {
|
||||
|
|
@ -1601,7 +1601,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
// PASS 2: condense delays
|
||||
if (!options.noDelayCondense) {
|
||||
// calculate delay usage
|
||||
for (int h=0; h<chans; h++) {
|
||||
for (int h=0; h<song.chans; h++) {
|
||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||
int delayCount=0;
|
||||
for (size_t i=0; i<chanStream[h]->size(); i+=8) {
|
||||
|
|
@ -1639,7 +1639,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
}
|
||||
|
||||
// condense delays
|
||||
for (int h=0; h<chans; h++) {
|
||||
for (int h=0; h<song.chans; h++) {
|
||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||
int delayPos=-1;
|
||||
int delayCount=0;
|
||||
|
|
@ -1693,7 +1693,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
|
||||
// PASS 3: note off + one-tick wait
|
||||
// optimize one-tick gaps sometimes used in songs
|
||||
for (int h=0; h<chans; h++) {
|
||||
for (int h=0; h<song.chans; h++) {
|
||||
unsigned char* buf=chanStream[h]->getFinalBuf();
|
||||
if (chanStream[h]->size()<8) continue;
|
||||
for (size_t i=0; i<chanStream[h]->size()-8; i+=8) {
|
||||
|
|
@ -1714,12 +1714,12 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
|
||||
// PASS 4: remove nop's
|
||||
// this includes modifying call addresses to compensate
|
||||
for (int h=0; h<chans; h++) {
|
||||
for (int h=0; h<song.chans; h++) {
|
||||
chanStream[h]=stripNops(chanStream[h]);
|
||||
}
|
||||
|
||||
// PASS 5: put all channels together
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
chanStreamOff[i]=globalStream->tell();
|
||||
logI("- %d: off %x size %ld",i,chanStreamOff[i],chanStream[i]->size());
|
||||
reloc8(chanStream[i]->getFinalBuf(),chanStream[i]->size(),0,globalStream->tell());
|
||||
|
|
@ -1798,7 +1798,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
// also find new offsets
|
||||
globalStream=stripNopsPacked(globalStream,sortedCmd,chanStreamOff);
|
||||
|
||||
for (int h=0; h<chans; h++) {
|
||||
for (int h=0; h<song.chans; h++) {
|
||||
chanStreamOff[h]+=w->tell();
|
||||
}
|
||||
|
||||
|
|
@ -1807,7 +1807,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
w->write(globalStream->getFinalBuf(),globalStream->size());
|
||||
|
||||
// calculate max stack sizes
|
||||
for (int h=0; h<chans; h++) {
|
||||
for (int h=0; h<song.chans; h++) {
|
||||
std::stack<unsigned int> callStack;
|
||||
unsigned int maxStackSize=0;
|
||||
unsigned char* buf=w->getFinalBuf();
|
||||
|
|
@ -1866,7 +1866,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
delete globalStream;
|
||||
|
||||
w->seek(40,SEEK_SET);
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (options.longPointers) {
|
||||
if (options.bigEndian) {
|
||||
w->writeI_BE(chanStreamOff[i]);
|
||||
|
|
@ -1884,7 +1884,7 @@ SafeWriter* DivEngine::saveCommand(DivCSProgress* progress, DivCSOptions options
|
|||
|
||||
logD("maximum stack sizes:");
|
||||
unsigned int cumulativeStackSize=0;
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
w->writeC(chanStackSize[i]);
|
||||
logD("- %d: %d",i,chanStackSize[i]);
|
||||
cumulativeStackSize+=chanStackSize[i];
|
||||
|
|
|
|||
|
|
@ -179,19 +179,23 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul
|
|||
case 0x92:
|
||||
return _("92xx: Set sample offset (third byte, ×65536)");
|
||||
}
|
||||
} else if (chan>=0 && chan<chans) {
|
||||
DivSysDef* sysDef=sysDefs[sysOfChan[chan]];
|
||||
auto iter=sysDef->effectHandlers.find(effect);
|
||||
if (iter!=sysDef->effectHandlers.end()) {
|
||||
return iter->second.description;
|
||||
}
|
||||
iter=sysDef->postEffectHandlers.find(effect);
|
||||
if (iter!=sysDef->postEffectHandlers.end()) {
|
||||
return iter->second.description;
|
||||
}
|
||||
iter=sysDef->preEffectHandlers.find(effect);
|
||||
if (iter!=sysDef->preEffectHandlers.end()) {
|
||||
return iter->second.description;
|
||||
} else if (chan>=0 && chan<song.chans) {
|
||||
DivSysDef* sysDef=sysDefs[song.sysOfChan[chan]];
|
||||
if (sysDef==NULL) {
|
||||
return notNull?_("Invalid effect"):NULL;
|
||||
} else {
|
||||
auto iter=sysDef->effectHandlers.find(effect);
|
||||
if (iter!=sysDef->effectHandlers.end()) {
|
||||
return iter->second.description;
|
||||
}
|
||||
iter=sysDef->postEffectHandlers.find(effect);
|
||||
if (iter!=sysDef->postEffectHandlers.end()) {
|
||||
return iter->second.description;
|
||||
}
|
||||
iter=sysDef->preEffectHandlers.find(effect);
|
||||
if (iter!=sysDef->preEffectHandlers.end()) {
|
||||
return iter->second.description;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
@ -201,7 +205,7 @@ const char* DivEngine::getEffectDesc(unsigned char effect, int chan, bool notNul
|
|||
|
||||
void DivEngine::calcSongTimestamps() {
|
||||
if (curSubSong!=NULL) {
|
||||
curSubSong->calcTimestamps(chans,song.grooves,song.jumpTreatment,song.ignoreJumpAtEnd,song.brokenSpeedSel,song.delayBehavior);
|
||||
curSubSong->calcTimestamps(song.chans,song.grooves,song.jumpTreatment,song.ignoreJumpAtEnd,song.brokenSpeedSel,song.delayBehavior);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -531,6 +535,7 @@ void DivEngine::initSongWithDesc(const char* description, bool inBase64, bool ol
|
|||
song.systemFlags[index].loadFromBase64(flags.c_str());
|
||||
}
|
||||
song.systemLen=index;
|
||||
song.initDefaultSystemChans();
|
||||
|
||||
// extra attributes
|
||||
song.subsong[0]->hz=c.getDouble("tickRate",60.0);
|
||||
|
|
@ -564,7 +569,8 @@ void DivEngine::createNew(const char* description, String sysName, bool inBase64
|
|||
} else {
|
||||
song.systemName=sysName;
|
||||
}
|
||||
recalcChans();
|
||||
song.initDefaultSystemChans();
|
||||
song.recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
initDispatch();
|
||||
|
|
@ -602,7 +608,8 @@ void DivEngine::createNewFromDefaults() {
|
|||
song.systemName=sysName;
|
||||
}
|
||||
|
||||
recalcChans();
|
||||
song.initDefaultSystemChans();
|
||||
song.recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
initDispatch();
|
||||
|
|
@ -710,8 +717,8 @@ void DivEngine::changeSong(size_t songIndex) {
|
|||
}
|
||||
|
||||
void DivEngine::copyChannelP(int src, int dest) {
|
||||
if (src<0 || src>=chans) return;
|
||||
if (dest<0 || dest>=chans) return;
|
||||
if (src<0 || src>=song.chans) return;
|
||||
if (dest<0 || dest>=song.chans) return;
|
||||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
copyChannel(src,dest);
|
||||
|
|
@ -720,8 +727,8 @@ void DivEngine::copyChannelP(int src, int dest) {
|
|||
}
|
||||
|
||||
void DivEngine::swapChannelsP(int src, int dest) {
|
||||
if (src<0 || src>=chans) return;
|
||||
if (dest<0 || dest>=chans) return;
|
||||
if (src<0 || src>=song.chans) return;
|
||||
if (dest<0 || dest>=song.chans) return;
|
||||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
swapChannels(src,dest);
|
||||
|
|
@ -874,7 +881,7 @@ void DivEngine::delUnusedIns() {
|
|||
memset(isUsed,0,256*sizeof(bool));
|
||||
|
||||
// scan
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
for (size_t j=0; j<song.subsong.size(); j++) {
|
||||
for (int k=0; k<DIV_MAX_PATTERNS; k++) {
|
||||
if (song.subsong[j]->pat[i].data[k]==NULL) continue;
|
||||
|
|
@ -992,12 +999,12 @@ bool DivEngine::changeSystem(int index, DivSystem which, bool preserveOrder) {
|
|||
lastError=_("invalid index");
|
||||
return false;
|
||||
}
|
||||
if (chans-getChannelCount(song.system[index])+getChannelCount(which)>DIV_MAX_CHANS) {
|
||||
if (song.chans-getChannelCount(song.system[index])+getChannelCount(which)>DIV_MAX_CHANS) {
|
||||
lastError=fmt::sprintf(_("max number of total channels is %d"),DIV_MAX_CHANS);
|
||||
return false;
|
||||
}
|
||||
|
||||
int chanCount=chans;
|
||||
int chanCount=song.chans;
|
||||
quitDispatch();
|
||||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
|
|
@ -1005,7 +1012,7 @@ bool DivEngine::changeSystem(int index, DivSystem which, bool preserveOrder) {
|
|||
if (!preserveOrder) {
|
||||
int firstChan=0;
|
||||
int chanMovement=getChannelCount(which)-getChannelCount(song.system[index]);
|
||||
while (dispatchOfChan[firstChan]!=index) firstChan++;
|
||||
while (song.dispatchOfChan[firstChan]!=index) firstChan++;
|
||||
int lastChan=firstChan+getChannelCount(song.system[index]);
|
||||
if (chanMovement!=0) {
|
||||
if (chanMovement>0) {
|
||||
|
|
@ -1030,7 +1037,7 @@ bool DivEngine::changeSystem(int index, DivSystem which, bool preserveOrder) {
|
|||
|
||||
song.system[index]=which;
|
||||
song.systemFlags[index].clear();
|
||||
recalcChans();
|
||||
song.recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
initDispatch();
|
||||
|
|
@ -1047,7 +1054,7 @@ bool DivEngine::addSystem(DivSystem which) {
|
|||
lastError=fmt::sprintf(_("max number of systems is %d"),DIV_MAX_CHIPS);
|
||||
return false;
|
||||
}
|
||||
if (chans+getChannelCount(which)>DIV_MAX_CHANS) {
|
||||
if (song.chans+getChannelCount(which)>DIV_MAX_CHANS) {
|
||||
lastError=fmt::sprintf(_("max number of total channels is %d"),DIV_MAX_CHANS);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1059,7 +1066,7 @@ bool DivEngine::addSystem(DivSystem which) {
|
|||
song.systemPan[song.systemLen]=0;
|
||||
song.systemPanFR[song.systemLen]=0;
|
||||
song.systemFlags[song.systemLen++].clear();
|
||||
recalcChans();
|
||||
song.recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
initDispatch();
|
||||
|
|
@ -1101,7 +1108,7 @@ bool DivEngine::duplicateSystem(int index, bool pat, bool end) {
|
|||
lastError=fmt::sprintf(_("max number of systems is %d"),DIV_MAX_CHIPS);
|
||||
return false;
|
||||
}
|
||||
if (chans+getChannelCount(song.system[index])>DIV_MAX_CHANS) {
|
||||
if (song.chans+getChannelCount(song.system[index])>DIV_MAX_CHANS) {
|
||||
lastError=fmt::sprintf(_("max number of total channels is %d"),DIV_MAX_CHANS);
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1113,7 +1120,7 @@ bool DivEngine::duplicateSystem(int index, bool pat, bool end) {
|
|||
song.systemPan[song.systemLen]=song.systemPan[index];
|
||||
song.systemPanFR[song.systemLen]=song.systemPanFR[index];
|
||||
song.systemFlags[song.systemLen++]=song.systemFlags[index];
|
||||
recalcChans();
|
||||
song.recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
initDispatch();
|
||||
|
|
@ -1184,7 +1191,7 @@ bool DivEngine::duplicateSystem(int index, bool pat, bool end) {
|
|||
swapSystemUnsafe(i,i-1,false);
|
||||
}
|
||||
|
||||
recalcChans();
|
||||
song.recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
initDispatch();
|
||||
|
|
@ -1206,14 +1213,14 @@ bool DivEngine::removeSystem(int index, bool preserveOrder) {
|
|||
lastError=_("invalid index");
|
||||
return false;
|
||||
}
|
||||
int chanCount=chans;
|
||||
int chanCount=song.chans;
|
||||
quitDispatch();
|
||||
BUSY_BEGIN;
|
||||
saveLock.lock();
|
||||
|
||||
if (!preserveOrder) {
|
||||
int firstChan=0;
|
||||
while (dispatchOfChan[firstChan]!=index) firstChan++;
|
||||
while (song.dispatchOfChan[firstChan]!=index) firstChan++;
|
||||
for (int i=0; i<getChannelCount(song.system[index]); i++) {
|
||||
stompChannel(i+firstChan);
|
||||
}
|
||||
|
|
@ -1239,7 +1246,7 @@ bool DivEngine::removeSystem(int index, bool preserveOrder) {
|
|||
song.systemPanFR[i]=song.systemPanFR[i+1];
|
||||
song.systemFlags[i]=song.systemFlags[i+1];
|
||||
}
|
||||
recalcChans();
|
||||
song.recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
initDispatch();
|
||||
|
|
@ -1391,7 +1398,7 @@ bool DivEngine::swapSystem(int src, int dest, bool preserveOrder) {
|
|||
|
||||
swapSystemUnsafe(src,dest,preserveOrder);
|
||||
|
||||
recalcChans();
|
||||
song.recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
initDispatch();
|
||||
|
|
@ -1514,28 +1521,28 @@ void DivEngine::setLoops(int loops) {
|
|||
}
|
||||
|
||||
DivChannelState* DivEngine::getChanState(int ch) {
|
||||
if (ch<0 || ch>=chans) return NULL;
|
||||
if (ch<0 || ch>=song.chans) return NULL;
|
||||
return &chan[ch];
|
||||
}
|
||||
|
||||
unsigned short DivEngine::getChanPan(int ch) {
|
||||
if (ch<0 || ch>=chans) return 0;
|
||||
return disCont[dispatchOfChan[ch]].dispatch->getPan(dispatchChanOfChan[ch]);
|
||||
if (ch<0 || ch>=song.chans) return 0;
|
||||
return disCont[song.dispatchOfChan[ch]].dispatch->getPan(song.dispatchChanOfChan[ch]);
|
||||
}
|
||||
|
||||
void* DivEngine::getDispatchChanState(int ch) {
|
||||
if (ch<0 || ch>=chans) return NULL;
|
||||
return disCont[dispatchOfChan[ch]].dispatch->getChanState(dispatchChanOfChan[ch]);
|
||||
if (ch<0 || ch>=song.chans) return NULL;
|
||||
return disCont[song.dispatchOfChan[ch]].dispatch->getChanState(song.dispatchChanOfChan[ch]);
|
||||
}
|
||||
|
||||
void DivEngine::getChanPaired(int ch, std::vector<DivChannelPair>& ret) {
|
||||
if (ch<0 || ch>=chans) return;
|
||||
disCont[dispatchOfChan[ch]].dispatch->getPaired(dispatchChanOfChan[ch],ret);
|
||||
if (ch<0 || ch>=song.chans) return;
|
||||
disCont[song.dispatchOfChan[ch]].dispatch->getPaired(song.dispatchChanOfChan[ch],ret);
|
||||
}
|
||||
|
||||
DivChannelModeHints DivEngine::getChanModeHints(int ch) {
|
||||
if (ch<0 || ch>=chans) return DivChannelModeHints();
|
||||
return disCont[dispatchOfChan[ch]].dispatch->getModeHints(dispatchChanOfChan[ch]);
|
||||
if (ch<0 || ch>=song.chans) return DivChannelModeHints();
|
||||
return disCont[song.dispatchOfChan[ch]].dispatch->getModeHints(song.dispatchChanOfChan[ch]);
|
||||
}
|
||||
|
||||
unsigned char* DivEngine::getRegisterPool(int sys, int& size, int& depth) {
|
||||
|
|
@ -1547,18 +1554,18 @@ unsigned char* DivEngine::getRegisterPool(int sys, int& size, int& depth) {
|
|||
}
|
||||
|
||||
DivMacroInt* DivEngine::getMacroInt(int chan) {
|
||||
if (chan<0 || chan>=chans) return NULL;
|
||||
return disCont[dispatchOfChan[chan]].dispatch->getChanMacroInt(dispatchChanOfChan[chan]);
|
||||
if (chan<0 || chan>=song.chans) return NULL;
|
||||
return disCont[song.dispatchOfChan[chan]].dispatch->getChanMacroInt(song.dispatchChanOfChan[chan]);
|
||||
}
|
||||
|
||||
DivSamplePos DivEngine::getSamplePos(int chan) {
|
||||
if (chan<0 || chan>=chans) return DivSamplePos();
|
||||
return disCont[dispatchOfChan[chan]].dispatch->getSamplePos(dispatchChanOfChan[chan]);
|
||||
if (chan<0 || chan>=song.chans) return DivSamplePos();
|
||||
return disCont[song.dispatchOfChan[chan]].dispatch->getSamplePos(song.dispatchChanOfChan[chan]);
|
||||
}
|
||||
|
||||
DivDispatchOscBuffer* DivEngine::getOscBuffer(int chan) {
|
||||
if (chan<0 || chan>=chans) return NULL;
|
||||
return disCont[dispatchOfChan[chan]].dispatch->getOscBuffer(dispatchChanOfChan[chan]);
|
||||
if (chan<0 || chan>=song.chans) return NULL;
|
||||
return disCont[song.dispatchOfChan[chan]].dispatch->getOscBuffer(song.dispatchChanOfChan[chan]);
|
||||
}
|
||||
|
||||
void DivEngine::enableCommandStream(bool enable) {
|
||||
|
|
@ -1694,7 +1701,7 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
|
|||
if (goal>0 || goalRow>0) {
|
||||
for (int i=0; i<song.systemLen; i++) disCont[i].dispatch->forceIns();
|
||||
}
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
chan[i].cut=-1;
|
||||
chan[i].cutType=0;
|
||||
}
|
||||
|
|
@ -2041,7 +2048,7 @@ void DivEngine::stop() {
|
|||
}
|
||||
if (output) if (output->midiOut!=NULL) {
|
||||
output->midiOut->send(TAMidiMessage(TA_MIDI_MACHINE_STOP,0,0));
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (chan[i].curMidiNote>=0) {
|
||||
output->midiOut->send(TAMidiMessage(0x80|(i&15),chan[i].curMidiNote,0));
|
||||
}
|
||||
|
|
@ -2053,8 +2060,8 @@ void DivEngine::stop() {
|
|||
}
|
||||
|
||||
// reset all chan oscs
|
||||
for (int i=0; i<chans; i++) {
|
||||
DivDispatchOscBuffer* buf=disCont[dispatchOfChan[i]].dispatch->getOscBuffer(dispatchChanOfChan[i]);
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
DivDispatchOscBuffer* buf=disCont[song.dispatchOfChan[i]].dispatch->getOscBuffer(song.dispatchChanOfChan[i]);
|
||||
if (buf!=NULL) {
|
||||
buf->reset();
|
||||
}
|
||||
|
|
@ -2094,7 +2101,7 @@ const char** DivEngine::getRegisterSheet(int sys) {
|
|||
void DivEngine::reset() {
|
||||
if (output) if (output->midiOut!=NULL) {
|
||||
output->midiOut->send(TAMidiMessage(TA_MIDI_MACHINE_STOP,0,0));
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (chan[i].curMidiNote>=0) {
|
||||
output->midiOut->send(TAMidiMessage(0x80|(i&15),chan[i].curMidiNote,0));
|
||||
}
|
||||
|
|
@ -2102,7 +2109,7 @@ void DivEngine::reset() {
|
|||
}
|
||||
for (int i=0; i<DIV_MAX_CHANS; i++) {
|
||||
chan[i]=DivChannelState();
|
||||
if (i<chans) chan[i].volMax=(disCont[dispatchOfChan[i]].dispatch->dispatch(DivCommand(DIV_CMD_GET_VOLMAX,dispatchChanOfChan[i]))<<8)|0xff;
|
||||
if (i<song.chans) chan[i].volMax=(disCont[song.dispatchOfChan[i]].dispatch->dispatch(DivCommand(DIV_CMD_GET_VOLMAX,song.dispatchChanOfChan[i]))<<8)|0xff;
|
||||
chan[i].volume=chan[i].volMax;
|
||||
if (!song.linearPitch) chan[i].vibratoFine=4;
|
||||
}
|
||||
|
|
@ -2375,16 +2382,16 @@ int DivEngine::getMaxVolumeChan(int ch) {
|
|||
|
||||
int DivEngine::mapVelocity(int ch, float vel) {
|
||||
if (ch<0) return 0;
|
||||
if (ch>=chans) return 0;
|
||||
if (disCont[dispatchOfChan[ch]].dispatch==NULL) return 0;
|
||||
return disCont[dispatchOfChan[ch]].dispatch->mapVelocity(dispatchChanOfChan[ch],vel);
|
||||
if (ch>=song.chans) return 0;
|
||||
if (disCont[song.dispatchOfChan[ch]].dispatch==NULL) return 0;
|
||||
return disCont[song.dispatchOfChan[ch]].dispatch->mapVelocity(song.dispatchChanOfChan[ch],vel);
|
||||
}
|
||||
|
||||
float DivEngine::getGain(int ch, int vol) {
|
||||
if (ch<0) return 0;
|
||||
if (ch>=chans) return 0;
|
||||
if (disCont[dispatchOfChan[ch]].dispatch==NULL) return 0;
|
||||
return disCont[dispatchOfChan[ch]].dispatch->getGain(dispatchChanOfChan[ch],vol);
|
||||
if (ch>=song.chans) return 0;
|
||||
if (disCont[song.dispatchOfChan[ch]].dispatch==NULL) return 0;
|
||||
return disCont[song.dispatchOfChan[ch]].dispatch->getGain(song.dispatchChanOfChan[ch],vol);
|
||||
}
|
||||
|
||||
unsigned char DivEngine::getOrder() {
|
||||
|
|
@ -2494,7 +2501,7 @@ void DivEngine::toggleMute(int chan) {
|
|||
|
||||
void DivEngine::toggleSolo(int chan) {
|
||||
bool solo=false;
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (i==chan) {
|
||||
solo=true;
|
||||
continue;
|
||||
|
|
@ -2507,17 +2514,17 @@ void DivEngine::toggleSolo(int chan) {
|
|||
}
|
||||
BUSY_BEGIN;
|
||||
if (!solo) {
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
isMuted[i]=(i!=chan);
|
||||
if (disCont[dispatchOfChan[i]].dispatch!=NULL) {
|
||||
disCont[dispatchOfChan[i]].dispatch->muteChannel(dispatchChanOfChan[i],isMuted[i]);
|
||||
if (disCont[song.dispatchOfChan[i]].dispatch!=NULL) {
|
||||
disCont[song.dispatchOfChan[i]].dispatch->muteChannel(song.dispatchChanOfChan[i],isMuted[i]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
isMuted[i]=false;
|
||||
if (disCont[dispatchOfChan[i]].dispatch!=NULL) {
|
||||
disCont[dispatchOfChan[i]].dispatch->muteChannel(dispatchChanOfChan[i],isMuted[i]);
|
||||
if (disCont[song.dispatchOfChan[i]].dispatch!=NULL) {
|
||||
disCont[song.dispatchOfChan[i]].dispatch->muteChannel(song.dispatchChanOfChan[i],isMuted[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2527,18 +2534,18 @@ void DivEngine::toggleSolo(int chan) {
|
|||
void DivEngine::muteChannel(int chan, bool mute) {
|
||||
BUSY_BEGIN;
|
||||
isMuted[chan]=mute;
|
||||
if (disCont[dispatchOfChan[chan]].dispatch!=NULL) {
|
||||
disCont[dispatchOfChan[chan]].dispatch->muteChannel(dispatchChanOfChan[chan],isMuted[chan]);
|
||||
if (disCont[song.dispatchOfChan[chan]].dispatch!=NULL) {
|
||||
disCont[song.dispatchOfChan[chan]].dispatch->muteChannel(song.dispatchChanOfChan[chan],isMuted[chan]);
|
||||
}
|
||||
BUSY_END;
|
||||
}
|
||||
|
||||
void DivEngine::unmuteAll() {
|
||||
BUSY_BEGIN;
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
isMuted[i]=false;
|
||||
if (disCont[dispatchOfChan[i]].dispatch!=NULL) {
|
||||
disCont[dispatchOfChan[i]].dispatch->muteChannel(dispatchChanOfChan[i],isMuted[i]);
|
||||
if (disCont[song.dispatchOfChan[i]].dispatch!=NULL) {
|
||||
disCont[song.dispatchOfChan[i]].dispatch->muteChannel(song.dispatchChanOfChan[i],isMuted[i]);
|
||||
}
|
||||
}
|
||||
BUSY_END;
|
||||
|
|
@ -2609,8 +2616,8 @@ int DivEngine::addInstrument(int refChan, DivInstrumentType fallbackType) {
|
|||
DivInstrument* ins=new DivInstrument;
|
||||
int insCount=(int)song.ins.size();
|
||||
DivInstrumentType prefType;
|
||||
if (refChan>chans) {
|
||||
refChan=chans-1;
|
||||
if (refChan>song.chans) {
|
||||
refChan=song.chans-1;
|
||||
}
|
||||
if (refChan<0) {
|
||||
prefType=fallbackType;
|
||||
|
|
@ -2634,7 +2641,7 @@ int DivEngine::addInstrument(int refChan, DivInstrumentType fallbackType) {
|
|||
break;
|
||||
}
|
||||
if (refChan>=0) {
|
||||
if (sysOfChan[refChan]==DIV_SYSTEM_QSOUND) {
|
||||
if (song.sysOfChan[refChan]==DIV_SYSTEM_QSOUND) {
|
||||
*ins=song.nullInsQSound;
|
||||
}
|
||||
}
|
||||
|
|
@ -2694,7 +2701,7 @@ void DivEngine::delInstrumentUnsafe(int index) {
|
|||
delete song.ins[index];
|
||||
song.ins.erase(song.ins.begin()+index);
|
||||
song.insLen=song.ins.size();
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
for (size_t j=0; j<song.subsong.size(); j++) {
|
||||
for (int k=0; k<DIV_MAX_PATTERNS; k++) {
|
||||
if (song.subsong[j]->pat[i].data[k]==NULL) continue;
|
||||
|
|
@ -3004,7 +3011,7 @@ void DivEngine::addOrder(int pos, bool duplicate, bool where) {
|
|||
}
|
||||
} else {
|
||||
bool used[DIV_MAX_PATTERNS];
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
memset(used,0,sizeof(bool)*DIV_MAX_PATTERNS);
|
||||
for (int j=0; j<curSubSong->ordersLen; j++) {
|
||||
used[curOrders->ord[i][j]]=true;
|
||||
|
|
@ -3053,7 +3060,7 @@ void DivEngine::deepCloneOrder(int pos, bool where) {
|
|||
if (curSubSong->ordersLen>=(DIV_MAX_PATTERNS-1)) return;
|
||||
warnings="";
|
||||
BUSY_BEGIN_SOFT;
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
bool didNotFind=true;
|
||||
logD("channel %d",i);
|
||||
order[i]=curOrders->ord[i][pos];
|
||||
|
|
@ -3077,14 +3084,14 @@ void DivEngine::deepCloneOrder(int pos, bool where) {
|
|||
}
|
||||
if (where) { // at the end
|
||||
saveLock.lock();
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
curOrders->ord[i][curSubSong->ordersLen]=order[i];
|
||||
}
|
||||
curSubSong->ordersLen++;
|
||||
saveLock.unlock();
|
||||
} else { // after current order
|
||||
saveLock.lock();
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
for (int j=curSubSong->ordersLen; j>pos; j--) {
|
||||
curOrders->ord[i][j]=curOrders->ord[i][j-1];
|
||||
}
|
||||
|
|
@ -3182,7 +3189,7 @@ void DivEngine::moveOrderDown(int& pos) {
|
|||
}
|
||||
|
||||
void DivEngine::exchangeIns(int one, int two) {
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
for (size_t j=0; j<song.subsong.size(); j++) {
|
||||
for (int k=0; k<DIV_MAX_PATTERNS; k++) {
|
||||
if (song.subsong[j]->pat[i].data[k]==NULL) continue;
|
||||
|
|
@ -3468,7 +3475,7 @@ void DivEngine::patchDisconnectAll(unsigned int portSet) {
|
|||
}
|
||||
|
||||
void DivEngine::noteOn(int chan, int ins, int note, int vol) {
|
||||
if (chan<0 || chan>=chans) return;
|
||||
if (chan<0 || chan>=song.chans) return;
|
||||
BUSY_BEGIN;
|
||||
pendingNotes.push_back(DivNoteEvent(chan,ins,note,vol,true));
|
||||
if (!playing) {
|
||||
|
|
@ -3480,7 +3487,7 @@ void DivEngine::noteOn(int chan, int ins, int note, int vol) {
|
|||
}
|
||||
|
||||
void DivEngine::noteOff(int chan) {
|
||||
if (chan<0 || chan>=chans) return;
|
||||
if (chan<0 || chan>=song.chans) return;
|
||||
BUSY_BEGIN;
|
||||
pendingNotes.push_back(DivNoteEvent(chan,-1,-1,-1,false));
|
||||
if (!playing) {
|
||||
|
|
@ -3497,7 +3504,7 @@ int DivEngine::getViableChannel(int chan, int off, int ins) {
|
|||
|
||||
// if there isn't an instrument, just offset chan by off
|
||||
if (ins==-1) {
|
||||
return (chan+off)%chans;
|
||||
return (chan+off)%song.chans;
|
||||
}
|
||||
|
||||
bool isViable[DIV_MAX_CHANS];
|
||||
|
|
@ -3507,7 +3514,7 @@ int DivEngine::getViableChannel(int chan, int off, int ins) {
|
|||
|
||||
// this is a copy of the routine in autoNoteOn...... I am lazy
|
||||
DivInstrument* insInst=getIns(ins);
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (ins==-1 || ins>=song.insLen || getPreferInsType(i)==insInst->type || (getPreferInsType(i)==DIV_INS_NULL && finalChanType==DIV_CH_NOISE) || getPreferInsSecondType(i)==insInst->type) {
|
||||
if (insInst->type==DIV_INS_OPL) {
|
||||
if (insInst->fm.ops==2 || getChannelType(i)==DIV_CH_OP) {
|
||||
|
|
@ -3527,12 +3534,12 @@ int DivEngine::getViableChannel(int chan, int off, int ins) {
|
|||
|
||||
// screw it if none of the channels are viable
|
||||
if (!isAtLeastOneViable) {
|
||||
return (chan+off)%chans;
|
||||
return (chan+off)%song.chans;
|
||||
}
|
||||
|
||||
// now offset (confined to viable channels)
|
||||
int channelsCycled=0;
|
||||
int i=(chan+1)%chans;
|
||||
int i=(chan+1)%song.chans;
|
||||
int attempts=0;
|
||||
while (true) {
|
||||
if (isViable[i]) {
|
||||
|
|
@ -3543,7 +3550,7 @@ int DivEngine::getViableChannel(int chan, int off, int ins) {
|
|||
}
|
||||
}
|
||||
|
||||
if (++i>=chans) {
|
||||
if (++i>=song.chans) {
|
||||
i=0;
|
||||
}
|
||||
|
||||
|
|
@ -3555,7 +3562,7 @@ int DivEngine::getViableChannel(int chan, int off, int ins) {
|
|||
}
|
||||
|
||||
// fail-safe
|
||||
return (chan+off)%chans;
|
||||
return (chan+off)%song.chans;
|
||||
}
|
||||
|
||||
bool DivEngine::autoNoteOn(int ch, int ins, int note, int vol, int transpose) {
|
||||
|
|
@ -3563,7 +3570,7 @@ bool DivEngine::autoNoteOn(int ch, int ins, int note, int vol, int transpose) {
|
|||
bool canPlayAnyway=false;
|
||||
bool notInViableChannel=false;
|
||||
if (midiBaseChan<0) midiBaseChan=0;
|
||||
if (midiBaseChan>=chans) midiBaseChan=chans-1;
|
||||
if (midiBaseChan>=song.chans) midiBaseChan=song.chans-1;
|
||||
int finalChan=midiBaseChan;
|
||||
int finalChanType=getChannelType(finalChan);
|
||||
|
||||
|
|
@ -3576,7 +3583,7 @@ bool DivEngine::autoNoteOn(int ch, int ins, int note, int vol, int transpose) {
|
|||
// 1. check which channels are viable for this instrument
|
||||
DivInstrument* insInst=getIns(ins);
|
||||
if (getPreferInsType(finalChan)!=insInst->type && getPreferInsSecondType(finalChan)!=insInst->type && getPreferInsType(finalChan)!=DIV_INS_NULL) notInViableChannel=true;
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (ins==-1 || ins>=song.insLen || getPreferInsType(i)==insInst->type || (getPreferInsType(i)==DIV_INS_NULL && finalChanType==DIV_CH_NOISE) || getPreferInsSecondType(i)==insInst->type) {
|
||||
if (insInst->type==DIV_INS_OPL) {
|
||||
if (insInst->fm.ops==2 || getChannelType(i)==DIV_CH_OP) {
|
||||
|
|
@ -3604,7 +3611,7 @@ bool DivEngine::autoNoteOn(int ch, int ins, int note, int vol, int transpose) {
|
|||
pendingNotes.push_back(DivNoteEvent(finalChan,ins,note+transpose,vol,true));
|
||||
return true;
|
||||
}
|
||||
if (++finalChan>=chans) {
|
||||
if (++finalChan>=song.chans) {
|
||||
finalChan=0;
|
||||
}
|
||||
} while (finalChan!=midiBaseChan);
|
||||
|
|
@ -3615,7 +3622,7 @@ bool DivEngine::autoNoteOn(int ch, int ins, int note, int vol, int transpose) {
|
|||
if (isViable[finalChan] && (insInst->type==DIV_INS_OPL || getChannelType(finalChan)==finalChanType || notInViableChannel) && chan[finalChan].midiAge<chan[candidate].midiAge) {
|
||||
candidate=finalChan;
|
||||
}
|
||||
if (++finalChan>=chans) {
|
||||
if (++finalChan>=song.chans) {
|
||||
finalChan=0;
|
||||
}
|
||||
} while (finalChan!=midiBaseChan);
|
||||
|
|
@ -3630,8 +3637,8 @@ void DivEngine::autoNoteOff(int ch, int note, int vol) {
|
|||
if (!playing) {
|
||||
return;
|
||||
}
|
||||
//if (ch<0 || ch>=chans) return;
|
||||
for (int i=0; i<chans; i++) {
|
||||
//if (ch<0 || ch>=song.chans) return;
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (chan[i].midiNote==note) {
|
||||
pendingNotes.push_back(DivNoteEvent(i,-1,-1,-1,false));
|
||||
chan[i].midiNote=-1;
|
||||
|
|
@ -3643,7 +3650,7 @@ void DivEngine::autoNoteOffAll() {
|
|||
if (!playing) {
|
||||
return;
|
||||
}
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (chan[i].midiNote!=-1) {
|
||||
pendingNotes.push_back(DivNoteEvent(i,-1,-1,-1,false));
|
||||
chan[i].midiNote=-1;
|
||||
|
|
@ -3768,7 +3775,7 @@ bool DivEngine::switchMaster(bool full) {
|
|||
}
|
||||
|
||||
void DivEngine::setMidiBaseChan(int chan) {
|
||||
if (chan<0 || chan>=chans) chan=0;
|
||||
if (chan<0 || chan>=song.chans) chan=0;
|
||||
midiBaseChan=chan;
|
||||
}
|
||||
|
||||
|
|
@ -3912,7 +3919,7 @@ void DivEngine::initDispatch(bool isRender) {
|
|||
autoPatchbay();
|
||||
saveLock.unlock();
|
||||
}
|
||||
recalcChans();
|
||||
song.recalcChans();
|
||||
BUSY_END;
|
||||
}
|
||||
|
||||
|
|
@ -3928,7 +3935,6 @@ void DivEngine::quitDispatch() {
|
|||
midiClockDrift=0;
|
||||
midiTimeCycles=0;
|
||||
midiTimeDrift=0;
|
||||
chans=0;
|
||||
playing=false;
|
||||
curSpeed=0;
|
||||
endOfSong=false;
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ void DivExportAmigaValidation::run() {
|
|||
size_t lastTick=0;
|
||||
//bool writeLoop=false;
|
||||
int loopPos=-1;
|
||||
for (int i=0; i<e->chans; i++) {
|
||||
for (int i=0; i<e->song.chans; i++) {
|
||||
e->chan[i].wentThroughNote=false;
|
||||
e->chan[i].goneThroughNote=false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1168,6 +1168,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
ds.systemName=getSongSystemLegacyName(ds,!getConfInt("noMultiSystem",0));
|
||||
ds.initDefaultSystemChans();
|
||||
ds.recalcChans();
|
||||
|
||||
if (active) quitDispatch();
|
||||
|
|
@ -1175,6 +1176,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
|||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
hasLoadedSomething=true;
|
||||
changeSong(0);
|
||||
// always convert to normal sample mode (I have no idea how will I do export)
|
||||
convertLegacySampleMode();
|
||||
|
|
|
|||
|
|
@ -664,6 +664,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
|
|||
ds.subsong[0]->optimizePatterns();
|
||||
ds.subsong[0]->rearrangePatterns();
|
||||
|
||||
ds.initDefaultSystemChans();
|
||||
ds.recalcChans();
|
||||
|
||||
if (active) quitDispatch();
|
||||
|
|
@ -671,8 +672,8 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) {
|
|||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
hasLoadedSomething=true;
|
||||
changeSong(0);
|
||||
recalcChans();
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
if (active) {
|
||||
|
|
|
|||
|
|
@ -2802,6 +2802,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
}
|
||||
}
|
||||
|
||||
ds.initDefaultSystemChans();
|
||||
ds.recalcChans();
|
||||
|
||||
if (active) quitDispatch();
|
||||
|
|
@ -2809,6 +2810,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si
|
|||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
hasLoadedSomething=true;
|
||||
changeSong(0);
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
|
|
|
|||
|
|
@ -2136,6 +2136,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) {
|
|||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
hasLoadedSomething=true;
|
||||
changeSong(0);
|
||||
// removal of legacy sample mode
|
||||
if (song.version<239) {
|
||||
|
|
|
|||
|
|
@ -1675,6 +1675,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
ds.systemName="PC";
|
||||
|
||||
// find subsongs
|
||||
ds.initDefaultSystemChans();
|
||||
ds.recalcChans();
|
||||
ds.findSubSongs();
|
||||
|
||||
|
|
@ -1708,6 +1709,7 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
|
|||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
hasLoadedSomething=true;
|
||||
changeSong(0);
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
|
|
|
|||
|
|
@ -431,6 +431,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
ds.insLen=ds.ins.size();
|
||||
|
||||
// find subsongs
|
||||
ds.initDefaultSystemChans();
|
||||
ds.recalcChans();
|
||||
ds.findSubSongs();
|
||||
|
||||
|
|
@ -439,6 +440,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
|
|||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
hasLoadedSomething=true;
|
||||
changeSong(0);
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
|
|
|
|||
|
|
@ -1179,6 +1179,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
// find subsongs
|
||||
ds.initDefaultSystemChans();
|
||||
ds.recalcChans();
|
||||
ds.findSubSongs();
|
||||
|
||||
|
|
@ -1215,6 +1216,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
|
|||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
hasLoadedSomething=true;
|
||||
changeSong(0);
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
|
|
|
|||
|
|
@ -302,7 +302,7 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) {
|
|||
|
||||
for (int j=0; j<s->ordersLen; j++) {
|
||||
w->writeText(fmt::sprintf("%.2X |",j));
|
||||
for (int k=0; k<chans; k++) {
|
||||
for (int k=0; k<song.chans; k++) {
|
||||
w->writeText(fmt::sprintf(" %.2X",s->orders.ord[k][j]));
|
||||
}
|
||||
w->writeText("\n");
|
||||
|
|
@ -318,7 +318,7 @@ SafeWriter* DivEngine::saveText(bool separatePatterns) {
|
|||
for (int k=0; k<s->patLen; k++) {
|
||||
w->writeText(fmt::sprintf("%.2X ",k));
|
||||
|
||||
for (int l=0; l<chans; l++) {
|
||||
for (int l=0; l<song.chans; l++) {
|
||||
DivPattern* p=s->pat[l].getPattern(s->orders.ord[l][j],false);
|
||||
short note, octave;
|
||||
noteToSplitNote(p->newData[k][DIV_PAT_NOTE],note,octave);
|
||||
|
|
|
|||
|
|
@ -711,6 +711,7 @@ bool DivEngine::loadTFMv1(unsigned char* file, size_t len) {
|
|||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
hasLoadedSomething=true;
|
||||
changeSong(0);
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
|
|
@ -905,6 +906,7 @@ bool DivEngine::loadTFMv2(unsigned char* file, size_t len) {
|
|||
info.loopPos=loopPos;
|
||||
TFMParsePattern(info);
|
||||
|
||||
ds.initDefaultSystemChans();
|
||||
ds.recalcChans();
|
||||
|
||||
if (active) quitDispatch();
|
||||
|
|
@ -912,6 +914,7 @@ bool DivEngine::loadTFMv2(unsigned char* file, size_t len) {
|
|||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
hasLoadedSomething=true;
|
||||
changeSong(0);
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
|
|
|
|||
|
|
@ -1377,6 +1377,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
|
|||
}
|
||||
|
||||
// find subsongs
|
||||
ds.initDefaultSystemChans();
|
||||
ds.recalcChans();
|
||||
ds.findSubSongs();
|
||||
|
||||
|
|
@ -1385,6 +1386,7 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
|
|||
saveLock.lock();
|
||||
song.unload();
|
||||
song=ds;
|
||||
hasLoadedSomething=true;
|
||||
changeSong(0);
|
||||
saveLock.unlock();
|
||||
BUSY_END;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "engine.h"
|
||||
#include <fmt/printf.h>
|
||||
|
||||
// TODO: this function could be in DivSong instead
|
||||
bool DivEngine::convertLegacySampleMode() {
|
||||
logD("converting legacy sample mode...");
|
||||
int legacyInsInit=-1;
|
||||
|
|
@ -114,7 +115,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
};
|
||||
|
||||
for (DivSubSong* h: song.subsong) {
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
// 0: sample off
|
||||
// 1: legacy mode
|
||||
// 2: normal mode
|
||||
|
|
@ -125,11 +126,11 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
bool noteOffDisablesSampleMode=false;
|
||||
bool hasLegacyToggle=false;
|
||||
|
||||
switch (sysOfChan[i]) {
|
||||
switch (song.sysOfChan[i]) {
|
||||
case DIV_SYSTEM_NES:
|
||||
case DIV_SYSTEM_5E01:
|
||||
// NES PCM channel (on by default)
|
||||
if (dispatchChanOfChan[i]!=4) {
|
||||
if (song.dispatchChanOfChan[i]!=4) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -137,14 +138,14 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_MMC5:
|
||||
// MMC5 PCM channel
|
||||
if (dispatchChanOfChan[i]!=2) {
|
||||
if (song.dispatchChanOfChan[i]!=2) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
break;
|
||||
case DIV_SYSTEM_YM2612:
|
||||
// YM2612 DAC channel
|
||||
if (dispatchChanOfChan[i]!=5) {
|
||||
if (song.dispatchChanOfChan[i]!=5) {
|
||||
continue;
|
||||
}
|
||||
hasLegacyToggle=true;
|
||||
|
|
@ -152,7 +153,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
case DIV_SYSTEM_YM2612_EXT:
|
||||
case DIV_SYSTEM_YM2612_CSM:
|
||||
// YM2612 DAC channel
|
||||
if (dispatchChanOfChan[i]!=8) {
|
||||
if (song.dispatchChanOfChan[i]!=8) {
|
||||
continue;
|
||||
}
|
||||
hasLegacyToggle=true;
|
||||
|
|
@ -170,7 +171,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
case DIV_SYSTEM_YM2610:
|
||||
case DIV_SYSTEM_YM2610_FULL:
|
||||
// Neo Geo CD ADPCM channels
|
||||
if (dispatchChanOfChan[i]<7) {
|
||||
if (song.dispatchChanOfChan[i]<7) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -180,7 +181,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
case DIV_SYSTEM_YM2610_EXT:
|
||||
case DIV_SYSTEM_YM2610_FULL_EXT:
|
||||
// Neo Geo CD ADPCM channels
|
||||
if (dispatchChanOfChan[i]<10) {
|
||||
if (song.dispatchChanOfChan[i]<10) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -189,7 +190,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_YM2612_DUALPCM:
|
||||
// DualPCM DAC
|
||||
if (dispatchChanOfChan[i]<5) {
|
||||
if (song.dispatchChanOfChan[i]<5) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -197,7 +198,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_YM2612_DUALPCM_EXT:
|
||||
// DualPCM DAC
|
||||
if (dispatchChanOfChan[i]<8 || dispatchChanOfChan[i]>9) {
|
||||
if (song.dispatchChanOfChan[i]<8 || song.dispatchChanOfChan[i]>9) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -205,7 +206,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_YM2610_CSM:
|
||||
// Neo Geo CD ADPCM channels
|
||||
if (dispatchChanOfChan[i]<11) {
|
||||
if (song.dispatchChanOfChan[i]<11) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -214,7 +215,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_YM2610B:
|
||||
// ADPCM channels
|
||||
if (dispatchChanOfChan[i]<9) {
|
||||
if (song.dispatchChanOfChan[i]<9) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -223,7 +224,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_YM2610B_EXT:
|
||||
// ADPCM channels
|
||||
if (dispatchChanOfChan[i]<12) {
|
||||
if (song.dispatchChanOfChan[i]<12) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -232,7 +233,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_YM2610B_CSM:
|
||||
// ADPCM channels
|
||||
if (dispatchChanOfChan[i]<13) {
|
||||
if (song.dispatchChanOfChan[i]<13) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -241,7 +242,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_YM2608:
|
||||
// ADPCM channel
|
||||
if (dispatchChanOfChan[i]!=15) {
|
||||
if (song.dispatchChanOfChan[i]!=15) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -249,7 +250,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_YM2608_EXT:
|
||||
// ADPCM channel
|
||||
if (dispatchChanOfChan[i]!=18) {
|
||||
if (song.dispatchChanOfChan[i]!=18) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -257,7 +258,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_YM2608_CSM:
|
||||
// ADPCM channel
|
||||
if (dispatchChanOfChan[i]!=19) {
|
||||
if (song.dispatchChanOfChan[i]!=19) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
|
|
@ -279,21 +280,21 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_Y8950:
|
||||
// Y8950 ADPCM
|
||||
if (dispatchChanOfChan[i]!=9) {
|
||||
if (song.dispatchChanOfChan[i]!=9) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
break;
|
||||
case DIV_SYSTEM_Y8950_DRUMS:
|
||||
// Y8950 ADPCM
|
||||
if (dispatchChanOfChan[i]!=11) {
|
||||
if (song.dispatchChanOfChan[i]!=11) {
|
||||
continue;
|
||||
}
|
||||
sampleMode=1;
|
||||
break;
|
||||
case DIV_SYSTEM_SWAN:
|
||||
// PCM channel
|
||||
if (dispatchChanOfChan[i]!=1) {
|
||||
if (song.dispatchChanOfChan[i]!=1) {
|
||||
continue;
|
||||
}
|
||||
noteOffDisablesSampleMode=true;
|
||||
|
|
@ -301,7 +302,7 @@ bool DivEngine::convertLegacySampleMode() {
|
|||
break;
|
||||
case DIV_SYSTEM_VRC6:
|
||||
// pulse DAC mode
|
||||
if (dispatchChanOfChan[i]>=2) {
|
||||
if (song.dispatchChanOfChan[i]>=2) {
|
||||
continue;
|
||||
}
|
||||
hasLegacyToggle=true;
|
||||
|
|
|
|||
|
|
@ -498,16 +498,16 @@ int DivEngine::dispatchCmd(DivCommand c) {
|
|||
|
||||
// map the channel to channel of chip
|
||||
// c.dis is a copy of c.chan because we'll use it in the next call
|
||||
c.chan=dispatchChanOfChan[c.dis];
|
||||
c.chan=song.dispatchChanOfChan[c.dis];
|
||||
|
||||
// dispatch command to chip dispatch
|
||||
return disCont[dispatchOfChan[c.dis]].dispatch->dispatch(c);
|
||||
return disCont[song.dispatchOfChan[c.dis]].dispatch->dispatch(c);
|
||||
}
|
||||
|
||||
// this function handles per-chip normal effects
|
||||
bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effectVal) {
|
||||
// don't process invalid chips
|
||||
DivSysDef* sysDef=sysDefs[sysOfChan[ch]];
|
||||
DivSysDef* sysDef=sysDefs[song.sysOfChan[ch]];
|
||||
if (sysDef==NULL) return false;
|
||||
// find the effect handler
|
||||
auto iter=sysDef->effectHandlers.find(effect);
|
||||
|
|
@ -530,7 +530,7 @@ bool DivEngine::perSystemEffect(int ch, unsigned char effect, unsigned char effe
|
|||
// this handles per-chip post effects...
|
||||
bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal) {
|
||||
// don't process invalid chips
|
||||
DivSysDef* sysDef=sysDefs[sysOfChan[ch]];
|
||||
DivSysDef* sysDef=sysDefs[song.sysOfChan[ch]];
|
||||
if (sysDef==NULL) return false;
|
||||
// find the effect handler
|
||||
auto iter=sysDef->postEffectHandlers.find(effect);
|
||||
|
|
@ -552,7 +552,7 @@ bool DivEngine::perSystemPostEffect(int ch, unsigned char effect, unsigned char
|
|||
|
||||
// ...and this handles chip pre-effects
|
||||
bool DivEngine::perSystemPreEffect(int ch, unsigned char effect, unsigned char effectVal) {
|
||||
DivSysDef* sysDef=sysDefs[sysOfChan[ch]];
|
||||
DivSysDef* sysDef=sysDefs[song.sysOfChan[ch]];
|
||||
if (sysDef==NULL) return false;
|
||||
auto iter=sysDef->preEffectHandlers.find(effect);
|
||||
if (iter==sysDef->preEffectHandlers.end()) return false;
|
||||
|
|
@ -721,7 +721,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
// this hack is disabled due to its dirtiness and the fact I
|
||||
// don't feel like being compatible with a buggy tracker any further
|
||||
if (effectVal==nextSpeed) {
|
||||
//if (sysOfChan[i]!=DIV_SYSTEM_YM2610 && sysOfChan[i]!=DIV_SYSTEM_YM2610_EXT) chan[i].delayLocked=true;
|
||||
//if (song.sysOfChan[i]!=DIV_SYSTEM_YM2610 && song.sysOfChan[i]!=DIV_SYSTEM_YM2610_EXT) chan[i].delayLocked=true;
|
||||
} else {
|
||||
chan[i].delayLocked=false;
|
||||
}
|
||||
|
|
@ -784,12 +784,12 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
chan[i].stopOnOff=false;
|
||||
}
|
||||
// depending on the system, portamento may still be disabled
|
||||
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsPorta(dispatchChanOfChan[i])) {
|
||||
if (disCont[song.dispatchOfChan[i]].dispatch->keyOffAffectsPorta(song.dispatchChanOfChan[i])) {
|
||||
chan[i].portaNote=-1;
|
||||
chan[i].portaSpeed=-1;
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||
// this here is a now-disabled hack which makes the noise channel also stop when square 3 is
|
||||
/*if (i==2 && sysOfChan[i]==DIV_SYSTEM_SMS) {
|
||||
/*if (i==2 && song.sysOfChan[i]==DIV_SYSTEM_SMS) {
|
||||
chan[i+1].portaNote=-1;
|
||||
chan[i+1].portaSpeed=-1;
|
||||
}*/
|
||||
|
|
@ -812,11 +812,11 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||
chan[i].stopOnOff=false;
|
||||
}
|
||||
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsPorta(dispatchChanOfChan[i])) {
|
||||
if (disCont[song.dispatchOfChan[i]].dispatch->keyOffAffectsPorta(song.dispatchChanOfChan[i])) {
|
||||
chan[i].portaNote=-1;
|
||||
chan[i].portaSpeed=-1;
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||
/*if (i==2 && sysOfChan[i]==DIV_SYSTEM_SMS) {
|
||||
/*if (i==2 && song.sysOfChan[i]==DIV_SYSTEM_SMS) {
|
||||
chan[i+1].portaNote=-1;
|
||||
chan[i+1].portaSpeed=-1;
|
||||
}*/
|
||||
|
|
@ -839,7 +839,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
// ...unless there's a way to trigger keyOn twice
|
||||
if (!chan[i].keyOn) {
|
||||
// the behavior of arpeggio reset upon note off varies per system
|
||||
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsArp(dispatchChanOfChan[i])) {
|
||||
if (disCont[song.dispatchOfChan[i]].dispatch->keyOffAffectsArp(song.dispatchChanOfChan[i])) {
|
||||
chan[i].arp=0;
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_ARPEGGIO,i,chan[i].arp));
|
||||
}
|
||||
|
|
@ -876,7 +876,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
// COMPAT FLAG: legacy ALWAYS_SET_VOLUME behavior (oldAlwaysSetVolume)
|
||||
// - prior to its addition, volume changes wouldn't be effective depending on the system if the volume is the same as the current one
|
||||
// - afterwards, volume change is made regardless in order to set the bottom byte of volume ("subvolume")
|
||||
if (!song.oldAlwaysSetVolume || disCont[dispatchOfChan[i]].dispatch->getLegacyAlwaysSetVolume() || (MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->newData[whatRow][DIV_PAT_VOL]) {
|
||||
if (!song.oldAlwaysSetVolume || disCont[song.dispatchOfChan[i]].dispatch->getLegacyAlwaysSetVolume() || (MIN(chan[i].volMax,chan[i].volume)>>8)!=pat->newData[whatRow][DIV_PAT_VOL]) {
|
||||
// here we let dispatchCmd() know we can do MIDI aftertouch if there isn't a note
|
||||
if (pat->newData[whatRow][DIV_PAT_NOTE]==-1) {
|
||||
chan[i].midiAftertouch=true;
|
||||
|
|
@ -1039,7 +1039,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
// COMPAT FLAG: limit slide range
|
||||
// - this confines pitch slides from dispatch->getPortaFloor to C-8 (I think)
|
||||
// - yep, the lowest portamento note depends on the system...
|
||||
chan[i].portaNote=song.limitSlides?disCont[dispatchOfChan[i]].dispatch->getPortaFloor(dispatchChanOfChan[i]):-60;
|
||||
chan[i].portaNote=song.limitSlides?disCont[song.dispatchOfChan[i]].dispatch->getPortaFloor(song.dispatchChanOfChan[i]):-60;
|
||||
chan[i].portaSpeed=effectVal;
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||
chan[i].portaStop=true;
|
||||
|
|
@ -1684,7 +1684,7 @@ void DivEngine::processRow(int i, bool afterDelay) {
|
|||
chan[i].portaNote=song.limitSlides?0x60:255;
|
||||
} else {
|
||||
// COMPAT FLAG: limit slide range
|
||||
chan[i].portaNote=song.limitSlides?disCont[dispatchOfChan[i]].dispatch->getPortaFloor(dispatchChanOfChan[i]):-60;
|
||||
chan[i].portaNote=song.limitSlides?disCont[song.dispatchOfChan[i]].dispatch->getPortaFloor(song.dispatchChanOfChan[i]):-60;
|
||||
}
|
||||
chan[i].portaSpeed=effectVal;
|
||||
chan[i].portaStop=true;
|
||||
|
|
@ -1726,7 +1726,7 @@ void DivEngine::nextRow() {
|
|||
if (view==DIV_STATUS_PATTERN && !skipping) {
|
||||
strcpy(pb1,"");
|
||||
strcpy(pb3,"");
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
// orders
|
||||
snprintf(pb,4095," %.2x",curOrders->ord[i][curOrder]);
|
||||
strcat(pb1,pb);
|
||||
|
|
@ -1792,13 +1792,13 @@ void DivEngine::nextRow() {
|
|||
}
|
||||
|
||||
// process row pre on all channels
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
// try to find pre effects
|
||||
processRowPre(i);
|
||||
}
|
||||
|
||||
// process row on all channels
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
// COMPAT FLAG: cut/delay effect policy (delayBehavior)
|
||||
// - if not lax, reset the row delay timer so it never happens
|
||||
if (song.delayBehavior!=2) {
|
||||
|
|
@ -1895,7 +1895,7 @@ void DivEngine::nextRow() {
|
|||
|
||||
// post row details
|
||||
// schedule pre-notes and delays (for C64 and/or a compat flag)
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
DivPattern* pat=curPat[i].getPattern(curOrders->ord[i][curOrder],false);
|
||||
if (pat->newData[curRow][DIV_PAT_NOTE]!=-1) {
|
||||
// if there is a note
|
||||
|
|
@ -1904,8 +1904,8 @@ void DivEngine::nextRow() {
|
|||
if (!chan[i].legato) {
|
||||
// check whether we should fire a pre-note event
|
||||
bool wantPreNote=false;
|
||||
if (disCont[dispatchOfChan[i]].dispatch!=NULL) {
|
||||
wantPreNote=disCont[dispatchOfChan[i]].dispatch->getWantPreNote();
|
||||
if (disCont[song.dispatchOfChan[i]].dispatch!=NULL) {
|
||||
wantPreNote=disCont[song.dispatchOfChan[i]].dispatch->getWantPreNote();
|
||||
if (wantPreNote) {
|
||||
bool doPreparePreNote=true;
|
||||
int addition=0;
|
||||
|
|
@ -2039,7 +2039,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
// this is a check that nullifies any note off event that right after a note on
|
||||
// it prevents a situation where some notes do not play
|
||||
for (int i=pendingNotes.size()-1; i>=0; i--) {
|
||||
if (pendingNotes[i].channel<0 || pendingNotes[i].channel>=chans) continue;
|
||||
if (pendingNotes[i].channel<0 || pendingNotes[i].channel>=song.chans) continue;
|
||||
if (pendingNotes[i].on) {
|
||||
isOn[pendingNotes[i].channel]=true;
|
||||
} else {
|
||||
|
|
@ -2058,7 +2058,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
// fetch event
|
||||
DivNoteEvent& note=pendingNotes.front();
|
||||
// don't if channel is out of bounds or event is canceled
|
||||
if (note.nop || note.channel<0 || note.channel>=chans) {
|
||||
if (note.nop || note.channel<0 || note.channel>=song.chans) {
|
||||
pendingNotes.pop_front();
|
||||
continue;
|
||||
}
|
||||
|
|
@ -2077,10 +2077,10 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
}
|
||||
// set volume as long as there's one associated with the event
|
||||
// and the chip has per-channel volume
|
||||
if (note.volume>=0 && !disCont[dispatchOfChan[note.channel]].dispatch->isVolGlobal()) {
|
||||
if (note.volume>=0 && !disCont[song.dispatchOfChan[note.channel]].dispatch->isVolGlobal()) {
|
||||
// map velocity to curve and then to equivalent chip volume
|
||||
float curvedVol=pow((float)note.volume/127.0f,midiVolExp);
|
||||
int mappedVol=disCont[dispatchOfChan[note.channel]].dispatch->mapVelocity(dispatchChanOfChan[note.channel],curvedVol);
|
||||
int mappedVol=disCont[song.dispatchOfChan[note.channel]].dispatch->mapVelocity(song.dispatchChanOfChan[note.channel],curvedVol);
|
||||
// fire command
|
||||
dispatchCmd(DivCommand(DIV_CMD_VOLUME,note.channel,mappedVol));
|
||||
}
|
||||
|
|
@ -2094,11 +2094,11 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
chan[note.channel].lastIns=note.ins;
|
||||
} else {
|
||||
// note off
|
||||
DivMacroInt* macroInt=disCont[dispatchOfChan[note.channel]].dispatch->getChanMacroInt(dispatchChanOfChan[note.channel]);
|
||||
DivMacroInt* macroInt=disCont[song.dispatchOfChan[note.channel]].dispatch->getChanMacroInt(song.dispatchChanOfChan[note.channel]);
|
||||
if (macroInt!=NULL) {
|
||||
// if the current instrument has a release point in any macros and
|
||||
// volume is per-channel, send a note release instead of a note off
|
||||
if (macroInt->hasRelease && !disCont[dispatchOfChan[note.channel]].dispatch->isVolGlobal()) {
|
||||
if (macroInt->hasRelease && !disCont[song.dispatchOfChan[note.channel]].dispatch->isVolGlobal()) {
|
||||
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF_ENV,note.channel));
|
||||
} else {
|
||||
dispatchCmd(DivCommand(DIV_CMD_NOTE_OFF,note.channel));
|
||||
|
|
@ -2123,7 +2123,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
// delayed row's state before it has a chance to do anything. a typical example would be
|
||||
// a delay scheduling a note-on to be simultaneous with the next row, and the next row also
|
||||
// containing a delayed note. if we don't apply the delayed row first, the world explodes.
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
// delay effects
|
||||
if (chan[i].rowDelay>0) {
|
||||
if (--chan[i].rowDelay==0) {
|
||||
|
|
@ -2189,7 +2189,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
}
|
||||
|
||||
// process stuff such as effects
|
||||
if (!shallStop) for (int i=0; i<chans; i++) {
|
||||
if (!shallStop) for (int i=0; i<song.chans; i++) {
|
||||
// retrigger
|
||||
if (chan[i].retrigSpeed) {
|
||||
if (--chan[i].retrigTick<0) {
|
||||
|
|
@ -2463,7 +2463,7 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
chan[i].stopOnOff=false;
|
||||
}
|
||||
// depending on the system, portamento may still be disabled
|
||||
if (disCont[dispatchOfChan[i]].dispatch->keyOffAffectsPorta(dispatchChanOfChan[i])) {
|
||||
if (disCont[song.dispatchOfChan[i]].dispatch->keyOffAffectsPorta(song.dispatchChanOfChan[i])) {
|
||||
chan[i].portaNote=-1;
|
||||
chan[i].portaSpeed=-1;
|
||||
dispatchCmd(DivCommand(DIV_CMD_HINT_PORTA,i,CLAMP(chan[i].portaNote,-128,127),MAX(chan[i].portaSpeed,0)));
|
||||
|
|
@ -2564,8 +2564,8 @@ bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
|
|||
shallStop=false;
|
||||
shallStopSched=false;
|
||||
// reset all chan oscs
|
||||
for (int i=0; i<chans; i++) {
|
||||
DivDispatchOscBuffer* buf=disCont[dispatchOfChan[i]].dispatch->getOscBuffer(dispatchChanOfChan[i]);
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
DivDispatchOscBuffer* buf=disCont[song.dispatchOfChan[i]].dispatch->getOscBuffer(song.dispatchChanOfChan[i]);
|
||||
if (buf!=NULL) {
|
||||
buf->reset();
|
||||
}
|
||||
|
|
@ -2858,7 +2858,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
|||
case TA_MIDI_NOTE_OFF: {
|
||||
if (midiIsDirect) {
|
||||
// in direct mode, map the event directly to the channel
|
||||
if (chan<0 || chan>=chans) break;
|
||||
if (chan<0 || chan>=song.chans) break;
|
||||
pendingNotes.push_back(DivNoteEvent(chan,-1,-1,-1,false,false,true));
|
||||
} else {
|
||||
// find a suitable channel and add this event to the queue
|
||||
|
|
@ -2877,7 +2877,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
|||
if (msg.data[1]==0) {
|
||||
if (midiIsDirect) {
|
||||
// in direct mode, map the event directly to the channel
|
||||
if (chan<0 || chan>=chans) break;
|
||||
if (chan<0 || chan>=song.chans) break;
|
||||
pendingNotes.push_back(DivNoteEvent(chan,-1,-1,-1,false,false,true));
|
||||
} else {
|
||||
// find a suitable channel and add this event to the queue
|
||||
|
|
@ -2886,7 +2886,7 @@ void DivEngine::nextBuf(float** in, float** out, int inChans, int outChans, unsi
|
|||
} else {
|
||||
if (midiIsDirect) {
|
||||
// in direct mode, map the event directly to the channel
|
||||
if (chan<0 || chan>=chans) break;
|
||||
if (chan<0 || chan>=song.chans) break;
|
||||
pendingNotes.push_back(DivNoteEvent(chan,ins,msg.data[0]-12,msg.data[1],true,false,true));
|
||||
} else {
|
||||
// find a suitable channel and add this event to the queue
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "song.h"
|
||||
#include "engine.h"
|
||||
#include "../ta-log.h"
|
||||
#include <inttypes.h>
|
||||
#include <chrono>
|
||||
|
|
@ -691,7 +691,20 @@ void DivSong::findSubSongs() {
|
|||
}
|
||||
}
|
||||
|
||||
void DivSong::initDefaultSystemChans() {
|
||||
for (int i=0; i<systemLen; i++) {
|
||||
const DivSysDef* sysDef=DivEngine::getSystemDef(system[i]);
|
||||
if (sysDef==NULL) {
|
||||
systemChans[i]=0;
|
||||
} else {
|
||||
systemChans[i]=sysDef->channels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DivSong::recalcChans() {
|
||||
logV("DivSong: recalcChans() called");
|
||||
|
||||
bool isInsTypePossible[DIV_INS_MAX];
|
||||
chans=0;
|
||||
int chanIndex=0;
|
||||
|
|
@ -707,7 +720,7 @@ void DivSong::recalcChans() {
|
|||
dispatchFirstChan[chanIndex]=firstChan;
|
||||
chanIndex++;
|
||||
|
||||
DivSysDef* sysDef=DivEngine::getSystemDef(system[i]);
|
||||
const DivSysDef* sysDef=DivEngine::getSystemDef(system[i]);
|
||||
if (sysDef!=NULL) {
|
||||
if (sysDef->chanInsType[j][0]!=DIV_INS_NULL) {
|
||||
isInsTypePossible[sysDef->chanInsType[j][0]]=true;
|
||||
|
|
@ -729,10 +742,9 @@ void DivSong::recalcChans() {
|
|||
checkAssetDir(waveDir,wave.size());
|
||||
checkAssetDir(sampleDir,sample.size());
|
||||
|
||||
hasLoadedSomething=true;
|
||||
logV("%d channels (%d chips)",chans,systemLen);
|
||||
}
|
||||
|
||||
|
||||
void DivSong::clearSongData() {
|
||||
for (DivSubSong* i: subsong) {
|
||||
i->clearData();
|
||||
|
|
|
|||
|
|
@ -429,9 +429,15 @@ struct DivSong {
|
|||
*/
|
||||
void clearSamples();
|
||||
|
||||
/**
|
||||
* set systemChans[] to default values.
|
||||
* call recalcChans() afterwards.
|
||||
*/
|
||||
void initDefaultSystemChans();
|
||||
|
||||
/**
|
||||
* recalculate channel count and internal state.
|
||||
" call after editing system[] or systemChans[].
|
||||
* call after editing system[] or systemChans[].
|
||||
*/
|
||||
void recalcChans();
|
||||
|
||||
|
|
@ -538,6 +544,8 @@ struct DivSong {
|
|||
subsong.push_back(new DivSubSong);
|
||||
system[0]=DIV_SYSTEM_YM2612;
|
||||
system[1]=DIV_SYSTEM_SMS;
|
||||
systemChans[0]=6;
|
||||
systemChans[1]=4;
|
||||
|
||||
// OPLL default instrument contest winner - piano_guitar_idk by Weeppiko
|
||||
nullInsOPLL.type=DIV_INS_OPLL;
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@ int DivEngine::getChannelCount(DivSystem sys) {
|
|||
}
|
||||
|
||||
int DivEngine::getTotalChannelCount() {
|
||||
return chans;
|
||||
return song.chans;
|
||||
}
|
||||
|
||||
std::vector<DivInstrumentType>& DivEngine::getPossibleInsTypes() {
|
||||
return possibleInsTypes;
|
||||
return song.possibleInsTypes;
|
||||
}
|
||||
|
||||
// for pre-dev103 modules
|
||||
|
|
@ -311,41 +311,41 @@ bool DivEngine::isSTDSystem(DivSystem sys) {
|
|||
}
|
||||
|
||||
const char* DivEngine::getChannelName(int chan) {
|
||||
if (chan<0 || chan>chans) return "??";
|
||||
if (chan<0 || chan>song.chans) return "??";
|
||||
if (!curSubSong->chanName[chan].empty()) return curSubSong->chanName[chan].c_str();
|
||||
if (sysDefs[sysOfChan[chan]]==NULL) return "??";
|
||||
if (sysDefs[song.sysOfChan[chan]]==NULL) return "??";
|
||||
|
||||
const char* ret=sysDefs[sysOfChan[chan]]->chanNames[dispatchChanOfChan[chan]];
|
||||
const char* ret=sysDefs[song.sysOfChan[chan]]->chanNames[song.dispatchChanOfChan[chan]];
|
||||
if (ret==NULL) return "??";
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char* DivEngine::getChannelShortName(int chan) {
|
||||
if (chan<0 || chan>chans) return "??";
|
||||
if (chan<0 || chan>song.chans) return "??";
|
||||
if (!curSubSong->chanShortName[chan].empty()) return curSubSong->chanShortName[chan].c_str();
|
||||
if (sysDefs[sysOfChan[chan]]==NULL) return "??";
|
||||
if (sysDefs[song.sysOfChan[chan]]==NULL) return "??";
|
||||
|
||||
const char* ret=sysDefs[sysOfChan[chan]]->chanShortNames[dispatchChanOfChan[chan]];
|
||||
const char* ret=sysDefs[song.sysOfChan[chan]]->chanShortNames[song.dispatchChanOfChan[chan]];
|
||||
if (ret==NULL) return "??";
|
||||
return ret;
|
||||
}
|
||||
|
||||
int DivEngine::getChannelType(int chan) {
|
||||
if (chan<0 || chan>chans) return DIV_CH_NOISE;
|
||||
if (sysDefs[sysOfChan[chan]]==NULL) return DIV_CH_NOISE;
|
||||
return sysDefs[sysOfChan[chan]]->chanTypes[dispatchChanOfChan[chan]];
|
||||
if (chan<0 || chan>song.chans) return DIV_CH_NOISE;
|
||||
if (sysDefs[song.sysOfChan[chan]]==NULL) return DIV_CH_NOISE;
|
||||
return sysDefs[song.sysOfChan[chan]]->chanTypes[song.dispatchChanOfChan[chan]];
|
||||
}
|
||||
|
||||
DivInstrumentType DivEngine::getPreferInsType(int chan) {
|
||||
if (chan<0 || chan>chans) return DIV_INS_STD;
|
||||
if (sysDefs[sysOfChan[chan]]==NULL) return DIV_INS_STD;
|
||||
return sysDefs[sysOfChan[chan]]->chanInsType[dispatchChanOfChan[chan]][0];
|
||||
if (chan<0 || chan>song.chans) return DIV_INS_STD;
|
||||
if (sysDefs[song.sysOfChan[chan]]==NULL) return DIV_INS_STD;
|
||||
return sysDefs[song.sysOfChan[chan]]->chanInsType[song.dispatchChanOfChan[chan]][0];
|
||||
}
|
||||
|
||||
DivInstrumentType DivEngine::getPreferInsSecondType(int chan) {
|
||||
if (chan<0 || chan>chans) return DIV_INS_NULL;
|
||||
if (sysDefs[sysOfChan[chan]]==NULL) return DIV_INS_NULL;
|
||||
return sysDefs[sysOfChan[chan]]->chanInsType[dispatchChanOfChan[chan]][1];
|
||||
if (chan<0 || chan>song.chans) return DIV_INS_NULL;
|
||||
if (sysDefs[song.sysOfChan[chan]]==NULL) return DIV_INS_NULL;
|
||||
return sysDefs[song.sysOfChan[chan]]->chanInsType[song.dispatchChanOfChan[chan]][1];
|
||||
}
|
||||
|
||||
int DivEngine::minVGMVersion(DivSystem which) {
|
||||
|
|
|
|||
|
|
@ -2689,8 +2689,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
bool alreadyWroteLoop=false;
|
||||
int ord=-1;
|
||||
int exportChans=0;
|
||||
for (int i=0; i<chans; i++) {
|
||||
if (!willExport[dispatchOfChan[i]]) continue;
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (!willExport[song.dispatchOfChan[i]]) continue;
|
||||
exportChans++;
|
||||
chan[i].wentThroughNote=false;
|
||||
chan[i].goneThroughNote=false;
|
||||
|
|
@ -2710,8 +2710,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
if (trailing) beenOneLoopAlready=true;
|
||||
trailing=true;
|
||||
if (!loop) countDown=0;
|
||||
for (int i=0; i<chans; i++) {
|
||||
if (!willExport[dispatchOfChan[i]]) continue;
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (!willExport[song.dispatchOfChan[i]]) continue;
|
||||
chan[i].wentThroughNote=false;
|
||||
}
|
||||
}
|
||||
|
|
@ -2719,8 +2719,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
switch (trailingTicks) {
|
||||
case -1: { // automatic
|
||||
bool stillHaveTo=false;
|
||||
for (int i=0; i<chans; i++) {
|
||||
if (!willExport[dispatchOfChan[i]]) continue;
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (!willExport[song.dispatchOfChan[i]]) continue;
|
||||
if (!chan[i].goneThroughNote) continue;
|
||||
if (!chan[i].wentThroughNote) {
|
||||
stillHaveTo=true;
|
||||
|
|
@ -2777,8 +2777,8 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
|
|||
w->writeC(0x01);
|
||||
w->writeC(prevOrder);
|
||||
w->writeC(prevRow);
|
||||
for (int i=0; i<chans; i++) {
|
||||
if (!willExport[dispatchOfChan[i]]) continue;
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (!willExport[song.dispatchOfChan[i]]) continue;
|
||||
w->writeC(curSubSong->orders.ord[i][prevOrder]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ void DivEngine::getTotalAudioFiles(int &files) {
|
|||
break;
|
||||
}
|
||||
case DIV_EXPORT_MODE_MANY_CHAN: {
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (!exportChannelMask[i]) continue;
|
||||
|
||||
files++;
|
||||
|
|
@ -71,7 +71,7 @@ void DivEngine::getTotalAudioFiles(int &files) {
|
|||
if (getChannelType(i)==5) {
|
||||
i++;
|
||||
while (true) {
|
||||
if (i>=chans) break;
|
||||
if (i>=song.chans) break;
|
||||
if (getChannelType(i)!=5) break;
|
||||
i++;
|
||||
}
|
||||
|
|
@ -425,7 +425,7 @@ void DivEngine::runExportThread() {
|
|||
|
||||
logI("rendering to files...");
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (!exportChannelMask[i]) continue;
|
||||
|
||||
SNDFILE* sf;
|
||||
|
|
@ -476,19 +476,19 @@ void DivEngine::runExportThread() {
|
|||
|
||||
MAP_BITRATE;
|
||||
|
||||
for (int j=0; j<chans; j++) {
|
||||
for (int j=0; j<song.chans; j++) {
|
||||
bool mute=(j!=i);
|
||||
isMuted[j]=mute;
|
||||
}
|
||||
if (getChannelType(i)==5) {
|
||||
for (int j=i; j<chans; j++) {
|
||||
for (int j=i; j<song.chans; j++) {
|
||||
if (getChannelType(j)!=5) break;
|
||||
isMuted[j]=false;
|
||||
}
|
||||
}
|
||||
for (int j=0; j<chans; j++) {
|
||||
if (disCont[dispatchOfChan[j]].dispatch!=NULL) {
|
||||
disCont[dispatchOfChan[j]].dispatch->muteChannel(dispatchChanOfChan[j],isMuted[j]);
|
||||
for (int j=0; j<song.chans; j++) {
|
||||
if (disCont[song.dispatchOfChan[j]].dispatch!=NULL) {
|
||||
disCont[song.dispatchOfChan[j]].dispatch->muteChannel(song.dispatchChanOfChan[j],isMuted[j]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -549,7 +549,7 @@ void DivEngine::runExportThread() {
|
|||
if (getChannelType(i)==5) {
|
||||
i++;
|
||||
while (true) {
|
||||
if (i>=chans) break;
|
||||
if (i>=song.chans) break;
|
||||
if (getChannelType(i)!=5) break;
|
||||
i++;
|
||||
}
|
||||
|
|
@ -564,10 +564,10 @@ void DivEngine::runExportThread() {
|
|||
delete[] outBuf[i];
|
||||
}
|
||||
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
isMuted[i]=false;
|
||||
if (disCont[dispatchOfChan[i]].dispatch!=NULL) {
|
||||
disCont[dispatchOfChan[i]].dispatch->muteChannel(dispatchChanOfChan[i],false);
|
||||
if (disCont[song.dispatchOfChan[i]].dispatch!=NULL) {
|
||||
disCont[song.dispatchOfChan[i]].dispatch->muteChannel(song.dispatchChanOfChan[i],false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -642,7 +642,7 @@ bool DivEngine::saveAudio(const char* path, DivAudioExportOptions options) {
|
|||
quitDispatch();
|
||||
initDispatch(true);
|
||||
renderSamplesP();
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (isMutedBefore[i]) {
|
||||
muteChannel(i,true);
|
||||
}
|
||||
|
|
@ -680,7 +680,7 @@ void DivEngine::finishAudioFile() {
|
|||
quitDispatch();
|
||||
initDispatch(false);
|
||||
renderSamplesP();
|
||||
for (int i=0; i<chans; i++) {
|
||||
for (int i=0; i<song.chans; i++) {
|
||||
if (isMutedBefore[i]) {
|
||||
muteChannel(i,true);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -868,15 +868,15 @@ void FurnaceGUI::drawChanOsc() {
|
|||
break;
|
||||
}
|
||||
case 's': {
|
||||
text+=e->getSystemName(e->sysOfChan[ch]);
|
||||
text+=e->getSystemName(e->song.sysOfChan[ch]);
|
||||
break;
|
||||
}
|
||||
case 'p': {
|
||||
text+=FurnaceGUI::getSystemPartNumber(e->sysOfChan[ch],e->song.systemFlags[e->dispatchOfChan[ch]]);
|
||||
text+=FurnaceGUI::getSystemPartNumber(e->song.sysOfChan[ch],e->song.systemFlags[e->song.dispatchOfChan[ch]]);
|
||||
break;
|
||||
}
|
||||
case 'S': {
|
||||
text+=fmt::sprintf("%d",e->dispatchOfChan[ch]);
|
||||
text+=fmt::sprintf("%d",e->song.dispatchOfChan[ch]);
|
||||
break;
|
||||
}
|
||||
case 'v': {
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ void FurnaceGUI::drawChannels() {
|
|||
ImGui::Button(ICON_FA_ARROWS "##ChanDrag");
|
||||
ImGui::EndDragDropSource();
|
||||
} else if (ImGui::IsItemHovered()) {
|
||||
ImGui::SetTooltip(_("%s #%d\n(drag to swap channels)\n(Shift-drag to copy channel contents)"),e->getSystemName(e->sysOfChan[i]),e->dispatchChanOfChan[i]);
|
||||
ImGui::SetTooltip(_("%s #%d\n(drag to swap channels)\n(Shift-drag to copy channel contents)"),e->getSystemName(e->song.sysOfChan[i]),e->song.dispatchChanOfChan[i]);
|
||||
}
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
const ImGuiPayload* dragItem=ImGui::AcceptDragDropPayload("FUR_CHAN");
|
||||
|
|
|
|||
|
|
@ -118,11 +118,11 @@ void FurnaceGUI::drawDebug() {
|
|||
ImGui::Columns(e->getTotalChannelCount());
|
||||
for (int i=0; i<e->getTotalChannelCount(); i++) {
|
||||
void* ch=e->getDispatchChanState(i);
|
||||
ImGui::TextColored(uiColors[GUI_COLOR_ACCENT_PRIMARY],"Ch. %d: %d, %d",i,e->dispatchOfChan[i],e->dispatchChanOfChan[i]);
|
||||
ImGui::TextColored(uiColors[GUI_COLOR_ACCENT_PRIMARY],"Ch. %d: %d, %d",i,e->song.dispatchOfChan[i],e->song.dispatchChanOfChan[i]);
|
||||
if (ch==NULL) {
|
||||
ImGui::Text("NULL");
|
||||
} else {
|
||||
putDispatchChan(ch,e->dispatchChanOfChan[i],e->sysOfChan[i]);
|
||||
putDispatchChan(ch,e->song.dispatchChanOfChan[i],e->song.sysOfChan[i]);
|
||||
}
|
||||
ImGui::NextColumn();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ void FurnaceGUI::drawEffectList() {
|
|||
float availB=ImGui::GetContentRegionAvail().x-ImGui::GetFrameHeightWithSpacing();
|
||||
if (availB>0) {
|
||||
ImGui::PushTextWrapPos(availB);
|
||||
ImGui::TextWrapped(_("Chip at cursor: %s"),e->getSystemName(e->sysOfChan[cursor.xCoarse]));
|
||||
ImGui::TextWrapped(_("Chip at cursor: %s"),e->getSystemName(e->song.sysOfChan[cursor.xCoarse]));
|
||||
ImGui::PopTextWrapPos();
|
||||
}
|
||||
effectSearch.Draw(_("Search"));
|
||||
|
|
@ -55,7 +55,7 @@ void FurnaceGUI::drawEffectList() {
|
|||
}
|
||||
prevName=name;
|
||||
if (fxColors[i]==GUI_COLOR_PATTERN_EFFECT_PANNING) {
|
||||
DivDispatch* dispatch=e->getDispatch(e->dispatchOfChan[cursor.xCoarse]);
|
||||
DivDispatch* dispatch=e->getDispatch(e->song.dispatchOfChan[cursor.xCoarse]);
|
||||
if (dispatch!=NULL) {
|
||||
int outputs=dispatch->getOutputCount();
|
||||
if (outputs<2) {
|
||||
|
|
|
|||
|
|
@ -1458,7 +1458,7 @@ void FurnaceGUI::drawPattern() {
|
|||
|
||||
for (int j=0; j<8; j++) {
|
||||
if (pair.pairs[j]==-1) continue;
|
||||
int pairCh=e->dispatchFirstChan[i]+pair.pairs[j];
|
||||
int pairCh=e->song.dispatchFirstChan[i]+pair.pairs[j];
|
||||
if (!e->curSubSong->chanShow[pairCh]) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1514,7 +1514,7 @@ void FurnaceGUI::drawPattern() {
|
|||
|
||||
for (int j=0; j<8; j++) {
|
||||
if (pair.pairs[j]==-1) continue;
|
||||
int pairCh=e->dispatchFirstChan[i]+pair.pairs[j];
|
||||
int pairCh=e->song.dispatchFirstChan[i]+pair.pairs[j];
|
||||
if (!e->curSubSong->chanShow[pairCh]) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,8 +32,8 @@ int logLevel=LOGLEVEL_TRACE;
|
|||
int logLevel=LOGLEVEL_TRACE; // until done
|
||||
#endif
|
||||
|
||||
FILE* logOut;
|
||||
FILE* logFile;
|
||||
FILE* logOut=NULL;
|
||||
FILE* logFile=NULL;
|
||||
char* logFileBuf;
|
||||
char* logFileWriteBuf;
|
||||
unsigned int logFilePosI;
|
||||
|
|
@ -140,6 +140,7 @@ int writeLog(int level, const char* msg, fmt::printf_args args) {
|
|||
}
|
||||
|
||||
if (logLevel<level) return 0;
|
||||
if (logOut==NULL) return -1;
|
||||
switch (level) {
|
||||
case LOGLEVEL_ERROR:
|
||||
return fmt::fprintf(logOut,"\x1b[1;31m[ERROR]\x1b[m %s\n",logEntries[pos].text);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue