diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bcd989c21..6c05127cc 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -26,7 +26,7 @@ jobs: - { name: 'macOS ARM', os: macos-latest, arch: arm64 } - { name: 'Linux x86_64', os: ubuntu-18.04, arch: x86_64 } #- { name: 'Linux ARM', os: ubuntu-18.04, arch: armhf } - fail-fast: false + fail-fast: true name: ${{ matrix.config.name }} runs-on: ${{ matrix.config.os }} diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e6659f96..8e9481a08 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -623,15 +623,13 @@ src/gui/volMeter.cpp src/gui/gui.cpp ) -if (WIN32 OR APPLE) +if (WIN32 AND (MSVC OR CMAKE_SIZEOF_VOID_P EQUAL 8)) list(APPEND GUI_SOURCES extern/nfd-modified/src/nfd_common.cpp) -endif() - -if (WIN32) list(APPEND GUI_SOURCES extern/nfd-modified/src/nfd_win.cpp) endif() if (APPLE) + list(APPEND GUI_SOURCES extern/nfd-modified/src/nfd_common.cpp) list(APPEND GUI_SOURCES src/gui/macstuff.m) list(APPEND GUI_SOURCES extern/nfd-modified/src/nfd_cocoa.mm) endif() @@ -709,6 +707,10 @@ if (WIN32) if (NOT MSVC) list(APPEND DEPENDENCIES_LIBRARIES -static) endif() + # support Windows XP + if (CMAKE_SIZEOF_VOID_P EQUAL 4 AND NOT MSVC) + list(APPEND DEPENDENCIES_DEFINES "_WIN32_WINNT=0x0501") + endif() elseif (APPLE) find_library(COCOA Cocoa REQUIRED) list(APPEND DEPENDENCIES_LIBRARIES ${COCOA}) diff --git a/README.md b/README.md index 710c2baba..3a27c23b8 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ check out the [Releases](https://github.com/tildearrow/furnace/releases) page. a [![Packaging status](https://repology.org/badge/tiny-repos/furnace.svg)](https://repology.org/project/furnace/versions) some people have provided packages for Unix/Unix-like distributions. here's a list. - - **Arch Linux**: [furnace-git is in the AUR.](https://aur.archlinux.org/packages/furnace-git) thank you Essem! + - **Arch Linux**: [furnace](https://archlinux.org/packages/community/x86_64/furnace/) is now in the community repo! - **FreeBSD**: [a package in ports](https://www.freshports.org/audio/furnace/) is available courtesy of ehaupt. - **Nix**: [package](https://search.nixos.org/packages?channel=unstable&show=furnace&from=0&size=50&sort=relevance&type=packages&query=furnace) thanks to OPNA2608. - **openSUSE**: [a package](https://software.opensuse.org/package/furnace) is available, courtesy of fpesari. @@ -264,7 +264,7 @@ you may need to log out and/or reboot after doing this. > .spc export? -**not yet!** coming in 0.7 though, in a future... +**not yet!** coming in 0.7 though, eventually... > how do I use C64 absolute filter/duty? diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 082cebc3f..6c75c8e4b 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,8 +1,8 @@ diff --git a/demos/misc/Eternal_Forest_Taito_Arcade.fur b/demos/arcade/Eternal_Forest_TaitoArcade.fur similarity index 100% rename from demos/misc/Eternal_Forest_Taito_Arcade.fur rename to demos/arcade/Eternal_Forest_TaitoArcade.fur diff --git a/demos/multichip/Ice_Wind_OPMSPCM.fur b/demos/arcade/Ice_Wind_SegaPCM.fur similarity index 100% rename from demos/multichip/Ice_Wind_OPMSPCM.fur rename to demos/arcade/Ice_Wind_SegaPCM.fur diff --git a/demos/namco/Mars_Bar_On_Mars.fur b/demos/arcade/Mars_Bar_On_Mars_NamcoWSG.fur similarity index 100% rename from demos/namco/Mars_Bar_On_Mars.fur rename to demos/arcade/Mars_Bar_On_Mars_NamcoWSG.fur diff --git a/demos/misc/Neo_Seaside_Volley_Court_NeoGeo.fur b/demos/arcade/Neo_Seaside_Volley_Court_NeoGeo.fur similarity index 100% rename from demos/misc/Neo_Seaside_Volley_Court_NeoGeo.fur rename to demos/arcade/Neo_Seaside_Volley_Court_NeoGeo.fur diff --git a/demos/namco/Phoenix_cover.fur b/demos/arcade/Phoenix_cover_NamcoWSG.fur similarity index 100% rename from demos/namco/Phoenix_cover.fur rename to demos/arcade/Phoenix_cover_NamcoWSG.fur diff --git a/demos/multichip/The_Good_Times_Arcade.fur b/demos/arcade/The_Good_Times_SegaPCM.fur similarity index 100% rename from demos/multichip/The_Good_Times_Arcade.fur rename to demos/arcade/The_Good_Times_SegaPCM.fur diff --git a/demos/multichip/Tubelectric_Fictional_Arcade.fur b/demos/arcade/Tubelectric_Fictional_Arcade.fur similarity index 100% rename from demos/multichip/Tubelectric_Fictional_Arcade.fur rename to demos/arcade/Tubelectric_Fictional_Arcade.fur diff --git a/demos/misc/UT99_Run_Taito_Arcade.fur b/demos/arcade/UT99_Run_TaitoArcade.fur similarity index 100% rename from demos/misc/UT99_Run_Taito_Arcade.fur rename to demos/arcade/UT99_Run_TaitoArcade.fur diff --git a/demos/misc/Utter Determination YM2610B.fur b/demos/arcade/Utter_Determination_TaitoArcade.fur similarity index 100% rename from demos/misc/Utter Determination YM2610B.fur rename to demos/arcade/Utter_Determination_TaitoArcade.fur diff --git a/demos/namco/ice-cap-nc30.fur b/demos/arcade/ice_cap_NamcoC30.fur similarity index 100% rename from demos/namco/ice-cap-nc30.fur rename to demos/arcade/ice_cap_NamcoC30.fur diff --git a/demos/multichip/iji_tor.fur b/demos/arcade/iji_tor_SegaPCM.fur similarity index 100% rename from demos/multichip/iji_tor.fur rename to demos/arcade/iji_tor_SegaPCM.fur diff --git a/demos/multichip/the_machines_are_socialising.fur b/demos/arcade/the_machines_are_socialising_SegaPCM.fur similarity index 100% rename from demos/multichip/the_machines_are_socialising.fur rename to demos/arcade/the_machines_are_socialising_SegaPCM.fur diff --git a/demos/genesis/MegadriveOverdrive.fur b/demos/genesis/MegadriveOverdrive.fur new file mode 100644 index 000000000..cc895f8d6 Binary files /dev/null and b/demos/genesis/MegadriveOverdrive.fur differ diff --git a/demos/misc/combat_vehicle_pokey.fur b/demos/misc/combat_vehicle_pokey.fur new file mode 100644 index 000000000..d5ff19e28 Binary files /dev/null and b/demos/misc/combat_vehicle_pokey.fur differ diff --git a/demos/opl/OPL3_SegaPCM_Xeno_Crisis_-_Facility_Area_2.fur b/demos/multichip/OPL3_SegaPCM_Xeno_Crisis_-_Facility_Area_2.fur similarity index 100% rename from demos/opl/OPL3_SegaPCM_Xeno_Crisis_-_Facility_Area_2.fur rename to demos/multichip/OPL3_SegaPCM_Xeno_Crisis_-_Facility_Area_2.fur diff --git a/instruments/README.md b/instruments/README.md index 949aab10a..6a558cf43 100644 --- a/instruments/README.md +++ b/instruments/README.md @@ -46,5 +46,7 @@ you may submit your own instruments by creating a pull request or contacting me! - any format Furnace is able to load is accepted. - I (strongly) prefer original instruments. +- your instruments have to be free of restrictions (these may be used in any project). + - be careful if your instrument contains samples. thanks for your contribution! diff --git a/papers/format.md b/papers/format.md index 0b8ebcd20..6765f8466 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: +- 133: Furnace 0.6pre3 - 132: Furnace 0.6pre2 - 131: Furnace dev131 - 130: Furnace dev130 diff --git a/res/Info.plist b/res/Info.plist index d7f0f98dd..86477d153 100644 --- a/res/Info.plist +++ b/res/Info.plist @@ -15,17 +15,17 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleLongVersionString - 0.6pre2 + 0.6pre3 CFBundleName Furnace CFBundlePackageType APPL CFBundleShortVersionString - 0.6pre2 + 0.6pre3 CFBundleSignature ???? CFBundleVersion - 0.6pre2 + 0.6pre3 NSHumanReadableCopyright NSHighResolutionCapable diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp index 2809b8f6b..616e3e220 100644 --- a/src/engine/engine.cpp +++ b/src/engine/engine.cpp @@ -2104,6 +2104,10 @@ double DivEngine::calcBaseFreq(double clock, double divider, int note, bool peri if (tuning>500.0) tuning=500.0; \ int boundaryBottom=tuning*pow(2.0,0.25)*(divider/clock); \ int boundaryTop=2.0*tuning*pow(2.0,0.25)*(divider/clock); \ + while (boundaryTop>((1<>=1; \ + boundaryBottom>>=1; \ + } \ int block=(note)/12; \ if (block<0) block=0; \ if (block>7) block=7; \ diff --git a/src/engine/engine.h b/src/engine/engine.h index faca57d9d..7eb5c00c1 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -47,8 +47,8 @@ #define BUSY_BEGIN_SOFT softLocked=true; isBusy.lock(); #define BUSY_END isBusy.unlock(); softLocked=false; -#define DIV_VERSION "0.6pre2" -#define DIV_ENGINE_VERSION 132 +#define DIV_VERSION "0.6pre3" +#define DIV_ENGINE_VERSION 133 // for imports #define DIV_VERSION_MOD 0xff01 #define DIV_VERSION_FC 0xff02 diff --git a/src/engine/fileOps.cpp b/src/engine/fileOps.cpp index d56836bfb..d5180c80e 100644 --- a/src/engine/fileOps.cpp +++ b/src/engine/fileOps.cpp @@ -2511,17 +2511,25 @@ bool DivEngine::loadFur(unsigned char* file, size_t len) { } // ExtCh compat flag - if (ds.version<125) { - for (int i=0; i=5 && chan[c.chan].dacMode) { @@ -1253,6 +1255,7 @@ void DivPlatformGenesis::setFlags(const DivConfig& flags) { } ladder=flags.getBool("ladderEffect",false); noExtMacros=flags.getBool("noExtMacros",false); + fbAllOps=flags.getBool("fbAllOps",false); OPN2_SetChipType(&fm,ladder?ym3438_mode_ym2612:0); CHECK_CUSTOM_CLOCK; if (useYMFM) { diff --git a/src/engine/platform/genesisext.cpp b/src/engine/platform/genesisext.cpp index ae6ac70bd..4eb34bc23 100644 --- a/src/engine/platform/genesisext.cpp +++ b/src/engine/platform/genesisext.cpp @@ -46,7 +46,9 @@ int DivPlatformGenesisExt::dispatch(DivCommand c) { if (opChan[ch].insChanged) { chan[2].state.alg=ins->fm.alg; - chan[2].state.fb=ins->fm.fb; + if (ch==0 || fbAllOps) { + chan[2].state.fb=ins->fm.fb; + } chan[2].state.fms=ins->fm.fms; chan[2].state.ams=ins->fm.ams; chan[2].state.op[ordch]=ins->fm.op[ordch]; @@ -491,7 +493,7 @@ void DivPlatformGenesisExt::tick(bool sysTick) { if (opChan[i].std.pitch.had) { if (opChan[i].std.pitch.mode) { opChan[i].pitch2+=opChan[i].std.pitch.val; - CLAMP_VAR(opChan[i].pitch2,-32768,32767); + CLAMP_VAR(opChan[i].pitch2,-1048576,1048575); } else { opChan[i].pitch2=opChan[i].std.pitch.val; } diff --git a/src/engine/platform/msm5232.cpp b/src/engine/platform/msm5232.cpp index e602aab32..4781945f5 100644 --- a/src/engine/platform/msm5232.cpp +++ b/src/engine/platform/msm5232.cpp @@ -141,6 +141,13 @@ void DivPlatformMSM5232::tick(bool sysTick) { if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { //DivInstrument* ins=parent->getIns(chan[i].ins,DIV_INS_PCE); chan[i].freq=chan[i].baseFreq+chan[i].pitch+chan[i].pitch2-(12<<7); + if (!parent->song.oldArpStrategy) { + if (chan[i].fixedArp) { + chan[i].freq=(chan[i].baseNoteOverride<<7)+(chan[i].pitch)-(12<<7); + } else { + chan[i].freq+=chan[i].arpOff<<7; + } + } if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>0x2aff) chan[i].freq=0x2aff; if (chan[i].keyOn) { diff --git a/src/engine/platform/nes.cpp b/src/engine/platform/nes.cpp index 5e9793a8e..a46a6d3f3 100644 --- a/src/engine/platform/nes.cpp +++ b/src/engine/platform/nes.cpp @@ -217,7 +217,7 @@ void DivPlatformNES::tick(bool sysTick) { rWrite(0x4000+i*4,(chan[i].envMode<<4)|chan[i].outVol|((chan[i].duty&3)<<6)); } } - if (NEW_ARP_STRAT && i!=3) { + if (NEW_ARP_STRAT) { chan[i].handleArp(); } else if (chan[i].std.arp.had) { if (i==3) { // noise @@ -271,9 +271,20 @@ void DivPlatformNES::tick(bool sysTick) { if (chan[i].freqChanged || chan[i].keyOn || chan[i].keyOff) { if (i==3) { // noise int ntPos=chan[i].baseFreq; - if (ntPos<0) ntPos=0; - if (ntPos>252) ntPos=252; - chan[i].freq=(parent->song.properNoiseLayout)?(15-(chan[i].baseFreq&15)):(noiseTable[ntPos]); + if (NEW_ARP_STRAT) { + if (chan[i].fixedArp) { + ntPos=chan[i].baseNoteOverride; + } else { + ntPos+=chan[i].arpOff; + } + } + if (parent->song.properNoiseLayout) { + chan[i].freq=15-(ntPos&15); + } else { + if (ntPos<0) ntPos=0; + if (ntPos>252) ntPos=252; + chan[i].freq=noiseTable[ntPos]; + } } else { chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,true,0,chan[i].pitch2,chipClock,CHIP_DIVIDER)-1; if (chan[i].freq>2047) chan[i].freq=2047; diff --git a/src/engine/platform/opll.cpp b/src/engine/platform/opll.cpp index 0136123e3..8ffd65014 100644 --- a/src/engine/platform/opll.cpp +++ b/src/engine/platform/opll.cpp @@ -248,7 +248,7 @@ void DivPlatformOPLL::tick(bool sysTick) { if (chan[i].freq<0) chan[i].freq=0; if (chan[i].freq>65535) chan[i].freq=65535; int freqt=toFreq(chan[i].freq); - if (freqt>2047) freqt=2047; + if (freqt>4095) freqt=4095; chan[i].freqL=freqt&0xff; if (i>=6 && properDrums && (i<9 || !noTopHatFreq)) { immWrite(0x10+drumSlot[i],freqt&0xff); @@ -456,12 +456,14 @@ int DivPlatformOPLL::dispatch(DivCommand c) { if (c.chan>=9 && !properDrums) return 0; chan[c.chan].keyOff=true; chan[c.chan].keyOn=false; + chan[c.chan].freqChanged=true; chan[c.chan].active=false; break; case DIV_CMD_NOTE_OFF_ENV: if (c.chan>=9 && !properDrums) return 0; chan[c.chan].keyOff=true; chan[c.chan].keyOn=false; + chan[c.chan].freqChanged=true; chan[c.chan].active=false; chan[c.chan].std.release(); break; diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index c4c9bcb83..47a8c0c54 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -169,6 +169,9 @@ void DivPlatformPCE::tick(bool sysTick) { } if (NEW_ARP_STRAT) { chan[i].handleArp(); + int noiseSeek=chan[i].fixedArp?chan[i].baseNoteOverride:(chan[i].note+chan[i].arpOff); + if (noiseSeek<0) noiseSeek=0; + chWrite(i,0x07,chan[i].noise?(0x80|(parent->song.properNoiseLayout?(noiseSeek&31):noiseFreq[noiseSeek%12])):0); } else if (chan[i].std.arp.had) { if (!chan[i].inPorta) { int noiseSeek=parent->calcArp(chan[i].note,chan[i].std.arp.val); diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index 30d3b804e..ccc9f48bc 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -45,6 +45,8 @@ void DivPlatformSegaPCM::acquire(short* bufL, short* bufR, size_t start, size_t oscBuf[i]->data[oscBuf[i]->needle++]=s->data8[chan[i].pcm.pos>>8]*(chan[i].chVolL+chan[i].chVolR)>>1; pcmL+=(s->data8[chan[i].pcm.pos>>8]*chan[i].chVolL); pcmR+=(s->data8[chan[i].pcm.pos>>8]*chan[i].chVolR); + } else { + oscBuf[i]->data[oscBuf[i]->needle++]=0; } chan[i].pcm.pos+=chan[i].pcm.freq; if (s->isLoopable() && chan[i].pcm.pos>=((unsigned int)s->loopEnd<<8)) { diff --git a/src/engine/platform/sound/snes/SPC_DSP.cpp b/src/engine/platform/sound/snes/SPC_DSP.cpp index 1a9375584..6ae8275bc 100644 --- a/src/engine/platform/sound/snes/SPC_DSP.cpp +++ b/src/engine/platform/sound/snes/SPC_DSP.cpp @@ -803,7 +803,7 @@ void SPC_DSP::run( int clocks_remain ) { loop: // GCC, why -#if defined(__GNUC__) && !defined(__clang__) +#if (defined(__GNUC__) && (__GNUC__ >= 7)) && !defined(__clang__) #define PHASE( n ) if ( n && !--clocks_remain ) break; __attribute__ ((fallthrough)); case n: #else #define PHASE( n ) if ( n && !--clocks_remain ) break; case n: diff --git a/src/engine/platform/ym2203.cpp b/src/engine/platform/ym2203.cpp index a968d49d2..95ab537fc 100644 --- a/src/engine/platform/ym2203.cpp +++ b/src/engine/platform/ym2203.cpp @@ -316,7 +316,7 @@ void DivPlatformYM2203::tick(bool sysTick) { if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { chan[i].pitch2+=chan[i].std.pitch.val; - CLAMP_VAR(chan[i].pitch2,-32768,32767); + CLAMP_VAR(chan[i].pitch2,-1048576,1048575); } else { chan[i].pitch2=chan[i].std.pitch.val; } @@ -449,7 +449,7 @@ void DivPlatformYM2203::tick(bool sysTick) { if (parent->song.linearPitch==2) { chan[i].freq=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2,chipClock,CHIP_FREQBASE,11); } else { - int fNum=parent->calcFreq(chan[i].baseFreq&0x7ff,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2); + int fNum=parent->calcFreq(chan[i].baseFreq,chan[i].pitch,chan[i].fixedArp?chan[i].baseNoteOverride:chan[i].arpOff,chan[i].fixedArp,false,4,chan[i].pitch2); int block=(chan[i].baseFreq&0xf800)>>11; if (fNum<0) fNum=0; if (fNum>2047) { @@ -1041,6 +1041,7 @@ void DivPlatformYM2203::setFlags(const DivConfig& flags) { } CHECK_CUSTOM_CLOCK; noExtMacros=flags.getBool("noExtMacros",false); + fbAllOps=flags.getBool("fbAllOps",false); rate=fm->sample_rate(chipClock); for (int i=0; i<6; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/ym2203ext.cpp b/src/engine/platform/ym2203ext.cpp index 12605a93b..701ae9e5e 100644 --- a/src/engine/platform/ym2203ext.cpp +++ b/src/engine/platform/ym2203ext.cpp @@ -44,7 +44,9 @@ int DivPlatformYM2203Ext::dispatch(DivCommand c) { if (opChan[ch].insChanged) { chan[2].state.alg=ins->fm.alg; - chan[2].state.fb=ins->fm.fb; + if (ch==0 || fbAllOps) { + chan[2].state.fb=ins->fm.fb; + } chan[2].state.op[ordch]=ins->fm.op[ordch]; } @@ -412,7 +414,7 @@ void DivPlatformYM2203Ext::tick(bool sysTick) { if (opChan[i].std.pitch.had) { if (opChan[i].std.pitch.mode) { opChan[i].pitch2+=opChan[i].std.pitch.val; - CLAMP_VAR(opChan[i].pitch2,-32768,32767); + CLAMP_VAR(opChan[i].pitch2,-1048576,1048575); } else { opChan[i].pitch2=opChan[i].std.pitch.val; } diff --git a/src/engine/platform/ym2608.cpp b/src/engine/platform/ym2608.cpp index 924b6dbb9..b5dba5f5e 100644 --- a/src/engine/platform/ym2608.cpp +++ b/src/engine/platform/ym2608.cpp @@ -328,7 +328,7 @@ void DivPlatformYM2608::acquire_combo(short* bufL, short* bufR, size_t start, si if (--delay<1 && !(fm->read(0)&0x80)) { QueuedWrite& w=writes.front(); - if (w.addr<=0x1c || w.addr==0x2d || w.addr==0x2e || w.addr==0x2f || (w.addr>=0x100 && w.addr<=0x12d)) { + if (w.addr<=0x1d || w.addr==0x2d || w.addr==0x2e || w.addr==0x2f || (w.addr>=0x100 && w.addr<=0x12d)) { // ymfm write fm->write(0x0+((w.addr>>8)<<1),w.addr); fm->write(0x1+((w.addr>>8)<<1),w.val); @@ -503,7 +503,7 @@ void DivPlatformYM2608::tick(bool sysTick) { if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { chan[i].pitch2+=chan[i].std.pitch.val; - CLAMP_VAR(chan[i].pitch2,-32768,32767); + CLAMP_VAR(chan[i].pitch2,-1048576,1048575); } else { chan[i].pitch2=chan[i].std.pitch.val; } @@ -1538,6 +1538,7 @@ void DivPlatformYM2608::setFlags(const DivConfig& flags) { } CHECK_CUSTOM_CLOCK; noExtMacros=flags.getBool("noExtMacros",false); + fbAllOps=flags.getBool("fbAllOps",false); rate=fm->sample_rate(chipClock); for (int i=0; i<16; i++) { oscBuf[i]->rate=rate; diff --git a/src/engine/platform/ym2608ext.cpp b/src/engine/platform/ym2608ext.cpp index 47a01d137..0a6abe7a5 100644 --- a/src/engine/platform/ym2608ext.cpp +++ b/src/engine/platform/ym2608ext.cpp @@ -44,7 +44,9 @@ int DivPlatformYM2608Ext::dispatch(DivCommand c) { if (opChan[ch].insChanged) { chan[2].state.alg=ins->fm.alg; - chan[2].state.fb=ins->fm.fb; + if (ch==0 || fbAllOps) { + chan[2].state.fb=ins->fm.fb; + } chan[2].state.fms=ins->fm.fms; chan[2].state.ams=ins->fm.ams; chan[2].state.op[ordch]=ins->fm.op[ordch]; @@ -435,7 +437,7 @@ void DivPlatformYM2608Ext::tick(bool sysTick) { if (opChan[i].std.pitch.had) { if (opChan[i].std.pitch.mode) { opChan[i].pitch2+=opChan[i].std.pitch.val; - CLAMP_VAR(opChan[i].pitch2,-32768,32767); + CLAMP_VAR(opChan[i].pitch2,-1048576,1048575); } else { opChan[i].pitch2=opChan[i].std.pitch.val; } diff --git a/src/engine/platform/ym2610.cpp b/src/engine/platform/ym2610.cpp index 12ac797da..858886d8e 100644 --- a/src/engine/platform/ym2610.cpp +++ b/src/engine/platform/ym2610.cpp @@ -436,7 +436,7 @@ void DivPlatformYM2610::tick(bool sysTick) { if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { chan[i].pitch2+=chan[i].std.pitch.val; - CLAMP_VAR(chan[i].pitch2,-32768,32767); + CLAMP_VAR(chan[i].pitch2,-1048576,1048575); } else { chan[i].pitch2=chan[i].std.pitch.val; } diff --git a/src/engine/platform/ym2610b.cpp b/src/engine/platform/ym2610b.cpp index 0d0d58c21..f53e239df 100644 --- a/src/engine/platform/ym2610b.cpp +++ b/src/engine/platform/ym2610b.cpp @@ -503,7 +503,7 @@ void DivPlatformYM2610B::tick(bool sysTick) { if (chan[i].std.pitch.had) { if (chan[i].std.pitch.mode) { chan[i].pitch2+=chan[i].std.pitch.val; - CLAMP_VAR(chan[i].pitch2,-32768,32767); + CLAMP_VAR(chan[i].pitch2,-1048576,1048575); } else { chan[i].pitch2=chan[i].std.pitch.val; } diff --git a/src/engine/platform/ym2610bext.cpp b/src/engine/platform/ym2610bext.cpp index 207708bde..c8d0b6454 100644 --- a/src/engine/platform/ym2610bext.cpp +++ b/src/engine/platform/ym2610bext.cpp @@ -40,7 +40,9 @@ int DivPlatformYM2610BExt::dispatch(DivCommand c) { if (opChan[ch].insChanged) { chan[extChanOffs].state.alg=ins->fm.alg; - chan[extChanOffs].state.fb=ins->fm.fb; + if (ch==0 || fbAllOps) { + chan[extChanOffs].state.fb=ins->fm.fb; + } chan[extChanOffs].state.fms=ins->fm.fms; chan[extChanOffs].state.ams=ins->fm.ams; chan[extChanOffs].state.op[ordch]=ins->fm.op[ordch]; @@ -431,7 +433,7 @@ void DivPlatformYM2610BExt::tick(bool sysTick) { if (opChan[i].std.pitch.had) { if (opChan[i].std.pitch.mode) { opChan[i].pitch2+=opChan[i].std.pitch.val; - CLAMP_VAR(opChan[i].pitch2,-32768,32767); + CLAMP_VAR(opChan[i].pitch2,-1048576,1048575); } else { opChan[i].pitch2=opChan[i].std.pitch.val; } diff --git a/src/engine/platform/ym2610ext.cpp b/src/engine/platform/ym2610ext.cpp index b4da0878f..54bbd2b7e 100644 --- a/src/engine/platform/ym2610ext.cpp +++ b/src/engine/platform/ym2610ext.cpp @@ -40,7 +40,9 @@ int DivPlatformYM2610Ext::dispatch(DivCommand c) { if (opChan[ch].insChanged) { chan[extChanOffs].state.alg=ins->fm.alg; - chan[extChanOffs].state.fb=ins->fm.fb; + if (ch==0 || fbAllOps) { + chan[extChanOffs].state.fb=ins->fm.fb; + } chan[extChanOffs].state.fms=ins->fm.fms; chan[extChanOffs].state.ams=ins->fm.ams; chan[extChanOffs].state.op[ordch]=ins->fm.op[ordch]; @@ -431,7 +433,7 @@ void DivPlatformYM2610Ext::tick(bool sysTick) { if (opChan[i].std.pitch.had) { if (opChan[i].std.pitch.mode) { opChan[i].pitch2+=opChan[i].std.pitch.val; - CLAMP_VAR(opChan[i].pitch2,-32768,32767); + CLAMP_VAR(opChan[i].pitch2,-1048576,1048575); } else { opChan[i].pitch2=opChan[i].std.pitch.val; } diff --git a/src/engine/platform/ym2610shared.h b/src/engine/platform/ym2610shared.h index 9671c1571..ab1bd0528 100644 --- a/src/engine/platform/ym2610shared.h +++ b/src/engine/platform/ym2610shared.h @@ -221,6 +221,7 @@ class DivPlatformYM2610Base: public DivPlatformOPN { } CHECK_CUSTOM_CLOCK; noExtMacros=flags.getBool("noExtMacros",false); + fbAllOps=flags.getBool("fbAllOps",false); rate=fm->sample_rate(chipClock); for (int i=0; i<16; i++) { oscBuf[i]->rate=rate; diff --git a/src/gui/editControls.cpp b/src/gui/editControls.cpp index f019f766b..912665f60 100644 --- a/src/gui/editControls.cpp +++ b/src/gui/editControls.cpp @@ -537,6 +537,9 @@ void FurnaceGUI::drawMobileControls() { if (ImGui::Button("Stats")) { statsOpen=!statsOpen; } + if (ImGui::Button("Compat Flags")) { + compatFlagsOpen=!compatFlagsOpen; + } ImGui::Separator(); diff --git a/src/gui/fileDialog.h b/src/gui/fileDialog.h index 6e91eddf8..b4a6d46e6 100644 --- a/src/gui/fileDialog.h +++ b/src/gui/fileDialog.h @@ -3,7 +3,7 @@ #include #include -#if defined(_WIN32) || defined(__APPLE__) +#if defined(_WIN64) || defined(__APPLE__) #define USE_NFD #endif diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 0149cc65c..59d23f2e2 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -626,10 +626,10 @@ void FurnaceGUI::autoDetectSystem() { } if (defCountMap.size()!=sysCountMap.size()) continue; isMatch=true; - logV("trying on defCountMap: %s",j.name); + /*logV("trying on defCountMap: %s",j.name); for (std::pair k: defCountMap) { logV("- %s: %d",e->getSystemName(k.first),k.second); - } + }*/ for (std::pair k: defCountMap) { try { if (sysCountMap.at(k.first)!=k.second) { @@ -3879,6 +3879,7 @@ bool FurnaceGUI::loop() { drawSettings(); drawDebug(); drawLog(); + drawCompatFlags(); drawStats(); } else { globalWinFlags=0; diff --git a/src/gui/insEdit.cpp b/src/gui/insEdit.cpp index a85ef1341..1b89de31d 100644 --- a/src/gui/insEdit.cpp +++ b/src/gui/insEdit.cpp @@ -264,7 +264,7 @@ const char* mikeyFeedbackBits[11] = { }; const char* msm5232ControlBits[7]={ - "2'", "4'", "8'", "16'", "sustain", NULL + "16'", "8'", "4'", "2'", "sustain", NULL }; const char* x1_010EnvBits[8]={ diff --git a/src/gui/presets.cpp b/src/gui/presets.cpp index b6a522976..dfdd59a8b 100644 --- a/src/gui/presets.cpp +++ b/src/gui/presets.cpp @@ -1114,479 +1114,6 @@ void FurnaceGUI::initSystemPresets() { ); CATEGORY_END; - CATEGORY_BEGIN("FM","chips which use frequency modulation (FM) to generate sound.\nsome of these also pack more (like square and sample channels)."); - ENTRY( - "Yamaha YM2151 (OPM)", { - CH(DIV_SYSTEM_YM2151, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM2203 (OPN)", { - CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=3") - } - ); - ENTRY( - "Yamaha YM2203 (extended channel 3)", { - CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=3") - } - ); - ENTRY( - "Yamaha YM2608 (OPNA)", { - CH(DIV_SYSTEM_YM2608, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM2608 (extended channel 3)", { - CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM2610 (OPNB)", { - CH(DIV_SYSTEM_YM2610_FULL, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM2610 (extended channel 2)", { - CH(DIV_SYSTEM_YM2610_FULL_EXT, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM2610B (OPNB2)", { - CH(DIV_SYSTEM_YM2610B, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM2610B (extended channel 3)", { - CH(DIV_SYSTEM_YM2610B_EXT, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM2612 (OPN2)", { - CH(DIV_SYSTEM_YM2612, 64, 0, "ladderEffect=true") - } - ); - ENTRY( - "Yamaha YM2612 (extended channel 3)", { - CH(DIV_SYSTEM_YM2612_EXT, 64, 0, "ladderEffect=true") - } - ); - ENTRY( - "Yamaha YM2612 (OPN2) CSM", { - CH(DIV_SYSTEM_YM2612_CSM, 64, 0, "ladderEffect=true") - } - ); - ENTRY( - "Yamaha YM2612 (OPN2) with DualPCM", { - CH(DIV_SYSTEM_YM2612_DUALPCM, 64, 0, "ladderEffect=true") - } - ); - ENTRY( - "Yamaha YM2612 (extended channel 3) with DualPCM", { - CH(DIV_SYSTEM_YM2612_DUALPCM_EXT, 64, 0, "ladderEffect=true") - } - ); - ENTRY( - "Yamaha YM2413 (OPLL)", { - CH(DIV_SYSTEM_OPLL, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM2413 (drums mode)", { - CH(DIV_SYSTEM_OPLL_DRUMS, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM2414 (OPZ)", { - CH(DIV_SYSTEM_OPZ, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM3438 (OPN2C)", { - CH(DIV_SYSTEM_YM2612, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM3438 (extended channel 3)", { - CH(DIV_SYSTEM_YM2612_EXT, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM3438 (OPN2C) CSM", { - CH(DIV_SYSTEM_YM2612_CSM, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM3438 (OPN2C) with DualPCM", { - CH(DIV_SYSTEM_YM2612_DUALPCM, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM3438 (extended channel 3) with DualPCM", { - CH(DIV_SYSTEM_YM2612_DUALPCM_EXT, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM3526 (OPL)", { - CH(DIV_SYSTEM_OPL, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM3526 (drums mode)", { - CH(DIV_SYSTEM_OPL_DRUMS, 64, 0, "") - } - ); - ENTRY( - "Yamaha Y8950", { - CH(DIV_SYSTEM_Y8950, 64, 0, "") - } - ); - ENTRY( - "Yamaha Y8950 (drums mode)", { - CH(DIV_SYSTEM_Y8950_DRUMS, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM3812 (OPL2)", { - CH(DIV_SYSTEM_OPL2, 64, 0, "") - } - ); - ENTRY( - "Yamaha YM3812 (drums mode)", { - CH(DIV_SYSTEM_OPL2_DRUMS, 64, 0, "") - } - ); - ENTRY( - "Yamaha YMF262 (OPL3)", { - CH(DIV_SYSTEM_OPL3, 64, 0, "") - } - ); - ENTRY( - "Yamaha YMF262 (drums mode)", { - CH(DIV_SYSTEM_OPL3_DRUMS, 64, 0, "") - } - ); - if (settings.hiddenSystems) { - ENTRY( - "Yamaha YMU759 (MA-2)", { - CH(DIV_SYSTEM_YMU759, 64, 0, "") - } - ); - } - CATEGORY_END; - - CATEGORY_BEGIN("Square","these chips generate square/pulse tones only (but may include noise)."); - ENTRY( - "TI SN76489", { - CH(DIV_SYSTEM_SMS, 64, 0, "chipType=1") - } - ); - ENTRY( - "TI SN76489A", { - CH(DIV_SYSTEM_SMS, 64, 0, "chipType=4") - } - ); - ENTRY( - "TI SN76496", { - CH(DIV_SYSTEM_SMS, 64, 0, "chipType=5") - } - ); - ENTRY( - "NCR 8496", { - CH(DIV_SYSTEM_SMS, 64, 0, "chipType=6") - } - ); - ENTRY( - "Tandy PSSJ 3-voice sound", { - CH(DIV_SYSTEM_SMS, 64, 0, "chipType=7") - // 8 bit DAC - } - ); - ENTRY( - "Sega PSG (SN76489-like)", { - CH(DIV_SYSTEM_SMS, 64, 0, ""), - } - ); - ENTRY( - "Sega PSG (SN76489-like, Stereo)", { - CH(DIV_SYSTEM_SMS, 64, 0, "chipType=3") - } - ); - ENTRY( - "TI SN94624", { - CH(DIV_SYSTEM_SMS, 64, 0, - "clockSel=6\n" - "chipType=8\n" - ) - } - ); - ENTRY( - "TI SN76494", { - CH(DIV_SYSTEM_SMS, 64, 0, - "clockSel=6\n" - "chipType=9\n" - ) - } - ); - ENTRY( - "Toshiba T6W28", { - CH(DIV_SYSTEM_T6W28, 64, 0, "") - } - ); - ENTRY( - "AY-3-8910", { - CH(DIV_SYSTEM_AY8910, 64, 0, "") - } - ); - ENTRY( - "AY-3-8914", { - CH(DIV_SYSTEM_AY8910, 64, 0, "chipType=3") - } - ); - ENTRY( - "Yamaha YM2149(F)", { - CH(DIV_SYSTEM_AY8910, 64, 0, "chipType=1") - } - ); - ENTRY( - "Philips SAA1099", { - CH(DIV_SYSTEM_SAA1099, 64, 0, "") - } - ); - ENTRY( - "PC Speaker", { - CH(DIV_SYSTEM_PCSPKR, 32, 0, "") - } - ); - ENTRY( - "Pokémon Mini", { - CH(DIV_SYSTEM_POKEMINI, 32, 0, "") - } - ); - ENTRY( - "Commodore VIC", { - CH(DIV_SYSTEM_VIC20, 64, 0, "clockSel=1") - } - ); - ENTRY( - "OKI MSM5232", { - CH(DIV_SYSTEM_MSM5232, 64, 0, "") - } - ); - ENTRY( - "Pong", { - CH(DIV_SYSTEM_PONG, 64, 0, "") - } - ); - CATEGORY_END; - - CATEGORY_BEGIN("Sample","chips/systems which use PCM or ADPCM samples for sound synthesis."); - ENTRY( - "Amiga", { - CH(DIV_SYSTEM_AMIGA, 64, 0, "clockSel=1") - }, - "tickRate=50" - ); - ENTRY( - "SegaPCM", { - CH(DIV_SYSTEM_SEGAPCM, 64, 0, "") - } - ); - ENTRY( - "Capcom QSound", { - CH(DIV_SYSTEM_QSOUND, 64, 0, "") - } - ); - ENTRY( - "Seta/Allumer X1-010", { - CH(DIV_SYSTEM_X1_010, 64, 0, "") - } - ); - ENTRY( - "Yamaha YMZ280B (PCMD8)", { - CH(DIV_SYSTEM_YMZ280B, 64, 0, "") - } - ); - ENTRY( - "Ricoh RF5C68", { - CH(DIV_SYSTEM_RF5C68, 64, 0, "") - } - ); - ENTRY( - "OKI MSM6258", { - CH(DIV_SYSTEM_MSM6258, 64, 0, "") - } - ); - ENTRY( - "OKI MSM6295", { - CH(DIV_SYSTEM_MSM6295, 64, 0, "") - } - ); - ENTRY( - "SNES", { - CH(DIV_SYSTEM_SNES, 64, 0, "") - } - ); - ENTRY( - "Konami K007232", { - CH(DIV_SYSTEM_K007232, 64, 0, "") - } - ); - ENTRY( - "Irem GA20", { - CH(DIV_SYSTEM_GA20, 64, 0, "") - } - ); - ENTRY( - "Generic PCM DAC", { - CH(DIV_SYSTEM_PCM_DAC, 64, 0, "") - } - ); - ENTRY( - "Ensoniq ES5506 (OTTO)", { - CH(DIV_SYSTEM_ES5506, 64, 0, "channels=31") - } - ); - CATEGORY_END; - - CATEGORY_BEGIN("Wavetable","chips which use user-specified waveforms to generate sound."); - ENTRY( - "PC Engine", { - CH(DIV_SYSTEM_PCE, 64, 0, "") - } - ); - ENTRY( - "Commodore PET (pseudo-wavetable)", { - CH(DIV_SYSTEM_PET, 64, 0, "") - }, - "tickRate=50" - ); - ENTRY( - "Konami Bubble System WSG", { - CH(DIV_SYSTEM_BUBSYS_WSG, 64, 0, "") - } - ); - ENTRY( - "Konami SCC", { - CH(DIV_SYSTEM_SCC, 64, 0, "") - } - ); - ENTRY( - "Konami SCC+", { - CH(DIV_SYSTEM_SCC_PLUS, 64, 0, "") - } - ); - ENTRY( - "Namco WSG", { - CH(DIV_SYSTEM_NAMCO, 64, 0, "") - } - ); - ENTRY( - "Namco C15 (8-channel mono)", { - CH(DIV_SYSTEM_NAMCO_15XX, 64, 0, "") - } - ); - ENTRY( - "Namco C30 (8-channel stereo)", { - CH(DIV_SYSTEM_NAMCO_CUS30, 64, 0, "") - } - ); - ENTRY( - "Namco 163", { - CH(DIV_SYSTEM_N163, 64, 0, "") - } - ); - ENTRY( - "Famicom Disk System (chip)", { - CH(DIV_SYSTEM_FDS, 64, 0, "") - } - ); - ENTRY( - "WonderSwan", { - CH(DIV_SYSTEM_SWAN, 64, 0, "") - }, - "tickRate=75.47169811320754716981" - ); - ENTRY( - "Virtual Boy", { - CH(DIV_SYSTEM_VBOY, 64, 0, "") - }, - "tickRate=50.2734877734878" - ); - ENTRY( - "Seta/Allumer X1-010", { - CH(DIV_SYSTEM_X1_010, 64, 0, "") - } - ); - CATEGORY_END; - - CATEGORY_BEGIN("Specialized","chips/systems with unique sound synthesis methods."); - ENTRY( - "MOS Technology SID (6581)", { - CH(DIV_SYSTEM_C64_6581, 64, 0, "clockSel=1") - }, - "tickRate=50.1245421" - ); - ENTRY( - "MOS Technology SID (8580)", { - CH(DIV_SYSTEM_C64_8580, 64, 0, "clockSel=1") - }, - "tickRate=50.1245421" - ); - ENTRY( - "Microchip AY8930", { - CH(DIV_SYSTEM_AY8930, 64, 0, "") - } - ); - ENTRY( - "Game Boy", { - CH(DIV_SYSTEM_GB, 64, 0, "") - } - ); - ENTRY( - "Atari Lynx", { - CH(DIV_SYSTEM_LYNX, 64, 0, "") - } - ); - ENTRY( - "POKEY", { - CH(DIV_SYSTEM_POKEY, 64, 0, "clockSel=1") - }, - "tickRate=50" - ); - ENTRY( - "Atari TIA", { - CH(DIV_SYSTEM_TIA, 64, 0, "") - } - ); - ENTRY( - "NES (Ricoh 2A03)", { - CH(DIV_SYSTEM_NES, 64, 0, "") - } - ); - ENTRY( - "Commander X16 (VERA only)", { - CH(DIV_SYSTEM_VERA, 64, 0, "") - } - ); - ENTRY( - "ZX Spectrum (beeper only)", { - CH(DIV_SYSTEM_SFX_BEEPER, 64, 0, "") - } - ); - if (settings.hiddenSystems) { - ENTRY( - "Dummy System", { - CH(DIV_SYSTEM_DUMMY, 64, 0, "") - } - ); - } - ENTRY( - "tildearrow Sound Unit", { - CH(DIV_SYSTEM_SOUND_UNIT, 64, 0, "") - } - ); - CATEGORY_END; - CATEGORY_BEGIN("Arcade systems","INSERT COIN"); ENTRY( "Pong", { @@ -2574,6 +2101,480 @@ void FurnaceGUI::initSystemPresets() { ); CATEGORY_END; + + CATEGORY_BEGIN("FM","chips which use frequency modulation (FM) to generate sound.\nsome of these also pack more (like square and sample channels)."); + ENTRY( + "Yamaha YM2151 (OPM)", { + CH(DIV_SYSTEM_YM2151, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM2203 (OPN)", { + CH(DIV_SYSTEM_YM2203, 64, 0, "clockSel=3") + } + ); + ENTRY( + "Yamaha YM2203 (extended channel 3)", { + CH(DIV_SYSTEM_YM2203_EXT, 64, 0, "clockSel=3") + } + ); + ENTRY( + "Yamaha YM2608 (OPNA)", { + CH(DIV_SYSTEM_YM2608, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM2608 (extended channel 3)", { + CH(DIV_SYSTEM_YM2608_EXT, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM2610 (OPNB)", { + CH(DIV_SYSTEM_YM2610_FULL, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM2610 (extended channel 2)", { + CH(DIV_SYSTEM_YM2610_FULL_EXT, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM2610B (OPNB2)", { + CH(DIV_SYSTEM_YM2610B, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM2610B (extended channel 3)", { + CH(DIV_SYSTEM_YM2610B_EXT, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM2612 (OPN2)", { + CH(DIV_SYSTEM_YM2612, 64, 0, "ladderEffect=true") + } + ); + ENTRY( + "Yamaha YM2612 (extended channel 3)", { + CH(DIV_SYSTEM_YM2612_EXT, 64, 0, "ladderEffect=true") + } + ); + ENTRY( + "Yamaha YM2612 (OPN2) CSM", { + CH(DIV_SYSTEM_YM2612_CSM, 64, 0, "ladderEffect=true") + } + ); + ENTRY( + "Yamaha YM2612 (OPN2) with DualPCM", { + CH(DIV_SYSTEM_YM2612_DUALPCM, 64, 0, "ladderEffect=true") + } + ); + ENTRY( + "Yamaha YM2612 (extended channel 3) with DualPCM", { + CH(DIV_SYSTEM_YM2612_DUALPCM_EXT, 64, 0, "ladderEffect=true") + } + ); + ENTRY( + "Yamaha YM2413 (OPLL)", { + CH(DIV_SYSTEM_OPLL, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM2413 (drums mode)", { + CH(DIV_SYSTEM_OPLL_DRUMS, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM2414 (OPZ)", { + CH(DIV_SYSTEM_OPZ, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM3438 (OPN2C)", { + CH(DIV_SYSTEM_YM2612, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM3438 (extended channel 3)", { + CH(DIV_SYSTEM_YM2612_EXT, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM3438 (OPN2C) CSM", { + CH(DIV_SYSTEM_YM2612_CSM, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM3438 (OPN2C) with DualPCM", { + CH(DIV_SYSTEM_YM2612_DUALPCM, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM3438 (extended channel 3) with DualPCM", { + CH(DIV_SYSTEM_YM2612_DUALPCM_EXT, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM3526 (OPL)", { + CH(DIV_SYSTEM_OPL, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM3526 (drums mode)", { + CH(DIV_SYSTEM_OPL_DRUMS, 64, 0, "") + } + ); + ENTRY( + "Yamaha Y8950", { + CH(DIV_SYSTEM_Y8950, 64, 0, "") + } + ); + ENTRY( + "Yamaha Y8950 (drums mode)", { + CH(DIV_SYSTEM_Y8950_DRUMS, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM3812 (OPL2)", { + CH(DIV_SYSTEM_OPL2, 64, 0, "") + } + ); + ENTRY( + "Yamaha YM3812 (drums mode)", { + CH(DIV_SYSTEM_OPL2_DRUMS, 64, 0, "") + } + ); + ENTRY( + "Yamaha YMF262 (OPL3)", { + CH(DIV_SYSTEM_OPL3, 64, 0, "") + } + ); + ENTRY( + "Yamaha YMF262 (drums mode)", { + CH(DIV_SYSTEM_OPL3_DRUMS, 64, 0, "") + } + ); + if (settings.hiddenSystems) { + ENTRY( + "Yamaha YMU759 (MA-2)", { + CH(DIV_SYSTEM_YMU759, 64, 0, "") + } + ); + } + CATEGORY_END; + + CATEGORY_BEGIN("Square","these chips generate square/pulse tones only (but may include noise)."); + ENTRY( + "TI SN76489", { + CH(DIV_SYSTEM_SMS, 64, 0, "chipType=1") + } + ); + ENTRY( + "TI SN76489A", { + CH(DIV_SYSTEM_SMS, 64, 0, "chipType=4") + } + ); + ENTRY( + "TI SN76496", { + CH(DIV_SYSTEM_SMS, 64, 0, "chipType=5") + } + ); + ENTRY( + "NCR 8496", { + CH(DIV_SYSTEM_SMS, 64, 0, "chipType=6") + } + ); + ENTRY( + "Tandy PSSJ 3-voice sound", { + CH(DIV_SYSTEM_SMS, 64, 0, "chipType=7") + // 8 bit DAC + } + ); + ENTRY( + "Sega PSG (SN76489-like)", { + CH(DIV_SYSTEM_SMS, 64, 0, ""), + } + ); + ENTRY( + "Sega PSG (SN76489-like, Stereo)", { + CH(DIV_SYSTEM_SMS, 64, 0, "chipType=3") + } + ); + ENTRY( + "TI SN94624", { + CH(DIV_SYSTEM_SMS, 64, 0, + "clockSel=6\n" + "chipType=8\n" + ) + } + ); + ENTRY( + "TI SN76494", { + CH(DIV_SYSTEM_SMS, 64, 0, + "clockSel=6\n" + "chipType=9\n" + ) + } + ); + ENTRY( + "Toshiba T6W28", { + CH(DIV_SYSTEM_T6W28, 64, 0, "") + } + ); + ENTRY( + "AY-3-8910", { + CH(DIV_SYSTEM_AY8910, 64, 0, "") + } + ); + ENTRY( + "AY-3-8914", { + CH(DIV_SYSTEM_AY8910, 64, 0, "chipType=3") + } + ); + ENTRY( + "Yamaha YM2149(F)", { + CH(DIV_SYSTEM_AY8910, 64, 0, "chipType=1") + } + ); + ENTRY( + "Philips SAA1099", { + CH(DIV_SYSTEM_SAA1099, 64, 0, "") + } + ); + ENTRY( + "PC Speaker", { + CH(DIV_SYSTEM_PCSPKR, 32, 0, "") + } + ); + ENTRY( + "Pokémon Mini", { + CH(DIV_SYSTEM_POKEMINI, 32, 0, "") + } + ); + ENTRY( + "Commodore VIC", { + CH(DIV_SYSTEM_VIC20, 64, 0, "clockSel=1") + } + ); + ENTRY( + "OKI MSM5232", { + CH(DIV_SYSTEM_MSM5232, 64, 0, "") + } + ); + ENTRY( + "Pong", { + CH(DIV_SYSTEM_PONG, 64, 0, "") + } + ); + CATEGORY_END; + + CATEGORY_BEGIN("Sample","chips/systems which use PCM or ADPCM samples for sound synthesis."); + ENTRY( + "Amiga", { + CH(DIV_SYSTEM_AMIGA, 64, 0, "clockSel=1") + }, + "tickRate=50" + ); + ENTRY( + "SegaPCM", { + CH(DIV_SYSTEM_SEGAPCM, 64, 0, "") + } + ); + ENTRY( + "Capcom QSound", { + CH(DIV_SYSTEM_QSOUND, 64, 0, "") + } + ); + ENTRY( + "Seta/Allumer X1-010", { + CH(DIV_SYSTEM_X1_010, 64, 0, "") + } + ); + ENTRY( + "Yamaha YMZ280B (PCMD8)", { + CH(DIV_SYSTEM_YMZ280B, 64, 0, "") + } + ); + ENTRY( + "Ricoh RF5C68", { + CH(DIV_SYSTEM_RF5C68, 64, 0, "") + } + ); + ENTRY( + "OKI MSM6258", { + CH(DIV_SYSTEM_MSM6258, 64, 0, "") + } + ); + ENTRY( + "OKI MSM6295", { + CH(DIV_SYSTEM_MSM6295, 64, 0, "") + } + ); + ENTRY( + "SNES", { + CH(DIV_SYSTEM_SNES, 64, 0, "") + } + ); + ENTRY( + "Konami K007232", { + CH(DIV_SYSTEM_K007232, 64, 0, "") + } + ); + ENTRY( + "Irem GA20", { + CH(DIV_SYSTEM_GA20, 64, 0, "") + } + ); + ENTRY( + "Generic PCM DAC", { + CH(DIV_SYSTEM_PCM_DAC, 64, 0, "") + } + ); + ENTRY( + "Ensoniq ES5506 (OTTO)", { + CH(DIV_SYSTEM_ES5506, 64, 0, "channels=31") + } + ); + CATEGORY_END; + + CATEGORY_BEGIN("Wavetable","chips which use user-specified waveforms to generate sound."); + ENTRY( + "PC Engine", { + CH(DIV_SYSTEM_PCE, 64, 0, "") + } + ); + ENTRY( + "Commodore PET (pseudo-wavetable)", { + CH(DIV_SYSTEM_PET, 64, 0, "") + }, + "tickRate=50" + ); + ENTRY( + "Konami Bubble System WSG", { + CH(DIV_SYSTEM_BUBSYS_WSG, 64, 0, "") + } + ); + ENTRY( + "Konami SCC", { + CH(DIV_SYSTEM_SCC, 64, 0, "") + } + ); + ENTRY( + "Konami SCC+", { + CH(DIV_SYSTEM_SCC_PLUS, 64, 0, "") + } + ); + ENTRY( + "Namco WSG", { + CH(DIV_SYSTEM_NAMCO, 64, 0, "") + } + ); + ENTRY( + "Namco C15 (8-channel mono)", { + CH(DIV_SYSTEM_NAMCO_15XX, 64, 0, "") + } + ); + ENTRY( + "Namco C30 (8-channel stereo)", { + CH(DIV_SYSTEM_NAMCO_CUS30, 64, 0, "") + } + ); + ENTRY( + "Namco 163", { + CH(DIV_SYSTEM_N163, 64, 0, "") + } + ); + ENTRY( + "Famicom Disk System (chip)", { + CH(DIV_SYSTEM_FDS, 64, 0, "") + } + ); + ENTRY( + "WonderSwan", { + CH(DIV_SYSTEM_SWAN, 64, 0, "") + }, + "tickRate=75.47169811320754716981" + ); + ENTRY( + "Virtual Boy", { + CH(DIV_SYSTEM_VBOY, 64, 0, "") + }, + "tickRate=50.2734877734878" + ); + ENTRY( + "Seta/Allumer X1-010", { + CH(DIV_SYSTEM_X1_010, 64, 0, "") + } + ); + CATEGORY_END; + + CATEGORY_BEGIN("Specialized","chips/systems with unique sound synthesis methods."); + ENTRY( + "MOS Technology SID (6581)", { + CH(DIV_SYSTEM_C64_6581, 64, 0, "clockSel=1") + }, + "tickRate=50.1245421" + ); + ENTRY( + "MOS Technology SID (8580)", { + CH(DIV_SYSTEM_C64_8580, 64, 0, "clockSel=1") + }, + "tickRate=50.1245421" + ); + ENTRY( + "Microchip AY8930", { + CH(DIV_SYSTEM_AY8930, 64, 0, "") + } + ); + ENTRY( + "Game Boy", { + CH(DIV_SYSTEM_GB, 64, 0, "") + } + ); + ENTRY( + "Atari Lynx", { + CH(DIV_SYSTEM_LYNX, 64, 0, "") + } + ); + ENTRY( + "POKEY", { + CH(DIV_SYSTEM_POKEY, 64, 0, "clockSel=1") + }, + "tickRate=50" + ); + ENTRY( + "Atari TIA", { + CH(DIV_SYSTEM_TIA, 64, 0, "") + } + ); + ENTRY( + "NES (Ricoh 2A03)", { + CH(DIV_SYSTEM_NES, 64, 0, "") + } + ); + ENTRY( + "Commander X16 (VERA only)", { + CH(DIV_SYSTEM_VERA, 64, 0, "") + } + ); + ENTRY( + "ZX Spectrum (beeper only)", { + CH(DIV_SYSTEM_SFX_BEEPER, 64, 0, "") + } + ); + if (settings.hiddenSystems) { + ENTRY( + "Dummy System", { + CH(DIV_SYSTEM_DUMMY, 64, 0, "") + } + ); + } + ENTRY( + "tildearrow Sound Unit", { + CH(DIV_SYSTEM_SOUND_UNIT, 64, 0, "") + } + ); + CATEGORY_END; + CATEGORY_BEGIN("DefleMask-compatible","these configurations are compatible with DefleMask.\nselect this if you need to save as .dmf or work with that program."); ENTRY( "Sega Genesis", { diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 2abcc67ea..2b6701848 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -40,8 +40,9 @@ #define POWER_SAVE_DEFAULT 0 #endif -#if defined(__HAIKU__) || defined(IS_MOBILE) +#if defined(__HAIKU__) || defined(IS_MOBILE) || (defined(_WIN32) && !defined(_WIN64)) // NFD doesn't support Haiku +// NFD doesn't support Windows XP either #define SYS_FILE_DIALOG_DEFAULT 0 #else #define SYS_FILE_DIALOG_DEFAULT 1 diff --git a/src/gui/sysConf.cpp b/src/gui/sysConf.cpp index aeac2de1d..9ba31ce7f 100644 --- a/src/gui/sysConf.cpp +++ b/src/gui/sysConf.cpp @@ -31,10 +31,12 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo case DIV_SYSTEM_YM2612: case DIV_SYSTEM_YM2612_EXT: case DIV_SYSTEM_YM2612_DUALPCM: - case DIV_SYSTEM_YM2612_DUALPCM_EXT: { + case DIV_SYSTEM_YM2612_DUALPCM_EXT: + case DIV_SYSTEM_YM2612_CSM: { int clockSel=flags.getInt("clockSel",0); bool ladder=flags.getBool("ladderEffect",0); bool noExtMacros=flags.getBool("noExtMacros",false); + bool fbAllOps=flags.getBool("fbAllOps",false); if (ImGui::RadioButton("NTSC (7.67MHz)",clockSel==0)) { clockSel=0; @@ -59,10 +61,13 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo if (ImGui::Checkbox("Enable DAC distortion",&ladder)) { altered=true; } - if (type==DIV_SYSTEM_YM2612_EXT || type==DIV_SYSTEM_YM2612_DUALPCM_EXT) { + if (type==DIV_SYSTEM_YM2612_EXT || type==DIV_SYSTEM_YM2612_DUALPCM_EXT || type==DIV_SYSTEM_YM2612_CSM) { if (ImGui::Checkbox("Disable ExtCh FM macros (compatibility)",&noExtMacros)) { altered=true; } + if (ImGui::Checkbox("Ins change in ExtCh operator 2-4 affects FB (compatibility)",&fbAllOps)) { + altered=true; + } } if (altered) { @@ -70,6 +75,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo flags.set("clockSel",clockSel); flags.set("ladderEffect",ladder); flags.set("noExtMacros",noExtMacros); + flags.set("fbAllOps",fbAllOps); }); } break; @@ -457,12 +463,15 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo } case DIV_SYSTEM_YM2610: case DIV_SYSTEM_YM2610_EXT: + case DIV_SYSTEM_YM2610_CSM: case DIV_SYSTEM_YM2610_FULL: case DIV_SYSTEM_YM2610_FULL_EXT: case DIV_SYSTEM_YM2610B: - case DIV_SYSTEM_YM2610B_EXT: { + case DIV_SYSTEM_YM2610B_EXT: + case DIV_SYSTEM_YM2610B_CSM: { int clockSel=flags.getInt("clockSel",0); bool noExtMacros=flags.getBool("noExtMacros",false); + bool fbAllOps=flags.getBool("fbAllOps",false); if (ImGui::RadioButton("8MHz (Neo Geo MVS)",clockSel==0)) { clockSel=0; @@ -473,16 +482,20 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo altered=true; } - if (type==DIV_SYSTEM_YM2610_EXT || type==DIV_SYSTEM_YM2610_FULL_EXT || type==DIV_SYSTEM_YM2610B_EXT) { + if (type==DIV_SYSTEM_YM2610_EXT || type==DIV_SYSTEM_YM2610_FULL_EXT || type==DIV_SYSTEM_YM2610B_EXT || type==DIV_SYSTEM_YM2610_CSM || type==DIV_SYSTEM_YM2610B_CSM) { if (ImGui::Checkbox("Disable ExtCh FM macros (compatibility)",&noExtMacros)) { altered=true; } + if (ImGui::Checkbox("Ins change in ExtCh operator 2-4 affects FB (compatibility)",&fbAllOps)) { + altered=true; + } } if (altered) { e->lockSave([&]() { flags.set("clockSel",clockSel); flags.set("noExtMacros",noExtMacros); + flags.set("fbAllOps",fbAllOps); }); } break; @@ -851,10 +864,12 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo break; } case DIV_SYSTEM_YM2203: - case DIV_SYSTEM_YM2203_EXT: { + case DIV_SYSTEM_YM2203_EXT: + case DIV_SYSTEM_YM2203_CSM: { int clockSel=flags.getInt("clockSel",0); int prescale=flags.getInt("prescale",0); bool noExtMacros=flags.getBool("noExtMacros",false); + bool fbAllOps=flags.getBool("fbAllOps",false); ImGui::Text("Clock rate:"); if (ImGui::RadioButton("3.58MHz (NTSC)",clockSel==0)) { @@ -895,10 +910,13 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo altered=true; } - if (type==DIV_SYSTEM_YM2203_EXT) { + if (type==DIV_SYSTEM_YM2203_EXT || type==DIV_SYSTEM_YM2203_CSM) { if (ImGui::Checkbox("Disable ExtCh FM macros (compatibility)",&noExtMacros)) { altered=true; } + if (ImGui::Checkbox("Ins change in ExtCh operator 2-4 affects FB (compatibility)",&fbAllOps)) { + altered=true; + } } if (altered) { @@ -906,15 +924,18 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo flags.set("clockSel",clockSel); flags.set("prescale",prescale); flags.set("noExtMacros",noExtMacros); + flags.set("fbAllOps",fbAllOps); }); } break; } case DIV_SYSTEM_YM2608: - case DIV_SYSTEM_YM2608_EXT: { + case DIV_SYSTEM_YM2608_EXT: + case DIV_SYSTEM_YM2608_CSM: { int clockSel=flags.getInt("clockSel",0); int prescale=flags.getInt("prescale",0); bool noExtMacros=flags.getBool("noExtMacros",false); + bool fbAllOps=flags.getBool("fbAllOps",false); ImGui::Text("Clock rate:"); if (ImGui::RadioButton("8MHz (Arcade)",clockSel==0)) { @@ -939,10 +960,13 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo altered=true; } - if (type==DIV_SYSTEM_YM2608_EXT) { + if (type==DIV_SYSTEM_YM2608_EXT || type==DIV_SYSTEM_YM2608_CSM) { if (ImGui::Checkbox("Disable ExtCh FM macros (compatibility)",&noExtMacros)) { altered=true; } + if (ImGui::Checkbox("Ins change in ExtCh operator 2-4 affects FB (compatibility)",&fbAllOps)) { + altered=true; + } } if (altered) { @@ -950,6 +974,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo flags.set("clockSel",clockSel); flags.set("prescale",prescale); flags.set("noExtMacros",noExtMacros); + flags.set("fbAllOps",fbAllOps); }); } break; @@ -1490,7 +1515,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo ImGui::Text("Initial part volume (channel 1-4):"); for (int i=0; i<4; i++) { - snprintf(temp,63,"%d'##GRPV%d",16>>i,i); + snprintf(temp,63,"%d'##GRPV%d",2<255) groupVol[i]=255; @@ -1500,7 +1525,7 @@ bool FurnaceGUI::drawSysConf(int chan, DivSystem type, DivConfig& flags, bool mo ImGui::Text("Initial part volume (channel 5-8):"); for (int i=4; i<8; i++) { - snprintf(temp,63,"%d'##GRPV%d",16>>(i-4),i); + snprintf(temp,63,"%d'##GRPV%d",2<<(i-4),i); if (CWSliderInt(temp,&groupVol[i],0,255)) { if (groupVol[i]<0) groupVol[i]=0; if (groupVol[i]>255) groupVol[i]=255;