mirror of
https://github.com/tildearrow/furnace.git
synced 2024-11-02 02:52:40 +00:00
SNES: implement more effects
This commit is contained in:
parent
3329e98c51
commit
6f1a41de1e
3 changed files with 115 additions and 36 deletions
|
@ -296,29 +296,7 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
}
|
}
|
||||||
if (chan[c.chan].insChanged) {
|
if (chan[c.chan].insChanged) {
|
||||||
chan[c.chan].state=ins->snes;
|
chan[c.chan].state=ins->snes;
|
||||||
if (chan[c.chan].state.useEnv) {
|
writeEnv(c.chan);
|
||||||
chWrite(c.chan,5,chan[c.chan].state.a|(chan[c.chan].state.d<<4)|0x80);
|
|
||||||
chWrite(c.chan,6,chan[c.chan].state.r|(chan[c.chan].state.s<<5));
|
|
||||||
} else {
|
|
||||||
chWrite(c.chan,5,0);
|
|
||||||
switch (chan[c.chan].state.gainMode) {
|
|
||||||
case DivInstrumentSNES::GAIN_MODE_DIRECT:
|
|
||||||
chWrite(c.chan,7,chan[c.chan].state.gain&127);
|
|
||||||
break;
|
|
||||||
case DivInstrumentSNES::GAIN_MODE_DEC_LINEAR:
|
|
||||||
chWrite(c.chan,7,0x80|(chan[c.chan].state.gain&31));
|
|
||||||
break;
|
|
||||||
case DivInstrumentSNES::GAIN_MODE_INC_LINEAR:
|
|
||||||
chWrite(c.chan,7,0xc0|(chan[c.chan].state.gain&31));
|
|
||||||
break;
|
|
||||||
case DivInstrumentSNES::GAIN_MODE_DEC_LOG:
|
|
||||||
chWrite(c.chan,7,0xa0|(chan[c.chan].state.gain&31));
|
|
||||||
break;
|
|
||||||
case DivInstrumentSNES::GAIN_MODE_INC_INVLOG:
|
|
||||||
chWrite(c.chan,7,0xe0|(chan[c.chan].state.gain&31));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
chan[c.chan].baseFreq=round(NOTE_FREQUENCY(c.value));
|
chan[c.chan].baseFreq=round(NOTE_FREQUENCY(c.value));
|
||||||
|
@ -368,6 +346,11 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
chan[c.chan].pitch=c.value;
|
chan[c.chan].pitch=c.value;
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_WAVE:
|
||||||
|
if (!chan[c.chan].useWave) break;
|
||||||
|
chan[c.chan].wave=c.value;
|
||||||
|
chan[c.chan].ws.changeWave1(chan[c.chan].wave);
|
||||||
|
break;
|
||||||
case DIV_CMD_NOTE_PORTA: {
|
case DIV_CMD_NOTE_PORTA: {
|
||||||
int destFreq=round(NOTE_FREQUENCY(c.value2));
|
int destFreq=round(NOTE_FREQUENCY(c.value2));
|
||||||
bool return2=false;
|
bool return2=false;
|
||||||
|
@ -404,9 +387,76 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
chan[c.chan].inPorta=c.value;
|
chan[c.chan].inPorta=c.value;
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_SAMPLE_POS:
|
case DIV_CMD_SAMPLE_POS:
|
||||||
|
// may have to remove this
|
||||||
chan[c.chan].audPos=c.value;
|
chan[c.chan].audPos=c.value;
|
||||||
chan[c.chan].setPos=true;
|
chan[c.chan].setPos=true;
|
||||||
break;
|
break;
|
||||||
|
case DIV_CMD_STD_NOISE_MODE:
|
||||||
|
chan[c.chan].noise=c.value;
|
||||||
|
writeNoise=true;
|
||||||
|
break;
|
||||||
|
case DIV_CMD_SNES_PITCH_MOD:
|
||||||
|
chan[c.chan].pitchMod=c.value;
|
||||||
|
writePitchMod=true;
|
||||||
|
break;
|
||||||
|
case DIV_CMD_SNES_INVERT:
|
||||||
|
chan[c.chan].invertL=(c.value>>4);
|
||||||
|
chan[c.chan].invertR=c.chan&15;
|
||||||
|
writeOutVol(c.chan);
|
||||||
|
break;
|
||||||
|
case DIV_CMD_SNES_GAIN_MODE:
|
||||||
|
if (c.value) {
|
||||||
|
chan[c.chan].state.useEnv=false;
|
||||||
|
switch (c.value) {
|
||||||
|
case 1:
|
||||||
|
chan[c.chan].state.gainMode=DivInstrumentSNES::GAIN_MODE_DIRECT;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
chan[c.chan].state.gainMode=DivInstrumentSNES::GAIN_MODE_DEC_LINEAR;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
chan[c.chan].state.gainMode=DivInstrumentSNES::GAIN_MODE_DEC_LOG;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
chan[c.chan].state.gainMode=DivInstrumentSNES::GAIN_MODE_INC_LINEAR;
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
chan[c.chan].state.gainMode=DivInstrumentSNES::GAIN_MODE_INC_INVLOG;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
chan[c.chan].state.useEnv=true;
|
||||||
|
}
|
||||||
|
writeEnv(c.chan);
|
||||||
|
break;
|
||||||
|
case DIV_CMD_SNES_GAIN:
|
||||||
|
if (chan[c.chan].state.gainMode==DivInstrumentSNES::GAIN_MODE_DIRECT) {
|
||||||
|
chan[c.chan].state.gain=c.value&0x7f;
|
||||||
|
} else {
|
||||||
|
chan[c.chan].state.gain=c.value&0x1f;
|
||||||
|
}
|
||||||
|
if (!chan[c.chan].state.useEnv) writeEnv(c.chan);
|
||||||
|
break;
|
||||||
|
case DIV_CMD_STD_NOISE_FREQ:
|
||||||
|
noiseFreq=c.value&0x1f;
|
||||||
|
writeControl=true;
|
||||||
|
break;
|
||||||
|
case DIV_CMD_FM_AR:
|
||||||
|
chan[c.chan].state.a=c.value&15;
|
||||||
|
if (chan[c.chan].state.useEnv) writeEnv(c.chan);
|
||||||
|
break;
|
||||||
|
case DIV_CMD_FM_DR:
|
||||||
|
chan[c.chan].state.d=c.value&7;
|
||||||
|
if (chan[c.chan].state.useEnv) writeEnv(c.chan);
|
||||||
|
break;
|
||||||
|
case DIV_CMD_FM_SL:
|
||||||
|
chan[c.chan].state.s=c.value&7;
|
||||||
|
if (chan[c.chan].state.useEnv) writeEnv(c.chan);
|
||||||
|
break;
|
||||||
|
case DIV_CMD_FM_RR:
|
||||||
|
chan[c.chan].state.r=c.value&0x1f;
|
||||||
|
if (chan[c.chan].state.useEnv) writeEnv(c.chan);
|
||||||
|
break;
|
||||||
case DIV_CMD_SNES_ECHO:
|
case DIV_CMD_SNES_ECHO:
|
||||||
chan[c.chan].echo=c.value;
|
chan[c.chan].echo=c.value;
|
||||||
writeEcho=true;
|
writeEcho=true;
|
||||||
|
@ -484,6 +534,32 @@ void DivPlatformSNES::writeOutVol(int ch) {
|
||||||
chWrite(ch,1,outR);
|
chWrite(ch,1,outR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DivPlatformSNES::writeEnv(int ch) {
|
||||||
|
if (chan[ch].state.useEnv) {
|
||||||
|
chWrite(ch,5,chan[ch].state.a|(chan[ch].state.d<<4)|0x80);
|
||||||
|
chWrite(ch,6,chan[ch].state.r|(chan[ch].state.s<<5));
|
||||||
|
} else {
|
||||||
|
chWrite(ch,5,0);
|
||||||
|
switch (chan[ch].state.gainMode) {
|
||||||
|
case DivInstrumentSNES::GAIN_MODE_DIRECT:
|
||||||
|
chWrite(ch,7,chan[ch].state.gain&127);
|
||||||
|
break;
|
||||||
|
case DivInstrumentSNES::GAIN_MODE_DEC_LINEAR:
|
||||||
|
chWrite(ch,7,0x80|(chan[ch].state.gain&31));
|
||||||
|
break;
|
||||||
|
case DivInstrumentSNES::GAIN_MODE_INC_LINEAR:
|
||||||
|
chWrite(ch,7,0xc0|(chan[ch].state.gain&31));
|
||||||
|
break;
|
||||||
|
case DivInstrumentSNES::GAIN_MODE_DEC_LOG:
|
||||||
|
chWrite(ch,7,0xa0|(chan[ch].state.gain&31));
|
||||||
|
break;
|
||||||
|
case DivInstrumentSNES::GAIN_MODE_INC_INVLOG:
|
||||||
|
chWrite(ch,7,0xe0|(chan[ch].state.gain&31));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DivPlatformSNES::muteChannel(int ch, bool mute) {
|
void DivPlatformSNES::muteChannel(int ch, bool mute) {
|
||||||
isMuted[ch]=mute;
|
isMuted[ch]=mute;
|
||||||
writeOutVol(ch);
|
writeOutVol(ch);
|
||||||
|
|
|
@ -131,6 +131,7 @@ class DivPlatformSNES: public DivDispatch {
|
||||||
private:
|
private:
|
||||||
void updateWave(int ch);
|
void updateWave(int ch);
|
||||||
void writeOutVol(int ch);
|
void writeOutVol(int ch);
|
||||||
|
void writeEnv(int ch);
|
||||||
void initEcho();
|
void initEcho();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -867,23 +867,11 @@ void DivEngine::registerSystems() {
|
||||||
{DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES},
|
{DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES, DIV_INS_SNES},
|
||||||
{},
|
{},
|
||||||
{
|
{
|
||||||
{0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}},
|
|
||||||
{0x11, {DIV_CMD_STD_NOISE_MODE, "11xx: Toggle noise mode"}},
|
|
||||||
{0x12, {DIV_CMD_SNES_ECHO, "12xx: Toggle echo on this channel"}},
|
|
||||||
{0x13, {DIV_CMD_SNES_PITCH_MOD, "13xx: Toggle pitch modulation"}},
|
|
||||||
{0x14, {DIV_CMD_SNES_INVERT, "14xy: Toggle invert (x: left; y: right)"}},
|
|
||||||
{0x15, {DIV_CMD_SNES_GAIN_MODE, "15xx: Set gain mode"}},
|
|
||||||
{0x16, {DIV_CMD_SNES_GAIN, "16xx: Set gain"}},
|
|
||||||
{0x18, {DIV_CMD_SNES_ECHO_ENABLE, "18xx: Enable echo buffer"}},
|
{0x18, {DIV_CMD_SNES_ECHO_ENABLE, "18xx: Enable echo buffer"}},
|
||||||
{0x19, {DIV_CMD_SNES_ECHO_DELAY, "19xx: Set echo delay"}},
|
{0x19, {DIV_CMD_SNES_ECHO_DELAY, "19xx: Set echo delay (0 to F)"}},
|
||||||
{0x1a, {DIV_CMD_SNES_ECHO_VOL_LEFT, "1Axx: Set left echo volume"}},
|
{0x1a, {DIV_CMD_SNES_ECHO_VOL_LEFT, "1Axx: Set left echo volume"}},
|
||||||
{0x1b, {DIV_CMD_SNES_ECHO_VOL_RIGHT, "1Bxx: Set right echo volume"}},
|
{0x1b, {DIV_CMD_SNES_ECHO_VOL_RIGHT, "1Bxx: Set right echo volume"}},
|
||||||
{0x1c, {DIV_CMD_SNES_ECHO_FEEDBACK, "1Cxx: Set echo feedback"}},
|
{0x1c, {DIV_CMD_SNES_ECHO_FEEDBACK, "1Cxx: Set echo feedback"}},
|
||||||
{0x1d, {DIV_CMD_STD_NOISE_FREQ, "1Dxx: Set noise frequency"}},
|
|
||||||
{0x20, {DIV_CMD_FM_AR, "20xx: Set attack"}},
|
|
||||||
{0x21, {DIV_CMD_FM_DR, "21xx: Set decay"}},
|
|
||||||
{0x22, {DIV_CMD_FM_SL, "22xx: Set sustain"}},
|
|
||||||
{0x23, {DIV_CMD_FM_RR, "23xx: Set release"}},
|
|
||||||
{0x30, {DIV_CMD_SNES_ECHO_FIR, "30xx: Set echo filter coefficient 0",constVal<0>,effectVal}},
|
{0x30, {DIV_CMD_SNES_ECHO_FIR, "30xx: Set echo filter coefficient 0",constVal<0>,effectVal}},
|
||||||
{0x31, {DIV_CMD_SNES_ECHO_FIR, "31xx: Set echo filter coefficient 1",constVal<1>,effectVal}},
|
{0x31, {DIV_CMD_SNES_ECHO_FIR, "31xx: Set echo filter coefficient 1",constVal<1>,effectVal}},
|
||||||
{0x32, {DIV_CMD_SNES_ECHO_FIR, "32xx: Set echo filter coefficient 2",constVal<2>,effectVal}},
|
{0x32, {DIV_CMD_SNES_ECHO_FIR, "32xx: Set echo filter coefficient 2",constVal<2>,effectVal}},
|
||||||
|
@ -892,6 +880,20 @@ void DivEngine::registerSystems() {
|
||||||
{0x35, {DIV_CMD_SNES_ECHO_FIR, "35xx: Set echo filter coefficient 5",constVal<5>,effectVal}},
|
{0x35, {DIV_CMD_SNES_ECHO_FIR, "35xx: Set echo filter coefficient 5",constVal<5>,effectVal}},
|
||||||
{0x36, {DIV_CMD_SNES_ECHO_FIR, "36xx: Set echo filter coefficient 6",constVal<6>,effectVal}},
|
{0x36, {DIV_CMD_SNES_ECHO_FIR, "36xx: Set echo filter coefficient 6",constVal<6>,effectVal}},
|
||||||
{0x37, {DIV_CMD_SNES_ECHO_FIR, "37xx: Set echo filter coefficient 7",constVal<7>,effectVal}},
|
{0x37, {DIV_CMD_SNES_ECHO_FIR, "37xx: Set echo filter coefficient 7",constVal<7>,effectVal}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{0x10, {DIV_CMD_WAVE, "10xx: Set waveform"}},
|
||||||
|
{0x11, {DIV_CMD_STD_NOISE_MODE, "11xx: Toggle noise mode"}},
|
||||||
|
{0x12, {DIV_CMD_SNES_ECHO, "12xx: Toggle echo on this channel"}},
|
||||||
|
{0x13, {DIV_CMD_SNES_PITCH_MOD, "13xx: Toggle pitch modulation"}},
|
||||||
|
{0x14, {DIV_CMD_SNES_INVERT, "14xy: Toggle invert (x: left; y: right)"}},
|
||||||
|
{0x15, {DIV_CMD_SNES_GAIN_MODE, "15xx: Set envelope mode (0: ADSR, 1: gain/direct, 2: dec, 3: exp, 4: inc, 5: bent)"}},
|
||||||
|
{0x16, {DIV_CMD_SNES_GAIN, "16xx: Set gain (00 to 7F if direct; 00 to 1F otherwise)"}},
|
||||||
|
{0x1d, {DIV_CMD_STD_NOISE_FREQ, "1Dxx: Set noise frequency (00 to 1F)"}},
|
||||||
|
{0x20, {DIV_CMD_FM_AR, "20xx: Set attack (0 to F)"}},
|
||||||
|
{0x21, {DIV_CMD_FM_DR, "21xx: Set decay (0 to 7)"}},
|
||||||
|
{0x22, {DIV_CMD_FM_SL, "22xx: Set sustain (0 to 7)"}},
|
||||||
|
{0x23, {DIV_CMD_FM_RR, "23xx: Set release (00 to 1F)"}},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue