dev118 - SNES true sustain
This commit is contained in:
parent
6f1a41de1e
commit
6028523eaf
|
@ -32,6 +32,8 @@ these fields are 0 in format versions prior to 100 (0.6pre1).
|
||||||
|
|
||||||
the format versions are:
|
the format versions are:
|
||||||
|
|
||||||
|
- 118: Furnace dev118
|
||||||
|
- 117: Furnace dev117
|
||||||
- 116: Furnace 0.6pre1.5
|
- 116: Furnace 0.6pre1.5
|
||||||
- 115: Furnace dev115
|
- 115: Furnace dev115
|
||||||
- 114: Furnace dev114
|
- 114: Furnace dev114
|
||||||
|
@ -905,6 +907,7 @@ size | description
|
||||||
1 | attack
|
1 | attack
|
||||||
1 | decay
|
1 | decay
|
||||||
1 | sustain
|
1 | sustain
|
||||||
|
| - bit 3: sustain mode (>=118)
|
||||||
1 | release
|
1 | release
|
||||||
--- | **macro speeds/delays** (>=111)
|
--- | **macro speeds/delays** (>=111)
|
||||||
1 | volume macro speed
|
1 | volume macro speed
|
||||||
|
|
|
@ -46,8 +46,8 @@
|
||||||
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
#define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock();
|
||||||
#define BUSY_END isBusy.unlock(); softLocked=false;
|
#define BUSY_END isBusy.unlock(); softLocked=false;
|
||||||
|
|
||||||
#define DIV_VERSION "dev117"
|
#define DIV_VERSION "dev118"
|
||||||
#define DIV_ENGINE_VERSION 117
|
#define DIV_ENGINE_VERSION 118
|
||||||
// for imports
|
// for imports
|
||||||
#define DIV_VERSION_MOD 0xff01
|
#define DIV_VERSION_MOD 0xff01
|
||||||
#define DIV_VERSION_FC 0xff02
|
#define DIV_VERSION_FC 0xff02
|
||||||
|
|
|
@ -559,13 +559,12 @@ void DivInstrument::putInsData(SafeWriter* w) {
|
||||||
w->writeC(es5506.envelope.k2Slow);
|
w->writeC(es5506.envelope.k2Slow);
|
||||||
|
|
||||||
// SNES
|
// SNES
|
||||||
// @tildearrow please update this
|
|
||||||
w->writeC(snes.useEnv);
|
w->writeC(snes.useEnv);
|
||||||
w->writeC(0);
|
w->writeC(snes.gainMode);
|
||||||
w->writeC(0);
|
w->writeC(snes.gain);
|
||||||
w->writeC(snes.a);
|
w->writeC(snes.a);
|
||||||
w->writeC(snes.d);
|
w->writeC(snes.d);
|
||||||
w->writeC(snes.s);
|
w->writeC((snes.s&7)|(snes.sus?8:0));
|
||||||
w->writeC(snes.r);
|
w->writeC(snes.r);
|
||||||
|
|
||||||
// macro speed/delay
|
// macro speed/delay
|
||||||
|
@ -1259,11 +1258,13 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) {
|
||||||
// SNES
|
// SNES
|
||||||
if (version>=109) {
|
if (version>=109) {
|
||||||
snes.useEnv=reader.readC();
|
snes.useEnv=reader.readC();
|
||||||
reader.readC();
|
snes.gainMode=(DivInstrumentSNES::GainMode)reader.readC();
|
||||||
reader.readC();
|
snes.gain=reader.readC();
|
||||||
snes.a=reader.readC();
|
snes.a=reader.readC();
|
||||||
snes.d=reader.readC();
|
snes.d=reader.readC();
|
||||||
snes.s=reader.readC();
|
snes.s=reader.readC();
|
||||||
|
snes.sus=snes.s&8;
|
||||||
|
snes.s&=7;
|
||||||
snes.r=reader.readC();
|
snes.r=reader.readC();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -527,12 +527,13 @@ struct DivInstrumentSNES {
|
||||||
GAIN_MODE_INC_LINEAR=6,
|
GAIN_MODE_INC_LINEAR=6,
|
||||||
GAIN_MODE_INC_INVLOG=7
|
GAIN_MODE_INC_INVLOG=7
|
||||||
};
|
};
|
||||||
bool useEnv;
|
bool useEnv, sus;
|
||||||
GainMode gainMode;
|
GainMode gainMode;
|
||||||
unsigned char gain;
|
unsigned char gain;
|
||||||
unsigned char a, d, s, r;
|
unsigned char a, d, s, r;
|
||||||
DivInstrumentSNES():
|
DivInstrumentSNES():
|
||||||
useEnv(true),
|
useEnv(true),
|
||||||
|
sus(false),
|
||||||
gainMode(GAIN_MODE_DIRECT),
|
gainMode(GAIN_MODE_DIRECT),
|
||||||
gain(127),
|
gain(127),
|
||||||
a(15),
|
a(15),
|
||||||
|
|
|
@ -208,7 +208,9 @@ void DivPlatformSNES::tick(bool sysTick) {
|
||||||
chan[i].keyOn=false;
|
chan[i].keyOn=false;
|
||||||
}
|
}
|
||||||
if (chan[i].keyOff) {
|
if (chan[i].keyOff) {
|
||||||
koff|=(1<<i);
|
if (!chan[i].state.sus) {
|
||||||
|
koff|=(1<<i);
|
||||||
|
}
|
||||||
chan[i].keyOff=false;
|
chan[i].keyOff=false;
|
||||||
}
|
}
|
||||||
if (chan[i].freqChanged) {
|
if (chan[i].freqChanged) {
|
||||||
|
@ -296,6 +298,9 @@ 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;
|
||||||
|
}
|
||||||
|
chan[c.chan].active=true;
|
||||||
|
if (chan[c.chan].insChanged || chan[c.chan].state.sus) {
|
||||||
writeEnv(c.chan);
|
writeEnv(c.chan);
|
||||||
}
|
}
|
||||||
if (c.value!=DIV_NOTE_NULL) {
|
if (c.value!=DIV_NOTE_NULL) {
|
||||||
|
@ -303,19 +308,30 @@ int DivPlatformSNES::dispatch(DivCommand c) {
|
||||||
chan[c.chan].freqChanged=true;
|
chan[c.chan].freqChanged=true;
|
||||||
chan[c.chan].note=c.value;
|
chan[c.chan].note=c.value;
|
||||||
}
|
}
|
||||||
chan[c.chan].active=true;
|
|
||||||
chan[c.chan].keyOn=true;
|
chan[c.chan].keyOn=true;
|
||||||
chan[c.chan].macroInit(ins);
|
chan[c.chan].macroInit(ins);
|
||||||
chan[c.chan].insChanged=false;
|
chan[c.chan].insChanged=false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DIV_CMD_NOTE_OFF:
|
case DIV_CMD_NOTE_OFF:
|
||||||
chan[c.chan].sample=-1;
|
|
||||||
chan[c.chan].active=false;
|
chan[c.chan].active=false;
|
||||||
chan[c.chan].keyOff=true;
|
chan[c.chan].keyOff=true;
|
||||||
chan[c.chan].macroInit(NULL);
|
chan[c.chan].keyOn=false;
|
||||||
|
if (chan[c.chan].state.sus) {
|
||||||
|
writeEnv(c.chan);
|
||||||
|
} else {
|
||||||
|
chan[c.chan].macroInit(NULL);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case DIV_CMD_NOTE_OFF_ENV:
|
case DIV_CMD_NOTE_OFF_ENV:
|
||||||
|
chan[c.chan].active=false;
|
||||||
|
chan[c.chan].keyOff=true;
|
||||||
|
chan[c.chan].keyOn=false;
|
||||||
|
if (chan[c.chan].state.sus) {
|
||||||
|
writeEnv(c.chan);
|
||||||
|
}
|
||||||
|
chan[c.chan].std.release();
|
||||||
|
break;
|
||||||
case DIV_CMD_ENV_RELEASE:
|
case DIV_CMD_ENV_RELEASE:
|
||||||
chan[c.chan].std.release();
|
chan[c.chan].std.release();
|
||||||
break;
|
break;
|
||||||
|
@ -537,7 +553,11 @@ void DivPlatformSNES::writeOutVol(int ch) {
|
||||||
void DivPlatformSNES::writeEnv(int ch) {
|
void DivPlatformSNES::writeEnv(int ch) {
|
||||||
if (chan[ch].state.useEnv) {
|
if (chan[ch].state.useEnv) {
|
||||||
chWrite(ch,5,chan[ch].state.a|(chan[ch].state.d<<4)|0x80);
|
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));
|
if (chan[ch].state.sus && chan[ch].active) {
|
||||||
|
chWrite(ch,6,chan[ch].state.s<<5);
|
||||||
|
} else {
|
||||||
|
chWrite(ch,6,chan[ch].state.r|(chan[ch].state.s<<5));
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
chWrite(ch,5,0);
|
chWrite(ch,5,0);
|
||||||
switch (chan[ch].state.gainMode) {
|
switch (chan[ch].state.gainMode) {
|
||||||
|
|
|
@ -4066,6 +4066,7 @@ void FurnaceGUI::drawInsEdit() {
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
ImGui::Checkbox("Make sustain effective",&ins->snes.sus);
|
||||||
} else {
|
} else {
|
||||||
if (ImGui::BeginTable("SNESGainParams",3,ImGuiTableFlags_NoHostExtendX)) {
|
if (ImGui::BeginTable("SNESGainParams",3,ImGuiTableFlags_NoHostExtendX)) {
|
||||||
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
|
Loading…
Reference in New Issue