NES: envelope and length counter effects
This commit is contained in:
parent
07f247af12
commit
9a1447e392
6 changed files with 100 additions and 8 deletions
|
|
@ -205,6 +205,10 @@ enum DivDispatchCmds {
|
|||
DIV_CMD_SNES_ECHO_FEEDBACK,
|
||||
DIV_CMD_SNES_ECHO_FIR,
|
||||
|
||||
DIV_CMD_NES_ENV_MODE,
|
||||
DIV_CMD_NES_LENGTH,
|
||||
DIV_CMD_NES_COUNT_MODE,
|
||||
|
||||
DIV_ALWAYS_SET_VOLUME, // () -> alwaysSetVol
|
||||
|
||||
DIV_CMD_MAX
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ void DivPlatformNES::tick(bool sysTick) {
|
|||
rWrite(0x4000+i*4,(chan[i].outVol==0)?0:255);
|
||||
chan[i].freqChanged=true;
|
||||
} else {
|
||||
rWrite(0x4000+i*4,0x30|chan[i].outVol|((chan[i].duty&3)<<6));
|
||||
rWrite(0x4000+i*4,(chan[i].envMode<<4)|chan[i].outVol|((chan[i].duty&3)<<6));
|
||||
}
|
||||
}
|
||||
if (chan[i].std.arp.had) {
|
||||
|
|
@ -239,7 +239,7 @@ void DivPlatformNES::tick(bool sysTick) {
|
|||
}
|
||||
}
|
||||
if (i!=2) {
|
||||
rWrite(0x4000+i*4,0x30|chan[i].outVol|((chan[i].duty&3)<<6));
|
||||
rWrite(0x4000+i*4,(chan[i].envMode<<4)|chan[i].outVol|((chan[i].duty&3)<<6));
|
||||
}
|
||||
if (i==3) { // noise
|
||||
chan[i].freqChanged=true;
|
||||
|
|
@ -289,11 +289,11 @@ void DivPlatformNES::tick(bool sysTick) {
|
|||
}
|
||||
if (i==3) { // noise
|
||||
rWrite(0x4002+i*4,(chan[i].duty<<7)|chan[i].freq);
|
||||
rWrite(0x4003+i*4,0xf0);
|
||||
rWrite(0x4003+i*4,(chan[i].len<<3));
|
||||
} else {
|
||||
rWrite(0x4002+i*4,chan[i].freq&0xff);
|
||||
if ((chan[i].prevFreq>>8)!=(chan[i].freq>>8) || i==2) {
|
||||
rWrite(0x4003+i*4,0xf8|(chan[i].freq>>8));
|
||||
rWrite(0x4003+i*4,(chan[i].len<<3)|(chan[i].freq>>8));
|
||||
}
|
||||
if (chan[i].freq!=65535 && chan[i].freq!=0) {
|
||||
chan[i].prevFreq=chan[i].freq;
|
||||
|
|
@ -419,7 +419,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
if (c.chan==2) {
|
||||
rWrite(0x4000+c.chan*4,0xff);
|
||||
} else if (!parent->song.brokenOutVol2) {
|
||||
rWrite(0x4000+c.chan*4,0x30|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
|
||||
rWrite(0x4000+c.chan*4,(chan[c.chan].envMode<<4)|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_NOTE_OFF:
|
||||
|
|
@ -451,7 +451,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
if (c.chan==2) {
|
||||
rWrite(0x4000+c.chan*4,0xff);
|
||||
} else {
|
||||
rWrite(0x4000+c.chan*4,0x30|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
|
||||
rWrite(0x4000+c.chan*4,(chan[c.chan].envMode<<4)|chan[c.chan].vol|((chan[c.chan].duty&3)<<6));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -491,7 +491,7 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
if (c.chan==3) { // noise
|
||||
chan[c.chan].freqChanged=true;
|
||||
} else if (c.chan<2) {
|
||||
rWrite(0x4000+c.chan*4,0x30|(chan[c.chan].active?chan[c.chan].outVol:0)|((chan[c.chan].duty&3)<<6));
|
||||
rWrite(0x4000+c.chan*4,(chan[c.chan].active?((chan[c.chan].envMode<<4)|chan[c.chan].outVol):0x30)|((chan[c.chan].duty&3)<<6));
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_NES_SWEEP:
|
||||
|
|
@ -507,6 +507,24 @@ int DivPlatformNES::dispatch(DivCommand c) {
|
|||
}
|
||||
rWrite(0x4001+(c.chan*4),chan[c.chan].sweep);
|
||||
break;
|
||||
case DIV_CMD_NES_ENV_MODE:
|
||||
chan[c.chan].envMode=c.value&3;
|
||||
if (c.chan==3) { // noise
|
||||
chan[c.chan].freqChanged=true;
|
||||
} else if (c.chan<2) {
|
||||
rWrite(0x4000+c.chan*4,(chan[c.chan].active?((chan[c.chan].envMode<<4)|chan[c.chan].outVol):0x30)|((chan[c.chan].duty&3)<<6));
|
||||
}
|
||||
break;
|
||||
case DIV_CMD_NES_LENGTH:
|
||||
if (c.chan>=4) break;
|
||||
chan[c.chan].len=c.value&0x1f;
|
||||
chan[c.chan].freqChanged=true;
|
||||
chan[c.chan].prevFreq=-1;
|
||||
break;
|
||||
case DIV_CMD_NES_COUNT_MODE:
|
||||
countMode=c.value;
|
||||
rWrite(0x4017,countMode?0x80:0);
|
||||
break;
|
||||
case DIV_CMD_NES_DMC:
|
||||
rWrite(0x4011,c.value&0x7f);
|
||||
break;
|
||||
|
|
@ -572,6 +590,7 @@ void DivPlatformNES::forceIns() {
|
|||
}
|
||||
rWrite(0x4001,chan[0].sweep);
|
||||
rWrite(0x4005,chan[1].sweep);
|
||||
rWrite(0x4017,countMode?0x80:0);
|
||||
}
|
||||
|
||||
void* DivPlatformNES::getChanState(int ch) {
|
||||
|
|
@ -615,6 +634,7 @@ void DivPlatformNES::reset() {
|
|||
dpcmBank=0;
|
||||
dpcmMode=false;
|
||||
goingToLoop=false;
|
||||
countMode=false;
|
||||
|
||||
if (useNP) {
|
||||
nes1_NP->Reset();
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@
|
|||
class DivPlatformNES: public DivDispatch {
|
||||
struct Channel {
|
||||
int freq, baseFreq, pitch, pitch2, prevFreq, note, ins;
|
||||
unsigned char duty, sweep;
|
||||
unsigned char duty, sweep, envMode, len;
|
||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, furnaceDac;
|
||||
signed char vol, outVol, wave;
|
||||
DivMacroInt std;
|
||||
|
|
@ -46,6 +46,8 @@ class DivPlatformNES: public DivDispatch {
|
|||
ins(-1),
|
||||
duty(0),
|
||||
sweep(8),
|
||||
envMode(3),
|
||||
len(0x1f),
|
||||
active(false),
|
||||
insChanged(true),
|
||||
freqChanged(false),
|
||||
|
|
@ -74,6 +76,7 @@ class DivPlatformNES: public DivDispatch {
|
|||
bool dacAntiClickOn;
|
||||
bool useNP;
|
||||
bool goingToLoop;
|
||||
bool countMode;
|
||||
struct NESAPU* nes;
|
||||
xgm::NES_APU* nes1_NP;
|
||||
xgm::NES_DMC* nes2_NP;
|
||||
|
|
|
|||
|
|
@ -206,6 +206,10 @@ const char* cmdName[]={
|
|||
"SNES_ECHO_FEEDBACK",
|
||||
"SNES_ECHO_FIR",
|
||||
|
||||
"DIV_CMD_NES_ENV_MODE",
|
||||
"DIV_CMD_NES_LENGTH",
|
||||
"DIV_CMD_NES_COUNT_MODE",
|
||||
|
||||
"ALWAYS_SET_VOLUME"
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -693,6 +693,9 @@ void DivEngine::registerSystems() {
|
|||
{0x12, {DIV_CMD_STD_NOISE_MODE, "12xx: Set duty cycle/noise mode (pulse: 0 to 3; noise: 0 or 1)"}},
|
||||
{0x13, {DIV_CMD_NES_SWEEP, "13xy: Sweep up (x: time; y: shift)",constVal<0>,effectVal}},
|
||||
{0x14, {DIV_CMD_NES_SWEEP, "14xy: Sweep down (x: time; y: shift)",constVal<1>,effectVal}},
|
||||
{0x15, {DIV_CMD_NES_ENV_MODE, "15xx: Set envelope mode (0: envelope, 1: length, 2: looping, 3: constant)"}},
|
||||
{0x16, {DIV_CMD_NES_LENGTH, "16xx: Set length counter (refer to manual for a list of values)"}},
|
||||
{0x17, {DIV_CMD_NES_COUNT_MODE, "17xx: Set frame counter mode (0: 4-step, 1: 5-step)"}},
|
||||
{0x18, {DIV_CMD_SAMPLE_MODE, "18xx: Select PCM/DPCM mode (0: PCM; 1: DPCM)"}}
|
||||
}
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue