hide soft panning effects on hard panning chips

issue #2739
This commit is contained in:
tildearrow 2026-01-11 19:06:58 -05:00
parent 22ff10d7f0
commit 378ba6fe80
58 changed files with 151 additions and 1 deletions

View file

@ -11,7 +11,7 @@ defaults:
shell: bash
env:
BUILD_TYPE: Debug
BUILD_TYPE: Release
jobs:
build:

View file

@ -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.

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -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<totalChans; i++) {
if (chan[i].ins==ins) {

View file

@ -99,6 +99,7 @@ class DivPlatformC140: 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 notifyInsDeletion(void* ins);

View file

@ -589,6 +589,10 @@ int DivPlatformDave::getOutputCount() {
return 2;
}
bool DivPlatformDave::hasSoftPan(int ch) {
return true;
}
bool DivPlatformDave::keyOffAffectsArp(int ch) {
return true;
}

View file

@ -87,6 +87,7 @@ class DivPlatformDave: 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);

View file

@ -1355,6 +1355,10 @@ int DivPlatformES5506::getOutputCount() {
return 12;
}
bool DivPlatformES5506::hasSoftPan(int ch) {
return true;
}
bool DivPlatformES5506::keyOffAffectsArp(int ch) {
return true;
}

View file

@ -307,6 +307,7 @@ class DivPlatformES5506: public DivDispatch, public es550x_intf {
virtual void tick(bool sysTick=true) override;
virtual void muteChannel(int ch, bool mute) override;
virtual int getOutputCount() override;
virtual bool hasSoftPan(int ch) override;
virtual bool keyOffAffectsArp(int ch) override;
virtual void setFlags(const DivConfig& flags) override;
virtual void notifyInsChange(int ins) override;

View file

@ -617,6 +617,10 @@ int DivPlatformGBAMinMod::getOutputCount() {
return 2;
}
bool DivPlatformGBAMinMod::hasSoftPan(int ch) {
return true;
}
void DivPlatformGBAMinMod::notifyInsChange(int ins) {
for (int i=0; i<16; i++) {
if (chan[i].ins==ins) {

View file

@ -106,6 +106,7 @@ class DivPlatformGBAMinMod: 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 notifyInsDeletion(void* ins);

View file

@ -493,6 +493,10 @@ int DivPlatformK007232::getOutputCount() {
return stereo?2:1;
}
bool DivPlatformK007232::hasSoftPan(int ch) {
return true;
}
bool DivPlatformK007232::hasAcquireDirect() {
return true;
}

View file

@ -94,6 +94,7 @@ class DivPlatformK007232: public DivDispatch, public k007232_intf {
void tick(bool sysTick=true);
void muteChannel(int ch, bool mute);
int getOutputCount();
bool hasSoftPan(int ch);
bool hasAcquireDirect();
void notifyInsChange(int ins);
void notifyWaveChange(int wave);

View file

@ -410,6 +410,10 @@ int DivPlatformK053260::getOutputCount() {
return 2;
}
bool DivPlatformK053260::hasSoftPan(int ch) {
return true;
}
void DivPlatformK053260::notifyInsChange(int ins) {
for (int i=0; i<4; i++) {
if (chan[i].ins==ins) {

View file

@ -74,6 +74,7 @@ class DivPlatformK053260: public DivDispatch, public k053260_intf {
virtual void tick(bool sysTick=true) override;
virtual void muteChannel(int ch, bool mute) override;
virtual int getOutputCount() override;
virtual bool hasSoftPan(int ch) override;
virtual void notifyInsChange(int ins) override;
virtual void notifyWaveChange(int wave) override;
virtual void notifyInsDeletion(void* ins) override;

View file

@ -487,6 +487,10 @@ int DivPlatformLynx::getOutputCount() {
return 2;
}
bool DivPlatformLynx::hasSoftPan(int ch) {
return true;
}
void DivPlatformLynx::forceIns() {
for (int i=0; i<4; i++) {
if (chan[i].active) {

View file

@ -96,6 +96,7 @@ class DivPlatformLynx: public DivDispatch {
void tick(bool sysTick=true);
void muteChannel(int ch, bool mute);
int getOutputCount();
bool hasSoftPan(int ch);
bool keyOffAffectsArp(int ch);
bool keyOffAffectsPorta(int ch);
bool getLegacyAlwaysSetVolume();

View file

@ -495,6 +495,10 @@ int DivPlatformMultiPCM::getOutputCount() {
return 2;
}
bool DivPlatformMultiPCM::hasSoftPan(int ch) {
return true;
}
bool DivPlatformMultiPCM::keyOffAffectsArp(int ch) {
return false;
}

View file

@ -114,6 +114,7 @@ class DivPlatformMultiPCM: public DivDispatch {
void tick(bool sysTick=true);
void muteChannel(int ch, bool mute);
int getOutputCount();
bool hasSoftPan(int ch);
bool keyOffAffectsArp(int ch);
bool keyOffAffectsPorta(int ch);
bool getLegacyAlwaysSetVolume();

View file

@ -523,6 +523,10 @@ int DivPlatformNamcoWSG::getOutputCount() {
return (devType==30)?2:1;
}
bool DivPlatformNamcoWSG::hasSoftPan(int ch) {
return (devType==30);
}
bool DivPlatformNamcoWSG::keyOffAffectsArp(int ch) {
return true;
}

View file

@ -71,6 +71,7 @@ class DivPlatformNamcoWSG: public DivDispatch {
void tick(bool sysTick=true);
void muteChannel(int ch, bool mute);
int getOutputCount();
bool hasSoftPan(int ch);
bool keyOffAffectsArp(int ch);
void setDeviceType(int type);
void setFlags(const DivConfig& flags);

View file

@ -508,6 +508,10 @@ int DivPlatformNDS::getOutputCount() {
return 2;
}
bool DivPlatformNDS::hasSoftPan(int ch) {
return true;
}
bool DivPlatformNDS::hasAcquireDirect() {
#ifdef ORIG_NDS_CORE
return false;

View file

@ -95,6 +95,7 @@ class DivPlatformNDS: public DivDispatch, public nds_sound_intf {
virtual void muteChannel(int ch, bool mute) override;
virtual float getPostAmp() override;
virtual int getOutputCount() override;
virtual bool hasSoftPan(int ch) override;
virtual bool hasAcquireDirect() override;
virtual void notifyInsChange(int ins) override;
virtual void notifyWaveChange(int wave) override;

View file

@ -2930,6 +2930,10 @@ int DivPlatformOPL::getOutputCount() {
return totalOutputs;
}
bool DivPlatformOPL::hasSoftPan(int ch) {
return (chipType==4 && ch>=pcmChanOffs);
}
bool DivPlatformOPL::keyOffAffectsArp(int ch) {
return false;
}

View file

@ -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);

View file

@ -610,6 +610,10 @@ int DivPlatformPCE::getOutputCount() {
return 2;
}
bool DivPlatformPCE::hasSoftPan(int ch) {
return true;
}
bool DivPlatformPCE::keyOffAffectsArp(int ch) {
return true;
}

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -494,6 +494,10 @@ int DivPlatformPowerNoise::getOutputCount() {
return 2;
}
bool DivPlatformPowerNoise::hasSoftPan(int ch) {
return true;
}
bool DivPlatformPowerNoise::keyOffAffectsArp(int ch) {
return true;
}

View file

@ -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);

View file

@ -676,6 +676,10 @@ int DivPlatformQSound::getOutputCount() {
return 2;
}
bool DivPlatformQSound::hasSoftPan(int ch) {
return true;
}
bool DivPlatformQSound::keyOffAffectsArp(int ch) {
return true;
}

View file

@ -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);

View file

@ -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) {

View file

@ -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);

View file

@ -415,6 +415,10 @@ int DivPlatformSAA1099::getOutputCount() {
return 2;
}
bool DivPlatformSAA1099::hasSoftPan(int ch) {
return true;
}
int DivPlatformSAA1099::getPortaFloor(int ch) {
return 12;
}

View file

@ -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();

View file

@ -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;

View file

@ -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<DivRegWrite>& wlist);

View file

@ -1332,6 +1332,10 @@ int DivPlatformSID3::getOutputCount() {
return 2;
}
bool DivPlatformSID3::hasSoftPan(int ch) {
return true;
}
bool DivPlatformSID3::getDCOffRequired()
{
return false;

View file

@ -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<DivChannelPair>& ret);
void quit();
~DivPlatformSID3();

View file

@ -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) {

View file

@ -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);

View file

@ -634,6 +634,10 @@ int DivPlatformSoundUnit::getOutputCount() {
return 2;
}
bool DivPlatformSoundUnit::hasSoftPan(int ch) {
return true;
}
bool DivPlatformSoundUnit::keyOffAffectsArp(int ch) {
return true;
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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);

View file

@ -358,6 +358,10 @@ int DivPlatformT6W28::getOutputCount() {
return 2;
}
bool DivPlatformT6W28::hasSoftPan(int ch) {
return true;
}
bool DivPlatformT6W28::keyOffAffectsArp(int ch) {
return true;
}

View file

@ -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);

View file

@ -565,6 +565,10 @@ int DivPlatformVB::getOutputCount() {
return 2;
}
bool DivPlatformVB::hasSoftPan(int ch) {
return true;
}
bool DivPlatformVB::keyOffAffectsArp(int ch) {
return true;
}

View file

@ -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();

View file

@ -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;
}

View file

@ -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);

View file

@ -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) {

View file

@ -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);

View file

@ -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;