From 1cbb61ec27aae8e0ebd62223a916c3c83a4cefb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=93=D0=B5=D1=80=D0=BC=D0=B0=D0=BD=20=D0=A1=D0=B5=D0=BC?= =?UTF-8?q?=D0=B5=D0=BD=D0=BE=D0=B2?= Date: Thu, 24 Aug 2023 19:08:06 +0300 Subject: [PATCH 01/23] More optimize inserts using reserve() Signed-off-by: German Semenov --- src/engine/engine.cpp | 14 ++++++++++--- src/engine/export/amigaValidation.cpp | 1 + src/engine/fileOps.cpp | 30 +++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 3b1d9d6c..05392127 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -950,12 +950,13 @@ bool DivEngine::addSystem(DivSystem which) { unsigned int outs=disCont[i].dispatch->getOutputCount(); if (outs>16) outs=16; if (outs<2) { + song.patchbay.reserve(DIV_MAX_OUTPUTS); for (unsigned int j=0; j& where) { BUSY_BEGIN; where.clear(); + where.reserve(cmdStream.size()); for (DivCommand& i: cmdStream) { where.push_back(i); } @@ -2822,23 +2827,26 @@ void DivEngine::autoPatchbay() { unsigned int outs=disCont[i].dispatch->getOutputCount(); if (outs>16) outs=16; if (outs<2) { + song.patchbay.reserve(DIV_MAX_OUTPUTS); for (unsigned int j=0; j DivExportAmigaValidation::go(DivEngine* e) { } // finish + ret.reserve(5); ret.push_back(DivROMExportOutput("sbook.bin",sbook)); ret.push_back(DivROMExportOutput("wbook.bin",wbook)); ret.push_back(DivROMExportOutput("sample.bin",sample)); diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index 1465c816..746f5904 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -342,6 +342,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { ds.insLen=16; } logI("reading instruments (%d)...",ds.insLen); + ds.ins.reserve(ds.insLen); for (int i=0; i0x0b) { ds.waveLen=(unsigned char)reader.readC(); logI("reading wavetables (%d)...",ds.waveLen); + ds.wave.reserve(ds.waveLen); for (int i=0; ilen=(unsigned char)reader.readI(); @@ -838,6 +840,7 @@ bool DivEngine::loadDMF(unsigned char* file, size_t len) { // it appears this byte stored the YMU759 sample rate ymuSampleRate=reader.readC(); } + ds.sample.reserve(ds.sampleLen); for (int i=0; iordersLen); @@ -2345,6 +2349,7 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { // patchbay unsigned int conns=reader.readI(); + ds.patchbay.reserve(conns); for (unsigned int i=0; i=95) { + ds.subsong.reserve(numberOfSubSongs); for (int i=0; idepth=DIV_SAMPLE_DEPTH_8BIT; @@ -3373,6 +3384,7 @@ bool DivEngine::loadMod(unsigned char* file, size_t len) { } // instrument creation + ds.ins.reserve(insCount); for(int i=0; itype=DIV_INS_AMIGA; @@ -3651,6 +3663,7 @@ bool DivEngine::loadS3M(unsigned char* file, size_t len) { } // load instruments/samples + ds.ins.reserve(ds.insLen); for (int i=0; idepth=DIV_SAMPLE_DEPTH_8BIT; @@ -3981,6 +3999,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) { return false; } logD("reading wavetables..."); + ds.wave.reserve(80); for (int i=0; i<80; i++) { DivWavetable* w=new DivWavetable; w->min=0; @@ -4009,6 +4028,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) { } } else { // generate preset waves + ds.wave.reserve(48); for (int i=0; i<48; i++) { DivWavetable* w=new DivWavetable; generateFCPresetWave(i,w); @@ -4156,6 +4176,7 @@ bool DivEngine::loadFC(unsigned char* file, size_t len) { // volume sequence ins->std.volMacro.len=0; + ds.ins.reserve(64 - 5); for (int j=5; j<64; j++) { loopMap[j]=ins->std.volMacro.len; if (m.val[j]==0xe1) { // end @@ -4553,6 +4574,7 @@ bool DivEngine::loadFTM(unsigned char* file, size_t len) { CHECK_BLOCK_VERSION(4); unsigned char totalSongs=reader.readC(); logV("%d songs:",totalSongs+1); + ds.subsong.reserve(totalSongs); for (int i=0; i<=totalSongs; i++) { String subSongName=reader.readString(); ds.subsong.push_back(new DivSubSong); @@ -5087,12 +5109,14 @@ DivDataErrors DivEngine::readAssetDirData(SafeReader& reader, std::vectorseek(0,SEEK_END); /// SUBSONGS + subSongPtr.reserve(song.subsong.size() - 1); for (subSongIndex=1; subSongIndextell()); @@ -5486,6 +5511,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) { } /// CHIP FLAGS + sysFlagsPtr.reserve(song.systemLen); for (int i=0; itell()); @@ -5522,6 +5549,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) { } /// WAVETABLE + wavePtr.reserve(song.waveLen); for (int i=0; itell()); @@ -5529,6 +5557,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) { } /// SAMPLE + samplePtr.reserve(song.sampleLen); for (int i=0; itell()); @@ -5536,6 +5565,7 @@ SafeWriter* DivEngine::saveFur(bool notPrimary, bool newPatternFormat) { } /// PATTERN + patPtr.reserve(patsToWrite.size()); for (PatToWrite& i: patsToWrite) { DivPattern* pat=song.subsong[i.subsong]->pat[i.chan].getPattern(i.pat,false); patPtr.push_back(w->tell()); From 6e28a8b01ca2f8d00ba398af4a61ac56ad40fe18 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 24 Aug 2023 14:23:00 -0500 Subject: [PATCH 02/23] WaveSynth: fix distorted sound issue #1411 --- src/engine/waveSynth.cpp | 28 +++++++++++++++++++++++----- src/engine/waveSynth.h | 3 ++- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/engine/waveSynth.cpp b/src/engine/waveSynth.cpp index cdb69688..6fe34f26 100644 --- a/src/engine/waveSynth.cpp +++ b/src/engine/waveSynth.cpp @@ -22,6 +22,22 @@ #include "instrument.h" #include "../ta-log.h" +inline bool effectOnlyAltersOutput(unsigned char effect) { + switch (effect) { + case DIV_WS_NONE: + case DIV_WS_INVERT: + case DIV_WS_ADD: + case DIV_WS_SUBTRACT: + case DIV_WS_AVERAGE: + return true; + break; + default: + return false; + break; + } + return false; +} + bool DivWaveSynth::activeChanged() { if (activeChangedB) { activeChangedB=false; @@ -211,19 +227,21 @@ void DivWaveSynth::setWidth(int val) { if (width>256) width=256; } -void DivWaveSynth::changeWave1(int num) { +#define SHALL_UPDATE_OUT (!state.enabled || force || (state.enabled && effectOnlyAltersOutput(state.effect))) + +void DivWaveSynth::changeWave1(int num, bool force) { DivWavetable* w1=e->getWave(num); if (width<1) return; for (int i=0; imax<1 || w1->len<1) { wave1[i]=0; - output[i]=0; + if (SHALL_UPDATE_OUT) output[i]=0; } else { int data=w1->data[i*w1->len/width]*height/w1->max; if (data<0) data=0; if (data>height) data=height; wave1[i]=data; - output[i]=data; + if (SHALL_UPDATE_OUT) output[i]=data; } } first=true; @@ -280,9 +298,9 @@ void DivWaveSynth::init(DivInstrument* which, int w, int h, bool insChanged) { divCounter=0; subDivCounter=0; - changeWave1(state.wave1); + changeWave1(state.wave1,true); changeWave2(state.wave2); - tick(true); + //tick(true); // ??? first=true; } } diff --git a/src/engine/waveSynth.h b/src/engine/waveSynth.h index 81a3cbe1..21b6055f 100644 --- a/src/engine/waveSynth.h +++ b/src/engine/waveSynth.h @@ -55,8 +55,9 @@ class DivWaveSynth { /** * change the first wave. * @param num wavetable number. + * @param force whether to force overwriting the current wave. */ - void changeWave1(int num); + void changeWave1(int num, bool force=false); /** * change the second wave. * @param num wavetable number. From 9bf736a51301e253fb80765ab2e4e917db24c4a4 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 24 Aug 2023 14:52:18 -0500 Subject: [PATCH 03/23] GUI: tweak SNES ins editor --- src/gui/insEdit.cpp | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 562c8222..6c12a647 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -5166,10 +5166,9 @@ void FurnaceGUI::drawInsEdit() { ins->snes.sus=3; } } else { - if (ImGui::BeginTable("SNESGainParams",3,ImGuiTableFlags_NoHostExtendX)) { - ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthFixed); + if (ImGui::BeginTable("SNESGainParams",2,ImGuiTableFlags_NoHostExtendX)) { + ImGui::TableSetupColumn("c0",ImGuiTableColumnFlags_WidthStretch); ImGui::TableSetupColumn("c1",ImGuiTableColumnFlags_WidthFixed,sliderSize.x); - ImGui::TableSetupColumn("c2",ImGuiTableColumnFlags_WidthStretch); ImGui::TableNextRow(); ImGui::TableNextColumn(); @@ -5178,9 +5177,6 @@ void FurnaceGUI::drawInsEdit() { ImGui::TableNextColumn(); CENTER_TEXT("Gain"); ImGui::TextUnformatted("Gain"); - ImGui::TableNextColumn(); - CENTER_TEXT("Envelope"); - ImGui::TextUnformatted("Envelope"); ImGui::TableNextRow(); ImGui::TableNextColumn(); @@ -5210,11 +5206,11 @@ void FurnaceGUI::drawInsEdit() { if (ins->snes.gain>gainMax) ins->snes.gain=gainMax; P(CWVSliderScalar("##Gain",sliderSize,ImGuiDataType_U8,&ins->snes.gain,&_ZERO,&gainMax)); rightClickable - ImGui::TableNextColumn(); - ImGui::Text("Envelope goes here..."); - ImGui::EndTable(); } + if (ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DEC_LINEAR || ins->snes.gainMode==DivInstrumentSNES::GAIN_MODE_DEC_LOG) { + ImGui::TextWrapped("using decrease modes will not produce any sound at all, unless you know what you are doing.\nit is recommended to use the Gain macro for decrease instead."); + } } ImGui::EndTabItem(); } From a31b847f32434e308fb93587983668887d3988c4 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 24 Aug 2023 14:59:17 -0500 Subject: [PATCH 04/23] GUI: don't show wave macro for beeper ins --- src/gui/insEdit.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 6c12a647..c34e80d3 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -5697,6 +5697,7 @@ void FurnaceGUI::drawInsEdit() { if (ins->type==DIV_INS_ES5506) waveMax=0; if (ins->type==DIV_INS_GA20) waveMax=0; if (ins->type==DIV_INS_K053260) waveMax=0; + if (ins->type==DIV_INS_BEEPER) waveMax=0; if (ins->type==DIV_INS_POKEMINI) waveMax=0; if (ins->type==DIV_INS_TED) waveMax=0; if (ins->type==DIV_INS_C140) waveMax=0; From f5f1a2948601da360fa927573ba243319afb4a15 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 24 Aug 2023 15:28:04 -0500 Subject: [PATCH 05/23] macroInt fixes issue #1412 --- src/engine/macroInt.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index e06f61b5..769a43a4 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -56,6 +56,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic has=false; return; } + if (released && type==1) delay=0; if (delay>0) { delay--; if (!linger) had=false; @@ -404,13 +405,16 @@ void DivMacroInt::init(DivInstrument* which) { if ((macroSource[i]->open&6)==4) { hasRelease=false; } else if ((macroSource[i]->open&6)==2) { - hasRelease=true; + if (macroSource[i]->val[8]>0) { + hasRelease=true; + } } else { hasRelease=(macroSource[i]->rellen); } } else { hasRelease=false; } + if (hasRelease) break; } } From 2b007a03e0b6f083e11493fa1a78ccce594c4b00 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 24 Aug 2023 15:33:53 -0500 Subject: [PATCH 06/23] code style --- src/engine/engine.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 05392127..3e0c7c8f 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -303,7 +303,7 @@ void DivEngine::notifyWaveChange(int wave) { } int DivEngine::loadSampleROM(String path, ssize_t expectedSize, unsigned char*& ret) { - ret = NULL; + ret=NULL; if (path.empty()) { return 0; } @@ -358,7 +358,7 @@ int DivEngine::loadSampleROM(String path, ssize_t expectedSize, unsigned char*& return -1; } fclose(f); - ret = file; + ret=file; return 0; } @@ -385,10 +385,10 @@ int DivEngine::loadSampleROMs() { delete[] mu5ROM; mu5ROM=NULL; } - int error = 0; - error += loadSampleROM(getConfString("yrw801Path",""), 0x200000, yrw801ROM); - error += loadSampleROM(getConfString("tg100Path",""), 0x200000, tg100ROM); - error += loadSampleROM(getConfString("mu5Path",""), 0x200000, mu5ROM); + int error=0; + error+=loadSampleROM(getConfString("yrw801Path",""), 0x200000, yrw801ROM); + error+=loadSampleROM(getConfString("tg100Path",""), 0x200000, tg100ROM); + error+=loadSampleROM(getConfString("mu5Path",""), 0x200000, mu5ROM); return error; } @@ -1066,7 +1066,7 @@ bool DivEngine::swapSystem(int src, int dest, bool preserveOrder) { swapList.reserve(song.systemLen); for (int i=0; i Date: Thu, 24 Aug 2023 15:34:16 -0500 Subject: [PATCH 07/23] NFD click callback should return S_OK on OK --- extern/nfd-modified/src/nfd_win.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extern/nfd-modified/src/nfd_win.cpp b/extern/nfd-modified/src/nfd_win.cpp index c60f7a75..3bded25c 100644 --- a/extern/nfd-modified/src/nfd_win.cpp +++ b/extern/nfd-modified/src/nfd_win.cpp @@ -61,7 +61,7 @@ class NFDWinEvents: public IFileDialogEvents { return ret; } - IFACEMETHODIMP OnFileOk(IFileDialog*) { return E_NOTIMPL; } + IFACEMETHODIMP OnFileOk(IFileDialog*) { return S_OK; } IFACEMETHODIMP OnFolderChange(IFileDialog*) { return E_NOTIMPL; } IFACEMETHODIMP OnFolderChanging(IFileDialog*, IShellItem*) { return E_NOTIMPL; } IFACEMETHODIMP OnOverwrite(IFileDialog*, IShellItem*, FDE_OVERWRITE_RESPONSE*) { return E_NOTIMPL; } From 06840de4c7bad78c1ff1fdeb6dbffa095477acea Mon Sep 17 00:00:00 2001 From: tildearrow Date: Thu, 24 Aug 2023 20:22:41 -0500 Subject: [PATCH 08/23] fix the macroInt fixes --- src/engine/macroInt.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 769a43a4..94ec602c 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -402,19 +402,14 @@ void DivMacroInt::init(DivInstrument* which) { if (macroSource[i]!=NULL) { macroList[i]->prepare(*macroSource[i],e); // check ADSR mode - if ((macroSource[i]->open&6)==4) { - hasRelease=false; - } else if ((macroSource[i]->open&6)==2) { + if ((macroSource[i]->open&6)==2) { if (macroSource[i]->val[8]>0) { hasRelease=true; } - } else { - hasRelease=(macroSource[i]->rellen); + } else if (macroSource[i]->rellen) { + hasRelease=true; } - } else { - hasRelease=false; } - if (hasRelease) break; } } From c3b5004e6698e2903a3bb9f006d29e065a8de0f2 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 25 Aug 2023 03:38:17 -0500 Subject: [PATCH 09/23] fix TL macro compat for ADSR/LFO --- src/engine/instrument.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 34a77f5e..7dabac9a 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -3329,8 +3329,14 @@ DivDataErrors DivInstrument::readInsDataOld(SafeReader &reader, short version) { // <167 TL macro compat if (version<167) { for (int i=0; i<4; i++) { - for (int j=0; j Date: Fri, 25 Aug 2023 03:47:09 -0500 Subject: [PATCH 10/23] fix again.... --- src/engine/instrument.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 7dabac9a..97b3bad8 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -2264,8 +2264,16 @@ void DivInstrument::readFeatureOx(SafeReader& reader, int op, short version) { // <167 TL macro compat if (macroCode==6 && version<167) { - for (int i=0; ilen; i++) { - target->val[i]^=0x7f; + for (int i=0; i<4; i++) { + if (target->open&6) { + for (int j=0; j<2; j++) { + target->val[j]^=0x7f; + } + } else { + for (int j=0; jlen; j++) { + target->val[j]^=0x7f; + } + } } } } From 55d7a5e9bc29e9c1c2f24943fc6ddf30af9e3624 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 25 Aug 2023 04:18:22 -0500 Subject: [PATCH 11/23] K007232: oscBuf was too fast --- src/engine/platform/k007232.cpp | 17 ++++++++++++----- src/engine/platform/k007232.h | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/engine/platform/k007232.cpp b/src/engine/platform/k007232.cpp index fb44a1a0..c1e314f5 100644 --- a/src/engine/platform/k007232.cpp +++ b/src/engine/platform/k007232.cpp @@ -78,15 +78,21 @@ void DivPlatformK007232::acquire(short** buf, size_t len) { const signed int rout[2]={(k007232.output(0)*((vol1>>4)&0xf)),(k007232.output(1)*((vol2>>4)&0xf))}; buf[0][h]=(lout[0]+lout[1])<<4; buf[1][h]=(rout[0]+rout[1])<<4; - for (int i=0; i<2; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=(lout[i]+rout[i])<<3; + if (++oscDivider>=8) { + oscDivider=0; + for (int i=0; i<2; i++) { + oscBuf[i]->data[oscBuf[i]->needle++]=(lout[i]+rout[i])<<3; + } } } else { const unsigned char vol=regPool[0xc]; const signed int out[2]={(k007232.output(0)*(vol&0xf)),(k007232.output(1)*((vol>>4)&0xf))}; buf[0][h]=(out[0]+out[1])<<4; - for (int i=0; i<2; i++) { - oscBuf[i]->data[oscBuf[i]->needle++]=out[i]<<4; + if (++oscDivider>=8) { + oscDivider=0; + for (int i=0; i<2; i++) { + oscBuf[i]->data[oscBuf[i]->needle++]=out[i]<<4; + } } } } @@ -484,7 +490,7 @@ void DivPlatformK007232::setFlags(const DivConfig& flags) { stereo=flags.getBool("stereo",false); for (int i=0; i<2; i++) { chan[i].volumeChanged=true; - oscBuf[i]->rate=rate; + oscBuf[i]->rate=rate/8; } } @@ -575,6 +581,7 @@ int DivPlatformK007232::init(DivEngine* p, int channels, int sugRate, const DivC } sampleMem=new unsigned char[getSampleMemCapacity()]; sampleMemLen=0; + oscDivider=0; setFlags(flags); reset(); diff --git a/src/engine/platform/k007232.h b/src/engine/platform/k007232.h index c8ea8aea..e3409b31 100644 --- a/src/engine/platform/k007232.h +++ b/src/engine/platform/k007232.h @@ -68,7 +68,7 @@ class DivPlatformK007232: public DivDispatch, public k007232_intf { bool sampleLoaded[256]; int delay; - unsigned char lastLoop, lastVolume; + unsigned char lastLoop, lastVolume, oscDivider; bool stereo; unsigned char* sampleMem; From c4b23e86436b14afec3e9daa441a89e89a7ea31e Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 25 Aug 2023 16:28:20 -0500 Subject: [PATCH 12/23] K007232: fix (?) loop marker being output issue #1409 --- .../vgsound_emu/src/k007232/k007232.cpp | 2 +- src/gui/chanOsc.cpp | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/extern/vgsound_emu-modified/vgsound_emu/src/k007232/k007232.cpp b/extern/vgsound_emu-modified/vgsound_emu/src/k007232/k007232.cpp index 02aa3460..6f9e9b81 100644 --- a/extern/vgsound_emu-modified/vgsound_emu/src/k007232/k007232.cpp +++ b/extern/vgsound_emu-modified/vgsound_emu/src/k007232/k007232.cpp @@ -67,7 +67,7 @@ void k007232_core::voice_t::tick(u8 ne) } } - m_out = s8(m_data) - 0x40; // send to output (ASD/BSD) pin + m_out = s8(m_data&0x7f) - 0x40; // send to output (ASD/BSD) pin } else { diff --git a/src/gui/chanOsc.cpp b/src/gui/chanOsc.cpp index aa7c91b5..5ca97f47 100644 --- a/src/gui/chanOsc.cpp +++ b/src/gui/chanOsc.cpp @@ -448,6 +448,7 @@ void FurnaceGUI::drawChanOsc() { float maxLevel=-1.0f; float dcOff=0.0f; unsigned short needlePos=buf->needle; + //unsigned short needlePosOrig=needlePos; for (int i=0; iinBuf[i]=(double)buf->data[(unsigned short)(needlePos-displaySize*2+((i*displaySize*2)/FURNACE_FFT_SIZE))]/32768.0; } @@ -475,10 +476,7 @@ void FurnaceGUI::drawChanOsc() { } chanOscPitch[ch]=(float)point/32.0f; - /* - String cPhase=fmt::sprintf("%d cphase: %f vol: %f",point,phase,chanOscVol[ch]); - dl->AddText(inRect.Min,0xffffffff,cPhase.c_str()); - */ + needlePos-=displaySize; for (unsigned short i=0; i=needlePosOrig)?"WARN":"OK"); + //dl->AddText(inRect.Min,0xffffffff,cPhase.c_str()); } ImU32 color=ImGui::GetColorU32(chanOscColor); if (chanOscUseGrad) { From 6c5ea4b95042452b124f3186ae516264b7562325 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 25 Aug 2023 17:22:04 -0500 Subject: [PATCH 13/23] fix step length in macroInt --- src/engine/macroInt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/macroInt.cpp b/src/engine/macroInt.cpp index 94ec602c..e53d53ae 100644 --- a/src/engine/macroInt.cpp +++ b/src/engine/macroInt.cpp @@ -56,7 +56,7 @@ void DivMacroStruct::doMacro(DivInstrumentMacro& source, bool released, bool tic has=false; return; } - if (released && type==1) delay=0; + if (released && type==1 && lastPos<3) delay=0; if (delay>0) { delay--; if (!linger) had=false; From 41316860a5da5195948e5ee740d445e4bd975859 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 25 Aug 2023 17:36:47 -0500 Subject: [PATCH 14/23] GUI: fix wave synth display issues issue #1417 --- src/gui/insEdit.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index c34e80d3..2c8f34d7 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -5321,14 +5321,14 @@ void FurnaceGUI::drawInsEdit() { float wavePreview1[256]; float wavePreview2[256]; float wavePreview3[256]; - for (int i=0; ilen; i++) { + for (int i=0; ilen+1; i++) { if (wave1->data[i]>wave1->max) { wavePreview1[i]=wave1->max; } else { wavePreview1[i]=wave1->data[i]; } } - for (int i=0; ilen; i++) { + for (int i=0; ilen+1; i++) { if (wave2->data[i]>wave2->max) { wavePreview2[i]=wave2->max; } else { @@ -5337,13 +5337,10 @@ void FurnaceGUI::drawInsEdit() { } if (ins->ws.enabled && (!wavePreviewPaused || wavePreviewInit)) { wavePreview.tick(true); + WAKE_UP; } for (int i=0; idata[i]>wavePreviewHeight) { - wavePreview3[i]=wavePreviewHeight; - } else { - wavePreview3[i]=wavePreview.output[i]; - } + wavePreview3[i]=wavePreview.output[i]; } float ySize=(isSingleWaveFX?96.0f:128.0f)*dpiScale; From bd95a76a4851fb94c392856cebeb50edeb8916c5 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 25 Aug 2023 17:51:10 -0500 Subject: [PATCH 15/23] fix nextOrder still happening after FFxx issue #1408 --- src/engine/playback.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/engine/playback.cpp b/src/engine/playback.cpp index 0078b015..7483a972 100644 --- a/src/engine/playback.cpp +++ b/src/engine/playback.cpp @@ -1164,7 +1164,11 @@ void DivEngine::nextRow() { } if (haltOn==DIV_HALT_PATTERN) halted=true; } else if (playing) if (++curRow>=curSubSong->patLen) { - nextOrder(); + if (shallStopSched) { + curRow=curSubSong->patLen-1; + } else { + nextOrder(); + } if (haltOn==DIV_HALT_PATTERN) halted=true; } From 2b0feefe28bcad716816017e9880d92c36144d30 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 25 Aug 2023 18:13:00 -0500 Subject: [PATCH 16/23] don't add to recent issue #1406 --- extern/nfd-modified/src/nfd_win.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/extern/nfd-modified/src/nfd_win.cpp b/extern/nfd-modified/src/nfd_win.cpp index 3bded25c..90e28ec3 100644 --- a/extern/nfd-modified/src/nfd_win.cpp +++ b/extern/nfd-modified/src/nfd_win.cpp @@ -677,6 +677,21 @@ nfdresult_t NFD_SaveDialog( const std::vector& filterList, goto end; } + // Set a flag for no history + DWORD dwFlags; + result = fileSaveDialog->GetOptions(&dwFlags); + if ( !SUCCEEDED(result) ) + { + NFDi_SetError("Could not get options."); + goto end; + } + result = fileSaveDialog->SetOptions(dwFlags | FOS_DONTADDTORECENT); + if ( !SUCCEEDED(result) ) + { + NFDi_SetError("Could not set options."); + goto end; + } + // Show the dialog. result = fileSaveDialog->Show(NULL); if ( SUCCEEDED(result) ) From 16bc35d75b034fb07fb191f08a1e9447916d3815 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 25 Aug 2023 18:32:34 -0500 Subject: [PATCH 17/23] manual system recent file tracking issue #1406 --- src/gui/gui.cpp | 33 +++++++++++++++++++++++++++++---- src/gui/gui.h | 1 + 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 04ccc258..27ec53c9 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2115,6 +2115,7 @@ int FurnaceGUI::save(String path, int dmfVersion) { showWarning(e->getWarnings(),GUI_WARN_GENERIC); } pushRecentFile(path); + pushRecentSys(path.c_str()); logD("save complete."); return 0; } @@ -2222,6 +2223,13 @@ void FurnaceGUI::pushRecentFile(String path) { } } +void FurnaceGUI::pushRecentSys(const char* path) { +#ifdef _WIN32 + WString widePath=utf8To16(path); + SHAddToRecentDocs(SHARD_PATHW,widePath.c_str()); +#endif +} + void FurnaceGUI::delFirstBackup(String name) { std::vector listOfFiles; #ifdef _WIN32 @@ -4819,29 +4827,39 @@ bool FurnaceGUI::loop() { break; case GUI_FILE_INS_SAVE: if (curIns>=0 && curIns<(int)e->song.ins.size()) { - e->song.ins[curIns]->save(copyOfName.c_str(),false,&e->song); + if (e->song.ins[curIns]->save(copyOfName.c_str(),false,&e->song)) { + pushRecentSys(copyOfName.c_str()); + } } break; case GUI_FILE_INS_SAVE_DMP: if (curIns>=0 && curIns<(int)e->song.ins.size()) { if (!e->song.ins[curIns]->saveDMP(copyOfName.c_str())) { showError("error while saving instrument! make sure your instrument is compatible."); + } else { + pushRecentSys(copyOfName.c_str()); } } break; case GUI_FILE_WAVE_SAVE: if (curWave>=0 && curWave<(int)e->song.wave.size()) { - e->song.wave[curWave]->save(copyOfName.c_str()); + if (e->song.wave[curWave]->save(copyOfName.c_str())) { + pushRecentSys(copyOfName.c_str()); + } } break; case GUI_FILE_WAVE_SAVE_DMW: if (curWave>=0 && curWave<(int)e->song.wave.size()) { - e->song.wave[curWave]->saveDMW(copyOfName.c_str()); + if (e->song.wave[curWave]->saveDMW(copyOfName.c_str())) { + pushRecentSys(copyOfName.c_str()); + } } break; case GUI_FILE_WAVE_SAVE_RAW: if (curWave>=0 && curWave<(int)e->song.wave.size()) { - e->song.wave[curWave]->saveRaw(copyOfName.c_str()); + if (e->song.wave[curWave]->saveRaw(copyOfName.c_str())) { + pushRecentSys(copyOfName.c_str()); + } } break; case GUI_FILE_SAMPLE_OPEN: { @@ -4905,6 +4923,8 @@ bool FurnaceGUI::loop() { if (curSample>=0 && curSample<(int)e->song.sample.size()) { if (!e->song.sample[curSample]->save(copyOfName.c_str())) { showError("could not save sample! open Log Viewer for more information."); + } else { + pushRecentSys(copyOfName.c_str()); } } break; @@ -4912,6 +4932,8 @@ bool FurnaceGUI::loop() { if (curSample>=0 && curSample<(int)e->song.sample.size()) { if (!e->song.sample[curSample]->saveRaw(copyOfName.c_str())) { showError("could not save sample! open Log Viewer for more information."); + } else { + pushRecentSys(copyOfName.c_str()); } } break; @@ -5061,6 +5083,7 @@ bool FurnaceGUI::loop() { if (f!=NULL) { fwrite(w->getFinalBuf(),1,w->size(),f); fclose(f); + pushRecentSys(copyOfName.c_str()); } else { showError("could not open file!"); } @@ -5081,6 +5104,7 @@ bool FurnaceGUI::loop() { if (f!=NULL) { fwrite(w->getFinalBuf(),1,w->size(),f); fclose(f); + pushRecentSys(copyOfName.c_str()); } else { showError("could not open file!"); } @@ -5107,6 +5131,7 @@ bool FurnaceGUI::loop() { if (f!=NULL) { fwrite(w->getFinalBuf(),1,w->size(),f); fclose(f); + pushRecentSys(copyOfName.c_str()); } else { showError("could not open file!"); } diff --git a/src/gui/gui.h b/src/gui/gui.h index 410d59b5..9f6b04b2 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -2342,6 +2342,7 @@ class FurnaceGUI { int load(String path); int loadStream(String path); void pushRecentFile(String path); + void pushRecentSys(const char* path); void exportAudio(String path, DivAudioExportModes mode); void delFirstBackup(String name); From 324fce3b1c75b176264d05fcf27fca5a7a816b5c Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 25 Aug 2023 20:41:13 -0500 Subject: [PATCH 18/23] GUI: hide sample ROMs option OPL4 won't make it to 0.6 --- src/gui/settings.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index ff0eef99..4c70b5f2 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -1303,6 +1303,7 @@ void FurnaceGUI::drawSettings() { ImGui::SameLine(); ImGui::Combo("##PCSOutMethod",&settings.pcSpeakerOutMethod,pcspkrOutMethods,5); + /* ImGui::Separator(); ImGui::Text("Sample ROMs:"); @@ -1332,6 +1333,7 @@ void FurnaceGUI::drawSettings() { if (ImGui::Button(ICON_FA_FOLDER "##MU5Load")) { openFileDialog(GUI_FILE_MU5_ROM_OPEN); } + */ END_SECTION; } From a17f7249d63f41061c0b303e5a98fafef4e005d5 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 25 Aug 2023 20:41:50 -0500 Subject: [PATCH 19/23] update settings doc with clarifications --- doc/2-interface/settings.md | 133 +++++++++++++++++------------------- 1 file changed, 63 insertions(+), 70 deletions(-) diff --git a/doc/2-interface/settings.md b/doc/2-interface/settings.md index 8b6da2a0..7a554664 100644 --- a/doc/2-interface/settings.md +++ b/doc/2-interface/settings.md @@ -1,32 +1,27 @@ # settings -settings are saved when clicking the **OK** button at the bottom of the dialog. - - +settings are saved when clicking the **OK** or **Apply** buttons at the bottom of the dialog. ## General ### Program -- **Render backend** - - changing this may help with performace issues. -- **Late render clear** +- **Render backend**: changing this may help with performace issues. +- **Late render clear**: this option is only useful when using old versions of Mesa drivers. it force-waits for VBlank by clearing after present, reducing latency. - **Power-saving mode**: saves power by lowering the frame rate to 2fps when idle. - may cause issues under Mesa drivers! - **Disable threaded input (restart after changing!)**: processes key presses for note preview on a separate thread (on supported platforms), which reduces latency. - however, crashes have been reported when threaded input is on. enable this option if that is the case. -- **Enable event delay** - - may cause issues with high-polling-rate mice when previewing notes. +- **Enable event delay**: may cause issues with high-polling-rate mice when previewing notes. ### File - **Use system file picker**: uses native OS file dialog instead of Furnace's. -- **Number of recent files**: number of files to show in the _open recent..._ menu. -- **Compress when saving** - - uses zlib to compress saved songs. -- **Save unused patterns** -- **Use new pattern format when saving** -- **Don't apply compatibility flags when loading .dmf** +- **Number of recent files**: number of files that will be remembered in the _open recent..._ menu. +- **Compress when saving**: uses zlib to compress saved songs. +- **Save unused patterns**: stores unused patterns in a saved song. +- **Use new pattern format when saving**: stores patterns in the new, optimized and smaller format. only disable if you need to work with older versions of Furnace. +- **Don't apply compatibility flags when loading .dmf**: does exactly what the option says. your .dmf songs may not play correctly after enabled. - **Play after opening song:** - No - Only if already playing @@ -73,22 +68,24 @@ settings are saved when clicking the **OK** button at the bottom of the dialog. - **Backend**: selects SDL or JACK for audio output. - only appears on Linux, or MacOS compiled with JACK support -- **Driver** +- **Driver**: select a different SDL audio driver if you're having problems with the default one. - **Device**: audio device for playback. - **Sample rate** - **Outputs**: number of audio outputs created, up to 16. - only appears when Backend is JACK. - **Channels**: number of output channels to use. - **Buffer size**: size of buffer in both samples and milliseconds. + - setting this to a low value may cause stuttering/glitches in playback (known as "underruns" or "xruns"). + - setting this to a high value increases latency. - **Low-latency mode (experimental!)**: reduces latency by running the engine faster than the tick rate. useful for live playback/jam mode. - - _warning:_ experimental! may produce glitches. only enable if your buffer size is small (10ms or less). -- **Force mono audio** + - only enable if your buffer size is small (10ms or less). +- **Force mono audio**: use if you're unable to hear stereo audio (e.g. single speaker or hearing loss in one ear). - **want:** displays requested audio configuration. - **got:** displays actual audio configuration returned by audio backend. ### Mixing -- **Quality**: selects quality of resampling. low quality reduces CPU load. +- **Quality**: selects quality of resampling. low quality reduces CPU load by a small amount. - **Software clipping**: clips output to nominal range (-1.0 to 1.0) before passing it to the audio device. - this avoids activating Windows' built-in limiter. @@ -96,32 +93,39 @@ settings are saved when clicking the **OK** button at the bottom of the dialog. - **Metronome volume** - - ## MIDI ### MIDI input - **MIDI input**: input device. -- **Note input** -- **Velocity input** -- **Map MIDI channels to direct channels** -- **Map Yamaha FM voice data to instruments** -- **Program change is instrument selection** -- **Value input style**: - - **Disabled/custom** - - **Two octaves (0 is C-4, F is D#5)** - - **Raw (note number is value)** - - **Two octaves alternate (lower keys are 0-9, upper keys are A-F)** - - **Use dual control change (one for each nibble)** - - **CC of upper nibble** - - **CC of lower nibble** - - **Use 14-bit control change** - - **MSB CC** - - **LSB CC** - - **Use single control change** - - **Control** -- **Per-column control change** +- **Note input**: enables note input. disable if you intend to use this device only for binding actions. +- **Velocity input**: enables velocity input when entering notes in the pattern. +- **Map MIDI channels to direct channels**: when enabled, notes from MIDI channels will be mapped to channels rather than the cursor position. +- **Map Yamaha FM voice data to instruments**: when enabled, Furnace will listen for any transmitted Yamaha SysEx patches. + - this option is only useful if you have a Yamaha FM synthesizer (e.g. TX81Z). + - selecting a voice or using the "Voice Transmit?" option will send a patch, and Furnace will create a new instrument with its data. + - this may also be triggered by clicking on "Receive from TX81Z" in the instrument editor (OPZ only). +- **Program change is instrument selection**: changes the current instrument when a program change event is received. +- **Value input style**: changes the way values are entered when the pattern cursor is not in the Note column. the following styles are available: + - **Disabled/custom**: no value input through MIDI. + - **Two octaves (0 is C-4, F is D#5)**: maps keys in two octaves to single nibble input. the layout is: + - ` - octave n -- octave n+1 -` + - ` 1 3 6 8 A D F # # # ` + - `0 2 4 5 7 9 B C E # # # # #` + - **Raw (note number is value)**: the note number becomes the input value. not useful if you want to input anything above 7F. + - **Two octaves alternate (lower keys are 0-9, upper keys are A-F)**: maps keys in two octaves, but with a different layout: + - ` - octave n -- octave n+1 -` + - ` A B C D E F # # # # ` + - `0 1 2 3 4 5 6 7 8 9 # # # #` + - **Use dual control change (one for each nibble)**: maps two control change events to the nibbles of a value. + - **CC of upper nibble**: select the CC number that will change the upper nibble. + - **CC of lower nibble**: select the CC number that will change the lower nibble. + - **Use 14-bit control change**: maps two control change events that together form a single 14-bit CC. some MIDI controllers do these. + - **MSB CC**: select the CC containing the upper portion of the control. + - **LSB CC**: select the CC containing the lower portion of the control. + - **Use single control change**: maps one control change event. not useful if you want to input odd numbers. + - **Control**: select the CC number that will change the value. +- **Per-column control change**: when enabled, you can map several control change events to a channel's columns. - **Instrument**\ **Volume**\ **Effect `x` type**\ @@ -135,36 +139,34 @@ settings are saved when clicking the **OK** button at the bottom of the dialog. - **LSB CC** - **Use single control change (imprecise)** - **Control** -- **Volume curve** -- **Actions:** +- **Volume curve**: adjust the velocity to volume curve. +- **Actions**: this allows you to bind note input and control change events to actions. - **`+`** button: adds a new action. - window-with-arrow button: new action with learning! press a button or move a slider/knob/something on your device. - each action has the following: - - **Type** - - **Channel** - - **Note/Control** - - **Velocity/Value** - - **Action** - - **Learn** - - **Remove** + - **Type**: type of event. + - **Channel**: channel of event. + - **Note/Control**: the note/control change number. + - **Velocity/Value**: the velocity or control value + - **Action**: the GUI action to perform. + - **Learn**: after clicking on this button, do something in your MIDI device and Furnace will map that to this action. + - **Remove**: remove this action. ### MIDI output - **MIDI output**: output device. - **Output mode:** - - **Off (use for TX81Z)** - - **Melodic** -- **Send Program Change** -- **Send MIDI clock** -- **Send MIDI timecode** - - **Timecode frame rate:** - - **Closest to Tick Rate** - - **Film (24fps)** - - **PAL (25fps)** - - **NTSC drop (29.97fps)** - - **NTSC non-drop (30fps)** - - + - **Off (use for TX81Z)**: don't output anything. use if you plan to use Furnace as sync master, or the "Receive from TX81Z" button in the OPZ instrument editor. + - **Melodic**: output MIDI events. +- **Send Program Change**: output program change events when instrument change commands occur. +- **Send MIDI clock**: output MIDI beat clock. +- **Send MIDI timecode**: output MIDI timecode. + - **Timecode frame rate**: sets the timing standard used for MIDI timecode. + - **Closest to Tick Rate**: automatically sets the rate based on the song's Tick Rate. + - **Film (24fps)**: output at 24 codes per second. + - **PAL (25fps)**: output at 25 codes per second. + - **NTSC drop (29.97fps)**: output at ~29.97 codes per second, skipping frames 0 and 1 of each minute that doesn't divide by 10. + - **NTSC non-drop (30fps)**: output at 30 codes per second. ## Emulation @@ -184,13 +186,6 @@ settings are saved when clicking the **OK** button at the bottom of the dialog. - **PC Speaker strategy**: this is covered in the [PC speaker system doc](../7-systems/pcspkr.md). -- **Sample ROMs:** - - **OPL4 YRW801 path** - - **MultiPCM TG100 path** - - **MultiPCM MU5 path** - - - ## Keyboard ### Keyboard @@ -417,10 +412,8 @@ settings are saved when clicking the **OK** button at the bottom of the dialog. - **Macro editor layout:** - **Unified** - - **Mobile** - **Grid** - **Single (with list)** - - **Single (combo box)** - **Use classic macro editor vertical slider** ### Wave Editor From 29fa249227d7ed18421fdb68d5d30cd764f83577 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 26 Aug 2023 03:13:17 -0500 Subject: [PATCH 20/23] GUI: really fix wave synth display issues issue #1417 --- src/gui/insEdit.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index 2c8f34d7..98d02e3a 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -5318,23 +5318,29 @@ void FurnaceGUI::drawInsEdit() { wavePreview.init(ins,wavePreviewLen,wavePreviewHeight,true); wavePreviewInit=false; } - float wavePreview1[256]; - float wavePreview2[256]; - float wavePreview3[256]; - for (int i=0; ilen+1; i++) { + float wavePreview1[257]; + float wavePreview2[257]; + float wavePreview3[257]; + for (int i=0; ilen; i++) { if (wave1->data[i]>wave1->max) { wavePreview1[i]=wave1->max; } else { wavePreview1[i]=wave1->data[i]; } } - for (int i=0; ilen+1; i++) { + if (wave1->len>0) { + wavePreview1[wave1->len]=wave1->data[wave1->len-1]; + } + for (int i=0; ilen; i++) { if (wave2->data[i]>wave2->max) { wavePreview2[i]=wave2->max; } else { wavePreview2[i]=wave2->data[i]; } } + if (wave2->len>0) { + wavePreview2[wave2->len]=wave2->data[wave2->len-1]; + } if (ins->ws.enabled && (!wavePreviewPaused || wavePreviewInit)) { wavePreview.tick(true); WAKE_UP; @@ -5342,6 +5348,9 @@ void FurnaceGUI::drawInsEdit() { for (int i=0; i0) { + wavePreview3[wavePreviewLen]=wavePreview3[wavePreviewLen-1]; + } float ySize=(isSingleWaveFX?96.0f:128.0f)*dpiScale; @@ -5356,7 +5365,7 @@ void FurnaceGUI::drawInsEdit() { } ImGui::TableNextColumn(); ImVec2 size3=ImVec2(ImGui::GetContentRegionAvail().x,ySize); - PlotNoLerp("##WaveformP3",wavePreview3,wavePreviewLen,0,"Result",0,wavePreviewHeight,size3); + PlotNoLerp("##WaveformP3",wavePreview3,wavePreviewLen+1,0,"Result",0,wavePreviewHeight,size3); ImGui::TableNextRow(); ImGui::TableNextColumn(); From 3dd4f3e7e8f0f5e854896ebcad9a7b4e1b341787 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 26 Aug 2023 03:36:28 -0500 Subject: [PATCH 21/23] release v0.6pre9 also fix a bug in TL macro compat --- android/app/build.gradle | 4 ++-- android/app/src/main/AndroidManifest.xml | 4 ++-- papers/clipboard-format.md | 2 +- papers/format.md | 1 + res/Info.plist | 6 +++--- src/engine/engine.h | 6 +++--- src/engine/instrument.cpp | 16 +++++++--------- src/gui/tutorial.cpp | 8 +------- 8 files changed, 20 insertions(+), 27 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 5384d6d9..dcf7fe76 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -15,8 +15,8 @@ android { } minSdkVersion 21 targetSdkVersion 26 - versionCode 166 - versionName "0.6pre8" + versionCode 169 + versionName "0.6pre9" externalNativeBuild { cmake { arguments "-DANDROID_APP_PLATFORM=android-21", "-DANDROID_STL=c++_static", "-DWARNINGS_ARE_ERRORS=ON" diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index a72f1b83..dd3c7a0b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,8 +1,8 @@ diff --git a/papers/clipboard-format.md b/papers/clipboard-format.md index 1b274543..cb353546 100644 --- a/papers/clipboard-format.md +++ b/papers/clipboard-format.md @@ -6,7 +6,7 @@ when copying pattern data from Furnace, it's stored in the clipboard as plain te org.tildearrow.furnace - Pattern Data (144) ``` -this top line of text is always the same except for the number in parentheses, which is the internal build number. for example, 0.6pre8 is `166`. +this top line of text is always the same except for the number in parentheses, which is the internal build number. for example, 0.6pre9 is `169`. the second line is a number between 0 and 18 (decimal) which indicates which column the clip starts from. - `0`: note. diff --git a/papers/format.md b/papers/format.md index 267b7410..a09579bd 100644 --- a/papers/format.md +++ b/papers/format.md @@ -32,6 +32,7 @@ these fields are 0 in format versions prior to 100 (0.6pre1). the format versions are: +- 169: Furnace 0.6pre9 - 166: Furnace 0.6pre8 - 162: Furnace 0.6pre7 - 161: Furnace 0.6pre6 diff --git a/res/Info.plist b/res/Info.plist index bb3bab0e..a7e16ca7 100644 --- a/res/Info.plist +++ b/res/Info.plist @@ -15,17 +15,17 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - 0.6pre8 + 0.6pre9 CFBundleName Furnace CFBundlePackageType APPL CFBundleShortVersionString - 0.6pre8 + 0.6pre9 CFBundleSignature ???? CFBundleVersion - 0.6pre8 + 0.6pre9 NSHumanReadableCopyright NSHighResolutionCapable diff --git a/src/engine/engine.h b/src/engine/engine.h index 653ca8ce..7fb6b511 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -54,10 +54,10 @@ #define EXTERN_BUSY_BEGIN_SOFT e->softLocked=true; e->isBusy.lock(); #define EXTERN_BUSY_END e->isBusy.unlock(); e->softLocked=false; -#define DIV_UNSTABLE +//#define DIV_UNSTABLE -#define DIV_VERSION "dev168" -#define DIV_ENGINE_VERSION 168 +#define DIV_VERSION "0.6pre9" +#define DIV_ENGINE_VERSION 169 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/engine/instrument.cpp b/src/engine/instrument.cpp index 97b3bad8..842b88fc 100644 --- a/src/engine/instrument.cpp +++ b/src/engine/instrument.cpp @@ -2264,15 +2264,13 @@ void DivInstrument::readFeatureOx(SafeReader& reader, int op, short version) { // <167 TL macro compat if (macroCode==6 && version<167) { - for (int i=0; i<4; i++) { - if (target->open&6) { - for (int j=0; j<2; j++) { - target->val[j]^=0x7f; - } - } else { - for (int j=0; jlen; j++) { - target->val[j]^=0x7f; - } + if (target->open&6) { + for (int j=0; j<2; j++) { + target->val[j]^=0x7f; + } + } else { + for (int j=0; jlen; j++) { + target->val[j]^=0x7f; } } } diff --git a/src/gui/tutorial.cpp b/src/gui/tutorial.cpp index c1be8912..ea753205 100644 --- a/src/gui/tutorial.cpp +++ b/src/gui/tutorial.cpp @@ -255,12 +255,6 @@ void FurnaceGUI::drawTutorial() { ImGui::Text("welcome to Furnace, the biggest open-source chiptune tracker!"); - ImGui::TextWrapped( - "did I say that 0.6pre5 will have a tutorial? well, it doesn't...\n" - "the reason is because 0.6pre5 fixes a critical bug which may cause config loss in some machines.\n" - "furthermore, it dramatically improves the backup system. couldn't put this version on hold anymore." - ); - ImGui::Separator(); ImGui::TextWrapped("here are some tips to get you started:"); @@ -280,7 +274,7 @@ void FurnaceGUI::drawTutorial() { ImGui::TextWrapped( "if you need help, you may:\n" "- read the (incomplete) manual: https://github.com/tildearrow/furnace/blob/master/doc/README.md\n" - "- ask for help in Discussions (https://github.com/tildearrow/furnace/discussions) or the Furnace Discord (https://discord.gg/EfrwT2wq7z)" + "- ask for help in Discussions (https://github.com/tildearrow/furnace/discussions), the Furnace Discord (https://discord.gg/EfrwT2wq7z) or Furnace in Revolt (https://rvlt.gg/GRPS6tmc)" ); ImGui::Separator(); From b5d6971f934ec94fd0918a9f16203c503c295df5 Mon Sep 17 00:00:00 2001 From: freq-mod <32672779+freq-mod@users.noreply.github.com> Date: Sat, 26 Aug 2023 13:10:05 +0200 Subject: [PATCH 22/23] Update sms.md Noise mode descrption --- doc/7-systems/sms.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/7-systems/sms.md b/doc/7-systems/sms.md index 36d13976..e4fe2231 100644 --- a/doc/7-systems/sms.md +++ b/doc/7-systems/sms.md @@ -1,6 +1,8 @@ # TI SN76489 (e.g. Sega Master System) -a relatively simple sound chip made by Texas Instruments. a derivative of it is used in Sega's Master System, the predecessor to Genesis. +a relatively simple sound chip made by Texas Instruments. a derivative of it is used in Sega's Master System, the predecessor to Genesis. It has three square wave channels and one noise channel... not really. + +Nominal mode of SN76489 has 3 quare wave channels, with noise channel having only 3 preset frequencies to use (absurdly low, very low, low). To use more pitches, one can enable mode, which "steals" pitch data from square wave channel 3. By doing that, SN76489 becomes effectively a 3 channel sound chip. In addition, periodic noise mode can be enabled, with same caveats. the original iteration of the SN76489 used in the TI-99/4A computer, the SN94624, could only produce tones as low as 100Hz, and was clocked at 447 KHz. all later versions (such as the one in the Master System and Genesis) had a clock divider but ran on a faster clock... except for the SN76494, which can play notes as low as 13.670 Hz (A -1). consequently, its pitch accuracy for higher notes is compromised. From 29651aabfd0a791e73cd39ad4053b4831d81473e Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sat, 26 Aug 2023 11:54:25 -0500 Subject: [PATCH 23/23] oh no there's a problem why did I not remove this before? now Yuzu is mad at me --- CMakeLists.txt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7e5d3afe..fb157e87 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -284,12 +284,6 @@ if (USE_SDL2) # This should probably go in a FAQ. set(SDL_LIBC ON CACHE BOOL "Tell SDL that we want it to use our C runtime (required for proper static linking)" FORCE) - # https://github.com/tildearrow/furnace/issues/1237 - # enabling this will result in SDL finding the Direct3D headers, forcing _WIN32_WINNT to an undesirable value (which makes the Wine headers define GetTickCount64) - if (SUPPORT_XP) - set(SDL_RENDER_D3D OFF CACHE BOOL "Enable the Direct3D render driver" FORCE) - endif() - add_subdirectory(extern/SDL EXCLUDE_FROM_ALL) list(APPEND DEPENDENCIES_DEFINES HAVE_SDL2) list(APPEND DEPENDENCIES_INCLUDE_DIRS extern/SDL/include)