diff --git a/src/engine/engine.h b/src/engine/engine.h index 4f11e82e..c433def8 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -46,8 +46,8 @@ #define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock(); #define BUSY_END isBusy.unlock(); softLocked=false; -#define DIV_VERSION "dev108" -#define DIV_ENGINE_VERSION 108 +#define DIV_VERSION "dev109" +#define DIV_ENGINE_VERSION 109 // for imports #define DIV_VERSION_MOD 0xff01 diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 838e1384..9f1f5fff 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -554,6 +554,15 @@ void DivInstrument::putInsData(SafeWriter* w) { w->writeC(es5506.envelope.k2Ramp); w->writeC(es5506.envelope.k1Slow); w->writeC(es5506.envelope.k2Slow); + + // SNES + w->writeC(snes.useEnv); + w->writeC(snes.gainMode); + w->writeC(snes.gain); + w->writeC(snes.a); + w->writeC(snes.d); + w->writeC(snes.s); + w->writeC(snes.r); blockEndSeek=w->tell(); w->seek(blockStartSeek,SEEK_SET); @@ -1140,6 +1149,17 @@ DivDataErrors DivInstrument::readInsData(SafeReader& reader, short version) { es5506.envelope.k2Slow=reader.readC(); } + // SNES + if (version>=109) { + snes.useEnv=reader.readC(); + snes.gainMode=(DivInstrumentSNES::GainMode)reader.readC(); + snes.gain=reader.readC(); + snes.a=reader.readC(); + snes.d=reader.readC(); + snes.s=reader.readC(); + snes.r=reader.readC(); + } + return DIV_DATA_SUCCESS; } diff --git a/src/engine/instrument.h b/src/engine/instrument.h index 32c03f45..da6d0841 100644 --- a/src/engine/instrument.h +++ b/src/engine/instrument.h @@ -501,6 +501,28 @@ struct DivInstrumentES5506 { envelope(Envelope()) {} }; +struct DivInstrumentSNES { + enum GainMode: unsigned char { + GAIN_MODE_DIRECT=0, + GAIN_MODE_DEC_LINEAR=4, + GAIN_MODE_DEC_LOG=5, + GAIN_MODE_INC_LINEAR=6, + GAIN_MODE_INC_INVLOG=7 + }; + bool useEnv; + GainMode gainMode; + unsigned char gain; + unsigned char a, d, s, r; + DivInstrumentSNES(): + useEnv(true), + gainMode(GAIN_MODE_DIRECT), + gain(127), + a(15), + d(7), + s(7), + r(0) {} +}; + struct DivInstrument { String name; bool mode; @@ -516,6 +538,7 @@ struct DivInstrument { DivInstrumentWaveSynth ws; DivInstrumentSoundUnit su; DivInstrumentES5506 es5506; + DivInstrumentSNES snes; /** * save the instrument to a SafeWriter. diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index f928e1f8..d09c8e2e 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -3373,6 +3373,7 @@ void FurnaceGUI::drawInsEdit() { } if (ins->type==DIV_INS_AMIGA || ins->type==DIV_INS_SU || + ins->type==DIV_INS_SNES || ins->type==DIV_INS_ES5506) if (ImGui::BeginTabItem((ins->type==DIV_INS_SU)?"Sound Unit":"Sample")) { String sName; if (ins->amiga.initSample<0 || ins->amiga.initSample>=e->song.sampleLen) { @@ -3668,6 +3669,101 @@ void FurnaceGUI::drawInsEdit() { ImGui::EndTabItem(); } } + if (ins->type==DIV_INS_SNES) if (ImGui::BeginTabItem("SNES")) { + P(ImGui::Checkbox("Use envelope",&ins->snes.useEnv)); + ImVec2 sliderSize=ImVec2(20.0f*dpiScale,128.0*dpiScale); + if (ins->snes.useEnv) { + if (ImGui::BeginTable("SNESEnvParams",5,ImGuiTableFlags_NoHostExtendX)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed,sliderSize.x); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,sliderSize.x); + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthFixed,sliderSize.x); + ImGui::TableSetupColumn("c3",ImGuiTableColumnFlags_WidthFixed,sliderSize.x); + ImGui::TableSetupColumn("c4",ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + CENTER_TEXT("A"); + ImGui::TextUnformatted("A"); + ImGui::TableNextColumn(); + CENTER_TEXT("D"); + ImGui::TextUnformatted("D"); + ImGui::TableNextColumn(); + CENTER_TEXT("S"); + ImGui::TextUnformatted("S"); + ImGui::TableNextColumn(); + CENTER_TEXT("R"); + ImGui::TextUnformatted("R"); + ImGui::TableNextColumn(); + CENTER_TEXT("Envelope"); + ImGui::TextUnformatted("Envelope"); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + P(CWVSliderScalar("##Attack",sliderSize,ImGuiDataType_U8,&ins->snes.a,&_ZERO,&_FIFTEEN)); + ImGui::TableNextColumn(); + P(CWVSliderScalar("##Decay",sliderSize,ImGuiDataType_U8,&ins->snes.d,&_ZERO,&_SEVEN)); + ImGui::TableNextColumn(); + P(CWVSliderScalar("##Sustain",sliderSize,ImGuiDataType_U8,&ins->snes.s,&_ZERO,&_SEVEN)); + ImGui::TableNextColumn(); + P(CWVSliderScalar("##Release",sliderSize,ImGuiDataType_U8,&ins->snes.r,&_ZERO,&_THIRTY_ONE)); + ImGui::TableNextColumn(); + drawFMEnv(0,ins->snes.a+1,1+ins->snes.d*2,ins->snes.r,ins->snes.r,(14-ins->snes.s*2),(ins->snes.r==0),0,0,7,16,ImVec2(ImGui::GetContentRegionAvail().x,sliderSize.y),ins->type); + + ImGui::EndTable(); + } + } else { + if (ImGui::BeginTable("SNESGainParams",3,ImGuiTableFlags_NoHostExtendX)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); + ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,sliderSize.x); + ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + CENTER_TEXT("Gain Mode"); + ImGui::TextUnformatted("Gain Mode"); + ImGui::TableNextColumn(); + CENTER_TEXT("Gain"); + ImGui::TextUnformatted("Gain"); + ImGui::TableNextColumn(); + CENTER_TEXT("Envelope"); + ImGui::TextUnformatted("Envelope"); + + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + if (ImGui::RadioButton("Direct",ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DIRECT)) { + ins->snes.gainMode=DivInstrumentSNES::GAIN_MODE_DIRECT; + PARAMETER; + } + if (ImGui::RadioButton("Decrease (linear)",ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DEC_LINEAR)) { + ins->snes.gainMode=DivInstrumentSNES::GAIN_MODE_DEC_LINEAR; + PARAMETER; + } + if (ImGui::RadioButton("Decrease (logarithmic)",ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DEC_LOG)) { + ins->snes.gainMode=DivInstrumentSNES::GAIN_MODE_DEC_LOG; + PARAMETER; + } + if (ImGui::RadioButton("Increase (linear)",ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_INC_LINEAR)) { + ins->snes.gainMode=DivInstrumentSNES::GAIN_MODE_INC_LINEAR; + PARAMETER; + } + if (ImGui::RadioButton("Increase (bent line)",ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_INC_INVLOG)) { + ins->snes.gainMode=DivInstrumentSNES::GAIN_MODE_INC_INVLOG; + PARAMETER; + } + + ImGui::TableNextColumn(); + unsigned char gainMax=(ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DIRECT)?127:31; + if (ins->snes.gain>gainMax) ins->snes.gain=gainMax; + P(CWVSliderScalar("##Gain",sliderSize,ImGuiDataType_U8,&ins->snes.gain,&_ZERO,&gainMax)); + + ImGui::TableNextColumn(); + ImGui::Text("Envelope goes here..."); + + ImGui::EndTable(); + } + } + ImGui::EndTabItem(); + } if (ins->type==DIV_INS_GB || (ins->type==DIV_INS_AMIGA && ins->amiga.useWave) || ins->type==DIV_INS_X1_010 || @@ -3676,6 +3772,7 @@ void FurnaceGUI::drawInsEdit() { ins->type==DIV_INS_SWAN || ins->type==DIV_INS_PCE || ins->type==DIV_INS_SCC || + ins->type==DIV_INS_SNES || ins->type==DIV_INS_NAMCO) { if (ImGui::BeginTabItem("Wavetable")) { if (ImGui::Checkbox("Enable synthesizer",&ins->ws.enabled)) {