Game Boy: software envelopes, part 1
This commit is contained in:
parent
6bcb3063a5
commit
bccecc4c07
|
@ -590,7 +590,9 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
|
|
||||||
logD("GB data: vol %d dir %d len %d sl %d",ins->gb.envVol,ins->gb.envDir,ins->gb.envLen,ins->gb.soundLen);
|
logD("GB data: vol %d dir %d len %d sl %d",ins->gb.envVol,ins->gb.envDir,ins->gb.envLen,ins->gb.soundLen);
|
||||||
} else if (ds.system[0]==DIV_SYSTEM_GB) {
|
} else if (ds.system[0]==DIV_SYSTEM_GB) {
|
||||||
// try to convert macro to envelope
|
// set software envelope flag
|
||||||
|
ins->gb.softEnv=true;
|
||||||
|
// try to convert macro to envelope in case the user decides to switch to them
|
||||||
if (ins->std.volMacro.len>0) {
|
if (ins->std.volMacro.len>0) {
|
||||||
ins->gb.envVol=ins->std.volMacro.val[0];
|
ins->gb.envVol=ins->std.volMacro.val[0];
|
||||||
if (ins->std.volMacro.val[0]<ins->std.volMacro.val[1]) {
|
if (ins->std.volMacro.val[0]<ins->std.volMacro.val[1]) {
|
||||||
|
@ -600,7 +602,6 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) {
|
||||||
ins->gb.soundLen=ins->std.volMacro.len*2;
|
ins->gb.soundLen=ins->std.volMacro.len*2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addWarning("Game Boy volume macros converted to envelopes. may not be perfect!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,16 @@ void DivPlatformGB::tick(bool sysTick) {
|
||||||
|
|
||||||
for (int i=0; i<4; i++) {
|
for (int i=0; i<4; i++) {
|
||||||
chan[i].std.next();
|
chan[i].std.next();
|
||||||
|
if (chan[i].softEnv) {
|
||||||
|
if (chan[i].std.vol.had) {
|
||||||
|
chan[i].outVol=VOL_SCALE_LINEAR(chan[i].vol&15,MIN(15,chan[i].std.vol.val),15);
|
||||||
|
if (chan[i].outVol<0) chan[i].outVol=0;
|
||||||
|
|
||||||
|
// temporary until zombie mode is implemented
|
||||||
|
chan[i].vol=chan[i].outVol;
|
||||||
|
chan[i].keyOn=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (chan[i].std.arp.had) {
|
if (chan[i].std.arp.had) {
|
||||||
if (i==3) { // noise
|
if (i==3) { // noise
|
||||||
if (chan[i].std.arp.mode) {
|
if (chan[i].std.arp.mode) {
|
||||||
|
@ -189,7 +199,7 @@ void DivPlatformGB::tick(bool sysTick) {
|
||||||
chan[i].duty=chan[i].std.duty.val;
|
chan[i].duty=chan[i].std.duty.val;
|
||||||
if (i!=2) {
|
if (i!=2) {
|
||||||
rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(chan[i].soundLen&63)));
|
rWrite(16+i*5+1,((chan[i].duty&3)<<6)|(63-(chan[i].soundLen&63)));
|
||||||
} else {
|
} else if (!chan[i].softEnv) {
|
||||||
if (parent->song.waveDutyIsVol) {
|
if (parent->song.waveDutyIsVol) {
|
||||||
rWrite(16+i*5+2,gbVolMap[(chan[i].std.duty.val&3)<<2]);
|
rWrite(16+i*5+2,gbVolMap[(chan[i].std.duty.val&3)<<2]);
|
||||||
}
|
}
|
||||||
|
@ -244,11 +254,13 @@ void DivPlatformGB::tick(bool sysTick) {
|
||||||
unsigned short data=ins->gb.hwSeq[chan[i].hwSeqPos].data;
|
unsigned short data=ins->gb.hwSeq[chan[i].hwSeqPos].data;
|
||||||
switch (ins->gb.hwSeq[chan[i].hwSeqPos].cmd) {
|
switch (ins->gb.hwSeq[chan[i].hwSeqPos].cmd) {
|
||||||
case DivInstrumentGB::DIV_GB_HWCMD_ENVELOPE:
|
case DivInstrumentGB::DIV_GB_HWCMD_ENVELOPE:
|
||||||
chan[i].envLen=data&7;
|
if (!chan[i].softEnv) {
|
||||||
chan[i].envDir=(data&8)?1:0;
|
chan[i].envLen=data&7;
|
||||||
chan[i].envVol=(data>>4)&15;
|
chan[i].envDir=(data&8)?1:0;
|
||||||
chan[i].soundLen=data>>8;
|
chan[i].envVol=(data>>4)&15;
|
||||||
chan[i].keyOn=true;
|
chan[i].soundLen=data>>8;
|
||||||
|
chan[i].keyOn=true;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DivInstrumentGB::DIV_GB_HWCMD_SWEEP:
|
case DivInstrumentGB::DIV_GB_HWCMD_SWEEP:
|
||||||
chan[i].sweep=data;
|
chan[i].sweep=data;
|
||||||
|
@ -352,6 +364,7 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
chan[c.chan].hwSeqPos=0;
|
chan[c.chan].hwSeqPos=0;
|
||||||
chan[c.chan].hwSeqDelay=0;
|
chan[c.chan].hwSeqDelay=0;
|
||||||
chan[c.chan].released=false;
|
chan[c.chan].released=false;
|
||||||
|
chan[c.chan].softEnv=ins->gb.softEnv;
|
||||||
chan[c.chan].macroInit(ins);
|
chan[c.chan].macroInit(ins);
|
||||||
if (c.chan==2) {
|
if (c.chan==2) {
|
||||||
if (chan[c.chan].wave<0) {
|
if (chan[c.chan].wave<0) {
|
||||||
|
@ -387,13 +400,15 @@ int DivPlatformGB::dispatch(DivCommand c) {
|
||||||
chan[c.chan].insChanged=true;
|
chan[c.chan].insChanged=true;
|
||||||
if (c.chan!=2) {
|
if (c.chan!=2) {
|
||||||
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_GB);
|
DivInstrument* ins=parent->getIns(chan[c.chan].ins,DIV_INS_GB);
|
||||||
chan[c.chan].envVol=ins->gb.envVol;
|
if (!ins->gb.softEnv) {
|
||||||
chan[c.chan].envLen=ins->gb.envLen;
|
chan[c.chan].envVol=ins->gb.envVol;
|
||||||
chan[c.chan].envDir=ins->gb.envDir;
|
chan[c.chan].envLen=ins->gb.envLen;
|
||||||
chan[c.chan].soundLen=ins->gb.soundLen;
|
chan[c.chan].envDir=ins->gb.envDir;
|
||||||
chan[c.chan].vol=chan[c.chan].envVol;
|
chan[c.chan].soundLen=ins->gb.soundLen;
|
||||||
if (parent->song.gbInsAffectsEnvelope) {
|
chan[c.chan].vol=chan[c.chan].envVol;
|
||||||
rWrite(16+c.chan*5+2,((chan[c.chan].vol<<4))|(chan[c.chan].envLen&7)|((chan[c.chan].envDir&1)<<3));
|
if (parent->song.gbInsAffectsEnvelope) {
|
||||||
|
rWrite(16+c.chan*5+2,((chan[c.chan].vol<<4))|(chan[c.chan].envLen&7)|((chan[c.chan].envDir&1)<<3));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ class DivPlatformGB: public DivDispatch {
|
||||||
struct Channel {
|
struct Channel {
|
||||||
int freq, baseFreq, pitch, pitch2, note, ins;
|
int freq, baseFreq, pitch, pitch2, note, ins;
|
||||||
unsigned char duty, sweep;
|
unsigned char duty, sweep;
|
||||||
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, released;
|
bool active, insChanged, freqChanged, sweepChanged, keyOn, keyOff, inPorta, released, softEnv;
|
||||||
signed char vol, outVol, wave;
|
signed char vol, outVol, wave;
|
||||||
unsigned char envVol, envDir, envLen, soundLen;
|
unsigned char envVol, envDir, envLen, soundLen;
|
||||||
unsigned short hwSeqPos;
|
unsigned short hwSeqPos;
|
||||||
|
@ -56,6 +56,7 @@ class DivPlatformGB: public DivDispatch {
|
||||||
keyOff(false),
|
keyOff(false),
|
||||||
inPorta(false),
|
inPorta(false),
|
||||||
released(false),
|
released(false),
|
||||||
|
softEnv(false),
|
||||||
vol(15),
|
vol(15),
|
||||||
outVol(15),
|
outVol(15),
|
||||||
wave(-1),
|
wave(-1),
|
||||||
|
|
Loading…
Reference in a new issue