diff --git a/src/engine/platform/vb.cpp b/src/engine/platform/vb.cpp index 8a1f78068..2d87025ca 100644 --- a/src/engine/platform/vb.cpp +++ b/src/engine/platform/vb.cpp @@ -128,12 +128,17 @@ void DivPlatformVB::updateWave(int ch) { } } +void DivPlatformVB::writeEnv(int ch) { + chWrite(ch,0x04,(chan[ch].outVol<<4)|(chan[ch].envLow&15)); + chWrite(ch,0x05,chan[ch].envHigh); +} + void DivPlatformVB::tick(bool sysTick) { for (int i=0; i<6; i++) { chan[i].std.next(); if (chan[i].std.vol.had) { chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol&15,MIN(15,chan[i].std.vol.val),15); - chWrite(i,0x04,chan[i].outVol<<4); + writeEnv(i); } if (chan[i].std.arp.had) { if (!chan[i].inPorta) { @@ -209,7 +214,7 @@ int DivPlatformVB::dispatch(DivCommand c) { chan[c.chan].macroInit(ins); if (!parent->song.brokenOutVol && !chan[c.chan].std.vol.will) { chan[c.chan].outVol=chan[c.chan].vol; - chWrite(c.chan,0x04,chan[c.chan].outVol<<4); + writeEnv(c.chan); } if (chan[c.chan].wave<0) { chan[c.chan].wave=0; @@ -240,7 +245,7 @@ int DivPlatformVB::dispatch(DivCommand c) { if (!chan[c.chan].std.vol.has) { chan[c.chan].outVol=c.value; if (chan[c.chan].active) { - chWrite(c.chan,0x04,chan[c.chan].outVol<<4); + writeEnv(c.chan); } } } @@ -260,20 +265,6 @@ int DivPlatformVB::dispatch(DivCommand c) { chan[c.chan].ws.changeWave1(chan[c.chan].wave); chan[c.chan].keyOn=true; break; - case DIV_CMD_PCE_LFO_MODE: - if (c.value==0) { - lfoMode=0; - } else { - lfoMode=c.value; - } - rWrite(0x08,lfoSpeed); - rWrite(0x09,lfoMode); - break; - case DIV_CMD_PCE_LFO_SPEED: - lfoSpeed=255-c.value; - rWrite(0x08,lfoSpeed); - rWrite(0x09,lfoMode); - break; case DIV_CMD_NOTE_PORTA: { int destFreq=NOTE_PERIODIC(c.value2); bool return2=false; @@ -298,8 +289,30 @@ int DivPlatformVB::dispatch(DivCommand c) { break; } case DIV_CMD_STD_NOISE_MODE: - chan[c.chan].noise=c.value; - chWrite(c.chan,0x07,chan[c.chan].noise?(0x80|chan[c.chan].note):0); + if (c.chan!=5) break; + chan[c.chan].envHigh&=~0x70; + chan[c.chan].envHigh|=(c.value&7)<<4; + writeEnv(c.chan); + break; + case DIV_CMD_STD_NOISE_FREQ: + chan[c.chan].envHigh&=~3; + chan[c.chan].envHigh|=(c.value>>4)&3; + chan[c.chan].envLow=c.value&15; + writeEnv(c.chan); + break; + case DIV_CMD_FDS_MOD_DEPTH: // set modulation + if (c.chan!=4) break; + modulation=c.value; + chWrite(4,0x06,modulation); + if (modulation!=0) { + chan[c.chan].envHigh|=0x10; + } else { + chan[c.chan].envHigh&=~0x10; + } + writeEnv(4); + break; + case DIV_CMD_FDS_MOD_WAVE: // set modulation wave + break; case DIV_CMD_PANNING: { chan[c.chan].pan=(c.value&0xf0)|(c.value2>>4); @@ -385,8 +398,7 @@ void DivPlatformVB::reset() { tempR=0; cycles=0; curChan=-1; - lfoMode=0; - lfoSpeed=255; + modulation=0; // set per-channel initial values for (int i=0; i<6; i++) { chWrite(i,0x01,isMuted[i]?0:chan[i].pan); diff --git a/src/engine/platform/vb.h b/src/engine/platform/vb.h index c779f7648..14892bff9 100644 --- a/src/engine/platform/vb.h +++ b/src/engine/platform/vb.h @@ -30,7 +30,7 @@ class DivPlatformVB: public DivDispatch { struct Channel { int freq, baseFreq, pitch, pitch2, note; int ins; - unsigned char pan; + unsigned char pan, envLow, envHigh; bool active, insChanged, freqChanged, keyOn, keyOff, inPorta, noise, deferredWaveUpdate; signed char vol, outVol, wave; DivMacroInt std; @@ -47,6 +47,8 @@ class DivPlatformVB: public DivDispatch { note(0), ins(-1), pan(255), + envLow(0), + envHigh(0), active(false), insChanged(true), freqChanged(false), @@ -73,10 +75,11 @@ class DivPlatformVB: public DivDispatch { int cycles, curChan, delay; int tempL; int tempR; - unsigned char lfoMode, lfoSpeed; + unsigned char modulation; VSU* vb; unsigned char regPool[0x600]; void updateWave(int ch); + void writeEnv(int ch); friend void putDispatchChip(void*,int); friend void putDispatchChan(void*,int,int); public: diff --git a/src/engine/sysDef.cpp b/src/engine/sysDef.cpp index 2ba7098ff..8a124c3f7 100644 --- a/src/engine/sysDef.cpp +++ b/src/engine/sysDef.cpp @@ -1180,7 +1180,13 @@ void DivEngine::registerSystems() { {DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_WAVE, DIV_CH_NOISE}, {DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY, DIV_INS_VBOY}, {}, - waveOnlyEffectHandlerMap + { + {0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}}, + {0x11, {DIV_CMD_STD_NOISE_MODE, "11xx: Set noise length (0 to 7)"}}, + {0x12, {DIV_CMD_STD_NOISE_FREQ, "12xy: Setup envelope (x: enabled/loop (1: enable, 2: loop, 3: enable+loop); y: speed/direction (0-7: down, 8-F: up))"}}, + {0x14, {DIV_CMD_FDS_MOD_DEPTH, "14xy: Setup modulation (channel 5 only)"}}, + {0x15, {DIV_CMD_FDS_MOD_WAVE, "15xx: Set modulation waveform (channel 5 only)"}}, + } ); sysDefs[DIV_SYSTEM_VRC7]=new DivSysDef(