VGM export: prepare to implement 30xx

issue #1798
This commit is contained in:
tildearrow 2024-10-19 14:24:26 -05:00
parent 2385f6f51b
commit 4281acc9dc
2 changed files with 50 additions and 33 deletions

View file

@ -394,9 +394,18 @@ struct DivRegWrite {
struct DivDelayedWrite { struct DivDelayedWrite {
int time; int time;
// this variable is internal.
// it is used by VGM export to make sure these writes are in order.
// do not change.
int order;
DivRegWrite write; DivRegWrite write;
DivDelayedWrite(int t, int o, unsigned int a, unsigned int v):
time(t),
order(o),
write(a,v) {}
DivDelayedWrite(int t, unsigned int a, unsigned int v): DivDelayedWrite(int t, unsigned int a, unsigned int v):
time(t), time(t),
order(0),
write(a,v) {} write(a,v) {}
}; };

View file

@ -2679,17 +2679,21 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
} }
} }
} }
// get register dumps
// calculate number of samples in this tick
int totalWait=cycles>>MASTER_CLOCK_PREC;
// get register dumps and put them into delayed writes
int writeNum=0;
for (int i=0; i<song.systemLen; i++) { for (int i=0; i<song.systemLen; i++) {
std::vector<DivRegWrite>& writes=disCont[i].dispatch->getRegisterWrites(); std::vector<DivRegWrite>& writes=disCont[i].dispatch->getRegisterWrites();
for (DivRegWrite& j: writes) { for (DivRegWrite& j: writes) {
performVGMWrite(w,song.system[i],j,streamIDs[i],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i],directStream,sampleStoppable); sortedWrites.push_back(std::pair<int,DivDelayedWrite>(i,DivDelayedWrite(0,writeNum++,j.addr,j.val)));
writeCount++;
} }
writes.clear(); writes.clear();
} }
// check whether we need to loop
int totalWait=cycles>>MASTER_CLOCK_PREC; // handle direct stream writes
if (directStream) { if (directStream) {
// render stream of all chips // render stream of all chips
for (int i=0; i<song.systemLen; i++) { for (int i=0; i<song.systemLen; i++) {
@ -2699,40 +2703,43 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
} }
delayedWrites[i].clear(); delayedWrites[i].clear();
} }
}
if (!sortedWrites.empty()) { // put writes
// sort if more than one chip if (!sortedWrites.empty()) {
if (song.systemLen>1) { // sort writes
std::sort(sortedWrites.begin(),sortedWrites.end(),[](const std::pair<int,DivDelayedWrite>& a, const std::pair<int,DivDelayedWrite>& b) -> bool { std::sort(sortedWrites.begin(),sortedWrites.end(),[](const std::pair<int,DivDelayedWrite>& a, const std::pair<int,DivDelayedWrite>& b) -> bool {
return a.second.time<b.second.time; if (a.second.time==b.second.time) {
}); return a.second.order<b.second.order;
} }
return a.second.time<b.second.time;
});
// write it out // write it out
int lastOne=0; int lastOne=0;
for (std::pair<int,DivDelayedWrite>& i: sortedWrites) { for (std::pair<int,DivDelayedWrite>& i: sortedWrites) {
if (i.second.time>lastOne) { if (i.second.time>lastOne) {
// write delay // write delay
int delay=i.second.time-lastOne; int delay=i.second.time-lastOne;
if (delay>16) { if (delay>16) {
w->writeC(0x61); w->writeC(0x61);
w->writeS(delay); w->writeS(delay);
} else if (delay>0) { } else if (delay>0) {
w->writeC(0x70+delay-1); w->writeC(0x70+delay-1);
}
lastOne=i.second.time;
} }
// write write lastOne=i.second.time;
performVGMWrite(w,song.system[i.first],i.second.write,streamIDs[i.first],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i.first],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i.first],directStream,sampleStoppable);
// handle global Furnace commands
writeCount++;
} }
sortedWrites.clear(); // write write
totalWait-=lastOne; performVGMWrite(w,song.system[i.first],i.second.write,streamIDs[i.first],loopTimer,loopFreq,loopSample,sampleDir,isSecond[i.first],pendingFreq,playingSample,setPos,sampleOff8,sampleLen8,bankOffset[i.first],directStream,sampleStoppable);
tickCount+=lastOne; writeCount++;
} }
} else { sortedWrites.clear();
totalWait-=lastOne;
tickCount+=lastOne;
}
// handle streams
if (!directStream) {
for (int i=0; i<streamID; i++) { for (int i=0; i<streamID; i++) {
if (loopSample[i]>=0) { if (loopSample[i]>=0) {
loopTimer[i]-=(loopFreq[i]/44100.0)*(double)totalWait; loopTimer[i]-=(loopFreq[i]/44100.0)*(double)totalWait;
@ -2786,6 +2793,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version, bool p
} }
} }
} }
// write wait // write wait
if (totalWait>0) { if (totalWait>0) {
if (totalWait==735) { if (totalWait==735) {