diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 81bf1aee7..5c552290a 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2091,46 +2091,6 @@ const char** DivEngine::getRegisterSheet(int sys) { return disCont[sys].dispatch->getRegisterSheet(); } -void DivEngine::recalcChans() { - bool isInsTypePossible[DIV_INS_MAX]; - chans=0; - int chanIndex=0; - memset(isInsTypePossible,0,DIV_INS_MAX*sizeof(bool)); - for (int i=0; ichanInsType[j][0]!=DIV_INS_NULL) { - isInsTypePossible[sysDefs[song.system[i]]->chanInsType[j][0]]=true; - } - - if (sysDefs[song.system[i]]->chanInsType[j][1]!=DIV_INS_NULL) { - isInsTypePossible[sysDefs[song.system[i]]->chanInsType[j][1]]=true; - } - } - } - } - - possibleInsTypes.clear(); - for (int i=0; imidiOut!=NULL) { output->midiOut->send(TAMidiMessage(TA_MIDI_MACHINE_STOP,0,0)); diff --git a/src/engine/engine.h b/src/engine/engine.h index 1c7d989eb..6b5611eb0 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -463,7 +463,6 @@ class DivEngine { TAAudioDesc want, got; String exportPath; std::thread* exportThread; - int chans; bool configLoaded; bool active; bool lowQuality; @@ -546,7 +545,6 @@ class DivEngine { std::vector midiIns; std::vector midiOuts; std::vector cmdStream; - std::vector possibleInsTypes; std::vector effectInst; std::vector curChanMask; static DivSysDef* sysDefs[DIV_MAX_CHIP_DEFS]; @@ -625,7 +623,6 @@ class DivEngine { bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal); bool perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal); bool perSystemPreEffect(int ch, unsigned char effect, unsigned char effectVal); - void recalcChans(); void reset(); void playSub(bool preserveDrift, int goalRow=0); void runMidiClock(int totalCycles=1); @@ -716,10 +713,6 @@ class DivEngine { DivChannelData* curPat; DivSubSong* curSubSong; DivInstrument* tempIns; - DivSystem sysOfChan[DIV_MAX_CHANS]; - int dispatchOfChan[DIV_MAX_CHANS]; - int dispatchChanOfChan[DIV_MAX_CHANS]; - int dispatchFirstChan[DIV_MAX_CHANS]; bool keyHit[DIV_MAX_CHANS]; float* oscBuf[DIV_MAX_OUTPUTS]; float oscSize; @@ -953,7 +946,7 @@ class DivEngine { const char* getSystemNameJ(DivSystem sys); // get sys definition - const DivSysDef* getSystemDef(DivSystem sys); + static const DivSysDef* getSystemDef(DivSystem sys); // get ROM export definition const DivROMExportDef* getROMExportDef(DivROMExportOptions opt); @@ -1456,7 +1449,6 @@ class DivEngine { DivEngine(): output(NULL), exportThread(NULL), - chans(0), configLoaded(false), active(false), lowQuality(false), @@ -1591,10 +1583,6 @@ class DivEngine { mu5ROM(NULL) { memset(isMuted,0,DIV_MAX_CHANS*sizeof(bool)); memset(keyHit,0,DIV_MAX_CHANS*sizeof(bool)); - memset(dispatchFirstChan,0,DIV_MAX_CHANS*sizeof(int)); - memset(dispatchChanOfChan,0,DIV_MAX_CHANS*sizeof(int)); - memset(dispatchOfChan,0,DIV_MAX_CHANS*sizeof(int)); - memset(sysOfChan,0,DIV_MAX_CHANS*sizeof(int)); memset(vibTable,0,64*sizeof(short)); memset(tremTable,0,128*sizeof(short)); memset(effectSlotMap,-1,4096*sizeof(short)); diff --git a/src/engine/fileOps/dmf.cpp b/src/engine/fileOps/dmf.cpp index dd4f93281..492f0c21f 100644 --- a/src/engine/fileOps/dmf.cpp +++ b/src/engine/fileOps/dmf.cpp @@ -1168,6 +1168,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { } ds.systemName=getSongSystemLegacyName(ds,!getConfInt("noMultiSystem",0)); + ds.recalcChans(); if (active) quitDispatch(); BUSY_BEGIN_SOFT; @@ -1175,7 +1176,6 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { song.unload(); song=ds; changeSong(0); - recalcChans(); // always convert to normal sample mode (I have no idea how will I do export) convertLegacySampleMode(); saveLock.unlock(); @@ -1289,7 +1289,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) { lastError="maximum number of wavetables in .dmf is 64"; return NULL; } - for (int i=0; iordersLen; j++) { if (curOrders->ord[i][j]>0x7f) { logE("order %d, %d is out of range (0-127)!",i,j); @@ -1356,7 +1356,7 @@ SafeWriter* DivEngine::saveDMF(unsigned char version) { w->writeI(curSubSong->patLen); w->writeC(curSubSong->ordersLen); - for (int i=0; iordersLen; j++) { w->writeC(curOrders->ord[i][j]); if (version>=25) { diff --git a/src/engine/fileOps/fc.cpp b/src/engine/fileOps/fc.cpp index 6e4408a7d..8fbf49502 100644 --- a/src/engine/fileOps/fc.cpp +++ b/src/engine/fileOps/fc.cpp @@ -664,6 +664,8 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) { ds.subsong[0]->optimizePatterns(); ds.subsong[0]->rearrangePatterns(); + ds.recalcChans(); + if (active) quitDispatch(); BUSY_BEGIN_SOFT; saveLock.lock(); diff --git a/src/engine/fileOps/ftm.cpp b/src/engine/fileOps/ftm.cpp index 791269891..1fee6f053 100644 --- a/src/engine/fileOps/ftm.cpp +++ b/src/engine/fileOps/ftm.cpp @@ -2802,13 +2802,14 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len, bool dnft, bool dnft_si } } + ds.recalcChans(); + if (active) quitDispatch(); BUSY_BEGIN_SOFT; saveLock.lock(); song.unload(); song=ds; changeSong(0); - recalcChans(); saveLock.unlock(); BUSY_END; if (active) { diff --git a/src/engine/fileOps/fur.cpp b/src/engine/fileOps/fur.cpp index a27bf30d7..7a22eed00 100644 --- a/src/engine/fileOps/fur.cpp +++ b/src/engine/fileOps/fur.cpp @@ -2129,6 +2129,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) { } else if (ds.version<237 && ds.linearPitch!=0) { addWarning("this song used partial pitch linearity, which has been removed from Furnace. you may have to adjust your song."); } + ds.recalcChans(); if (active) quitDispatch(); BUSY_BEGIN_SOFT; @@ -2136,7 +2137,6 @@ bool DivEngine::loadFur(unsigned char* file, size_t len, int variantID) { song.unload(); song=ds; changeSong(0); - recalcChans(); // removal of legacy sample mode if (song.version<239) { if (convertLegacySampleMode()) { @@ -2242,7 +2242,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) { // low short is pattern number std::vector patsToWrite; if (getConfInt("saveUnusedPatterns",0)==1) { - for (int i=0; iwriteI(0); } - for (int i=0; iordersLen; j++) { w->writeC(subSong->orders.ord[i][j]); } } - for (int i=0; iwriteC(subSong->pat[i].effectCols); } - for (int i=0; iwriteC( (subSong->chanShow[i]?1:0)| (subSong->chanShowChanOsc[i]?2:0) ); } - for (int i=0; iwriteC(subSong->chanCollapse[i]); } - for (int i=0; iwriteString(subSong->chanName[i],false); } - for (int i=0; iwriteString(subSong->chanShortName[i],false); } @@ -2518,32 +2518,32 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) { w->writeString(subSong->name,false); w->writeString(subSong->notes,false); - for (int i=0; iordersLen; j++) { w->writeC(subSong->orders.ord[i][j]); } } - for (int i=0; iwriteC(subSong->pat[i].effectCols); } - for (int i=0; iwriteC( (subSong->chanShow[i]?1:0)| (subSong->chanShowChanOsc[i]?2:0) ); } - for (int i=0; iwriteC(subSong->chanCollapse[i]); } - for (int i=0; iwriteString(subSong->chanName[i],false); } - for (int i=0; iwriteString(subSong->chanShortName[i],false); } diff --git a/src/engine/fileOps/it.cpp b/src/engine/fileOps/it.cpp index 02d0b00a5..3fe6285a1 100644 --- a/src/engine/fileOps/it.cpp +++ b/src/engine/fileOps/it.cpp @@ -1675,7 +1675,8 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) { ds.systemName="PC"; // find subsongs - ds.findSubSongs(maxChan); + ds.recalcChans(); + ds.findSubSongs(); // populate subsongs with default panning values for (size_t i=0; i newSubSongs; for (DivSubSong* i: subsong) { std::vector subSongStart; @@ -689,9 +689,50 @@ void DivSong::findSubSongs(int chans) { for (DivSubSong* i: newSubSongs) { subsong.push_back(i); } - } +void DivSong::recalcChans() { + bool isInsTypePossible[DIV_INS_MAX]; + chans=0; + int chanIndex=0; + memset(isInsTypePossible,0,DIV_INS_MAX*sizeof(bool)); + for (int i=0; ichanInsType[j][0]!=DIV_INS_NULL) { + isInsTypePossible[sysDef->chanInsType[j][0]]=true; + } + + if (sysDef->chanInsType[j][1]!=DIV_INS_NULL) { + isInsTypePossible[sysDef->chanInsType[j][1]]=true; + } + } + } + } + + possibleInsTypes.clear(); + for (int i=0; iclearData(); @@ -749,4 +790,4 @@ void DivSong::unload() { delete i; } subsong.clear(); -} \ No newline at end of file +} diff --git a/src/engine/song.h b/src/engine/song.h index fef22a7c4..83414452a 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -274,6 +274,7 @@ struct DivSong { bool isDMF; // system + int chans; DivSystem system[DIV_MAX_CHIPS]; unsigned short systemChans[DIV_MAX_CHIPS]; unsigned char systemLen; @@ -396,10 +397,17 @@ struct DivSong { DivWavetable nullWave; DivSample nullSample; + DivSystem sysOfChan[DIV_MAX_CHANS]; + int dispatchOfChan[DIV_MAX_CHANS]; + int dispatchChanOfChan[DIV_MAX_CHANS]; + int dispatchFirstChan[DIV_MAX_CHANS]; + + std::vector possibleInsTypes; + /** * find data past 0Bxx effects and place that into new sub-songs. */ - void findSubSongs(int chans); + void findSubSongs(); /** * clear orders and patterns. @@ -421,6 +429,12 @@ struct DivSong { */ void clearSamples(); + /** + * recalculate channel count and internal state. + " call after editing system[] or systemChans[]. + */ + void recalcChans(); + /** * unloads the song, freeing all memory associated with it. * use before destroying the object. @@ -430,6 +444,7 @@ struct DivSong { DivSong(): version(0), isDMF(false), + chans(0), systemLen(2), name(""), author(""), @@ -508,6 +523,11 @@ struct DivSong { oldAlwaysSetVolume(false), oldSampleOffset(false), oldCenterRate(true) { + memset(dispatchFirstChan,0,DIV_MAX_CHANS*sizeof(int)); + memset(dispatchChanOfChan,0,DIV_MAX_CHANS*sizeof(int)); + memset(dispatchOfChan,0,DIV_MAX_CHANS*sizeof(int)); + memset(sysOfChan,0,DIV_MAX_CHANS*sizeof(int)); + for (int i=0; i