diff --git a/TODO.md b/TODO.md index 8c36f2161..f06d3cf64 100644 --- a/TODO.md +++ b/TODO.md @@ -1,7 +1,6 @@ # to-do for 0.6pre1 - RF5C68 system -- ZX beeper system overlay percussion - ADPCM chips - Game Boy envelope macro/sequence - rewrite the system name detection function anyway diff --git a/src/engine/platform/zxbeeper.cpp b/src/engine/platform/zxbeeper.cpp index 5fc3942fc..8f0f54374 100644 --- a/src/engine/platform/zxbeeper.cpp +++ b/src/engine/platform/zxbeeper.cpp @@ -43,6 +43,25 @@ void DivPlatformZXBeeper::acquire(short* bufL, short* bufR, size_t start, size_t for (size_t h=start; h=0 && curSamplesong.sampleLen) { + if (--curSamplePeriod<0) { + DivSample* s=parent->getSample(curSample); + if (s->samples<=0) { + curSample=-1; + continue; + } + + o=s->data8[curSamplePos++]; + bufL[h]=o?16384:0; + if (curSamplePos>=s->samples) curSample=-1; + // 256 bits + if (curSamplePos>2047) curSample=-1; + + curSamplePeriod=15; + } + continue; + } + unsigned short oldPos=chan[curChan].sPosition; if (sOffTimer) { @@ -128,9 +147,7 @@ int DivPlatformZXBeeper::dispatch(DivCommand c) { break; } case DIV_CMD_NOTE_OFF: - chan[c.chan].dacSample=-1; if (dumpWrites) addWrite(0xffff0002+(c.chan<<8),0); - chan[c.chan].pcm=false; chan[c.chan].active=false; chan[c.chan].keyOff=true; chan[c.chan].macroInit(NULL); @@ -190,13 +207,9 @@ int DivPlatformZXBeeper::dispatch(DivCommand c) { chan[c.chan].duty=c.value; break; case DIV_CMD_SAMPLE_MODE: - chan[c.chan].pcm=c.value; - break; - case DIV_CMD_SAMPLE_BANK: - sampleBank=c.value; - if (sampleBank>(parent->song.sample.size()/12)) { - sampleBank=parent->song.sample.size()/12; - } + curSample=c.value; + curSamplePos=0; + curSamplePeriod=0; break; case DIV_CMD_LEGATO: chan[c.chan].baseFreq=NOTE_FREQUENCY(c.value+((chan[c.chan].std.arp.will && !chan[c.chan].std.arp.mode)?(chan[c.chan].std.arp.val):(0))); @@ -265,8 +278,10 @@ void DivPlatformZXBeeper::reset() { cycles=0; curChan=0; sOffTimer=0; - sampleBank=0; ulaOut=0; + curSample=-1; + curSamplePos=0; + curSamplePeriod=0; } bool DivPlatformZXBeeper::keyOffAffectsArp(int ch) { diff --git a/src/engine/platform/zxbeeper.h b/src/engine/platform/zxbeeper.h index 4e5feabfc..f655a9112 100644 --- a/src/engine/platform/zxbeeper.h +++ b/src/engine/platform/zxbeeper.h @@ -27,10 +27,8 @@ class DivPlatformZXBeeper: public DivDispatch { struct Channel { int freq, baseFreq, pitch, pitch2, note; - int dacPeriod, dacRate; - unsigned int dacPos; - int dacSample, ins; - bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, noise, pcm, furnaceDac; + int ins; + bool active, insChanged, freqChanged, keyOn, keyOff, inPorta; signed char vol, outVol; unsigned short sPosition; unsigned char duty; @@ -45,10 +43,6 @@ class DivPlatformZXBeeper: public DivDispatch { pitch(0), pitch2(0), note(0), - dacPeriod(0), - dacRate(0), - dacPos(0), - dacSample(-1), ins(-1), active(false), insChanged(true), @@ -56,9 +50,6 @@ class DivPlatformZXBeeper: public DivDispatch { keyOn(false), keyOff(false), inPorta(false), - noise(false), - pcm(false), - furnaceDac(false), vol(1), outVol(1), sPosition(0), @@ -75,10 +66,10 @@ class DivPlatformZXBeeper: public DivDispatch { std::queue writes; unsigned char lastPan, ulaOut; - int cycles, curChan, sOffTimer, delay; + int cycles, curChan, sOffTimer, delay, curSample, curSamplePeriod; + unsigned int curSamplePos; int tempL[32]; int tempR[32]; - unsigned char sampleBank, lfoMode, lfoSpeed; unsigned char regPool[128]; friend void putDispatchChan(void*,int,int); public: diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index a60ccf179..accdf6e3d 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1522,7 +1522,21 @@ void DivEngine::registerSystems() { {"Channel 1", "Channel 2", "Channel 3", "Channel 4", "Channel 5", "Channel 6"}, {"CH1", "CH2", "CH3", "CH4", "CH5", "CH6"}, {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE}, - {DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER} + {DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER, DIV_INS_BEEPER}, + {}, + [this](int ch, unsigned char effect, unsigned char effectVal) -> bool { + switch (effect) { + case 0x12: // pulse width + dispatchCmd(DivCommand(DIV_CMD_STD_NOISE_MODE,ch,effectVal)); + break; + case 0x17: // overlay sample + dispatchCmd(DivCommand(DIV_CMD_SAMPLE_MODE,ch,effectVal)); + break; + default: + return false; + } + return true; + } ); sysDefs[DIV_SYSTEM_YM2612_EXT]=new DivSysDef(