From 23dc645ced419f6f35cee6f0bef734fdc1bf5ab5 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 28 May 2021 02:02:54 -0500 Subject: [PATCH] out of bounds and non-determinism fixes the soldiers play properly now --- src/engine/macroInt.cpp | 16 ++++++++++++++++ src/engine/macroInt.h | 9 +++++++++ src/engine/orders.h | 4 ++++ src/engine/platform/gb.cpp | 21 ++++++++------------- src/engine/platform/gb.h | 3 --- src/engine/song.h | 32 ++++++++++++++++++++++++++++++++ src/engine/wavetable.h | 5 +++++ 7 files changed, 74 insertions(+), 16 deletions(-) diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index e78264e95..ffeef00ce 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -3,6 +3,10 @@ void DivMacroInt::next() { if (ins==NULL) return; + if (finishedVol) finishedVol=false; + if (hadVol!=hasVol) { + finishedVol=true; + } hadVol=hasVol; if (hasVol) { vol=ins->std.volMacro[volPos++]; @@ -15,6 +19,10 @@ void DivMacroInt::next() { } } + if (finishedArp) finishedArp=false; + if (hadArp!=hasArp) { + finishedArp=true; + } hadArp=hasArp; if (hasArp) { arp=ins->std.arpMacro[arpPos++]; @@ -27,6 +35,10 @@ void DivMacroInt::next() { } } + if (finishedDuty) finishedDuty=false; + if (hadDuty!=hasDuty) { + finishedDuty=true; + } hadDuty=hasDuty; if (hasDuty) { duty=ins->std.dutyMacro[dutyPos++]; @@ -39,6 +51,10 @@ void DivMacroInt::next() { } } + if (finishedWave) finishedWave=false; + if (hadWave!=hasWave) { + finishedWave=true; + } hadWave=hasWave; if (hasWave) { wave=ins->std.waveMacro[wavePos++]; diff --git a/src/engine/macroInt.h b/src/engine/macroInt.h index 32800a0cb..2b8d41a73 100644 --- a/src/engine/macroInt.h +++ b/src/engine/macroInt.h @@ -10,11 +10,16 @@ class DivMacroInt { unsigned char vol, arp, duty, wave; bool hasVol, hasArp, hasDuty, hasWave; bool hadVol, hadArp, hadDuty, hadWave; + bool finishedVol, finishedArp, finishedDuty, finishedWave; bool arpMode; void next(); void init(DivInstrument* which); DivMacroInt(): ins(NULL), + volPos(0), + arpPos(0), + dutyPos(0), + wavePos(0), vol(0), arp(0), duty(0), @@ -27,6 +32,10 @@ class DivMacroInt { hadArp(false), hadDuty(false), hadWave(false), + finishedVol(false), + finishedArp(false), + finishedDuty(false), + finishedWave(false), arpMode(false) {} }; diff --git a/src/engine/orders.h b/src/engine/orders.h index c9f610a79..f3e43ac53 100644 --- a/src/engine/orders.h +++ b/src/engine/orders.h @@ -1,3 +1,7 @@ struct DivOrders { unsigned char ord[32][128]; + + DivOrders() { + memset(ord,0,32*128); + } }; diff --git a/src/engine/platform/gb.cpp b/src/engine/platform/gb.cpp index 05c44c9e3..ab1e6688c 100644 --- a/src/engine/platform/gb.cpp +++ b/src/engine/platform/gb.cpp @@ -68,6 +68,8 @@ void DivPlatformGB::tick() { } else { chan[i].baseFreq=chan[i].note+chan[i].std.arp-12; } + if (chan[i].baseFreq>255) chan[i].baseFreq=255; + if (chan[i].baseFreq<0) chan[i].baseFreq=0; } else { if (chan[i].std.arpMode) { chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].std.arp+24)/12.0f))); @@ -76,6 +78,11 @@ void DivPlatformGB::tick() { } } chan[i].freqChanged=true; + } else { + if (chan[i].std.arpMode && chan[i].std.finishedArp) { + chan[i].baseFreq=round(FREQ_BASE/pow(2.0f,((float)(chan[i].note)/12.0f))); + chan[i].freqChanged=true; + } } if (chan[i].std.hadDuty) { chan[i].duty=chan[i].std.duty; @@ -139,13 +146,6 @@ void DivPlatformGB::tick() { chan[i].freqChanged=false; } } - - for (int i=0; i<64; i++) { - if (pendingWrites[i]!=oldWrites[i]) { - GB_apu_write(gb,i,pendingWrites[i]&0xff); - oldWrites[i]=pendingWrites[i]; - } - } } int DivPlatformGB::dispatch(DivCommand c) { @@ -192,7 +192,7 @@ int DivPlatformGB::dispatch(DivCommand c) { if (c.chan!=2) break; chan[c.chan].wave=c.value; updateWave(); - chan[c.chan].freqChanged=true; + chan[c.chan].keyOn=true; break; case DIV_CMD_NOTE_PORTA: { int destFreq=round(FREQ_BASE/pow(2.0f,((float)c.value2/12.0f))); @@ -268,14 +268,9 @@ int DivPlatformGB::init(DivEngine* p, int channels, int sugRate) { gb->model=GB_MODEL_DMG_B; GB_apu_init(gb); GB_set_sample_rate(gb,rate); - for (int i=0; i<64; i++) { - oldWrites[i]=-1; - pendingWrites[i]=-1; - } // enable all channels GB_apu_write(gb,0x26,0x80); GB_apu_write(gb,0x25,0xff); lastPan=0xff; - updateSNMode=false; return 4; } diff --git a/src/engine/platform/gb.h b/src/engine/platform/gb.h index d623cdfcb..37b807cf8 100644 --- a/src/engine/platform/gb.h +++ b/src/engine/platform/gb.h @@ -31,9 +31,6 @@ class DivPlatformGB: public DivDispatch { }; Channel chan[4]; unsigned char lastPan; - bool updateSNMode; - short oldWrites[64]; - short pendingWrites[64]; GB_gameboy_t* gb; void updateWave(); diff --git a/src/engine/song.h b/src/engine/song.h index b81dc0eca..56b933265 100644 --- a/src/engine/song.h +++ b/src/engine/song.h @@ -97,4 +97,36 @@ struct DivSong { DivInstrument nullIns; DivWavetable nullWave; + + DivSong(): + version(0), + system(DIV_SYSTEM_NULL), + name(""), + author(""), + carrier(""), + composer(""), + vendor(""), + category(""), + writer(""), + arranger(""), + copyright(""), + manGroup(""), + manInfo(""), + createdDate(""), + revisionDate(""), + hilightA(4), + hilightB(16), + timeBase(1), + speed1(6), + speed2(6), + arpLen(1), + pal(false), + customTempo(false), + hz(60), + patLen(0), + ordersLen(0), + insLen(0), + waveLen(0), + sampleLen(0) { + } }; diff --git a/src/engine/wavetable.h b/src/engine/wavetable.h index 64fcd9525..87be93eba 100644 --- a/src/engine/wavetable.h +++ b/src/engine/wavetable.h @@ -1,4 +1,9 @@ struct DivWavetable { int len; int data[32]; + + DivWavetable(): + len(32) { + memset(data,0,32*sizeof(int)); + } };