Merge branch 'master' into feature/More-OPL-Patch-Support

This commit is contained in:
James Alan Nguyen 2022-04-17 15:41:18 +10:00
commit ac656f07bb
46 changed files with 397 additions and 148 deletions

View file

@ -853,6 +853,7 @@ void DivEngine::playSub(bool preserveDrift, int goalRow) {
}
if (!preserveDrift) {
ticks=1;
subticks=1;
}
skipping=false;
cmdStream.clear();
@ -1970,7 +1971,7 @@ void DivEngine::autoNoteOn(int ch, int ins, int note, int vol) {
}
do {
if ((ins==-1 || getPreferInsType(finalChan)==getIns(ins)->type) && chan[finalChan].midiNote==-1) {
if ((ins==-1 || getPreferInsType(finalChan)==getIns(ins)->type || getIns(ins)->type==DIV_INS_AMIGA) && chan[finalChan].midiNote==-1) {
chan[finalChan].midiNote=note;
pendingNotes.push(DivNoteEvent(finalChan,ins,note,vol,true));
break;
@ -1996,6 +1997,20 @@ void DivEngine::autoNoteOff(int ch, int note, int vol) {
}
}
void DivEngine::autoNoteOffAll() {
if (!playing) {
reset();
freelance=true;
playing=true;
}
for (int i=0; i<chans; i++) {
if (chan[i].midiNote!=-1) {
pendingNotes.push(DivNoteEvent(i,-1,-1,-1,false));
chan[i].midiNote=-1;
}
}
}
void DivEngine::setOrder(unsigned char order) {
BUSY_BEGIN_SOFT;
curOrder=order;

View file

@ -271,7 +271,7 @@ class DivEngine {
void nextRow();
void performVGMWrite(SafeWriter* w, DivSystem sys, DivRegWrite& write, int streamOff, double* loopTimer, double* loopFreq, int* loopSample, bool isSecond);
// returns true if end of song.
bool nextTick(bool noAccum=false);
bool nextTick(bool noAccum=false, bool inhibitLowLat=false);
bool perSystemEffect(int ch, unsigned char effect, unsigned char effectVal);
bool perSystemPostEffect(int ch, unsigned char effect, unsigned char effectVal);
void recalcChans();
@ -572,6 +572,7 @@ class DivEngine {
void autoNoteOn(int chan, int ins, int note, int vol=-1);
void autoNoteOff(int chan, int note, int vol=-1);
void autoNoteOffAll();
// go to order
void setOrder(unsigned char order);

View file

@ -264,6 +264,20 @@ void DivPlatformArcade::tick(bool sysTick) {
rWrite(0x1b,chan[i].std.wave.val&3);
}
if (chan[i].std.panL.had) {
chan[i].chVolL=(chan[i].std.panL.val&2)>>1;
chan[i].chVolR=chan[i].std.panL.val&1;
if (isMuted[i]) {
rWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3));
} else {
rWrite(chanOffs[i]+ADDR_LR_FB_ALG,(chan[i].state.alg&7)|(chan[i].state.fb<<3)|((chan[i].chVolL&1)<<6)|((chan[i].chVolR&1)<<7));
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
chan[i].keyOn=true;

View file

@ -215,6 +215,9 @@ void DivPlatformAY8910::tick(bool sysTick) {
rWrite(0x08+i,(chan[i].outVol&15)|((chan[i].psgMode&4)<<2));
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
oldWrites[0x08+i]=-1;

View file

@ -226,6 +226,9 @@ void DivPlatformAY8930::tick(bool sysTick) {
rWrite(0x08+i,(chan[i].outVol&31)|((chan[i].psgMode&4)<<3));
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
oldWrites[0x08+i]=-1;

View file

@ -110,6 +110,9 @@ void DivPlatformBubSysWSG::tick(bool sysTick) {
if (!chan[i].keyOff) chan[i].keyOn=true;
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].active) {
if (chan[i].ws.tick()) {
updateWave(i);

View file

@ -181,6 +181,9 @@ void DivPlatformC64::tick(bool sysTick) {
chan[i].wave=chan[i].std.wave.val;
rWrite(i*7+4,(chan[i].wave<<4)|(chan[i].ring<<2)|(chan[i].sync<<1)|(int)(chan[i].active));
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.ex1.had) {
filtControl=chan[i].std.ex1.val&15;
updateFilter();

View file

@ -107,21 +107,11 @@ void DivPlatformFDS::tick(bool sysTick) {
rWrite(0x4080,0x80|chan[i].outVol);
}
if (chan[i].std.arp.had) {
if (i==3) { // noise
if (!chan[i].inPorta) {
if (chan[i].std.arp.mode) {
chan[i].baseFreq=chan[i].std.arp.val;
chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val);
} else {
chan[i].baseFreq=chan[i].note+chan[i].std.arp.val;
}
if (chan[i].baseFreq>255) chan[i].baseFreq=255;
if (chan[i].baseFreq<0) chan[i].baseFreq=0;
} else {
if (!chan[i].inPorta) {
if (chan[i].std.arp.mode) {
chan[i].baseFreq=NOTE_FREQUENCY(chan[i].std.arp.val);
} else {
chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+chan[i].std.arp.val);
}
chan[i].baseFreq=NOTE_FREQUENCY(chan[i].note+chan[i].std.arp.val);
}
}
chan[i].freqChanged=true;
@ -155,6 +145,9 @@ void DivPlatformFDS::tick(bool sysTick) {
//if (!chan[i].keyOff) chan[i].keyOn=true;
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].active) {
if (ws.tick()) {
updateWave();

View file

@ -192,6 +192,9 @@ void DivPlatformGB::tick(bool sysTick) {
if (!chan[i].keyOff) chan[i].keyOn=true;
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
chan[i].keyOn=true;

View file

@ -258,6 +258,10 @@ void DivPlatformGenesis::tick(bool sysTick) {
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
chan[i].keyOn=true;

View file

@ -171,6 +171,10 @@ void DivPlatformLynx::tick(bool sysTick) {
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].freqChanged) {
if (chan[i].lfsr >= 0) {
WRITE_LFSR(i, (chan[i].lfsr&0xff));
@ -184,8 +188,8 @@ void DivPlatformLynx::tick(bool sysTick) {
}
WRITE_CONTROL(i, (chan[i].fd.clockDivider|0x18|chan[i].duty.int_feedback7));
WRITE_BACKUP( i, chan[i].fd.backup );
}
else if (chan[i].std.duty.had) {
chan[i].freqChanged=false;
} else if (chan[i].std.duty.had) {
chan[i].duty = chan[i].std.duty.val;
WRITE_FEEDBACK(i, chan[i].duty.feedback);
WRITE_CONTROL(i, (chan[i].fd.clockDivider|0x18|chan[i].duty.int_feedback7));

View file

@ -123,6 +123,9 @@ void DivPlatformMMC5::tick(bool sysTick) {
chan[i].duty=chan[i].std.duty.val;
rWrite(0x5000+i*4,0x30|chan[i].outVol|((chan[i].duty&3)<<6));
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
chan[i].freqChanged=true;

View file

@ -261,6 +261,9 @@ void DivPlatformN163::tick(bool sysTick) {
}
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.ex1.had) {
if (chan[i].waveLen!=(chan[i].std.ex1.val&0xfc)) {
chan[i].waveLen=chan[i].std.ex1.val&0xfc;

View file

@ -195,6 +195,9 @@ void DivPlatformNES::tick(bool sysTick) {
chan[i].freqChanged=true;
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].sweepChanged) {
chan[i].sweepChanged=false;
if (i==0) {

View file

@ -269,6 +269,10 @@ void DivPlatformOPL::tick(bool sysTick) {
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
chan[i].keyOn=true;

View file

@ -145,6 +145,10 @@ void DivPlatformOPLL::tick(bool sysTick) {
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
chan[i].keyOn=true;

View file

@ -196,6 +196,9 @@ void DivPlatformPCE::tick(bool sysTick) {
if (!chan[i].keyOff) chan[i].keyOn=true;
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].active) {
if (chan[i].ws.tick() || (chan[i].std.phaseReset.had && chan[i].std.phaseReset.val==1)) {
updateWave(i);

View file

@ -186,6 +186,9 @@ void DivPlatformPCSpeaker::tick(bool sysTick) {
chan[i].freqChanged=true;
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)-1+chan[i].std.pitch.val;
if (chan[i].freq<0) chan[i].freq=0;

View file

@ -112,6 +112,9 @@ void DivPlatformPET::tick(bool sysTick) {
rWrite(10,chan.wave);
}
}
if (chan.std.pitch.had) {
chan.freqChanged=true;
}
if (chan.freqChanged || chan.keyOn || chan.keyOff) {
chan.freq=parent->calcFreq(chan.baseFreq,chan.pitch,true)+chan.std.pitch.val;
if (chan.freq>257) chan.freq=257;

View file

@ -326,6 +326,9 @@ void DivPlatformQSound::tick(bool sysTick) {
chan[i].freqChanged=true;
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
//DivInstrument* ins=parent->getIns(chan[i].ins);
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false)+chan[i].std.pitch.val;

View file

@ -166,6 +166,9 @@ void DivPlatformSAA1099::tick(bool sysTick) {
if (chan[i].std.wave.had) {
chan[i].psgMode=chan[i].std.wave.val&3;
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.ex1.had) {
saaEnv[i/3]=chan[i].std.ex1.val;
rWrite(0x18+(i/3),saaEnv[i/3]);

View file

@ -99,6 +99,10 @@ void DivPlatformSegaPCM::tick(bool sysTick) {
chan[i].freqChanged=true;
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
/*if (chan[i].keyOn || chan[i].keyOff) {
chan[i].keyOff=false;
}*/

View file

@ -98,6 +98,9 @@ void DivPlatformSMS::tick(bool sysTick) {
}
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
}
for (int i=0; i<3; i++) {
if (chan[i].freqChanged) {

View file

@ -173,6 +173,9 @@ void DivPlatformSwan::tick(bool sysTick) {
chan[i].ws.changeWave1(chan[i].wave);
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].active) {
sndCtrl|=(1<<i);
if (chan[i].ws.tick()) {

View file

@ -116,6 +116,9 @@ void DivPlatformTIA::tick(bool sysTick) {
rWrite(0x15+i,chan[i].shape);
chan[i].freqChanged=true;
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
if (chan[i].insChanged) {
if (!chan[i].std.wave.will) {

View file

@ -228,6 +228,10 @@ void DivPlatformTX81Z::tick(bool sysTick) {
rWrite(0x1b,chan[i].std.wave.val&3);
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
chan[i].keyOn=true;

View file

@ -184,6 +184,9 @@ void DivPlatformVERA::tick(bool sysTick) {
if (chan[i].std.wave.had) {
rWriteHi(i,3,chan[i].std.wave.val);
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].freqChanged) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,false,8)+chan[i].std.pitch.val;
if (chan[i].freq>65535) chan[i].freq=65535;

View file

@ -119,6 +119,9 @@ void DivPlatformVIC20::tick(bool sysTick) {
chan[i].keyOn=true;
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)+chan[i].std.pitch.val;
if (i<3) {

View file

@ -178,6 +178,9 @@ void DivPlatformVRC6::tick(bool sysTick) {
chWrite(i,0,(chan[i].outVol&0xf)|((chan[i].duty&7)<<4));
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) {
if (i==2) { // sawtooth
chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,true)-1+chan[i].std.pitch.val;

View file

@ -372,6 +372,9 @@ void DivPlatformX1_010::tick(bool sysTick) {
}
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.ex1.had) {
bool nextEnable=(chan[i].std.ex1.val&1);
if (nextEnable!=(chan[i].env.flag.envEnable)) {

View file

@ -408,6 +408,10 @@ void DivPlatformYM2610::tick(bool sysTick) {
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
chan[i].keyOn=true;

View file

@ -472,6 +472,10 @@ void DivPlatformYM2610B::tick(bool sysTick) {
}
}
if (chan[i].std.pitch.had) {
chan[i].freqChanged=true;
}
if (chan[i].std.phaseReset.had) {
if (chan[i].std.phaseReset.val==1) {
chan[i].keyOn=true;

View file

@ -1472,19 +1472,21 @@ void DivEngine::nextRow() {
firstTick=true;
}
bool DivEngine::nextTick(bool noAccum) {
bool DivEngine::nextTick(bool noAccum, bool inhibitLowLat) {
bool ret=false;
if (divider<10) divider=10;
if (lowLatency) {
if (lowLatency && !skipping && !inhibitLowLat) {
tickMult=1000/divider;
if (tickMult<1) tickMult=1;
} else {
tickMult=1;
}
cycles=got.rate*pow(2,MASTER_CLOCK_PREC)/(divider*tickMult);
clockDrift+=fmod(got.rate*pow(2,MASTER_CLOCK_PREC),(double)divider);
if (clockDrift>=divider) {
clockDrift-=divider;
clockDrift+=fmod(got.rate*pow(2,MASTER_CLOCK_PREC),(double)(divider*tickMult));
if (clockDrift>=(divider*tickMult)) {
clockDrift-=(divider*tickMult);
cycles++;
}

View file

@ -1384,7 +1384,7 @@ SafeWriter* DivEngine::saveVGM(bool* sysToExport, bool loop, int version) {
writeLoop=true;
}
}
if (nextTick() || !playing) {
if (nextTick(false,true) || !playing) {
done=true;
if (!loop) {
for (int i=0; i<song.systemLen; i++) {