giga-refactor, part 1

This commit is contained in:
tildearrow 2025-11-12 00:39:28 -05:00
parent 2f25acd017
commit a654d33df2
13 changed files with 102 additions and 86 deletions

View file

@ -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; i<song.systemLen; i++) {
int chanCount=song.systemChans[i];
int firstChan=chans;
chans+=chanCount;
for (int j=0; j<chanCount; j++) {
sysOfChan[chanIndex]=song.system[i];
dispatchOfChan[chanIndex]=i;
dispatchChanOfChan[chanIndex]=j;
dispatchFirstChan[chanIndex]=firstChan;
chanIndex++;
if (sysDefs[song.system[i]]!=NULL) {
if (sysDefs[song.system[i]]->chanInsType[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; i<DIV_INS_MAX; i++) {
if (isInsTypePossible[i]) possibleInsTypes.push_back((DivInstrumentType)i);
}
checkAssetDir(song.insDir,song.ins.size());
checkAssetDir(song.waveDir,song.wave.size());
checkAssetDir(song.sampleDir,song.sample.size());
hasLoadedSomething=true;
}
void DivEngine::reset() {
if (output) if (output->midiOut!=NULL) {
output->midiOut->send(TAMidiMessage(TA_MIDI_MACHINE_STOP,0,0));

View file

@ -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<String> midiIns;
std::vector<String> midiOuts;
std::vector<DivCommand> cmdStream;
std::vector<DivInstrumentType> possibleInsTypes;
std::vector<DivEffectContainer> effectInst;
std::vector<int> 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));

View file

@ -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; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
for (int j=0; j<curSubSong->ordersLen; 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; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
for (int j=0; j<curSubSong->ordersLen; j++) {
w->writeC(curOrders->ord[i][j]);
if (version>=25) {

View file

@ -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();

View file

@ -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) {

View file

@ -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<PatToWrite> patsToWrite;
if (getConfInt("saveUnusedPatterns",0)==1) {
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++) {
DivSubSong* subs=song.subsong[j];
for (int k=0; k<DIV_MAX_PATTERNS; k++) {
@ -2253,7 +2253,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
}
} else {
bool alreadyAdded[DIV_MAX_PATTERNS];
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++) {
DivSubSong* subs=song.subsong[j];
memset(alreadyAdded,0,DIV_MAX_PATTERNS*sizeof(bool));
@ -2358,32 +2358,32 @@ SafeWriter* DivEngine::saveFur(bool notPrimary) {
w->writeI(0);
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
for (int j=0; j<subSong->ordersLen; j++) {
w->writeC(subSong->orders.ord[i][j]);
}
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
w->writeC(subSong->pat[i].effectCols);
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
w->writeC(
(subSong->chanShow[i]?1:0)|
(subSong->chanShowChanOsc[i]?2:0)
);
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
w->writeC(subSong->chanCollapse[i]);
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
w->writeString(subSong->chanName[i],false);
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
w->writeString(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; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
for (int j=0; j<subSong->ordersLen; j++) {
w->writeC(subSong->orders.ord[i][j]);
}
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
w->writeC(subSong->pat[i].effectCols);
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
w->writeC(
(subSong->chanShow[i]?1:0)|
(subSong->chanShowChanOsc[i]?2:0)
);
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
w->writeC(subSong->chanCollapse[i]);
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
w->writeString(subSong->chanName[i],false);
}
for (int i=0; i<chans; i++) {
for (int i=0; i<song.chans; i++) {
w->writeString(subSong->chanShortName[i],false);
}

View file

@ -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<ds.subsong.size(); i++) {
@ -1708,7 +1709,6 @@ bool DivEngine::loadIT(unsigned char* file, size_t len) {
song.unload();
song=ds;
changeSong(0);
recalcChans();
saveLock.unlock();
BUSY_END;
if (active) {

View file

@ -431,7 +431,8 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
ds.insLen=ds.ins.size();
// find subsongs
ds.findSubSongs(chCount);
ds.recalcChans();
ds.findSubSongs();
if (active) quitDispatch();
BUSY_BEGIN_SOFT;
@ -439,7 +440,6 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) {
song.unload();
song=ds;
changeSong(0);
recalcChans();
saveLock.unlock();
BUSY_END;
if (active) {

View file

@ -1179,7 +1179,8 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
}
// find subsongs
ds.findSubSongs(DIV_MAX_CHANS);
ds.recalcChans();
ds.findSubSongs();
// populate subsongs with default panning values
if (masterVol&128) { // only in stereo mode
@ -1215,7 +1216,6 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) {
song.unload();
song=ds;
changeSong(0);
recalcChans();
saveLock.unlock();
BUSY_END;
if (active) {

View file

@ -704,13 +704,14 @@ bool DivEngine::loadTFMv1(unsigned char* file, size_t len) {
info.loopPos=loopPos;
TFMParsePattern(info);
ds.recalcChans();
if (active) quitDispatch();
BUSY_BEGIN_SOFT;
saveLock.lock();
song.unload();
song=ds;
changeSong(0);
recalcChans();
saveLock.unlock();
BUSY_END;
if (active) {
@ -904,13 +905,14 @@ bool DivEngine::loadTFMv2(unsigned char* file, size_t len) {
info.loopPos=loopPos;
TFMParsePattern(info);
ds.recalcChans();
if (active) quitDispatch();
BUSY_BEGIN_SOFT;
saveLock.lock();
song.unload();
song=ds;
changeSong(0);
recalcChans();
saveLock.unlock();
BUSY_END;
if (active) {

View file

@ -1377,7 +1377,8 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
}
// find subsongs
ds.findSubSongs(totalChans);
ds.recalcChans();
ds.findSubSongs();
if (active) quitDispatch();
BUSY_BEGIN_SOFT;
@ -1385,7 +1386,6 @@ bool DivEngine::loadXM(unsigned char* file, size_t len) {
song.unload();
song=ds;
changeSong(0);
recalcChans();
saveLock.unlock();
BUSY_END;
if (active) {

View file

@ -574,7 +574,7 @@ void DivSubSong::makePatUnique() {
}
}
void DivSong::findSubSongs(int chans) {
void DivSong::findSubSongs() {
std::vector<DivSubSong*> newSubSongs;
for (DivSubSong* i: subsong) {
std::vector<int> 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; i<systemLen; i++) {
int chanCount=systemChans[i];
int firstChan=chans;
chans+=chanCount;
for (int j=0; j<chanCount; j++) {
sysOfChan[chanIndex]=system[i];
dispatchOfChan[chanIndex]=i;
dispatchChanOfChan[chanIndex]=j;
dispatchFirstChan[chanIndex]=firstChan;
chanIndex++;
DivSysDef* sysDef=DivEngine::getSystemDef(system[i]);
if (sysDef!=NULL) {
if (sysDef->chanInsType[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; i<DIV_INS_MAX; i++) {
if (isInsTypePossible[i]) possibleInsTypes.push_back((DivInstrumentType)i);
}
checkAssetDir(insDir,ins.size());
checkAssetDir(waveDir,wave.size());
checkAssetDir(sampleDir,sample.size());
hasLoadedSomething=true;
}
void DivSong::clearSongData() {
for (DivSubSong* i: subsong) {
i->clearData();
@ -749,4 +790,4 @@ void DivSong::unload() {
delete i;
}
subsong.clear();
}
}

View file

@ -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<DivInstrumentType> 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<DIV_MAX_CHIPS; i++) {
system[i]=DIV_SYSTEM_NULL;
systemChans[i]=0;
@ -654,6 +674,8 @@ struct DivSong {
nullInsESFM.fm.op[3].sl=15;
nullInsESFM.fm.op[3].rr=9;
nullInsESFM.fm.op[3].mult=1;
recalcChans();
}
};