From 378ba6fe80ecb62f7eb24f14c2652e0cc9096f29 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Sun, 11 Jan 2026 19:06:58 -0500 Subject: [PATCH] hide soft panning effects on hard panning chips issue #2739 --- .github/workflows/build.yml | 2 +- src/engine/dispatch.h | 6 ++++++ src/engine/platform/abstract.cpp | 4 ++++ src/engine/platform/bifurcator.cpp | 4 ++++ src/engine/platform/bifurcator.h | 1 + src/engine/platform/c140.cpp | 4 ++++ src/engine/platform/c140.h | 1 + src/engine/platform/dave.cpp | 4 ++++ src/engine/platform/dave.h | 1 + src/engine/platform/es5506.cpp | 4 ++++ src/engine/platform/es5506.h | 1 + src/engine/platform/gbaminmod.cpp | 4 ++++ src/engine/platform/gbaminmod.h | 1 + src/engine/platform/k007232.cpp | 4 ++++ src/engine/platform/k007232.h | 1 + src/engine/platform/k053260.cpp | 4 ++++ src/engine/platform/k053260.h | 1 + src/engine/platform/lynx.cpp | 4 ++++ src/engine/platform/lynx.h | 1 + src/engine/platform/multipcm.cpp | 4 ++++ src/engine/platform/multipcm.h | 1 + src/engine/platform/namcowsg.cpp | 4 ++++ src/engine/platform/namcowsg.h | 1 + src/engine/platform/nds.cpp | 4 ++++ src/engine/platform/nds.h | 1 + src/engine/platform/opl.cpp | 4 ++++ src/engine/platform/opl.h | 1 + src/engine/platform/pce.cpp | 4 ++++ src/engine/platform/pce.h | 1 + src/engine/platform/pcmdac.cpp | 4 ++++ src/engine/platform/pcmdac.h | 1 + src/engine/platform/powernoise.cpp | 4 ++++ src/engine/platform/powernoise.h | 1 + src/engine/platform/qsound.cpp | 4 ++++ src/engine/platform/qsound.h | 1 + src/engine/platform/rf5c68.cpp | 4 ++++ src/engine/platform/rf5c68.h | 1 + src/engine/platform/saa.cpp | 4 ++++ src/engine/platform/saa.h | 1 + src/engine/platform/segapcm.cpp | 4 ++++ src/engine/platform/segapcm.h | 1 + src/engine/platform/sid3.cpp | 4 ++++ src/engine/platform/sid3.h | 1 + src/engine/platform/snes.cpp | 4 ++++ src/engine/platform/snes.h | 1 + src/engine/platform/su.cpp | 4 ++++ src/engine/platform/su.h | 1 + src/engine/platform/swan.cpp | 4 ++++ src/engine/platform/swan.h | 1 + src/engine/platform/t6w28.cpp | 4 ++++ src/engine/platform/t6w28.h | 1 + src/engine/platform/vb.cpp | 4 ++++ src/engine/platform/vb.h | 1 + src/engine/platform/x1_010.cpp | 4 ++++ src/engine/platform/x1_010.h | 1 + src/engine/platform/ymz280b.cpp | 4 ++++ src/engine/platform/ymz280b.h | 1 + src/gui/effectList.cpp | 5 +++++ 58 files changed, 151 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8092888d0..dc57589f7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -11,7 +11,7 @@ defaults: shell: bash env: - BUILD_TYPE: Debug + BUILD_TYPE: Release jobs: build: diff --git a/src/engine/dispatch.h b/src/engine/dispatch.h index 5c277bb35..eb3c37a82 100644 --- a/src/engine/dispatch.h +++ b/src/engine/dispatch.h @@ -830,6 +830,12 @@ class DivDispatch { */ virtual bool isVolGlobal(); + /** + * test whether a channel supports soft panning. + * @return truth. + */ + virtual bool hasSoftPan(int ch); + /** * map MIDI velocity (from 0 to 127) to chip volume. * @param ch the chip channel. -1 means N/A. diff --git a/src/engine/platform/abstract.cpp b/src/engine/platform/abstract.cpp index bb3b40030..6edb24d22 100644 --- a/src/engine/platform/abstract.cpp +++ b/src/engine/platform/abstract.cpp @@ -107,6 +107,10 @@ bool DivDispatch::isVolGlobal() { return false; } +bool DivDispatch::hasSoftPan(int ch) { + return false; +} + int DivDispatch::mapVelocity(int ch, float vel) { const int volMax=MAX(1,dispatch(DivCommand(DIV_CMD_GET_VOLMAX,MAX(ch,0)))); return round(vel*volMax); diff --git a/src/engine/platform/bifurcator.cpp b/src/engine/platform/bifurcator.cpp index f67f69f50..4d33ae454 100644 --- a/src/engine/platform/bifurcator.cpp +++ b/src/engine/platform/bifurcator.cpp @@ -326,6 +326,10 @@ int DivPlatformBifurcator::getOutputCount() { return 2; } +bool DivPlatformBifurcator::hasSoftPan(int ch) { + return true; +} + DivMacroInt* DivPlatformBifurcator::getChanMacroInt(int ch) { return &chan[ch].std; } diff --git a/src/engine/platform/bifurcator.h b/src/engine/platform/bifurcator.h index 4023b50da..bc3ac3832 100644 --- a/src/engine/platform/bifurcator.h +++ b/src/engine/platform/bifurcator.h @@ -62,6 +62,7 @@ class DivPlatformBifurcator: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); DivMacroInt* getChanMacroInt(int ch); unsigned short getPan(int chan); void setFlags(const DivConfig& flags); diff --git a/src/engine/platform/c140.cpp b/src/engine/platform/c140.cpp index f6ea8893a..4558260b7 100644 --- a/src/engine/platform/c140.cpp +++ b/src/engine/platform/c140.cpp @@ -535,6 +535,10 @@ int DivPlatformC140::getOutputCount() { return 2; } +bool DivPlatformC140::hasSoftPan(int ch) { + return true; +} + void DivPlatformC140::notifyInsChange(int ins) { for (int i=0; i=pcmChanOffs); +} + bool DivPlatformOPL::keyOffAffectsArp(int ch) { return false; } diff --git a/src/engine/platform/opl.h b/src/engine/platform/opl.h index b06b95962..676e7d4a9 100644 --- a/src/engine/platform/opl.h +++ b/src/engine/platform/opl.h @@ -203,6 +203,7 @@ class DivPlatformOPL: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); void setCore(unsigned char which); void setOPLType(int type, bool drums); bool keyOffAffectsArp(int ch); diff --git a/src/engine/platform/pce.cpp b/src/engine/platform/pce.cpp index c410c3d09..66ac20fb1 100644 --- a/src/engine/platform/pce.cpp +++ b/src/engine/platform/pce.cpp @@ -610,6 +610,10 @@ int DivPlatformPCE::getOutputCount() { return 2; } +bool DivPlatformPCE::hasSoftPan(int ch) { + return true; +} + bool DivPlatformPCE::keyOffAffectsArp(int ch) { return true; } diff --git a/src/engine/platform/pce.h b/src/engine/platform/pce.h index 07cf6a1b4..cbcae987f 100644 --- a/src/engine/platform/pce.h +++ b/src/engine/platform/pce.h @@ -95,6 +95,7 @@ class DivPlatformPCE: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); bool keyOffAffectsArp(int ch); bool hasAcquireDirect(); void setFlags(const DivConfig& flags); diff --git a/src/engine/platform/pcmdac.cpp b/src/engine/platform/pcmdac.cpp index 023cad6d7..17722851b 100644 --- a/src/engine/platform/pcmdac.cpp +++ b/src/engine/platform/pcmdac.cpp @@ -544,6 +544,10 @@ int DivPlatformPCMDAC::getOutputCount() { return 2; } +bool DivPlatformPCMDAC::hasSoftPan(int ch) { + return outStereo; +} + DivMacroInt* DivPlatformPCMDAC::getChanMacroInt(int ch) { if (ch>=chans) return NULL; return &chan[ch].std; diff --git a/src/engine/platform/pcmdac.h b/src/engine/platform/pcmdac.h index c6d22179e..59ec24e62 100644 --- a/src/engine/platform/pcmdac.h +++ b/src/engine/platform/pcmdac.h @@ -80,6 +80,7 @@ class DivPlatformPCMDAC: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); DivMacroInt* getChanMacroInt(int ch); unsigned short getPan(int chan); DivSamplePos getSamplePos(int ch); diff --git a/src/engine/platform/powernoise.cpp b/src/engine/platform/powernoise.cpp index 8051ed2ce..735462909 100644 --- a/src/engine/platform/powernoise.cpp +++ b/src/engine/platform/powernoise.cpp @@ -494,6 +494,10 @@ int DivPlatformPowerNoise::getOutputCount() { return 2; } +bool DivPlatformPowerNoise::hasSoftPan(int ch) { + return true; +} + bool DivPlatformPowerNoise::keyOffAffectsArp(int ch) { return true; } diff --git a/src/engine/platform/powernoise.h b/src/engine/platform/powernoise.h index 867269af8..28a487830 100644 --- a/src/engine/platform/powernoise.h +++ b/src/engine/platform/powernoise.h @@ -94,6 +94,7 @@ class DivPlatformPowerNoise: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); bool keyOffAffectsArp(int ch); void setFlags(const DivConfig& flags); void notifyWaveChange(int wave); diff --git a/src/engine/platform/qsound.cpp b/src/engine/platform/qsound.cpp index 213de85f1..dd7969960 100644 --- a/src/engine/platform/qsound.cpp +++ b/src/engine/platform/qsound.cpp @@ -676,6 +676,10 @@ int DivPlatformQSound::getOutputCount() { return 2; } +bool DivPlatformQSound::hasSoftPan(int ch) { + return true; +} + bool DivPlatformQSound::keyOffAffectsArp(int ch) { return true; } diff --git a/src/engine/platform/qsound.h b/src/engine/platform/qsound.h index d78d50560..111b21eb9 100644 --- a/src/engine/platform/qsound.h +++ b/src/engine/platform/qsound.h @@ -81,6 +81,7 @@ class DivPlatformQSound: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); bool keyOffAffectsArp(int ch); void setFlags(const DivConfig& flags); void notifyInsChange(int ins); diff --git a/src/engine/platform/rf5c68.cpp b/src/engine/platform/rf5c68.cpp index 45a16255a..0142c83b8 100644 --- a/src/engine/platform/rf5c68.cpp +++ b/src/engine/platform/rf5c68.cpp @@ -357,6 +357,10 @@ int DivPlatformRF5C68::getOutputCount() { return 2; } +bool DivPlatformRF5C68::hasSoftPan(int ch) { + return true; +} + void DivPlatformRF5C68::notifyInsChange(int ins) { for (int i=0; i<8; i++) { if (chan[i].ins==ins) { diff --git a/src/engine/platform/rf5c68.h b/src/engine/platform/rf5c68.h index c2081d1fa..7c7348f97 100644 --- a/src/engine/platform/rf5c68.h +++ b/src/engine/platform/rf5c68.h @@ -69,6 +69,7 @@ class DivPlatformRF5C68: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); void setChipModel(int type); void notifyInsChange(int ins); void notifyWaveChange(int wave); diff --git a/src/engine/platform/saa.cpp b/src/engine/platform/saa.cpp index 5283a5176..3adbcd21f 100644 --- a/src/engine/platform/saa.cpp +++ b/src/engine/platform/saa.cpp @@ -415,6 +415,10 @@ int DivPlatformSAA1099::getOutputCount() { return 2; } +bool DivPlatformSAA1099::hasSoftPan(int ch) { + return true; +} + int DivPlatformSAA1099::getPortaFloor(int ch) { return 12; } diff --git a/src/engine/platform/saa.h b/src/engine/platform/saa.h index 056e9a278..ee627083b 100644 --- a/src/engine/platform/saa.h +++ b/src/engine/platform/saa.h @@ -83,6 +83,7 @@ class DivPlatformSAA1099: public DivDispatch { void muteChannel(int ch, bool mute); void setFlags(const DivConfig& flags); int getOutputCount(); + bool hasSoftPan(int ch); int getPortaFloor(int ch); bool keyOffAffectsArp(int ch); bool getLegacyAlwaysSetVolume(); diff --git a/src/engine/platform/segapcm.cpp b/src/engine/platform/segapcm.cpp index 877d76f4d..3599081f7 100644 --- a/src/engine/platform/segapcm.cpp +++ b/src/engine/platform/segapcm.cpp @@ -533,6 +533,10 @@ int DivPlatformSegaPCM::getOutputCount() { return 2; } +bool DivPlatformSegaPCM::hasSoftPan(int ch) { + return true; +} + int DivPlatformSegaPCM::init(DivEngine* p, int channels, int sugRate, const DivConfig& flags) { parent=p; dumpWrites=false; diff --git a/src/engine/platform/segapcm.h b/src/engine/platform/segapcm.h index e00fb0d74..2a6ea589e 100644 --- a/src/engine/platform/segapcm.h +++ b/src/engine/platform/segapcm.h @@ -104,6 +104,7 @@ class DivPlatformSegaPCM: public DivDispatch { void renderSamples(int chipID); void setFlags(const DivConfig& flags); int getOutputCount(); + bool hasSoftPan(int ch); bool getLegacyAlwaysSetVolume(); void poke(unsigned int addr, unsigned short val); void poke(std::vector& wlist); diff --git a/src/engine/platform/sid3.cpp b/src/engine/platform/sid3.cpp index 9dd44849c..a33092dec 100644 --- a/src/engine/platform/sid3.cpp +++ b/src/engine/platform/sid3.cpp @@ -1332,6 +1332,10 @@ int DivPlatformSID3::getOutputCount() { return 2; } +bool DivPlatformSID3::hasSoftPan(int ch) { + return true; +} + bool DivPlatformSID3::getDCOffRequired() { return false; diff --git a/src/engine/platform/sid3.h b/src/engine/platform/sid3.h index f4acc43ec..2c30078d8 100644 --- a/src/engine/platform/sid3.h +++ b/src/engine/platform/sid3.h @@ -269,6 +269,7 @@ class DivPlatformSID3: public DivDispatch { const char** getRegisterSheet(); int init(DivEngine* parent, int channels, int sugRate, const DivConfig& flags); int getOutputCount(); + bool hasSoftPan(int ch); void getPaired(int ch, std::vector& ret); void quit(); ~DivPlatformSID3(); diff --git a/src/engine/platform/snes.cpp b/src/engine/platform/snes.cpp index be76b48b3..e2c30213b 100644 --- a/src/engine/platform/snes.cpp +++ b/src/engine/platform/snes.cpp @@ -919,6 +919,10 @@ int DivPlatformSNES::getOutputCount() { return 2; } +bool DivPlatformSNES::hasSoftPan(int ch) { + return true; +} + void DivPlatformSNES::notifyInsChange(int ins) { for (int i=0; i<8; i++) { if (chan[i].ins==ins) { diff --git a/src/engine/platform/snes.h b/src/engine/platform/snes.h index 306bf653d..1b3ed315c 100644 --- a/src/engine/platform/snes.h +++ b/src/engine/platform/snes.h @@ -117,6 +117,7 @@ class DivPlatformSNES: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); void notifyInsChange(int ins); void notifyWaveChange(int wave); void setFlags(const DivConfig& flags); diff --git a/src/engine/platform/su.cpp b/src/engine/platform/su.cpp index 5195dabbd..faa2e29af 100644 --- a/src/engine/platform/su.cpp +++ b/src/engine/platform/su.cpp @@ -634,6 +634,10 @@ int DivPlatformSoundUnit::getOutputCount() { return 2; } +bool DivPlatformSoundUnit::hasSoftPan(int ch) { + return true; +} + bool DivPlatformSoundUnit::keyOffAffectsArp(int ch) { return true; } diff --git a/src/engine/platform/su.h b/src/engine/platform/su.h index 0ccfb4774..c04ca54fa 100644 --- a/src/engine/platform/su.h +++ b/src/engine/platform/su.h @@ -126,6 +126,7 @@ class DivPlatformSoundUnit: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); bool keyOffAffectsArp(int ch); void setFlags(const DivConfig& flags); void notifyInsDeletion(void* ins); diff --git a/src/engine/platform/swan.cpp b/src/engine/platform/swan.cpp index 19ba44719..c6cd46afc 100644 --- a/src/engine/platform/swan.cpp +++ b/src/engine/platform/swan.cpp @@ -661,6 +661,10 @@ int DivPlatformSwan::getOutputCount() { return (stereo || useMdfn)?2:1; } +bool DivPlatformSwan::hasSoftPan(int ch) { + return (stereo || useMdfn); +} + bool DivPlatformSwan::hasAcquireDirect() { return useMdfn; } diff --git a/src/engine/platform/swan.h b/src/engine/platform/swan.h index 64707d805..f676522c0 100644 --- a/src/engine/platform/swan.h +++ b/src/engine/platform/swan.h @@ -82,6 +82,7 @@ class DivPlatformSwan: public DivDispatch { void notifyWaveChange(int wave); void notifyInsDeletion(void* ins); int getOutputCount(); + bool hasSoftPan(int ch); bool hasAcquireDirect(); void setUseMdfn(bool use); void poke(unsigned int addr, unsigned short val); diff --git a/src/engine/platform/t6w28.cpp b/src/engine/platform/t6w28.cpp index 44276f82d..aa43d7253 100644 --- a/src/engine/platform/t6w28.cpp +++ b/src/engine/platform/t6w28.cpp @@ -358,6 +358,10 @@ int DivPlatformT6W28::getOutputCount() { return 2; } +bool DivPlatformT6W28::hasSoftPan(int ch) { + return true; +} + bool DivPlatformT6W28::keyOffAffectsArp(int ch) { return true; } diff --git a/src/engine/platform/t6w28.h b/src/engine/platform/t6w28.h index dd8bbf9c6..accf7f36e 100644 --- a/src/engine/platform/t6w28.h +++ b/src/engine/platform/t6w28.h @@ -72,6 +72,7 @@ class DivPlatformT6W28: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); bool keyOffAffectsArp(int ch); bool hasAcquireDirect(); void setFlags(const DivConfig& flags); diff --git a/src/engine/platform/vb.cpp b/src/engine/platform/vb.cpp index a0be3efb5..dd705b07f 100644 --- a/src/engine/platform/vb.cpp +++ b/src/engine/platform/vb.cpp @@ -565,6 +565,10 @@ int DivPlatformVB::getOutputCount() { return 2; } +bool DivPlatformVB::hasSoftPan(int ch) { + return true; +} + bool DivPlatformVB::keyOffAffectsArp(int ch) { return true; } diff --git a/src/engine/platform/vb.h b/src/engine/platform/vb.h index 1a95f39b5..ecc755ba9 100644 --- a/src/engine/platform/vb.h +++ b/src/engine/platform/vb.h @@ -90,6 +90,7 @@ class DivPlatformVB: public DivDispatch { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); bool keyOffAffectsArp(int ch); bool hasAcquireDirect(); float getPostAmp(); diff --git a/src/engine/platform/x1_010.cpp b/src/engine/platform/x1_010.cpp index 1ca69e262..0c4e95912 100644 --- a/src/engine/platform/x1_010.cpp +++ b/src/engine/platform/x1_010.cpp @@ -890,6 +890,10 @@ int DivPlatformX1_010::getOutputCount() { return stereo?2:1; } +bool DivPlatformX1_010::hasSoftPan(int ch) { + return true; +} + bool DivPlatformX1_010::keyOffAffectsArp(int ch) { return true; } diff --git a/src/engine/platform/x1_010.h b/src/engine/platform/x1_010.h index 721400914..258d526ea 100644 --- a/src/engine/platform/x1_010.h +++ b/src/engine/platform/x1_010.h @@ -141,6 +141,7 @@ class DivPlatformX1_010: public DivDispatch, public vgsound_emu_mem_intf { void tick(bool sysTick=true); void muteChannel(int ch, bool mute); int getOutputCount(); + bool hasSoftPan(int ch); bool keyOffAffectsArp(int ch); float getPostAmp(); void setFlags(const DivConfig& flags); diff --git a/src/engine/platform/ymz280b.cpp b/src/engine/platform/ymz280b.cpp index 55350818a..5f3a5baf6 100644 --- a/src/engine/platform/ymz280b.cpp +++ b/src/engine/platform/ymz280b.cpp @@ -395,6 +395,10 @@ int DivPlatformYMZ280B::getOutputCount() { return 2; } +bool DivPlatformYMZ280B::hasSoftPan(int ch) { + return true; +} + void DivPlatformYMZ280B::notifyInsChange(int ins) { for (int i=0; i<8; i++) { if (chan[i].ins==ins) { diff --git a/src/engine/platform/ymz280b.h b/src/engine/platform/ymz280b.h index cd7191b86..3485c43bc 100644 --- a/src/engine/platform/ymz280b.h +++ b/src/engine/platform/ymz280b.h @@ -70,6 +70,7 @@ class DivPlatformYMZ280B: public DivDispatch { void muteChannel(int ch, bool mute); float getPostAmp(); int getOutputCount(); + bool hasSoftPan(int ch); void setChipModel(int type); void notifyInsChange(int ins); void notifyWaveChange(int wave); diff --git a/src/gui/effectList.cpp b/src/gui/effectList.cpp index 284b8cb1a..4ce1c22d0 100644 --- a/src/gui/effectList.cpp +++ b/src/gui/effectList.cpp @@ -61,6 +61,11 @@ void FurnaceGUI::drawEffectList() { if (outputs<2) { continue; } + if (!dispatch->hasSoftPan(e->song.dispatchChanOfChan[cursor.xCoarse])) { + if (i==0x80) continue; + if (i==0x83) continue; + if (i==0x84) continue; + } if (outputs<3) { if (i>=0x88 && i<=0x8f) { continue;